winch: Add support for <i32|i64>.rem_* WebAssembly instructions (#5823)
This commit adds support for i32 and i64 remainder instructions for x64.
This commit is contained in:
@@ -7,7 +7,7 @@ use crate::{
|
||||
abi::local::LocalSlot,
|
||||
codegen::CodeGenContext,
|
||||
isa::reg::Reg,
|
||||
masm::{DivKind, MacroAssembler as Masm, OperandSize, RegImm},
|
||||
masm::{DivKind, MacroAssembler as Masm, OperandSize, RegImm, RemKind},
|
||||
};
|
||||
use cranelift_codegen::{settings, Final, MachBufferFinalized};
|
||||
|
||||
@@ -156,6 +156,10 @@ impl Masm for MacroAssembler {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn rem(&mut self, _context: &mut CodeGenContext, _kind: RemKind, _size: OperandSize) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn zero(&mut self, reg: Reg) {
|
||||
self.asm.load_constant(0, reg);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
use crate::{
|
||||
isa::reg::Reg,
|
||||
masm::{DivKind, OperandSize},
|
||||
masm::{DivKind, OperandSize, RemKind},
|
||||
};
|
||||
use cranelift_codegen::{
|
||||
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.
|
||||
pub(crate) struct Assembler {
|
||||
/// 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.
|
||||
pub fn mul_ir(&mut self, imm: i32, dst: Reg, size: OperandSize) {
|
||||
let imm = RegMemImm::imm(imm as u32);
|
||||
|
||||
@@ -4,7 +4,7 @@ use super::{
|
||||
regs::{self, rbp, rsp},
|
||||
};
|
||||
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 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));
|
||||
}
|
||||
|
||||
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) {
|
||||
assert!(self.sp_offset == locals_size);
|
||||
|
||||
|
||||
@@ -13,6 +13,14 @@ pub(crate) enum DivKind {
|
||||
Unsigned,
|
||||
}
|
||||
|
||||
/// Remainder kind.
|
||||
pub(crate) enum RemKind {
|
||||
/// Signed remainder.
|
||||
Signed,
|
||||
/// Unsigned remainder.
|
||||
Unsigned,
|
||||
}
|
||||
|
||||
/// Operand size, in bits.
|
||||
#[derive(Copy, Clone, Eq, PartialEq)]
|
||||
pub(crate) enum OperandSize {
|
||||
@@ -116,6 +124,9 @@ pub(crate) trait MacroAssembler {
|
||||
/// functions.
|
||||
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.
|
||||
fn push(&mut self, src: Reg) -> u32;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
//! machine code emitter.
|
||||
|
||||
use crate::codegen::CodeGen;
|
||||
use crate::masm::{DivKind, MacroAssembler, OperandSize, RegImm};
|
||||
use crate::masm::{DivKind, MacroAssembler, OperandSize, RegImm, RemKind};
|
||||
use crate::stack::Val;
|
||||
use wasmparser::ValType;
|
||||
use wasmparser::VisitOperator;
|
||||
@@ -41,6 +41,10 @@ macro_rules! def_unsupported {
|
||||
(emit I32DivU $($rest:tt)*) => {};
|
||||
(emit I64DivS $($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 I64Sub $($rest:tt)*) => {};
|
||||
(emit LocalGet $($rest:tt)*) => {};
|
||||
@@ -134,6 +138,34 @@ where
|
||||
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_local_get(&mut self, index: u32) {
|
||||
|
||||
25
winch/filetests/filetests/x64/i32_rems/const.wat
Normal file
25
winch/filetests/filetests/x64/i32_rems/const.wat
Normal file
@@ -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
Normal file
25
winch/filetests/filetests/x64/i32_rems/one_zero.wat
Normal file
@@ -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
Normal file
25
winch/filetests/filetests/x64/i32_rems/overflow.wat
Normal file
@@ -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
Normal file
29
winch/filetests/filetests/x64/i32_rems/params.wat
Normal file
@@ -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
Normal file
25
winch/filetests/filetests/x64/i32_rems/zero_zero.wat
Normal file
@@ -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
Normal file
21
winch/filetests/filetests/x64/i32_remu/const.wat
Normal file
@@ -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
Normal file
21
winch/filetests/filetests/x64/i32_remu/one_zero.wat
Normal file
@@ -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
Normal file
25
winch/filetests/filetests/x64/i32_remu/params.wat
Normal file
@@ -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
Normal file
21
winch/filetests/filetests/x64/i32_remu/signed.wat
Normal file
@@ -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
Normal file
21
winch/filetests/filetests/x64/i32_remu/zero_zero.wat
Normal file
@@ -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
Normal file
25
winch/filetests/filetests/x64/i64_rems/const.wat
Normal file
@@ -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
Normal file
25
winch/filetests/filetests/x64/i64_rems/one_zero.wat
Normal file
@@ -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
Normal file
26
winch/filetests/filetests/x64/i64_rems/overflow.wat
Normal file
@@ -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
Normal file
29
winch/filetests/filetests/x64/i64_rems/params.wat
Normal file
@@ -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
Normal file
25
winch/filetests/filetests/x64/i64_rems/zero_zero.wat
Normal file
@@ -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
Normal file
21
winch/filetests/filetests/x64/i64_remu/const.wat
Normal file
@@ -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
Normal file
21
winch/filetests/filetests/x64/i64_remu/one_zero.wat
Normal file
@@ -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
Normal file
25
winch/filetests/filetests/x64/i64_remu/params.wat
Normal file
@@ -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
Normal file
21
winch/filetests/filetests/x64/i64_remu/signed.wat
Normal file
@@ -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
Normal file
21
winch/filetests/filetests/x64/i64_remu/zero_zero.wat
Normal file
@@ -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
|
||||
Reference in New Issue
Block a user