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