mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 14:54:47 +00:00
add basic returned value loading
This commit is contained in:
parent
55c6c9abad
commit
cb64543476
3 changed files with 74 additions and 60 deletions
|
@ -269,28 +269,33 @@ impl CallConv<AArch64GeneralReg, AArch64FloatReg, AArch64Assembler> for AArch64C
|
|||
}
|
||||
|
||||
fn return_complex_symbol<'a>(
|
||||
buf: &mut Vec<'a, u8>,
|
||||
storage_manager: &mut StorageManager<
|
||||
_buf: &mut Vec<'a, u8>,
|
||||
_storage_manager: &mut StorageManager<
|
||||
'a,
|
||||
AArch64GeneralReg,
|
||||
AArch64FloatReg,
|
||||
AArch64Assembler,
|
||||
AArch64Call,
|
||||
>,
|
||||
sym: &Symbol,
|
||||
layout: &Layout<'a>,
|
||||
_sym: &Symbol,
|
||||
_layout: &Layout<'a>,
|
||||
) {
|
||||
todo!("Returning complex symbols for AArch64");
|
||||
}
|
||||
|
||||
fn return_struct<'a>(
|
||||
fn load_returned_complex_symbol<'a>(
|
||||
_buf: &mut Vec<'a, u8>,
|
||||
_struct_offset: i32,
|
||||
_struct_size: u32,
|
||||
_field_layouts: &[Layout<'a>],
|
||||
_ret_reg: Option<AArch64GeneralReg>,
|
||||
_storage_manager: &mut StorageManager<
|
||||
'a,
|
||||
AArch64GeneralReg,
|
||||
AArch64FloatReg,
|
||||
AArch64Assembler,
|
||||
AArch64Call,
|
||||
>,
|
||||
_sym: &Symbol,
|
||||
_layout: &Layout<'a>,
|
||||
) {
|
||||
todo!("Returning structs for AArch64");
|
||||
todo!("Loading returned complex symbols for AArch64");
|
||||
}
|
||||
|
||||
fn returns_via_arg_pointer(_ret_layout: &Layout) -> bool {
|
||||
|
|
|
@ -102,14 +102,13 @@ pub trait CallConv<GeneralReg: RegTrait, FloatReg: RegTrait, ASM: Assembler<Gene
|
|||
layout: &Layout<'a>,
|
||||
);
|
||||
|
||||
// return_struct returns a struct currently on the stack at `struct_offset`.
|
||||
// It does so using registers and stack as necessary.
|
||||
fn return_struct<'a>(
|
||||
/// load_returned_complex_symbol loads a complex symbol that was returned from a function call.
|
||||
/// It uses the layout to determine how the data should be loaded into the symbol.
|
||||
fn load_returned_complex_symbol<'a>(
|
||||
buf: &mut Vec<'a, u8>,
|
||||
struct_offset: i32,
|
||||
struct_size: u32,
|
||||
field_layouts: &[Layout<'a>],
|
||||
ret_reg: Option<GeneralReg>,
|
||||
storage_manager: &mut StorageManager<'a, GeneralReg, FloatReg, ASM, Self>,
|
||||
sym: &Symbol,
|
||||
layout: &Layout<'a>,
|
||||
);
|
||||
|
||||
// returns true if the layout should be returned via an argument pointer.
|
||||
|
@ -595,36 +594,25 @@ impl<
|
|||
|
||||
// move return value to dst.
|
||||
match ret_layout {
|
||||
Layout::Builtin(Builtin::Int(IntWidth::I64 | IntWidth::U64) | Builtin::Bool) => {
|
||||
single_register_integers!() => {
|
||||
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]);
|
||||
}
|
||||
Layout::Builtin(Builtin::Float(FloatWidth::F64)) => {
|
||||
single_register_floats!() => {
|
||||
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]);
|
||||
}
|
||||
// Layout::Builtin(Builtin::Str) => {
|
||||
// if CC::returns_via_arg_pointer(ret_layout) {
|
||||
// // This will happen on windows, return via pointer here.
|
||||
// todo!("FnCall: Returning strings via pointer");
|
||||
// } else {
|
||||
// let offset = self.claim_stack_size(16);
|
||||
// self.symbol_storage_map.insert(
|
||||
// *dst,
|
||||
// SymbolStorage::Base {
|
||||
// offset,
|
||||
// size: 16,
|
||||
// owned: true,
|
||||
// },
|
||||
// );
|
||||
// ASM::mov_base32_reg64(&mut self.buf, offset, CC::GENERAL_RETURN_REGS[0]);
|
||||
// ASM::mov_base32_reg64(&mut self.buf, offset + 8, CC::GENERAL_RETURN_REGS[1]);
|
||||
// }
|
||||
// }
|
||||
Layout::Struct([]) => {
|
||||
// Nothing needs to be done to load a returned empty struct.
|
||||
}
|
||||
x => todo!("FnCall: receiving return type, {:?}", x),
|
||||
_ => {
|
||||
CC::load_returned_complex_symbol(
|
||||
&mut self.buf,
|
||||
&mut self.storage_manager,
|
||||
dst,
|
||||
ret_layout,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -442,16 +442,16 @@ impl CallConv<X86_64GeneralReg, X86_64FloatReg, X86_64Assembler> for X86_64Syste
|
|||
}
|
||||
|
||||
fn return_complex_symbol<'a>(
|
||||
buf: &mut Vec<'a, u8>,
|
||||
storage_manager: &mut StorageManager<
|
||||
_buf: &mut Vec<'a, u8>,
|
||||
_storage_manager: &mut StorageManager<
|
||||
'a,
|
||||
X86_64GeneralReg,
|
||||
X86_64FloatReg,
|
||||
X86_64Assembler,
|
||||
X86_64SystemV,
|
||||
>,
|
||||
sym: &Symbol,
|
||||
layout: &Layout<'a>,
|
||||
_sym: &Symbol,
|
||||
_layout: &Layout<'a>,
|
||||
) {
|
||||
// Complex types.
|
||||
// let val = self.symbol_storage_map.get(sym);
|
||||
|
@ -523,14 +523,30 @@ impl CallConv<X86_64GeneralReg, X86_64FloatReg, X86_64Assembler> for X86_64Syste
|
|||
todo!("Returning complex symbols for X86_64");
|
||||
}
|
||||
|
||||
fn return_struct<'a>(
|
||||
_buf: &mut Vec<'a, u8>,
|
||||
_struct_offset: i32,
|
||||
_struct_size: u32,
|
||||
_field_layouts: &[Layout<'a>],
|
||||
_ret_reg: Option<X86_64GeneralReg>,
|
||||
fn load_returned_complex_symbol<'a>(
|
||||
buf: &mut Vec<'a, u8>,
|
||||
storage_manager: &mut StorageManager<
|
||||
'a,
|
||||
X86_64GeneralReg,
|
||||
X86_64FloatReg,
|
||||
X86_64Assembler,
|
||||
X86_64SystemV,
|
||||
>,
|
||||
sym: &Symbol,
|
||||
layout: &Layout<'a>,
|
||||
) {
|
||||
todo!("Returning structs for X86_64");
|
||||
match layout {
|
||||
single_register_layouts!() => {
|
||||
internal_error!("single register layouts are not complex symbols");
|
||||
}
|
||||
Layout::Struct([]) => {}
|
||||
Layout::Builtin(Builtin::Str | Builtin::List(_)) => {
|
||||
let offset = storage_manager.claim_stack_area(sym, 16);
|
||||
X86_64Assembler::mov_base32_reg64(buf, offset, Self::GENERAL_RETURN_REGS[0]);
|
||||
X86_64Assembler::mov_base32_reg64(buf, offset + 8, Self::GENERAL_RETURN_REGS[1]);
|
||||
}
|
||||
x => todo!("receiving complex return type, {:?}", x),
|
||||
}
|
||||
}
|
||||
|
||||
fn returns_via_arg_pointer(ret_layout: &Layout) -> bool {
|
||||
|
@ -848,28 +864,33 @@ impl CallConv<X86_64GeneralReg, X86_64FloatReg, X86_64Assembler> for X86_64Windo
|
|||
}
|
||||
|
||||
fn return_complex_symbol<'a>(
|
||||
buf: &mut Vec<'a, u8>,
|
||||
storage_manager: &mut StorageManager<
|
||||
_buf: &mut Vec<'a, u8>,
|
||||
_storage_manager: &mut StorageManager<
|
||||
'a,
|
||||
X86_64GeneralReg,
|
||||
X86_64FloatReg,
|
||||
X86_64Assembler,
|
||||
X86_64WindowsFastcall,
|
||||
>,
|
||||
sym: &Symbol,
|
||||
layout: &Layout<'a>,
|
||||
_sym: &Symbol,
|
||||
_layout: &Layout<'a>,
|
||||
) {
|
||||
todo!("Returning symbols for X86_64");
|
||||
todo!("Returning complex symbols for X86_64");
|
||||
}
|
||||
|
||||
fn return_struct<'a>(
|
||||
fn load_returned_complex_symbol<'a>(
|
||||
_buf: &mut Vec<'a, u8>,
|
||||
_struct_offset: i32,
|
||||
_struct_size: u32,
|
||||
_field_layouts: &[Layout<'a>],
|
||||
_ret_reg: Option<X86_64GeneralReg>,
|
||||
_storage_manager: &mut StorageManager<
|
||||
'a,
|
||||
X86_64GeneralReg,
|
||||
X86_64FloatReg,
|
||||
X86_64Assembler,
|
||||
X86_64WindowsFastcall,
|
||||
>,
|
||||
_sym: &Symbol,
|
||||
_layout: &Layout<'a>,
|
||||
) {
|
||||
todo!("Returning structs for X86_64WindowsFastCall");
|
||||
todo!("Loading returned complex symbols for X86_64");
|
||||
}
|
||||
|
||||
fn returns_via_arg_pointer(ret_layout: &Layout) -> bool {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue