mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-27 22:09:09 +00:00
128-bit multiplication
This commit is contained in:
parent
2b849f167f
commit
0f058c8b46
4 changed files with 43 additions and 28 deletions
|
@ -848,6 +848,13 @@ impl<
|
|||
let dst_reg = self.storage_manager.claim_float_reg(&mut self.buf, dst);
|
||||
ASM::mov_freg64_freg64(&mut self.buf, dst_reg, CC::FLOAT_RETURN_REGS[0]);
|
||||
}
|
||||
Layout::I128 | Layout::U128 => {
|
||||
let offset = self.storage_manager.claim_stack_area(dst, 16);
|
||||
|
||||
ASM::mov_base32_reg64(&mut self.buf, offset + 0, CC::GENERAL_RETURN_REGS[0]);
|
||||
ASM::mov_base32_reg64(&mut self.buf, offset + 8, CC::GENERAL_RETURN_REGS[1]);
|
||||
}
|
||||
|
||||
other => {
|
||||
//
|
||||
match self.layout_interner.get(other) {
|
||||
|
|
|
@ -458,8 +458,32 @@ impl X64_64SystemVStoreArgs {
|
|||
match in_layout {
|
||||
single_register_integers!() => self.store_arg_general(buf, storage_manager, sym),
|
||||
single_register_floats!() => self.store_arg_float(buf, storage_manager, sym),
|
||||
Layout::I128 | Layout::U128 => {
|
||||
let (offset, _) = storage_manager.stack_offset_and_size(&sym);
|
||||
|
||||
if self.general_i + 1 < Self::GENERAL_PARAM_REGS.len() {
|
||||
let reg1 = Self::GENERAL_PARAM_REGS[self.general_i + 0];
|
||||
let reg2 = Self::GENERAL_PARAM_REGS[self.general_i + 1];
|
||||
|
||||
X86_64Assembler::mov_reg64_base32(buf, reg1, offset + 0);
|
||||
X86_64Assembler::mov_reg64_base32(buf, reg2, offset + 8);
|
||||
|
||||
self.general_i += 2;
|
||||
} else {
|
||||
// Copy to stack using return reg as buffer.
|
||||
let reg = Self::GENERAL_RETURN_REGS[0];
|
||||
|
||||
X86_64Assembler::mov_reg64_base32(buf, reg, offset + 0);
|
||||
X86_64Assembler::mov_stack32_reg64(buf, self.tmp_stack_offset + 0, reg);
|
||||
|
||||
X86_64Assembler::mov_reg64_base32(buf, reg, offset + 8);
|
||||
X86_64Assembler::mov_stack32_reg64(buf, self.tmp_stack_offset + 8, reg);
|
||||
|
||||
self.tmp_stack_offset += 16;
|
||||
}
|
||||
}
|
||||
x if layout_interner.stack_size(x) == 0 => {}
|
||||
x if layout_interner.stack_size(x) > 16 => {
|
||||
x if layout_interner.stack_size(x) == 16 => {
|
||||
// TODO: Double check this.
|
||||
// Just copy onto the stack.
|
||||
// Use return reg as buffer because it will be empty right now.
|
||||
|
|
|
@ -546,22 +546,8 @@ trait Backend<'a> {
|
|||
arg_layouts,
|
||||
ret_layout,
|
||||
),
|
||||
LowLevel::NumMul => {
|
||||
debug_assert_eq!(
|
||||
2,
|
||||
args.len(),
|
||||
"NumMul: expected to have exactly two argument"
|
||||
);
|
||||
debug_assert_eq!(
|
||||
arg_layouts[0], arg_layouts[1],
|
||||
"NumMul: expected all arguments of to have the same layout"
|
||||
);
|
||||
debug_assert_eq!(
|
||||
arg_layouts[0], *ret_layout,
|
||||
"NumMul: expected to have the same argument and return layout"
|
||||
);
|
||||
self.build_num_mul(sym, &args[0], &args[1], ret_layout)
|
||||
}
|
||||
LowLevel::NumMul => self.build_num_mul(sym, &args[0], &args[1], ret_layout),
|
||||
LowLevel::NumMulWrap => self.build_num_mul(sym, &args[0], &args[1], ret_layout),
|
||||
LowLevel::NumDivTruncUnchecked | LowLevel::NumDivFrac => {
|
||||
debug_assert_eq!(
|
||||
2,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue