mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 23:04:49 +00:00
add returning str and list
This commit is contained in:
parent
cb64543476
commit
d65a971508
3 changed files with 44 additions and 79 deletions
|
@ -1,7 +1,4 @@
|
||||||
use crate::{
|
use crate::{single_register_floats, single_register_integers, Backend, Env, Relocation};
|
||||||
single_register_floats, single_register_integers, single_register_layouts, Backend, Env,
|
|
||||||
Relocation,
|
|
||||||
};
|
|
||||||
use bumpalo::collections::Vec;
|
use bumpalo::collections::Vec;
|
||||||
use roc_builtins::bitcode::{FloatWidth, IntWidth};
|
use roc_builtins::bitcode::{FloatWidth, IntWidth};
|
||||||
use roc_collections::all::{MutMap, MutSet};
|
use roc_collections::all::{MutMap, MutSet};
|
||||||
|
@ -602,9 +599,6 @@ impl<
|
||||||
let dst_reg = self.storage_manager.claim_float_reg(&mut self.buf, dst);
|
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]);
|
ASM::mov_freg64_freg64(&mut self.buf, dst_reg, CC::FLOAT_RETURN_REGS[0]);
|
||||||
}
|
}
|
||||||
Layout::Struct([]) => {
|
|
||||||
// Nothing needs to be done to load a returned empty struct.
|
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
CC::load_returned_complex_symbol(
|
CC::load_returned_complex_symbol(
|
||||||
&mut self.buf,
|
&mut self.buf,
|
||||||
|
|
|
@ -646,6 +646,29 @@ impl<
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// gets the stack offset and size of the specified symbol.
|
||||||
|
// the symbol must already be stored on the stack.
|
||||||
|
pub fn stack_offset_and_size(&self, sym: &Symbol) -> (i32, u32) {
|
||||||
|
let storage = if let Some(storage) = self.symbol_storage_map.get(sym) {
|
||||||
|
storage
|
||||||
|
} else {
|
||||||
|
internal_error!("Unknown symbol: {}", sym);
|
||||||
|
};
|
||||||
|
match storage {
|
||||||
|
Stack(Primitive { base_offset, .. }) => (*base_offset, 8),
|
||||||
|
Stack(ReferencedPrimitive { base_offset, size } | Complex { base_offset, size }) => {
|
||||||
|
(*base_offset, *size)
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
internal_error!(
|
||||||
|
"Data no on the stack for sym ({}) with storage ({:?})",
|
||||||
|
sym,
|
||||||
|
storage
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// claim_stack_area is the public wrapper around claim_stack_size.
|
/// claim_stack_area is the public wrapper around claim_stack_size.
|
||||||
/// It also deals with updating symbol storage.
|
/// It also deals with updating symbol storage.
|
||||||
/// It returns the base offset of the stack area.
|
/// It returns the base offset of the stack area.
|
||||||
|
|
|
@ -442,85 +442,33 @@ impl CallConv<X86_64GeneralReg, X86_64FloatReg, X86_64Assembler> for X86_64Syste
|
||||||
}
|
}
|
||||||
|
|
||||||
fn return_complex_symbol<'a>(
|
fn return_complex_symbol<'a>(
|
||||||
_buf: &mut Vec<'a, u8>,
|
buf: &mut Vec<'a, u8>,
|
||||||
_storage_manager: &mut StorageManager<
|
storage_manager: &mut StorageManager<
|
||||||
'a,
|
'a,
|
||||||
X86_64GeneralReg,
|
X86_64GeneralReg,
|
||||||
X86_64FloatReg,
|
X86_64FloatReg,
|
||||||
X86_64Assembler,
|
X86_64Assembler,
|
||||||
X86_64SystemV,
|
X86_64SystemV,
|
||||||
>,
|
>,
|
||||||
_sym: &Symbol,
|
sym: &Symbol,
|
||||||
_layout: &Layout<'a>,
|
layout: &Layout<'a>,
|
||||||
) {
|
) {
|
||||||
// Complex types.
|
let (base_offset, size) = storage_manager.stack_offset_and_size(sym);
|
||||||
// let val = self.symbol_storage_map.get(sym);
|
match layout {
|
||||||
// match val {
|
single_register_layouts!() => {
|
||||||
// Some(SymbolStorage::GeneralReg(reg)) if *reg == CC::GENERAL_RETURN_REGS[0] => {}
|
internal_error!("single register layouts are not complex symbols");
|
||||||
// Some(SymbolStorage::GeneralReg(reg)) => {
|
}
|
||||||
// // If it fits in a general purpose register, just copy it over to.
|
Layout::Struct([]) => {}
|
||||||
// // Technically this can be optimized to produce shorter instructions if less than 64bits.
|
Layout::Builtin(Builtin::Str | Builtin::List(_)) => {
|
||||||
// ASM::mov_reg64_reg64(&mut self.buf, CC::GENERAL_RETURN_REGS[0], *reg);
|
X86_64Assembler::mov_reg64_base32(buf, Self::GENERAL_RETURN_REGS[0], base_offset);
|
||||||
// }
|
X86_64Assembler::mov_reg64_base32(
|
||||||
// Some(SymbolStorage::FloatReg(reg)) if *reg == CC::FLOAT_RETURN_REGS[0] => {}
|
buf,
|
||||||
// Some(SymbolStorage::FloatReg(reg)) => {
|
Self::GENERAL_RETURN_REGS[1],
|
||||||
// ASM::mov_freg64_freg64(&mut self.buf, CC::FLOAT_RETURN_REGS[0], *reg);
|
base_offset + 8,
|
||||||
// }
|
);
|
||||||
// Some(SymbolStorage::Base { offset, size, .. }) => match layout {
|
}
|
||||||
// Layout::Builtin(Builtin::Int(IntWidth::I64 | IntWidth::U64)) => {
|
x => todo!("returning complex type, {:?}", x),
|
||||||
// ASM::mov_reg64_base32(&mut self.buf, CC::GENERAL_RETURN_REGS[0], *offset);
|
}
|
||||||
// }
|
|
||||||
// Layout::Builtin(Builtin::Float(FloatWidth::F64)) => {
|
|
||||||
// ASM::mov_freg64_base32(&mut self.buf, CC::FLOAT_RETURN_REGS[0], *offset);
|
|
||||||
// }
|
|
||||||
// Layout::Builtin(Builtin::Str) => {
|
|
||||||
// if self.symbol_storage_map.contains_key(&Symbol::RET_POINTER) {
|
|
||||||
// // This will happen on windows, return via pointer here.
|
|
||||||
// todo!("Returning strings via pointer");
|
|
||||||
// } else {
|
|
||||||
// ASM::mov_reg64_base32(&mut self.buf, CC::GENERAL_RETURN_REGS[0], *offset);
|
|
||||||
// ASM::mov_reg64_base32(
|
|
||||||
// &mut self.buf,
|
|
||||||
// CC::GENERAL_RETURN_REGS[1],
|
|
||||||
// *offset + 8,
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// Layout::Struct(field_layouts) => {
|
|
||||||
// let (offset, size) = (*offset, *size);
|
|
||||||
// // Nothing to do for empty struct
|
|
||||||
// if size > 0 {
|
|
||||||
// let ret_reg = if self.symbol_storage_map.contains_key(&Symbol::RET_POINTER)
|
|
||||||
// {
|
|
||||||
// Some(
|
|
||||||
// self.storage_manager
|
|
||||||
// .load_to_general_reg(&mut self.buf, &Symbol::RET_POINTER),
|
|
||||||
// )
|
|
||||||
// } else {
|
|
||||||
// None
|
|
||||||
// };
|
|
||||||
// CC::return_struct(&mut self.buf, offset, size, field_layouts, ret_reg);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// x => todo!("returning symbol with layout, {:?}", x),
|
|
||||||
// },
|
|
||||||
// Some(x) => todo!("returning symbol storage, {:?}", x),
|
|
||||||
// None if layout == &Layout::Struct(&[]) => {
|
|
||||||
// // Empty struct is not defined and does nothing.
|
|
||||||
// }
|
|
||||||
// None => {
|
|
||||||
// internal_error!("Unknown return symbol: {:?}", sym);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// let inst_loc = self.buf.len() as u64;
|
|
||||||
// let offset = ASM::jmp_imm32(&mut self.buf, 0x1234_5678) as u64;
|
|
||||||
// self.relocs.push(Relocation::JmpToReturn {
|
|
||||||
// inst_loc,
|
|
||||||
// inst_size: self.buf.len() as u64 - inst_loc,
|
|
||||||
// offset,
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
todo!("Returning complex symbols for X86_64");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_returned_complex_symbol<'a>(
|
fn load_returned_complex_symbol<'a>(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue