Skip to content

Commit 0a4dcc4

Browse files
authored
Winch: implement rmw add ops (bytecodealliance#9990)
* add lock_xlock 64 asm * add atomic_rmw to masm * add atomic rmw to codegen * implement add rmw operations for visitor * remove leftover comment * fmt * rename atomic_rmw to emit_atomic_rmw * fix tests after rebase * report error on unsupported extend kind for atomic op * remove useless check
1 parent 3a4cf0a commit 0a4dcc4

File tree

14 files changed

+409
-7
lines changed

14 files changed

+409
-7
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.add_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 0x61
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 0x63
25+
;; 44: movl $0, %ecx
26+
;; movq 0x58(%r14), %r11
27+
;; movq (%r11), %rdx
28+
;; addq %rcx, %rdx
29+
;; lock xaddw %ax, (%rdx)
30+
;; movzwl %ax, %eax
31+
;; addq $0x10, %rsp
32+
;; popq %rbp
33+
;; retq
34+
;; 61: ud2
35+
;; 63: 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.add_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 0x4d
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+
;; lock xaddb %al, (%rdx)
26+
;; movzbl %al, %eax
27+
;; addq $0x10, %rsp
28+
;; popq %rbp
29+
;; retq
30+
;; 4d: 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.add (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 0x5b
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 0x5d
25+
;; 42: movl $0, %ecx
26+
;; movq 0x58(%r14), %r11
27+
;; movq (%r11), %rdx
28+
;; addq %rcx, %rdx
29+
;; lock xaddl %eax, (%rdx)
30+
;; addq $0x10, %rsp
31+
;; popq %rbp
32+
;; retq
33+
;; 5b: ud2
34+
;; 5d: 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.add_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 0x64
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 0x66
25+
;; 46: movl $0, %ecx
26+
;; movq 0x58(%r14), %r11
27+
;; movq (%r11), %rdx
28+
;; addq %rcx, %rdx
29+
;; lock xaddw %ax, (%rdx)
30+
;; movzwq %ax, %rax
31+
;; addq $0x10, %rsp
32+
;; popq %rbp
33+
;; retq
34+
;; 64: ud2
35+
;; 66: 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.add_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 0x50
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+
;; lock xaddb %al, (%rdx)
26+
;; movzbq %al, %rax
27+
;; addq $0x10, %rsp
28+
;; popq %rbp
29+
;; retq
30+
;; 50: 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.add_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 0x50
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+
;; lock xaddb %al, (%rdx)
26+
;; movzbq %al, %rax
27+
;; addq $0x10, %rsp
28+
;; popq %rbp
29+
;; retq
30+
;; 50: 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.add (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 0x60
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 0x62
25+
;; 46: movl $0, %ecx
26+
;; movq 0x58(%r14), %r11
27+
;; movq (%r11), %rdx
28+
;; addq %rcx, %rdx
29+
;; lock xaddq %rax, (%rdx)
30+
;; addq $0x10, %rsp
31+
;; popq %rbp
32+
;; retq
33+
;; 60: ud2
34+
;; 62: ud2

winch/codegen/src/codegen/error.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ pub(crate) enum CodeGenError {
3232
/// implies a compiler bug.
3333
#[error("Winch internal error: {0}")]
3434
Internal(InternalError),
35+
#[error("Unsupported extend kind")]
36+
UnsupportedExtendKind,
3537
}
3638

3739
/// An internal error.
@@ -185,4 +187,8 @@ impl CodeGenError {
185187
pub(crate) const fn unimplemented_masm_instruction() -> Self {
186188
Self::UnimplementedMasmInstruction
187189
}
190+
191+
pub(crate) const fn unsupported_extend_kind() -> Self {
192+
Self::UnsupportedExtendKind
193+
}
188194
}

winch/codegen/src/codegen/mod.rs

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ use crate::{
33
codegen::BlockSig,
44
isa::reg::{writable, Reg},
55
masm::{
6-
Imm, IntCmpKind, LoadKind, MacroAssembler, MemOpKind, OperandSize, RegImm, SPOffset,
7-
ShiftKind, TrapCode,
6+
ExtendKind, Imm, IntCmpKind, LoadKind, MacroAssembler, MemOpKind, OperandSize, RegImm,
7+
RmwOp, SPOffset, ShiftKind, TrapCode, UNTRUSTED_FLAGS,
88
},
99
stack::TypedReg,
1010
};
@@ -1363,6 +1363,37 @@ where
13631363

13641364
Ok(())
13651365
}
1366+
1367+
pub(crate) fn emit_atomic_rmw(
1368+
&mut self,
1369+
arg: &MemArg,
1370+
op: RmwOp,
1371+
size: OperandSize,
1372+
extend: Option<ExtendKind>,
1373+
) -> Result<()> {
1374+
// Only unsigned extends are supported for atomic operations.
1375+
match extend {
1376+
Some(kind) if kind.signed() => bail!(CodeGenError::unsupported_extend_kind()),
1377+
_ => (),
1378+
}
1379+
1380+
let operand = self.context.pop_to_reg(self.masm, None).unwrap();
1381+
if let Some(addr) = self.emit_compute_heap_address_align_checked(arg, size)? {
1382+
let src = self.masm.address_at_reg(addr, 0)?;
1383+
self.masm.atomic_rmw(
1384+
src,
1385+
writable!(operand.reg),
1386+
size,
1387+
op,
1388+
UNTRUSTED_FLAGS,
1389+
extend,
1390+
)?;
1391+
self.context.stack.push(operand.into());
1392+
self.context.free_reg(addr);
1393+
}
1394+
1395+
Ok(())
1396+
}
13661397
}
13671398

13681399
/// Returns the index of the [`ControlStackFrame`] for the given

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

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@ use crate::{
1313
},
1414
masm::{
1515
CalleeKind, DivKind, ExtendKind, FloatCmpKind, Imm as I, IntCmpKind, LoadKind,
16-
MacroAssembler as Masm, MemOpKind, MulWideKind, OperandSize, RegImm, RemKind, RoundingMode,
17-
SPOffset, ShiftKind, StackSlot, TrapCode, TruncKind,
16+
MacroAssembler as Masm, MemOpKind, MulWideKind, OperandSize, RegImm, RemKind, RmwOp,
17+
RoundingMode, SPOffset, ShiftKind, StackSlot, TrapCode, TruncKind,
1818
},
1919
stack::TypedReg,
2020
};
2121
use anyhow::{anyhow, bail, Result};
2222
use cranelift_codegen::{
2323
binemit::CodeOffset,
24-
ir::{RelSourceLoc, SourceLoc},
24+
ir::{MemFlags, RelSourceLoc, SourceLoc},
2525
isa::aarch64::inst::{Cond, VectorSize},
2626
settings, Final, MachBufferFinalized, MachLabel,
2727
};
@@ -893,6 +893,18 @@ impl Masm for MacroAssembler {
893893
let _ = (context, kind);
894894
Err(anyhow!(CodeGenError::unimplemented_masm_instruction()))
895895
}
896+
897+
fn atomic_rmw(
898+
&mut self,
899+
_addr: Self::Address,
900+
_operand: WritableReg,
901+
_size: OperandSize,
902+
_op: RmwOp,
903+
_flags: MemFlags,
904+
_extend: Option<ExtendKind>,
905+
) -> Result<()> {
906+
Err(anyhow!(CodeGenError::unimplemented_masm_instruction()))
907+
}
896908
}
897909

898910
impl MacroAssembler {

0 commit comments

Comments
 (0)