///|
pub(all) enum IRegister {
VReg(Int) // Virtual Register
AReg(Int) // Argument Register (after grouping)
TReg(Int) // Temporary Register (after grouping)
SReg(Int) // Saved Register (after grouping)
StackPtr // Stack Pointer
FramePtr // Frame Pointer
FramePtrPrim // Fake Frame Pointer used in prologue/epilogue
ReturnAddr // Return Address
} derive(Hash, Eq)
///|
pub impl Show for IRegister with output(self, logger) {
let s = match self {
VReg(n) => "v\{n}"
AReg(n) => "a\{n}"
TReg(n) => "t\{n}"
SReg(n) => "s\{n}"
StackPtr => "sp"
FramePtr => "fp"
FramePtrPrim => "fp'"
ReturnAddr => "ra"
}
logger.write_string(s)
}
///|
pub(all) enum FRegister {
VFReg(Int) // Virtual Float Register
FAReg(Int) // Float Argument Register (after grouping)
FTReg(Int) // Float Temporary Register (after grouping)
FSReg(Int) // Float Saved Register (after grouping)
} derive(Hash, Eq)
///|
pub impl Show for FRegister with output(self, logger) {
let s = match self {
VFReg(n) => "vf\{n}"
FAReg(n) => "fa\{n}"
FTReg(n) => "ft\{n}"
FSReg(n) => "fs\{n}"
}
logger.write_string(s)
}
///|
pub(all) enum Operand {
IRegister(IRegister)
FRegister(FRegister)
// It means value stored in memory, need load/store
Mem(IRegister, Int64)
// Memory Address, it means address calculated by base register + offset
MemLoc(IRegister, Int64)
// For loading/storing multiple values
MemGroup(IRegister, Array[Int64])
Imm(Int64) // Immediate Value
FImm(Double) // Floating Point Immediate Value
Label(String) // Label
} derive(Hash, Eq)
///|
fn Operand::is_fp_operand(self : Self) -> Bool {
match self {
FRegister(_) => true
FImm(_) => true
_ => false
}
}
///|
fn Operand::is_virtual_reg(self : Self) -> Bool {
match self {
IRegister(VReg(_)) => true
FRegister(VFReg(_)) => true
_ => false
}
}
///|
pub impl Show for Operand with output(self, logger) {
let s = match self {
IRegister(r) => r.to_string()
FRegister(r) => r.to_string()
Mem(base, offset) =>
if offset < 0 {
"(\{base} - \{-offset})"
} else if offset == 0 {
"(\{base})"
} else {
"(\{base} + \{offset})"
}
MemLoc(base, offset) =>
if offset < 0 {
"[\{base} - \{-offset}]"
} else if offset == 0 {
"[\{base}]"
} else {
"[\{base} + \{offset}]"
}
MemGroup(base, offsets) => {
let offset_strs = offsets.map(off => off.to_string())
let offset_strs = offset_strs.join(", ")
"(\{base} + {\{offset_strs}})"
}
Imm(i) => "\{i}"
FImm(f) => "\{f}"
Label(l) => l
}
logger.write_string(s)
}