cranelift-codegen: port bnot lowering to ISLE in x64
This commit is contained in:
committed by
Andrew Brown
parent
b5e5366550
commit
da73952021
@@ -66,6 +66,9 @@
|
||||
(src RegMem)
|
||||
(dst WritableReg)
|
||||
(src_size OperandSize))
|
||||
(Not (size OperandSize)
|
||||
(src Reg)
|
||||
(dst WritableReg))
|
||||
))
|
||||
|
||||
(type OperandSize extern
|
||||
@@ -1216,3 +1219,11 @@
|
||||
(decl insertps (Reg RegMem u8) Reg)
|
||||
(rule (insertps src1 src2 lane)
|
||||
(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)))
|
||||
|
||||
@@ -1007,6 +1007,27 @@
|
||||
|
||||
;;;; 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
|
||||
;; all-one value
|
||||
(rule (lower (has_type ty @ (multi_lane _bits _lanes) (bnot x)))
|
||||
|
||||
@@ -1533,33 +1533,8 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
||||
| Opcode::Imax
|
||||
| Opcode::Umax
|
||||
| Opcode::Imin
|
||||
| Opcode::Umin => 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::Umin
|
||||
| Opcode::Bnot => implemented_in_isle(ctx),
|
||||
|
||||
Opcode::Bitselect => {
|
||||
let ty = ty.unwrap();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
src/clif.isle 9c0563583e5500de00ec5e226edc0547ac3ea789c8d76f1da0401c80ec619320fdc9a6f17fd76bbcac74a5894f85385c1f51c900c2b83bc9906d03d0f29bf5cb
|
||||
src/prelude.isle 9bd1fcb6a3604a24cf2e05e6b7eb04dcb3b9dc8fa9a2f1c8f29c25b6e3bf7f679b3b1b72dff87501497b72bc30fc92fd755b898db7e03f380235fae931b6a74b
|
||||
src/isa/x64/inst.isle 19426891392b579dbb626361dc3e04e67d322a5fa23a06c0b3ea3866c13c2882d36323e3e20e0a6564e2324ad2681df35df2fa32731e4e6b7496793cc59a36fa
|
||||
src/isa/x64/lower.isle aafce143123aaa62ffba7a143acf21b6f5fd751a747e1a93912f37d618e4297450d6e908405f5f21073927de62bc1d779cf14f0609402aba6c98f2801f08f4bf
|
||||
src/isa/x64/inst.isle b151120df3c356ac697122a8557becd8857eb725851506e844edeb85d831d461322a96d280ad84f9a23518e1e4efb607aebc0e249004148675e4cc19e89f0655
|
||||
src/isa/x64/lower.isle c9b408df0a089fb4f207838973ac775b0f9b56c86f056867c28e6bae317873d3844f74f713f9acd6fed98d3d11a2f9d19d392fe5049169dad33b1fc703b9b766
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user