Browse Source

winch(aarch64): abs, ceil, floor, nearest, trunc, neg, sqrt (#8425)

* winch(amd64): more fpu

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

* Add tests

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

---------

Signed-off-by: Edoardo Vacchi <evacchi@users.noreply.github.com>
pull/8481/head
Edoardo Vacchi 6 months ago
committed by GitHub
parent
commit
a4a4c94538
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 26
      tests/disas/winch/aarch64/f32_abs/f32_abs_const.wat
  2. 25
      tests/disas/winch/aarch64/f32_abs/f32_abs_param.wat
  3. 26
      tests/disas/winch/aarch64/f32_ceil/f32_ceil_const.wat
  4. 25
      tests/disas/winch/aarch64/f32_ceil/f32_ceil_param.wat
  5. 26
      tests/disas/winch/aarch64/f32_floor/f32_floor_const.wat
  6. 25
      tests/disas/winch/aarch64/f32_floor/f32_floor_param.wat
  7. 26
      tests/disas/winch/aarch64/f32_nearest/f32_nearest_const.wat
  8. 25
      tests/disas/winch/aarch64/f32_nearest/f32_nearest_param.wat
  9. 26
      tests/disas/winch/aarch64/f32_neg/f32_neg_const.wat
  10. 25
      tests/disas/winch/aarch64/f32_neg/f32_neg_param.wat
  11. 26
      tests/disas/winch/aarch64/f32_sqrt/f32_sqrt_const.wat
  12. 25
      tests/disas/winch/aarch64/f32_sqrt/f32_sqrt_param.wat
  13. 26
      tests/disas/winch/aarch64/f32_trunc/f32_trunc_const.wat
  14. 25
      tests/disas/winch/aarch64/f32_trunc/f32_trunc_param.wat
  15. 28
      tests/disas/winch/aarch64/f64_abs/f64_abs_const.wat
  16. 25
      tests/disas/winch/aarch64/f64_abs/f64_abs_param.wat
  17. 28
      tests/disas/winch/aarch64/f64_ceil/f64_ceil_const.wat
  18. 25
      tests/disas/winch/aarch64/f64_ceil/f64_ceil_param.wat
  19. 28
      tests/disas/winch/aarch64/f64_floor/f64_floor_const.wat
  20. 25
      tests/disas/winch/aarch64/f64_floor/f64_floor_param.wat
  21. 28
      tests/disas/winch/aarch64/f64_nearest/f64_nearest_const.wat
  22. 25
      tests/disas/winch/aarch64/f64_nearest/f64_nearest_param.wat
  23. 28
      tests/disas/winch/aarch64/f64_neg/f64_neg_const.wat
  24. 25
      tests/disas/winch/aarch64/f64_neg/f64_neg_param.wat
  25. 28
      tests/disas/winch/aarch64/f64_sqrt/f64_sqrt_const.wat
  26. 25
      tests/disas/winch/aarch64/f64_sqrt/f64_sqrt_param.wat
  27. 28
      tests/disas/winch/aarch64/f64_trunc/f64_trunc_const.wat
  28. 25
      tests/disas/winch/aarch64/f64_trunc/f64_trunc_param.wat
  29. 51
      winch/codegen/src/isa/aarch64/asm.rs
  30. 22
      winch/codegen/src/isa/aarch64/masm.rs
  31. 1
      winch/codegen/src/masm.rs

26
tests/disas/winch/aarch64/f32_abs/f32_abs_const.wat

@ -0,0 +1,26 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result f32)
(f32.const -1.32)
(f32.abs)
)
)
;; 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, #0xf5c3
;; movk w16, #0xbfa8, lsl #16
;; fmov s0, w16
;; fabs s0, s0
;; add sp, sp, #0x10
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

25
tests/disas/winch/aarch64/f32_abs/f32_abs_param.wat

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

26
tests/disas/winch/aarch64/f32_ceil/f32_ceil_const.wat

@ -0,0 +1,26 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result f32)
(f32.const -1.32)
(f32.ceil)
)
)
;; 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, #0xf5c3
;; movk w16, #0xbfa8, lsl #16
;; fmov s0, w16
;; frintp s0, s0
;; add sp, sp, #0x10
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

25
tests/disas/winch/aarch64/f32_ceil/f32_ceil_param.wat

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

26
tests/disas/winch/aarch64/f32_floor/f32_floor_const.wat

@ -0,0 +1,26 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result f32)
(f32.const -1.32)
(f32.floor)
)
)
;; 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, #0xf5c3
;; movk w16, #0xbfa8, lsl #16
;; fmov s0, w16
;; frintm s0, s0
;; add sp, sp, #0x10
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

25
tests/disas/winch/aarch64/f32_floor/f32_floor_param.wat

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

26
tests/disas/winch/aarch64/f32_nearest/f32_nearest_const.wat

@ -0,0 +1,26 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result f32)
(f32.const -1.32)
(f32.nearest)
)
)
;; 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, #0xf5c3
;; movk w16, #0xbfa8, lsl #16
;; fmov s0, w16
;; frintn s0, s0
;; add sp, sp, #0x10
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

25
tests/disas/winch/aarch64/f32_nearest/f32_nearest_param.wat

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

26
tests/disas/winch/aarch64/f32_neg/f32_neg_const.wat

@ -0,0 +1,26 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result f32)
(f32.const -1.32)
(f32.neg)
)
)
;; 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, #0xf5c3
;; movk w16, #0xbfa8, lsl #16
;; fmov s0, w16
;; fneg s0, s0
;; add sp, sp, #0x10
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

25
tests/disas/winch/aarch64/f32_neg/f32_neg_param.wat

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

26
tests/disas/winch/aarch64/f32_sqrt/f32_sqrt_const.wat

@ -0,0 +1,26 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result f32)
(f32.const 1.32)
(f32.sqrt)
)
)
;; 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, #0xf5c3
;; movk w16, #0x3fa8, lsl #16
;; fmov s0, w16
;; fsqrt s0, s0
;; add sp, sp, #0x10
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

25
tests/disas/winch/aarch64/f32_sqrt/f32_sqrt_param.wat

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

26
tests/disas/winch/aarch64/f32_trunc/f32_trunc_const.wat

@ -0,0 +1,26 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result f32)
(f32.const -1.32)
(f32.trunc)
)
)
;; 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, #0xf5c3
;; movk w16, #0xbfa8, lsl #16
;; fmov s0, w16
;; frintz s0, s0
;; add sp, sp, #0x10
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

25
tests/disas/winch/aarch64/f32_trunc/f32_trunc_param.wat

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

28
tests/disas/winch/aarch64/f64_abs/f64_abs_const.wat

@ -0,0 +1,28 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result f64)
(f64.const -1.32)
(f64.abs)
)
)
;; 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, #0x851f
;; movk x16, #0x51eb, lsl #16
;; movk x16, #0x1eb8, lsl #32
;; movk x16, #0xbff5, lsl #48
;; fmov d0, x16
;; fabs d0, d0
;; add sp, sp, #0x10
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

25
tests/disas/winch/aarch64/f64_abs/f64_abs_param.wat

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

28
tests/disas/winch/aarch64/f64_ceil/f64_ceil_const.wat

@ -0,0 +1,28 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result f64)
(f64.const -1.32)
(f64.ceil)
)
)
;; 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, #0x851f
;; movk x16, #0x51eb, lsl #16
;; movk x16, #0x1eb8, lsl #32
;; movk x16, #0xbff5, lsl #48
;; fmov d0, x16
;; frintp d0, d0
;; add sp, sp, #0x10
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

25
tests/disas/winch/aarch64/f64_ceil/f64_ceil_param.wat

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

28
tests/disas/winch/aarch64/f64_floor/f64_floor_const.wat

@ -0,0 +1,28 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result f64)
(f64.const -1.32)
(f64.floor)
)
)
;; 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, #0x851f
;; movk x16, #0x51eb, lsl #16
;; movk x16, #0x1eb8, lsl #32
;; movk x16, #0xbff5, lsl #48
;; fmov d0, x16
;; frintm d0, d0
;; add sp, sp, #0x10
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

25
tests/disas/winch/aarch64/f64_floor/f64_floor_param.wat

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

28
tests/disas/winch/aarch64/f64_nearest/f64_nearest_const.wat

@ -0,0 +1,28 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result f64)
(f64.const -1.32)
(f64.nearest)
)
)
;; 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, #0x851f
;; movk x16, #0x51eb, lsl #16
;; movk x16, #0x1eb8, lsl #32
;; movk x16, #0xbff5, lsl #48
;; fmov d0, x16
;; frintn d0, d0
;; add sp, sp, #0x10
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

25
tests/disas/winch/aarch64/f64_nearest/f64_nearest_param.wat

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

28
tests/disas/winch/aarch64/f64_neg/f64_neg_const.wat

@ -0,0 +1,28 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result f64)
(f64.const -1.32)
(f64.neg)
)
)
;; 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, #0x851f
;; movk x16, #0x51eb, lsl #16
;; movk x16, #0x1eb8, lsl #32
;; movk x16, #0xbff5, lsl #48
;; fmov d0, x16
;; fneg d0, d0
;; add sp, sp, #0x10
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

25
tests/disas/winch/aarch64/f64_neg/f64_neg_param.wat

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

28
tests/disas/winch/aarch64/f64_sqrt/f64_sqrt_const.wat

@ -0,0 +1,28 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result f64)
(f64.const 1.32)
(f64.sqrt)
)
)
;; 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, #0x851f
;; movk x16, #0x51eb, lsl #16
;; movk x16, #0x1eb8, lsl #32
;; movk x16, #0x3ff5, lsl #48
;; fmov d0, x16
;; fsqrt d0, d0
;; add sp, sp, #0x10
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

25
tests/disas/winch/aarch64/f64_sqrt/f64_sqrt_param.wat

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

28
tests/disas/winch/aarch64/f64_trunc/f64_trunc_const.wat

@ -0,0 +1,28 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result f64)
(f64.const -1.32)
(f64.trunc)
)
)
;; 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, #0x851f
;; movk x16, #0x51eb, lsl #16
;; movk x16, #0x1eb8, lsl #32
;; movk x16, #0xbff5, lsl #48
;; fmov d0, x16
;; frintz d0, d0
;; add sp, sp, #0x10
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

25
tests/disas/winch/aarch64/f64_trunc/f64_trunc_param.wat

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

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

@ -1,8 +1,9 @@
//! Assembler library implementation for Aarch64. //! Assembler library implementation for Aarch64.
use super::{address::Address, regs}; use super::{address::Address, regs};
use crate::masm::RoundingMode;
use crate::{masm::OperandSize, reg::Reg}; use crate::{masm::OperandSize, reg::Reg};
use cranelift_codegen::isa::aarch64::inst::{FPUOp2, ScalarSize}; use cranelift_codegen::isa::aarch64::inst::{FPUOp1, FPUOp2, FpuRoundMode, ScalarSize};
use cranelift_codegen::{ use cranelift_codegen::{
ir::{MemFlags, SourceLoc}, ir::{MemFlags, SourceLoc},
isa::aarch64::inst::{ isa::aarch64::inst::{
@ -264,6 +265,37 @@ impl Assembler {
self.emit_fpu_rrr(FPUOp2::Min, rm, rn, rd, size); self.emit_fpu_rrr(FPUOp2::Min, rm, rn, rd, size);
} }
/// Float neg with two registers.
pub fn fneg_rr(&mut self, rn: Reg, rd: Reg, size: OperandSize) {
self.emit_fpu_rr(FPUOp1::Neg, rn, rd, size);
}
/// Float abs with two registers.
pub fn fabs_rr(&mut self, rn: Reg, rd: Reg, size: OperandSize) {
self.emit_fpu_rr(FPUOp1::Abs, rn, rd, size);
}
/// Float sqrt with two registers.
pub fn fsqrt_rr(&mut self, rn: Reg, rd: Reg, size: OperandSize) {
self.emit_fpu_rr(FPUOp1::Sqrt, rn, rd, size);
}
/// Float round (ceil, trunc, floor) with two registers.
pub fn fround_rr(&mut self, rn: Reg, rd: Reg, mode: RoundingMode, size: OperandSize) {
let fpu_mode = match (mode, size) {
(RoundingMode::Nearest, OperandSize::S32) => FpuRoundMode::Nearest32,
(RoundingMode::Up, OperandSize::S32) => FpuRoundMode::Plus32,
(RoundingMode::Down, OperandSize::S32) => FpuRoundMode::Minus32,
(RoundingMode::Zero, OperandSize::S32) => FpuRoundMode::Zero32,
(RoundingMode::Nearest, OperandSize::S64) => FpuRoundMode::Nearest64,
(RoundingMode::Up, OperandSize::S64) => FpuRoundMode::Plus64,
(RoundingMode::Down, OperandSize::S64) => FpuRoundMode::Minus64,
(RoundingMode::Zero, OperandSize::S64) => FpuRoundMode::Zero64,
(m, o) => panic!("Invalid rounding mode or operand size {:?}, {:?}", m, o),
};
self.emit_fpu_round(fpu_mode, rn, rd)
}
/// Return instruction. /// Return instruction.
pub fn ret(&mut self) { pub fn ret(&mut self) {
self.emit(Inst::Ret {}); self.emit(Inst::Ret {});
@ -313,6 +345,23 @@ impl Assembler {
}); });
} }
fn emit_fpu_rr(&mut self, op: FPUOp1, rn: Reg, rd: Reg, size: OperandSize) {
self.emit(Inst::FpuRR {
fpu_op: op,
size: size.into(),
rd: Writable::from_reg(rd.into()),
rn: rn.into(),
});
}
fn emit_fpu_round(&mut self, op: FpuRoundMode, rn: Reg, rd: Reg) {
self.emit(Inst::FpuRound {
op: op,
rd: Writable::from_reg(rd.into()),
rn: rn.into(),
});
}
/// Get a label from the underlying machine code buffer. /// Get a label from the underlying machine code buffer.
pub fn get_label(&mut self) -> MachLabel { pub fn get_label(&mut self) -> MachLabel {
self.buffer.get_label() self.buffer.get_label()

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

@ -316,27 +316,29 @@ impl Masm for MacroAssembler {
todo!() todo!()
} }
fn float_neg(&mut self, _dst: Reg, _size: OperandSize) { fn float_neg(&mut self, dst: Reg, size: OperandSize) {
todo!() self.asm.fneg_rr(dst, dst, size);
} }
fn float_abs(&mut self, _dst: Reg, _size: OperandSize) { fn float_abs(&mut self, dst: Reg, size: OperandSize) {
todo!() self.asm.fabs_rr(dst, dst, size);
} }
fn float_round<F: FnMut(&mut FuncEnv<Self::Ptr>, &mut CodeGenContext, &mut Self)>( fn float_round<F: FnMut(&mut FuncEnv<Self::Ptr>, &mut CodeGenContext, &mut Self)>(
&mut self, &mut self,
_mode: RoundingMode, mode: RoundingMode,
_env: &mut FuncEnv<Self::Ptr>, _env: &mut FuncEnv<Self::Ptr>,
_context: &mut CodeGenContext, context: &mut CodeGenContext,
_size: OperandSize, size: OperandSize,
_fallback: F, _fallback: F,
) { ) {
todo!(); let src = context.pop_to_reg(self, None);
self.asm.fround_rr(src.into(), src.into(), mode, size);
context.stack.push(src.into());
} }
fn float_sqrt(&mut self, _dst: Reg, _src: Reg, _size: OperandSize) { fn float_sqrt(&mut self, dst: Reg, src: Reg, size: OperandSize) {
todo!() self.asm.fsqrt_rr(src, dst, size);
} }
fn and(&mut self, _dst: Reg, _lhs: Reg, _rhs: RegImm, _size: OperandSize) { fn and(&mut self, _dst: Reg, _lhs: Reg, _rhs: RegImm, _size: OperandSize) {

1
winch/codegen/src/masm.rs

@ -425,6 +425,7 @@ impl From<Reg> for RegImm {
} }
} }
#[derive(Debug)]
pub enum RoundingMode { pub enum RoundingMode {
Nearest, Nearest,
Up, Up,

Loading…
Cancel
Save