feat(backend): Support cmp/label/bc/br ir instr
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
use std::{fmt::Display, ops::Add};
|
||||
|
||||
use crate::backend::register_allocator::{REG_FP, REG_LR, REG_PC, REG_R0, REG_R1, REG_R2, REG_R3, REG_R12, REG_SP, Register};
|
||||
use crate::{backend::register_allocator::{REG_FP, REG_LR, REG_PC, REG_R0, REG_R1, REG_R2, REG_R3, REG_R12, REG_SP, Register}, ir::types::CmpOp as IRCmpOp};
|
||||
pub enum ARMInstr{
|
||||
Move(MoveInstr),
|
||||
Load(LoadInstr),
|
||||
@@ -10,11 +10,14 @@ pub enum ARMInstr{
|
||||
SDiv(SDivInstr),
|
||||
Add(AddInstr),
|
||||
Sub(SubInstr),
|
||||
Rsb(RsbInstr),
|
||||
Cmp(CmpInstr),
|
||||
Push(PushInstr),
|
||||
Pop(PopInstr),
|
||||
FunctionHead(String, usize),
|
||||
Bl(BlInstr),
|
||||
B(BInstr),
|
||||
Label(String),
|
||||
}
|
||||
|
||||
impl Display for ARMInstr {
|
||||
@@ -28,11 +31,14 @@ impl Display for ARMInstr {
|
||||
ARMInstr::SDiv(instr) => write!(f, "{}", instr),
|
||||
ARMInstr::Add(instr) => write!(f, "{}", instr),
|
||||
ARMInstr::Sub(instr) => write!(f, "{}", instr),
|
||||
ARMInstr::Rsb(instr) => write!(f, "{}", instr),
|
||||
ARMInstr::Cmp(instr) => write!(f, "{}", instr),
|
||||
ARMInstr::Push(instr) => write!(f, "{}", instr),
|
||||
ARMInstr::Pop(instr) => write!(f, "{}", instr),
|
||||
ARMInstr::Bl(instr) => write!(f, "{}", instr),
|
||||
ARMInstr::B(instr) => write!(f, "{}", instr),
|
||||
ARMInstr::FunctionHead(name, align_size) => write!(f, ".align {}\n.global {}\n.type {}, %function\n{}:", align_size, name, name, name),
|
||||
ARMInstr::Label(name) => write!(f, "{}:", name),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -56,6 +62,18 @@ pub enum ConditionCode {
|
||||
Gt,
|
||||
Ge,
|
||||
}
|
||||
impl From<IRCmpOp> for ConditionCode {
|
||||
fn from(cmp_op: IRCmpOp) -> Self {
|
||||
match cmp_op {
|
||||
IRCmpOp::Eq => ConditionCode::Eq,
|
||||
IRCmpOp::Ne => ConditionCode::Ne,
|
||||
IRCmpOp::Lt => ConditionCode::Lt,
|
||||
IRCmpOp::Le => ConditionCode::Le,
|
||||
IRCmpOp::Gt => ConditionCode::Gt,
|
||||
IRCmpOp::Ge => ConditionCode::Ge,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Display for ConditionCode {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let code_str = match self {
|
||||
@@ -89,6 +107,9 @@ impl MoveInstr {
|
||||
pub fn new_uncond(dest: Register, src: RegisterOrImm) -> ARMInstr {
|
||||
ARMInstr::Move(MoveInstr(None, dest, src))
|
||||
}
|
||||
pub fn new_cond(condition: ConditionCode, dest: Register, src: RegisterOrImm) -> ARMInstr {
|
||||
ARMInstr::Move(MoveInstr(Some(condition), dest, src))
|
||||
}
|
||||
pub fn new_sp_to_fp() -> ARMInstr {
|
||||
ARMInstr::Move(MoveInstr(None, REG_FP, RegisterOrImm::Reg(REG_SP)))
|
||||
}
|
||||
@@ -205,20 +226,37 @@ impl SubInstr {
|
||||
ARMInstr::Sub(SubInstr(REG_SP, REG_SP, RegisterOrImm::Imm(offset)))
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for SubInstr {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let SubInstr(dest, left, right) = self;
|
||||
write!(f, "sub {}, {}, {}", dest, left, right)
|
||||
}
|
||||
}
|
||||
pub struct CmpInstr(Register, Register);
|
||||
pub struct RsbInstr(Register, Register, RegisterOrImm);
|
||||
impl RsbInstr {
|
||||
pub fn new(dest: Register, left: Register, right: RegisterOrImm) -> ARMInstr {
|
||||
ARMInstr::Rsb(RsbInstr(dest, left, right))
|
||||
}
|
||||
}
|
||||
impl Display for RsbInstr {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let RsbInstr(dest, left, right) = self;
|
||||
write!(f, "rsb {}, {}, {}", dest, left, right)
|
||||
}
|
||||
}
|
||||
pub struct CmpInstr(Register, RegisterOrImm);
|
||||
impl Display for CmpInstr {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let CmpInstr(left, right) = self;
|
||||
write!(f, "cmp {}, {}", left, right)
|
||||
}
|
||||
}
|
||||
|
||||
impl CmpInstr {
|
||||
pub fn new(left: Register, right: RegisterOrImm) -> ARMInstr {
|
||||
ARMInstr::Cmp(CmpInstr(left, right))
|
||||
}
|
||||
}
|
||||
pub struct PushInstr(Vec<Register>);
|
||||
impl PushInstr {
|
||||
pub fn new_push_fp_lr() -> ARMInstr {
|
||||
@@ -272,16 +310,41 @@ impl Display for PopInstr {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BlInstr(String);
|
||||
pub struct BlInstr(Option<ConditionCode>, String);
|
||||
impl Display for BlInstr {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let BlInstr(func_name) = self;
|
||||
write!(f, "bl {}", func_name)
|
||||
match &self.0 {
|
||||
Some(condition) => write!(f, "bl{} {}", condition, self.1),
|
||||
None => write!(f, "bl {}", self.1),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl BlInstr {
|
||||
pub fn new(func_name: String) -> ARMInstr {
|
||||
ARMInstr::Bl(BlInstr(func_name))
|
||||
pub fn new(label_name: String) -> ARMInstr {
|
||||
ARMInstr::Bl(BlInstr(None, label_name))
|
||||
}
|
||||
|
||||
pub fn new_cond(condition: ConditionCode, label_name: String) -> ARMInstr {
|
||||
ARMInstr::Bl(BlInstr(Some(condition), label_name))
|
||||
}
|
||||
}
|
||||
pub struct BInstr(Option<ConditionCode>, String);
|
||||
impl Display for BInstr {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match &self.0 {
|
||||
Some(condition) => write!(f, "b{} {}", condition, self.1),
|
||||
None => write!(f, "b {}", self.1),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl BInstr {
|
||||
pub fn new(label_name: String) -> ARMInstr {
|
||||
ARMInstr::B(BInstr(None, label_name))
|
||||
}
|
||||
|
||||
pub fn new_cond(condition: ConditionCode, label_name: String) -> ARMInstr {
|
||||
ARMInstr::B(BInstr(Some(condition), label_name))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user