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:
Saúl Cabrera
2023-02-20 12:52:06 -05:00
committed by GitHub
parent c26a65a854
commit 4d954f5c0e
25 changed files with 579 additions and 4 deletions

View File

@@ -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);