From d743292710bf0aaea0ca94776b0be70dfadfdf96 Mon Sep 17 00:00:00 2001 From: Janis Date: Mon, 23 Dec 2024 03:08:13 +0100 Subject: [PATCH] compile help script fix issue where mir interpreted intern indices as data for constants --- src/mir.rs | 43 ++++++++++++++---- src/triples.rs | 116 ++----------------------------------------------- test.sh | 4 ++ 3 files changed, 42 insertions(+), 121 deletions(-) create mode 100755 test.sh diff --git a/src/mir.rs b/src/mir.rs index 0d0fc7e..018a6d1 100644 --- a/src/mir.rs +++ b/src/mir.rs @@ -868,7 +868,12 @@ impl Mir { node } - pub fn push_const(&mut self, value: intern::Index, ty: Type) -> u32 { + pub fn push_const( + &mut self, + ip: &intern::InternPool, + value: intern::Index, + ty: Type, + ) -> u32 { let inst = match ty { Type::Byte => Inst::ConstantByte, Type::Word => Inst::ConstantWord, @@ -878,7 +883,15 @@ impl Mir { Type::DoublePrecision => Inst::ConstantDoublePrecision, _ => unreachable!(), }; - let data = Data::index(value); + let data = match ip.get_key(value) { + intern::Key::F32 { bits } => Data::imm32(bits.to_bits()), + intern::Key::F64 { bits } => Data::imm64(bits.to_bits()), + intern::Key::SInt64 { bits } => Data::imm64(bits as u64), + intern::Key::UInt64 { bits } => Data::imm64(bits as u64), + intern::Key::SIntSmall { bits } => Data::imm32(bits as u32), + intern::Key::UIntSmall { bits } => Data::imm32(bits as u32), + _ => unreachable!(), + }; self.push(inst, data) } @@ -2542,8 +2555,14 @@ impl Function { ) { match inst { Inst::ConstantBytes => { - _ = strings; - todo!() + use std::fmt::Write; + let data = strings.get_bytes(data.as_index()); + let mut str = String::new(); + write!(&mut str, ".byte ").unwrap(); + for b in data { + write!(&mut str, "{b:>02x},").unwrap(); + } + self.add_constant(i, str); } Inst::ConstantByte => { self.add_constant(i, format!(".byte {}", data.as_imm8())); @@ -2703,10 +2722,18 @@ impl Mir { } Inst::ExternRef(ty) => { // let ty = ty.unwrap_or(Type::QWord); - ImmRegMem::Rip(RipRelative::Reference(format!( - "{}", - strings.get_str(data.as_index()) - ))) + match ty { + None | Some(Type::Function) => { + ImmRegMem::Rip(RipRelative::Reference(format!( + "{}", + strings.get_str(data.as_index()) + ))) + } + Some(ty) => ImmRegMem::Rip(RipRelative::Label( + ty, + format!("{}", strings.get_str(data.as_index())), + )), + } } _ => { unreachable!() diff --git a/src/triples.rs b/src/triples.rs index 3e7d635..1956bcf 100644 --- a/src/triples.rs +++ b/src/triples.rs @@ -162,12 +162,6 @@ pub enum Inst { /// (name: intern, ty: intern) /// lhs: value node GlobalConstant(intern::Index, intern::Index), - /// u32 - ConstantU32, - /// lo, hi - ConstantU64, - /// index - ConstantMultiByte, /// type, value Constant, /// size, align @@ -235,10 +229,7 @@ pub enum Inst { impl Inst { fn is_constant(self) -> bool { match self { - Inst::ConstantU32 - | Inst::ConstantU64 - | Inst::ConstantMultiByte - | Inst::Constant => true, + Inst::Constant => true, _ => false, } @@ -962,34 +953,6 @@ impl IRBuilder<'_, '_> { self.intern_pool().display_key(val), )?; } - Inst::ConstantU32 => { - writeln_indented!( - indent, - w, - "%{} = const i32 {}", - node, - data.as_u32() - )?; - } - Inst::ConstantU64 => { - writeln_indented!( - indent, - w, - "%{} = const i64 {}", - node, - data.as_u64() - )?; - } - Inst::ConstantMultiByte => { - let value = self.intern_pool().get_bytes(data.as_index()); - writeln_indented!( - indent, - w, - "%{} = const bytes {:x?}", - node, - value - )?; - } Inst::Add(ty) => { let (lhs, rhs) = data.as_lhs_rhs(); writeln_indented!( @@ -1414,43 +1377,7 @@ impl<'a> MirBuilder<'a> { let mir_ty = self .intern_pool() .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); - mir.push_const(val, mir_ty) - } - Inst::ConstantU32 => mir.push( - mir::Inst::ConstantDWord, - mir::Data::imm32(data.unwrap().as_u32()), - ), - Inst::ConstantU64 => mir.push( - mir::Inst::ConstantQWord, - mir::Data::imm64(data.unwrap().as_u64()), - ), - Inst::ConstantMultiByte => { - let bytes = - self.intern_pool().get_bytes(data.unwrap().as_index()); - let mut buf = [0u8; 8]; - match bytes.len() { - 1 => mir.gen_u8(bytes[0]), - 2 => mir.gen_u16(u16::from_le_bytes( - bytes[..2].try_into().unwrap(), - )), - 3..=4 => { - buf[..bytes.len()].copy_from_slice(bytes); - mir.gen_u32(u32::from_le_bytes( - buf[..4].try_into().unwrap(), - )) - } - 5..=8 => { - buf[..bytes.len()].copy_from_slice(bytes); - mir.gen_u64(u64::from_le_bytes( - buf[..8].try_into().unwrap(), - )) - } - _ => { - unimplemented!( - "constants larger than 8 bytes are not currently supported!" - ) - } - } + mir.push_const(self.intern_pool(), val, mir_ty) } Inst::Alloca => { let (l, r) = data.unwrap().as_lhs_rhs(); @@ -2017,44 +1944,7 @@ impl<'a> MirBuilder<'a> { let mir_ty = self .intern_pool() .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); - mir.push_const(val, mir_ty) - } - Inst::ConstantU32 => mir.push( - mir::Inst::ConstantDWord, - mir::Data::imm32(data.unwrap().as_u32()), - ), - Inst::ConstantU64 => mir.push( - mir::Inst::ConstantQWord, - mir::Data::imm64(data.unwrap().as_u64()), - ), - Inst::ConstantMultiByte => { - let bytes = self - .intern_pool() - .get_bytes(data.unwrap().as_index()); - let mut buf = [0u8; 8]; - match bytes.len() { - 1 => mir.gen_u8(bytes[0]), - 2 => mir.gen_u16(u16::from_le_bytes( - bytes[..2].try_into().unwrap(), - )), - 3..=4 => { - buf[..bytes.len()].copy_from_slice(bytes); - mir.gen_u32(u32::from_le_bytes( - buf[..4].try_into().unwrap(), - )) - } - 5..=8 => { - buf[..bytes.len()].copy_from_slice(bytes); - mir.gen_u64(u64::from_le_bytes( - buf[..8].try_into().unwrap(), - )) - } - _ => { - unimplemented!( - "constants larger than 8 bytes are not currently supported!" - ) - } - } + mir.push_const(self.intern_pool(), val, mir_ty) } _ => { unimplemented!() diff --git a/test.sh b/test.sh new file mode 100755 index 0000000..6caf792 --- /dev/null +++ b/test.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +cargo run --bin main -- -i "$1" asm > asm.S +clang asm.S -c && clang asm.o -o asm && ./asm; echo $?