diff --git a/compiler/gen_dev/src/generic64/aarch64.rs b/compiler/gen_dev/src/generic64/aarch64.rs index 2de5b9f8f1..3410b0fb20 100644 --- a/compiler/gen_dev/src/generic64/aarch64.rs +++ b/compiler/gen_dev/src/generic64/aarch64.rs @@ -269,28 +269,33 @@ impl CallConv 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, + _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 { diff --git a/compiler/gen_dev/src/generic64/mod.rs b/compiler/gen_dev/src/generic64/mod.rs index 12a7e41ef5..07048a46de 100644 --- a/compiler/gen_dev/src/generic64/mod.rs +++ b/compiler/gen_dev/src/generic64/mod.rs @@ -102,14 +102,13 @@ pub trait CallConv, ); - // 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, + 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, + ); + } } } diff --git a/compiler/gen_dev/src/generic64/x86_64.rs b/compiler/gen_dev/src/generic64/x86_64.rs index b8e164cbab..e333f02142 100644 --- a/compiler/gen_dev/src/generic64/x86_64.rs +++ b/compiler/gen_dev/src/generic64/x86_64.rs @@ -442,16 +442,16 @@ impl CallConv 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 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, + 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 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, + _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 {