cranelift: Implement ineg.i128 for everyone (#5129)

* cranelift: Add `ineg` runtests

* aarch64: Implement `ineg.i128`

* x64: Implement `ineg.i128`

* riscv: Implement `ineg.i128`

* fuzzgen: Enable `ineg.i128`
This commit is contained in:
Afonso Bordado
2022-10-29 00:10:00 +01:00
committed by GitHub
parent 81f7ef7fbe
commit 879b52825f
9 changed files with 127 additions and 20 deletions

View File

@@ -1731,6 +1731,13 @@
(decl writable_zero_reg () WritableReg)
(extern constructor writable_zero_reg writable_zero_reg)
(decl value_regs_zero () ValueRegs)
(rule (value_regs_zero)
(value_regs
(imm $I64 (ImmExtend.Zero) 0)
(imm $I64 (ImmExtend.Zero) 0)))
;; Helper for emitting `MInst.Mov` instructions.
(decl mov (Reg Type) Reg)
(rule (mov src ty)
@@ -2286,6 +2293,24 @@
(decl sub_vec (Reg Reg VectorSize) Reg)
(rule (sub_vec x y size) (vec_rrr (VecALUOp.Sub) x y size))
(decl sub_i128 (ValueRegs ValueRegs) ValueRegs)
(rule (sub_i128 x y)
(let
;; Get the high/low registers for `x`.
((x_regs ValueRegs x)
(x_lo Reg (value_regs_get x_regs 0))
(x_hi Reg (value_regs_get x_regs 1))
;; Get the high/low registers for `y`.
(y_regs ValueRegs y)
(y_lo Reg (value_regs_get y_regs 0))
(y_hi Reg (value_regs_get y_regs 1)))
;; the actual subtraction is `subs` followed by `sbc` which comprises
;; the low/high bits of the result
(with_flags
(sub_with_flags_paired $I64 x_lo y_lo)
(sbc_paired $I64 x_hi y_hi))))
;; Helpers for generating `madd` instructions.
(decl madd (Type Reg Reg Reg) Reg)

View File

@@ -540,21 +540,7 @@
;; `i128`
(rule -1 (lower (has_type $I128 (isub x y)))
(let
;; Get the high/low registers for `x`.
((x_regs ValueRegs x)
(x_lo Reg (value_regs_get x_regs 0))
(x_hi Reg (value_regs_get x_regs 1))
;; Get the high/low registers for `y`.
(y_regs ValueRegs y)
(y_lo Reg (value_regs_get y_regs 0))
(y_hi Reg (value_regs_get y_regs 1)))
;; the actual subtraction is `subs` followed by `sbc` which comprises
;; the low/high bits of the result
(with_flags
(sub_with_flags_paired $I64 x_lo y_lo)
(sbc_paired $I64 x_hi y_hi))))
(sub_i128 x y))
;;;; Rules for `uadd_sat` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -582,6 +568,10 @@
(rule 1 (lower (has_type (fits_in_64 ty) (ineg x)))
(sub ty (zero_reg) x))
;; `i128`
(rule 2 (lower (has_type $I128 (ineg x)))
(sub_i128 (value_regs_zero) x))
;; vectors.
(rule (lower (has_type (ty_vec128 ty) (ineg x)))
(neg x (vector_size ty)))

View File

@@ -703,6 +703,10 @@
(decl zero_reg () Reg)
(extern constructor zero_reg zero_reg)
(decl value_regs_zero () ValueRegs)
(rule (value_regs_zero)
(value_regs (imm $I64 0) (imm $I64 0)))
(decl gen_float_round (FloatRoundOP Reg Type) Reg)
(rule
(gen_float_round op rs ty)

View File

@@ -71,9 +71,11 @@
;;;; Rules for `ineg` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; `i64` and smaller.
(rule (lower (has_type (fits_in_64 ty) (ineg x)))
(rule 1 (lower (has_type (fits_in_64 ty) (ineg x)))
(alu_rrr (AluOPRRR.Sub) (zero_reg) x))
(rule 2 (lower (has_type $I128 (ineg x)))
(i128_sub (value_regs_zero) x))
;;;; Rules for `imul` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

View File

@@ -2917,6 +2917,14 @@
(size OperandSize (operand_size_of_type_32_64 ty))
(_ Unit (emit (MInst.Neg size src dst))))
dst))
;; Helper for creating `neg` instructions whose flags are also used.
(decl x64_neg_paired (Type Gpr) ProducesFlags)
(rule (x64_neg_paired ty src)
(let ((dst WritableGpr (temp_writable_gpr))
(size OperandSize (operand_size_of_type_32_64 ty))
(inst MInst (MInst.Neg size src dst)))
(ProducesFlags.ProducesFlagsReturnsResultWithConsumer inst dst)))
(decl x64_lea (SyntheticAmode) Gpr)
(rule (x64_lea addr)

View File

@@ -777,6 +777,15 @@
(rule -1 (lower (has_type (fits_in_64 ty) (ineg x)))
(x64_neg ty x))
(rule -2 (lower (has_type $I128 (ineg x)))
;; Get the high/low registers for `x`.
(let ((regs ValueRegs x)
(lo Gpr (value_regs_get_gpr regs 0))
(hi Gpr (value_regs_get_gpr regs 1)))
;; Do a neg followed by an sub-with-borrow.
(with_flags (x64_neg_paired $I64 lo)
(x64_sbb_paired $I64 (imm $I64 0) hi))))
;; SSE.
(rule (lower (has_type $I8X16 (ineg x)))