gcrecomp_core/runtime/calling.rs
1// Calling convention helpers
2use crate::runtime::context::CpuContext;
3
4/// PowerPC calling convention helper
5pub struct CallingConvention;
6
7impl CallingConvention {
8 /// Setup stack frame for function call
9 /// PowerPC uses r1 as stack pointer
10 pub fn setup_stack_frame(ctx: &mut CpuContext, frame_size: u32) {
11 // Save old stack pointer
12 let old_sp = ctx.get_register(1);
13
14 // Allocate new stack frame
15 let new_sp = old_sp.wrapping_sub(frame_size);
16 ctx.set_register(1, new_sp);
17
18 // Store old stack pointer in the new frame (standard PowerPC convention)
19 // This would typically be done with stwu instruction
20 }
21
22 /// Teardown stack frame
23 pub fn teardown_stack_frame(ctx: &mut CpuContext, frame_size: u32) {
24 // Restore stack pointer
25 let current_sp = ctx.get_register(1);
26 let old_sp = current_sp.wrapping_add(frame_size);
27 ctx.set_register(1, old_sp);
28 }
29
30 /// Get function argument from register
31 /// PowerPC passes first 8 arguments in r3-r10
32 pub fn get_argument(ctx: &CpuContext, arg_num: u8) -> u32 {
33 if arg_num < 8 {
34 ctx.get_register(3 + arg_num)
35 } else {
36 // Arguments beyond 8 are passed on the stack
37 // This would require reading from the stack frame
38 0
39 }
40 }
41
42 /// Set function return value
43 /// PowerPC returns values in r3
44 pub fn set_return_value(ctx: &mut CpuContext, value: u32) {
45 ctx.set_register(3, value);
46 }
47
48 /// Get return value
49 pub fn get_return_value(ctx: &CpuContext) -> u32 {
50 ctx.get_register(3)
51 }
52}
53