use super::{
allocated_ops::{AllocatedOpcode, AllocatedRegister},
virtual_immediate::*,
virtual_register::*,
DataId, Op,
};
use crate::asm_generation::RegisterPool;
use std::collections::{BTreeSet, HashMap};
use std::fmt;
#[allow(clippy::upper_case_acronyms)]
#[derive(Clone, Debug)]
pub(crate) enum VirtualOp {
ADD(VirtualRegister, VirtualRegister, VirtualRegister),
ADDI(VirtualRegister, VirtualRegister, VirtualImmediate12),
AND(VirtualRegister, VirtualRegister, VirtualRegister),
ANDI(VirtualRegister, VirtualRegister, VirtualImmediate12),
DIV(VirtualRegister, VirtualRegister, VirtualRegister),
DIVI(VirtualRegister, VirtualRegister, VirtualImmediate12),
EQ(VirtualRegister, VirtualRegister, VirtualRegister),
EXP(VirtualRegister, VirtualRegister, VirtualRegister),
EXPI(VirtualRegister, VirtualRegister, VirtualImmediate12),
GT(VirtualRegister, VirtualRegister, VirtualRegister),
LT(VirtualRegister, VirtualRegister, VirtualRegister),
MLOG(VirtualRegister, VirtualRegister, VirtualRegister),
MOD(VirtualRegister, VirtualRegister, VirtualRegister),
MODI(VirtualRegister, VirtualRegister, VirtualImmediate12),
MOVE(VirtualRegister, VirtualRegister),
MOVI(VirtualRegister, VirtualImmediate18),
MROO(VirtualRegister, VirtualRegister, VirtualRegister),
MUL(VirtualRegister, VirtualRegister, VirtualRegister),
MULI(VirtualRegister, VirtualRegister, VirtualImmediate12),
NOOP,
NOT(VirtualRegister, VirtualRegister),
OR(VirtualRegister, VirtualRegister, VirtualRegister),
ORI(VirtualRegister, VirtualRegister, VirtualImmediate12),
SLL(VirtualRegister, VirtualRegister, VirtualRegister),
SLLI(VirtualRegister, VirtualRegister, VirtualImmediate12),
SRL(VirtualRegister, VirtualRegister, VirtualRegister),
SRLI(VirtualRegister, VirtualRegister, VirtualImmediate12),
SUB(VirtualRegister, VirtualRegister, VirtualRegister),
SUBI(VirtualRegister, VirtualRegister, VirtualImmediate12),
XOR(VirtualRegister, VirtualRegister, VirtualRegister),
XORI(VirtualRegister, VirtualRegister, VirtualImmediate12),
JMP(VirtualRegister),
JI(VirtualImmediate24),
JNE(VirtualRegister, VirtualRegister, VirtualRegister),
JNEI(VirtualRegister, VirtualRegister, VirtualImmediate12),
JNZI(VirtualRegister, VirtualImmediate18),
RET(VirtualRegister),
ALOC(VirtualRegister),
CFEI(VirtualImmediate24),
CFSI(VirtualImmediate24),
LB(VirtualRegister, VirtualRegister, VirtualImmediate12),
LW(VirtualRegister, VirtualRegister, VirtualImmediate12),
MCL(VirtualRegister, VirtualRegister),
MCLI(VirtualRegister, VirtualImmediate18),
MCP(VirtualRegister, VirtualRegister, VirtualRegister),
MCPI(VirtualRegister, VirtualRegister, VirtualImmediate12),
MEQ(
VirtualRegister,
VirtualRegister,
VirtualRegister,
VirtualRegister,
),
SB(VirtualRegister, VirtualRegister, VirtualImmediate12),
SW(VirtualRegister, VirtualRegister, VirtualImmediate12),
BAL(VirtualRegister, VirtualRegister, VirtualRegister),
BHEI(VirtualRegister),
BHSH(VirtualRegister, VirtualRegister),
BURN(VirtualRegister),
CALL(
VirtualRegister,
VirtualRegister,
VirtualRegister,
VirtualRegister,
),
CB(VirtualRegister),
CCP(
VirtualRegister,
VirtualRegister,
VirtualRegister,
VirtualRegister,
),
CROO(VirtualRegister, VirtualRegister),
CSIZ(VirtualRegister, VirtualRegister),
LDC(VirtualRegister, VirtualRegister, VirtualRegister),
LOG(
VirtualRegister,
VirtualRegister,
VirtualRegister,
VirtualRegister,
),
LOGD(
VirtualRegister,
VirtualRegister,
VirtualRegister,
VirtualRegister,
),
MINT(VirtualRegister),
RETD(VirtualRegister, VirtualRegister),
RVRT(VirtualRegister),
SMO(
VirtualRegister,
VirtualRegister,
VirtualRegister,
VirtualRegister,
),
SCWQ(VirtualRegister, VirtualRegister, VirtualRegister),
SRW(VirtualRegister, VirtualRegister, VirtualRegister),
SRWQ(
VirtualRegister,
VirtualRegister,
VirtualRegister,
VirtualRegister,
),
SWW(VirtualRegister, VirtualRegister, VirtualRegister),
SWWQ(
VirtualRegister,
VirtualRegister,
VirtualRegister,
VirtualRegister,
),
TIME(VirtualRegister, VirtualRegister),
TR(VirtualRegister, VirtualRegister, VirtualRegister),
TRO(
VirtualRegister,
VirtualRegister,
VirtualRegister,
VirtualRegister,
),
ECR(VirtualRegister, VirtualRegister, VirtualRegister),
K256(VirtualRegister, VirtualRegister, VirtualRegister),
S256(VirtualRegister, VirtualRegister, VirtualRegister),
FLAG(VirtualRegister),
GM(VirtualRegister, VirtualImmediate18),
GTF(VirtualRegister, VirtualRegister, VirtualImmediate12),
BLOB(VirtualImmediate24),
DataSectionOffsetPlaceholder,
DataSectionRegisterLoadPlaceholder,
LWDataId(VirtualRegister, DataId),
Undefined,
}
impl VirtualOp {
pub(crate) fn registers(&self) -> BTreeSet<&VirtualRegister> {
use VirtualOp::*;
(match self {
ADD(r1, r2, r3) => vec![r1, r2, r3],
ADDI(r1, r2, _i) => vec![r1, r2],
AND(r1, r2, r3) => vec![r1, r2, r3],
ANDI(r1, r2, _i) => vec![r1, r2],
DIV(r1, r2, r3) => vec![r1, r2, r3],
DIVI(r1, r2, _i) => vec![r1, r2],
EQ(r1, r2, r3) => vec![r1, r2, r3],
EXP(r1, r2, r3) => vec![r1, r2, r3],
EXPI(r1, r2, _i) => vec![r1, r2],
GT(r1, r2, r3) => vec![r1, r2, r3],
LT(r1, r2, r3) => vec![r1, r2, r3],
MLOG(r1, r2, r3) => vec![r1, r2, r3],
MOD(r1, r2, r3) => vec![r1, r2, r3],
MODI(r1, r2, _i) => vec![r1, r2],
MOVE(r1, r2) => vec![r1, r2],
MOVI(r1, _i) => vec![r1],
MROO(r1, r2, r3) => vec![r1, r2, r3],
MUL(r1, r2, r3) => vec![r1, r2, r3],
MULI(r1, r2, _i) => vec![r1, r2],
NOOP => vec![],
NOT(r1, r2) => vec![r1, r2],
OR(r1, r2, r3) => vec![r1, r2, r3],
ORI(r1, r2, _i) => vec![r1, r2],
SLL(r1, r2, r3) => vec![r1, r2, r3],
SLLI(r1, r2, _i) => vec![r1, r2],
SRL(r1, r2, r3) => vec![r1, r2, r3],
SRLI(r1, r2, _i) => vec![r1, r2],
SUB(r1, r2, r3) => vec![r1, r2, r3],
SUBI(r1, r2, _i) => vec![r1, r2],
XOR(r1, r2, r3) => vec![r1, r2, r3],
XORI(r1, r2, _i) => vec![r1, r2],
JMP(r1) => vec![r1],
JI(_im) => vec![],
JNE(r1, r2, r3) => vec![r1, r2, r3],
JNEI(r1, r2, _i) => vec![r1, r2],
JNZI(r1, _i) => vec![r1],
RET(r1) => vec![r1],
ALOC(r1) => vec![r1],
CFEI(_imm) => vec![],
CFSI(_imm) => vec![],
LB(r1, r2, _i) => vec![r1, r2],
LW(r1, r2, _i) => vec![r1, r2],
MCL(r1, r2) => vec![r1, r2],
MCLI(r1, _imm) => vec![r1],
MCP(r1, r2, r3) => vec![r1, r2, r3],
MCPI(r1, r2, _imm) => vec![r1, r2],
MEQ(r1, r2, r3, r4) => vec![r1, r2, r3, r4],
SB(r1, r2, _i) => vec![r1, r2],
SW(r1, r2, _i) => vec![r1, r2],
BAL(r1, r2, r3) => vec![r1, r2, r3],
BHEI(r1) => vec![r1],
BHSH(r1, r2) => vec![r1, r2],
BURN(r1) => vec![r1],
CALL(r1, r2, r3, r4) => vec![r1, r2, r3, r4],
CB(r1) => vec![r1],
CCP(r1, r2, r3, r4) => vec![r1, r2, r3, r4],
CROO(r1, r2) => vec![r1, r2],
CSIZ(r1, r2) => vec![r1, r2],
LDC(r1, r2, r3) => vec![r1, r2, r3],
LOG(r1, r2, r3, r4) => vec![r1, r2, r3, r4],
LOGD(r1, r2, r3, r4) => vec![r1, r2, r3, r4],
MINT(r1) => vec![r1],
RETD(r1, r2) => vec![r1, r2],
RVRT(r1) => vec![r1],
SMO(r1, r2, r3, r4) => vec![r1, r2, r3, r4],
SCWQ(r1, r2, r3) => vec![r1, r2, r3],
SRW(r1, r2, r3) => vec![r1, r2, r3],
SRWQ(r1, r2, r3, r4) => vec![r1, r2, r3, r4],
SWW(r1, r2, r3) => vec![r1, r2, r3],
SWWQ(r1, r2, r3, r4) => vec![r1, r2, r3, r4],
TIME(r1, r2) => vec![r1, r2],
TR(r1, r2, r3) => vec![r1, r2, r3],
TRO(r1, r2, r3, r4) => vec![r1, r2, r3, r4],
ECR(r1, r2, r3) => vec![r1, r2, r3],
K256(r1, r2, r3) => vec![r1, r2, r3],
S256(r1, r2, r3) => vec![r1, r2, r3],
FLAG(r1) => vec![r1],
GM(r1, _imm) => vec![r1],
GTF(r1, r2, _i) => vec![r1, r2],
BLOB(_imm) => vec![],
DataSectionOffsetPlaceholder => vec![],
DataSectionRegisterLoadPlaceholder => vec![
&VirtualRegister::Constant(ConstantRegister::DataSectionStart),
&VirtualRegister::Constant(ConstantRegister::InstructionStart),
],
LWDataId(r1, _i) => vec![r1],
Undefined => vec![],
})
.into_iter()
.collect()
}
pub(crate) fn use_registers(&self) -> BTreeSet<&VirtualRegister> {
use VirtualOp::*;
(match self {
ADD(_r1, r2, r3) => vec![r2, r3],
ADDI(_r1, r2, _i) => vec![r2],
AND(_r1, r2, r3) => vec![r2, r3],
ANDI(_r1, r2, _i) => vec![r2],
DIV(_r1, r2, r3) => vec![r2, r3],
DIVI(_r1, r2, _i) => vec![r2],
EQ(_r1, r2, r3) => vec![r2, r3],
EXP(_r1, r2, r3) => vec![r2, r3],
EXPI(_r1, r2, _i) => vec![r2],
GT(_r1, r2, r3) => vec![r2, r3],
LT(_r1, r2, r3) => vec![r2, r3],
MLOG(_r1, r2, r3) => vec![r2, r3],
MOD(_r1, r2, r3) => vec![r2, r3],
MODI(r1, r2, _i) => vec![r1, r2],
MOVE(_r1, r2) => vec![r2],
MOVI(_r1, _i) => vec![],
MROO(_r1, r2, r3) => vec![r2, r3],
MUL(_r1, r2, r3) => vec![r2, r3],
MULI(_r1, r2, _i) => vec![r2],
NOOP => vec![],
NOT(_r1, r2) => vec![r2],
OR(_r1, r2, r3) => vec![r2, r3],
ORI(_r1, r2, _i) => vec![r2],
SLL(_r1, r2, r3) => vec![r2, r3],
SLLI(_r1, r2, _i) => vec![r2],
SRL(_r1, r2, r3) => vec![r2, r3],
SRLI(_r1, r2, _i) => vec![r2],
SUB(_r1, r2, r3) => vec![r2, r3],
SUBI(_r1, r2, _i) => vec![r2],
XOR(_r1, r2, r3) => vec![r2, r3],
XORI(_r1, r2, _i) => vec![r2],
JMP(r1) => vec![r1],
JI(_im) => vec![],
JNE(r1, r2, r3) => vec![r1, r2, r3],
JNEI(r1, r2, _i) => vec![r1, r2],
JNZI(r1, _i) => vec![r1],
RET(r1) => vec![r1],
ALOC(r1) => vec![r1],
CFEI(_imm) => vec![],
CFSI(_imm) => vec![],
LB(_r1, r2, _i) => vec![r2],
LW(_r1, r2, _i) => vec![r2],
MCL(r1, r2) => vec![r1, r2],
MCLI(r1, _imm) => vec![r1],
MCP(r1, r2, r3) => vec![r1, r2, r3],
MCPI(r1, r2, _imm) => vec![r1, r2],
MEQ(_r1, r2, r3, r4) => vec![r2, r3, r4],
SB(r1, r2, _i) => vec![r1, r2],
SW(r1, r2, _i) => vec![r1, r2],
BAL(_r1, r2, r3) => vec![r2, r3],
BHEI(_r1) => vec![],
BHSH(r1, r2) => vec![r1, r2],
BURN(r1) => vec![r1],
CALL(r1, r2, r3, r4) => vec![r1, r2, r3, r4],
CB(r1) => vec![r1],
CCP(r1, r2, r3, r4) => vec![r1, r2, r3, r4],
CROO(r1, r2) => vec![r1, r2],
CSIZ(_r1, r2) => vec![r2],
LDC(r1, r2, r3) => vec![r1, r2, r3],
LOG(r1, r2, r3, r4) => vec![r1, r2, r3, r4],
LOGD(r1, r2, r3, r4) => vec![r1, r2, r3, r4],
MINT(r1) => vec![r1],
RETD(r1, r2) => vec![r1, r2],
RVRT(r1) => vec![r1],
SMO(r1, r2, r3, r4) => vec![r1, r2, r3, r4],
SCWQ(r1, _r2, r3) => vec![r1, r3],
SRW(_r1, _r2, r3) => vec![r3],
SRWQ(r1, _r2, r3, r4) => vec![r1, r3, r4],
SWW(r1, _r2, r3) => vec![r1, r3],
SWWQ(r1, _r2, r3, r4) => vec![r1, r3, r4],
TIME(_r1, r2) => vec![r2],
TR(r1, r2, r3) => vec![r1, r2, r3],
TRO(r1, r2, r3, r4) => vec![r1, r2, r3, r4],
ECR(r1, r2, r3) => vec![r1, r2, r3],
K256(r1, r2, r3) => vec![r1, r2, r3],
S256(r1, r2, r3) => vec![r1, r2, r3],
FLAG(r1) => vec![r1],
GM(_r1, _imm) => vec![],
GTF(_r1, r2, _i) => vec![r2],
BLOB(_imm) => vec![],
DataSectionOffsetPlaceholder => vec![],
DataSectionRegisterLoadPlaceholder => vec![&VirtualRegister::Constant(
ConstantRegister::InstructionStart,
)],
LWDataId(_r1, _i) => vec![],
Undefined => vec![],
})
.into_iter()
.collect()
}
pub(crate) fn def_registers(&self) -> BTreeSet<&VirtualRegister> {
use VirtualOp::*;
(match self {
ADD(r1, _r2, _r3) => vec![r1],
ADDI(r1, _r2, _i) => vec![r1],
AND(r1, _r2, _r3) => vec![r1],
ANDI(r1, _r2, _i) => vec![r1],
DIV(r1, _r2, _r3) => vec![r1],
DIVI(r1, _r2, _i) => vec![r1],
EQ(r1, _r2, _r3) => vec![r1],
EXP(r1, _r2, _r3) => vec![r1],
EXPI(r1, _r2, _i) => vec![r1],
GT(r1, _r2, _r3) => vec![r1],
LT(r1, _r2, _r3) => vec![r1],
MLOG(r1, _r2, _r3) => vec![r1],
MOD(r1, _r2, _r3) => vec![r1],
MODI(r1, _r2, _i) => vec![r1],
MOVE(r1, _r2) => vec![r1],
MOVI(r1, _i) => vec![r1],
MROO(r1, _r2, _r3) => vec![r1],
MUL(r1, _r2, _r3) => vec![r1],
MULI(r1, _r2, _i) => vec![r1],
NOOP => vec![],
NOT(r1, _r2) => vec![r1],
OR(r1, _r2, _r3) => vec![r1],
ORI(r1, _r2, _i) => vec![r1],
SLL(r1, _r2, _r3) => vec![r1],
SLLI(r1, _r2, _i) => vec![r1],
SRL(r1, _r2, _r3) => vec![r1],
SRLI(r1, _r2, _i) => vec![r1],
SUB(r1, _r2, _r3) => vec![r1],
SUBI(r1, _r2, _i) => vec![r1],
XOR(r1, _r2, _r3) => vec![r1],
XORI(r1, _r2, _i) => vec![r1],
JMP(_r1) => vec![],
JI(_im) => vec![],
JNE(_r1, _r2, _r3) => vec![],
JNEI(_r1, _r2, _i) => vec![],
JNZI(_r1, _i) => vec![],
RET(_r1) => vec![],
ALOC(_r1) => vec![],
CFEI(_imm) => vec![],
CFSI(_imm) => vec![],
LB(r1, _r2, _i) => vec![r1],
LW(r1, _r2, _i) => vec![r1],
MCL(_r1, _r2) => vec![],
MCLI(_r1, _imm) => vec![],
MCP(_r1, _r2, _r3) => vec![],
MCPI(_r1, _r2, _imm) => vec![],
MEQ(r1, _r2, _r3, _r4) => vec![r1],
SB(_r1, _r2, _i) => vec![],
SW(_r1, _r2, _i) => vec![],
BAL(r1, _r2, _r3) => vec![r1],
BHEI(r1) => vec![r1],
BHSH(_r1, _r2) => vec![],
BURN(_r1) => vec![],
CALL(_r1, _r2, _r3, _r4) => vec![],
CB(_r1) => vec![],
CCP(_r1, _r2, _r3, _r4) => vec![],
CROO(_r1, _r2) => vec![],
CSIZ(r1, _r2) => vec![r1],
LDC(_r1, _r2, _r3) => vec![],
LOG(_r1, _r2, _r3, _r4) => vec![],
LOGD(_r1, _r2, _r3, _r4) => vec![],
MINT(_r1) => vec![],
RETD(_r1, _r2) => vec![],
RVRT(_r1) => vec![],
SMO(_r1, _r2, _r3, _r4) => vec![],
SCWQ(_r1, r2, _r3) => vec![r2],
SRW(r1, r2, _r3) => vec![r1, r2],
SRWQ(_r1, r2, _r3, _r4) => vec![r2],
SWW(_r1, r2, _r3) => vec![r2],
SWWQ(_r1, r2, _r3, _r4) => vec![r2],
TIME(r1, _r2) => vec![r1],
TR(_r1, _r2, _r3) => vec![],
TRO(_r1, _r2, _r3, _r4) => vec![],
ECR(_r1, _r2, _r3) => vec![],
K256(_r1, _r2, _r3) => vec![],
S256(_r1, _r2, _r3) => vec![],
FLAG(_r1) => vec![],
GM(r1, _imm) => vec![r1],
GTF(r1, _r2, _i) => vec![r1],
BLOB(_imm) => vec![],
LWDataId(r1, _i) => vec![r1],
DataSectionOffsetPlaceholder => vec![],
DataSectionRegisterLoadPlaceholder => vec![&VirtualRegister::Constant(
ConstantRegister::DataSectionStart,
)],
Undefined => vec![],
})
.into_iter()
.collect()
}
pub(crate) fn successors(&self, index: usize, ops: &[Op]) -> Vec<usize> {
use VirtualOp::*;
let next_op = if index >= ops.len() - 1 {
vec![]
} else {
vec![index + 1]
};
match self {
RVRT(_) => vec![],
JI(_) | JNEI(..) | JNZI(..) => {
unreachable!("At this stage we shouldn't have jumps in the code.")
}
_ => next_op,
}
}
pub(crate) fn update_register(
&self,
reg_to_reg_map: &HashMap<VirtualRegister, VirtualRegister>,
) -> Self {
use VirtualOp::*;
match self {
ADD(r1, r2, r3) => Self::ADD(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
update_reg(reg_to_reg_map, r3),
),
ADDI(r1, r2, i) => Self::ADDI(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
i.clone(),
),
AND(r1, r2, r3) => Self::AND(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
update_reg(reg_to_reg_map, r3),
),
ANDI(r1, r2, i) => Self::ANDI(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
i.clone(),
),
DIV(r1, r2, r3) => Self::DIV(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
update_reg(reg_to_reg_map, r3),
),
DIVI(r1, r2, i) => Self::DIVI(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
i.clone(),
),
EQ(r1, r2, r3) => Self::EQ(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
update_reg(reg_to_reg_map, r3),
),
EXP(r1, r2, r3) => Self::EXP(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
update_reg(reg_to_reg_map, r3),
),
EXPI(r1, r2, i) => Self::EXPI(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
i.clone(),
),
GT(r1, r2, r3) => Self::GT(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
update_reg(reg_to_reg_map, r3),
),
LT(r1, r2, r3) => Self::LT(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
update_reg(reg_to_reg_map, r3),
),
MLOG(r1, r2, r3) => Self::MLOG(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
update_reg(reg_to_reg_map, r3),
),
MOD(r1, r2, r3) => Self::MOD(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
update_reg(reg_to_reg_map, r3),
),
MODI(r1, r2, i) => Self::MODI(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
i.clone(),
),
MOVE(r1, r2) => Self::MOVE(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
),
MOVI(r1, i) => Self::MOVI(update_reg(reg_to_reg_map, r1), i.clone()),
MROO(r1, r2, r3) => Self::MROO(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
update_reg(reg_to_reg_map, r3),
),
MUL(r1, r2, r3) => Self::MUL(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
update_reg(reg_to_reg_map, r3),
),
MULI(r1, r2, i) => Self::MULI(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
i.clone(),
),
NOOP => Self::NOOP,
NOT(r1, r2) => Self::NOT(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
),
OR(r1, r2, r3) => Self::OR(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
update_reg(reg_to_reg_map, r3),
),
ORI(r1, r2, i) => Self::ORI(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
i.clone(),
),
SLL(r1, r2, r3) => Self::SLL(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
update_reg(reg_to_reg_map, r3),
),
SLLI(r1, r2, i) => Self::SLLI(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
i.clone(),
),
SRL(r1, r2, r3) => Self::SRL(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
update_reg(reg_to_reg_map, r3),
),
SRLI(r1, r2, i) => Self::SRLI(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
i.clone(),
),
SUB(r1, r2, r3) => Self::SUB(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
update_reg(reg_to_reg_map, r3),
),
SUBI(r1, r2, i) => Self::SUBI(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
i.clone(),
),
XOR(r1, r2, r3) => Self::XOR(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
update_reg(reg_to_reg_map, r3),
),
XORI(r1, r2, i) => Self::XORI(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
i.clone(),
),
JMP(r1) => Self::JMP(update_reg(reg_to_reg_map, r1)),
JI(_) => self.clone(),
JNE(r1, r2, r3) => Self::JNE(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
update_reg(reg_to_reg_map, r3),
),
JNEI(r1, r2, i) => Self::JNEI(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
i.clone(),
),
JNZI(r1, i) => Self::JNZI(update_reg(reg_to_reg_map, r1), i.clone()),
RET(r1) => Self::RET(update_reg(reg_to_reg_map, r1)),
ALOC(r1) => Self::ALOC(update_reg(reg_to_reg_map, r1)),
CFEI(i) => Self::CFEI(i.clone()),
CFSI(i) => Self::CFSI(i.clone()),
LB(r1, r2, i) => Self::LB(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
i.clone(),
),
LW(r1, r2, i) => Self::LW(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
i.clone(),
),
MCL(r1, r2) => Self::MCL(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
),
MCLI(r1, i) => Self::MCLI(update_reg(reg_to_reg_map, r1), i.clone()),
MCP(r1, r2, r3) => Self::MCP(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
update_reg(reg_to_reg_map, r3),
),
MEQ(r1, r2, r3, r4) => Self::MEQ(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
update_reg(reg_to_reg_map, r3),
update_reg(reg_to_reg_map, r4),
),
MCPI(r1, r2, i) => Self::MCPI(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
i.clone(),
),
SB(r1, r2, i) => Self::SB(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
i.clone(),
),
SW(r1, r2, i) => Self::SW(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
i.clone(),
),
BAL(r1, r2, r3) => Self::BAL(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
update_reg(reg_to_reg_map, r3),
),
BHEI(r1) => Self::BHEI(update_reg(reg_to_reg_map, r1)),
BHSH(r1, r2) => Self::BHSH(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
),
BURN(r1) => Self::BURN(update_reg(reg_to_reg_map, r1)),
CALL(r1, r2, r3, r4) => Self::CALL(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
update_reg(reg_to_reg_map, r3),
update_reg(reg_to_reg_map, r4),
),
CB(r1) => Self::CB(update_reg(reg_to_reg_map, r1)),
CCP(r1, r2, r3, r4) => Self::CCP(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
update_reg(reg_to_reg_map, r3),
update_reg(reg_to_reg_map, r4),
),
CROO(r1, r2) => Self::CROO(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
),
CSIZ(r1, r2) => Self::CSIZ(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
),
LDC(r1, r2, r3) => Self::LDC(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
update_reg(reg_to_reg_map, r3),
),
LOG(r1, r2, r3, r4) => Self::LOG(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
update_reg(reg_to_reg_map, r3),
update_reg(reg_to_reg_map, r4),
),
LOGD(r1, r2, r3, r4) => Self::LOGD(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
update_reg(reg_to_reg_map, r3),
update_reg(reg_to_reg_map, r4),
),
MINT(r1) => Self::MINT(update_reg(reg_to_reg_map, r1)),
RETD(r1, r2) => Self::RETD(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
),
RVRT(reg1) => Self::RVRT(update_reg(reg_to_reg_map, reg1)),
SMO(r1, r2, r3, r4) => Self::SMO(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
update_reg(reg_to_reg_map, r3),
update_reg(reg_to_reg_map, r4),
),
SCWQ(r1, r2, r3) => Self::SCWQ(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
update_reg(reg_to_reg_map, r3),
),
SRW(r1, r2, r3) => Self::SRW(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
update_reg(reg_to_reg_map, r3),
),
SRWQ(r1, r2, r3, r4) => Self::SRWQ(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
update_reg(reg_to_reg_map, r3),
update_reg(reg_to_reg_map, r4),
),
SWW(r1, r2, r3) => Self::SWW(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
update_reg(reg_to_reg_map, r3),
),
SWWQ(r1, r2, r3, r4) => Self::SWWQ(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
update_reg(reg_to_reg_map, r3),
update_reg(reg_to_reg_map, r4),
),
TIME(r1, r2) => Self::TIME(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
),
TR(r1, r2, r3) => Self::TR(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
update_reg(reg_to_reg_map, r3),
),
TRO(r1, r2, r3, r4) => Self::TRO(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
update_reg(reg_to_reg_map, r3),
update_reg(reg_to_reg_map, r4),
),
ECR(r1, r2, r3) => Self::ECR(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
update_reg(reg_to_reg_map, r3),
),
K256(r1, r2, r3) => Self::K256(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
update_reg(reg_to_reg_map, r3),
),
S256(r1, r2, r3) => Self::S256(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
update_reg(reg_to_reg_map, r3),
),
FLAG(r1) => Self::FLAG(update_reg(reg_to_reg_map, r1)),
GM(r1, i) => Self::GM(update_reg(reg_to_reg_map, r1), i.clone()),
GTF(r1, r2, i) => Self::GTF(
update_reg(reg_to_reg_map, r1),
update_reg(reg_to_reg_map, r2),
i.clone(),
),
BLOB(i) => Self::BLOB(i.clone()),
DataSectionOffsetPlaceholder => Self::DataSectionOffsetPlaceholder,
DataSectionRegisterLoadPlaceholder => Self::DataSectionRegisterLoadPlaceholder,
LWDataId(r1, i) => Self::LWDataId(update_reg(reg_to_reg_map, r1), i.clone()),
Undefined => Self::Undefined,
}
}
pub(crate) fn update_jump_immediate_values(&mut self, offset_map: &HashMap<u64, u64>) -> Self {
use VirtualOp::*;
match self {
JI(i) => Self::JI(
VirtualImmediate24::new(
*offset_map
.get(&(i.value as u64))
.expect("new offset should be valid"),
crate::span::Span::new(" ".into(), 0, 0, None).unwrap(),
)
.unwrap(),
),
JNEI(r1, r2, i) => Self::JNEI(
r1.clone(),
r2.clone(),
VirtualImmediate12::new(
*offset_map
.get(&(i.value as u64))
.expect("new offset should be valid"),
crate::span::Span::new(" ".into(), 0, 0, None).unwrap(),
)
.unwrap(),
),
JNZI(r1, i) => Self::JNZI(
r1.clone(),
VirtualImmediate18::new(
*offset_map
.get(&(i.value as u64))
.expect("new offset should be valid"),
crate::span::Span::new(" ".into(), 0, 0, None).unwrap(),
)
.unwrap(),
),
_ => self.clone(),
}
}
pub(crate) fn allocate_registers(&self, pool: &RegisterPool) -> AllocatedOpcode {
let virtual_registers = self.registers();
let register_allocation_result = virtual_registers
.clone()
.into_iter()
.map(|x| match x {
VirtualRegister::Constant(c) => (x, Some(AllocatedRegister::Constant(*c))),
VirtualRegister::Virtual(_) => (x, pool.get_register(x)),
})
.map(|(x, register_opt)| register_opt.map(|register| (x, register)))
.collect::<Option<Vec<_>>>();
let mut mapping = HashMap::default();
match register_allocation_result {
Some(o) => {
for (key, val) in o {
mapping.insert(key, val);
}
}
None => {
unimplemented!(
"The allocator cannot resolve a register mapping for this program.
This is a temporary artifact of the extremely early stage version of this language.
Try to lower the number of variables you use."
);
}
};
use VirtualOp::*;
match self {
ADD(reg1, reg2, reg3) => AllocatedOpcode::ADD(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
map_reg(&mapping, reg3),
),
ADDI(reg1, reg2, imm) => AllocatedOpcode::ADDI(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
imm.clone(),
),
AND(reg1, reg2, reg3) => AllocatedOpcode::AND(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
map_reg(&mapping, reg3),
),
ANDI(reg1, reg2, imm) => AllocatedOpcode::ANDI(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
imm.clone(),
),
DIV(reg1, reg2, reg3) => AllocatedOpcode::DIV(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
map_reg(&mapping, reg3),
),
DIVI(reg1, reg2, imm) => AllocatedOpcode::DIVI(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
imm.clone(),
),
EQ(reg1, reg2, reg3) => AllocatedOpcode::EQ(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
map_reg(&mapping, reg3),
),
EXP(reg1, reg2, reg3) => AllocatedOpcode::EXP(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
map_reg(&mapping, reg3),
),
EXPI(reg1, reg2, imm) => AllocatedOpcode::EXPI(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
imm.clone(),
),
GT(reg1, reg2, reg3) => AllocatedOpcode::GT(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
map_reg(&mapping, reg3),
),
LT(reg1, reg2, reg3) => AllocatedOpcode::LT(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
map_reg(&mapping, reg3),
),
MLOG(reg1, reg2, reg3) => AllocatedOpcode::MLOG(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
map_reg(&mapping, reg3),
),
MOD(reg1, reg2, reg3) => AllocatedOpcode::MOD(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
map_reg(&mapping, reg3),
),
MODI(reg1, reg2, imm) => AllocatedOpcode::MODI(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
imm.clone(),
),
MOVE(reg1, reg2) => {
AllocatedOpcode::MOVE(map_reg(&mapping, reg1), map_reg(&mapping, reg2))
}
MOVI(reg1, imm) => AllocatedOpcode::MOVI(map_reg(&mapping, reg1), imm.clone()),
MROO(reg1, reg2, reg3) => AllocatedOpcode::MROO(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
map_reg(&mapping, reg3),
),
MUL(reg1, reg2, reg3) => AllocatedOpcode::MUL(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
map_reg(&mapping, reg3),
),
MULI(reg1, reg2, imm) => AllocatedOpcode::MULI(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
imm.clone(),
),
NOOP => AllocatedOpcode::NOOP,
NOT(reg1, reg2) => {
AllocatedOpcode::NOT(map_reg(&mapping, reg1), map_reg(&mapping, reg2))
}
OR(reg1, reg2, reg3) => AllocatedOpcode::OR(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
map_reg(&mapping, reg3),
),
ORI(reg1, reg2, imm) => AllocatedOpcode::ORI(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
imm.clone(),
),
SLL(reg1, reg2, reg3) => AllocatedOpcode::SLL(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
map_reg(&mapping, reg3),
),
SLLI(reg1, reg2, imm) => AllocatedOpcode::SLLI(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
imm.clone(),
),
SRL(reg1, reg2, reg3) => AllocatedOpcode::SRL(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
map_reg(&mapping, reg3),
),
SRLI(reg1, reg2, imm) => AllocatedOpcode::SRLI(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
imm.clone(),
),
SUB(reg1, reg2, reg3) => AllocatedOpcode::SUB(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
map_reg(&mapping, reg3),
),
SUBI(reg1, reg2, imm) => AllocatedOpcode::SUBI(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
imm.clone(),
),
XOR(reg1, reg2, reg3) => AllocatedOpcode::XOR(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
map_reg(&mapping, reg3),
),
XORI(reg1, reg2, imm) => AllocatedOpcode::XORI(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
imm.clone(),
),
JMP(reg1) => AllocatedOpcode::JMP(map_reg(&mapping, reg1)),
JI(imm) => AllocatedOpcode::JI(imm.clone()),
JNE(reg1, reg2, reg3) => AllocatedOpcode::JNE(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
map_reg(&mapping, reg3),
),
JNEI(reg1, reg2, imm) => AllocatedOpcode::JNEI(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
imm.clone(),
),
JNZI(reg1, imm) => AllocatedOpcode::JNZI(map_reg(&mapping, reg1), imm.clone()),
RET(reg) => AllocatedOpcode::RET(map_reg(&mapping, reg)),
ALOC(reg) => AllocatedOpcode::ALOC(map_reg(&mapping, reg)),
CFEI(imm) => AllocatedOpcode::CFEI(imm.clone()),
CFSI(imm) => AllocatedOpcode::CFSI(imm.clone()),
LB(reg1, reg2, imm) => AllocatedOpcode::LB(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
imm.clone(),
),
LW(reg1, reg2, imm) => AllocatedOpcode::LW(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
imm.clone(),
),
MCL(reg1, reg2) => {
AllocatedOpcode::MCL(map_reg(&mapping, reg1), map_reg(&mapping, reg2))
}
MCLI(reg1, imm) => AllocatedOpcode::MCLI(map_reg(&mapping, reg1), imm.clone()),
MCP(reg1, reg2, reg3) => AllocatedOpcode::MCP(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
map_reg(&mapping, reg3),
),
MCPI(reg1, reg2, imm) => AllocatedOpcode::MCPI(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
imm.clone(),
),
MEQ(reg1, reg2, reg3, reg4) => AllocatedOpcode::MEQ(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
map_reg(&mapping, reg3),
map_reg(&mapping, reg4),
),
SB(reg1, reg2, imm) => AllocatedOpcode::SB(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
imm.clone(),
),
SW(reg1, reg2, imm) => AllocatedOpcode::SW(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
imm.clone(),
),
BAL(reg1, reg2, reg3) => AllocatedOpcode::BAL(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
map_reg(&mapping, reg3),
),
BHEI(reg1) => AllocatedOpcode::BHEI(map_reg(&mapping, reg1)),
BHSH(reg1, reg2) => {
AllocatedOpcode::BHSH(map_reg(&mapping, reg1), map_reg(&mapping, reg2))
}
BURN(reg1) => AllocatedOpcode::BURN(map_reg(&mapping, reg1)),
CALL(reg1, reg2, reg3, reg4) => AllocatedOpcode::CALL(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
map_reg(&mapping, reg3),
map_reg(&mapping, reg4),
),
CB(reg1) => AllocatedOpcode::CB(map_reg(&mapping, reg1)),
CCP(reg1, reg2, reg3, reg4) => AllocatedOpcode::CCP(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
map_reg(&mapping, reg3),
map_reg(&mapping, reg4),
),
CROO(reg1, reg2) => {
AllocatedOpcode::CROO(map_reg(&mapping, reg1), map_reg(&mapping, reg2))
}
CSIZ(reg1, reg2) => {
AllocatedOpcode::CSIZ(map_reg(&mapping, reg1), map_reg(&mapping, reg2))
}
LDC(reg1, reg2, reg3) => AllocatedOpcode::LDC(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
map_reg(&mapping, reg3),
),
LOG(reg1, reg2, reg3, reg4) => AllocatedOpcode::LOG(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
map_reg(&mapping, reg3),
map_reg(&mapping, reg4),
),
LOGD(reg1, reg2, reg3, reg4) => AllocatedOpcode::LOGD(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
map_reg(&mapping, reg3),
map_reg(&mapping, reg4),
),
MINT(reg1) => AllocatedOpcode::MINT(map_reg(&mapping, reg1)),
RETD(reg1, reg2) => {
AllocatedOpcode::RETD(map_reg(&mapping, reg1), map_reg(&mapping, reg2))
}
RVRT(reg1) => AllocatedOpcode::RVRT(map_reg(&mapping, reg1)),
SMO(reg1, reg2, reg3, reg4) => AllocatedOpcode::SMO(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
map_reg(&mapping, reg3),
map_reg(&mapping, reg4),
),
SCWQ(reg1, reg2, reg3) => AllocatedOpcode::SCWQ(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
map_reg(&mapping, reg3),
),
SRW(reg1, reg2, reg3) => AllocatedOpcode::SRW(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
map_reg(&mapping, reg3),
),
SRWQ(reg1, reg2, reg3, reg4) => AllocatedOpcode::SRWQ(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
map_reg(&mapping, reg3),
map_reg(&mapping, reg4),
),
SWW(reg1, reg2, reg3) => AllocatedOpcode::SWW(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
map_reg(&mapping, reg3),
),
SWWQ(reg1, reg2, reg3, reg4) => AllocatedOpcode::SWWQ(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
map_reg(&mapping, reg3),
map_reg(&mapping, reg4),
),
TIME(reg1, reg2) => {
AllocatedOpcode::TIME(map_reg(&mapping, reg1), map_reg(&mapping, reg2))
}
TR(reg1, reg2, reg3) => AllocatedOpcode::TR(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
map_reg(&mapping, reg3),
),
TRO(reg1, reg2, reg3, reg4) => AllocatedOpcode::TRO(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
map_reg(&mapping, reg3),
map_reg(&mapping, reg4),
),
ECR(reg1, reg2, reg3) => AllocatedOpcode::ECR(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
map_reg(&mapping, reg3),
),
K256(reg1, reg2, reg3) => AllocatedOpcode::K256(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
map_reg(&mapping, reg3),
),
S256(reg1, reg2, reg3) => AllocatedOpcode::S256(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
map_reg(&mapping, reg3),
),
FLAG(reg) => AllocatedOpcode::FLAG(map_reg(&mapping, reg)),
GM(reg, imm) => AllocatedOpcode::GM(map_reg(&mapping, reg), imm.clone()),
GTF(reg1, reg2, imm) => AllocatedOpcode::GTF(
map_reg(&mapping, reg1),
map_reg(&mapping, reg2),
imm.clone(),
),
BLOB(imm) => AllocatedOpcode::BLOB(imm.clone()),
DataSectionOffsetPlaceholder => AllocatedOpcode::DataSectionOffsetPlaceholder,
DataSectionRegisterLoadPlaceholder => {
AllocatedOpcode::DataSectionRegisterLoadPlaceholder
}
LWDataId(reg1, label) => {
AllocatedOpcode::LWDataId(map_reg(&mapping, reg1), label.clone())
}
Undefined => AllocatedOpcode::Undefined,
}
}
}
fn map_reg(
mapping: &HashMap<&VirtualRegister, AllocatedRegister>,
reg: &VirtualRegister,
) -> AllocatedRegister {
mapping.get(reg).unwrap().clone()
}
fn update_reg(
reg_to_reg_map: &HashMap<VirtualRegister, VirtualRegister>,
reg: &VirtualRegister,
) -> VirtualRegister {
if let Some(r) = reg_to_reg_map.get(reg) {
r.clone()
} else {
reg.clone()
}
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub struct Label(pub(crate) usize);
impl fmt::Display for Label {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, ".{}", self.0)
}
}