cranelift-codegen: port bnot lowering to ISLE in x64

This commit is contained in:
Nick Fitzgerald
2021-12-08 16:54:02 -08:00
committed by Andrew Brown
parent b5e5366550
commit da73952021
5 changed files with 254 additions and 181 deletions

View File

@@ -66,6 +66,9 @@
(src RegMem) (src RegMem)
(dst WritableReg) (dst WritableReg)
(src_size OperandSize)) (src_size OperandSize))
(Not (size OperandSize)
(src Reg)
(dst WritableReg))
)) ))
(type OperandSize extern (type OperandSize extern
@@ -1216,3 +1219,11 @@
(decl insertps (Reg RegMem u8) Reg) (decl insertps (Reg RegMem u8) Reg)
(rule (insertps src1 src2 lane) (rule (insertps src1 src2 lane)
(xmm_rm_r_imm (SseOpcode.Insertps) src1 src2 lane (OperandSize.Size32))) (xmm_rm_r_imm (SseOpcode.Insertps) src1 src2 lane (OperandSize.Size32)))
;; Helper for creating `not` instructions.
(decl not (Type Reg) Reg)
(rule (not ty src)
(let ((dst WritableReg (temp_writable_reg ty))
(size OperandSize (operand_size_of_type ty))
(_ Unit (emit (MInst.Not size src dst))))
(writable_reg_to_reg dst)))

View File

@@ -1007,6 +1007,27 @@
;;;; Rules for `bnot` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Rules for `bnot` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; `i64` and smaller.
(rule (lower (has_type (fits_in_64 ty) (bnot x)))
(value_reg (not ty (put_in_reg x))))
;; `i128`.
(decl i128_not (Value) ValueRegs)
(rule (i128_not x)
(let ((x_regs ValueRegs (put_in_regs x))
(x_lo Reg (value_regs_get x_regs 0))
(x_hi Reg (value_regs_get x_regs 1)))
(value_regs (not $I64 x_lo)
(not $I64 x_hi))))
(rule (lower (has_type $I128 (bnot x)))
(i128_not x))
(rule (lower (has_type $B128 (bnot x)))
(i128_not x))
;; Special case for vector-types where bit-negation is an xor against an ;; Special case for vector-types where bit-negation is an xor against an
;; all-one value ;; all-one value
(rule (lower (has_type ty @ (multi_lane _bits _lanes) (bnot x))) (rule (lower (has_type ty @ (multi_lane _bits _lanes) (bnot x)))

View File

@@ -1533,33 +1533,8 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
| Opcode::Imax | Opcode::Imax
| Opcode::Umax | Opcode::Umax
| Opcode::Imin | Opcode::Imin
| Opcode::Umin => implemented_in_isle(ctx), | Opcode::Umin
| Opcode::Bnot => implemented_in_isle(ctx),
Opcode::Bnot => {
let ty = ty.unwrap();
if ty.is_vector() {
unreachable!(
"implemented in ISLE: inst = `{}`, type = `{:?}`",
ctx.dfg().display_inst(insn),
ty
);
} else if ty == types::I128 || ty == types::B128 {
let src = put_input_in_regs(ctx, inputs[0]);
let dst = get_output_reg(ctx, outputs[0]);
ctx.emit(Inst::gen_move(dst.regs()[0], src.regs()[0], types::I64));
ctx.emit(Inst::not(OperandSize::Size64, dst.regs()[0]));
ctx.emit(Inst::gen_move(dst.regs()[1], src.regs()[1], types::I64));
ctx.emit(Inst::not(OperandSize::Size64, dst.regs()[1]));
} else if ty.is_bool() {
unimplemented!("bool bnot")
} else {
let src = put_input_in_reg(ctx, inputs[0]);
let dst = get_output_reg(ctx, outputs[0]).only_reg().unwrap();
ctx.emit(Inst::gen_move(dst, src, ty));
ctx.emit(Inst::not(OperandSize::from_ty(ty), dst));
}
}
Opcode::Bitselect => { Opcode::Bitselect => {
let ty = ty.unwrap(); let ty = ty.unwrap();

View File

@@ -1,4 +1,4 @@
src/clif.isle 9c0563583e5500de00ec5e226edc0547ac3ea789c8d76f1da0401c80ec619320fdc9a6f17fd76bbcac74a5894f85385c1f51c900c2b83bc9906d03d0f29bf5cb src/clif.isle 9c0563583e5500de00ec5e226edc0547ac3ea789c8d76f1da0401c80ec619320fdc9a6f17fd76bbcac74a5894f85385c1f51c900c2b83bc9906d03d0f29bf5cb
src/prelude.isle 9bd1fcb6a3604a24cf2e05e6b7eb04dcb3b9dc8fa9a2f1c8f29c25b6e3bf7f679b3b1b72dff87501497b72bc30fc92fd755b898db7e03f380235fae931b6a74b src/prelude.isle 9bd1fcb6a3604a24cf2e05e6b7eb04dcb3b9dc8fa9a2f1c8f29c25b6e3bf7f679b3b1b72dff87501497b72bc30fc92fd755b898db7e03f380235fae931b6a74b
src/isa/x64/inst.isle 19426891392b579dbb626361dc3e04e67d322a5fa23a06c0b3ea3866c13c2882d36323e3e20e0a6564e2324ad2681df35df2fa32731e4e6b7496793cc59a36fa src/isa/x64/inst.isle b151120df3c356ac697122a8557becd8857eb725851506e844edeb85d831d461322a96d280ad84f9a23518e1e4efb607aebc0e249004148675e4cc19e89f0655
src/isa/x64/lower.isle aafce143123aaa62ffba7a143acf21b6f5fd751a747e1a93912f37d618e4297450d6e908405f5f21073927de62bc1d779cf14f0609402aba6c98f2801f08f4bf src/isa/x64/lower.isle c9b408df0a089fb4f207838973ac775b0f9b56c86f056867c28e6bae317873d3844f74f713f9acd6fed98d3d11a2f9d19d392fe5049169dad33b1fc703b9b766

File diff suppressed because it is too large Load Diff