mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-01 15:51:12 +00:00
make mov between different-sized registers more robust
This commit is contained in:
parent
17fde9dd9d
commit
9bdf9e4b99
3 changed files with 55 additions and 8 deletions
|
@ -751,8 +751,18 @@ impl Assembler<AArch64GeneralReg, AArch64FloatReg> for AArch64Assembler {
|
|||
fmov_freg_freg(buf, FloatWidth::F64, dst, src);
|
||||
}
|
||||
#[inline(always)]
|
||||
fn mov_reg64_reg64(buf: &mut Vec<'_, u8>, dst: AArch64GeneralReg, src: AArch64GeneralReg) {
|
||||
mov_reg64_reg64(buf, dst, src);
|
||||
fn mov_reg_reg(
|
||||
buf: &mut Vec<'_, u8>,
|
||||
register_width: RegisterWidth,
|
||||
dst: AArch64GeneralReg,
|
||||
src: AArch64GeneralReg,
|
||||
) {
|
||||
match register_width {
|
||||
RegisterWidth::W8 => todo!(),
|
||||
RegisterWidth::W16 => todo!(),
|
||||
RegisterWidth::W32 => todo!(),
|
||||
RegisterWidth::W64 => mov_reg64_reg64(buf, dst, src),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
|
|
@ -37,6 +37,18 @@ pub enum RegisterWidth {
|
|||
W64,
|
||||
}
|
||||
|
||||
impl RegisterWidth {
|
||||
fn try_from_layout(layout: InLayout) -> Option<Self> {
|
||||
match layout {
|
||||
Layout::BOOL | Layout::I8 | Layout::U8 => Some(RegisterWidth::W8),
|
||||
Layout::I16 | Layout::U16 => Some(RegisterWidth::W16),
|
||||
Layout::U32 | Layout::I32 => Some(RegisterWidth::W32),
|
||||
Layout::I64 | Layout::U64 => Some(RegisterWidth::W64),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait CallConv<GeneralReg: RegTrait, FloatReg: RegTrait, ASM: Assembler<GeneralReg, FloatReg>>:
|
||||
Sized + Copy
|
||||
{
|
||||
|
@ -256,7 +268,25 @@ pub trait Assembler<GeneralReg: RegTrait, FloatReg: RegTrait>: Sized + Copy {
|
|||
);
|
||||
fn mov_reg64_imm64(buf: &mut Vec<'_, u8>, dst: GeneralReg, imm: i64);
|
||||
fn mov_freg64_freg64(buf: &mut Vec<'_, u8>, dst: FloatReg, src: FloatReg);
|
||||
fn mov_reg64_reg64(buf: &mut Vec<'_, u8>, dst: GeneralReg, src: GeneralReg);
|
||||
|
||||
fn mov_reg_reg(
|
||||
buf: &mut Vec<'_, u8>,
|
||||
register_width: RegisterWidth,
|
||||
dst: GeneralReg,
|
||||
src: GeneralReg,
|
||||
);
|
||||
fn mov_reg64_reg64(buf: &mut Vec<'_, u8>, dst: GeneralReg, src: GeneralReg) {
|
||||
Self::mov_reg_reg(buf, RegisterWidth::W64, dst, src);
|
||||
}
|
||||
fn mov_reg32_reg32(buf: &mut Vec<'_, u8>, dst: GeneralReg, src: GeneralReg) {
|
||||
Self::mov_reg_reg(buf, RegisterWidth::W32, dst, src);
|
||||
}
|
||||
fn mov_reg16_reg16(buf: &mut Vec<'_, u8>, dst: GeneralReg, src: GeneralReg) {
|
||||
Self::mov_reg_reg(buf, RegisterWidth::W16, dst, src);
|
||||
}
|
||||
fn mov_reg8_reg8(buf: &mut Vec<'_, u8>, dst: GeneralReg, src: GeneralReg) {
|
||||
Self::mov_reg_reg(buf, RegisterWidth::W8, dst, src);
|
||||
}
|
||||
|
||||
// base32 is similar to stack based instructions but they reference the base/frame pointer.
|
||||
fn mov_freg64_base32(buf: &mut Vec<'_, u8>, dst: FloatReg, offset: i32);
|
||||
|
@ -800,8 +830,10 @@ impl<
|
|||
// move return value to dst.
|
||||
match *ret_layout {
|
||||
single_register_integers!() => {
|
||||
let width = RegisterWidth::try_from_layout(*ret_layout).unwrap();
|
||||
|
||||
let dst_reg = self.storage_manager.claim_general_reg(&mut self.buf, dst);
|
||||
ASM::mov_reg64_reg64(&mut self.buf, dst_reg, CC::GENERAL_RETURN_REGS[0]);
|
||||
ASM::mov_reg_reg(&mut self.buf, width, dst_reg, CC::GENERAL_RETURN_REGS[0]);
|
||||
}
|
||||
single_register_floats!() => {
|
||||
let dst_reg = self.storage_manager.claim_float_reg(&mut self.buf, dst);
|
||||
|
|
|
@ -4,10 +4,10 @@ use crate::{
|
|||
single_register_layouts, Relocation,
|
||||
};
|
||||
use bumpalo::collections::Vec;
|
||||
use roc_builtins::bitcode::FloatWidth;
|
||||
use roc_builtins::bitcode::{FloatWidth, IntWidth};
|
||||
use roc_error_macros::internal_error;
|
||||
use roc_module::symbol::Symbol;
|
||||
use roc_mono::layout::{InLayout, Layout, LayoutInterner, STLayoutInterner, UnionLayout};
|
||||
use roc_mono::layout::{Builtin, InLayout, Layout, LayoutInterner, STLayoutInterner, UnionLayout};
|
||||
|
||||
use super::{CompareOperation, RegisterWidth};
|
||||
|
||||
|
@ -1425,8 +1425,13 @@ impl Assembler<X86_64GeneralReg, X86_64FloatReg> for X86_64Assembler {
|
|||
movsd_freg64_freg64(buf, dst, src);
|
||||
}
|
||||
#[inline(always)]
|
||||
fn mov_reg64_reg64(buf: &mut Vec<'_, u8>, dst: X86_64GeneralReg, src: X86_64GeneralReg) {
|
||||
mov_reg64_reg64(buf, dst, src);
|
||||
fn mov_reg_reg(
|
||||
buf: &mut Vec<'_, u8>,
|
||||
register_width: RegisterWidth,
|
||||
dst: X86_64GeneralReg,
|
||||
src: X86_64GeneralReg,
|
||||
) {
|
||||
mov_reg_reg(buf, register_width, dst, src);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue