Skip to content

Commit 146aa47

Browse files
authored
Winch: implement rmw xchg for x64 (bytecodealliance#10029)
* implement x64 xchg * fix test post rebase
1 parent 1d1c06f commit 146aa47

12 files changed

+338
-13
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
;;! target = "x86_64"
2+
;;! test = "winch"
3+
4+
(module
5+
(memory 1 1 shared)
6+
(func (export "_start") (result i32)
7+
(i32.atomic.rmw16.xchg_u (i32.const 0) (i32.const 42))))
8+
;; wasm[0]::function[0]:
9+
;; pushq %rbp
10+
;; movq %rsp, %rbp
11+
;; movq 8(%rdi), %r11
12+
;; movq 0x10(%r11), %r11
13+
;; addq $0x10, %r11
14+
;; cmpq %rsp, %r11
15+
;; ja 0x5f
16+
;; 1c: movq %rdi, %r14
17+
;; subq $0x10, %rsp
18+
;; movq %rdi, 8(%rsp)
19+
;; movq %rsi, (%rsp)
20+
;; movl $0x2a, %eax
21+
;; movl $0, %ecx
22+
;; andw $1, %cx
23+
;; cmpw $0, %cx
24+
;; jne 0x61
25+
;; 44: movl $0, %ecx
26+
;; movq 0x58(%r14), %r11
27+
;; movq (%r11), %rdx
28+
;; addq %rcx, %rdx
29+
;; xchgw %ax, (%rdx)
30+
;; movzwl %ax, %eax
31+
;; addq $0x10, %rsp
32+
;; popq %rbp
33+
;; retq
34+
;; 5f: ud2
35+
;; 61: ud2
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
;;! target = "x86_64"
2+
;;! test = "winch"
3+
4+
(module
5+
(memory 1 1 shared)
6+
(func (export "_start") (result i32)
7+
(i32.atomic.rmw8.xchg_u (i32.const 0) (i32.const 42))))
8+
;; wasm[0]::function[0]:
9+
;; pushq %rbp
10+
;; movq %rsp, %rbp
11+
;; movq 8(%rdi), %r11
12+
;; movq 0x10(%r11), %r11
13+
;; addq $0x10, %r11
14+
;; cmpq %rsp, %r11
15+
;; ja 0x4b
16+
;; 1c: movq %rdi, %r14
17+
;; subq $0x10, %rsp
18+
;; movq %rdi, 8(%rsp)
19+
;; movq %rsi, (%rsp)
20+
;; movl $0x2a, %eax
21+
;; movl $0, %ecx
22+
;; movq 0x58(%r14), %r11
23+
;; movq (%r11), %rdx
24+
;; addq %rcx, %rdx
25+
;; xchgb %al, (%rdx)
26+
;; movzbl %al, %eax
27+
;; addq $0x10, %rsp
28+
;; popq %rbp
29+
;; retq
30+
;; 4b: ud2
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
;;! target = "x86_64"
2+
;;! test = "winch"
3+
4+
(module
5+
(memory 1 1 shared)
6+
(func (export "_start") (result i32)
7+
(i32.atomic.rmw.xchg (i32.const 0) (i32.const 42))))
8+
;; wasm[0]::function[0]:
9+
;; pushq %rbp
10+
;; movq %rsp, %rbp
11+
;; movq 8(%rdi), %r11
12+
;; movq 0x10(%r11), %r11
13+
;; addq $0x10, %r11
14+
;; cmpq %rsp, %r11
15+
;; ja 0x59
16+
;; 1c: movq %rdi, %r14
17+
;; subq $0x10, %rsp
18+
;; movq %rdi, 8(%rsp)
19+
;; movq %rsi, (%rsp)
20+
;; movl $0x2a, %eax
21+
;; movl $0, %ecx
22+
;; andl $3, %ecx
23+
;; cmpl $0, %ecx
24+
;; jne 0x5b
25+
;; 42: movl $0, %ecx
26+
;; movq 0x58(%r14), %r11
27+
;; movq (%r11), %rdx
28+
;; addq %rcx, %rdx
29+
;; xchgl %eax, (%rdx)
30+
;; addq $0x10, %rsp
31+
;; popq %rbp
32+
;; retq
33+
;; 59: ud2
34+
;; 5b: ud2
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
;;! target = "x86_64"
2+
;;! test = "winch"
3+
4+
(module
5+
(memory 1 1 shared)
6+
(func (export "_start") (result i64)
7+
(i64.atomic.rmw16.xchg_u (i32.const 0) (i64.const 42))))
8+
;; wasm[0]::function[0]:
9+
;; pushq %rbp
10+
;; movq %rsp, %rbp
11+
;; movq 8(%rdi), %r11
12+
;; movq 0x10(%r11), %r11
13+
;; addq $0x10, %r11
14+
;; cmpq %rsp, %r11
15+
;; ja 0x62
16+
;; 1c: movq %rdi, %r14
17+
;; subq $0x10, %rsp
18+
;; movq %rdi, 8(%rsp)
19+
;; movq %rsi, (%rsp)
20+
;; movq $0x2a, %rax
21+
;; movl $0, %ecx
22+
;; andw $1, %cx
23+
;; cmpw $0, %cx
24+
;; jne 0x64
25+
;; 46: movl $0, %ecx
26+
;; movq 0x58(%r14), %r11
27+
;; movq (%r11), %rdx
28+
;; addq %rcx, %rdx
29+
;; xchgw %ax, (%rdx)
30+
;; movzwq %ax, %rax
31+
;; addq $0x10, %rsp
32+
;; popq %rbp
33+
;; retq
34+
;; 62: ud2
35+
;; 64: ud2

tests/disas/winch/x64/atomic/rmw/i64_atomic_rmw32_addu.wat

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,31 @@
44
(module
55
(memory 1 1 shared)
66
(func (export "_start") (result i64)
7-
(i64.atomic.rmw8.add_u (i32.const 0) (i64.const 42))))
7+
(i64.atomic.rmw32.add_u (i32.const 0) (i64.const 42))))
88
;; wasm[0]::function[0]:
99
;; pushq %rbp
1010
;; movq %rsp, %rbp
1111
;; movq 8(%rdi), %r11
1212
;; movq 0x10(%r11), %r11
1313
;; addq $0x10, %r11
1414
;; cmpq %rsp, %r11
15-
;; ja 0x50
15+
;; ja 0x5d
1616
;; 1c: movq %rdi, %r14
1717
;; subq $0x10, %rsp
1818
;; movq %rdi, 8(%rsp)
1919
;; movq %rsi, (%rsp)
2020
;; movq $0x2a, %rax
2121
;; movl $0, %ecx
22+
;; andl $3, %ecx
23+
;; cmpl $0, %ecx
24+
;; jne 0x5f
25+
;; 44: movl $0, %ecx
2226
;; movq 0x58(%r14), %r11
2327
;; movq (%r11), %rdx
2428
;; addq %rcx, %rdx
25-
;; lock xaddb %al, (%rdx)
26-
;; movzbq %al, %rax
29+
;; lock xaddl %eax, (%rdx)
2730
;; addq $0x10, %rsp
2831
;; popq %rbp
2932
;; retq
30-
;; 50: ud2
33+
;; 5d: ud2
34+
;; 5f: ud2
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
;;! target = "x86_64"
2+
;;! test = "winch"
3+
4+
(module
5+
(memory 1 1 shared)
6+
(func (export "_start") (result i64)
7+
(i64.atomic.rmw32.xchg_u (i32.const 0) (i64.const 42))))
8+
;; wasm[0]::function[0]:
9+
;; pushq %rbp
10+
;; movq %rsp, %rbp
11+
;; movq 8(%rdi), %r11
12+
;; movq 0x10(%r11), %r11
13+
;; addq $0x10, %r11
14+
;; cmpq %rsp, %r11
15+
;; ja 0x5b
16+
;; 1c: movq %rdi, %r14
17+
;; subq $0x10, %rsp
18+
;; movq %rdi, 8(%rsp)
19+
;; movq %rsi, (%rsp)
20+
;; movq $0x2a, %rax
21+
;; movl $0, %ecx
22+
;; andl $3, %ecx
23+
;; cmpl $0, %ecx
24+
;; jne 0x5d
25+
;; 44: movl $0, %ecx
26+
;; movq 0x58(%r14), %r11
27+
;; movq (%r11), %rdx
28+
;; addq %rcx, %rdx
29+
;; xchgl %eax, (%rdx)
30+
;; addq $0x10, %rsp
31+
;; popq %rbp
32+
;; retq
33+
;; 5b: ud2
34+
;; 5d: ud2
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
;;! target = "x86_64"
2+
;;! test = "winch"
3+
4+
(module
5+
(memory 1 1 shared)
6+
(func (export "_start") (result i64)
7+
(i64.atomic.rmw8.xchg_u (i32.const 0) (i64.const 42))))
8+
;; wasm[0]::function[0]:
9+
;; pushq %rbp
10+
;; movq %rsp, %rbp
11+
;; movq 8(%rdi), %r11
12+
;; movq 0x10(%r11), %r11
13+
;; addq $0x10, %r11
14+
;; cmpq %rsp, %r11
15+
;; ja 0x4e
16+
;; 1c: movq %rdi, %r14
17+
;; subq $0x10, %rsp
18+
;; movq %rdi, 8(%rsp)
19+
;; movq %rsi, (%rsp)
20+
;; movq $0x2a, %rax
21+
;; movl $0, %ecx
22+
;; movq 0x58(%r14), %r11
23+
;; movq (%r11), %rdx
24+
;; addq %rcx, %rdx
25+
;; xchgb %al, (%rdx)
26+
;; movzbq %al, %rax
27+
;; addq $0x10, %rsp
28+
;; popq %rbp
29+
;; retq
30+
;; 4e: ud2
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
;;! target = "x86_64"
2+
;;! test = "winch"
3+
4+
(module
5+
(memory 1 1 shared)
6+
(func (export "_start") (result i64)
7+
(i64.atomic.rmw.xchg (i32.const 0) (i64.const 42))))
8+
;; wasm[0]::function[0]:
9+
;; pushq %rbp
10+
;; movq %rsp, %rbp
11+
;; movq 8(%rdi), %r11
12+
;; movq 0x10(%r11), %r11
13+
;; addq $0x10, %r11
14+
;; cmpq %rsp, %r11
15+
;; ja 0x5e
16+
;; 1c: movq %rdi, %r14
17+
;; subq $0x10, %rsp
18+
;; movq %rdi, 8(%rsp)
19+
;; movq %rsi, (%rsp)
20+
;; movq $0x2a, %rax
21+
;; movl $0, %ecx
22+
;; andq $7, %rcx
23+
;; cmpq $0, %rcx
24+
;; jne 0x60
25+
;; 46: movl $0, %ecx
26+
;; movq 0x58(%r14), %r11
27+
;; movq (%r11), %rdx
28+
;; addq %rcx, %rdx
29+
;; xchgq %rax, (%rdx)
30+
;; addq $0x10, %rsp
31+
;; popq %rbp
32+
;; retq
33+
;; 5e: ud2
34+
;; 60: ud2

winch/codegen/src/isa/x64/asm.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1147,6 +1147,31 @@ impl Assembler {
11471147
});
11481148
}
11491149

1150+
pub fn xchg(
1151+
&mut self,
1152+
addr: Address,
1153+
operand: Reg,
1154+
dst: WritableReg,
1155+
size: OperandSize,
1156+
flags: MemFlags,
1157+
) {
1158+
assert!(addr.is_offset());
1159+
let mem = Self::to_synthetic_amode(
1160+
&addr,
1161+
&mut self.pool,
1162+
&mut self.constants,
1163+
&mut self.buffer,
1164+
flags,
1165+
);
1166+
1167+
self.emit(Inst::Xchg {
1168+
size: size.into(),
1169+
operand: operand.into(),
1170+
mem,
1171+
dst_old: dst.map(Into::into),
1172+
});
1173+
}
1174+
11501175
pub fn cmp_ir(&mut self, src1: Reg, imm: i32, size: OperandSize) {
11511176
let imm = RegMemImm::imm(imm as u32);
11521177

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1410,6 +1410,9 @@ impl Masm for MacroAssembler {
14101410
self.asm
14111411
.lock_xadd(addr, operand.to_reg(), operand, size, flags);
14121412
}
1413+
RmwOp::Xchg => {
1414+
self.asm.xchg(addr, operand.to_reg(), operand, size, flags);
1415+
}
14131416
}
14141417

14151418
if let Some(extend) = extend {

winch/codegen/src/masm.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ pub(crate) enum MulWideKind {
5656
pub(crate) enum RmwOp {
5757
Add,
5858
Sub,
59+
Xchg,
5960
}
6061

6162
/// The direction to perform the memory move.

0 commit comments

Comments
 (0)