Skip to content

Commit

Permalink
semi-functional state again
Browse files Browse the repository at this point in the history
  • Loading branch information
Vlamonster committed Dec 5, 2023
1 parent 4829bbd commit 3730bb9
Show file tree
Hide file tree
Showing 23 changed files with 215 additions and 172 deletions.
2 changes: 1 addition & 1 deletion compiler/src/passes/assign/assign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ fn assign_instr<'p>(
) -> Instr<Arg, UniqueSym<'p>> {
let map = |arg: VarArg<UniqueSym<'p>>| -> Arg {
match arg {
VarArg::Imm { val } => Arg::Imm { val },
VarArg::Imm(imm) => Arg::Imm(imm),
VarArg::Reg { reg } => Arg::Reg { reg },
VarArg::Deref { reg, off } => Arg::Deref { reg, off },
VarArg::XVar { sym } => color_map[&sym].clone(),
Expand Down
10 changes: 6 additions & 4 deletions compiler/src/passes/assign/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ mod color_interference;
mod compute_interference;
mod include_liveness;

use crate::passes::select::{Block, FunSelected, Instr, InstrSelected, Reg, VarArg, X86Selected};
use crate::passes::select::{
Block, FunSelected, Imm, Instr, InstrSelected, Reg, VarArg, X86Selected,
};
use crate::utils::gen_sym::UniqueSym;
use derive_more::Display;
use functor_derive::Functor;
Expand All @@ -27,8 +29,8 @@ pub type InstrAssigned<'p> = Instr<Arg, UniqueSym<'p>>;

#[derive(Clone, Display)]
pub enum Arg {
#[display(fmt = "${val}")]
Imm { val: i64 },
#[display(fmt = "${_0}")]
Imm(Imm),
#[display(fmt = "%{reg}")]
Reg { reg: Reg },
#[display(fmt = "[%{reg} + ${off}]")]
Expand Down Expand Up @@ -79,7 +81,7 @@ impl<'p> From<LBlock<'p>> for Block<'p, VarArg<UniqueSym<'p>>> {
impl<'p> From<Arg> for VarArg<UniqueSym<'p>> {
fn from(value: Arg) -> Self {
match value {
Arg::Imm { val } => VarArg::Imm { val },
Arg::Imm(imm) => VarArg::Imm(imm),
Arg::Reg { reg } => VarArg::Reg { reg },
Arg::Deref { reg, off } => VarArg::Deref { reg, off },
}
Expand Down
18 changes: 13 additions & 5 deletions compiler/src/passes/conclude/conclude.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::passes::assign::{Arg, InstrAssigned};
use crate::passes::conclude::X86Concluded;
use crate::passes::patch::X86Patched;
use crate::passes::select::{Block, Instr};
use crate::passes::select::{Block, Imm, Instr};
use crate::utils::gen_sym::gen_sym;
use crate::*;

Expand Down Expand Up @@ -44,7 +44,7 @@ impl<'p> X86Patched<'p> {
block!(
callq_direct!(entries[&self.entry], 0),
movq!(reg!(RAX), reg!(RDI)),
movq!(imm!(0x3C), reg!(RAX)),
movq!(imm32!(0x3C), reg!(RAX)), // todo: can be smaller
syscall!(2)
),
);
Expand All @@ -58,15 +58,23 @@ fn fix_stack_space(block: &mut Block<Arg>, stack_space: usize) {
for instr in &mut block.instrs {
match instr {
InstrAssigned::Addq {
src: Arg::Imm { val },
src: Arg::Imm(Imm::Imm32(val)),
..
}
| InstrAssigned::Subq {
src: Arg::Imm { val },
src: Arg::Imm(Imm::Imm32(val)),
..
} => {
assert_eq!(*val, 0x1000);
*val = stack_space as i64;
*val = stack_space as u32;
}
InstrAssigned::Addq {
src: Arg::Imm(_), ..
}
| InstrAssigned::Subq {
src: Arg::Imm(_), ..
} => {
todo!()
}
_ => {}
}
Expand Down
1 change: 0 additions & 1 deletion compiler/src/passes/conclude/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use crate::passes::select::Block;
use crate::utils::gen_sym::UniqueSym;
use std::collections::HashMap;


pub struct X86Concluded<'p> {
pub blocks: HashMap<UniqueSym<'p>, Block<'p, Arg>>,
pub entry: UniqueSym<'p>,
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/passes/eliminate/eliminate_params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub fn flatten_type<'p>(
defs: &HashMap<UniqueSym<'p>, TypeDef<UniqueSym<'p>, &'p str>>,
) -> Vec<(UniqueSym<'p>, Type<UniqueSym<'p>>)> {
match typ {
Type::Int {..} | Type::Bool | Type::Unit | Type::Never | Type::Fn { .. } => {
Type::Int { .. } | Type::Bool | Type::Unit | Type::Never | Type::Fn { .. } => {
vec![(sym, typ.clone())]
}
Type::Var { sym: def_sym } => match &defs[&def_sym] {
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/passes/eliminate/eliminate_seq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ pub fn eliminate_seq<'p>(
// Changes based on LHS
match typ {
// No changes needed
Type::Int {.. } | Type::Bool | Type::Unit | Type::Never | Type::Fn { .. } => {
Type::Int { .. } | Type::Bool | Type::Unit | Type::Never | Type::Fn { .. } => {
TailEliminated::Seq {
syms: vec![sym],
bnd: Meta {
Expand Down
98 changes: 62 additions & 36 deletions compiler/src/passes/emit/binary.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::passes::assign::Arg;
use crate::passes::emit::encode_reg;
use crate::passes::select::Reg;
use crate::passes::select::{Imm, Reg};

pub struct BinaryOpInfo {
/// Opcode when src = Reg and dst = Reg | Deref.
Expand Down Expand Up @@ -105,35 +105,43 @@ pub fn encode_binary_instr(op_info: BinaryOpInfo, src: &Arg, dst: &Arg) -> Vec<u
v.extend(off.to_le_bytes());
v
}
(Arg::Imm { val: imm }, Arg::Reg { reg: dst }) => {
let (d, ddd) = encode_reg(dst);
let imm = *imm as i32;
(Arg::Imm(imm), Arg::Reg { reg: dst }) => match imm {
Imm::Imm8(_) => todo!(),
Imm::Imm16(_) => todo!(),
Imm::Imm32(imm) => {
let (d, ddd) = encode_reg(dst);

let mut v = vec![
0b0100_1000 | d,
op_info.i_rm,
0b11_000_000 | op_info.pad << 3 | ddd,
];
v.extend(imm.to_le_bytes());
v
}
(Arg::Imm { val: imm }, Arg::Deref { reg: dst, off }) => {
let (d, ddd) = encode_reg(dst);
let off = *off as i32;
let imm = *imm as i32;
let mut v = vec![
0b0100_1000 | d,
op_info.i_rm,
0b11_000_000 | op_info.pad << 3 | ddd,
];
v.extend(imm.to_le_bytes());
v
}
Imm::Imm64(_) => todo!(),
},
(Arg::Imm(imm), Arg::Deref { reg: dst, off }) => match imm {
Imm::Imm8(_) => todo!(),
Imm::Imm16(_) => todo!(),
Imm::Imm32(imm) => {
let (d, ddd) = encode_reg(dst);
let off = *off as i32;

let mut v = vec![
0b0100_1000 | d,
op_info.i_rm,
0b10_000_000 | op_info.pad << 3 | ddd,
];
if matches!(dst, Reg::RSP | Reg::R12) {
v.push(0x24);
let mut v = vec![
0b0100_1000 | d,
op_info.i_rm,
0b10_000_000 | op_info.pad << 3 | ddd,
];
if matches!(dst, Reg::RSP | Reg::R12) {
v.push(0x24);
}
v.extend(off.to_le_bytes());
v.extend(imm.to_le_bytes());
v
}
v.extend(off.to_le_bytes());
v.extend(imm.to_le_bytes());
v
}
Imm::Imm64(_) => todo!(),
},
(Arg::Deref { .. }, Arg::Deref { .. }) => {
unreachable!("Found binary instruction with 2 derefs.");
}
Expand All @@ -153,7 +161,7 @@ mod tests {
check!(reg_reg, addq!(reg!(RSP), reg!(RDX)), vec![0x48, 0x01, 0xE2]);
check!(
imm_reg,
addq!(imm!(i32::MAX as i64), reg!(RBP)),
addq!(imm32!(i32::MAX as i64), reg!(RBP)),
vec![0x48, 0x81, 0xC5, 0xFF, 0xFF, 0xFF, 0x7F]
);
check!(
Expand All @@ -173,12 +181,18 @@ mod tests {
);
check!(
imm_deref1,
addq!(imm!((i32::MAX - 0xFF) as i64), deref!(R9, i32::MAX as i64)),
addq!(
imm32!((i32::MAX - 0xFF) as i64),
deref!(R9, i32::MAX as i64)
),
vec![0x49, 0x81, 0x81, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0xFF, 0xFF, 0x7F]
);
check!(
imm_deref2,
addq!(imm!((i32::MAX - 0xFF) as i64), deref!(RDX, i32::MAX as i64)),
addq!(
imm32!((i32::MAX - 0xFF) as i64),
deref!(RDX, i32::MAX as i64)
),
vec![0x48, 0x81, 0x82, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0xFF, 0xFF, 0x7F]
);
}
Expand All @@ -189,7 +203,7 @@ mod tests {
check!(reg_reg, subq!(reg!(RSP), reg!(RDX)), vec![0x48, 0x29, 0xE2]);
check!(
imm_reg,
subq!(imm!(i32::MAX as i64), reg!(RBP)),
subq!(imm32!(i32::MAX as i64), reg!(RBP)),
vec![0x48, 0x81, 0xED, 0xFF, 0xFF, 0xFF, 0x7F]
);
check!(
Expand All @@ -209,12 +223,18 @@ mod tests {
);
check!(
imm_deref1,
subq!(imm!((i32::MAX - 0xFF) as i64), deref!(R9, i32::MAX as i64)),
subq!(
imm32!((i32::MAX - 0xFF) as i64),
deref!(R9, i32::MAX as i64)
),
vec![0x49, 0x81, 0xA9, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0xFF, 0xFF, 0x7F]
);
check!(
imm_deref2,
subq!(imm!((i32::MAX - 0xFF) as i64), deref!(RDX, i32::MAX as i64)),
subq!(
imm32!((i32::MAX - 0xFF) as i64),
deref!(RDX, i32::MAX as i64)
),
vec![0x48, 0x81, 0xAA, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0xFF, 0xFF, 0x7F]
);
}
Expand All @@ -225,7 +245,7 @@ mod tests {
check!(reg_reg, movq!(reg!(RSP), reg!(RDX)), vec![0x48, 0x89, 0xE2]);
check!(
imm_reg,
movq!(imm!(i32::MAX as i64), reg!(RBP)),
movq!(imm32!(i32::MAX as i64), reg!(RBP)),
vec![0x48, 0xC7, 0xC5, 0xFF, 0xFF, 0xFF, 0x7F]
);
check!(
Expand All @@ -250,12 +270,18 @@ mod tests {
);
check!(
imm_deref1,
movq!(imm!((i32::MAX - 0xFF) as i64), deref!(R9, i32::MAX as i64)),
movq!(
imm32!((i32::MAX - 0xFF) as i64),
deref!(R9, i32::MAX as i64)
),
vec![0x49, 0xC7, 0x81, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0xFF, 0xFF, 0x7F]
);
check!(
imm_deref2,
movq!(imm!((i32::MAX - 0xFF) as i64), deref!(RDX, i32::MAX as i64)),
movq!(
imm32!((i32::MAX - 0xFF) as i64),
deref!(RDX, i32::MAX as i64)
),
vec![0x48, 0xC7, 0x82, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0xFF, 0xFF, 0x7F]
);
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/passes/emit/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ mod push_pop;
mod special;
mod unary;

use crate::imm32;
use crate::passes::assign::Arg;
use crate::passes::conclude::X86Concluded;
use crate::passes::emit::binary::{
Expand All @@ -18,7 +19,6 @@ use crate::passes::emit::unary::{encode_unary_instr, CALLQ_INDIRECT_INFO, NEGQ_I
use crate::passes::select::{Block, Cnd, Instr, Reg};
use crate::utils::gen_sym::UniqueSym;
use std::collections::HashMap;
use crate::imm32;

impl<'p> X86Concluded<'p> {
#[must_use]
Expand Down
20 changes: 12 additions & 8 deletions compiler/src/passes/emit/push_pop.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::passes::assign::Arg;
use crate::passes::emit;
use crate::passes::select::Imm;

pub struct PushPopInfo {
pub op_reg: u8,
Expand All @@ -24,13 +25,16 @@ pub const POPQ_INFO: PushPopInfo = PushPopInfo {

pub fn encode_push_pop(op_info: PushPopInfo, reg: &Arg) -> Vec<u8> {
match reg {
Arg::Imm { val } => {
let val = *val as i32;

let mut v = vec![op_info.op_imm];
v.extend(val.to_le_bytes());
v
}
Arg::Imm(imm) => match imm {
Imm::Imm8(_) => todo!(),
Imm::Imm16(_) => todo!(),
Imm::Imm32(val) => {
let mut v = vec![op_info.op_imm];
v.extend(val.to_le_bytes());
v
}
Imm::Imm64(_) => todo!(),
},
Arg::Reg { reg } => {
let (r, rrr) = emit::encode_reg(reg);
if r == 0 {
Expand Down Expand Up @@ -84,7 +88,7 @@ mod tests {

check!(
imm,
pushq!(imm!(i32::MAX as i64)),
pushq!(imm32!(i32::MAX as i64)),
vec![0x68, 0xFF, 0xFF, 0xFF, 0x7F]
);
}
Expand Down
7 changes: 3 additions & 4 deletions compiler/src/passes/explicate/explicate_pred.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,10 +178,9 @@ pub fn explicate_pred<'p>(
// cargo format should get some help
AExpr::FunRef { .. }
| AExpr::Atom {
atm:
Atom::Val {
val: TLit::Int { .. } | TLit::Unit,
},
atm: Atom::Val {
val: TLit::Int { .. } | TLit::Unit,
},
..
}
| AExpr::Assign { .. }
Expand Down
6 changes: 2 additions & 4 deletions compiler/src/passes/parse/grammar.lalrpop
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::passes::parse::{
BinaryOp, DefParsed, ExprParsed, InstrParsed, Lit, Meta, Param, PrgParsed, Spanned, Type, TypeDef, UnaryOp, types::Int,
};
use crate::passes::select::{VarArg, Reg};
use crate::passes::select::{VarArg, Reg, Imm};
use functor_derive::Functor;

grammar;
Expand Down Expand Up @@ -407,9 +407,7 @@ AsmInstr: InstrParsed<'input> = {
AsmArg: VarArg<Spanned<&'input str>> = {
<reg:AsmReg> => VarArg::Reg { reg },
"{" <sym:Ident> "}" => VarArg::XVar { sym },
"$" <val:Int> => VarArg::Imm {
val: val.parse().expect("Internal compiler error (oh no!): We were too lazy to make a proper error for this"),
},
"$" <val:Int> => VarArg::Imm(Imm::Imm32(val.parse().expect("Internal compiler error (oh no!): We were too lazy to make a proper error for this"))),
"[" <reg:AsmReg> "+" <off:Int> "]" => VarArg::Deref {
reg,
off: off.parse().expect("Internal compiler error (oh no!): We were too lazy to make a proper error for this"),
Expand Down
4 changes: 2 additions & 2 deletions compiler/src/passes/parse/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub enum Type<A> {

/// Integer types
#[derive(Debug, Clone, Display, Eq, PartialEq)]
pub enum Int{
pub enum Int {
I8,
U8,
I16,
Expand All @@ -33,4 +33,4 @@ pub enum Int{
U32,
I64,
U64,
}
}
2 changes: 1 addition & 1 deletion compiler/src/passes/select/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ macro_rules! syscall {
#[macro_export]
macro_rules! imm32 {
($val:expr) => {
$crate::passes::assign::Arg::Imm { val: todo!() }.into()
$crate::passes::assign::Arg::Imm($crate::passes::select::Imm::Imm32($val as u32)).into()
};
}

Expand Down
Loading

0 comments on commit 3730bb9

Please sign in to comment.