aarch64: Migrate imul to ISLE
This commit migrates the `imul` clif instruction lowering for AArch64 to ISLE. This is a relatively complicated instruction with lots of special cases due to the simd proposal for wasm. Like x64, however, the special casing lends itself to ISLE quite well and the lowerings here in theory are pretty straightforward. The main gotcha of this commit is that this encounters a unique situation which hasn't been encountered yet with other lowerings, namely the `Umlal32` instruction used in the implementation of `i64x2.mul` is unique in the `VecRRRLongOp` class of instructions in that it both reads and writes the destination register (`use_mod` instead of simply `use_def`). This meant that I needed to add another helper in ISLe for creating a `vec_rrrr_long` instruction (despite this enum variant not actually existing) which implicitly moves the first operand into the destination before issuing the actual `VecRRRLong` instruction.
This commit is contained in:
@@ -1455,6 +1455,38 @@
|
||||
(_ Unit (emit (MInst.VecMisc op dst src size))))
|
||||
(writable_reg_to_reg dst)))
|
||||
|
||||
;; Helper for emitting `MInst.VecRRRLong` instructions.
|
||||
(decl vec_rrr_long (VecRRRLongOp Reg Reg bool) Reg)
|
||||
(rule (vec_rrr_long op src1 src2 high_half)
|
||||
(let ((dst WritableReg (temp_writable_reg $I8X16))
|
||||
(_ Unit (emit (MInst.VecRRRLong op dst src1 src2 high_half))))
|
||||
(writable_reg_to_reg dst)))
|
||||
|
||||
;; Helper for emitting `MInst.VecRRRLong` instructions, but for variants
|
||||
;; where the operation both reads and modifies the destination register.
|
||||
;;
|
||||
;; Currently this is only used for `VecRRRLongOp.Umlal*`
|
||||
(decl vec_rrrr_long (VecRRRLongOp Reg Reg Reg bool) Reg)
|
||||
(rule (vec_rrrr_long op src1 src2 src3 high_half)
|
||||
(let ((dst WritableReg (temp_writable_reg $I8X16))
|
||||
(_1 Unit (emit (MInst.FpuMove128 dst src1)))
|
||||
(_2 Unit (emit (MInst.VecRRRLong op dst src2 src3 high_half))))
|
||||
(writable_reg_to_reg dst)))
|
||||
|
||||
;; Helper for emitting `MInst.VecRRNarrow` instructions.
|
||||
(decl vec_rr_narrow (VecRRNarrowOp Reg bool) Reg)
|
||||
(rule (vec_rr_narrow op src high_half)
|
||||
(let ((dst WritableReg (temp_writable_reg $I8X16))
|
||||
(_ Unit (emit (MInst.VecRRNarrow op dst src high_half))))
|
||||
(writable_reg_to_reg dst)))
|
||||
|
||||
;; Helper for emitting `MInst.VecRRLong` instructions.
|
||||
(decl vec_rr_long (VecRRLongOp Reg bool) Reg)
|
||||
(rule (vec_rr_long op src high_half)
|
||||
(let ((dst WritableReg (temp_writable_reg $I8X16))
|
||||
(_ Unit (emit (MInst.VecRRLong op dst src high_half))))
|
||||
(writable_reg_to_reg dst)))
|
||||
|
||||
;; Immediate value helpers ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(decl imm (Type u64) Reg)
|
||||
|
||||
Reference in New Issue
Block a user