///|
pub(all) enum IntRegRole {
Scratch1
Scratch2
FP
LR
SRet
} derive(Eq, Debug)
///|
pub fn int_reg_index(role : IntRegRole) -> Int {
match role {
Scratch1 => 10
Scratch2 => 11
FP => 5
LR => 5
SRet => 7
}
}
///|
pub(all) struct MachineEnvData {
preferred_int : Array[@machv.PReg]
nonpreferred_int : Array[@machv.PReg]
preferred_float : Array[@machv.PReg]
nonpreferred_float : Array[@machv.PReg]
preferred_vector : Array[@machv.PReg]
nonpreferred_vector : Array[@machv.PReg]
callee_saved_int : Array[@machv.PReg]
callee_saved_float : Array[@machv.PReg]
scratch_int : Array[Int]
scratch_float : Array[Int]
} derive(Debug)
///|
pub fn sysv_callee_saved() -> Array[@machv.PReg] {
[int_reg(3), int_reg(5), int_reg(12), int_reg(13), int_reg(14), int_reg(15)]
}
///|
pub fn allocatable_callee_saved_regs() -> Array[@machv.PReg] {
let fp_idx = int_reg_index(FP)
let regs : Array[@machv.PReg] = []
for r in sysv_callee_saved() {
if r.index == fp_idx {
continue
}
regs.push(r)
}
regs
}
///|
pub fn allocatable_scratch_regs() -> Array[@machv.PReg] {
[
int_reg(6),
int_reg(7),
int_reg(0),
int_reg(1),
int_reg(2),
int_reg(8),
int_reg(9),
]
}
///|
pub fn sysv_arg_fprs() -> Array[@machv.PReg] {
let regs : Array[@machv.PReg] = []
for i in 0..<8 {
regs.push(float_reg(i))
}
regs
}
///|
pub fn allocatable_scratch_fprs() -> Array[@machv.PReg] {
let regs : Array[@machv.PReg] = []
for i in 0..<16 {
regs.push(float_reg(i))
}
regs
}
///|
pub fn call_clobbered_gprs() -> Array[@machv.PReg] {
[
int_reg(0),
int_reg(1),
int_reg(2),
int_reg(6),
int_reg(7),
int_reg(8),
int_reg(9),
int_reg(10),
int_reg(11),
]
}
///|
pub fn call_clobbered_fprs() -> Array[@machv.PReg] {
allocatable_scratch_fprs()
}
///|
pub fn call_clobbered_fprs_same_abi() -> Array[@machv.PReg] {
call_clobbered_fprs()
}
///|
pub fn build_machine_env(
reserved_int_regs? : Array[Int] = [],
) -> MachineEnvData {
let preferred_int : Array[@machv.PReg] = []
let nonpreferred_int : Array[@machv.PReg] = []
let callee_saved_int : Array[@machv.PReg] = []
for r in allocatable_scratch_regs() {
preferred_int.push(r)
}
for r in allocatable_callee_saved_regs() {
if reserved_int_regs.contains(r.index) {
continue
}
nonpreferred_int.push(r)
callee_saved_int.push(r)
}
let preferred_float : Array[@machv.PReg] = []
let nonpreferred_float : Array[@machv.PReg] = []
for r in sysv_arg_fprs() {
preferred_float.push(r)
}
for r in allocatable_scratch_fprs() {
if r.index < 8 || r.index == 14 || r.index == 15 {
continue
}
preferred_float.push(r)
}
let callee_saved_float : Array[@machv.PReg] = []
let preferred_vector : Array[@machv.PReg] = []
let nonpreferred_vector : Array[@machv.PReg] = []
for r in sysv_arg_fprs() {
preferred_vector.push({ index: r.index, class: Vector })
}
for r in allocatable_scratch_fprs() {
if r.index < 8 || r.index == 14 || r.index == 15 {
continue
}
preferred_vector.push({ index: r.index, class: Vector })
}
{
preferred_int,
nonpreferred_int,
preferred_float,
nonpreferred_float,
preferred_vector,
nonpreferred_vector,
callee_saved_int,
callee_saved_float,
scratch_int: [int_reg_index(Scratch1), int_reg_index(Scratch2)],
scratch_float: [14, 15],
}
}