mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 14:54:47 +00:00
float and nested records to the dev backend
This commit is contained in:
parent
950d380ea0
commit
210004529d
2 changed files with 124 additions and 35 deletions
|
@ -639,6 +639,25 @@ impl<
|
||||||
CC: CallConv<GeneralReg, FloatReg>,
|
CC: CallConv<GeneralReg, FloatReg>,
|
||||||
> Backend64Bit<'a, GeneralReg, FloatReg, ASM, CC>
|
> Backend64Bit<'a, GeneralReg, FloatReg, ASM, CC>
|
||||||
{
|
{
|
||||||
|
fn get_tmp_general_reg(&mut self) -> Result<GeneralReg, String> {
|
||||||
|
if !self.general_free_regs.is_empty() {
|
||||||
|
let free_reg = *self
|
||||||
|
.general_free_regs
|
||||||
|
.get(self.general_free_regs.len() - 1)
|
||||||
|
.unwrap();
|
||||||
|
if CC::general_callee_saved(&free_reg) {
|
||||||
|
self.general_used_callee_saved_regs.insert(free_reg);
|
||||||
|
}
|
||||||
|
Ok(free_reg)
|
||||||
|
} else if !self.general_used_regs.is_empty() {
|
||||||
|
let (reg, sym) = self.general_used_regs.remove(0);
|
||||||
|
self.free_to_stack(&sym)?;
|
||||||
|
Ok(reg)
|
||||||
|
} else {
|
||||||
|
Err("completely out of general purpose registers".to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn claim_general_reg(&mut self, sym: &Symbol) -> Result<GeneralReg, String> {
|
fn claim_general_reg(&mut self, sym: &Symbol) -> Result<GeneralReg, String> {
|
||||||
let reg = if !self.general_free_regs.is_empty() {
|
let reg = if !self.general_free_regs.is_empty() {
|
||||||
let free_reg = self.general_free_regs.pop().unwrap();
|
let free_reg = self.general_free_regs.pop().unwrap();
|
||||||
|
@ -793,16 +812,33 @@ impl<
|
||||||
|
|
||||||
fn copy_symbol_to_stack_offset(
|
fn copy_symbol_to_stack_offset(
|
||||||
&mut self,
|
&mut self,
|
||||||
offset: i32,
|
to_offset: i32,
|
||||||
sym: &Symbol,
|
sym: &Symbol,
|
||||||
layout: &Layout<'a>,
|
layout: &Layout<'a>,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
match layout {
|
match layout {
|
||||||
Layout::Builtin(Builtin::Int64) => {
|
Layout::Builtin(Builtin::Int64) => {
|
||||||
let reg = self.load_to_general_reg(sym)?;
|
let reg = self.load_to_general_reg(sym)?;
|
||||||
ASM::mov_base32_reg64(&mut self.buf, offset, reg);
|
ASM::mov_base32_reg64(&mut self.buf, to_offset, reg);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Layout::Builtin(Builtin::Float64) => {
|
||||||
|
let reg = self.load_to_float_reg(sym)?;
|
||||||
|
ASM::mov_base32_freg64(&mut self.buf, to_offset, reg);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Layout::Struct(_) if layout.safe_to_memcpy() => {
|
||||||
|
let tmp_reg = self.get_tmp_general_reg()?;
|
||||||
|
if let Some(SymbolStorage::Base(from_offset)) = self.symbol_storage_map.get(sym) {
|
||||||
|
for i in 0..layout.stack_size(PTR_SIZE) as i32 {
|
||||||
|
ASM::mov_reg64_base32(&mut self.buf, tmp_reg, from_offset + i);
|
||||||
|
ASM::mov_base32_reg64(&mut self.buf, to_offset + i, tmp_reg);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(format!("unknown struct: {:?}", sym))
|
||||||
|
}
|
||||||
|
}
|
||||||
x => Err(format!(
|
x => Err(format!(
|
||||||
"copying data to the stack with layout, {:?}, not implemented yet",
|
"copying data to the stack with layout, {:?}, not implemented yet",
|
||||||
x
|
x
|
||||||
|
|
|
@ -39,44 +39,97 @@ mod gen_record {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[test]
|
#[test]
|
||||||
// fn f64_record() {
|
fn nested_record() {
|
||||||
// assert_evals_to!(
|
assert_evals_to!(
|
||||||
// indoc!(
|
indoc!(
|
||||||
// r#"
|
r#"
|
||||||
// rec = { y: 17.2, x: 15.1, z: 19.3 }
|
{ x: 15, y: { a: 12, b: 15, c: 2}, z: 19 }.x
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
15,
|
||||||
|
i64
|
||||||
|
);
|
||||||
|
|
||||||
// rec.x
|
assert_evals_to!(
|
||||||
// "#
|
indoc!(
|
||||||
// ),
|
r#"
|
||||||
// 15.1,
|
{ x: 15, y: { a: 12, b: 15, c: 2}, z: 19 }.y.a
|
||||||
// f64
|
"#
|
||||||
// );
|
),
|
||||||
|
12,
|
||||||
|
i64
|
||||||
|
);
|
||||||
|
|
||||||
// assert_evals_to!(
|
assert_evals_to!(
|
||||||
// indoc!(
|
indoc!(
|
||||||
// r#"
|
r#"
|
||||||
// rec = { y: 17.2, x: 15.1, z: 19.3 }
|
{ x: 15, y: { a: 12, b: 15, c: 2}, z: 19 }.y.b
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
15,
|
||||||
|
i64
|
||||||
|
);
|
||||||
|
|
||||||
// rec.y
|
assert_evals_to!(
|
||||||
// "#
|
indoc!(
|
||||||
// ),
|
r#"
|
||||||
// 17.2,
|
{ x: 15, y: { a: 12, b: 15, c: 2}, z: 19 }.y.c
|
||||||
// f64
|
"#
|
||||||
// );
|
),
|
||||||
|
2,
|
||||||
|
i64
|
||||||
|
);
|
||||||
|
|
||||||
// assert_evals_to!(
|
assert_evals_to!(
|
||||||
// indoc!(
|
indoc!(
|
||||||
// r#"
|
r#"
|
||||||
// rec = { y: 17.2, x: 15.1, z: 19.3 }
|
{ x: 15, y: { a: 12, b: 15, c: 2}, z: 19 }.z
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
19,
|
||||||
|
i64
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// rec.z
|
#[test]
|
||||||
// "#
|
fn f64_record() {
|
||||||
// ),
|
assert_evals_to!(
|
||||||
// 19.3,
|
indoc!(
|
||||||
// f64
|
r#"
|
||||||
// );
|
rec = { y: 17.2, x: 15.1, z: 19.3 }
|
||||||
// }
|
|
||||||
|
rec.x
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
15.1,
|
||||||
|
f64
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_evals_to!(
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
rec = { y: 17.2, x: 15.1, z: 19.3 }
|
||||||
|
|
||||||
|
rec.y
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
17.2,
|
||||||
|
f64
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_evals_to!(
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
rec = { y: 17.2, x: 15.1, z: 19.3 }
|
||||||
|
|
||||||
|
rec.z
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
19.3,
|
||||||
|
f64
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// #[test]
|
// #[test]
|
||||||
// fn fn_record() {
|
// fn fn_record() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue