mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-27 05:49:08 +00:00
dev backend: Box.unbox and List.get str
This commit is contained in:
parent
4d1a6b17a8
commit
8df8c19ae2
3 changed files with 87 additions and 16 deletions
|
@ -1510,34 +1510,34 @@ impl<
|
|||
|storage_manager, buf, list_ptr| {
|
||||
ASM::mov_reg64_base32(buf, list_ptr, base_offset as i32);
|
||||
storage_manager.with_tmp_general_reg(buf, |storage_manager, buf, tmp| {
|
||||
// calculate `element_width * index`
|
||||
ASM::mov_reg64_imm64(buf, tmp, ret_stack_size as i64);
|
||||
ASM::imul_reg64_reg64_reg64(buf, tmp, tmp, index_reg);
|
||||
|
||||
// add the offset to the list pointer, store in `tmp`
|
||||
ASM::add_reg64_reg64_reg64(buf, tmp, tmp, list_ptr);
|
||||
let element_ptr = tmp;
|
||||
|
||||
match *ret_layout {
|
||||
single_register_integers!() if ret_stack_size == 8 => {
|
||||
let dst_reg = storage_manager.claim_general_reg(buf, dst);
|
||||
ASM::mov_reg64_mem64_offset32(buf, dst_reg, tmp, 0);
|
||||
ASM::mov_reg64_mem64_offset32(buf, dst_reg, element_ptr, 0);
|
||||
}
|
||||
single_register_floats!() => {
|
||||
let dst_reg = storage_manager.claim_float_reg(buf, dst);
|
||||
ASM::mov_freg64_freg64(buf, dst_reg, CC::FLOAT_RETURN_REGS[0]);
|
||||
}
|
||||
Layout::STR => {
|
||||
let dst_reg = storage_manager.claim_general_reg(buf, dst);
|
||||
// the `list_ptr` register is now unused, and we can use it as scratch space
|
||||
let tmp_reg = list_ptr;
|
||||
|
||||
let base_offset = storage_manager.claim_stack_area(dst, 24);
|
||||
|
||||
// move 1 into a register
|
||||
ASM::mov_mem64_offset32_reg64(buf, dst_reg, 0, tmp);
|
||||
ASM::mov_base32_reg64(buf, base_offset + 0, dst_reg);
|
||||
|
||||
// word 2
|
||||
ASM::mov_mem64_offset32_reg64(buf, dst_reg, 8, tmp);
|
||||
ASM::mov_base32_reg64(buf, base_offset + 8, dst_reg);
|
||||
|
||||
// word 3
|
||||
ASM::mov_mem64_offset32_reg64(buf, dst_reg, 16, tmp);
|
||||
ASM::mov_base32_reg64(buf, base_offset + 16, dst_reg);
|
||||
Self::unbox_str_or_list(
|
||||
buf,
|
||||
storage_manager,
|
||||
*dst,
|
||||
element_ptr,
|
||||
tmp_reg,
|
||||
);
|
||||
}
|
||||
other => {
|
||||
//
|
||||
|
@ -2056,6 +2056,14 @@ impl<
|
|||
let dst_reg = self.storage_manager.claim_general_reg(&mut self.buf, &dst);
|
||||
ASM::mov_reg64_mem64_offset32(&mut self.buf, dst_reg, ptr_reg, 0);
|
||||
}
|
||||
Layout::STR => {
|
||||
self.storage_manager.with_tmp_general_reg(
|
||||
&mut self.buf,
|
||||
|storage_manager, buf, tmp_reg| {
|
||||
Self::unbox_str_or_list(buf, storage_manager, dst, ptr_reg, tmp_reg);
|
||||
},
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
todo!("unboxing of {:?}", self.layout_interner.dbg(element_layout))
|
||||
}
|
||||
|
@ -2418,6 +2426,25 @@ impl<
|
|||
);
|
||||
}
|
||||
|
||||
fn unbox_str_or_list(
|
||||
buf: &mut Vec<'a, u8>,
|
||||
storage_manager: &mut StorageManager<'a, 'r, GeneralReg, FloatReg, ASM, CC>,
|
||||
dst: Symbol,
|
||||
ptr_reg: GeneralReg,
|
||||
tmp_reg: GeneralReg,
|
||||
) {
|
||||
let base_offset = storage_manager.claim_stack_area(&dst, 24);
|
||||
|
||||
ASM::mov_reg64_mem64_offset32(buf, tmp_reg, ptr_reg, 0);
|
||||
ASM::mov_base32_reg64(buf, base_offset + 0, tmp_reg);
|
||||
|
||||
ASM::mov_reg64_mem64_offset32(buf, tmp_reg, ptr_reg, 8);
|
||||
ASM::mov_base32_reg64(buf, base_offset + 8, tmp_reg);
|
||||
|
||||
ASM::mov_reg64_mem64_offset32(buf, tmp_reg, ptr_reg, 16);
|
||||
ASM::mov_base32_reg64(buf, base_offset + 16, tmp_reg);
|
||||
}
|
||||
|
||||
/// Updates a jump instruction to a new offset and returns the number of bytes written.
|
||||
fn update_jmp_imm32_offset(
|
||||
&mut self,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue