* 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.
225 lines
3.6 KiB
Plaintext
225 lines
3.6 KiB
Plaintext
test compile precise-output
|
|
set unwind_info=false
|
|
target aarch64
|
|
|
|
function u0:0(i8) -> f32 {
|
|
block0(v0: i8):
|
|
v1 = fcvt_from_uint.f32 v0
|
|
return v1
|
|
}
|
|
|
|
; VCode:
|
|
; block0:
|
|
; uxtb w2, w0
|
|
; ucvtf s0, w2
|
|
; ret
|
|
;
|
|
; Disassembled:
|
|
; block0: ; offset 0x0
|
|
; uxtb w2, w0
|
|
; ucvtf s0, w2
|
|
; ret
|
|
|
|
function u0:0(i8) -> f64 {
|
|
block0(v0: i8):
|
|
v1 = fcvt_from_uint.f64 v0
|
|
return v1
|
|
}
|
|
|
|
; VCode:
|
|
; block0:
|
|
; uxtb w2, w0
|
|
; ucvtf d0, w2
|
|
; ret
|
|
;
|
|
; Disassembled:
|
|
; block0: ; offset 0x0
|
|
; uxtb w2, w0
|
|
; ucvtf d0, w2
|
|
; ret
|
|
|
|
function u0:0(i16) -> f32 {
|
|
block0(v0: i16):
|
|
v1 = fcvt_from_uint.f32 v0
|
|
return v1
|
|
}
|
|
|
|
; VCode:
|
|
; block0:
|
|
; uxth w2, w0
|
|
; ucvtf s0, w2
|
|
; ret
|
|
;
|
|
; Disassembled:
|
|
; block0: ; offset 0x0
|
|
; uxth w2, w0
|
|
; ucvtf s0, w2
|
|
; ret
|
|
|
|
function u0:0(i16) -> f64 {
|
|
block0(v0: i16):
|
|
v1 = fcvt_from_uint.f64 v0
|
|
return v1
|
|
}
|
|
|
|
; VCode:
|
|
; block0:
|
|
; uxth w2, w0
|
|
; ucvtf d0, w2
|
|
; ret
|
|
;
|
|
; Disassembled:
|
|
; block0: ; offset 0x0
|
|
; uxth w2, w0
|
|
; ucvtf d0, w2
|
|
; ret
|
|
|
|
function u0:0(f32) -> i8 {
|
|
block0(v0: f32):
|
|
v1 = fcvt_to_uint.i8 v0
|
|
return v1
|
|
}
|
|
|
|
; VCode:
|
|
; block0:
|
|
; fcmp s0, s0
|
|
; b.vc 8 ; udf
|
|
; fmov s4, #-1
|
|
; fcmp s0, s4
|
|
; b.gt 8 ; udf
|
|
; movz w8, #17280, LSL #16
|
|
; fmov s18, w8
|
|
; fcmp s0, s18
|
|
; b.lt 8 ; udf
|
|
; fcvtzu w0, s0
|
|
; ret
|
|
;
|
|
; Disassembled:
|
|
; block0: ; offset 0x0
|
|
; fcmp s0, s0
|
|
; b.vc #0xc
|
|
; .byte 0x1f, 0xc1, 0x00, 0x00 ; trap: bad_toint
|
|
; fmov s4, #-1.00000000
|
|
; fcmp s0, s4
|
|
; b.gt #0x1c
|
|
; .byte 0x1f, 0xc1, 0x00, 0x00 ; trap: int_ovf
|
|
; mov w8, #0x43800000
|
|
; fmov s18, w8
|
|
; fcmp s0, s18
|
|
; b.lt #0x30
|
|
; .byte 0x1f, 0xc1, 0x00, 0x00 ; trap: int_ovf
|
|
; fcvtzu w0, s0
|
|
; ret
|
|
|
|
function u0:0(f64) -> i8 {
|
|
block0(v0: f64):
|
|
v1 = fcvt_to_uint.i8 v0
|
|
return v1
|
|
}
|
|
|
|
; VCode:
|
|
; block0:
|
|
; fcmp d0, d0
|
|
; b.vc 8 ; udf
|
|
; fmov d4, #-1
|
|
; fcmp d0, d4
|
|
; b.gt 8 ; udf
|
|
; movz x8, #16496, LSL #48
|
|
; fmov d18, x8
|
|
; fcmp d0, d18
|
|
; b.lt 8 ; udf
|
|
; fcvtzu w0, d0
|
|
; ret
|
|
;
|
|
; Disassembled:
|
|
; block0: ; offset 0x0
|
|
; fcmp d0, d0
|
|
; b.vc #0xc
|
|
; .byte 0x1f, 0xc1, 0x00, 0x00 ; trap: bad_toint
|
|
; fmov d4, #-1.00000000
|
|
; fcmp d0, d4
|
|
; b.gt #0x1c
|
|
; .byte 0x1f, 0xc1, 0x00, 0x00 ; trap: int_ovf
|
|
; mov x8, #0x4070000000000000
|
|
; fmov d18, x8
|
|
; fcmp d0, d18
|
|
; b.lt #0x30
|
|
; .byte 0x1f, 0xc1, 0x00, 0x00 ; trap: int_ovf
|
|
; fcvtzu w0, d0
|
|
; ret
|
|
|
|
function u0:0(f32) -> i16 {
|
|
block0(v0: f32):
|
|
v1 = fcvt_to_uint.i16 v0
|
|
return v1
|
|
}
|
|
|
|
; VCode:
|
|
; block0:
|
|
; fcmp s0, s0
|
|
; b.vc 8 ; udf
|
|
; fmov s4, #-1
|
|
; fcmp s0, s4
|
|
; b.gt 8 ; udf
|
|
; movz w8, #18304, LSL #16
|
|
; fmov s18, w8
|
|
; fcmp s0, s18
|
|
; b.lt 8 ; udf
|
|
; fcvtzu w0, s0
|
|
; ret
|
|
;
|
|
; Disassembled:
|
|
; block0: ; offset 0x0
|
|
; fcmp s0, s0
|
|
; b.vc #0xc
|
|
; .byte 0x1f, 0xc1, 0x00, 0x00 ; trap: bad_toint
|
|
; fmov s4, #-1.00000000
|
|
; fcmp s0, s4
|
|
; b.gt #0x1c
|
|
; .byte 0x1f, 0xc1, 0x00, 0x00 ; trap: int_ovf
|
|
; mov w8, #0x47800000
|
|
; fmov s18, w8
|
|
; fcmp s0, s18
|
|
; b.lt #0x30
|
|
; .byte 0x1f, 0xc1, 0x00, 0x00 ; trap: int_ovf
|
|
; fcvtzu w0, s0
|
|
; ret
|
|
|
|
function u0:0(f64) -> i16 {
|
|
block0(v0: f64):
|
|
v1 = fcvt_to_uint.i16 v0
|
|
return v1
|
|
}
|
|
|
|
; VCode:
|
|
; block0:
|
|
; fcmp d0, d0
|
|
; b.vc 8 ; udf
|
|
; fmov d4, #-1
|
|
; fcmp d0, d4
|
|
; b.gt 8 ; udf
|
|
; movz x8, #16624, LSL #48
|
|
; fmov d18, x8
|
|
; fcmp d0, d18
|
|
; b.lt 8 ; udf
|
|
; fcvtzu w0, d0
|
|
; ret
|
|
;
|
|
; Disassembled:
|
|
; block0: ; offset 0x0
|
|
; fcmp d0, d0
|
|
; b.vc #0xc
|
|
; .byte 0x1f, 0xc1, 0x00, 0x00 ; trap: bad_toint
|
|
; fmov d4, #-1.00000000
|
|
; fcmp d0, d4
|
|
; b.gt #0x1c
|
|
; .byte 0x1f, 0xc1, 0x00, 0x00 ; trap: int_ovf
|
|
; mov x8, #0x40f0000000000000
|
|
; fmov d18, x8
|
|
; fcmp d0, d18
|
|
; b.lt #0x30
|
|
; .byte 0x1f, 0xc1, 0x00, 0x00 ; trap: int_ovf
|
|
; fcvtzu w0, d0
|
|
; ret
|
|
|