Browse Source

winch(arm64): and, or, xor, shifts (#8921)

* winch(arm64): and, or, xor, shifts

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

* fmt

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

* docs

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

* shift

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

* shifts: test cases

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

* cleanup

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

* apply first batch of suggestions

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

* refactor shift operations

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

* fix doc strings

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

* Minor cleanups

This commit includes very minor clean-ups, these are mechanical changes
only.

* Rename `shift_rr` to `shift`, as we're still passing the context in,
  the callee can decide what to do with the instruction arguments.

* Delete the un-used `Into<AluOp> for ShiftKind`

---------

Signed-off-by: Edoardo Vacchi <evacchi@users.noreply.github.com>
Co-authored-by: Saúl Cabrera <saulecabrera@gmail.com>
pull/8756/head
Edoardo Vacchi 4 months ago
committed by GitHub
parent
commit
c69ab340ca
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 26
      tests/disas/winch/aarch64/i32_and/const.wat
  2. 44
      tests/disas/winch/aarch64/i32_and/locals.wat
  3. 29
      tests/disas/winch/aarch64/i32_and/params.wat
  4. 26
      tests/disas/winch/aarch64/i32_or/const.wat
  5. 44
      tests/disas/winch/aarch64/i32_or/locals.wat
  6. 29
      tests/disas/winch/aarch64/i32_or/params.wat
  7. 28
      tests/disas/winch/aarch64/i32_rotl/16_const.wat
  8. 27
      tests/disas/winch/aarch64/i32_rotl/8_const.wat
  9. 45
      tests/disas/winch/aarch64/i32_rotl/locals.wat
  10. 30
      tests/disas/winch/aarch64/i32_rotl/params.wat
  11. 27
      tests/disas/winch/aarch64/i32_rotr/16_const.wat
  12. 26
      tests/disas/winch/aarch64/i32_rotr/8_const.wat
  13. 44
      tests/disas/winch/aarch64/i32_rotr/locals.wat
  14. 29
      tests/disas/winch/aarch64/i32_rotr/params.wat
  15. 28
      tests/disas/winch/aarch64/i32_shl/16_const.wat
  16. 27
      tests/disas/winch/aarch64/i32_shl/8_const.wat
  17. 44
      tests/disas/winch/aarch64/i32_shl/locals.wat
  18. 29
      tests/disas/winch/aarch64/i32_shl/params.wat
  19. 27
      tests/disas/winch/aarch64/i32_shr_s/16_const.wat
  20. 26
      tests/disas/winch/aarch64/i32_shr_s/8_const.wat
  21. 44
      tests/disas/winch/aarch64/i32_shr_s/locals.wat
  22. 29
      tests/disas/winch/aarch64/i32_shr_s/params.wat
  23. 27
      tests/disas/winch/aarch64/i32_shr_u/16_const.wat
  24. 26
      tests/disas/winch/aarch64/i32_shr_u/8_const.wat
  25. 44
      tests/disas/winch/aarch64/i32_shr_u/locals.wat
  26. 29
      tests/disas/winch/aarch64/i32_shr_u/params.wat
  27. 26
      tests/disas/winch/aarch64/i32_xor/const.wat
  28. 44
      tests/disas/winch/aarch64/i32_xor/locals.wat
  29. 29
      tests/disas/winch/aarch64/i32_xor/params.wat
  30. 26
      tests/disas/winch/aarch64/i64_and/32_const.wat
  31. 26
      tests/disas/winch/aarch64/i64_and/64_const.wat
  32. 44
      tests/disas/winch/aarch64/i64_and/locals.wat
  33. 29
      tests/disas/winch/aarch64/i64_and/params.wat
  34. 26
      tests/disas/winch/aarch64/i64_or/32_const.wat
  35. 26
      tests/disas/winch/aarch64/i64_or/64_const.wat
  36. 44
      tests/disas/winch/aarch64/i64_or/locals.wat
  37. 29
      tests/disas/winch/aarch64/i64_or/params.wat
  38. 28
      tests/disas/winch/aarch64/i64_rotl/16_const.wat
  39. 27
      tests/disas/winch/aarch64/i64_rotl/8_const.wat
  40. 46
      tests/disas/winch/aarch64/i64_rotl/locals.wat
  41. 30
      tests/disas/winch/aarch64/i64_rotl/params.wat
  42. 27
      tests/disas/winch/aarch64/i64_rotr/16_const.wat
  43. 26
      tests/disas/winch/aarch64/i64_rotr/8_const.wat
  44. 45
      tests/disas/winch/aarch64/i64_rotr/locals.wat
  45. 29
      tests/disas/winch/aarch64/i64_rotr/params.wat
  46. 27
      tests/disas/winch/aarch64/i64_shl/16_const.wat
  47. 26
      tests/disas/winch/aarch64/i64_shl/8_const.wat
  48. 45
      tests/disas/winch/aarch64/i64_shl/locals.wat
  49. 29
      tests/disas/winch/aarch64/i64_shl/params.wat
  50. 27
      tests/disas/winch/aarch64/i64_shr_s/16_const.wat
  51. 26
      tests/disas/winch/aarch64/i64_shr_s/8_const.wat
  52. 45
      tests/disas/winch/aarch64/i64_shr_s/locals.wat
  53. 29
      tests/disas/winch/aarch64/i64_shr_s/params.wat
  54. 27
      tests/disas/winch/aarch64/i64_shr_u/16_const.wat
  55. 26
      tests/disas/winch/aarch64/i64_shr_u/8_const.wat
  56. 45
      tests/disas/winch/aarch64/i64_shr_u/locals.wat
  57. 29
      tests/disas/winch/aarch64/i64_shr_u/params.wat
  58. 26
      tests/disas/winch/aarch64/i64_xor/32_const.wat
  59. 26
      tests/disas/winch/aarch64/i64_xor/64_const.wat
  60. 44
      tests/disas/winch/aarch64/i64_xor/locals.wat
  61. 29
      tests/disas/winch/aarch64/i64_xor/params.wat
  62. 53
      winch/codegen/src/codegen/context.rs
  63. 29
      winch/codegen/src/codegen/mod.rs
  64. 140
      winch/codegen/src/isa/aarch64/asm.rs
  65. 69
      winch/codegen/src/isa/aarch64/masm.rs
  66. 41
      winch/codegen/src/isa/x64/masm.rs
  67. 8
      winch/codegen/src/masm.rs
  68. 30
      winch/codegen/src/visitor.rs

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

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

44
tests/disas/winch/aarch64/i32_and/locals.wat

@ -0,0 +1,44 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result i32)
(local $foo i32)
(local $bar i32)
(i32.const 1)
(local.set $foo)
(i32.const 2)
(local.set $bar)
(local.get $foo)
(local.get $bar)
(i32.and)
)
)
;; 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, #1
;; mov w0, w16
;; stur w0, [x28, #4]
;; mov x16, #2
;; mov w0, w16
;; stur w0, [x28]
;; ldur w0, [x28]
;; ldur w1, [x28, #4]
;; and w1, w1, w0
;; mov w0, w1
;; add sp, sp, #0x18
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

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

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

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

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

44
tests/disas/winch/aarch64/i32_or/locals.wat

@ -0,0 +1,44 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result i32)
(local $foo i32)
(local $bar i32)
(i32.const 1)
(local.set $foo)
(i32.const 2)
(local.set $bar)
(local.get $foo)
(local.get $bar)
(i32.or)
)
)
;; 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, #1
;; mov w0, w16
;; stur w0, [x28, #4]
;; mov x16, #2
;; mov w0, w16
;; stur w0, [x28]
;; ldur w0, [x28]
;; ldur w1, [x28, #4]
;; orr w1, w1, w0
;; mov w0, w1
;; add sp, sp, #0x18
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

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

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

28
tests/disas/winch/aarch64/i32_rotl/16_const.wat

@ -0,0 +1,28 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result i32)
(i32.const 1)
(i32.const 512)
(i32.rotl)
)
)
;; 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, #1
;; mov w0, w16
;; sub w0, w0, wzr
;; mov x16, #0x200
;; ror w0, w0, w16
;; add sp, sp, #0x10
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

27
tests/disas/winch/aarch64/i32_rotl/8_const.wat

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

45
tests/disas/winch/aarch64/i32_rotl/locals.wat

@ -0,0 +1,45 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result i32)
(local $foo i32)
(local $bar i32)
(i32.const 1)
(local.set $foo)
(i32.const 2)
(local.set $bar)
(local.get $foo)
(local.get $bar)
(i32.rotl)
)
)
;; 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, #1
;; mov w0, w16
;; stur w0, [x28, #4]
;; mov x16, #2
;; mov w0, w16
;; stur w0, [x28]
;; ldur w0, [x28]
;; ldur w1, [x28, #4]
;; sub w0, w0, wzr
;; ror w1, w1, w0
;; mov w0, w1
;; add sp, sp, #0x18
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

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

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

27
tests/disas/winch/aarch64/i32_rotr/16_const.wat

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

26
tests/disas/winch/aarch64/i32_rotr/8_const.wat

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

44
tests/disas/winch/aarch64/i32_rotr/locals.wat

@ -0,0 +1,44 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result i32)
(local $foo i32)
(local $bar i32)
(i32.const 1)
(local.set $foo)
(i32.const 2)
(local.set $bar)
(local.get $foo)
(local.get $bar)
(i32.rotr)
)
)
;; 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, #1
;; mov w0, w16
;; stur w0, [x28, #4]
;; mov x16, #2
;; mov w0, w16
;; stur w0, [x28]
;; ldur w0, [x28]
;; ldur w1, [x28, #4]
;; ror w1, w1, w0
;; mov w0, w1
;; add sp, sp, #0x18
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

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

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

28
tests/disas/winch/aarch64/i32_shl/16_const.wat

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

27
tests/disas/winch/aarch64/i32_shl/8_const.wat

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

44
tests/disas/winch/aarch64/i32_shl/locals.wat

@ -0,0 +1,44 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result i32)
(local $foo i32)
(local $bar i32)
(i32.const 1)
(local.set $foo)
(i32.const 2)
(local.set $bar)
(local.get $foo)
(local.get $bar)
(i32.shl)
)
)
;; 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, #1
;; mov w0, w16
;; stur w0, [x28, #4]
;; mov x16, #2
;; mov w0, w16
;; stur w0, [x28]
;; ldur w0, [x28]
;; ldur w1, [x28, #4]
;; lsl w1, w1, w0
;; mov w0, w1
;; add sp, sp, #0x18
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

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

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

27
tests/disas/winch/aarch64/i32_shr_s/16_const.wat

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

26
tests/disas/winch/aarch64/i32_shr_s/8_const.wat

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

44
tests/disas/winch/aarch64/i32_shr_s/locals.wat

@ -0,0 +1,44 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result i32)
(local $foo i32)
(local $bar i32)
(i32.const 1)
(local.set $foo)
(i32.const 2)
(local.set $bar)
(local.get $foo)
(local.get $bar)
(i32.shr_s)
)
)
;; 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, #1
;; mov w0, w16
;; stur w0, [x28, #4]
;; mov x16, #2
;; mov w0, w16
;; stur w0, [x28]
;; ldur w0, [x28]
;; ldur w1, [x28, #4]
;; asr w1, w1, w0
;; mov w0, w1
;; add sp, sp, #0x18
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

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

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

27
tests/disas/winch/aarch64/i32_shr_u/16_const.wat

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

26
tests/disas/winch/aarch64/i32_shr_u/8_const.wat

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

44
tests/disas/winch/aarch64/i32_shr_u/locals.wat

@ -0,0 +1,44 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result i32)
(local $foo i32)
(local $bar i32)
(i32.const 1)
(local.set $foo)
(i32.const 2)
(local.set $bar)
(local.get $foo)
(local.get $bar)
(i32.shr_u)
)
)
;; 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, #1
;; mov w0, w16
;; stur w0, [x28, #4]
;; mov x16, #2
;; mov w0, w16
;; stur w0, [x28]
;; ldur w0, [x28]
;; ldur w1, [x28, #4]
;; lsr w1, w1, w0
;; mov w0, w1
;; add sp, sp, #0x18
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

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

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

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

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

44
tests/disas/winch/aarch64/i32_xor/locals.wat

@ -0,0 +1,44 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result i32)
(local $foo i32)
(local $bar i32)
(i32.const 1)
(local.set $foo)
(i32.const 2)
(local.set $bar)
(local.get $foo)
(local.get $bar)
(i32.xor)
)
)
;; 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, #1
;; mov w0, w16
;; stur w0, [x28, #4]
;; mov x16, #2
;; mov w0, w16
;; stur w0, [x28]
;; ldur w0, [x28]
;; ldur w1, [x28, #4]
;; eor w1, w1, w0
;; mov w0, w1
;; add sp, sp, #0x18
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

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

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

26
tests/disas/winch/aarch64/i64_and/32_const.wat

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

26
tests/disas/winch/aarch64/i64_and/64_const.wat

@ -0,0 +1,26 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result i64)
(i64.const 9223372036854775806)
(i64.const 9223372036854775807)
(i64.and)
)
)
;; 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]
;; orr x16, xzr, #0x7ffffffffffffffe
;; mov x0, x16
;; and x0, x0, #0x7fffffffffffffff
;; add sp, sp, #0x10
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

44
tests/disas/winch/aarch64/i64_and/locals.wat

@ -0,0 +1,44 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result i64)
(local $foo i64)
(local $bar i64)
(i64.const 2)
(local.set $foo)
(i64.const 3)
(local.set $bar)
(local.get $foo)
(local.get $bar)
(i64.and)
)
)
;; 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, #2
;; mov x0, x16
;; stur x0, [x28, #8]
;; mov x16, #3
;; mov x0, x16
;; stur x0, [x28]
;; ldur x0, [x28]
;; ldur x1, [x28, #8]
;; and x1, x1, x0
;; mov x0, x1
;; add sp, sp, #0x20
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

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

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

26
tests/disas/winch/aarch64/i64_or/32_const.wat

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

26
tests/disas/winch/aarch64/i64_or/64_const.wat

@ -0,0 +1,26 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result i64)
(i64.const 9223372036854775806)
(i64.const 9223372036854775807)
(i64.or)
)
)
;; 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]
;; orr x16, xzr, #0x7ffffffffffffffe
;; mov x0, x16
;; orr x0, x0, #0x7fffffffffffffff
;; add sp, sp, #0x10
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

44
tests/disas/winch/aarch64/i64_or/locals.wat

@ -0,0 +1,44 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result i64)
(local $foo i64)
(local $bar i64)
(i64.const 2)
(local.set $foo)
(i64.const 3)
(local.set $bar)
(local.get $foo)
(local.get $bar)
(i64.or)
)
)
;; 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, #2
;; mov x0, x16
;; stur x0, [x28, #8]
;; mov x16, #3
;; mov x0, x16
;; stur x0, [x28]
;; ldur x0, [x28]
;; ldur x1, [x28, #8]
;; orr x1, x1, x0
;; mov x0, x1
;; add sp, sp, #0x20
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

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

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

28
tests/disas/winch/aarch64/i64_rotl/16_const.wat

@ -0,0 +1,28 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result i64)
(i64.const 1)
(i64.const 512)
(i64.rotl)
)
)
;; 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, #1
;; mov x0, x16
;; sub x0, x0, xzr
;; mov x16, #0x200
;; ror x0, x0, x16
;; add sp, sp, #0x10
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

27
tests/disas/winch/aarch64/i64_rotl/8_const.wat

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

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

@ -0,0 +1,46 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result i64)
(local $foo i64)
(local $bar i64)
(i64.const 1)
(local.set $foo)
(i64.const 2)
(local.set $bar)
(local.get $foo)
(local.get $bar)
(i64.rotl)
)
)
;; 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, #1
;; mov x0, x16
;; stur x0, [x28, #8]
;; mov x16, #2
;; mov x0, x16
;; stur x0, [x28]
;; ldur x0, [x28]
;; ldur x1, [x28, #8]
;; sub x0, x0, xzr
;; ror x1, x1, x0
;; mov x0, x1
;; add sp, sp, #0x20
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

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

@ -0,0 +1,30 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (param i64) (param i64) (result i64)
(local.get 0)
(local.get 1)
(i64.rotl)
)
)
;; 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 x2, [x28, #8]
;; stur x3, [x28]
;; ldur x0, [x28]
;; ldur x1, [x28, #8]
;; sub x0, x0, xzr
;; ror x1, x1, x0
;; mov x0, x1
;; add sp, sp, #0x20
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

27
tests/disas/winch/aarch64/i64_rotr/16_const.wat

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

26
tests/disas/winch/aarch64/i64_rotr/8_const.wat

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

45
tests/disas/winch/aarch64/i64_rotr/locals.wat

@ -0,0 +1,45 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result i64)
(local $foo i64)
(local $bar i64)
(i64.const 1)
(local.set $foo)
(i64.const 2)
(local.set $bar)
(local.get $foo)
(local.get $bar)
(i64.rotr)
)
)
;; 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, #1
;; mov x0, x16
;; stur x0, [x28, #8]
;; mov x16, #2
;; mov x0, x16
;; stur x0, [x28]
;; ldur x0, [x28]
;; ldur x1, [x28, #8]
;; ror x1, x1, x0
;; mov x0, x1
;; add sp, sp, #0x20
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

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

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

27
tests/disas/winch/aarch64/i64_shl/16_const.wat

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

26
tests/disas/winch/aarch64/i64_shl/8_const.wat

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

45
tests/disas/winch/aarch64/i64_shl/locals.wat

@ -0,0 +1,45 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result i64)
(local $foo i64)
(local $bar i64)
(i64.const 1)
(local.set $foo)
(i64.const 2)
(local.set $bar)
(local.get $foo)
(local.get $bar)
(i64.shl)
)
)
;; 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, #1
;; mov x0, x16
;; stur x0, [x28, #8]
;; mov x16, #2
;; mov x0, x16
;; stur x0, [x28]
;; ldur x0, [x28]
;; ldur x1, [x28, #8]
;; lsl x1, x1, x0
;; mov x0, x1
;; add sp, sp, #0x20
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

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

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

27
tests/disas/winch/aarch64/i64_shr_s/16_const.wat

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

26
tests/disas/winch/aarch64/i64_shr_s/8_const.wat

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

45
tests/disas/winch/aarch64/i64_shr_s/locals.wat

@ -0,0 +1,45 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result i64)
(local $foo i64)
(local $bar i64)
(i64.const 1)
(local.set $foo)
(i64.const 2)
(local.set $bar)
(local.get $foo)
(local.get $bar)
(i64.shr_s)
)
)
;; 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, #1
;; mov x0, x16
;; stur x0, [x28, #8]
;; mov x16, #2
;; mov x0, x16
;; stur x0, [x28]
;; ldur x0, [x28]
;; ldur x1, [x28, #8]
;; asr x1, x1, x0
;; mov x0, x1
;; add sp, sp, #0x20
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

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

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

27
tests/disas/winch/aarch64/i64_shr_u/16_const.wat

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

26
tests/disas/winch/aarch64/i64_shr_u/8_const.wat

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

45
tests/disas/winch/aarch64/i64_shr_u/locals.wat

@ -0,0 +1,45 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result i64)
(local $foo i64)
(local $bar i64)
(i64.const 1)
(local.set $foo)
(i64.const 2)
(local.set $bar)
(local.get $foo)
(local.get $bar)
(i64.shr_u)
)
)
;; 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, #1
;; mov x0, x16
;; stur x0, [x28, #8]
;; mov x16, #2
;; mov x0, x16
;; stur x0, [x28]
;; ldur x0, [x28]
;; ldur x1, [x28, #8]
;; lsr x1, x1, x0
;; mov x0, x1
;; add sp, sp, #0x20
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

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

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

26
tests/disas/winch/aarch64/i64_xor/32_const.wat

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

26
tests/disas/winch/aarch64/i64_xor/64_const.wat

@ -0,0 +1,26 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result i64)
(i64.const 9223372036854775806)
(i64.const 9223372036854775807)
(i64.xor)
)
)
;; 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]
;; orr x16, xzr, #0x7ffffffffffffffe
;; mov x0, x16
;; eor x0, x0, #0x7fffffffffffffff
;; add sp, sp, #0x10
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

44
tests/disas/winch/aarch64/i64_xor/locals.wat

@ -0,0 +1,44 @@
;;! target = "aarch64"
;;! test = "winch"
(module
(func (result i64)
(local $foo i64)
(local $bar i64)
(i64.const 2)
(local.set $foo)
(i64.const 3)
(local.set $bar)
(local.get $foo)
(local.get $bar)
(i64.xor)
)
)
;; 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, #2
;; mov x0, x16
;; stur x0, [x28, #8]
;; mov x16, #3
;; mov x0, x16
;; stur x0, [x28]
;; ldur x0, [x28]
;; ldur x1, [x28, #8]
;; eor x1, x1, x0
;; mov x0, x1
;; add sp, sp, #0x20
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret

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

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

53
winch/codegen/src/codegen/context.rs

@ -5,7 +5,7 @@ use crate::{
abi::{vmctx, ABIOperand, ABIResults, RetArea, ABI},
frame::Frame,
isa::reg::RegClass,
masm::{MacroAssembler, OperandSize, RegImm, SPOffset, StackSlot},
masm::{MacroAssembler, OperandSize, RegImm, SPOffset, ShiftKind, StackSlot},
reg::Reg,
regalloc::RegAlloc,
stack::{Stack, TypedReg, Val},
@ -319,6 +319,57 @@ impl<'a> CodeGenContext<'a> {
};
}
/// Prepares arguments for emitting an i32 shift operation.
pub fn i32_shift<M>(&mut self, masm: &mut M, kind: ShiftKind)
where
M: MacroAssembler,
{
let top = self.stack.peek().expect("value at stack top");
if top.is_i32_const() {
let val = self
.stack
.pop_i32_const()
.expect("i32 const value at stack top");
let typed_reg = self.pop_to_reg(masm, None);
masm.shift_ir(
typed_reg.reg,
val as u64,
typed_reg.reg,
kind,
OperandSize::S32,
);
self.stack.push(typed_reg.into());
} else {
masm.shift(self, kind, OperandSize::S32);
}
}
/// Prepares arguments for emitting an i64 binary operation.
pub fn i64_shift<M>(&mut self, masm: &mut M, kind: ShiftKind)
where
M: MacroAssembler,
{
let top = self.stack.peek().expect("value at stack top");
if top.is_i64_const() {
let val = self
.stack
.pop_i64_const()
.expect("i64 const value at stack top");
let typed_reg = self.pop_to_reg(masm, None);
masm.shift_ir(
typed_reg.reg,
val as u64,
typed_reg.reg,
kind,
OperandSize::S64,
);
self.stack.push(typed_reg.into());
} else {
masm.shift(self, kind, OperandSize::S64);
};
}
/// Prepares arguments for emitting a convert operation.
pub fn convert_op<F, M>(&mut self, masm: &mut M, dst_ty: WasmValType, mut emit: F)
where

29
winch/codegen/src/codegen/mod.rs

@ -5,7 +5,7 @@ use crate::{
masm::{
ExtendKind, IntCmpKind, MacroAssembler, OperandSize, RegImm, SPOffset, ShiftKind, TrapCode,
},
stack::{TypedReg, Val},
stack::TypedReg,
};
use anyhow::Result;
use smallvec::SmallVec;
@ -848,24 +848,17 @@ where
.masm
.address_at_reg(base, heap_data.current_length_offset);
self.masm.load_ptr(size_addr, size_reg);
// Prepare the stack to emit a shift to get the size in pages rather
// than in bytes.
self.context
.stack
.push(TypedReg::new(heap_data.ty, size_reg).into());
// Emit a shift to get the size in pages rather than in bytes.
let dst = TypedReg::new(heap_data.ty, size_reg);
let pow = heap_data.page_size_log2;
// Ensure that the constant is correctly typed according to the heap
// type to reduce register pressure when emitting the shift operation.
match heap_data.ty {
WasmValType::I32 => self.context.stack.push(Val::i32(i32::from(pow))),
WasmValType::I64 => self.context.stack.push(Val::i64(i64::from(pow))),
_ => unreachable!(),
}
self.masm
.shift(&mut self.context, ShiftKind::ShrU, heap_data.ty.into());
self.masm.shift_ir(
dst.reg,
pow as u64,
dst.into(),
ShiftKind::ShrU,
heap_data.ty.into(),
);
self.context.stack.push(dst.into());
}
}

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

@ -1,12 +1,12 @@
//! Assembler library implementation for Aarch64.
use super::{address::Address, regs};
use crate::masm::RoundingMode;
use crate::masm::{RoundingMode, ShiftKind};
use crate::{masm::OperandSize, reg::Reg};
use cranelift_codegen::isa::aarch64::inst::FPUOpRI::{UShr32, UShr64};
use cranelift_codegen::isa::aarch64::inst::{
FPULeftShiftImm, FPUOp1, FPUOp2, FPUOpRI, FPUOpRIMod, FPURightShiftImm, FpuRoundMode,
ScalarSize,
FPULeftShiftImm, FPUOp1, FPUOp2, FPUOpRI, FPUOpRIMod, FPURightShiftImm, FpuRoundMode, ImmLogic,
ImmShift, ScalarSize,
};
use cranelift_codegen::{
ir::{MemFlags, SourceLoc},
@ -28,6 +28,7 @@ impl From<OperandSize> for inst::OperandSize {
}
}
}
impl Into<ScalarSize> for OperandSize {
fn into(self) -> ScalarSize {
match self {
@ -239,6 +240,79 @@ impl Assembler {
self.emit_alu_rrrr(ALUOp3::MAdd, scratch, rn, rd, regs::zero(), size);
}
/// And with three registers.
pub fn and_rrr(&mut self, rm: Reg, rn: Reg, rd: Reg, size: OperandSize) {
self.emit_alu_rrr(ALUOp::And, rm, rn, rd, size);
}
/// And immediate and register.
pub fn and_ir(&mut self, imm: u64, rn: Reg, rd: Reg, size: OperandSize) {
let alu_op = ALUOp::And;
let cl_size: inst::OperandSize = size.into();
if let Some(imm) = ImmLogic::maybe_from_u64(imm, cl_size.to_ty()) {
self.emit_alu_rri_logic(alu_op, imm, rn, rd, size);
} else {
let scratch = regs::scratch();
self.load_constant(imm, scratch);
self.emit_alu_rrr(alu_op, scratch, rn, rd, size);
}
}
/// Or with three registers.
pub fn or_rrr(&mut self, rm: Reg, rn: Reg, rd: Reg, size: OperandSize) {
self.emit_alu_rrr(ALUOp::Orr, rm, rn, rd, size);
}
/// Or immediate and register.
pub fn or_ir(&mut self, imm: u64, rn: Reg, rd: Reg, size: OperandSize) {
let alu_op = ALUOp::Orr;
let cl_size: inst::OperandSize = size.into();
if let Some(imm) = ImmLogic::maybe_from_u64(imm, cl_size.to_ty()) {
self.emit_alu_rri_logic(alu_op, imm, rn, rd, size);
} else {
let scratch = regs::scratch();
self.load_constant(imm, scratch);
self.emit_alu_rrr(alu_op, scratch, rn, rd, size);
}
}
/// Xor with three registers.
pub fn xor_rrr(&mut self, rm: Reg, rn: Reg, rd: Reg, size: OperandSize) {
self.emit_alu_rrr(ALUOp::Eor, rm, rn, rd, size);
}
/// Xor immediate and register.
pub fn xor_ir(&mut self, imm: u64, rn: Reg, rd: Reg, size: OperandSize) {
let alu_op = ALUOp::Eor;
let cl_size: inst::OperandSize = size.into();
if let Some(imm) = ImmLogic::maybe_from_u64(imm, cl_size.to_ty()) {
self.emit_alu_rri_logic(alu_op, imm, rn, rd, size);
} else {
let scratch = regs::scratch();
self.load_constant(imm, scratch);
self.emit_alu_rrr(alu_op, scratch, rn, rd, size);
}
}
/// Shift with three registers.
pub fn shift_rrr(&mut self, rm: Reg, rn: Reg, rd: Reg, kind: ShiftKind, size: OperandSize) {
let shift_op = self.shift_kind_to_alu_op(kind, rm, size);
self.emit_alu_rrr(shift_op, rm, rn, rd, size);
}
/// Shift immediate and register.
pub fn shift_ir(&mut self, imm: u64, rn: Reg, rd: Reg, kind: ShiftKind, size: OperandSize) {
let shift_op = self.shift_kind_to_alu_op(kind, rn, size);
if let Some(imm) = ImmShift::maybe_from_u64(imm) {
self.emit_alu_rri_shift(shift_op, imm, rn, rd, size);
} else {
let scratch = regs::scratch();
self.load_constant(imm, scratch);
self.emit_alu_rrr(shift_op, scratch, 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);
@ -346,6 +420,50 @@ impl Assembler {
});
}
fn emit_alu_rri_logic(
&mut self,
op: ALUOp,
imm: ImmLogic,
rn: Reg,
rd: Reg,
size: OperandSize,
) {
self.emit(Inst::AluRRImmLogic {
alu_op: op,
size: size.into(),
rd: Writable::from_reg(rd.into()),
rn: rn.into(),
imml: imm,
});
}
fn emit_alu_rri_shift(
&mut self,
op: ALUOp,
imm: ImmShift,
rn: Reg,
rd: Reg,
size: OperandSize,
) {
self.emit(Inst::AluRRImmShift {
alu_op: op,
size: size.into(),
rd: Writable::from_reg(rd.into()),
rn: rn.into(),
immshift: imm,
});
}
fn emit_alu_rrr(&mut self, op: ALUOp, rm: Reg, rn: Reg, rd: Reg, size: OperandSize) {
self.emit(Inst::AluRRR {
alu_op: op,
size: size.into(),
rd: Writable::from_reg(rd.into()),
rn: rn.into(),
rm: rm.into(),
});
}
fn emit_alu_rrr_extend(&mut self, op: ALUOp, rm: Reg, rn: Reg, rd: Reg, size: OperandSize) {
self.emit(Inst::AluRRRExtend {
alu_op: op,
@ -412,6 +530,22 @@ impl Assembler {
});
}
// 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 {
match kind {
ShiftKind::Shl => ALUOp::Lsl,
ShiftKind::ShrS => ALUOp::Asr,
ShiftKind::ShrU => ALUOp::Lsr,
ShiftKind::Rotr => ALUOp::RotR,
ShiftKind::Rotl => {
// neg(r) is sub(zero, r).
self.emit_alu_rrr(ALUOp::Sub, regs::zero(), r, r, size);
ALUOp::RotR
}
}
}
/// Get a label from the underlying machine code buffer.
pub fn get_label(&mut self) -> MachLabel {
self.buffer.get_label()

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

@ -347,20 +347,73 @@ impl Masm for MacroAssembler {
self.asm.fsqrt_rr(src, dst, size);
}
fn and(&mut self, _dst: Reg, _lhs: Reg, _rhs: RegImm, _size: OperandSize) {
todo!()
fn and(&mut self, dst: Reg, lhs: Reg, rhs: RegImm, size: OperandSize) {
match (rhs, lhs, dst) {
(RegImm::Imm(v), rn, rd) => {
let imm = match v {
I::I32(v) => v as u64,
I::I64(v) => v,
_ => unreachable!(),
};
self.asm.and_ir(imm, rn, rd, size);
}
(RegImm::Reg(rm), rn, rd) => {
self.asm.and_rrr(rm, rn, rd, size);
}
}
}
fn or(&mut self, _dst: Reg, _lhs: Reg, _rhs: RegImm, _size: OperandSize) {
todo!()
fn or(&mut self, dst: Reg, lhs: Reg, rhs: RegImm, size: OperandSize) {
match (rhs, lhs, dst) {
(RegImm::Imm(v), rn, rd) => {
let imm = match v {
I::I32(v) => v as u64,
I::I64(v) => v,
_ => unreachable!(),
};
self.asm.or_ir(imm, rn, rd, size);
}
(RegImm::Reg(rm), rn, rd) => {
self.asm.or_rrr(rm, rn, rd, size);
}
}
}
fn xor(&mut self, _dst: Reg, _lhs: Reg, _rhs: RegImm, _size: OperandSize) {
todo!()
fn xor(&mut self, dst: Reg, lhs: Reg, rhs: RegImm, size: OperandSize) {
match (rhs, lhs, dst) {
(RegImm::Imm(v), rn, rd) => {
let imm = match v {
I::I32(v) => v as u64,
I::I64(v) => v,
_ => unreachable!(),
};
self.asm.xor_ir(imm, rn, rd, size);
}
(RegImm::Reg(rm), rn, rd) => {
self.asm.xor_rrr(rm, rn, rd, size);
}
}
}
fn shift(&mut self, _context: &mut CodeGenContext, _kind: ShiftKind, _size: OperandSize) {
todo!()
fn shift_ir(&mut self, dst: Reg, imm: u64, lhs: Reg, kind: ShiftKind, size: OperandSize) {
self.asm.shift_ir(imm, lhs, dst, kind, size)
}
fn shift(&mut self, context: &mut CodeGenContext, kind: ShiftKind, size: OperandSize) {
let src = context.pop_to_reg(self, None);
let dst = context.pop_to_reg(self, None);
self.asm
.shift_rrr(src.into(), dst.into(), dst.into(), kind, size);
context.free_reg(src);
context.stack.push(dst.into());
}
fn div(&mut self, _context: &mut CodeGenContext, _kind: DivKind, _size: OperandSize) {

41
winch/codegen/src/isa/x64/masm.rs

@ -530,39 +530,20 @@ impl Masm for MacroAssembler {
}
}
fn shift(&mut self, context: &mut CodeGenContext, kind: ShiftKind, size: OperandSize) {
let top = context.stack.peek().expect("value at stack top");
if size == OperandSize::S32 && top.is_i32_const() {
let val = context
.stack
.pop_i32_const()
.expect("i32 const value at stack top");
let typed_reg = context.pop_to_reg(self, None);
self.asm.shift_ir(val as u8, typed_reg.into(), kind, size);
context.stack.push(typed_reg.into());
} else if size == OperandSize::S64 && top.is_i64_const() {
let val = context
.stack
.pop_i64_const()
.expect("i64 const value at stack top");
let typed_reg = context.pop_to_reg(self, None);
self.asm.shift_ir(val as u8, typed_reg.into(), kind, size);
fn shift_ir(&mut self, dst: Reg, imm: u64, lhs: Reg, kind: ShiftKind, size: OperandSize) {
Self::ensure_two_argument_form(&dst, &lhs);
self.asm.shift_ir(imm as u8, dst, kind, size)
}
context.stack.push(typed_reg.into());
} else {
// Number of bits to shift must be in the CL register.
let src = context.pop_to_reg(self, Some(regs::rcx()));
let dst = context.pop_to_reg(self, None);
fn shift(&mut self, context: &mut CodeGenContext, kind: ShiftKind, size: OperandSize) {
// Number of bits to shift must be in the CL register.
let src = context.pop_to_reg(self, Some(regs::rcx()));
let dst = context.pop_to_reg(self, None);
self.asm.shift_rr(src.into(), dst.into(), kind, size);
self.asm.shift_rr(src.into(), dst.into(), kind, size);
context.free_reg(src);
context.stack.push(dst.into());
}
context.free_reg(src);
context.stack.push(dst.into());
}
fn div(&mut self, context: &mut CodeGenContext, kind: DivKind, size: OperandSize) {

8
winch/codegen/src/masm.rs

@ -137,6 +137,7 @@ pub(crate) enum FloatCmpKind {
/// Kinds of shifts in WebAssembly.The [`masm`] implementation for each ISA is
/// responsible for emitting the correct sequence of instructions when
/// lowering to machine code.
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub(crate) enum ShiftKind {
/// Left shift.
Shl,
@ -694,8 +695,11 @@ pub(crate) trait MacroAssembler {
/// Perform logical exclusive or operation.
fn xor(&mut self, dst: Reg, lhs: Reg, rhs: RegImm, size: OperandSize);
/// Perform a shift operation.
/// Shift is special in that some architectures have specific expectations
/// Perform a shift operation between a register and an immediate.
fn shift_ir(&mut self, dst: Reg, imm: u64, lhs: Reg, kind: ShiftKind, size: OperandSize);
/// Perform a shift operation between two registers.
/// This case is special in that some architectures have specific expectations
/// regarding the location of the instruction arguments. To free the
/// caller from having to deal with the architecture specific constraints
/// we give this function access to the code generation context, allowing

30
winch/codegen/src/visitor.rs

@ -1070,73 +1070,63 @@ where
}
fn visit_i32_shl(&mut self) {
use OperandSize::*;
use ShiftKind::*;
self.masm.shift(&mut self.context, Shl, S32);
self.context.i32_shift(self.masm, Shl);
}
fn visit_i64_shl(&mut self) {
use OperandSize::*;
use ShiftKind::*;
self.masm.shift(&mut self.context, Shl, S64);
self.context.i64_shift(self.masm, Shl);
}
fn visit_i32_shr_s(&mut self) {
use OperandSize::*;
use ShiftKind::*;
self.masm.shift(&mut self.context, ShrS, S32);
self.context.i32_shift(self.masm, ShrS);
}
fn visit_i64_shr_s(&mut self) {
use OperandSize::*;
use ShiftKind::*;
self.masm.shift(&mut self.context, ShrS, S64);
self.context.i64_shift(self.masm, ShrS);
}
fn visit_i32_shr_u(&mut self) {
use OperandSize::*;
use ShiftKind::*;
self.masm.shift(&mut self.context, ShrU, S32);
self.context.i32_shift(self.masm, ShrU);
}
fn visit_i64_shr_u(&mut self) {
use OperandSize::*;
use ShiftKind::*;
self.masm.shift(&mut self.context, ShrU, S64);
self.context.i64_shift(self.masm, ShrU);
}
fn visit_i32_rotl(&mut self) {
use OperandSize::*;
use ShiftKind::*;
self.masm.shift(&mut self.context, Rotl, S32);
self.context.i32_shift(self.masm, Rotl);
}
fn visit_i64_rotl(&mut self) {
use OperandSize::*;
use ShiftKind::*;
self.masm.shift(&mut self.context, Rotl, S64);
self.context.i64_shift(self.masm, Rotl);
}
fn visit_i32_rotr(&mut self) {
use OperandSize::*;
use ShiftKind::*;
self.masm.shift(&mut self.context, Rotr, S32);
self.context.i32_shift(self.masm, Rotr);
}
fn visit_i64_rotr(&mut self) {
use OperandSize::*;
use ShiftKind::*;
self.masm.shift(&mut self.context, Rotr, S64);
self.context.i64_shift(self.masm, Rotr);
}
fn visit_end(&mut self) {

Loading…
Cancel
Save