use crate::{
backend::riscv::from_ir::{function::FunctionCompileContext, register_assign::RegisterAssign},
ir,
};
pub fn emit_code(
statement: &ir::function::statement::Store,
ctx: &mut FunctionCompileContext,
) -> String {
let ir::function::statement::Store {
data_type: _,
source,
target,
} = statement;
let mut result = String::new();
let source_register = match source {
ir::quantity::Quantity::RegisterName(local) => {
let local = ctx.local_assign.get(local).unwrap();
match local {
RegisterAssign::Register(register) => register.clone(),
RegisterAssign::StackValue(stack_offset) => {
result.push_str(&format!(" lw t0, {stack_offset}(sp)\n"));
"t0".to_string()
}
RegisterAssign::StackRef(_) => unreachable!(),
RegisterAssign::MultipleRegisters(registers) => {
if let ir::quantity::Quantity::RegisterName(local) = target {
let local = ctx.local_assign.get(local).unwrap();
if let RegisterAssign::StackRef(stack_offset) = local {
for (i, register) in registers.iter().enumerate() {
result.push_str(&format!(
" sw {}, {}(sp)\n",
register,
stack_offset + i * 4
));
}
} else {
unimplemented!()
}
} else {
unimplemented!()
}
return result;
}
}
}
ir::quantity::Quantity::GlobalVariableName(_) => todo!(),
ir::quantity::Quantity::NumberLiteral(n) => {
result.push_str(&format!(" li t0, {n}\n"));
"t0".to_string()
}
};
let target_stack_offset = if let ir::quantity::Quantity::RegisterName(local) = target {
let local = ctx.local_assign.get(local).unwrap();
match local {
RegisterAssign::StackRef(stack_offset) => stack_offset,
RegisterAssign::Register(_) => todo!(),
RegisterAssign::StackValue(_stack_offset) => todo!(),
RegisterAssign::MultipleRegisters(_) => todo!(),
}
} else {
todo!()
};
result.push_str(&format!(
" sw {source_register}, {target_stack_offset}(sp)\n"
));
result
}