Skip to content

Commit 418abb9

Browse files
committed
[cc] aarch64 regalloc fix
Fixed bug in cc/arch/aarch64/regalloc.rs: The aarch64 register allocator was calculating stack offsets independently for int and FP overflow arguments: // Before (wrong): // FP overflow: offset = 16 + (fp_arg_idx - 8) * 8 // Int overflow: offset = 16 + (int_arg_idx - 8) * 8 // Both start at 16 → collision when both overflow! Per AAPCS64, stack arguments must be placed in parameter order (not separated by type). Fixed by using a single shared stack_arg_offset counter. Verified with clang cross-compilation: - q (int #9) should be at stack offset 0 - r (double #9) should be at stack offset 8
1 parent 9823bd9 commit 418abb9

File tree

1 file changed

+16
-4
lines changed

1 file changed

+16
-4
lines changed

cc/arch/aarch64/regalloc.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -653,11 +653,19 @@ impl RegAlloc {
653653
}
654654

655655
/// Pre-allocate argument registers per AAPCS64
656+
///
657+
/// AAPCS64 passes arguments as follows:
658+
/// - First 8 integer/pointer args in X0-X7
659+
/// - First 8 FP args in V0-V7 (D0-D7 for doubles, S0-S7 for floats)
660+
/// - Remaining args go on the stack in parameter order (not separated by type)
656661
fn allocate_arguments(&mut self, func: &Function, types: &TypeTable) {
657662
let int_arg_regs = Reg::arg_regs();
658663
let fp_arg_regs = VReg::arg_regs();
659664
let mut int_arg_idx = 0usize;
660665
let mut fp_arg_idx = 0usize;
666+
// Stack offset for overflow args - must be shared across all types
667+
// because AAPCS64 places stack args in parameter order
668+
let mut stack_arg_offset = 16i32;
661669

662670
// Detect hidden return pointer for large struct returns
663671
let sret_pseudo = func
@@ -684,9 +692,11 @@ impl RegAlloc {
684692
self.free_fp_regs.retain(|&r| r != fp_arg_regs[fp_arg_idx]);
685693
self.fp_pseudos.insert(pseudo.id);
686694
} else {
687-
let offset = 16 + (fp_arg_idx - fp_arg_regs.len()) as i32 * 8;
688-
self.locations.insert(pseudo.id, Loc::Stack(offset));
695+
// Stack args are placed in parameter order per AAPCS64
696+
self.locations
697+
.insert(pseudo.id, Loc::Stack(stack_arg_offset));
689698
self.fp_pseudos.insert(pseudo.id);
699+
stack_arg_offset += 8;
690700
}
691701
fp_arg_idx += 1;
692702
} else {
@@ -695,8 +705,10 @@ impl RegAlloc {
695705
.insert(pseudo.id, Loc::Reg(int_arg_regs[int_arg_idx]));
696706
self.free_regs.retain(|&r| r != int_arg_regs[int_arg_idx]);
697707
} else {
698-
let offset = 16 + (int_arg_idx - int_arg_regs.len()) as i32 * 8;
699-
self.locations.insert(pseudo.id, Loc::Stack(offset));
708+
// Stack args are placed in parameter order per AAPCS64
709+
self.locations
710+
.insert(pseudo.id, Loc::Stack(stack_arg_offset));
711+
stack_arg_offset += 8;
700712
}
701713
int_arg_idx += 1;
702714
}

0 commit comments

Comments
 (0)