///|
pub(all) enum RegClass {
Int
Float32
Float64
Vector
} derive(Eq, Debug)
///|
fn RegClass::to_string(self : RegClass) -> String {
match self {
Int => "int"
Float32 => "float"
Float64 => "double"
Vector => "vector"
}
}
///|
pub impl Show for RegClass with fn output(self, logger) {
logger.write_string(self.to_string())
}
///|
pub(all) struct VReg {
id : Int
class : RegClass
} derive(Eq, Debug)
///|
fn VReg::to_string(self : VReg) -> String {
match self.class {
Int => "v\{self.id}"
Float32 | Float64 => "f\{self.id}"
Vector => "vec\{self.id}"
}
}
///|
pub impl Show for VReg with fn output(self, logger) {
logger.write_string(self.to_string())
}
///|
pub(all) struct PReg {
index : Int
class : RegClass
} derive(Eq, Debug)
///|
fn PReg::to_string(self : PReg) -> String {
match self.class {
Int => "x\{self.index}"
Float32 | Float64 => "d\{self.index}"
Vector => "v\{self.index}"
}
}
///|
pub impl Show for PReg with fn output(self, logger) {
logger.write_string(self.to_string())
}
///|
pub let spill_slot_base : Int = 256
///|
pub fn PReg::is_spilled(self : PReg) -> Bool {
self.index >= spill_slot_base
}
///|
pub fn PReg::get_spill_slot(self : PReg) -> Int {
if self.index >= spill_slot_base {
self.index - spill_slot_base
} else {
-1
}
}
///|
pub fn PReg::spilled(slot : Int, class : RegClass) -> PReg {
{ index: spill_slot_base + slot, class }
}
///|
pub(all) enum Reg {
Virtual(VReg)
Physical(PReg)
} derive(Eq, Debug)
///|
fn Reg::to_string(self : Reg) -> String {
match self {
Virtual(vreg) => vreg.to_string()
Physical(preg) => preg.to_string()
}
}
///|
pub impl Show for Reg with fn output(self, logger) {
logger.write_string(self.to_string())
}
///|
pub(all) struct Writable {
reg : Reg
} derive(Eq, Debug)
///|
fn Writable::to_string(self : Writable) -> String {
self.reg.to_string()
}
///|
pub impl Show for Writable with fn output(self, logger) {
logger.write_string(self.to_string())
}
///|
pub(all) enum OperandConstraint {
Any
FixedReg(PReg)
} derive(Eq, Debug)
///|
fn OperandConstraint::to_string(self : OperandConstraint) -> String {
match self {
Any => "any"
FixedReg(preg) => "fixed(\{preg})"
}
}
///|
pub impl Show for OperandConstraint with fn output(self, logger) {
logger.write_string(self.to_string())
}
///|
pub(all) enum OperandRole {
Use
Def
UseDef
} derive(Eq, Debug)
///|
pub(all) struct Operand {
reg : Reg
role : OperandRole
tie_id : Int
} derive(Eq, Debug)
///|
pub fn Operand::use_reg(reg : Reg) -> Operand {
{ reg, role: Use, tie_id: -1 }
}
///|
pub fn Operand::def(reg : Reg) -> Operand {
{ reg, role: Def, tie_id: -1 }
}
///|
pub fn Operand::use_def(reg : Reg) -> Operand {
{ reg, role: UseDef, tie_id: -1 }
}
///|
pub fn Operand::with_tie(self : Operand, tie_id : Int) -> Operand {
{ reg: self.reg, role: self.role, tie_id }
}