use crate::{
backend::riscv::from_ir::{function::FunctionCompileContext, register_assign::RegisterAssign},
ir,
};
pub fn emit_code(
statement: &ir::function::statement::Load,
ctx: &mut FunctionCompileContext,
) -> String {
let ir::function::statement::Load {
to,
data_type: _,
from,
} = statement;
let mut result = String::new();
let from_stack_offset = match from {
ir::quantity::Quantity::RegisterName(local) => {
let physical_register = ctx.local_assign.get(local).unwrap();
match physical_register {
RegisterAssign::Register(_register) => {
todo!()
}
RegisterAssign::StackRef(stack_offset) => stack_offset,
RegisterAssign::StackValue(_) => {
todo!()
}
RegisterAssign::MultipleRegisters(_) => unreachable!(),
}
}
ir::quantity::Quantity::GlobalVariableName(_global) => todo!(),
ir::quantity::Quantity::NumberLiteral(_literal) => unreachable!(),
};
let to_physical = ctx.local_assign.get(to).unwrap();
let to_register = match to_physical {
RegisterAssign::Register(register) => register.to_string(),
RegisterAssign::StackValue(_) => "t0".to_string(),
RegisterAssign::StackRef(_) => unreachable!(),
RegisterAssign::MultipleRegisters(registers) => {
for (i, register) in registers.iter().enumerate() {
result.push_str(&format!(
" lw {}, {}(sp)\n",
register,
from_stack_offset + i * 4
));
}
return result;
}
};
result.push_str(&format!(" lw {to_register}, {from_stack_offset}(sp)\n"));
if let RegisterAssign::StackValue(stack_offset) = to_physical {
result.push_str(&format!(" sw {to_register}, {stack_offset}(sp)\n"));
}
result
}