GitLab will continue to be upgraded from 11.4.5-ce.0 on November 25th 2019 at 4.00pm (AEDT) to 5.00pm (AEDT) due to Critical Security Patch Availability. During the update, GitLab and Mattermost services will not be available.

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