Browse Source

winch(arm64): float_copysign (#8507)

* winch(arm64): float_copysign

Signed-off-by: Edoardo Vacchi <evacchi@users.noreply.github.com>

* Add doc comments

Signed-off-by: Edoardo Vacchi <evacchi@users.noreply.github.com>

---------

Signed-off-by: Edoardo Vacchi <evacchi@users.noreply.github.com>
pull/8559/head
Edoardo Vacchi 6 months ago
committed by GitHub
parent
commit
96909c9755
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 32
      tests/disas/winch/aarch64/f32_copysign/const.wat
  2. 47
      tests/disas/winch/aarch64/f32_copysign/locals.wat
  3. 30
      tests/disas/winch/aarch64/f32_copysign/params.wat
  4. 36
      tests/disas/winch/aarch64/f64_copysign/const.wat
  5. 52
      tests/disas/winch/aarch64/f64_copysign/locals.wat
  6. 30
      tests/disas/winch/aarch64/f64_copysign/params.wat
  7. 52
      winch/codegen/src/isa/aarch64/asm.rs
  8. 10
      winch/codegen/src/isa/aarch64/masm.rs

32
tests/disas/winch/aarch64/f32_copysign/const.wat

@ -0,0 +1,32 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result f32)
(f32.const -1.1)
(f32.const 2.2)
(f32.copysign)
)
)
;; wasm[0]::function[0]:
;; stp x29, x30, [sp, #-0x10]!
;; mov x29, sp
;; mov x28, sp
;; mov x9, x0
;; sub sp, sp, #0x10
;; mov x28, sp
;; stur x0, [x28, #8]
;; stur x1, [x28]
;; mov w16, #0xcccd
;; movk w16, #0x400c, lsl #16
;; fmov s0, w16
;; mov w16, #0xcccd
;; movk w16, #0xbf8c, lsl #16
;; fmov s1, w16
;; ushr v0.2s, v0.2s, #0x1f
;; sli v1.2s, v0.2s, #0x1f
;; fmov s0, s1
;; add sp, sp, #0x10
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

47
tests/disas/winch/aarch64/f32_copysign/locals.wat

@ -0,0 +1,47 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result f32)
(local $foo f32)
(local $bar f32)
(f32.const -1.1)
(local.set $foo)
(f32.const 2.2)
(local.set $bar)
(local.get $foo)
(local.get $bar)
f32.copysign
)
)
;; wasm[0]::function[0]:
;; stp x29, x30, [sp, #-0x10]!
;; mov x29, sp
;; mov x28, sp
;; mov x9, x0
;; sub sp, sp, #0x18
;; mov x28, sp
;; stur x0, [x28, #0x10]
;; stur x1, [x28, #8]
;; mov x16, #0
;; stur x16, [x28]
;; mov w16, #0xcccd
;; movk w16, #0xbf8c, lsl #16
;; fmov s0, w16
;; stur w0, [x28, #4]
;; mov w16, #0xcccd
;; movk w16, #0x400c, lsl #16
;; fmov s0, w16
;; stur w0, [x28]
;; ldur w0, [x28]
;; ldur w1, [x28, #4]
;; ushr v0.2s, v0.2s, #0x1f
;; sli v1.2s, v0.2s, #0x1f
;; fmov s0, s1
;; add sp, sp, #0x18
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

30
tests/disas/winch/aarch64/f32_copysign/params.wat

@ -0,0 +1,30 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (param f32) (param f32) (result f32)
(local.get 0)
(local.get 1)
(f32.copysign)
)
)
;; wasm[0]::function[0]:
;; stp x29, x30, [sp, #-0x10]!
;; mov x29, sp
;; mov x28, sp
;; mov x9, x0
;; sub sp, sp, #0x18
;; mov x28, sp
;; stur x0, [x28, #0x10]
;; stur x1, [x28, #8]
;; stur w0, [x28, #4]
;; stur w1, [x28]
;; ldur w0, [x28]
;; ldur w1, [x28, #4]
;; ushr v0.2s, v0.2s, #0x1f
;; sli v1.2s, v0.2s, #0x1f
;; fmov s0, s1
;; add sp, sp, #0x18
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

36
tests/disas/winch/aarch64/f64_copysign/const.wat

@ -0,0 +1,36 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result f64)
(f64.const -1.1)
(f64.const 2.2)
(f64.copysign)
)
)
;; wasm[0]::function[0]:
;; stp x29, x30, [sp, #-0x10]!
;; mov x29, sp
;; mov x28, sp
;; mov x9, x0
;; sub sp, sp, #0x10
;; mov x28, sp
;; stur x0, [x28, #8]
;; stur x1, [x28]
;; mov x16, #0x999a
;; movk x16, #0x9999, lsl #16
;; movk x16, #0x9999, lsl #32
;; movk x16, #0x4001, lsl #48
;; fmov d0, x16
;; mov x16, #0x999a
;; movk x16, #0x9999, lsl #16
;; movk x16, #0x9999, lsl #32
;; movk x16, #0xbff1, lsl #48
;; fmov d1, x16
;; ushr d0, d0, #0x3f
;; sli d1, d0, #0x3f
;; fmov d0, d1
;; add sp, sp, #0x10
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

52
tests/disas/winch/aarch64/f64_copysign/locals.wat

@ -0,0 +1,52 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result f64)
(local $foo f64)
(local $bar f64)
(f64.const -1.1)
(local.set $foo)
(f64.const 2.2)
(local.set $bar)
(local.get $foo)
(local.get $bar)
f64.copysign
)
)
;; wasm[0]::function[0]:
;; stp x29, x30, [sp, #-0x10]!
;; mov x29, sp
;; mov x28, sp
;; mov x9, x0
;; sub sp, sp, #0x20
;; mov x28, sp
;; stur x0, [x28, #0x18]
;; stur x1, [x28, #0x10]
;; mov x16, #0
;; stur x16, [x28, #8]
;; stur x16, [x28]
;; mov x16, #0x999a
;; movk x16, #0x9999, lsl #16
;; movk x16, #0x9999, lsl #32
;; movk x16, #0xbff1, lsl #48
;; fmov d0, x16
;; stur x0, [x28, #8]
;; mov x16, #0x999a
;; movk x16, #0x9999, lsl #16
;; movk x16, #0x9999, lsl #32
;; movk x16, #0x4001, lsl #48
;; fmov d0, x16
;; stur x0, [x28]
;; ldur x0, [x28]
;; ldur x1, [x28, #8]
;; ushr d0, d0, #0x3f
;; sli d1, d0, #0x3f
;; fmov d0, d1
;; add sp, sp, #0x20
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

30
tests/disas/winch/aarch64/f64_copysign/params.wat

@ -0,0 +1,30 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (param f64) (param f64) (result f64)
(local.get 0)
(local.get 1)
(f64.copysign)
)
)
;; wasm[0]::function[0]:
;; stp x29, x30, [sp, #-0x10]!
;; mov x29, sp
;; mov x28, sp
;; mov x9, x0
;; sub sp, sp, #0x20
;; mov x28, sp
;; stur x0, [x28, #0x18]
;; stur x1, [x28, #0x10]
;; stur x0, [x28, #8]
;; stur x1, [x28]
;; ldur x0, [x28]
;; ldur x1, [x28, #8]
;; ushr d0, d0, #0x3f
;; sli d1, d0, #0x3f
;; fmov d0, d1
;; add sp, sp, #0x20
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

52
winch/codegen/src/isa/aarch64/asm.rs

@ -3,7 +3,11 @@
use super::{address::Address, regs};
use crate::masm::RoundingMode;
use crate::{masm::OperandSize, reg::Reg};
use cranelift_codegen::isa::aarch64::inst::{FPUOp1, FPUOp2, FpuRoundMode, ScalarSize};
use cranelift_codegen::isa::aarch64::inst::FPUOpRI::{UShr32, UShr64};
use cranelift_codegen::isa::aarch64::inst::{
FPULeftShiftImm, FPUOp1, FPUOp2, FPUOpRI, FPUOpRIMod, FPURightShiftImm, FpuRoundMode,
ScalarSize,
};
use cranelift_codegen::{
ir::{MemFlags, SourceLoc},
isa::aarch64::inst::{
@ -296,6 +300,35 @@ impl Assembler {
self.emit_fpu_round(fpu_mode, rn, rd)
}
/// Float unsigned shift right with two registers and an immediate.
pub fn fushr_rri(&mut self, rn: Reg, rd: Reg, amount: u8, size: OperandSize) {
let imm = FPURightShiftImm {
amount: amount,
lane_size_in_bits: size.num_bits(),
};
let ushr = match size {
OperandSize::S32 => UShr32(imm),
OperandSize::S64 => UShr64(imm),
_ => unreachable!(),
};
self.emit_fpu_rri(ushr, rn, rd)
}
/// Float unsigned shift left and insert with three registers
/// and an immediate.
pub fn fsli_rri_mod(&mut self, ri: Reg, rn: Reg, rd: Reg, amount: u8, size: OperandSize) {
let imm = FPULeftShiftImm {
amount: amount,
lane_size_in_bits: size.num_bits(),
};
let sli = match size {
OperandSize::S32 => FPUOpRIMod::Sli32(imm),
OperandSize::S64 => FPUOpRIMod::Sli64(imm),
_ => unreachable!(),
};
self.emit_fpu_rri_mod(sli, ri, rn, rd)
}
/// Return instruction.
pub fn ret(&mut self) {
self.emit(Inst::Ret {});
@ -345,6 +378,23 @@ impl Assembler {
});
}
fn emit_fpu_rri(&mut self, op: FPUOpRI, rn: Reg, rd: Reg) {
self.emit(Inst::FpuRRI {
fpu_op: op,
rd: Writable::from_reg(rd.into()),
rn: rn.into(),
});
}
fn emit_fpu_rri_mod(&mut self, op: FPUOpRIMod, ri: Reg, rn: Reg, rd: Reg) {
self.emit(Inst::FpuRRIMod {
fpu_op: op,
rd: Writable::from_reg(rd.into()),
ri: ri.into(),
rn: rn.into(),
});
}
fn emit_fpu_rr(&mut self, op: FPUOp1, rn: Reg, rd: Reg, size: OperandSize) {
self.emit(Inst::FpuRR {
fpu_op: op,

10
winch/codegen/src/isa/aarch64/masm.rs

@ -312,8 +312,14 @@ impl Masm for MacroAssembler {
self.asm.fmax_rrr(rhs, lhs, dst, size);
}
fn float_copysign(&mut self, _dst: Reg, _lhs: Reg, _rhs: Reg, _size: OperandSize) {
todo!()
fn float_copysign(&mut self, dst: Reg, lhs: Reg, rhs: Reg, size: OperandSize) {
let max_shift = match size {
OperandSize::S32 => 0x1f,
OperandSize::S64 => 0x3f,
_ => unreachable!(),
};
self.asm.fushr_rri(rhs, rhs, max_shift, size);
self.asm.fsli_rri_mod(lhs, rhs, dst, max_shift, size);
}
fn float_neg(&mut self, dst: Reg, size: OperandSize) {

Loading…
Cancel
Save