Skip to main content

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