winch: Add full support for integer sub and add instructions (#5737)

This patch adds complete support for the `sub` and `add` WebAssembly instructions
for x64, and complete support for the `add` WebAssembly instruction for aarch64.

This patch also refactors how the binary operations get constructed within the
`VisitOperator` trait implementation. The refactor adds methods in the
`CodeGenContext` to abstract all the common steps to emit binary operations,
making this process less repetitive and less brittle (e.g. omitting to push the resulting value
to the stack, or omitting to free registers after used).

This patch also improves test coverage and refactors the filetests directory to make it
easier to add tests for other instructions.
This commit is contained in:
Saúl Cabrera
2023-02-08 20:01:44 -05:00
committed by GitHub
parent 9637840b4b
commit 7c5c7e4b6d
59 changed files with 992 additions and 120 deletions

View File

@@ -1,12 +1,11 @@
;;! target = "x86_64"
(module
(export "main" (func $main))
(func $main (result i32)
(func (result i32)
(i32.const 10)
(i32.const 20)
i32.add)
(i32.add)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp

View File

@@ -1,19 +1,20 @@
;;! target = "x86_64"
(module
(export "main" (func $main))
(func $main (result i32)
(func (result i32)
(local $foo i32)
(local $bar i32)
(i32.const 10)
(local.set $foo)
(i32.const 20)
(local.set $bar)
(local.get $foo)
(local.get $bar)
i32.add)
i32.add
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp

View File

@@ -0,0 +1,14 @@
;;! target = "x86_64"
(module
(func (result i32)
(i32.const 0x7fffffff)
(i32.const 1)
(i32.add)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: b8ffffff7f mov eax, 0x7fffffff
;; 9: 83c001 add eax, 1
;; c: 5d pop rbp
;; d: c3 ret

View File

@@ -0,0 +1,15 @@
;;! target = "x86_64"
(module
(func (result i32)
(i32.const 0x80000000)
(i32.const -1)
(i32.add)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: b800000080 mov eax, 0x80000000
;; 9: 83c0ff add eax, -1
;; c: 5d pop rbp
;; d: c3 ret

View File

@@ -0,0 +1,15 @@
;;! target = "x86_64"
(module
(func (result i32)
(i32.const -1)
(i32.const 1)
(i32.add)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: b8ffffffff mov eax, 0xffffffff
;; 9: 83c001 add eax, 1
;; c: 5d pop rbp
;; d: c3 ret

View File

@@ -1,12 +1,11 @@
;;! target = "x86_64"
(module
(export "main" (func $main))
(func $main (param i32) (param i32) (result i32)
(local.get 0)
(local.get 1)
i32.add)
(func (param i32) (param i32) (result i32)
(local.get 0)
(local.get 1)
(i32.add)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp

View File

@@ -0,0 +1,15 @@
;;! target = "x86_64"
(module
(func (result i32)
(i32.const -1)
(i32.const -1)
(i32.add)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: b8ffffffff mov eax, 0xffffffff
;; 9: 83c0ff add eax, -1
;; c: 5d pop rbp
;; d: c3 ret

View File

@@ -0,0 +1,15 @@
;;! target = "x86_64"
(module
(func (result i32)
(i32.const 1)
(i32.const 0)
(i32.add)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: b801000000 mov eax, 1
;; 9: 83c000 add eax, 0
;; c: 5d pop rbp
;; d: c3 ret

View File

@@ -0,0 +1,15 @@
;;! target = "x86_64"
(module
(func (result i32)
(i32.const 10)
(i32.const 20)
(i32.sub)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: b80a000000 mov eax, 0xa
;; 9: 83e814 sub eax, 0x14
;; c: 5d pop rbp
;; d: c3 ret

View File

@@ -0,0 +1,33 @@
;;! target = "x86_64"
(module
(func (result i32)
(local $foo i32)
(local $bar i32)
(i32.const 10)
(local.set $foo)
(i32.const 20)
(local.set $bar)
(local.get $foo)
(local.get $bar)
i32.sub
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: 4883ec08 sub rsp, 8
;; 8: 48c7042400000000 mov qword ptr [rsp], 0
;; 10: b80a000000 mov eax, 0xa
;; 15: 89442404 mov dword ptr [rsp + 4], eax
;; 19: b814000000 mov eax, 0x14
;; 1e: 890424 mov dword ptr [rsp], eax
;; 21: 8b0424 mov eax, dword ptr [rsp]
;; 24: 8b4c2404 mov ecx, dword ptr [rsp + 4]
;; 28: 29c1 sub ecx, eax
;; 2a: 4889c8 mov rax, rcx
;; 2d: 4883c408 add rsp, 8
;; 31: 5d pop rbp
;; 32: c3 ret

View File

@@ -0,0 +1,14 @@
;;! target = "x86_64"
(module
(func (result i32)
(i32.const 0x7fffffff)
(i32.const -1)
(i32.sub)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: b8ffffff7f mov eax, 0x7fffffff
;; 9: 83e8ff sub eax, -1
;; c: 5d pop rbp
;; d: c3 ret

View File

@@ -0,0 +1,15 @@
;;! target = "x86_64"
(module
(func (result i32)
(i32.const 0x80000000)
(i32.const 1)
(i32.sub)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: b800000080 mov eax, 0x80000000
;; 9: 83e801 sub eax, 1
;; c: 5d pop rbp
;; d: c3 ret

View File

@@ -0,0 +1,15 @@
;;! target = "x86_64"
(module
(func (result i32)
(i32.const -1)
(i32.const 1)
(i32.sub)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: b8ffffffff mov eax, 0xffffffff
;; 9: 83e801 sub eax, 1
;; c: 5d pop rbp
;; d: c3 ret

View File

@@ -0,0 +1,21 @@
;;! target = "x86_64"
(module
(func (param i32) (param i32) (result i32)
(local.get 0)
(local.get 1)
(i32.sub)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: 4883ec08 sub rsp, 8
;; 8: 897c2404 mov dword ptr [rsp + 4], edi
;; c: 893424 mov dword ptr [rsp], esi
;; f: 8b0424 mov eax, dword ptr [rsp]
;; 12: 8b4c2404 mov ecx, dword ptr [rsp + 4]
;; 16: 29c1 sub ecx, eax
;; 18: 4889c8 mov rax, rcx
;; 1b: 4883c408 add rsp, 8
;; 1f: 5d pop rbp
;; 20: c3 ret

View File

@@ -0,0 +1,15 @@
;;! target = "x86_64"
(module
(func (result i32)
(i32.const -1)
(i32.const -1)
(i32.sub)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: b8ffffffff mov eax, 0xffffffff
;; 9: 83e8ff sub eax, -1
;; c: 5d pop rbp
;; d: c3 ret

View File

@@ -0,0 +1,15 @@
;;! target = "x86_64"
(module
(func (result i32)
(i32.const 1)
(i32.const 0)
(i32.add)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: b801000000 mov eax, 1
;; 9: 83c000 add eax, 0
;; c: 5d pop rbp
;; d: c3 ret

View File

@@ -0,0 +1,15 @@
;;! target = "x86_64"
(module
(func (result i64)
(i64.const 10)
(i64.const 20)
(i64.add)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: 48c7c00a000000 mov rax, 0xa
;; b: 4883c014 add rax, 0x14
;; f: 5d pop rbp
;; 10: c3 ret

View File

@@ -0,0 +1,35 @@
;;! target = "x86_64"
(module
(func (result i64)
(local $foo i64)
(local $bar i64)
(i64.const 10)
(local.set $foo)
(i64.const 20)
(local.set $bar)
(local.get $foo)
(local.get $bar)
i64.add
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: 4883ec10 sub rsp, 0x10
;; 8: 4531db xor r11d, r11d
;; b: 4c895c2408 mov qword ptr [rsp + 8], r11
;; 10: 4c891c24 mov qword ptr [rsp], r11
;; 14: 48c7c00a000000 mov rax, 0xa
;; 1b: 4889442408 mov qword ptr [rsp + 8], rax
;; 20: 48c7c014000000 mov rax, 0x14
;; 27: 48890424 mov qword ptr [rsp], rax
;; 2b: 488b0424 mov rax, qword ptr [rsp]
;; 2f: 488b4c2408 mov rcx, qword ptr [rsp + 8]
;; 34: 4801c1 add rcx, rax
;; 37: 4889c8 mov rax, rcx
;; 3a: 4883c410 add rsp, 0x10
;; 3e: 5d pop rbp
;; 3f: c3 ret

View File

@@ -0,0 +1,16 @@
;;! target = "x86_64"
(module
(func (result i64)
(i64.const 1)
(i64.const 0x7fffffffffffffff)
(i64.add)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: 48c7c001000000 mov rax, 1
;; b: 49bbffffffffffffff7f
;; movabs r11, 0x7fffffffffffffff
;; 15: 4c01d8 add rax, r11
;; 18: 5d pop rbp
;; 19: c3 ret

View File

@@ -0,0 +1,16 @@
;;! target = "x86_64"
(module
(func (result i64)
(i64.const 0x8000000000000000)
(i64.const -1)
(i64.add)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: 48b80000000000000080
;; movabs rax, 0x8000000000000000
;; e: 4883c0ff add rax, -1
;; 12: 5d pop rbp
;; 13: c3 ret

View File

@@ -0,0 +1,15 @@
;;! target = "x86_64"
(module
(func (result i64)
(i64.const -1)
(i64.const 1)
(i64.add)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: 48c7c0ffffffff mov rax, 0xffffffffffffffff
;; b: 4883c001 add rax, 1
;; f: 5d pop rbp
;; 10: c3 ret

View File

@@ -0,0 +1,21 @@
;;! target = "x86_64"
(module
(func (param i64) (param i64) (result i64)
(local.get 0)
(local.get 1)
(i64.add)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: 4883ec10 sub rsp, 0x10
;; 8: 48897c2408 mov qword ptr [rsp + 8], rdi
;; d: 48893424 mov qword ptr [rsp], rsi
;; 11: 488b0424 mov rax, qword ptr [rsp]
;; 15: 488b4c2408 mov rcx, qword ptr [rsp + 8]
;; 1a: 4801c1 add rcx, rax
;; 1d: 4889c8 mov rax, rcx
;; 20: 4883c410 add rsp, 0x10
;; 24: 5d pop rbp
;; 25: c3 ret

View File

@@ -0,0 +1,15 @@
;;! target = "x86_64"
(module
(func (result i64)
(i64.const -1)
(i64.const -1)
(i64.add)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: 48c7c0ffffffff mov rax, 0xffffffffffffffff
;; b: 4883c0ff add rax, -1
;; f: 5d pop rbp
;; 10: c3 ret

View File

@@ -0,0 +1,15 @@
;;! target = "x86_64"
(module
(func (result i64)
(i64.const 1)
(i64.const 0)
(i64.add)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: 48c7c001000000 mov rax, 1
;; b: 4883c000 add rax, 0
;; f: 5d pop rbp
;; 10: c3 ret

View File

@@ -0,0 +1,15 @@
;;! target = "x86_64"
(module
(func (result i64)
(i64.const 10)
(i64.const 20)
(i64.sub)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: 48c7c00a000000 mov rax, 0xa
;; b: 4883e814 sub rax, 0x14
;; f: 5d pop rbp
;; 10: c3 ret

View File

@@ -0,0 +1,35 @@
;;! target = "x86_64"
(module
(func (result i64)
(local $foo i64)
(local $bar i64)
(i64.const 10)
(local.set $foo)
(i64.const 20)
(local.set $bar)
(local.get $foo)
(local.get $bar)
i64.sub
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: 4883ec10 sub rsp, 0x10
;; 8: 4531db xor r11d, r11d
;; b: 4c895c2408 mov qword ptr [rsp + 8], r11
;; 10: 4c891c24 mov qword ptr [rsp], r11
;; 14: 48c7c00a000000 mov rax, 0xa
;; 1b: 4889442408 mov qword ptr [rsp + 8], rax
;; 20: 48c7c014000000 mov rax, 0x14
;; 27: 48890424 mov qword ptr [rsp], rax
;; 2b: 488b0424 mov rax, qword ptr [rsp]
;; 2f: 488b4c2408 mov rcx, qword ptr [rsp + 8]
;; 34: 4829c1 sub rcx, rax
;; 37: 4889c8 mov rax, rcx
;; 3a: 4883c410 add rsp, 0x10
;; 3e: 5d pop rbp
;; 3f: c3 ret

View File

@@ -0,0 +1,15 @@
;;! target = "x86_64"
(module
(func (result i64)
(i64.const 0x7fffffffffffffff)
(i64.const -1)
(i64.sub)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: 48b8ffffffffffffff7f
;; movabs rax, 0x7fffffffffffffff
;; e: 4883e8ff sub rax, -1
;; 12: 5d pop rbp
;; 13: c3 ret

View File

@@ -0,0 +1,16 @@
;;! target = "x86_64"
(module
(func (result i64)
(i64.const 0x8000000000000000)
(i64.const 1)
(i64.sub)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: 48b80000000000000080
;; movabs rax, 0x8000000000000000
;; e: 4883e801 sub rax, 1
;; 12: 5d pop rbp
;; 13: c3 ret

View File

@@ -0,0 +1,15 @@
;;! target = "x86_64"
(module
(func (result i64)
(i64.const -1)
(i64.const 1)
(i64.sub)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: 48c7c0ffffffff mov rax, 0xffffffffffffffff
;; b: 4883e801 sub rax, 1
;; f: 5d pop rbp
;; 10: c3 ret

View File

@@ -0,0 +1,21 @@
;;! target = "x86_64"
(module
(func (param i64) (param i64) (result i64)
(local.get 0)
(local.get 1)
(i64.sub)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: 4883ec10 sub rsp, 0x10
;; 8: 48897c2408 mov qword ptr [rsp + 8], rdi
;; d: 48893424 mov qword ptr [rsp], rsi
;; 11: 488b0424 mov rax, qword ptr [rsp]
;; 15: 488b4c2408 mov rcx, qword ptr [rsp + 8]
;; 1a: 4829c1 sub rcx, rax
;; 1d: 4889c8 mov rax, rcx
;; 20: 4883c410 add rsp, 0x10
;; 24: 5d pop rbp
;; 25: c3 ret

View File

@@ -0,0 +1,15 @@
;;! target = "x86_64"
(module
(func (result i64)
(i64.const -1)
(i64.const -1)
(i64.sub)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: 48c7c0ffffffff mov rax, 0xffffffffffffffff
;; b: 4883e8ff sub rax, -1
;; f: 5d pop rbp
;; 10: c3 ret

View File

@@ -0,0 +1,15 @@
;;! target = "x86_64"
(module
(func (result i64)
(i64.const 1)
(i64.const 0)
(i64.add)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: 48c7c001000000 mov rax, 1
;; b: 4883c000 add rax, 0
;; f: 5d pop rbp
;; 10: c3 ret

View File

@@ -1,12 +0,0 @@
;;! target = "x86_64"
(module
(func (result i32)
(i32.const 42)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: 48c7c02a000000 mov rax, 0x2a
;; b: 5d pop rbp
;; c: c3 ret