missing functions for dev backend for glue

This commit is contained in:
Folkert 2024-01-27 14:51:09 +01:00
parent e2dac4f022
commit 1e744dca7c
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C
9 changed files with 113 additions and 17 deletions

View file

@ -1668,6 +1668,11 @@ impl Assembler<AArch64GeneralReg, AArch64FloatReg> for AArch64Assembler {
Self::mov_freg64_mem64_offset32(buf, dst, AArch64GeneralReg::FP, offset)
}
#[inline(always)]
fn mov_freg32_base32(buf: &mut Vec<'_, u8>, dst: AArch64FloatReg, offset: i32) {
Self::mov_freg32_mem32_offset32(buf, dst, AArch64GeneralReg::FP, offset)
}
#[inline(always)]
fn mov_reg_mem_offset32(
buf: &mut Vec<'_, u8>,

View file

@ -358,6 +358,7 @@ pub trait Assembler<GeneralReg: RegTrait, FloatReg: RegTrait>: Sized + Copy {
// 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);
fn mov_freg32_base32(buf: &mut Vec<'_, u8>, dst: FloatReg, offset: i32);
fn mov_reg_base32(
buf: &mut Vec<'_, u8>,
@ -2154,6 +2155,30 @@ impl<
);
}
fn build_int_to_float_cast(
&mut self,
dst: &Symbol,
src: &Symbol,
int_width: IntWidth,
float_width: FloatWidth,
) {
use roc_builtins::bitcode::{INT_TO_FLOAT_CAST_F32, INT_TO_FLOAT_CAST_F64};
self.build_fn_call(
dst,
match float_width {
FloatWidth::F32 => INT_TO_FLOAT_CAST_F32[int_width].to_string(),
FloatWidth::F64 => INT_TO_FLOAT_CAST_F64[int_width].to_string(),
},
&[*src],
&[Layout::from_int_width(int_width)],
match float_width {
FloatWidth::F32 => &Layout::F32,
FloatWidth::F64 => &Layout::F64,
},
);
}
fn build_num_cmp(
&mut self,
dst: &Symbol,

View file

@ -448,17 +448,26 @@ impl<
}
Stack(ReferencedPrimitive {
base_offset, size, ..
}) if base_offset % 8 == 0 && size == 8 => {
// The primitive is aligned and the data is exactly 8 bytes, treat it like regular stack.
let reg = self.get_float_reg(buf);
ASM::mov_freg64_base32(buf, reg, base_offset);
self.float_used_regs.push((reg, *sym));
self.symbol_storage_map.insert(*sym, Reg(Float(reg)));
self.free_reference(sym);
reg
}
Stack(ReferencedPrimitive { .. }) => {
todo!("loading referenced primitives")
}) => {
if base_offset % 8 == 0 && size == 8 {
// The primitive is aligned and the data is exactly 8 bytes, treat it like regular stack.
let reg = self.get_float_reg(buf);
ASM::mov_freg64_base32(buf, reg, base_offset);
self.float_used_regs.push((reg, *sym));
self.symbol_storage_map.insert(*sym, Reg(Float(reg)));
self.free_reference(sym);
reg
} else if base_offset % 4 == 0 && size == 4 {
// The primitive is aligned and the data is exactly 8 bytes, treat it like regular stack.
let reg = self.get_float_reg(buf);
ASM::mov_freg32_base32(buf, reg, base_offset);
self.float_used_regs.push((reg, *sym));
self.symbol_storage_map.insert(*sym, Reg(Float(reg)));
self.free_reference(sym);
reg
} else {
todo!("loading referenced primitives")
}
}
Stack(Complex { .. }) => {
internal_error!("Cannot load large values into float registers: {}", sym)
@ -570,12 +579,15 @@ impl<
}
Stack(ReferencedPrimitive {
base_offset, size, ..
}) if base_offset % 8 == 0 && *size == 8 => {
// The primitive is aligned and the data is exactly 8 bytes, treat it like regular stack.
ASM::mov_freg64_base32(buf, reg, *base_offset);
}
Stack(ReferencedPrimitive { .. }) => {
todo!("loading referenced primitives")
}) => {
if base_offset % 8 == 0 && *size == 8 {
// The primitive is aligned and the data is exactly 8 bytes, treat it like regular stack.
ASM::mov_freg64_base32(buf, reg, *base_offset);
} else if base_offset % 4 == 0 && *size == 4 {
ASM::mov_freg32_base32(buf, reg, *base_offset);
} else {
todo!("loading referenced primitives")
}
}
Stack(Complex { .. }) => {
internal_error!("Cannot load large values into float registers: {}", sym)

View file

@ -2433,6 +2433,11 @@ impl Assembler<X86_64GeneralReg, X86_64FloatReg> for X86_64Assembler {
movsd_freg64_base64_offset32(buf, dst, X86_64GeneralReg::RBP, offset)
}
#[inline(always)]
fn mov_freg32_base32(buf: &mut Vec<'_, u8>, dst: X86_64FloatReg, offset: i32) {
movss_freg32_base32_offset32(buf, dst, X86_64GeneralReg::RBP, offset)
}
#[inline(always)]
fn mov_reg_base32(
buf: &mut Vec<'_, u8>,

View file

@ -2019,6 +2019,24 @@ trait Backend<'a> {
self.build_num_cmp(sym, &args[0], &args[1], &arg_layouts[0]);
}
LowLevel::NumToFloatCast => {
let float_width = match *ret_layout {
Layout::F64 => FloatWidth::F64,
Layout::F32 => FloatWidth::F32,
_ => unreachable!("invalid return layout for NumToFloatCast"),
};
match arg_layouts[0].try_to_int_width() {
Some(int_width) => {
self.build_int_to_float_cast(sym, &args[0], int_width, float_width);
}
None => {
//
todo!("other NumToFloatCast cases");
}
}
}
x => todo!("low level, {:?}", x),
}
}
@ -2135,6 +2153,14 @@ trait Backend<'a> {
target: IntWidth,
);
fn build_int_to_float_cast(
&mut self,
dst: &Symbol,
src: &Symbol,
int_width: IntWidth,
float_width: FloatWidth,
);
/// build_num_abs stores the absolute value of src into dst.
fn build_num_abs(&mut self, dst: &Symbol, src: &Symbol, layout: &InLayout<'a>);