aarch64: Use VCodeConstant for f64/v128 constants (#5997)

* aarch64: Translate float and splat lowering to ISLE

I was looking into `constant_f128` and its fallback lowering into memory
and to get familiar with the code I figured it'd be good to port some
Rust logic to ISLE. This commit ports the `constant_{f128,f64,f32}`
helpers into ISLE from Rust as well as the `splat_const` helper which
ended up being closely related.

Tests reflect a number of regalloc changes that happened but also namely
one major difference is that in the lowering of `f32` a 32-bit immediate
is created now instead of a 64-bit immediate (in a GP register before
it's moved into a FP register). This semantically has no change but the
generated code is slightly different in a few minor cases.

* aarch64: Load f64/v128 constants from a pool

This commit removes the `LoadFpuConst64` and `LoadFpuConst128`
pseudo-instructions from the AArch64 backend which internally loaded a
nearby constant and then jumped over it. Constants now go through the
`VCodeConstant` infrastructure which gets placed at the end of the
function similar to how x64 works. Some minor support was added in as
well to add a new addressing mode for a `MachLabel`-relative load.
This commit is contained in:
Alex Crichton
2023-03-13 14:33:52 -05:00
committed by GitHub
parent 6ecdc2482e
commit 03b5dbb3e0
25 changed files with 622 additions and 744 deletions

View File

@@ -896,7 +896,7 @@
(CallInd
(link WritableReg)
(info BoxCallIndInfo))
;; A pseudo-instruction that captures register arguments in vregs.
(Args
(args VecArgPair))
@@ -1555,8 +1555,8 @@
(decl u8_as_u16 (u8) u16)
(extern constructor u8_as_u16 u8_as_u16)
(decl u64_as_u32 (u64) u32)
(extern constructor u64_as_u32 u64_as_u32)
(decl u64_truncate_to_u32 (u64) u32)
(extern constructor u64_truncate_to_u32 u64_truncate_to_u32)
(decl u64_as_i16 (u64) i16)
(extern constructor u64_as_i16 u64_as_i16)
@@ -3000,7 +3000,7 @@
;; 32-bit result type, any value
(rule 5 (imm (gpr32_ty ty) n)
(let ((dst WritableReg (temp_writable_reg ty))
(_ Unit (emit (MInst.Mov32Imm dst (u64_as_u32 n)))))
(_ Unit (emit (MInst.Mov32Imm dst (u64_truncate_to_u32 n)))))
dst))
;; 64-bit result type, value fits in i16
@@ -3051,7 +3051,7 @@
;; TODO: use LZER to load 0.0
(rule 8 (imm $F32 n)
(let ((dst WritableReg (temp_writable_reg $F32))
(_ Unit (emit (MInst.LoadFpuConst32 dst (u64_as_u32 n)))))
(_ Unit (emit (MInst.LoadFpuConst32 dst (u64_truncate_to_u32 n)))))
dst))
;; 64-bit floating-point type, any value. Loaded from literal pool.

View File

@@ -18,7 +18,7 @@
;;;; Rules for `f32const` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule (lower (f32const (u64_from_ieee32 x)))
(rule (lower (f32const (u32_from_ieee32 x)))
(imm $F32 x))

View File

@@ -436,7 +436,7 @@ impl generated_code::Context for IsleContext<'_, '_, MInst, S390xBackend> {
}
#[inline]
fn u64_as_u32(&mut self, n: u64) -> u32 {
fn u64_truncate_to_u32(&mut self, n: u64) -> u32 {
n as u32
}