Skip to content

Commit 242d61e

Browse files
committed
Start to stack transform
1 parent 0e4d2c5 commit 242d61e

2 files changed

Lines changed: 83 additions & 1 deletion

File tree

rust_src/asm.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pub enum Operand {
1919
Immediate(Immediate),
2020
Register(RegId),
2121
Pseudo(Identifier),
22-
Stack(usize),
22+
Stack(i32),
2323
}
2424

2525
#[derive(Debug, Clone)]

rust_src/tacky_to_asm.rs

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//! Convert TACKY IR to ASM
22
3+
use std::{collections::HashMap, hash::Hash};
4+
35
use crate::{asm, ast, shared_types::Identifier, tacky};
46

57
fn simple_binary_to_asm(
@@ -190,6 +192,59 @@ fn program_to_asm(prog: &tacky::Program) -> asm::Program {
190192
asm::Program { function: func }
191193
}
192194

195+
struct MoveToStack {
196+
stack_size: i32,
197+
// Symbol to stack offset
198+
symbol_map: HashMap<String, i32>,
199+
}
200+
impl MoveToStack {
201+
fn new() -> MoveToStack {
202+
MoveToStack {
203+
stack_size: 0,
204+
symbol_map: HashMap::new(),
205+
}
206+
}
207+
208+
fn to_stack(&mut self, val: &mut asm::Operand) {
209+
if let asm::Operand::Pseudo(id) = val {
210+
let offset = if let Some(offset) = self.symbol_map.get(id.val()) {
211+
*offset
212+
} else {
213+
self.stack_size += 4;
214+
self.symbol_map.insert(id.val().clone(), self.stack_size);
215+
self.stack_size
216+
};
217+
*val = asm::Operand::Stack(-offset);
218+
}
219+
}
220+
221+
/// Move pseudo register operands to the stack. Returns needed stack space.
222+
fn move_to_stack(&mut self, prog: &mut asm::Program) -> i32 {
223+
prog
224+
.function
225+
.instructions
226+
.iter_mut()
227+
.for_each(|instr| match instr {
228+
asm::Instruction::Move { src, dst } => {
229+
self.to_stack(src);
230+
self.to_stack(dst);
231+
}
232+
asm::Instruction::Return => todo!(),
233+
asm::Instruction::Neg(operand) => todo!(),
234+
asm::Instruction::Not(operand) => todo!(),
235+
asm::Instruction::AllocateStack(_) => todo!(),
236+
asm::Instruction::Binary { op, src, dst } => todo!(),
237+
asm::Instruction::Idiv(operand) => todo!(),
238+
asm::Instruction::Cdq => todo!(),
239+
asm::Instruction::Cmp { src, dst } => todo!(),
240+
asm::Instruction::Jmp(identifier) => todo!(),
241+
asm::Instruction::JmpCC(condition_code, identifier) => todo!(),
242+
asm::Instruction::SetCC(condition_code, operand) => todo!(),
243+
asm::Instruction::Label(identifier) => todo!(),
244+
});
245+
self.stack_size
246+
}
247+
}
193248
/// Convert TACKY IR to ASM
194249
pub fn tacky_to_asm(prog: &tacky::Program) -> asm::Program {
195250
let asm_prog: asm::Program = program_to_asm(prog);
@@ -227,4 +282,31 @@ mod tests {
227282
};
228283
Ok(())
229284
}
285+
286+
#[test]
287+
fn pseudo_to_stack() {
288+
let mut prog = asm::Program {
289+
function: asm::Function {
290+
name: Identifier::new("main"),
291+
instructions: vec![asm::Instruction::Move {
292+
src: asm::Operand::Pseudo(Identifier::new("reg1")),
293+
dst: asm::Operand::Register(asm::RegId::AX),
294+
}],
295+
},
296+
};
297+
let mut mts = MoveToStack::new();
298+
mts.move_to_stack(&mut prog);
299+
match prog.function.instructions[..] {
300+
[
301+
asm::Instruction::Move {
302+
src: asm::Operand::Stack(-4),
303+
dst: _,
304+
},
305+
] => ..,
306+
_ => panic!(
307+
"Operand not moved to stack: {:?}",
308+
prog.function.instructions
309+
),
310+
};
311+
}
230312
}

0 commit comments

Comments
 (0)