Skip to content

Commit

Permalink
cranelift: Port bitselect over to ISLE on x64
Browse files Browse the repository at this point in the history
  • Loading branch information
fitzgen committed Jan 6, 2022
1 parent be24edf commit 247a0fe
Show file tree
Hide file tree
Showing 6 changed files with 433 additions and 398 deletions.
1 change: 0 additions & 1 deletion cranelift/codegen/src/isa/x64/inst.isle
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,6 @@
;; Performs an xor operation of the two operands specified
(decl sse_xor (Type Reg RegMem) Reg)
(rule (sse_xor ty x y) (xmm_rm_r ty (sse_xor_op ty) x y))

;; Determine the appropriate operation to compare two vectors of the specified
;; type.
(decl sse_cmp_op (Type) SseOpcode)
Expand Down
64 changes: 35 additions & 29 deletions cranelift/codegen/src/isa/x64/lower.isle
Original file line number Diff line number Diff line change
Expand Up @@ -360,18 +360,14 @@

;; SSE.

(rule (lower (has_type $F32X4 (band x y)))
(value_reg (andps (put_in_reg x)
(put_in_reg_mem y))))

(rule (lower (has_type $F64X2 (band x y)))
(value_reg (andpd (put_in_reg x)
(put_in_reg_mem y))))
(decl sse_and (Type Reg RegMem) Reg)
(rule (sse_and $F32X4 x y) (andps x y))
(rule (sse_and $F64X2 x y) (andpd x y))
(rule (sse_and (multi_lane _bits _lanes) x y) (pand x y))

(rule (lower (has_type (multi_lane _bits _lanes)
(rule (lower (has_type ty @ (multi_lane _bits _lanes)
(band x y)))
(value_reg (pand (put_in_reg x)
(put_in_reg_mem y))))
(value_reg (sse_and ty (put_in_reg x) (put_in_reg_mem y))))

;; `{i,b}128`.

Expand Down Expand Up @@ -436,18 +432,14 @@

;; SSE.

(rule (lower (has_type $F32X4 (bor x y)))
(value_reg (orps (put_in_reg x)
(put_in_reg_mem y))))

(rule (lower (has_type $F64X2 (bor x y)))
(value_reg (orpd (put_in_reg x)
(put_in_reg_mem y))))
(decl sse_or (Type Reg RegMem) Reg)
(rule (sse_or $F32X4 x y) (orps x y))
(rule (sse_or $F64X2 x y) (orpd x y))
(rule (sse_or (multi_lane _bits _lanes) x y) (por x y))

(rule (lower (has_type (multi_lane _bits _lanes)
(rule (lower (has_type ty @ (multi_lane _bits _lanes)
(bor x y)))
(value_reg (por (put_in_reg x)
(put_in_reg_mem y))))
(value_reg (sse_or ty (put_in_reg x) (put_in_reg_mem y))))

;; `{i,b}128`.

Expand Down Expand Up @@ -960,22 +952,22 @@

;;;; Rules for `band_not` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(decl sse_and_not (Type Reg RegMem) Reg)
(rule (sse_and_not $F32X4 x y) (andnps x y))
(rule (sse_and_not $F64X2 x y) (andnpd x y))
(rule (sse_and_not (multi_lane _bits _lanes) x y) (pandn x y))

;; Note the flipping of operands below. CLIF specifies
;;
;; band_not(x, y) = and(x, not(y))
;;
;; while x86 does
;;
;; pandn(x, y) = and(not(x), y)

(rule (lower (has_type $F32X4 (band_not x y)))
(value_reg (andnps (put_in_reg y) (put_in_reg_mem x))))

(rule (lower (has_type $F64X2 (band_not x y)))
(value_reg (andnpd (put_in_reg y) (put_in_reg_mem x))))

(rule (lower (has_type (multi_lane _bits _lanes) (band_not x y)))
(value_reg (pandn (put_in_reg y) (put_in_reg_mem x))))
(rule (lower (has_type ty (band_not x y)))
(value_reg (sse_and_not ty
(put_in_reg y)
(put_in_reg_mem x))))

;;;; Rules for `iabs` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Expand Down Expand Up @@ -1044,6 +1036,20 @@
(rule (lower (has_type ty @ (multi_lane _bits _lanes) (bnot x)))
(value_reg (sse_xor ty (put_in_reg x) (RegMem.Reg (vector_all_ones ty)))))

;;;; Rules for `bitselect` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(rule (lower (has_type ty @ (multi_lane _bits _lanes)
(bitselect condition
if_true
if_false)))
;; a = and condition, if_true
;; b = and_not condition, if_false
;; return or a, b
(let ((cond_reg Reg (put_in_reg condition))
(a Reg (sse_and ty cond_reg (put_in_reg_mem if_true)))
(b Reg (sse_and_not ty cond_reg (put_in_reg_mem if_false))))
(value_reg (sse_or ty a (RegMem.Reg b)))))

;;;; Rules for `insertlane` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(rule (lower (insertlane vec @ (value_type ty) val (u8_from_uimm8 idx)))
Expand Down
26 changes: 2 additions & 24 deletions cranelift/codegen/src/isa/x64/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1534,30 +1534,8 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
| Opcode::Umax
| Opcode::Imin
| Opcode::Umin
| Opcode::Bnot => implemented_in_isle(ctx),

Opcode::Bitselect => {
let ty = ty.unwrap();
let condition = put_input_in_reg(ctx, inputs[0]);
let if_true = put_input_in_reg(ctx, inputs[1]);
let if_false = input_to_reg_mem(ctx, inputs[2]);
let dst = get_output_reg(ctx, outputs[0]).only_reg().unwrap();

if ty.is_vector() {
let tmp1 = ctx.alloc_tmp(ty).only_reg().unwrap();
ctx.emit(Inst::gen_move(tmp1, if_true, ty));
ctx.emit(Inst::and(ty, RegMem::reg(condition.clone()), tmp1));

let tmp2 = ctx.alloc_tmp(ty).only_reg().unwrap();
ctx.emit(Inst::gen_move(tmp2, condition, ty));
ctx.emit(Inst::and_not(ty, if_false, tmp2));

ctx.emit(Inst::gen_move(dst, tmp2.to_reg(), ty));
ctx.emit(Inst::or(ty, RegMem::from(tmp1), dst));
} else {
unimplemented!("no lowering for scalar bitselect instruction")
}
}
| Opcode::Bnot
| Opcode::Bitselect => implemented_in_isle(ctx),

Opcode::Vselect => {
let ty = ty.unwrap();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
src/clif.isle f176ef3bba99365
src/prelude.isle babc931e5dc5b4cf
src/isa/x64/inst.isle fb5d3ac8e68c46d2
src/isa/x64/lower.isle d39e01add89178d5
src/isa/x64/inst.isle 9951164661578952
src/isa/x64/lower.isle 57c693599ccffefc
Loading

0 comments on commit 247a0fe

Please sign in to comment.