Browse Source

Winch aarch64 clz & ctz (#9033)

* winch aarch64 clz & ctz

* winch aarch64 clz & ctz tests
pull/9038/head
Vulcain 3 months ago
committed by GitHub
parent
commit
8c8d1551e9
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 25
      tests/disas/winch/aarch64/i32_clz/const.wat
  2. 32
      tests/disas/winch/aarch64/i32_clz/locals.wat
  3. 25
      tests/disas/winch/aarch64/i32_clz/params.wat
  4. 26
      tests/disas/winch/aarch64/i32_ctz/const.wat
  5. 31
      tests/disas/winch/aarch64/i32_ctz/locals.wat
  6. 26
      tests/disas/winch/aarch64/i32_ctz/params.wat
  7. 25
      tests/disas/winch/aarch64/i64_clz/const.wat
  8. 32
      tests/disas/winch/aarch64/i64_clz/locals.wat
  9. 25
      tests/disas/winch/aarch64/i64_clz/params.wat
  10. 26
      tests/disas/winch/aarch64/i64_ctz/const.wat
  11. 33
      tests/disas/winch/aarch64/i64_ctz/locals.wat
  12. 26
      tests/disas/winch/aarch64/i64_ctz/params.wat
  13. 23
      winch/codegen/src/isa/aarch64/asm.rs
  14. 10
      winch/codegen/src/isa/aarch64/masm.rs

25
tests/disas/winch/aarch64/i32_clz/const.wat

@ -0,0 +1,25 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result i32)
(i32.const 10)
(i32.clz)
)
)
;; 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, #0xa
;; mov w0, w16
;; clz w0, w0
;; add sp, sp, #0x10
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

32
tests/disas/winch/aarch64/i32_clz/locals.wat

@ -0,0 +1,32 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result i32)
(local $foo i32)
(i32.const 10)
(local.tee $foo)
i32.clz
)
)
;; 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 x16, #0xa
;; mov w0, w16
;; stur w0, [x28, #4]
;; clz w0, w0
;; add sp, sp, #0x18
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

25
tests/disas/winch/aarch64/i32_clz/params.wat

@ -0,0 +1,25 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (param i32) (result i32)
(local.get 0)
(i32.clz)
)
)
;; 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 w2, [x28, #4]
;; ldur w0, [x28, #4]
;; clz w0, w0
;; add sp, sp, #0x18
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

26
tests/disas/winch/aarch64/i32_ctz/const.wat

@ -0,0 +1,26 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result i32)
(i32.const 10)
(i32.ctz)
)
)
;; 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, #0xa
;; mov w0, w16
;; rbit w16, w0
;; clz w0, w16
;; add sp, sp, #0x10
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

31
tests/disas/winch/aarch64/i32_ctz/locals.wat

@ -0,0 +1,31 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result i32)
(local $foo i32)
(i32.const 10)
(local.tee $foo)
i32.ctz
)
)
;; 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 x16, #0xa
;; mov w0, w16
;; stur w0, [x28, #4]
;; rbit w16, w0
;; clz w0, w16
;; add sp, sp, #0x18
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

26
tests/disas/winch/aarch64/i32_ctz/params.wat

@ -0,0 +1,26 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (param i32) (result i32)
(local.get 0)
(i32.ctz)
)
)
;; 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 w2, [x28, #4]
;; ldur w0, [x28, #4]
;; rbit w16, w0
;; clz w0, w16
;; add sp, sp, #0x18
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

25
tests/disas/winch/aarch64/i64_clz/const.wat

@ -0,0 +1,25 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result i64)
(i64.const 10)
(i64.clz)
)
)
;; 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, #0xa
;; mov x0, x16
;; clz x0, x0
;; add sp, sp, #0x10
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

32
tests/disas/winch/aarch64/i64_clz/locals.wat

@ -0,0 +1,32 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result i64)
(local $foo i64)
(i64.const 10)
(local.tee $foo)
i64.clz
)
)
;; 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 x16, #0xa
;; mov x0, x16
;; stur x0, [x28]
;; clz x0, x0
;; add sp, sp, #0x18
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

25
tests/disas/winch/aarch64/i64_clz/params.wat

@ -0,0 +1,25 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (param i64) (result i64)
(local.get 0)
(i64.clz)
)
)
;; 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 x2, [x28]
;; ldur x0, [x28]
;; clz x0, x0
;; add sp, sp, #0x18
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

26
tests/disas/winch/aarch64/i64_ctz/const.wat

@ -0,0 +1,26 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result i64)
(i64.const 10)
(i64.ctz)
)
)
;; 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, #0xa
;; mov x0, x16
;; rbit x16, x0
;; clz x0, x16
;; add sp, sp, #0x10
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

33
tests/disas/winch/aarch64/i64_ctz/locals.wat

@ -0,0 +1,33 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result i64)
(local $foo i64)
(i64.const 10)
(local.tee $foo)
i64.ctz
)
)
;; 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 x16, #0xa
;; mov x0, x16
;; stur x0, [x28]
;; rbit x16, x0
;; clz x0, x16
;; add sp, sp, #0x18
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

26
tests/disas/winch/aarch64/i64_ctz/params.wat

@ -0,0 +1,26 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (param i64) (result i64)
(local.get 0)
(i64.ctz)
)
)
;; 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 x2, [x28]
;; ldur x0, [x28]
;; rbit x16, x0
;; clz x0, x16
;; add sp, sp, #0x18
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

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

@ -5,8 +5,8 @@ use crate::masm::{FloatCmpKind, IntCmpKind, RoundingMode, ShiftKind};
use crate::{masm::OperandSize, reg::Reg};
use cranelift_codegen::isa::aarch64::inst::FPUOpRI::{UShr32, UShr64};
use cranelift_codegen::isa::aarch64::inst::{
Cond, FPULeftShiftImm, FPUOp1, FPUOp2, FPUOpRI, FPUOpRIMod, FPURightShiftImm, FpuRoundMode,
ImmLogic, ImmShift, ScalarSize,
BitOp, Cond, FPULeftShiftImm, FPUOp1, FPUOp2, FPUOpRI, FPUOpRIMod, FPURightShiftImm,
FpuRoundMode, ImmLogic, ImmShift, ScalarSize,
};
use cranelift_codegen::{
ir::{MemFlags, SourceLoc},
@ -360,6 +360,16 @@ impl Assembler {
}
}
/// Count Leading Zeros.
pub fn clz(&mut self, rn: Reg, rd: Reg, size: OperandSize) {
self.emit_bit_rr(BitOp::Clz, rn, rd, size);
}
/// Reverse Bits reverses the bit order in a register.
pub fn rbit(&mut self, rn: Reg, rd: Reg, size: OperandSize) {
self.emit_bit_rr(BitOp::RBit, rn, rd, size);
}
/// Float add with three registers.
pub fn fadd_rrr(&mut self, rm: Reg, rn: Reg, rd: Reg, size: OperandSize) {
self.emit_fpu_rrr(FPUOp2::Add, rm, rn, rd, size);
@ -595,6 +605,15 @@ impl Assembler {
});
}
fn emit_bit_rr(&mut self, op: BitOp, rn: Reg, rd: Reg, size: OperandSize) {
self.emit(Inst::BitRR {
op,
size: size.into(),
rd: Writable::from_reg(rd.into()),
rn: rn.into(),
});
}
// Convert ShiftKind to ALUOp. If kind == Rotl, then emulate it by emitting
// the negation of the given reg r, and returns ALUOp::RotR.
fn shift_kind_to_alu_op(&mut self, kind: ShiftKind, r: Reg, size: OperandSize) -> ALUOp {

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

@ -542,12 +542,14 @@ impl Masm for MacroAssembler {
self.asm.cset(dst, kind.into());
}
fn clz(&mut self, _src: Reg, _dst: Reg, _size: OperandSize) {
todo!()
fn clz(&mut self, src: Reg, dst: Reg, size: OperandSize) {
self.asm.clz(src, dst, size);
}
fn ctz(&mut self, _src: Reg, _dst: Reg, _size: OperandSize) {
todo!()
fn ctz(&mut self, src: Reg, dst: Reg, size: OperandSize) {
let scratch = regs::scratch();
self.asm.rbit(src, scratch, size);
self.asm.clz(scratch, dst, size);
}
fn wrap(&mut self, _src: Reg, _dst: Reg) {

Loading…
Cancel
Save