add basic returned value loading

This commit is contained in:
Brendan Hansknecht 2022-02-17 21:08:28 -08:00
parent 55c6c9abad
commit cb64543476
3 changed files with 74 additions and 60 deletions

View file

@ -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 {

View file

@ -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,
);
}
}
}

View file

@ -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 {