Commit 8f260a2a authored by qinsoon's avatar qinsoon

backend code emission for factorial

parent 1ac03aae
......@@ -56,7 +56,7 @@ impl MuFunction {
let id = self.get_id();
self.context.value_tags.insert(tag, id);
self.context.values.insert(id, ValueEntry{id: id, tag: tag, ty: ty.clone(), use_count: Cell::new(0), expr: None});
self.context.values.insert(id, SSAVarEntry{id: id, tag: tag, ty: ty.clone(), use_count: Cell::new(0), expr: None});
P(TreeNode {
id: id,
......@@ -121,7 +121,7 @@ impl FunctionContent {
#[derive(Debug)]
pub struct FunctionContext {
pub value_tags: HashMap<MuTag, MuID>,
pub values: HashMap<MuID, ValueEntry>
pub values: HashMap<MuID, SSAVarEntry>
}
impl FunctionContext {
......@@ -132,14 +132,14 @@ impl FunctionContext {
}
}
pub fn get_value_by_tag(&self, tag: MuTag) -> Option<&ValueEntry> {
pub fn get_value_by_tag(&self, tag: MuTag) -> Option<&SSAVarEntry> {
match self.value_tags.get(tag) {
Some(id) => self.get_value(*id),
None => None
}
}
pub fn get_value_mut_by_tag(&mut self, tag: MuTag) -> Option<&mut ValueEntry> {
pub fn get_value_mut_by_tag(&mut self, tag: MuTag) -> Option<&mut SSAVarEntry> {
let id : MuID = match self.value_tags.get(tag) {
Some(id) => *id,
None => return None
......@@ -148,11 +148,11 @@ impl FunctionContext {
self.get_value_mut(id)
}
pub fn get_value(&self, id: MuID) -> Option<&ValueEntry> {
pub fn get_value(&self, id: MuID) -> Option<&SSAVarEntry> {
self.values.get(&id)
}
pub fn get_value_mut(&mut self, id: MuID) -> Option<&mut ValueEntry> {
pub fn get_value_mut(&mut self, id: MuID) -> Option<&mut SSAVarEntry> {
self.values.get_mut(&id)
}
}
......@@ -383,7 +383,7 @@ pub enum Value_ {
}
#[derive(Debug, Clone)]
pub struct ValueEntry {
pub struct SSAVarEntry {
pub id: MuID,
pub tag: MuTag,
pub ty: P<MuType>,
......@@ -396,13 +396,13 @@ pub struct ValueEntry {
pub expr: Option<Instruction>
}
impl ValueEntry {
impl SSAVarEntry {
pub fn assign_expr(&mut self, expr: Instruction) {
self.expr = Some(expr)
}
}
impl fmt::Display for ValueEntry {
impl fmt::Display for SSAVarEntry {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} {}#{}", self.ty, self.tag, self.id)
}
......
This diff is collapsed.
......@@ -3,6 +3,13 @@ use ast::ir::*;
use ast::inst::*;
pub trait CodeGenerator {
fn start_code(&mut self, func_name: MuTag);
fn finish_code(&mut self);
fn print_cur_code(&self);
fn start_block(&mut self, block_name: MuTag);
fn emit_cmp_r64_r64(&mut self, op1: &P<Value>, op2: &P<Value>);
fn emit_cmp_r64_imm32(&mut self, op1: &P<Value>, op2: u32);
fn emit_cmp_r64_mem64(&mut self, op1: &P<Value>, op2: &P<Value>);
......@@ -40,6 +47,6 @@ pub trait CodeGenerator {
fn emit_ret(&mut self);
fn emit_push(&mut self, src: &P<Value>);
fn emit_pop(&mut self, dest: &P<Value>);
fn emit_push_r64(&mut self, src: &P<Value>);
fn emit_pop_r64(&mut self, dest: &P<Value>);
}
\ No newline at end of file
......@@ -375,9 +375,11 @@ impl <'a> InstructionSelection {
}
fn emit_common_prologue(&mut self, args: &Vec<P<Value>>) {
self.backend.start_block("prologue");
// push all callee-saved registers
for reg in x86_64::CALLEE_SAVED_GPRs.iter() {
self.backend.emit_push(&reg);
self.backend.emit_push_r64(&reg);
}
// unload arguments
......@@ -401,9 +403,11 @@ impl <'a> InstructionSelection {
}
fn emit_common_epilogue(&mut self, ret_inst: &Instruction) {
self.backend.start_block("epilogue");
// pop all callee-saved registers
for reg in x86_64::CALLEE_SAVED_GPRs.iter() {
self.backend.emit_pop(&reg);
self.backend.emit_pop_r64(&reg);
}
let ref ops = ret_inst.ops.borrow();
......@@ -617,7 +621,9 @@ impl CompilerPass for InstructionSelection {
fn start_function(&mut self, vm_context: &VMContext, func: &mut MuFunction) {
debug!("{}", self.name());
// prologue (get arguments from entry block first)
self.backend.start_code(func.fn_name);
// prologue (get arguments from entry block first)
let entry_block = func.content.as_ref().unwrap().get_entry_block();
let ref args = entry_block.content.as_ref().unwrap().args;
self.emit_common_prologue(args);
......@@ -627,6 +633,8 @@ impl CompilerPass for InstructionSelection {
fn visit_function(&mut self, vm_context: &VMContext, func: &mut MuFunction) {
for block_label in func.block_trace.as_ref().unwrap() {
let block = func.content.as_mut().unwrap().get_block_mut(block_label);
self.backend.start_block(block.label);
let block_content = block.content.as_mut().unwrap();
......@@ -635,4 +643,11 @@ impl CompilerPass for InstructionSelection {
}
}
}
#[allow(unused_variables)]
fn finish_function(&mut self, vm_context: &VMContext, func: &mut MuFunction) {
self.backend.print_cur_code();
self.backend.finish_code();
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment