mir function type and using internpool

This commit is contained in:
Janis 2024-12-23 02:33:43 +01:00
parent 3be955aebf
commit 7801fefa17
2 changed files with 57 additions and 35 deletions

View file

@ -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")
}

View file

@ -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, &reg_alloc, node as u32)?;
self.render_node(w, ip, &reg_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)
}
}