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>(
|
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,
|
||||||
AArch64GeneralReg,
|
AArch64GeneralReg,
|
||||||
AArch64FloatReg,
|
AArch64FloatReg,
|
||||||
AArch64Assembler,
|
AArch64Assembler,
|
||||||
AArch64Call,
|
AArch64Call,
|
||||||
>,
|
>,
|
||||||
sym: &Symbol,
|
_sym: &Symbol,
|
||||||
layout: &Layout<'a>,
|
_layout: &Layout<'a>,
|
||||||
) {
|
) {
|
||||||
todo!("Returning complex symbols for AArch64");
|
todo!("Returning complex symbols for AArch64");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn return_struct<'a>(
|
fn load_returned_complex_symbol<'a>(
|
||||||
_buf: &mut Vec<'a, u8>,
|
_buf: &mut Vec<'a, u8>,
|
||||||
_struct_offset: i32,
|
_storage_manager: &mut StorageManager<
|
||||||
_struct_size: u32,
|
'a,
|
||||||
_field_layouts: &[Layout<'a>],
|
AArch64GeneralReg,
|
||||||
_ret_reg: Option<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 {
|
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>,
|
layout: &Layout<'a>,
|
||||||
);
|
);
|
||||||
|
|
||||||
// return_struct returns a struct currently on the stack at `struct_offset`.
|
/// load_returned_complex_symbol loads a complex symbol that was returned from a function call.
|
||||||
// It does so using registers and stack as necessary.
|
/// It uses the layout to determine how the data should be loaded into the symbol.
|
||||||
fn return_struct<'a>(
|
fn load_returned_complex_symbol<'a>(
|
||||||
buf: &mut Vec<'a, u8>,
|
buf: &mut Vec<'a, u8>,
|
||||||
struct_offset: i32,
|
storage_manager: &mut StorageManager<'a, GeneralReg, FloatReg, ASM, Self>,
|
||||||
struct_size: u32,
|
sym: &Symbol,
|
||||||
field_layouts: &[Layout<'a>],
|
layout: &Layout<'a>,
|
||||||
ret_reg: Option<GeneralReg>,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// returns true if the layout should be returned via an argument pointer.
|
// returns true if the layout should be returned via an argument pointer.
|
||||||
|
@ -595,36 +594,25 @@ impl<
|
||||||
|
|
||||||
// move return value to dst.
|
// move return value to dst.
|
||||||
match ret_layout {
|
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);
|
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]);
|
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);
|
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::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([]) => {
|
Layout::Struct([]) => {
|
||||||
// Nothing needs to be done to load a returned empty 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>(
|
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.
|
// Complex types.
|
||||||
// let val = self.symbol_storage_map.get(sym);
|
// 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");
|
todo!("Returning complex symbols for X86_64");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn return_struct<'a>(
|
fn load_returned_complex_symbol<'a>(
|
||||||
_buf: &mut Vec<'a, u8>,
|
buf: &mut Vec<'a, u8>,
|
||||||
_struct_offset: i32,
|
storage_manager: &mut StorageManager<
|
||||||
_struct_size: u32,
|
'a,
|
||||||
_field_layouts: &[Layout<'a>],
|
X86_64GeneralReg,
|
||||||
_ret_reg: Option<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 {
|
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>(
|
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_64WindowsFastcall,
|
X86_64WindowsFastcall,
|
||||||
>,
|
>,
|
||||||
sym: &Symbol,
|
_sym: &Symbol,
|
||||||
layout: &Layout<'a>,
|
_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>,
|
_buf: &mut Vec<'a, u8>,
|
||||||
_struct_offset: i32,
|
_storage_manager: &mut StorageManager<
|
||||||
_struct_size: u32,
|
'a,
|
||||||
_field_layouts: &[Layout<'a>],
|
X86_64GeneralReg,
|
||||||
_ret_reg: Option<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 {
|
fn returns_via_arg_pointer(ret_layout: &Layout) -> bool {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue