mirror of
https://github.com/roc-lang/roc.git
synced 2025-07-24 06:55:15 +00:00
dev backend unsigned multiply: round 2
This commit is contained in:
parent
3f6f070042
commit
2a302cfc46
4 changed files with 30 additions and 11 deletions
|
@ -21,7 +21,7 @@ mod disassembler_test_macro;
|
|||
pub(crate) mod storage;
|
||||
pub(crate) mod x86_64;
|
||||
|
||||
use storage::StorageManager;
|
||||
use storage::{RegStorage, StorageManager};
|
||||
|
||||
const REFCOUNT_ONE: u64 = i64::MIN as u64;
|
||||
// TODO: on all number functions double check and deal with over/underflow.
|
||||
|
@ -773,14 +773,24 @@ impl<
|
|||
Layout::Builtin(Builtin::Int(
|
||||
IntWidth::U64 | IntWidth::U32 | IntWidth::U16 | IntWidth::U8,
|
||||
)) => {
|
||||
// TODO find a general way to do this
|
||||
let rax = CC::GENERAL_RETURN_REGS[0];
|
||||
let rdx = CC::GENERAL_RETURN_REGS[1];
|
||||
|
||||
self.storage_manager
|
||||
.ensure_reg_free(&mut self.buf, RegStorage::General(rax));
|
||||
|
||||
self.storage_manager
|
||||
.ensure_reg_free(&mut self.buf, RegStorage::General(rdx));
|
||||
|
||||
self.storage_manager
|
||||
.load_to_specified_general_reg(&mut self.buf, src1, rax);
|
||||
|
||||
let dst_reg = self.storage_manager.claim_general_reg(&mut self.buf, dst);
|
||||
let src1_reg = self
|
||||
.storage_manager
|
||||
.load_to_general_reg(&mut self.buf, src1);
|
||||
let src2_reg = self
|
||||
.storage_manager
|
||||
.load_to_general_reg(&mut self.buf, src2);
|
||||
ASM::umul_reg64_reg64_reg64(&mut self.buf, dst_reg, src1_reg, src2_reg);
|
||||
ASM::umul_reg64_reg64_reg64(&mut self.buf, dst_reg, rax, src2_reg);
|
||||
}
|
||||
Layout::Builtin(Builtin::Float(FloatWidth::F64)) => {
|
||||
let dst_reg = self.storage_manager.claim_float_reg(&mut self.buf, dst);
|
||||
|
|
|
@ -22,7 +22,7 @@ use StackStorage::*;
|
|||
use Storage::*;
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
enum RegStorage<GeneralReg: RegTrait, FloatReg: RegTrait> {
|
||||
pub enum RegStorage<GeneralReg: RegTrait, FloatReg: RegTrait> {
|
||||
General(GeneralReg),
|
||||
Float(FloatReg),
|
||||
}
|
||||
|
@ -756,7 +756,7 @@ impl<
|
|||
|
||||
#[allow(dead_code)]
|
||||
/// Ensures that a register is free. If it is not free, data will be moved to make it free.
|
||||
fn ensure_reg_free(
|
||||
pub fn ensure_reg_free(
|
||||
&mut self,
|
||||
buf: &mut Vec<'a, u8>,
|
||||
wanted_reg: RegStorage<GeneralReg, FloatReg>,
|
||||
|
|
|
@ -1017,7 +1017,7 @@ impl Assembler<X86_64GeneralReg, X86_64FloatReg> for X86_64Assembler {
|
|||
src2: X86_64GeneralReg,
|
||||
) {
|
||||
mov_reg64_reg64(buf, dst, src1);
|
||||
mul_reg64_reg64(buf, dst, src2);
|
||||
mul_reg64_reg64(buf, src2);
|
||||
}
|
||||
|
||||
fn mul_freg32_freg32_freg32(
|
||||
|
@ -1550,8 +1550,8 @@ fn imul_reg64_reg64(buf: &mut Vec<'_, u8>, dst: X86_64GeneralReg, src: X86_64Gen
|
|||
|
||||
/// `MUL r/m64` -> Unsigned Multiply r/m64 to r64.
|
||||
#[inline(always)]
|
||||
fn mul_reg64_reg64(buf: &mut Vec<'_, u8>, dst: X86_64GeneralReg, src: X86_64GeneralReg) {
|
||||
todo!()
|
||||
fn mul_reg64_reg64(buf: &mut Vec<'_, u8>, src: X86_64GeneralReg) {
|
||||
binop_reg64_reg64(0xF7, buf, X86_64GeneralReg::RAX, src);
|
||||
}
|
||||
|
||||
/// Jump near, relative, RIP = RIP + 32-bit displacement sign extended to 64-bits.
|
||||
|
@ -2175,6 +2175,15 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mul_reg64_reg64() {
|
||||
disassembler_test!(
|
||||
mul_reg64_reg64,
|
||||
|reg| format!("mul {}", reg),
|
||||
ALL_GENERAL_REGS
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mulsd_freg64_freg64() {
|
||||
disassembler_test!(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue