mir function type and using internpool
This commit is contained in:
parent
3be955aebf
commit
7801fefa17
|
@ -2,6 +2,7 @@ use std::{
|
|||
collections::BTreeMap,
|
||||
fmt::Display,
|
||||
hash::{Hash, Hasher},
|
||||
marker::PhantomData,
|
||||
};
|
||||
|
||||
use num_bigint::{BigInt, BigUint, Sign};
|
||||
|
@ -679,7 +680,8 @@ impl InternPool {
|
|||
Key::ArrayType { .. } => {
|
||||
panic!("arrays can't be directly accessed in mir")
|
||||
}
|
||||
Key::FunctionType { .. } | Key::PointerType { .. } => Type::QWord,
|
||||
Key::FunctionType { .. } => Type::Function,
|
||||
Key::PointerType { .. } => Type::QWord,
|
||||
Key::StructType { .. } => {
|
||||
panic!("arrays can't be directly accessed in mir")
|
||||
}
|
||||
|
|
88
src/mir.rs
88
src/mir.rs
|
@ -13,7 +13,6 @@ use itertools::Itertools;
|
|||
use crate::asm::amd64::Register;
|
||||
use crate::ast::IntegralType;
|
||||
use crate::ast2::intern;
|
||||
use crate::string_table::{Index as StringsIndex, StringTable};
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
|
||||
pub enum Type {
|
||||
|
@ -29,6 +28,7 @@ pub enum Type {
|
|||
SinglePrecision,
|
||||
/// 64bit ieee-754
|
||||
DoublePrecision,
|
||||
Function,
|
||||
// XWord,
|
||||
// YWord,
|
||||
// ZWord,
|
||||
|
@ -43,6 +43,7 @@ impl core::fmt::Display for Type {
|
|||
Type::QWord => "qword",
|
||||
Type::SinglePrecision => "f32",
|
||||
Type::DoublePrecision => "f64",
|
||||
Type::Function => "fn",
|
||||
};
|
||||
|
||||
write!(f, "{name}")
|
||||
|
@ -64,6 +65,7 @@ impl Type {
|
|||
Type::DWord => reg.into_dword(),
|
||||
Type::QWord => reg.into_qword(),
|
||||
Type::SinglePrecision | Type::DoublePrecision => reg,
|
||||
Type::Function => reg.into_qword(),
|
||||
}
|
||||
}
|
||||
pub const fn is_floating(self) -> bool {
|
||||
|
@ -93,6 +95,7 @@ impl Type {
|
|||
Type::QWord => 64,
|
||||
Type::SinglePrecision => 32,
|
||||
Type::DoublePrecision => 64,
|
||||
Type::Function => 64,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,7 +104,9 @@ impl Type {
|
|||
Type::Byte => Inst::ConstantByte,
|
||||
Type::Word => Inst::ConstantWord,
|
||||
Type::SinglePrecision | Type::DWord => Inst::ConstantDWord,
|
||||
Type::DoublePrecision | Type::QWord => Inst::ConstantQWord,
|
||||
Type::Function | Type::DoublePrecision | Type::QWord => {
|
||||
Inst::ConstantQWord
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -113,6 +118,7 @@ impl Type {
|
|||
Type::QWord => 8,
|
||||
Type::SinglePrecision => 4,
|
||||
Type::DoublePrecision => 8,
|
||||
Type::Function => 8,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -348,7 +354,7 @@ pub union Data {
|
|||
imm16: u16,
|
||||
imm32: u32,
|
||||
imm64: u64,
|
||||
index: StringsIndex,
|
||||
index: intern::Index,
|
||||
node: u32,
|
||||
binary: (u32, u32),
|
||||
}
|
||||
|
@ -387,7 +393,7 @@ impl Data {
|
|||
pub fn imm64(v: u64) -> Data {
|
||||
Self { imm64: v }
|
||||
}
|
||||
pub fn index(v: StringsIndex) -> Data {
|
||||
pub fn index(v: intern::Index) -> Data {
|
||||
Self { index: v }
|
||||
}
|
||||
pub fn node(v: u32) -> Data {
|
||||
|
@ -417,7 +423,7 @@ impl Data {
|
|||
pub fn as_imm64(self) -> u64 {
|
||||
unsafe { self.imm64 }
|
||||
}
|
||||
pub fn as_index(self) -> StringsIndex {
|
||||
pub fn as_index(self) -> intern::Index {
|
||||
unsafe { self.index }
|
||||
}
|
||||
pub fn as_node(self) -> u32 {
|
||||
|
@ -736,7 +742,7 @@ impl<'a> BinaryOperands<'a> {
|
|||
}
|
||||
|
||||
pub struct Mir {
|
||||
name: StringsIndex,
|
||||
name: intern::Index,
|
||||
pub nodes: Vec<Inst>,
|
||||
pub data: Vec<Data>,
|
||||
}
|
||||
|
@ -808,7 +814,7 @@ impl Mir {
|
|||
}
|
||||
|
||||
impl Mir {
|
||||
pub fn new(name: StringsIndex) -> Mir {
|
||||
pub fn new(name: intern::Index) -> Mir {
|
||||
Self {
|
||||
name,
|
||||
nodes: Vec::new(),
|
||||
|
@ -862,6 +868,20 @@ impl Mir {
|
|||
node
|
||||
}
|
||||
|
||||
pub fn push_const(&mut self, value: intern::Index, ty: Type) -> u32 {
|
||||
let inst = match ty {
|
||||
Type::Byte => Inst::ConstantByte,
|
||||
Type::Word => Inst::ConstantWord,
|
||||
Type::DWord => Inst::ConstantDWord,
|
||||
Type::QWord => Inst::ConstantQWord,
|
||||
Type::SinglePrecision => Inst::ConstantSinglePrecision,
|
||||
Type::DoublePrecision => Inst::ConstantDoublePrecision,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let data = Data::index(value);
|
||||
self.push(inst, data)
|
||||
}
|
||||
|
||||
pub fn gen_u8(&mut self, value: u8) -> u32 {
|
||||
self.push(Inst::ConstantByte, Data::imm8(value))
|
||||
}
|
||||
|
@ -1012,10 +1032,10 @@ impl Mir {
|
|||
alloc
|
||||
}
|
||||
|
||||
pub fn gen_label(&mut self, name: StringsIndex) -> u32 {
|
||||
pub fn gen_label(&mut self, name: intern::Index) -> u32 {
|
||||
self.push(Inst::Label, Data::index(name))
|
||||
}
|
||||
pub fn gen_extern(&mut self, ty: Option<Type>, name: StringsIndex) -> u32 {
|
||||
pub fn gen_extern(&mut self, ty: Option<Type>, name: intern::Index) -> u32 {
|
||||
self.push(Inst::ExternRef(ty), Data::index(name))
|
||||
}
|
||||
pub fn gen_alloca(&mut self, size: u32, align: u32) -> u32 {
|
||||
|
@ -1085,7 +1105,9 @@ impl Mir {
|
|||
Type::Byte => self.gen_u8(mask as u8),
|
||||
Type::Word => self.gen_u16(mask as u16),
|
||||
Type::SinglePrecision | Type::DWord => self.gen_u32(mask as u32),
|
||||
Type::DoublePrecision | Type::QWord => self.gen_u64(mask as u64),
|
||||
Type::Function | Type::DoublePrecision | Type::QWord => {
|
||||
self.gen_u64(mask as u64)
|
||||
}
|
||||
};
|
||||
|
||||
let masked = self.gen_bitand(ty, src, mask);
|
||||
|
@ -1303,7 +1325,7 @@ impl Mir {
|
|||
fn render_node<W: core::fmt::Write>(
|
||||
&self,
|
||||
w: &mut W,
|
||||
strings: &StringTable,
|
||||
ip: &intern::InternPool,
|
||||
liveness: &Liveness,
|
||||
node: u32,
|
||||
) -> core::fmt::Result {
|
||||
|
@ -1316,15 +1338,13 @@ impl Mir {
|
|||
}
|
||||
|
||||
match inst {
|
||||
Inst::Label => writeln!(
|
||||
w,
|
||||
"%{node} = label {}",
|
||||
strings.get_str(data.as_index())
|
||||
),
|
||||
Inst::Label => {
|
||||
writeln!(w, "%{node} = label {}", ip.get_str(data.as_index()))
|
||||
}
|
||||
Inst::ConstantBytes => writeln!(
|
||||
w,
|
||||
"%{node} = bytes({:x?})",
|
||||
strings.get_bytes(data.as_index())
|
||||
ip.get_bytes(data.as_index())
|
||||
),
|
||||
Inst::ConstantByte => {
|
||||
writeln!(w, "%{node} = imm8({:x?})", data.as_imm8())
|
||||
|
@ -1357,7 +1377,7 @@ impl Mir {
|
|||
if let Some(ty) = ty {
|
||||
write!(w, "{ty} ")?;
|
||||
}
|
||||
writeln!(w, "{}", strings.get_str(data.as_index()))
|
||||
writeln!(w, "{}", ip.get_str(data.as_index()))
|
||||
}
|
||||
Inst::Alloca => {
|
||||
let (size, align) = data.as_binary();
|
||||
|
@ -1535,20 +1555,20 @@ impl Mir {
|
|||
pub fn render<W: core::fmt::Write>(
|
||||
&self,
|
||||
w: &mut W,
|
||||
strings: &StringTable,
|
||||
ip: &intern::InternPool,
|
||||
) -> core::fmt::Result {
|
||||
let reg_alloc = self.build_liveness();
|
||||
for node in 0..self.nodes.len() {
|
||||
self.render_node(w, strings, ®_alloc, node as u32)?;
|
||||
self.render_node(w, ip, ®_alloc, node as u32)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn display<'a, 'b>(
|
||||
&'a self,
|
||||
strings: &'b StringTable,
|
||||
ip: &'b intern::InternPool,
|
||||
) -> DisplayMir<'a, 'b> {
|
||||
DisplayMir { mir: self, strings }
|
||||
DisplayMir { mir: self, ip }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2440,7 +2460,7 @@ impl core::fmt::Display for RipRelative {
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct Function {
|
||||
name: StringsIndex,
|
||||
name: intern::Index,
|
||||
constants: BTreeMap<usize, String>,
|
||||
branches: BTreeMap<NodeRef, String>,
|
||||
current_branch: NodeRef,
|
||||
|
@ -2451,7 +2471,7 @@ pub struct Function {
|
|||
// predefined constants: 0F32, 0F64, NEG1F32, NEG1F64
|
||||
|
||||
impl Function {
|
||||
fn new(name: StringsIndex) -> Self {
|
||||
fn new(name: intern::Index) -> Self {
|
||||
let current_branch = NodeRef::MIN;
|
||||
let branches = BTreeMap::from([(current_branch, String::new())]);
|
||||
Self {
|
||||
|
@ -2466,22 +2486,22 @@ impl Function {
|
|||
|
||||
pub fn finish_as_function(
|
||||
self,
|
||||
strings: &StringTable,
|
||||
ip: &intern::InternPool,
|
||||
) -> Result<String, core::fmt::Error> {
|
||||
let mut buf = String::new();
|
||||
self.finish(&mut buf, strings)?;
|
||||
self.finish(&mut buf, ip)?;
|
||||
|
||||
Ok(buf)
|
||||
}
|
||||
|
||||
pub fn finish_constants(
|
||||
self,
|
||||
strings: &StringTable,
|
||||
ip: &intern::InternPool,
|
||||
) -> Result<String, core::fmt::Error> {
|
||||
use core::fmt::Write;
|
||||
let mut buf = String::new();
|
||||
let w = &mut buf;
|
||||
let name = strings.get_str(self.name).to_owned();
|
||||
let name = ip.get_str(self.name).to_owned();
|
||||
writeln!(w, "{name}:")?;
|
||||
|
||||
for (_, contents) in self.constants {
|
||||
|
@ -2518,7 +2538,7 @@ impl Function {
|
|||
i: usize,
|
||||
inst: Inst,
|
||||
data: Data,
|
||||
strings: &StringTable,
|
||||
strings: &intern::InternPool,
|
||||
) {
|
||||
match inst {
|
||||
Inst::ConstantBytes => {
|
||||
|
@ -2552,7 +2572,7 @@ impl Function {
|
|||
pub fn finish<W: core::fmt::Write>(
|
||||
mut self,
|
||||
w: &mut W,
|
||||
strings: &StringTable,
|
||||
strings: &intern::InternPool,
|
||||
) -> core::fmt::Result {
|
||||
let name = strings.get_str(self.name).to_owned();
|
||||
writeln!(w, ".globl {name}")?;
|
||||
|
@ -2603,7 +2623,7 @@ impl Mir {
|
|||
liveness: &Liveness,
|
||||
mapping: &BTreeMap<usize, (u32, u32)>,
|
||||
func: &mut Function,
|
||||
strings: &StringTable,
|
||||
strings: &intern::InternPool,
|
||||
node: u32,
|
||||
) -> ImmRegMem {
|
||||
let inst = self.nodes[node as usize];
|
||||
|
@ -2696,7 +2716,7 @@ impl Mir {
|
|||
|
||||
pub fn assemble(
|
||||
&self,
|
||||
strings: &StringTable,
|
||||
strings: &intern::InternPool,
|
||||
) -> Result<Function, core::fmt::Error> {
|
||||
use core::fmt::Write;
|
||||
// mapping if (i, (stack_offset, bytes)) for local stack variables
|
||||
|
@ -4217,11 +4237,11 @@ impl Mir {
|
|||
|
||||
pub struct DisplayMir<'a, 'b> {
|
||||
mir: &'a Mir,
|
||||
strings: &'b StringTable,
|
||||
ip: &'b intern::InternPool,
|
||||
}
|
||||
|
||||
impl<'a, 'b> core::fmt::Display for DisplayMir<'a, 'b> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
self.mir.render(f, &self.strings)
|
||||
self.mir.render(f, &self.ip)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue