use alloc::string::String;
use regalloc2::MachineEnv;
use regalloc2::PReg;
use regalloc2::VReg;
use crate::machinst::*;
use crate::settings;
pub fn gpr(num: u8) -> Reg {
let preg = gpr_preg(num);
Reg::from(VReg::new(preg.index(), RegClass::Int))
}
pub(crate) const fn gpr_preg(num: u8) -> PReg {
assert!(num < 16);
PReg::new(num as usize, RegClass::Int)
}
pub fn writable_gpr(num: u8) -> Writable<Reg> {
Writable::from_reg(gpr(num))
}
pub fn vr(num: u8) -> Reg {
let preg = vr_preg(num);
Reg::from(VReg::new(preg.index(), RegClass::Float))
}
pub(crate) const fn vr_preg(num: u8) -> PReg {
assert!(num < 32);
PReg::new(num as usize, RegClass::Float)
}
#[allow(dead_code)] pub fn writable_vr(num: u8) -> Writable<Reg> {
Writable::from_reg(vr(num))
}
pub fn is_fpr(r: Reg) -> bool {
let r = r.to_real_reg().unwrap();
assert!(r.class() == RegClass::Float);
return r.hw_enc() < 16;
}
pub fn stack_reg() -> Reg {
gpr(15)
}
pub fn writable_stack_reg() -> Writable<Reg> {
Writable::from_reg(stack_reg())
}
pub fn spilltmp_reg() -> Reg {
gpr(1)
}
pub fn writable_spilltmp_reg() -> Writable<Reg> {
Writable::from_reg(spilltmp_reg())
}
pub fn zero_reg() -> Reg {
gpr(0)
}
pub fn create_machine_env(_flags: &settings::Flags) -> MachineEnv {
fn preg(r: Reg) -> PReg {
r.to_real_reg().unwrap().into()
}
MachineEnv {
preferred_regs_by_class: [
vec![
preg(gpr(2)),
preg(gpr(3)),
preg(gpr(4)),
preg(gpr(5)),
],
vec![
preg(vr(0)),
preg(vr(1)),
preg(vr(2)),
preg(vr(3)),
preg(vr(4)),
preg(vr(5)),
preg(vr(6)),
preg(vr(7)),
preg(vr(16)),
preg(vr(17)),
preg(vr(18)),
preg(vr(19)),
preg(vr(20)),
preg(vr(21)),
preg(vr(22)),
preg(vr(23)),
preg(vr(24)),
preg(vr(25)),
preg(vr(26)),
preg(vr(27)),
preg(vr(28)),
preg(vr(29)),
preg(vr(30)),
preg(vr(31)),
],
],
non_preferred_regs_by_class: [
vec![
preg(gpr(6)),
preg(gpr(7)),
preg(gpr(8)),
preg(gpr(9)),
preg(gpr(10)),
preg(gpr(11)),
preg(gpr(12)),
preg(gpr(13)),
preg(gpr(14)),
],
vec![
preg(vr(8)),
preg(vr(9)),
preg(vr(10)),
preg(vr(11)),
preg(vr(12)),
preg(vr(13)),
preg(vr(14)),
preg(vr(15)),
],
],
fixed_stack_slots: vec![],
}
}
pub fn show_reg(reg: Reg) -> String {
if let Some(rreg) = reg.to_real_reg() {
match rreg.class() {
RegClass::Int => format!("%r{}", rreg.hw_enc()),
RegClass::Float => format!("%v{}", rreg.hw_enc()),
}
} else {
format!("%{:?}", reg)
}
}
pub fn maybe_show_fpr(reg: Reg) -> Option<String> {
if let Some(rreg) = reg.to_real_reg() {
if is_fpr(reg) {
return Some(format!("%f{}", rreg.hw_enc()));
}
}
None
}
pub fn pretty_print_reg(reg: Reg, allocs: &mut AllocationConsumer<'_>) -> String {
let reg = allocs.next(reg);
show_reg(reg)
}
pub fn pretty_print_reg_mod(
rd: Writable<Reg>,
ri: Reg,
allocs: &mut AllocationConsumer<'_>,
) -> String {
let output = allocs.next_writable(rd).to_reg();
let input = allocs.next(ri);
if output == input {
show_reg(output)
} else {
format!("{}<-{}", show_reg(output), show_reg(input))
}
}
pub fn pretty_print_fpr(reg: Reg, allocs: &mut AllocationConsumer<'_>) -> (String, Option<String>) {
let reg = allocs.next(reg);
(show_reg(reg), maybe_show_fpr(reg))
}