From 7801fefa177da5431c9fad61bc31cf809625f3c7 Mon Sep 17 00:00:00 2001 From: Janis Date: Mon, 23 Dec 2024 02:33:43 +0100 Subject: [PATCH] mir function type and using internpool --- src/ast2/intern.rs | 4 ++- src/mir.rs | 88 ++++++++++++++++++++++++++++------------------ 2 files changed, 57 insertions(+), 35 deletions(-) diff --git a/src/ast2/intern.rs b/src/ast2/intern.rs index a59aee5..884e445 100644 --- a/src/ast2/intern.rs +++ b/src/ast2/intern.rs @@ -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") } diff --git a/src/mir.rs b/src/mir.rs index 35df816..0d0fc7e 100644 --- a/src/mir.rs +++ b/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, pub data: Vec, } @@ -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, name: StringsIndex) -> u32 { + pub fn gen_extern(&mut self, ty: Option, 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( &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( &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, branches: BTreeMap, 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 { 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 { 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( 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, 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 { 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) } }