|
2 | 2 |
|
3 | 3 | use crate::{ |
4 | 4 | isa::reg::Reg, |
5 | | - masm::{DivKind, OperandSize}, |
| 5 | + masm::{DivKind, OperandSize, RemKind}, |
6 | 6 | }; |
7 | 7 | use cranelift_codegen::{ |
8 | 8 | isa::x64::{ |
@@ -73,6 +73,15 @@ impl From<DivKind> for DivOrRemKind { |
73 | 73 | } |
74 | 74 | } |
75 | 75 |
|
| 76 | +impl From<RemKind> for DivOrRemKind { |
| 77 | + fn from(kind: RemKind) -> Self { |
| 78 | + match kind { |
| 79 | + RemKind::Signed => DivOrRemKind::SignedRem, |
| 80 | + RemKind::Unsigned => DivOrRemKind::UnsignedRem, |
| 81 | + } |
| 82 | + } |
| 83 | +} |
| 84 | + |
76 | 85 | /// Low level assembler implementation for x64. |
77 | 86 | pub(crate) struct Assembler { |
78 | 87 | /// The machine instruction buffer. |
@@ -299,6 +308,26 @@ impl Assembler { |
299 | 308 | }); |
300 | 309 | } |
301 | 310 |
|
| 311 | + /// Signed/unsigned remainder. |
| 312 | + /// |
| 313 | + /// Emits a sequence of instructions to ensure the correctness of the |
| 314 | + /// division invariants and ultimately calculate the remainder. |
| 315 | + /// This function assumes that the |
| 316 | + /// caller has correctly allocated the dividend as `(rdx:rax)` and |
| 317 | + /// accounted for the remainder to be stored in `rdx`. |
| 318 | + pub fn rem(&mut self, divisor: Reg, dst: (Reg, Reg), kind: RemKind, size: OperandSize) { |
| 319 | + self.emit(Inst::CheckedDivOrRemSeq { |
| 320 | + kind: kind.into(), |
| 321 | + size: size.into(), |
| 322 | + divisor: divisor.into(), |
| 323 | + dividend_lo: dst.0.into(), |
| 324 | + dividend_hi: dst.1.into(), |
| 325 | + dst_quotient: dst.0.into(), |
| 326 | + dst_remainder: dst.1.into(), |
| 327 | + tmp: None, |
| 328 | + }); |
| 329 | + } |
| 330 | + |
302 | 331 | /// Multiply immediate and register. |
303 | 332 | pub fn mul_ir(&mut self, imm: i32, dst: Reg, size: OperandSize) { |
304 | 333 | let imm = RegMemImm::imm(imm as u32); |
|
0 commit comments