Browse Source

winch: Add support for `<i32|i64>.rem_*` WebAssembly instructions (#5823)

This commit adds support for i32 and i64 remainder instructions for
x64.
pull/5004/merge
Saúl Cabrera 2 years ago
committed by GitHub
parent
commit
4d954f5c0e
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      winch/codegen/src/isa/aarch64/masm.rs
  2. 31
      winch/codegen/src/isa/x64/asm.rs
  3. 24
      winch/codegen/src/isa/x64/masm.rs
  4. 11
      winch/codegen/src/masm.rs
  5. 34
      winch/codegen/src/visitor.rs
  6. 25
      winch/filetests/filetests/x64/i32_rems/const.wat
  7. 25
      winch/filetests/filetests/x64/i32_rems/one_zero.wat
  8. 25
      winch/filetests/filetests/x64/i32_rems/overflow.wat
  9. 29
      winch/filetests/filetests/x64/i32_rems/params.wat
  10. 25
      winch/filetests/filetests/x64/i32_rems/zero_zero.wat
  11. 21
      winch/filetests/filetests/x64/i32_remu/const.wat
  12. 21
      winch/filetests/filetests/x64/i32_remu/one_zero.wat
  13. 25
      winch/filetests/filetests/x64/i32_remu/params.wat
  14. 21
      winch/filetests/filetests/x64/i32_remu/signed.wat
  15. 21
      winch/filetests/filetests/x64/i32_remu/zero_zero.wat
  16. 25
      winch/filetests/filetests/x64/i64_rems/const.wat
  17. 25
      winch/filetests/filetests/x64/i64_rems/one_zero.wat
  18. 26
      winch/filetests/filetests/x64/i64_rems/overflow.wat
  19. 29
      winch/filetests/filetests/x64/i64_rems/params.wat
  20. 25
      winch/filetests/filetests/x64/i64_rems/zero_zero.wat
  21. 21
      winch/filetests/filetests/x64/i64_remu/const.wat
  22. 21
      winch/filetests/filetests/x64/i64_remu/one_zero.wat
  23. 25
      winch/filetests/filetests/x64/i64_remu/params.wat
  24. 21
      winch/filetests/filetests/x64/i64_remu/signed.wat
  25. 21
      winch/filetests/filetests/x64/i64_remu/zero_zero.wat

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

@ -7,7 +7,7 @@ use crate::{
abi::local::LocalSlot, abi::local::LocalSlot,
codegen::CodeGenContext, codegen::CodeGenContext,
isa::reg::Reg, isa::reg::Reg,
masm::{DivKind, MacroAssembler as Masm, OperandSize, RegImm}, masm::{DivKind, MacroAssembler as Masm, OperandSize, RegImm, RemKind},
}; };
use cranelift_codegen::{settings, Final, MachBufferFinalized}; use cranelift_codegen::{settings, Final, MachBufferFinalized};
@ -156,6 +156,10 @@ impl Masm for MacroAssembler {
todo!() todo!()
} }
fn rem(&mut self, _context: &mut CodeGenContext, _kind: RemKind, _size: OperandSize) {
todo!()
}
fn zero(&mut self, reg: Reg) { fn zero(&mut self, reg: Reg) {
self.asm.load_constant(0, reg); self.asm.load_constant(0, reg);
} }

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

@ -2,7 +2,7 @@
use crate::{ use crate::{
isa::reg::Reg, isa::reg::Reg,
masm::{DivKind, OperandSize}, masm::{DivKind, OperandSize, RemKind},
}; };
use cranelift_codegen::{ use cranelift_codegen::{
isa::x64::{ isa::x64::{
@ -73,6 +73,15 @@ impl From<DivKind> for DivOrRemKind {
} }
} }
impl From<RemKind> for DivOrRemKind {
fn from(kind: RemKind) -> Self {
match kind {
RemKind::Signed => DivOrRemKind::SignedRem,
RemKind::Unsigned => DivOrRemKind::UnsignedRem,
}
}
}
/// Low level assembler implementation for x64. /// Low level assembler implementation for x64.
pub(crate) struct Assembler { pub(crate) struct Assembler {
/// The machine instruction buffer. /// The machine instruction buffer.
@ -299,6 +308,26 @@ impl Assembler {
}); });
} }
/// Signed/unsigned remainder.
///
/// Emits a sequence of instructions to ensure the correctness of the
/// division invariants and ultimately calculate the remainder.
/// This function assumes that the
/// caller has correctly allocated the dividend as `(rdx:rax)` and
/// accounted for the remainder to be stored in `rdx`.
pub fn rem(&mut self, divisor: Reg, dst: (Reg, Reg), kind: RemKind, size: OperandSize) {
self.emit(Inst::CheckedDivOrRemSeq {
kind: kind.into(),
size: size.into(),
divisor: divisor.into(),
dividend_lo: dst.0.into(),
dividend_hi: dst.1.into(),
dst_quotient: dst.0.into(),
dst_remainder: dst.1.into(),
tmp: None,
});
}
/// Multiply immediate and register. /// Multiply immediate and register.
pub fn mul_ir(&mut self, imm: i32, dst: Reg, size: OperandSize) { pub fn mul_ir(&mut self, imm: i32, dst: Reg, size: OperandSize) {
let imm = RegMemImm::imm(imm as u32); let imm = RegMemImm::imm(imm as u32);

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

@ -4,7 +4,7 @@ use super::{
regs::{self, rbp, rsp}, regs::{self, rbp, rsp},
}; };
use crate::isa::reg::Reg; use crate::isa::reg::Reg;
use crate::masm::{DivKind, MacroAssembler as Masm, OperandSize, RegImm}; use crate::masm::{DivKind, MacroAssembler as Masm, OperandSize, RegImm, RemKind};
use crate::{abi::LocalSlot, codegen::CodeGenContext, stack::Val}; use crate::{abi::LocalSlot, codegen::CodeGenContext, stack::Val};
use cranelift_codegen::{isa::x64::settings as x64_settings, settings, Final, MachBufferFinalized}; use cranelift_codegen::{isa::x64::settings as x64_settings, settings, Final, MachBufferFinalized};
@ -174,6 +174,28 @@ impl Masm for MacroAssembler {
context.stack.push(Val::reg(rax)); context.stack.push(Val::reg(rax));
} }
fn rem(&mut self, context: &mut CodeGenContext, kind: RemKind, size: OperandSize) {
// Allocate rdx:rax.
let rdx = context.gpr(regs::rdx(), self);
let rax = context.gpr(regs::rax(), self);
// Allocate the divisor, which can be any gpr.
let divisor = context.pop_to_reg(self, size);
// Mark rax as allocatable.
context.regalloc.free_gpr(rax);
// Move the top value to rax.
let rax = context.pop_to_named_reg(self, rax, size);
self.asm.rem(divisor, (rax, rdx), kind, size);
// Free the divisor and rax.
context.free_gpr(divisor);
context.free_gpr(rax);
// Push the remainder.
context.stack.push(Val::reg(rdx));
}
fn epilogue(&mut self, locals_size: u32) { fn epilogue(&mut self, locals_size: u32) {
assert!(self.sp_offset == locals_size); assert!(self.sp_offset == locals_size);

11
winch/codegen/src/masm.rs

@ -13,6 +13,14 @@ pub(crate) enum DivKind {
Unsigned, Unsigned,
} }
/// Remainder kind.
pub(crate) enum RemKind {
/// Signed remainder.
Signed,
/// Unsigned remainder.
Unsigned,
}
/// Operand size, in bits. /// Operand size, in bits.
#[derive(Copy, Clone, Eq, PartialEq)] #[derive(Copy, Clone, Eq, PartialEq)]
pub(crate) enum OperandSize { pub(crate) enum OperandSize {
@ -116,6 +124,9 @@ pub(crate) trait MacroAssembler {
/// functions. /// functions.
fn div(&mut self, context: &mut CodeGenContext, kind: DivKind, size: OperandSize); fn div(&mut self, context: &mut CodeGenContext, kind: DivKind, size: OperandSize);
/// Calculate remainder.
fn rem(&mut self, context: &mut CodeGenContext, kind: RemKind, size: OperandSize);
/// Push the register to the stack, returning the offset. /// Push the register to the stack, returning the offset.
fn push(&mut self, src: Reg) -> u32; fn push(&mut self, src: Reg) -> u32;

34
winch/codegen/src/visitor.rs

@ -5,7 +5,7 @@
//! machine code emitter. //! machine code emitter.
use crate::codegen::CodeGen; use crate::codegen::CodeGen;
use crate::masm::{DivKind, MacroAssembler, OperandSize, RegImm}; use crate::masm::{DivKind, MacroAssembler, OperandSize, RegImm, RemKind};
use crate::stack::Val; use crate::stack::Val;
use wasmparser::ValType; use wasmparser::ValType;
use wasmparser::VisitOperator; use wasmparser::VisitOperator;
@ -41,6 +41,10 @@ macro_rules! def_unsupported {
(emit I32DivU $($rest:tt)*) => {}; (emit I32DivU $($rest:tt)*) => {};
(emit I64DivS $($rest:tt)*) => {}; (emit I64DivS $($rest:tt)*) => {};
(emit I64DivU $($rest:tt)*) => {}; (emit I64DivU $($rest:tt)*) => {};
(emit I64RemU $($rest:tt)*) => {};
(emit I64RemS $($rest:tt)*) => {};
(emit I32RemU $($rest:tt)*) => {};
(emit I32RemS $($rest:tt)*) => {};
(emit I64Mul $($rest:tt)*) => {}; (emit I64Mul $($rest:tt)*) => {};
(emit I64Sub $($rest:tt)*) => {}; (emit I64Sub $($rest:tt)*) => {};
(emit LocalGet $($rest:tt)*) => {}; (emit LocalGet $($rest:tt)*) => {};
@ -134,6 +138,34 @@ where
self.masm.div(&mut self.context, Unsigned, S64); self.masm.div(&mut self.context, Unsigned, S64);
} }
fn visit_i32_rem_s(&mut self) {
use OperandSize::*;
use RemKind::*;
self.masm.rem(&mut self.context, Signed, S32);
}
fn visit_i32_rem_u(&mut self) {
use OperandSize::*;
use RemKind::*;
self.masm.rem(&mut self.context, Unsigned, S32);
}
fn visit_i64_rem_s(&mut self) {
use OperandSize::*;
use RemKind::*;
self.masm.rem(&mut self.context, Signed, S64);
}
fn visit_i64_rem_u(&mut self) {
use OperandSize::*;
use RemKind::*;
self.masm.rem(&mut self.context, Unsigned, S64);
}
fn visit_end(&mut self) {} fn visit_end(&mut self) {}
fn visit_local_get(&mut self, index: u32) { fn visit_local_get(&mut self, index: u32) {

25
winch/filetests/filetests/x64/i32_rems/const.wat

@ -0,0 +1,25 @@
;;! target = "x86_64"
(module
(func (result i32)
(i32.const 7)
(i32.const 5)
(i32.rem_s)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: b905000000 mov ecx, 5
;; 9: b807000000 mov eax, 7
;; e: 83f900 cmp ecx, 0
;; 11: 0f8502000000 jne 0x19
;; 17: 0f0b ud2
;; 19: 83f9ff cmp ecx, -1
;; 1c: 0f850a000000 jne 0x2c
;; 22: b800000000 mov eax, 0
;; 27: e903000000 jmp 0x2f
;; 2c: 99 cdq
;; 2d: f7f9 idiv ecx
;; 2f: 4889d0 mov rax, rdx
;; 32: 5d pop rbp
;; 33: c3 ret

25
winch/filetests/filetests/x64/i32_rems/one_zero.wat

@ -0,0 +1,25 @@
;;! target = "x86_64"
(module
(func (result i32)
(i32.const 1)
(i32.const 0)
(i32.rem_s)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: b900000000 mov ecx, 0
;; 9: b801000000 mov eax, 1
;; e: 83f900 cmp ecx, 0
;; 11: 0f8502000000 jne 0x19
;; 17: 0f0b ud2
;; 19: 83f9ff cmp ecx, -1
;; 1c: 0f850a000000 jne 0x2c
;; 22: b800000000 mov eax, 0
;; 27: e903000000 jmp 0x2f
;; 2c: 99 cdq
;; 2d: f7f9 idiv ecx
;; 2f: 4889d0 mov rax, rdx
;; 32: 5d pop rbp
;; 33: c3 ret

25
winch/filetests/filetests/x64/i32_rems/overflow.wat

@ -0,0 +1,25 @@
;;! target = "x86_64"
(module
(func (result i32)
(i32.const 0x80000000)
(i32.const -1)
(i32.rem_s)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: b9ffffffff mov ecx, 0xffffffff
;; 9: b800000080 mov eax, 0x80000000
;; e: 83f900 cmp ecx, 0
;; 11: 0f8502000000 jne 0x19
;; 17: 0f0b ud2
;; 19: 83f9ff cmp ecx, -1
;; 1c: 0f850a000000 jne 0x2c
;; 22: b800000000 mov eax, 0
;; 27: e903000000 jmp 0x2f
;; 2c: 99 cdq
;; 2d: f7f9 idiv ecx
;; 2f: 4889d0 mov rax, rdx
;; 32: 5d pop rbp
;; 33: c3 ret

29
winch/filetests/filetests/x64/i32_rems/params.wat

@ -0,0 +1,29 @@
;;! target = "x86_64"
(module
(func (param i32) (param i32) (result i32)
(local.get 0)
(local.get 1)
(i32.rem_s)
)
)
;; 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: 8b0c24 mov ecx, dword ptr [rsp]
;; 12: 8b442404 mov eax, dword ptr [rsp + 4]
;; 16: 83f900 cmp ecx, 0
;; 19: 0f8502000000 jne 0x21
;; 1f: 0f0b ud2
;; 21: 83f9ff cmp ecx, -1
;; 24: 0f850a000000 jne 0x34
;; 2a: b800000000 mov eax, 0
;; 2f: e903000000 jmp 0x37
;; 34: 99 cdq
;; 35: f7f9 idiv ecx
;; 37: 4889d0 mov rax, rdx
;; 3a: 4883c408 add rsp, 8
;; 3e: 5d pop rbp
;; 3f: c3 ret

25
winch/filetests/filetests/x64/i32_rems/zero_zero.wat

@ -0,0 +1,25 @@
;;! target = "x86_64"
(module
(func (result i32)
(i32.const 0)
(i32.const 0)
(i32.rem_s)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: b900000000 mov ecx, 0
;; 9: b800000000 mov eax, 0
;; e: 83f900 cmp ecx, 0
;; 11: 0f8502000000 jne 0x19
;; 17: 0f0b ud2
;; 19: 83f9ff cmp ecx, -1
;; 1c: 0f850a000000 jne 0x2c
;; 22: b800000000 mov eax, 0
;; 27: e903000000 jmp 0x2f
;; 2c: 99 cdq
;; 2d: f7f9 idiv ecx
;; 2f: 4889d0 mov rax, rdx
;; 32: 5d pop rbp
;; 33: c3 ret

21
winch/filetests/filetests/x64/i32_remu/const.wat

@ -0,0 +1,21 @@
;;! target = "x86_64"
(module
(func (result i32)
(i32.const 7)
(i32.const 5)
(i32.rem_u)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: b905000000 mov ecx, 5
;; 9: b807000000 mov eax, 7
;; e: 83f900 cmp ecx, 0
;; 11: 0f8502000000 jne 0x19
;; 17: 0f0b ud2
;; 19: ba00000000 mov edx, 0
;; 1e: f7f1 div ecx
;; 20: 4889d0 mov rax, rdx
;; 23: 5d pop rbp
;; 24: c3 ret

21
winch/filetests/filetests/x64/i32_remu/one_zero.wat

@ -0,0 +1,21 @@
;;! target = "x86_64"
(module
(func (result i32)
(i32.const 1)
(i32.const 0)
(i32.rem_u)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: b900000000 mov ecx, 0
;; 9: b801000000 mov eax, 1
;; e: 83f900 cmp ecx, 0
;; 11: 0f8502000000 jne 0x19
;; 17: 0f0b ud2
;; 19: ba00000000 mov edx, 0
;; 1e: f7f1 div ecx
;; 20: 4889d0 mov rax, rdx
;; 23: 5d pop rbp
;; 24: c3 ret

25
winch/filetests/filetests/x64/i32_remu/params.wat

@ -0,0 +1,25 @@
;;! target = "x86_64"
(module
(func (param i32) (param i32) (result i32)
(local.get 0)
(local.get 1)
(i32.rem_u)
)
)
;; 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: 8b0c24 mov ecx, dword ptr [rsp]
;; 12: 8b442404 mov eax, dword ptr [rsp + 4]
;; 16: 83f900 cmp ecx, 0
;; 19: 0f8502000000 jne 0x21
;; 1f: 0f0b ud2
;; 21: ba00000000 mov edx, 0
;; 26: f7f1 div ecx
;; 28: 4889d0 mov rax, rdx
;; 2b: 4883c408 add rsp, 8
;; 2f: 5d pop rbp
;; 30: c3 ret

21
winch/filetests/filetests/x64/i32_remu/signed.wat

@ -0,0 +1,21 @@
;;! target = "x86_64"
(module
(func (result i32)
(i32.const -1)
(i32.const -1)
(i32.rem_u)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: b9ffffffff mov ecx, 0xffffffff
;; 9: b8ffffffff mov eax, 0xffffffff
;; e: 83f900 cmp ecx, 0
;; 11: 0f8502000000 jne 0x19
;; 17: 0f0b ud2
;; 19: ba00000000 mov edx, 0
;; 1e: f7f1 div ecx
;; 20: 4889d0 mov rax, rdx
;; 23: 5d pop rbp
;; 24: c3 ret

21
winch/filetests/filetests/x64/i32_remu/zero_zero.wat

@ -0,0 +1,21 @@
;;! target = "x86_64"
(module
(func (result i32)
(i32.const 0)
(i32.const 0)
(i32.rem_u)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: b900000000 mov ecx, 0
;; 9: b800000000 mov eax, 0
;; e: 83f900 cmp ecx, 0
;; 11: 0f8502000000 jne 0x19
;; 17: 0f0b ud2
;; 19: ba00000000 mov edx, 0
;; 1e: f7f1 div ecx
;; 20: 4889d0 mov rax, rdx
;; 23: 5d pop rbp
;; 24: c3 ret

25
winch/filetests/filetests/x64/i64_rems/const.wat

@ -0,0 +1,25 @@
;;! target = "x86_64"
(module
(func (result i64)
(i64.const 7)
(i64.const 5)
(i64.rem_s)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: 48c7c105000000 mov rcx, 5
;; b: 48c7c007000000 mov rax, 7
;; 12: 4883f900 cmp rcx, 0
;; 16: 0f8502000000 jne 0x1e
;; 1c: 0f0b ud2
;; 1e: 4883f9ff cmp rcx, -1
;; 22: 0f850a000000 jne 0x32
;; 28: b800000000 mov eax, 0
;; 2d: e905000000 jmp 0x37
;; 32: 4899 cqo
;; 34: 48f7f9 idiv rcx
;; 37: 4889d0 mov rax, rdx
;; 3a: 5d pop rbp
;; 3b: c3 ret

25
winch/filetests/filetests/x64/i64_rems/one_zero.wat

@ -0,0 +1,25 @@
;;! target = "x86_64"
(module
(func (result i64)
(i64.const 1)
(i64.const 0)
(i64.rem_s)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: 48c7c100000000 mov rcx, 0
;; b: 48c7c001000000 mov rax, 1
;; 12: 4883f900 cmp rcx, 0
;; 16: 0f8502000000 jne 0x1e
;; 1c: 0f0b ud2
;; 1e: 4883f9ff cmp rcx, -1
;; 22: 0f850a000000 jne 0x32
;; 28: b800000000 mov eax, 0
;; 2d: e905000000 jmp 0x37
;; 32: 4899 cqo
;; 34: 48f7f9 idiv rcx
;; 37: 4889d0 mov rax, rdx
;; 3a: 5d pop rbp
;; 3b: c3 ret

26
winch/filetests/filetests/x64/i64_rems/overflow.wat

@ -0,0 +1,26 @@
;;! target = "x86_64"
(module
(func (result i64)
(i64.const 0x8000000000000000)
(i64.const -1)
(i64.rem_s)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: 48c7c1ffffffff mov rcx, 0xffffffffffffffff
;; b: 48b80000000000000080
;; movabs rax, 0x8000000000000000
;; 15: 4883f900 cmp rcx, 0
;; 19: 0f8502000000 jne 0x21
;; 1f: 0f0b ud2
;; 21: 4883f9ff cmp rcx, -1
;; 25: 0f850a000000 jne 0x35
;; 2b: b800000000 mov eax, 0
;; 30: e905000000 jmp 0x3a
;; 35: 4899 cqo
;; 37: 48f7f9 idiv rcx
;; 3a: 4889d0 mov rax, rdx
;; 3d: 5d pop rbp
;; 3e: c3 ret

29
winch/filetests/filetests/x64/i64_rems/params.wat

@ -0,0 +1,29 @@
;;! target = "x86_64"
(module
(func (param i64) (param i64) (result i64)
(local.get 0)
(local.get 1)
(i64.rem_s)
)
)
;; 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: 488b0c24 mov rcx, qword ptr [rsp]
;; 15: 488b442408 mov rax, qword ptr [rsp + 8]
;; 1a: 4883f900 cmp rcx, 0
;; 1e: 0f8502000000 jne 0x26
;; 24: 0f0b ud2
;; 26: 4883f9ff cmp rcx, -1
;; 2a: 0f850a000000 jne 0x3a
;; 30: b800000000 mov eax, 0
;; 35: e905000000 jmp 0x3f
;; 3a: 4899 cqo
;; 3c: 48f7f9 idiv rcx
;; 3f: 4889d0 mov rax, rdx
;; 42: 4883c410 add rsp, 0x10
;; 46: 5d pop rbp
;; 47: c3 ret

25
winch/filetests/filetests/x64/i64_rems/zero_zero.wat

@ -0,0 +1,25 @@
;;! target = "x86_64"
(module
(func (result i64)
(i64.const 0)
(i64.const 0)
(i64.rem_s)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: 48c7c100000000 mov rcx, 0
;; b: 48c7c000000000 mov rax, 0
;; 12: 4883f900 cmp rcx, 0
;; 16: 0f8502000000 jne 0x1e
;; 1c: 0f0b ud2
;; 1e: 4883f9ff cmp rcx, -1
;; 22: 0f850a000000 jne 0x32
;; 28: b800000000 mov eax, 0
;; 2d: e905000000 jmp 0x37
;; 32: 4899 cqo
;; 34: 48f7f9 idiv rcx
;; 37: 4889d0 mov rax, rdx
;; 3a: 5d pop rbp
;; 3b: c3 ret

21
winch/filetests/filetests/x64/i64_remu/const.wat

@ -0,0 +1,21 @@
;;! target = "x86_64"
(module
(func (result i64)
(i64.const 7)
(i64.const 5)
(i64.rem_u)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: 48c7c105000000 mov rcx, 5
;; b: 48c7c007000000 mov rax, 7
;; 12: 4883f900 cmp rcx, 0
;; 16: 0f8502000000 jne 0x1e
;; 1c: 0f0b ud2
;; 1e: ba00000000 mov edx, 0
;; 23: 48f7f1 div rcx
;; 26: 4889d0 mov rax, rdx
;; 29: 5d pop rbp
;; 2a: c3 ret

21
winch/filetests/filetests/x64/i64_remu/one_zero.wat

@ -0,0 +1,21 @@
;;! target = "x86_64"
(module
(func (result i64)
(i64.const 1)
(i64.const 0)
(i64.rem_u)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: 48c7c100000000 mov rcx, 0
;; b: 48c7c001000000 mov rax, 1
;; 12: 4883f900 cmp rcx, 0
;; 16: 0f8502000000 jne 0x1e
;; 1c: 0f0b ud2
;; 1e: ba00000000 mov edx, 0
;; 23: 48f7f1 div rcx
;; 26: 4889d0 mov rax, rdx
;; 29: 5d pop rbp
;; 2a: c3 ret

25
winch/filetests/filetests/x64/i64_remu/params.wat

@ -0,0 +1,25 @@
;;! target = "x86_64"
(module
(func (param i64) (param i64) (result i64)
(local.get 0)
(local.get 1)
(i64.rem_u)
)
)
;; 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: 488b0c24 mov rcx, qword ptr [rsp]
;; 15: 488b442408 mov rax, qword ptr [rsp + 8]
;; 1a: 4883f900 cmp rcx, 0
;; 1e: 0f8502000000 jne 0x26
;; 24: 0f0b ud2
;; 26: ba00000000 mov edx, 0
;; 2b: 48f7f1 div rcx
;; 2e: 4889d0 mov rax, rdx
;; 31: 4883c410 add rsp, 0x10
;; 35: 5d pop rbp
;; 36: c3 ret

21
winch/filetests/filetests/x64/i64_remu/signed.wat

@ -0,0 +1,21 @@
;;! target = "x86_64"
(module
(func (result i64)
(i64.const -1)
(i64.const -1)
(i64.rem_u)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: 48c7c1ffffffff mov rcx, 0xffffffffffffffff
;; b: 48c7c0ffffffff mov rax, 0xffffffffffffffff
;; 12: 4883f900 cmp rcx, 0
;; 16: 0f8502000000 jne 0x1e
;; 1c: 0f0b ud2
;; 1e: ba00000000 mov edx, 0
;; 23: 48f7f1 div rcx
;; 26: 4889d0 mov rax, rdx
;; 29: 5d pop rbp
;; 2a: c3 ret

21
winch/filetests/filetests/x64/i64_remu/zero_zero.wat

@ -0,0 +1,21 @@
;;! target = "x86_64"
(module
(func (result i64)
(i64.const 0)
(i64.const 0)
(i64.rem_u)
)
)
;; 0: 55 push rbp
;; 1: 4889e5 mov rbp, rsp
;; 4: 48c7c100000000 mov rcx, 0
;; b: 48c7c000000000 mov rax, 0
;; 12: 4883f900 cmp rcx, 0
;; 16: 0f8502000000 jne 0x1e
;; 1c: 0f0b ud2
;; 1e: ba00000000 mov edx, 0
;; 23: 48f7f1 div rcx
;; 26: 4889d0 mov rax, rdx
;; 29: 5d pop rbp
;; 2a: c3 ret
Loading…
Cancel
Save