use crate::detail::{align_down, mut_offset};
use crate::stack::Stack;
pub type InitFn = extern "C" fn(usize, *mut usize) -> !;
pub extern "C" fn gen_init(a1: usize, a2: *mut usize) -> ! {
super::gen::gen_init_impl(a1, a2);
}
extern "C" {
pub fn bootstrap_green_task();
pub fn prefetch(data: *const usize);
#[allow(improper_ctypes)] pub fn swap_registers(out_regs: *mut Registers, in_regs: *const Registers);
}
#[repr(C)]
#[derive(Debug)]
#[allow(improper_ctypes)]
pub struct Registers {
gpr: [usize; 32],
fp: [f64; 18],
vr: [u128; 12], }
const REG_LR: usize = 0;
const REG_FP: usize = 2;
const REG_GLOB_ENTRY: usize = 4;
const REG_R14: usize = 5; const REG_R15: usize = 6; const REG_R16: usize = 7;
impl Registers {
pub fn new() -> Self {
Self {
gpr: [0; 32],
fp: [0.0; 18],
vr: [0; 12],
}
}
pub fn prefetch(&self) {
unsafe {
prefetch(&self.gpr[0]);
}
}
}
pub fn initialize_call_frame(
regs: &mut Registers,
fptr: InitFn,
arg: usize,
arg2: *mut usize,
stack: &Stack,
) {
let end = stack.end();
let sp = align_down(end);
let sp = mut_offset(sp, -2);
regs.gpr[REG_FP] = sp as usize;
regs.gpr[REG_R14] = arg;
regs.gpr[REG_R15] = arg2 as usize;
regs.gpr[REG_R16] = fptr as usize;
regs.gpr[REG_LR] = bootstrap_green_task as *const () as usize;
regs.gpr[REG_GLOB_ENTRY] = bootstrap_green_task as *const () as usize;
}