mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-27 13:59:08 +00:00
copy bigger things to the stack
This commit is contained in:
parent
09d4553019
commit
7f8ff25cd3
1 changed files with 77 additions and 9 deletions
|
@ -668,6 +668,60 @@ impl CallConv<AArch64GeneralReg, AArch64FloatReg, AArch64Assembler> for AArch64C
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn copy_symbol_to_stack_offset<'a, CC>(
|
||||||
|
buf: &mut Vec<'a, u8>,
|
||||||
|
storage_manager: &mut AArch64StorageManager<'a, '_>,
|
||||||
|
sym: Symbol,
|
||||||
|
tmp_reg: AArch64GeneralReg,
|
||||||
|
stack_offset: i32,
|
||||||
|
) -> u32
|
||||||
|
where
|
||||||
|
CC: CallConv<AArch64GeneralReg, AArch64FloatReg, AArch64Assembler>,
|
||||||
|
{
|
||||||
|
type ASM = AArch64Assembler;
|
||||||
|
|
||||||
|
let mut copied = 0;
|
||||||
|
let (base_offset, size) = storage_manager.stack_offset_and_size(&sym);
|
||||||
|
|
||||||
|
if size - copied >= 8 {
|
||||||
|
for _ in (0..(size - copied)).step_by(8) {
|
||||||
|
ASM::mov_reg64_base32(buf, tmp_reg, base_offset + copied as i32);
|
||||||
|
ASM::mov_stack32_reg64(buf, stack_offset + copied as i32, tmp_reg);
|
||||||
|
|
||||||
|
copied += 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if size - copied >= 4 {
|
||||||
|
for _ in (0..(size - copied)).step_by(4) {
|
||||||
|
ASM::mov_reg32_base32(buf, tmp_reg, base_offset + copied as i32);
|
||||||
|
ASM::mov_stack32_reg32(buf, stack_offset + copied as i32, tmp_reg);
|
||||||
|
|
||||||
|
copied += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if size - copied >= 2 {
|
||||||
|
for _ in (0..(size - copied)).step_by(2) {
|
||||||
|
ASM::mov_reg16_base32(buf, tmp_reg, base_offset + copied as i32);
|
||||||
|
ASM::mov_stack32_reg16(buf, stack_offset + copied as i32, tmp_reg);
|
||||||
|
|
||||||
|
copied += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if size - copied >= 1 {
|
||||||
|
for _ in (0..(size - copied)).step_by(1) {
|
||||||
|
ASM::mov_reg8_base32(buf, tmp_reg, base_offset + copied as i32);
|
||||||
|
ASM::mov_stack32_reg8(buf, stack_offset + copied as i32, tmp_reg);
|
||||||
|
|
||||||
|
copied += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size
|
||||||
|
}
|
||||||
|
|
||||||
impl AArch64Call {
|
impl AArch64Call {
|
||||||
fn returns_via_arg_pointer<'a>(
|
fn returns_via_arg_pointer<'a>(
|
||||||
interner: &STLayoutInterner<'a>,
|
interner: &STLayoutInterner<'a>,
|
||||||
|
@ -815,10 +869,11 @@ impl AArch64CallStoreArgs {
|
||||||
sym: Symbol,
|
sym: Symbol,
|
||||||
in_layout: InLayout<'a>,
|
in_layout: InLayout<'a>,
|
||||||
) {
|
) {
|
||||||
|
type CC = AArch64Call;
|
||||||
type ASM = AArch64Assembler;
|
type ASM = AArch64Assembler;
|
||||||
|
|
||||||
// we use the return register as a temporary register; it will be overwritten anyway
|
// we use the return register as a temporary register; it will be overwritten anyway
|
||||||
let _tmp_reg = Self::GENERAL_RETURN_REGS[0];
|
let tmp_reg = Self::GENERAL_RETURN_REGS[0];
|
||||||
|
|
||||||
match layout_interner.get_repr(in_layout) {
|
match layout_interner.get_repr(in_layout) {
|
||||||
single_register_integers!() => self.store_arg_general(buf, storage_manager, sym),
|
single_register_integers!() => self.store_arg_general(buf, storage_manager, sym),
|
||||||
|
@ -849,14 +904,18 @@ impl AArch64CallStoreArgs {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ if layout_interner.stack_size(in_layout) == 0 => {}
|
_ if layout_interner.stack_size(in_layout) == 0 => {}
|
||||||
/*
|
|
||||||
_ if layout_interner.stack_size(in_layout) > 16 => {
|
_ if layout_interner.stack_size(in_layout) > 16 => {
|
||||||
// TODO: Double check this.
|
// TODO: Double check this.
|
||||||
// Just copy onto the stack.
|
// Just copy onto the stack.
|
||||||
let stack_offset = self.tmp_stack_offset;
|
let stack_offset = self.tmp_stack_offset;
|
||||||
|
|
||||||
let size =
|
let size = copy_symbol_to_stack_offset::<CC>(
|
||||||
copy_symbol_to_stack_offset(buf, storage_manager, sym, tmp_reg, stack_offset);
|
buf,
|
||||||
|
storage_manager,
|
||||||
|
sym,
|
||||||
|
tmp_reg,
|
||||||
|
stack_offset,
|
||||||
|
);
|
||||||
|
|
||||||
self.tmp_stack_offset += size as i32;
|
self.tmp_stack_offset += size as i32;
|
||||||
}
|
}
|
||||||
|
@ -870,20 +929,29 @@ impl AArch64CallStoreArgs {
|
||||||
LayoutRepr::Struct { .. } => {
|
LayoutRepr::Struct { .. } => {
|
||||||
let stack_offset = self.tmp_stack_offset;
|
let stack_offset = self.tmp_stack_offset;
|
||||||
|
|
||||||
let size =
|
let size = copy_symbol_to_stack_offset::<CC>(
|
||||||
copy_symbol_to_stack_offset(buf, storage_manager, sym, tmp_reg, stack_offset);
|
buf,
|
||||||
|
storage_manager,
|
||||||
|
sym,
|
||||||
|
tmp_reg,
|
||||||
|
stack_offset,
|
||||||
|
);
|
||||||
|
|
||||||
self.tmp_stack_offset += size as i32;
|
self.tmp_stack_offset += size as i32;
|
||||||
}
|
}
|
||||||
LayoutRepr::Union(UnionLayout::NonRecursive(_)) => {
|
LayoutRepr::Union(UnionLayout::NonRecursive(_)) => {
|
||||||
let stack_offset = self.tmp_stack_offset;
|
let stack_offset = self.tmp_stack_offset;
|
||||||
|
|
||||||
let size =
|
let size = copy_symbol_to_stack_offset::<CC>(
|
||||||
copy_symbol_to_stack_offset(buf, storage_manager, sym, tmp_reg, stack_offset);
|
buf,
|
||||||
|
storage_manager,
|
||||||
|
sym,
|
||||||
|
tmp_reg,
|
||||||
|
stack_offset,
|
||||||
|
);
|
||||||
|
|
||||||
self.tmp_stack_offset += size as i32;
|
self.tmp_stack_offset += size as i32;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
_ => {
|
_ => {
|
||||||
todo!(
|
todo!(
|
||||||
"calling with arg type, {:?}",
|
"calling with arg type, {:?}",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue