Browse Source

winch(arm64): fpu arithmetics (add, sub, mul, div, min, max) and regalloc (#8365)

* winch(arm64): fpu arithmetics (add, sub, mul, div, min, max)

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

* disas: add fpu test cases (add)

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

* winch(arm64): regalloc for fpu

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

* disas: add fpu test cases (add64)

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

* disas: add fpu test cases

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

* Apply suggestions from code review

Co-authored-by: Saúl Cabrera <saulecabrera@gmail.com>

* Apply suggestions from code review

Co-authored-by: Saúl Cabrera <saulecabrera@gmail.com>

* add todo for f32 mov

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

---------

Signed-off-by: Edoardo Vacchi <evacchi@users.noreply.github.com>
Co-authored-by: Saúl Cabrera <saulecabrera@gmail.com>
pull/8372/head
Edoardo Vacchi 7 months ago
committed by GitHub
parent
commit
d36d4708b9
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 31
      tests/disas/winch/aarch64/f32_add/const.wat
  2. 46
      tests/disas/winch/aarch64/f32_add/locals.wat
  3. 29
      tests/disas/winch/aarch64/f32_add/params.wat
  4. 31
      tests/disas/winch/aarch64/f32_div/const.wat
  5. 46
      tests/disas/winch/aarch64/f32_div/locals.wat
  6. 29
      tests/disas/winch/aarch64/f32_div/params.wat
  7. 31
      tests/disas/winch/aarch64/f32_max/const.wat
  8. 46
      tests/disas/winch/aarch64/f32_max/locals.wat
  9. 29
      tests/disas/winch/aarch64/f32_max/params.wat
  10. 31
      tests/disas/winch/aarch64/f32_min/const.wat
  11. 46
      tests/disas/winch/aarch64/f32_min/locals.wat
  12. 29
      tests/disas/winch/aarch64/f32_min/params.wat
  13. 31
      tests/disas/winch/aarch64/f32_mul/const.wat
  14. 46
      tests/disas/winch/aarch64/f32_mul/locals.wat
  15. 29
      tests/disas/winch/aarch64/f32_mul/params.wat
  16. 31
      tests/disas/winch/aarch64/f32_sub/const.wat
  17. 46
      tests/disas/winch/aarch64/f32_sub/locals.wat
  18. 29
      tests/disas/winch/aarch64/f32_sub/params.wat
  19. 35
      tests/disas/winch/aarch64/f64_add/const.wat
  20. 51
      tests/disas/winch/aarch64/f64_add/locals.wat
  21. 29
      tests/disas/winch/aarch64/f64_add/params.wat
  22. 35
      tests/disas/winch/aarch64/f64_div/const.wat
  23. 51
      tests/disas/winch/aarch64/f64_div/locals.wat
  24. 29
      tests/disas/winch/aarch64/f64_div/params.wat
  25. 35
      tests/disas/winch/aarch64/f64_max/const.wat
  26. 51
      tests/disas/winch/aarch64/f64_max/locals.wat
  27. 29
      tests/disas/winch/aarch64/f64_max/params.wat
  28. 35
      tests/disas/winch/aarch64/f64_min/const.wat
  29. 51
      tests/disas/winch/aarch64/f64_min/locals.wat
  30. 29
      tests/disas/winch/aarch64/f64_min/params.wat
  31. 35
      tests/disas/winch/aarch64/f64_mul/const.wat
  32. 51
      tests/disas/winch/aarch64/f64_mul/locals.wat
  33. 29
      tests/disas/winch/aarch64/f64_mul/params.wat
  34. 35
      tests/disas/winch/aarch64/f64_sub/const.wat
  35. 51
      tests/disas/winch/aarch64/f64_sub/locals.wat
  36. 29
      tests/disas/winch/aarch64/f64_sub/params.wat
  37. 2
      winch/codegen/src/isa/aarch64/abi.rs
  38. 69
      winch/codegen/src/isa/aarch64/asm.rs
  39. 44
      winch/codegen/src/isa/aarch64/masm.rs
  40. 8
      winch/codegen/src/isa/aarch64/mod.rs
  41. 14
      winch/codegen/src/isa/aarch64/regs.rs
  42. 2
      winch/codegen/src/regalloc.rs
  43. 2
      winch/codegen/src/regset.rs

31
tests/disas/winch/aarch64/f32_add/const.wat

@ -0,0 +1,31 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result f32)
(f32.const 1.1)
(f32.const 2.2)
(f32.add)
)
)
;; 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, #0x3f8c, lsl #16
;; fmov s1, w16
;; fadd s1, s1, s0
;; fmov d0, d1
;; add sp, sp, #0x10
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

46
tests/disas/winch/aarch64/f32_add/locals.wat

@ -0,0 +1,46 @@
;;! 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.add
)
)
;; 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, #0x3f8c, 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]
;; fadd s1, s1, s0
;; fmov d0, d1
;; add sp, sp, #0x18
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

29
tests/disas/winch/aarch64/f32_add/params.wat

@ -0,0 +1,29 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (param f32) (param f32) (result f32)
(local.get 0)
(local.get 1)
(f32.add)
)
)
;; 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]
;; fadd s1, s1, s0
;; fmov d0, d1
;; add sp, sp, #0x18
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

31
tests/disas/winch/aarch64/f32_div/const.wat

@ -0,0 +1,31 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result f32)
(f32.const 1.1)
(f32.const 2.2)
(f32.div)
)
)
;; 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, #0x3f8c, lsl #16
;; fmov s1, w16
;; fdiv s1, s1, s0
;; fmov d0, d1
;; add sp, sp, #0x10
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

46
tests/disas/winch/aarch64/f32_div/locals.wat

@ -0,0 +1,46 @@
;;! 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.div
)
)
;; 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, #0x3f8c, 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]
;; fdiv s1, s1, s0
;; fmov d0, d1
;; add sp, sp, #0x18
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

29
tests/disas/winch/aarch64/f32_div/params.wat

@ -0,0 +1,29 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (param f32) (param f32) (result f32)
(local.get 0)
(local.get 1)
(f32.div)
)
)
;; 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]
;; fdiv s1, s1, s0
;; fmov d0, d1
;; add sp, sp, #0x18
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

31
tests/disas/winch/aarch64/f32_max/const.wat

@ -0,0 +1,31 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result f32)
(f32.const 1.1)
(f32.const 2.2)
(f32.max)
)
)
;; 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, #0x3f8c, lsl #16
;; fmov s1, w16
;; fmax s1, s1, s0
;; fmov d0, d1
;; add sp, sp, #0x10
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

46
tests/disas/winch/aarch64/f32_max/locals.wat

@ -0,0 +1,46 @@
;;! 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.max
)
)
;; 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, #0x3f8c, 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]
;; fmax s1, s1, s0
;; fmov d0, d1
;; add sp, sp, #0x18
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

29
tests/disas/winch/aarch64/f32_max/params.wat

@ -0,0 +1,29 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (param f32) (param f32) (result f32)
(local.get 0)
(local.get 1)
(f32.max)
)
)
;; 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]
;; fmax s1, s1, s0
;; fmov d0, d1
;; add sp, sp, #0x18
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

31
tests/disas/winch/aarch64/f32_min/const.wat

@ -0,0 +1,31 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result f32)
(f32.const 1.1)
(f32.const 2.2)
(f32.min)
)
)
;; 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, #0x3f8c, lsl #16
;; fmov s1, w16
;; fmin s1, s1, s0
;; fmov d0, d1
;; add sp, sp, #0x10
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

46
tests/disas/winch/aarch64/f32_min/locals.wat

@ -0,0 +1,46 @@
;;! 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.min
)
)
;; 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, #0x3f8c, 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]
;; fmin s1, s1, s0
;; fmov d0, d1
;; add sp, sp, #0x18
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

29
tests/disas/winch/aarch64/f32_min/params.wat

@ -0,0 +1,29 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (param f32) (param f32) (result f32)
(local.get 0)
(local.get 1)
(f32.min)
)
)
;; 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]
;; fmin s1, s1, s0
;; fmov d0, d1
;; add sp, sp, #0x18
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

31
tests/disas/winch/aarch64/f32_mul/const.wat

@ -0,0 +1,31 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result f32)
(f32.const 1.1)
(f32.const 2.2)
(f32.mul)
)
)
;; 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, #0x3f8c, lsl #16
;; fmov s1, w16
;; fmul s1, s1, s0
;; fmov d0, d1
;; add sp, sp, #0x10
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

46
tests/disas/winch/aarch64/f32_mul/locals.wat

@ -0,0 +1,46 @@
;;! 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.mul
)
)
;; 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, #0x3f8c, 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]
;; fmul s1, s1, s0
;; fmov d0, d1
;; add sp, sp, #0x18
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

29
tests/disas/winch/aarch64/f32_mul/params.wat

@ -0,0 +1,29 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (param f32) (param f32) (result f32)
(local.get 0)
(local.get 1)
(f32.mul)
)
)
;; 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]
;; fmul s1, s1, s0
;; fmov d0, d1
;; add sp, sp, #0x18
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

31
tests/disas/winch/aarch64/f32_sub/const.wat

@ -0,0 +1,31 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result f32)
(f32.const 1.1)
(f32.const 2.2)
(f32.sub)
)
)
;; 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, #0x3f8c, lsl #16
;; fmov s1, w16
;; fsub s1, s1, s0
;; fmov d0, d1
;; add sp, sp, #0x10
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

46
tests/disas/winch/aarch64/f32_sub/locals.wat

@ -0,0 +1,46 @@
;;! 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.sub
)
)
;; 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, #0x3f8c, 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]
;; fsub s1, s1, s0
;; fmov d0, d1
;; add sp, sp, #0x18
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

29
tests/disas/winch/aarch64/f32_sub/params.wat

@ -0,0 +1,29 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (param f32) (param f32) (result f32)
(local.get 0)
(local.get 1)
(f32.sub)
)
)
;; 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]
;; fsub s1, s1, s0
;; fmov d0, d1
;; add sp, sp, #0x18
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

35
tests/disas/winch/aarch64/f64_add/const.wat

@ -0,0 +1,35 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result f64)
(f64.const 1.1)
(f64.const 2.2)
(f64.add)
)
)
;; 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, #0x3ff1, lsl #48
;; fmov d1, x16
;; fadd d1, d1, d0
;; fmov d0, d1
;; add sp, sp, #0x10
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

51
tests/disas/winch/aarch64/f64_add/locals.wat

@ -0,0 +1,51 @@
;;! 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.add
)
)
;; 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, #0x3ff1, 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]
;; fadd d1, d1, d0
;; fmov d0, d1
;; add sp, sp, #0x20
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

29
tests/disas/winch/aarch64/f64_add/params.wat

@ -0,0 +1,29 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (param f64) (param f64) (result f64)
(local.get 0)
(local.get 1)
(f64.add)
)
)
;; 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]
;; fadd d1, d1, d0
;; fmov d0, d1
;; add sp, sp, #0x20
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

35
tests/disas/winch/aarch64/f64_div/const.wat

@ -0,0 +1,35 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result f64)
(f64.const 1.1)
(f64.const 2.2)
(f64.div)
)
)
;; 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, #0x3ff1, lsl #48
;; fmov d1, x16
;; fdiv d1, d1, d0
;; fmov d0, d1
;; add sp, sp, #0x10
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

51
tests/disas/winch/aarch64/f64_div/locals.wat

@ -0,0 +1,51 @@
;;! 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.div
)
)
;; 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, #0x3ff1, 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]
;; fdiv d1, d1, d0
;; fmov d0, d1
;; add sp, sp, #0x20
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

29
tests/disas/winch/aarch64/f64_div/params.wat

@ -0,0 +1,29 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (param f64) (param f64) (result f64)
(local.get 0)
(local.get 1)
(f64.div)
)
)
;; 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]
;; fdiv d1, d1, d0
;; fmov d0, d1
;; add sp, sp, #0x20
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

35
tests/disas/winch/aarch64/f64_max/const.wat

@ -0,0 +1,35 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result f64)
(f64.const 1.1)
(f64.const 2.2)
(f64.max)
)
)
;; 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, #0x3ff1, lsl #48
;; fmov d1, x16
;; fmax d1, d1, d0
;; fmov d0, d1
;; add sp, sp, #0x10
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

51
tests/disas/winch/aarch64/f64_max/locals.wat

@ -0,0 +1,51 @@
;;! 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.max
)
)
;; 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, #0x3ff1, 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]
;; fmax d1, d1, d0
;; fmov d0, d1
;; add sp, sp, #0x20
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

29
tests/disas/winch/aarch64/f64_max/params.wat

@ -0,0 +1,29 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (param f64) (param f64) (result f64)
(local.get 0)
(local.get 1)
(f64.max)
)
)
;; 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]
;; fmax d1, d1, d0
;; fmov d0, d1
;; add sp, sp, #0x20
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

35
tests/disas/winch/aarch64/f64_min/const.wat

@ -0,0 +1,35 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result f64)
(f64.const 1.1)
(f64.const 2.2)
(f64.min)
)
)
;; 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, #0x3ff1, lsl #48
;; fmov d1, x16
;; fmin d1, d1, d0
;; fmov d0, d1
;; add sp, sp, #0x10
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

51
tests/disas/winch/aarch64/f64_min/locals.wat

@ -0,0 +1,51 @@
;;! 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.min
)
)
;; 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, #0x3ff1, 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]
;; fmin d1, d1, d0
;; fmov d0, d1
;; add sp, sp, #0x20
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

29
tests/disas/winch/aarch64/f64_min/params.wat

@ -0,0 +1,29 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (param f64) (param f64) (result f64)
(local.get 0)
(local.get 1)
(f64.min)
)
)
;; 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]
;; fmin d1, d1, d0
;; fmov d0, d1
;; add sp, sp, #0x20
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

35
tests/disas/winch/aarch64/f64_mul/const.wat

@ -0,0 +1,35 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result f64)
(f64.const 1.1)
(f64.const 2.2)
(f64.mul)
)
)
;; 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, #0x3ff1, lsl #48
;; fmov d1, x16
;; fmul d1, d1, d0
;; fmov d0, d1
;; add sp, sp, #0x10
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

51
tests/disas/winch/aarch64/f64_mul/locals.wat

@ -0,0 +1,51 @@
;;! 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.mul
)
)
;; 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, #0x3ff1, 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]
;; fmul d1, d1, d0
;; fmov d0, d1
;; add sp, sp, #0x20
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

29
tests/disas/winch/aarch64/f64_mul/params.wat

@ -0,0 +1,29 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (param f64) (param f64) (result f64)
(local.get 0)
(local.get 1)
(f64.mul)
)
)
;; 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]
;; fmul d1, d1, d0
;; fmov d0, d1
;; add sp, sp, #0x20
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

35
tests/disas/winch/aarch64/f64_sub/const.wat

@ -0,0 +1,35 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result f64)
(f64.const 1.1)
(f64.const 2.2)
(f64.sub)
)
)
;; 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, #0x3ff1, lsl #48
;; fmov d1, x16
;; fsub d1, d1, d0
;; fmov d0, d1
;; add sp, sp, #0x10
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

51
tests/disas/winch/aarch64/f64_sub/locals.wat

@ -0,0 +1,51 @@
;;! 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.sub
)
)
;; 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, #0x3ff1, 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]
;; fsub d1, d1, d0
;; fmov d0, d1
;; add sp, sp, #0x20
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

29
tests/disas/winch/aarch64/f64_sub/params.wat

@ -0,0 +1,29 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (param f64) (param f64) (result f64)
(local.get 0)
(local.get 1)
(f64.sub)
)
)
;; 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]
;; fsub d1, d1, d0
;; fmov d0, d1
;; add sp, sp, #0x20
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

2
winch/codegen/src/isa/aarch64/abi.rs

@ -118,7 +118,7 @@ impl ABI for Aarch64ABI {
}
fn float_scratch_reg() -> Reg {
todo!()
regs::float_scratch()
}
fn vmctx_reg() -> Reg {

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

@ -2,6 +2,7 @@
use super::{address::Address, regs};
use crate::{masm::OperandSize, reg::Reg};
use cranelift_codegen::isa::aarch64::inst::{FPUOp2, ScalarSize};
use cranelift_codegen::{
ir::{MemFlags, SourceLoc},
isa::aarch64::inst::{
@ -22,6 +23,17 @@ impl From<OperandSize> for inst::OperandSize {
}
}
}
impl Into<ScalarSize> for OperandSize {
fn into(self) -> ScalarSize {
match self {
OperandSize::S8 => ScalarSize::Size8,
OperandSize::S16 => ScalarSize::Size16,
OperandSize::S32 => ScalarSize::Size32,
OperandSize::S64 => ScalarSize::Size64,
OperandSize::S128 => ScalarSize::Size128,
}
}
}
/// Low level assembler implementation for Aarch64.
pub(crate) struct Assembler {
@ -149,6 +161,23 @@ impl Assembler {
});
}
pub fn fmov64_rr(&mut self, rm: Reg, rd: Reg) {
let writable_rd = Writable::from_reg(rd.into());
self.emit(Inst::FpuMove64 {
rd: writable_rd,
rn: rm.into(),
})
}
pub fn mov_to_fpu(&mut self, rn: Reg, rd: Reg, size: OperandSize) {
let writable_rd = Writable::from_reg(rd.into());
self.emit(Inst::MovToFpu {
size: size.into(),
rd: writable_rd,
rn: rn.into(),
});
}
/// Add with three registers.
pub fn add_rrr(&mut self, rm: Reg, rn: Reg, rd: Reg, size: OperandSize) {
self.emit_alu_rrr_extend(ALUOp::Add, rm, rn, rd, size);
@ -195,6 +224,36 @@ impl Assembler {
self.emit_alu_rrrr(ALUOp3::MAdd, scratch, rn, rd, regs::zero(), 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);
}
/// Float sub with three registers.
pub fn fsub_rrr(&mut self, rm: Reg, rn: Reg, rd: Reg, size: OperandSize) {
self.emit_fpu_rrr(FPUOp2::Sub, rm, rn, rd, size);
}
/// Float multiply with three registers.
pub fn fmul_rrr(&mut self, rm: Reg, rn: Reg, rd: Reg, size: OperandSize) {
self.emit_fpu_rrr(FPUOp2::Mul, rm, rn, rd, size);
}
/// Float division with three registers.
pub fn fdiv_rrr(&mut self, rm: Reg, rn: Reg, rd: Reg, size: OperandSize) {
self.emit_fpu_rrr(FPUOp2::Div, rm, rn, rd, size);
}
/// Float max with three registers.
pub fn fmax_rrr(&mut self, rm: Reg, rn: Reg, rd: Reg, size: OperandSize) {
self.emit_fpu_rrr(FPUOp2::Max, rm, rn, rd, size);
}
/// Float min with three registers.
pub fn fmin_rrr(&mut self, rm: Reg, rn: Reg, rd: Reg, size: OperandSize) {
self.emit_fpu_rrr(FPUOp2::Min, rm, rn, rd, size);
}
/// Return instruction.
pub fn ret(&mut self) {
self.emit(Inst::Ret {});
@ -234,6 +293,16 @@ impl Assembler {
});
}
fn emit_fpu_rrr(&mut self, op: FPUOp2, rm: Reg, rn: Reg, rd: Reg, size: OperandSize) {
self.emit(Inst::FpuRRR {
fpu_op: op,
size: size.into(),
rd: Writable::from_reg(rd.into()),
rn: rn.into(),
rm: rm.into(),
});
}
/// Get a label from the underlying machine code buffer.
pub fn get_label(&mut self) -> MachLabel {
self.buffer.get_label()

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

@ -14,6 +14,7 @@ use cranelift_codegen::{
ir::{RelSourceLoc, SourceLoc},
settings, Final, MachBufferFinalized, MachLabel,
};
use regalloc2::RegClass;
use wasmtime_environ::PtrSize;
/// Aarch64 MacroAssembler.
@ -197,16 +198,25 @@ impl Masm for MacroAssembler {
let imm = match v {
I::I32(v) => v as u64,
I::I64(v) => v,
_ => panic!(),
I::F32(v) => v as u64,
I::F64(v) => v,
};
let scratch = regs::scratch();
self.asm.load_constant(imm, scratch);
self.asm.mov_rr(scratch, rd, size);
}
(RegImm::Reg(rs), rd) => {
self.asm.mov_rr(rs, rd, size);
match rd.class() {
RegClass::Int => self.asm.mov_rr(scratch, rd, size),
RegClass::Float => self.asm.mov_to_fpu(scratch, rd, size),
_ => todo!(),
}
}
(RegImm::Reg(rs), rd) => match (rs.class(), rd.class()) {
(RegClass::Int, RegClass::Int) => self.asm.mov_rr(rs, rd, size),
// TODO: verify whether we should use `fmov sd, sn` for F32.
(RegClass::Float, RegClass::Float) => self.asm.fmov64_rr(rs, rd),
(RegClass::Int, RegClass::Float) => self.asm.mov_to_fpu(rs, rd, size),
_ => todo!(),
},
}
}
@ -279,28 +289,28 @@ impl Masm for MacroAssembler {
}
}
fn float_add(&mut self, _dst: Reg, _lhs: Reg, _rhs: Reg, _size: OperandSize) {
todo!()
fn float_add(&mut self, dst: Reg, lhs: Reg, rhs: Reg, size: OperandSize) {
self.asm.fadd_rrr(rhs, lhs, dst, size);
}
fn float_sub(&mut self, _dst: Reg, _lhs: Reg, _rhs: Reg, _size: OperandSize) {
todo!()
fn float_sub(&mut self, dst: Reg, lhs: Reg, rhs: Reg, size: OperandSize) {
self.asm.fsub_rrr(rhs, lhs, dst, size);
}
fn float_mul(&mut self, _dst: Reg, _lhs: Reg, _rhs: Reg, _size: OperandSize) {
todo!()
fn float_mul(&mut self, dst: Reg, lhs: Reg, rhs: Reg, size: OperandSize) {
self.asm.fmul_rrr(rhs, lhs, dst, size);
}
fn float_div(&mut self, _dst: Reg, _lhs: Reg, _rhs: Reg, _size: OperandSize) {
todo!()
fn float_div(&mut self, dst: Reg, lhs: Reg, rhs: Reg, size: OperandSize) {
self.asm.fdiv_rrr(rhs, lhs, dst, size);
}
fn float_min(&mut self, _dst: Reg, _lhs: Reg, _rhs: Reg, _size: OperandSize) {
todo!()
fn float_min(&mut self, dst: Reg, lhs: Reg, rhs: Reg, size: OperandSize) {
self.asm.fmin_rrr(rhs, lhs, dst, size);
}
fn float_max(&mut self, _dst: Reg, _lhs: Reg, _rhs: Reg, _size: OperandSize) {
todo!()
fn float_max(&mut self, dst: Reg, lhs: Reg, rhs: Reg, size: OperandSize) {
self.asm.fmax_rrr(rhs, lhs, dst, size);
}
fn float_copysign(&mut self, _dst: Reg, _lhs: Reg, _rhs: Reg, _size: OperandSize) {

8
winch/codegen/src/isa/aarch64/mod.rs

@ -1,4 +1,5 @@
use self::regs::{ALL_GPR, MAX_FPR, MAX_GPR, NON_ALLOCATABLE_GPR};
use crate::isa::aarch64::regs::{ALL_FPR, NON_ALLOCATABLE_FPR};
use crate::{
abi::{wasm_sig, ABI},
codegen::{CodeGen, CodeGenContext, FuncEnv, TypeConverter},
@ -116,8 +117,11 @@ impl TargetIsa for Aarch64 {
NON_ALLOCATABLE_GPR.into(),
usize::try_from(MAX_GPR).unwrap(),
);
// TODO: Add floating point bitmask
let fpr = RegBitSet::float(0, 0, usize::try_from(MAX_FPR).unwrap());
let fpr = RegBitSet::float(
ALL_FPR.into(),
NON_ALLOCATABLE_FPR.into(),
usize::try_from(MAX_FPR).unwrap(),
);
let regalloc = RegAlloc::from(gpr, fpr);
let codegen_context = CodeGenContext::new(regalloc, stack, frame, &vmoffsets);
let mut codegen = CodeGen::new(&mut masm, codegen_context, env, abi_sig);

14
winch/codegen/src/isa/aarch64/regs.rs

@ -31,6 +31,11 @@ pub(crate) const fn scratch() -> Reg {
ip0()
}
// Alias to register v31.
pub(crate) const fn float_scratch() -> Reg {
vreg(31)
}
/// Scratch register.
/// Intra-procedure-call corruptible register.
pub(crate) const fn ip1() -> Reg {
@ -135,7 +140,7 @@ pub(crate) const fn shadow_sp() -> Reg {
xreg(28)
}
/// Bitmask for non-allocatble GPR.
/// Bitmask for non-allocatable GPR.
pub(crate) const NON_ALLOCATABLE_GPR: u32 = (1 << ip0().hw_enc())
| (1 << ip1().hw_enc())
| (1 << platform().hw_enc())
@ -147,3 +152,10 @@ pub(crate) const NON_ALLOCATABLE_GPR: u32 = (1 << ip0().hw_enc())
/// Bitmask to represent the available general purpose registers.
pub(crate) const ALL_GPR: u32 = u32::MAX & !NON_ALLOCATABLE_GPR;
/// Bitmask for non-allocatable FPR.
/// All FPRs are allocatable, v0..=v7 are generally used for params and results.
pub(crate) const NON_ALLOCATABLE_FPR: u32 = 1 << float_scratch().hw_enc();
/// Bitmask to represent the available floating point registers.
pub(crate) const ALL_FPR: u32 = u32::MAX & !NON_ALLOCATABLE_FPR;

2
winch/codegen/src/regalloc.rs

@ -35,7 +35,7 @@ impl RegAlloc {
self.regset.reg_for_class(class).unwrap_or_else(|| {
spill(self);
self.regset.reg_for_class(class).unwrap_or_else(|| {
panic!("expected register for class {:?}, to be avilable", class)
panic!("expected register for class {:?}, to be available", class)
})
})
}

2
winch/codegen/src/regset.rs

@ -1,6 +1,6 @@
use crate::isa::reg::{Reg, RegClass};
/// A bit set to track regiter availability.
/// A bit set to track register availability.
pub(crate) struct RegSet {
/// Bitset to track general purpose register availability.
gpr: RegBitSet,

Loading…
Cancel
Save