Skip to content

Commit

Permalink
implement x64 xchg
Browse files Browse the repository at this point in the history
  • Loading branch information
MarinPostma committed Jan 16, 2025
1 parent c72de0b commit d36a7c9
Show file tree
Hide file tree
Showing 12 changed files with 340 additions and 13 deletions.
35 changes: 35 additions & 0 deletions tests/disas/winch/x64/atomic/rmw/i32_atomic_rmw16_xchgu.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
;;! target = "x86_64"
;;! test = "winch"

(module
(memory 1 1 shared)
(func (export "_start") (result i32)
(i32.atomic.rmw16.xchg_u (i32.const 0) (i32.const 42))))
;; wasm[0]::function[0]:
;; pushq %rbp
;; movq %rsp, %rbp
;; movq 8(%rdi), %r11
;; movq 0x10(%r11), %r11
;; addq $0x10, %r11
;; cmpq %rsp, %r11
;; ja 0x5f
;; 1c: movq %rdi, %r14
;; subq $0x10, %rsp
;; movq %rdi, 8(%rsp)
;; movq %rsi, (%rsp)
;; movl $0x2a, %eax
;; movl $0, %ecx
;; andw $1, %cx
;; cmpw $0, %cx
;; jne 0x61
;; 44: movl $0, %ecx
;; movq 0x58(%r14), %r11
;; movq (%r11), %rdx
;; addq %rcx, %rdx
;; xchgw %ax, (%rdx)
;; movzwl %ax, %eax
;; addq $0x10, %rsp
;; popq %rbp
;; retq
;; 5f: ud2
;; 61: ud2
30 changes: 30 additions & 0 deletions tests/disas/winch/x64/atomic/rmw/i32_atomic_rmw8_xchgu.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
;;! target = "x86_64"
;;! test = "winch"

(module
(memory 1 1 shared)
(func (export "_start") (result i32)
(i32.atomic.rmw8.xchg_u (i32.const 0) (i32.const 42))))
;; wasm[0]::function[0]:
;; pushq %rbp
;; movq %rsp, %rbp
;; movq 8(%rdi), %r11
;; movq 0x10(%r11), %r11
;; addq $0x10, %r11
;; cmpq %rsp, %r11
;; ja 0x4b
;; 1c: movq %rdi, %r14
;; subq $0x10, %rsp
;; movq %rdi, 8(%rsp)
;; movq %rsi, (%rsp)
;; movl $0x2a, %eax
;; movl $0, %ecx
;; movq 0x58(%r14), %r11
;; movq (%r11), %rdx
;; addq %rcx, %rdx
;; xchgb %al, (%rdx)
;; movzbl %al, %eax
;; addq $0x10, %rsp
;; popq %rbp
;; retq
;; 4b: ud2
34 changes: 34 additions & 0 deletions tests/disas/winch/x64/atomic/rmw/i32_atomic_rmw_xchg.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
;;! target = "x86_64"
;;! test = "winch"

(module
(memory 1 1 shared)
(func (export "_start") (result i32)
(i32.atomic.rmw.xchg (i32.const 0) (i32.const 42))))
;; wasm[0]::function[0]:
;; pushq %rbp
;; movq %rsp, %rbp
;; movq 8(%rdi), %r11
;; movq 0x10(%r11), %r11
;; addq $0x10, %r11
;; cmpq %rsp, %r11
;; ja 0x59
;; 1c: movq %rdi, %r14
;; subq $0x10, %rsp
;; movq %rdi, 8(%rsp)
;; movq %rsi, (%rsp)
;; movl $0x2a, %eax
;; movl $0, %ecx
;; andl $3, %ecx
;; cmpl $0, %ecx
;; jne 0x5b
;; 42: movl $0, %ecx
;; movq 0x58(%r14), %r11
;; movq (%r11), %rdx
;; addq %rcx, %rdx
;; xchgl %eax, (%rdx)
;; addq $0x10, %rsp
;; popq %rbp
;; retq
;; 59: ud2
;; 5b: ud2
35 changes: 35 additions & 0 deletions tests/disas/winch/x64/atomic/rmw/i64_atomic_rmw16_xchgu.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
;;! target = "x86_64"
;;! test = "winch"

(module
(memory 1 1 shared)
(func (export "_start") (result i64)
(i64.atomic.rmw16.xchg_u (i32.const 0) (i64.const 42))))
;; wasm[0]::function[0]:
;; pushq %rbp
;; movq %rsp, %rbp
;; movq 8(%rdi), %r11
;; movq 0x10(%r11), %r11
;; addq $0x10, %r11
;; cmpq %rsp, %r11
;; ja 0x62
;; 1c: movq %rdi, %r14
;; subq $0x10, %rsp
;; movq %rdi, 8(%rsp)
;; movq %rsi, (%rsp)
;; movq $0x2a, %rax
;; movl $0, %ecx
;; andw $1, %cx
;; cmpw $0, %cx
;; jne 0x64
;; 46: movl $0, %ecx
;; movq 0x58(%r14), %r11
;; movq (%r11), %rdx
;; addq %rcx, %rdx
;; xchgw %ax, (%rdx)
;; movzwq %ax, %rax
;; addq $0x10, %rsp
;; popq %rbp
;; retq
;; 62: ud2
;; 64: ud2
14 changes: 9 additions & 5 deletions tests/disas/winch/x64/atomic/rmw/i64_atomic_rmw32_addu.wat
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,31 @@
(module
(memory 1 1 shared)
(func (export "_start") (result i64)
(i64.atomic.rmw8.add_u (i32.const 0) (i64.const 42))))
(i64.atomic.rmw32.add_u (i32.const 0) (i64.const 42))))
;; wasm[0]::function[0]:
;; pushq %rbp
;; movq %rsp, %rbp
;; movq 8(%rdi), %r11
;; movq 0x10(%r11), %r11
;; addq $0x10, %r11
;; cmpq %rsp, %r11
;; ja 0x50
;; ja 0x5d
;; 1c: movq %rdi, %r14
;; subq $0x10, %rsp
;; movq %rdi, 8(%rsp)
;; movq %rsi, (%rsp)
;; movq $0x2a, %rax
;; movl $0, %ecx
;; andl $3, %ecx
;; cmpl $0, %ecx
;; jne 0x5f
;; 44: movl $0, %ecx
;; movq 0x58(%r14), %r11
;; movq (%r11), %rdx
;; addq %rcx, %rdx
;; lock xaddb %al, (%rdx)
;; movzbq %al, %rax
;; lock xaddl %eax, (%rdx)
;; addq $0x10, %rsp
;; popq %rbp
;; retq
;; 50: ud2
;; 5d: ud2
;; 5f: ud2
35 changes: 35 additions & 0 deletions tests/disas/winch/x64/atomic/rmw/i64_atomic_rmw32_xchgu.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
;;! target = "x86_64"
;;! test = "winch"

(module
(memory 1 1 shared)
(func (export "_start") (result i64)
(i64.atomic.rmw32.xchg_u (i32.const 0) (i64.const 42))))
;; wasm[0]::function[0]:
;; pushq %rbp
;; movq %rsp, %rbp
;; movq 8(%rdi), %r11
;; movq 0x10(%r11), %r11
;; addq $0x10, %r11
;; cmpq %rsp, %r11
;; ja 0x5d
;; 1c: movq %rdi, %r14
;; subq $0x10, %rsp
;; movq %rdi, 8(%rsp)
;; movq %rsi, (%rsp)
;; movq $0x2a, %rax
;; movl $0, %ecx
;; andl $3, %ecx
;; cmpl $0, %ecx
;; jne 0x5f
;; 44: movl $0, %ecx
;; movq 0x58(%r14), %r11
;; movq (%r11), %rdx
;; addq %rcx, %rdx
;; xchgl %eax, (%rdx)
;; movl %eax, %eax
;; addq $0x10, %rsp
;; popq %rbp
;; retq
;; 5d: ud2
;; 5f: ud2
30 changes: 30 additions & 0 deletions tests/disas/winch/x64/atomic/rmw/i64_atomic_rmw8_xchgu.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
;;! target = "x86_64"
;;! test = "winch"

(module
(memory 1 1 shared)
(func (export "_start") (result i64)
(i64.atomic.rmw8.xchg_u (i32.const 0) (i64.const 42))))
;; wasm[0]::function[0]:
;; pushq %rbp
;; movq %rsp, %rbp
;; movq 8(%rdi), %r11
;; movq 0x10(%r11), %r11
;; addq $0x10, %r11
;; cmpq %rsp, %r11
;; ja 0x4e
;; 1c: movq %rdi, %r14
;; subq $0x10, %rsp
;; movq %rdi, 8(%rsp)
;; movq %rsi, (%rsp)
;; movq $0x2a, %rax
;; movl $0, %ecx
;; movq 0x58(%r14), %r11
;; movq (%r11), %rdx
;; addq %rcx, %rdx
;; xchgb %al, (%rdx)
;; movzbq %al, %rax
;; addq $0x10, %rsp
;; popq %rbp
;; retq
;; 4e: ud2
34 changes: 34 additions & 0 deletions tests/disas/winch/x64/atomic/rmw/i64_atomic_rmw_xchg.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
;;! target = "x86_64"
;;! test = "winch"

(module
(memory 1 1 shared)
(func (export "_start") (result i64)
(i64.atomic.rmw.xchg (i32.const 0) (i64.const 42))))
;; wasm[0]::function[0]:
;; pushq %rbp
;; movq %rsp, %rbp
;; movq 8(%rdi), %r11
;; movq 0x10(%r11), %r11
;; addq $0x10, %r11
;; cmpq %rsp, %r11
;; ja 0x5e
;; 1c: movq %rdi, %r14
;; subq $0x10, %rsp
;; movq %rdi, 8(%rsp)
;; movq %rsi, (%rsp)
;; movq $0x2a, %rax
;; movl $0, %ecx
;; andq $7, %rcx
;; cmpq $0, %rcx
;; jne 0x60
;; 46: movl $0, %ecx
;; movq 0x58(%r14), %r11
;; movq (%r11), %rdx
;; addq %rcx, %rdx
;; xchgq %rax, (%rdx)
;; addq $0x10, %rsp
;; popq %rbp
;; retq
;; 5e: ud2
;; 60: ud2
25 changes: 25 additions & 0 deletions winch/codegen/src/isa/x64/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1098,6 +1098,31 @@ impl Assembler {
});
}

pub fn xchg(
&mut self,
addr: Address,
operand: Reg,
dst: WritableReg,
size: OperandSize,
flags: MemFlags,
) {
assert!(addr.is_offset());
let mem = Self::to_synthetic_amode(
&addr,
&mut self.pool,
&mut self.constants,
&mut self.buffer,
flags,
);

self.emit(Inst::Xchg {
size: size.into(),
operand: operand.into(),
mem,
dst_old: dst.map(Into::into),
});
}

pub fn cmp_ir(&mut self, src1: Reg, imm: i32, size: OperandSize) {
let imm = RegMemImm::imm(imm as u32);

Expand Down
4 changes: 4 additions & 0 deletions winch/codegen/src/isa/x64/masm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1335,11 +1335,15 @@ impl Masm for MacroAssembler {
self.asm
.lock_xadd(addr, operand.to_reg(), operand, size, flags);
}
RmwOp::Xchg => {
self.asm.xchg(addr, operand.to_reg(), operand, size, flags);
}
}

if let Some(extend) = extend {
self.asm.movzx_rr(operand.to_reg(), operand, extend);
}

Ok(())
}
}
Expand Down
1 change: 1 addition & 0 deletions winch/codegen/src/masm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ pub(crate) enum MulWideKind {
pub(crate) enum RmwOp {
Add,
Sub,
Xchg,
}

/// The direction to perform the memory move.
Expand Down
Loading

0 comments on commit d36a7c9

Please sign in to comment.