///|
pub(all) enum IntRegRole {
Scratch1
Scratch2
FP
LR
SRet
} derive(Eq, Debug)
///|
pub fn int_reg_index(role : IntRegRole) -> Int {
match role {
Scratch1 => 16
Scratch2 => 17
FP => 29
LR => 30
SRet => 8
}
}
///|
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 aapcs64_arg_gprs() -> Array[@machv.PReg] {
[
int_reg(0),
int_reg(1),
int_reg(2),
int_reg(3),
int_reg(4),
int_reg(5),
int_reg(6),
int_reg(7),
]
}
///|
pub fn aapcs64_ret_gprs() -> Array[@machv.PReg] {
aapcs64_arg_gprs()
}
///|
pub fn aapcs64_callee_saved() -> Array[@machv.PReg] {
[
int_reg(19),
int_reg(20),
int_reg(21),
int_reg(22),
int_reg(23),
int_reg(24),
int_reg(25),
int_reg(26),
int_reg(27),
int_reg(28),
int_reg(29),
int_reg(30),
]
}
///|
pub fn allocatable_scratch_regs() -> Array[@machv.PReg] {
[
int_reg(0),
int_reg(1),
int_reg(2),
int_reg(3),
int_reg(4),
int_reg(5),
int_reg(6),
int_reg(7),
int_reg(8),
int_reg(9),
int_reg(10),
int_reg(11),
int_reg(12),
int_reg(13),
int_reg(14),
int_reg(15),
]
}
///|
pub fn allocatable_callee_saved_regs() -> Array[@machv.PReg] {
let regs : Array[@machv.PReg] = []
let fp_idx = int_reg_index(FP)
let lr_idx = int_reg_index(LR)
for r in aapcs64_callee_saved() {
if r.index == fp_idx || r.index == lr_idx {
continue
}
regs.push(r)
}
regs
}
///|
pub fn aapcs64_arg_fprs() -> Array[@machv.PReg] {
[
float_reg(0),
float_reg(1),
float_reg(2),
float_reg(3),
float_reg(4),
float_reg(5),
float_reg(6),
float_reg(7),
]
}
///|
pub fn aapcs64_ret_fprs() -> Array[@machv.PReg] {
aapcs64_arg_fprs()
}
///|
pub fn callee_saved_fprs() -> Array[@machv.PReg] {
[
float_reg(8),
float_reg(9),
float_reg(10),
float_reg(11),
float_reg(12),
float_reg(13),
float_reg(14),
float_reg(15),
]
}
///|
pub fn allocatable_scratch_fprs() -> Array[@machv.PReg] {
let regs : Array[@machv.PReg] = []
for i in 16..<32 {
regs.push(float_reg(i))
}
regs
}
///|
pub fn call_clobbered_gprs() -> Array[@machv.PReg] {
let regs : Array[@machv.PReg] = []
for i in 0..<18 {
regs.push(int_reg(i))
}
regs
}
///|
pub fn call_clobbered_fprs() -> Array[@machv.PReg] {
let regs : Array[@machv.PReg] = []
for i in 0..<32 {
regs.push(float_reg(i))
}
regs
}
///|
pub fn call_clobbered_fprs_same_abi() -> Array[@machv.PReg] {
let regs : Array[@machv.PReg] = []
for i in 0..<32 {
if i >= 8 && i <= 15 {
continue
}
regs.push(float_reg(i))
}
regs
}
///|
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 aapcs64_arg_fprs() {
preferred_float.push(r)
}
for r in allocatable_scratch_fprs() {
if r.index == 16 || r.index == 17 {
continue
}
preferred_float.push(r)
}
let callee_saved_float = callee_saved_fprs()
for r in callee_saved_float {
nonpreferred_float.push(r)
}
let preferred_vector : Array[@machv.PReg] = []
let nonpreferred_vector : Array[@machv.PReg] = []
for r in aapcs64_arg_fprs() {
preferred_vector.push({ index: r.index, class: Vector })
}
for r in allocatable_scratch_fprs() {
if r.index == 16 || r.index == 17 {
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: [16, 17],
}
}