1use lamina_mir::{Register, VirtualReg};
4
5pub fn load_register_to_rax<
7 W: std::io::Write,
8 RA: crate::regalloc::RegisterAllocator<PhysReg = &'static str>,
9>(
10 reg: &VirtualReg,
11 writer: &mut W,
12 reg_alloc: &RA,
13 stack_slots: &std::collections::HashMap<VirtualReg, i32>,
14) -> Result<(), std::io::Error> {
15 if let Some(phys) = reg_alloc.get_mapping(reg) {
16 writeln!(writer, " movq %{}, %rax", phys)?;
17 } else if let Some(offset) = stack_slots.get(reg) {
18 writeln!(writer, " movq {}(%rbp), %rax", offset)?;
19 } else {
20 return Err(std::io::Error::new(
21 std::io::ErrorKind::InvalidData,
22 format!("Virtual register {:?} has no mapping or stack slot", reg),
23 ));
24 }
25 Ok(())
26}
27
28pub fn store_rax_to_register<
30 W: std::io::Write,
31 RA: crate::regalloc::RegisterAllocator<PhysReg = &'static str>,
32>(
33 reg: &VirtualReg,
34 writer: &mut W,
35 reg_alloc: &RA,
36 stack_slots: &std::collections::HashMap<VirtualReg, i32>,
37) -> Result<(), std::io::Error> {
38 if let Some(phys) = reg_alloc.get_mapping(reg) {
39 writeln!(writer, " movq %rax, %{}", phys)?;
40 } else if let Some(offset) = stack_slots.get(reg) {
41 writeln!(writer, " movq %rax, {}(%rbp)", offset)?;
42 } else {
43 return Err(std::io::Error::new(
44 std::io::ErrorKind::InvalidData,
45 format!("Virtual register {:?} has no mapping or stack slot", reg),
46 ));
47 }
48 Ok(())
49}
50
51pub fn load_register_to_register<
53 W: std::io::Write,
54 RA: crate::regalloc::RegisterAllocator<PhysReg = &'static str>,
55>(
56 src: &VirtualReg,
57 writer: &mut W,
58 reg_alloc: &RA,
59 stack_slots: &std::collections::HashMap<VirtualReg, i32>,
60 target_reg: &str,
61) -> Result<(), std::io::Error> {
62 if let Some(phys) = reg_alloc.get_mapping(src) {
63 writeln!(writer, " movq %{}, %{}", phys, target_reg)?;
64 } else if let Some(offset) = stack_slots.get(src) {
65 writeln!(writer, " movq {}(%rbp), %{}", offset, target_reg)?;
66 } else {
67 return Err(std::io::Error::new(
68 std::io::ErrorKind::InvalidData,
69 format!("Virtual register {:?} has no mapping or stack slot", src),
70 ));
71 }
72 Ok(())
73}
74
75pub fn load_operand_to_rax<
77 W: std::io::Write,
78 RA: crate::regalloc::RegisterAllocator<PhysReg = &'static str>,
79>(
80 operand: &lamina_mir::Operand,
81 writer: &mut W,
82 reg_alloc: &RA,
83 stack_slots: &std::collections::HashMap<VirtualReg, i32>,
84) -> Result<(), std::io::Error> {
85 match operand {
86 lamina_mir::Operand::Register(reg) => match reg {
87 Register::Virtual(v) => load_register_to_rax(v, writer, reg_alloc, stack_slots),
88 Register::Physical(p) => {
89 writeln!(writer, " movq %{}, %rax", p.name)?;
90 Ok(())
91 }
92 },
93 lamina_mir::Operand::Immediate(imm) => match imm {
94 lamina_mir::instruction::Immediate::I8(v) => {
95 writeln!(writer, " movq ${}, %rax", *v as i64)
96 }
97 lamina_mir::instruction::Immediate::I16(v) => {
98 writeln!(writer, " movq ${}, %rax", *v as i64)
99 }
100 lamina_mir::instruction::Immediate::I32(v) => {
101 writeln!(writer, " movq ${}, %rax", *v as i64)
102 }
103 lamina_mir::instruction::Immediate::I64(v) => writeln!(writer, " movq ${}, %rax", v),
104 lamina_mir::instruction::Immediate::F32(_)
105 | lamina_mir::instruction::Immediate::F64(_) => {
106 writeln!(
107 writer,
108 " # Floating point immediates not yet implemented"
109 )?;
110 Ok(())
111 }
112 },
113 }
114}
115
116pub fn load_operand_to_register<
118 W: std::io::Write,
119 RA: crate::regalloc::RegisterAllocator<PhysReg = &'static str>,
120>(
121 operand: &lamina_mir::Operand,
122 writer: &mut W,
123 reg_alloc: &RA,
124 stack_slots: &std::collections::HashMap<VirtualReg, i32>,
125 target_reg: &str,
126) -> Result<(), std::io::Error> {
127 match operand {
128 lamina_mir::Operand::Register(reg) => match reg {
129 Register::Virtual(v) => {
130 load_register_to_register(v, writer, reg_alloc, stack_slots, target_reg)
131 }
132 Register::Physical(p) => {
133 writeln!(writer, " movq %{}, %{}", p.name, target_reg)?;
134 Ok(())
135 }
136 },
137 lamina_mir::Operand::Immediate(imm) => match imm {
138 lamina_mir::instruction::Immediate::I8(v) => {
139 writeln!(writer, " movq ${}, %{}", *v as i64, target_reg)
140 }
141 lamina_mir::instruction::Immediate::I16(v) => {
142 writeln!(writer, " movq ${}, %{}", *v as i64, target_reg)
143 }
144 lamina_mir::instruction::Immediate::I32(v) => {
145 writeln!(writer, " movq ${}, %{}", *v as i64, target_reg)
146 }
147 lamina_mir::instruction::Immediate::I64(v) => {
148 writeln!(writer, " movq ${}, %{}", v, target_reg)
149 }
150 lamina_mir::instruction::Immediate::F32(_)
151 | lamina_mir::instruction::Immediate::F64(_) => {
152 writeln!(
153 writer,
154 " # Floating point immediates not yet implemented"
155 )?;
156 Ok(())
157 }
158 },
159 }
160}