mir/triples use internpool now for types
This commit is contained in:
parent
0994f4b187
commit
a3bee90ac3
|
@ -98,10 +98,10 @@ pub enum Key<'a> {
|
||||||
bigint: BigInt,
|
bigint: BigInt,
|
||||||
},
|
},
|
||||||
UIntType {
|
UIntType {
|
||||||
bits: u16,
|
bit_width: u16,
|
||||||
},
|
},
|
||||||
SIntType {
|
SIntType {
|
||||||
bits: u16,
|
bit_width: u16,
|
||||||
},
|
},
|
||||||
SimpleType {
|
SimpleType {
|
||||||
ty: SimpleType,
|
ty: SimpleType,
|
||||||
|
@ -144,8 +144,8 @@ impl Hash for Key<'_> {
|
||||||
Key::F64 { bits } => ordered_float::OrderedFloat(*bits).hash(state),
|
Key::F64 { bits } => ordered_float::OrderedFloat(*bits).hash(state),
|
||||||
Key::PositiveInt { bigint } => bigint.hash(state),
|
Key::PositiveInt { bigint } => bigint.hash(state),
|
||||||
Key::NegativeInt { bigint } => bigint.hash(state),
|
Key::NegativeInt { bigint } => bigint.hash(state),
|
||||||
Key::UIntType { bits } => bits.hash(state),
|
Key::UIntType { bit_width: bits } => bits.hash(state),
|
||||||
Key::SIntType { bits } => bits.hash(state),
|
Key::SIntType { bit_width: bits } => bits.hash(state),
|
||||||
Key::SimpleType { ty } => ty.hash(state),
|
Key::SimpleType { ty } => ty.hash(state),
|
||||||
Key::PointerType { pointee, flags } => (pointee, flags).hash(state),
|
Key::PointerType { pointee, flags } => (pointee, flags).hash(state),
|
||||||
Key::ArrayType {
|
Key::ArrayType {
|
||||||
|
@ -180,6 +180,14 @@ impl PointerFlags {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn union(self, other: Self) -> Self {
|
||||||
|
Self::new(
|
||||||
|
self.is_const || other.is_const,
|
||||||
|
self.volatile || other.volatile,
|
||||||
|
self.noalias || other.noalias,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn pack(self) -> u8 {
|
pub fn pack(self) -> u8 {
|
||||||
(self.volatile as u8) << 0
|
(self.volatile as u8) << 0
|
||||||
| (self.is_const as u8) << 1
|
| (self.is_const as u8) << 1
|
||||||
|
@ -325,43 +333,44 @@ impl std::fmt::Debug for InternPool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const STATIC_KEYS: [Key; 21] = [
|
macro_rules! static_keys {
|
||||||
Key::SimpleType {
|
($($name:ident => $def:expr),* $(,)?) => {
|
||||||
ty: SimpleType::Bool,
|
impl Index {
|
||||||
},
|
$(
|
||||||
Key::SimpleType {
|
pub const $name: Self = Self(${index()});
|
||||||
ty: SimpleType::F32,
|
)*
|
||||||
},
|
}
|
||||||
Key::SimpleType {
|
const STATIC_KEYS: [Key; ${count($def)}] = [
|
||||||
ty: SimpleType::F64,
|
$($def),*
|
||||||
},
|
|
||||||
Key::SimpleType {
|
|
||||||
ty: SimpleType::USize,
|
|
||||||
},
|
|
||||||
Key::SimpleType {
|
|
||||||
ty: SimpleType::ISize,
|
|
||||||
},
|
|
||||||
Key::SimpleType {
|
|
||||||
ty: SimpleType::Void,
|
|
||||||
},
|
|
||||||
Key::SimpleType {
|
|
||||||
ty: SimpleType::ComptimeInt,
|
|
||||||
},
|
|
||||||
Key::SIntType { bits: 1 },
|
|
||||||
Key::UIntType { bits: 1 },
|
|
||||||
Key::SIntType { bits: 0 },
|
|
||||||
Key::UIntType { bits: 0 },
|
|
||||||
Key::SIntType { bits: 8 },
|
|
||||||
Key::UIntType { bits: 8 },
|
|
||||||
Key::SIntType { bits: 16 },
|
|
||||||
Key::UIntType { bits: 16 },
|
|
||||||
Key::SIntType { bits: 32 },
|
|
||||||
Key::UIntType { bits: 32 },
|
|
||||||
Key::SIntType { bits: 64 },
|
|
||||||
Key::UIntType { bits: 64 },
|
|
||||||
Key::TrueValue,
|
|
||||||
Key::FalseValue,
|
|
||||||
];
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static_keys!(
|
||||||
|
BOOL => Key::SimpleType {ty: SimpleType::Bool,},
|
||||||
|
F32 => Key::SimpleType {ty: SimpleType::F32,},
|
||||||
|
F64 => Key::SimpleType {ty: SimpleType::F64,},
|
||||||
|
USIZE => Key::SimpleType {ty: SimpleType::USize,},
|
||||||
|
ISIZE => Key::SimpleType {ty: SimpleType::ISize,},
|
||||||
|
VOID => Key::SimpleType {ty: SimpleType::Void,},
|
||||||
|
COMPTIME_INT => Key::SimpleType {ty: SimpleType::ComptimeInt,},
|
||||||
|
I1 => Key::SIntType { bit_width: 1 },
|
||||||
|
U1 => Key::UIntType { bit_width: 1 },
|
||||||
|
I0 => Key::SIntType { bit_width: 0 },
|
||||||
|
U0 => Key::UIntType { bit_width: 0 },
|
||||||
|
I8 => Key::SIntType { bit_width: 8 },
|
||||||
|
U8 => Key::UIntType { bit_width: 8 },
|
||||||
|
I16 => Key::SIntType { bit_width: 16 },
|
||||||
|
U16 => Key::UIntType { bit_width: 16 },
|
||||||
|
I32 => Key::SIntType { bit_width: 32 },
|
||||||
|
U32 => Key::UIntType { bit_width: 32 },
|
||||||
|
I64 => Key::SIntType { bit_width: 64 },
|
||||||
|
U64 => Key::UIntType { bit_width: 64 },
|
||||||
|
I128 => Key::SIntType { bit_width: 128 },
|
||||||
|
U128 => Key::UIntType { bit_width: 128 },
|
||||||
|
TRUE => Key::TrueValue,
|
||||||
|
FALSE => Key::FalseValue,
|
||||||
|
);
|
||||||
|
|
||||||
impl InternPool {
|
impl InternPool {
|
||||||
pub fn get_void_type(&self) -> Index {
|
pub fn get_void_type(&self) -> Index {
|
||||||
|
@ -406,40 +415,40 @@ impl InternPool {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
pub fn get_u0_type(&self) -> Index {
|
pub fn get_u0_type(&self) -> Index {
|
||||||
self.get_assume_present(&Key::UIntType { bits: 0 })
|
self.get_assume_present(&Key::UIntType { bit_width: 0 })
|
||||||
}
|
}
|
||||||
pub fn get_i0_type(&self) -> Index {
|
pub fn get_i0_type(&self) -> Index {
|
||||||
self.get_assume_present(&Key::SIntType { bits: 0 })
|
self.get_assume_present(&Key::SIntType { bit_width: 0 })
|
||||||
}
|
}
|
||||||
pub fn get_u1_type(&self) -> Index {
|
pub fn get_u1_type(&self) -> Index {
|
||||||
self.get_assume_present(&Key::UIntType { bits: 1 })
|
self.get_assume_present(&Key::UIntType { bit_width: 1 })
|
||||||
}
|
}
|
||||||
pub fn get_i1_type(&self) -> Index {
|
pub fn get_i1_type(&self) -> Index {
|
||||||
self.get_assume_present(&Key::SIntType { bits: 1 })
|
self.get_assume_present(&Key::SIntType { bit_width: 1 })
|
||||||
}
|
}
|
||||||
pub fn get_u8_type(&self) -> Index {
|
pub fn get_u8_type(&self) -> Index {
|
||||||
self.get_assume_present(&Key::UIntType { bits: 8 })
|
self.get_assume_present(&Key::UIntType { bit_width: 8 })
|
||||||
}
|
}
|
||||||
pub fn get_i8_type(&self) -> Index {
|
pub fn get_i8_type(&self) -> Index {
|
||||||
self.get_assume_present(&Key::SIntType { bits: 8 })
|
self.get_assume_present(&Key::SIntType { bit_width: 8 })
|
||||||
}
|
}
|
||||||
pub fn get_u16_type(&self) -> Index {
|
pub fn get_u16_type(&self) -> Index {
|
||||||
self.get_assume_present(&Key::UIntType { bits: 16 })
|
self.get_assume_present(&Key::UIntType { bit_width: 16 })
|
||||||
}
|
}
|
||||||
pub fn get_i16_type(&self) -> Index {
|
pub fn get_i16_type(&self) -> Index {
|
||||||
self.get_assume_present(&Key::SIntType { bits: 16 })
|
self.get_assume_present(&Key::SIntType { bit_width: 16 })
|
||||||
}
|
}
|
||||||
pub fn get_u32_type(&self) -> Index {
|
pub fn get_u32_type(&self) -> Index {
|
||||||
self.get_assume_present(&Key::UIntType { bits: 32 })
|
self.get_assume_present(&Key::UIntType { bit_width: 32 })
|
||||||
}
|
}
|
||||||
pub fn get_i32_type(&self) -> Index {
|
pub fn get_i32_type(&self) -> Index {
|
||||||
self.get_assume_present(&Key::SIntType { bits: 32 })
|
self.get_assume_present(&Key::SIntType { bit_width: 32 })
|
||||||
}
|
}
|
||||||
pub fn get_u64_type(&self) -> Index {
|
pub fn get_u64_type(&self) -> Index {
|
||||||
self.get_assume_present(&Key::UIntType { bits: 64 })
|
self.get_assume_present(&Key::UIntType { bit_width: 64 })
|
||||||
}
|
}
|
||||||
pub fn get_i64_type(&self) -> Index {
|
pub fn get_i64_type(&self) -> Index {
|
||||||
self.get_assume_present(&Key::SIntType { bits: 64 })
|
self.get_assume_present(&Key::SIntType { bit_width: 64 })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -447,41 +456,173 @@ impl InternPool {
|
||||||
pub struct TypeInfo {
|
pub struct TypeInfo {
|
||||||
pub bitsize: u32,
|
pub bitsize: u32,
|
||||||
pub bitalign: u32,
|
pub bitalign: u32,
|
||||||
|
pub signed: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InternPool {
|
impl InternPool {
|
||||||
|
pub fn peer_type(&mut self, lhs: Index, rhs: Index) -> Option<Index> {
|
||||||
|
if lhs == rhs {
|
||||||
|
return Some(rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
let lt = self.get_key(lhs);
|
||||||
|
let rt = self.get_key(rhs);
|
||||||
|
|
||||||
|
match (lt, rt) {
|
||||||
|
(
|
||||||
|
Key::SimpleType {
|
||||||
|
ty: SimpleType::ComptimeInt,
|
||||||
|
},
|
||||||
|
Key::SimpleType {
|
||||||
|
ty: SimpleType::F32,
|
||||||
|
}
|
||||||
|
| Key::SimpleType {
|
||||||
|
ty: SimpleType::F64,
|
||||||
|
}
|
||||||
|
| Key::SimpleType {
|
||||||
|
ty: SimpleType::USize,
|
||||||
|
}
|
||||||
|
| Key::SimpleType {
|
||||||
|
ty: SimpleType::ISize,
|
||||||
|
}
|
||||||
|
| Key::SIntType { .. }
|
||||||
|
| Key::UIntType { .. },
|
||||||
|
) => Some(rhs),
|
||||||
|
(
|
||||||
|
Key::SimpleType {
|
||||||
|
ty: SimpleType::F32,
|
||||||
|
}
|
||||||
|
| Key::SimpleType {
|
||||||
|
ty: SimpleType::F64,
|
||||||
|
}
|
||||||
|
| Key::SimpleType {
|
||||||
|
ty: SimpleType::USize,
|
||||||
|
}
|
||||||
|
| Key::SimpleType {
|
||||||
|
ty: SimpleType::ISize,
|
||||||
|
}
|
||||||
|
| Key::SIntType { .. }
|
||||||
|
| Key::UIntType { .. },
|
||||||
|
Key::SimpleType {
|
||||||
|
ty: SimpleType::ComptimeInt,
|
||||||
|
},
|
||||||
|
) => Some(lhs),
|
||||||
|
(
|
||||||
|
Key::PointerType {
|
||||||
|
pointee: lp,
|
||||||
|
flags: lf,
|
||||||
|
},
|
||||||
|
Key::PointerType {
|
||||||
|
pointee: rp,
|
||||||
|
flags: rf,
|
||||||
|
},
|
||||||
|
) => {
|
||||||
|
if lp == rp {
|
||||||
|
Some(self.get_pointer_type(lp, Some(lf.union(rf))))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_mir_type(
|
||||||
|
&self,
|
||||||
|
index: Index,
|
||||||
|
_ptr_size: TypeInfo,
|
||||||
|
) -> crate::mir::Type {
|
||||||
|
use crate::mir::Type;
|
||||||
|
match self.get_key(index) {
|
||||||
|
Key::UIntType { bit_width: bits } => {
|
||||||
|
let bits = bits as u32;
|
||||||
|
|
||||||
|
Type::from_bitsize_int(bits)
|
||||||
|
}
|
||||||
|
Key::SIntType { bit_width: bits } => {
|
||||||
|
let bits = bits as u32;
|
||||||
|
Type::from_bitsize_int(bits)
|
||||||
|
}
|
||||||
|
Key::SimpleType { ty } => match ty {
|
||||||
|
SimpleType::F32 => Type::SinglePrecision,
|
||||||
|
SimpleType::F64 => Type::DoublePrecision,
|
||||||
|
SimpleType::Bool => Type::Byte,
|
||||||
|
SimpleType::Void => {
|
||||||
|
todo!("void can't be turned into a mir type")
|
||||||
|
}
|
||||||
|
SimpleType::ISize | SimpleType::USize => Type::QWord,
|
||||||
|
SimpleType::ComptimeInt => {
|
||||||
|
panic!("comptime int can't be turned into a mir type")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Key::ArrayType { .. } => {
|
||||||
|
panic!("arrays can't be directly accessed in mir")
|
||||||
|
}
|
||||||
|
Key::FunctionType { .. } | Key::PointerType { .. } => Type::QWord,
|
||||||
|
Key::StructType { .. } => {
|
||||||
|
panic!("arrays can't be directly accessed in mir")
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
panic!("index was not a type")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_type_signed(&self, index: Index, _ptr_size: TypeInfo) -> bool {
|
||||||
|
match self.get_key(index) {
|
||||||
|
Key::UIntType { .. } => false,
|
||||||
|
Key::SIntType { .. } => true,
|
||||||
|
Key::SimpleType { ty } => match ty {
|
||||||
|
SimpleType::USize => false,
|
||||||
|
SimpleType::ISize => true,
|
||||||
|
_ => false,
|
||||||
|
},
|
||||||
|
Key::PointerType { .. } => false,
|
||||||
|
Key::ArrayType { .. } => false,
|
||||||
|
Key::FunctionType { .. } => false,
|
||||||
|
Key::StructType { .. } => false,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn size_of_type(&self, index: Index, ptr_size: TypeInfo) -> TypeInfo {
|
pub fn size_of_type(&self, index: Index, ptr_size: TypeInfo) -> TypeInfo {
|
||||||
match self.get_key(index) {
|
match self.get_key(index) {
|
||||||
Key::UIntType { bits } => {
|
Key::UIntType { bit_width: bits } => {
|
||||||
let bits = bits as u32;
|
let bits = bits as u32;
|
||||||
TypeInfo {
|
TypeInfo {
|
||||||
bitsize: bits,
|
bitsize: bits,
|
||||||
bitalign: bits.next_multiple_of(8).next_power_of_two(),
|
bitalign: bits.next_multiple_of(8).next_power_of_two(),
|
||||||
|
signed: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Key::SIntType { bits } => {
|
Key::SIntType { bit_width: bits } => {
|
||||||
let bits = bits as u32;
|
let bits = bits as u32;
|
||||||
TypeInfo {
|
TypeInfo {
|
||||||
bitsize: bits,
|
bitsize: bits,
|
||||||
bitalign: bits.next_multiple_of(8).next_power_of_two(),
|
bitalign: bits.next_multiple_of(8).next_power_of_two(),
|
||||||
|
signed: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Key::SimpleType { ty } => match ty {
|
Key::SimpleType { ty } => match ty {
|
||||||
SimpleType::F32 => TypeInfo {
|
SimpleType::F32 => TypeInfo {
|
||||||
bitsize: 32,
|
bitsize: 32,
|
||||||
bitalign: 32,
|
bitalign: 32,
|
||||||
|
signed: true,
|
||||||
},
|
},
|
||||||
SimpleType::F64 => TypeInfo {
|
SimpleType::F64 => TypeInfo {
|
||||||
bitsize: 64,
|
bitsize: 64,
|
||||||
bitalign: 64,
|
bitalign: 64,
|
||||||
|
signed: true,
|
||||||
},
|
},
|
||||||
SimpleType::Bool => TypeInfo {
|
SimpleType::Bool => TypeInfo {
|
||||||
bitsize: 1,
|
bitsize: 1,
|
||||||
bitalign: 1,
|
bitalign: 1,
|
||||||
|
signed: false,
|
||||||
},
|
},
|
||||||
SimpleType::Void => TypeInfo {
|
SimpleType::Void => TypeInfo {
|
||||||
bitsize: 0,
|
bitsize: 0,
|
||||||
bitalign: 0,
|
bitalign: 0,
|
||||||
|
signed: false,
|
||||||
},
|
},
|
||||||
SimpleType::USize => ptr_size,
|
SimpleType::USize => ptr_size,
|
||||||
SimpleType::ISize => ptr_size,
|
SimpleType::ISize => ptr_size,
|
||||||
|
@ -495,6 +636,7 @@ impl InternPool {
|
||||||
let bitsize = element_size.bitalign * length;
|
let bitsize = element_size.bitalign * length;
|
||||||
TypeInfo {
|
TypeInfo {
|
||||||
bitsize,
|
bitsize,
|
||||||
|
signed: false,
|
||||||
..element_size
|
..element_size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -518,6 +660,7 @@ impl InternPool {
|
||||||
TypeInfo {
|
TypeInfo {
|
||||||
bitsize: size,
|
bitsize: size,
|
||||||
bitalign: align,
|
bitalign: align,
|
||||||
|
signed: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -527,7 +670,7 @@ impl InternPool {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_ast1_type(
|
pub fn from_ast1_type(
|
||||||
&self,
|
&mut self,
|
||||||
pointer_bits: u16,
|
pointer_bits: u16,
|
||||||
ty: &crate::ast::Type,
|
ty: &crate::ast::Type,
|
||||||
) -> Index {
|
) -> Index {
|
||||||
|
@ -536,9 +679,9 @@ impl InternPool {
|
||||||
crate::ast::Type::ComptimeNumber => self.get_comptime_int_type(),
|
crate::ast::Type::ComptimeNumber => self.get_comptime_int_type(),
|
||||||
crate::ast::Type::Integer(i) => self.get_assume_present(&{
|
crate::ast::Type::Integer(i) => self.get_assume_present(&{
|
||||||
if i.signed {
|
if i.signed {
|
||||||
Key::SIntType { bits: i.bits }
|
Key::SIntType { bit_width: i.bits }
|
||||||
} else {
|
} else {
|
||||||
Key::UIntType { bits: i.bits }
|
Key::UIntType { bit_width: i.bits }
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
crate::ast::Type::Floating(crate::ast::FloatingType::Binary32) => {
|
crate::ast::Type::Floating(crate::ast::FloatingType::Binary32) => {
|
||||||
|
@ -547,14 +690,26 @@ impl InternPool {
|
||||||
crate::ast::Type::Floating(crate::ast::FloatingType::Binary64) => {
|
crate::ast::Type::Floating(crate::ast::FloatingType::Binary64) => {
|
||||||
self.get_f64_type()
|
self.get_f64_type()
|
||||||
}
|
}
|
||||||
crate::ast::Type::Pointer { constness, pointee } => self
|
crate::ast::Type::Pointer { constness, pointee } => {
|
||||||
.get_assume_present(&Key::PointerType {
|
let pointee = self.from_ast1_type(pointer_bits, &pointee);
|
||||||
pointee: self.from_ast1_type(pointer_bits, &pointee),
|
self.get_or_insert(Key::PointerType {
|
||||||
|
pointee,
|
||||||
flags: PointerFlags::new(*constness, false, false),
|
flags: PointerFlags::new(*constness, false, false),
|
||||||
}),
|
})
|
||||||
crate::ast::Type::Fn { .. } => {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
}
|
||||||
|
crate::ast::Type::Fn {
|
||||||
|
parameter_types,
|
||||||
|
return_type,
|
||||||
|
} => {
|
||||||
|
let parameters = parameter_types
|
||||||
|
.iter()
|
||||||
|
.map(|ty| self.from_ast1_type(pointer_bits, ty))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
let return_type =
|
||||||
|
self.from_ast1_type(pointer_bits, &return_type);
|
||||||
|
self.get_function_type(return_type, parameters)
|
||||||
|
}
|
||||||
|
crate::ast::Type::Void => self.get_void_type(),
|
||||||
_ => {
|
_ => {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
@ -568,10 +723,10 @@ impl InternPool {
|
||||||
) -> crate::ast::Type {
|
) -> crate::ast::Type {
|
||||||
use crate::ast::Type;
|
use crate::ast::Type;
|
||||||
match self.get_key(index) {
|
match self.get_key(index) {
|
||||||
Key::UIntType { bits } => {
|
Key::UIntType { bit_width: bits } => {
|
||||||
Type::Integer(IntegralType::new(false, bits))
|
Type::Integer(IntegralType::new(false, bits))
|
||||||
}
|
}
|
||||||
Key::SIntType { bits } => {
|
Key::SIntType { bit_width: bits } => {
|
||||||
Type::Integer(IntegralType::new(true, bits))
|
Type::Integer(IntegralType::new(true, bits))
|
||||||
}
|
}
|
||||||
Key::SimpleType { ty } => match ty {
|
Key::SimpleType { ty } => match ty {
|
||||||
|
@ -613,9 +768,14 @@ impl InternPool {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const AMD64_POINTER_BITS: u16 = 64;
|
pub const AMD64_POINTER_BITS: u16 = 64;
|
||||||
|
pub const AMD64_POINTER_TYPE_INFO: TypeInfo = TypeInfo {
|
||||||
|
bitsize: 64,
|
||||||
|
bitalign: 64,
|
||||||
|
signed: false,
|
||||||
|
};
|
||||||
|
|
||||||
impl InternPool {
|
impl InternPool {
|
||||||
pub fn create() -> Self {
|
pub fn new() -> Self {
|
||||||
let mut this = Self {
|
let mut this = Self {
|
||||||
tags: Vec::new(),
|
tags: Vec::new(),
|
||||||
indices: Vec::new(),
|
indices: Vec::new(),
|
||||||
|
@ -701,10 +861,10 @@ impl InternPool {
|
||||||
self.create_item(Tag::NegativeInt, i)
|
self.create_item(Tag::NegativeInt, i)
|
||||||
}
|
}
|
||||||
|
|
||||||
Key::UIntType { bits } => {
|
Key::UIntType { bit_width: bits } => {
|
||||||
self.create_item(Tag::UIntType, bits as u32)
|
self.create_item(Tag::UIntType, bits as u32)
|
||||||
}
|
}
|
||||||
Key::SIntType { bits } => {
|
Key::SIntType { bit_width: bits } => {
|
||||||
self.create_item(Tag::SIntType, bits as u32)
|
self.create_item(Tag::SIntType, bits as u32)
|
||||||
}
|
}
|
||||||
Key::SimpleType { ty } => {
|
Key::SimpleType { ty } => {
|
||||||
|
@ -855,10 +1015,10 @@ impl InternPool {
|
||||||
Key::PositiveInt { bigint }
|
Key::PositiveInt { bigint }
|
||||||
}
|
}
|
||||||
Tag::SIntType => Key::SIntType {
|
Tag::SIntType => Key::SIntType {
|
||||||
bits: item.index as u16,
|
bit_width: item.index as u16,
|
||||||
},
|
},
|
||||||
Tag::UIntType => Key::UIntType {
|
Tag::UIntType => Key::UIntType {
|
||||||
bits: item.index as u16,
|
bit_width: item.index as u16,
|
||||||
},
|
},
|
||||||
Tag::SimpleType => {
|
Tag::SimpleType => {
|
||||||
let ty = item.idx() as u8;
|
let ty = item.idx() as u8;
|
||||||
|
@ -964,8 +1124,8 @@ impl InternPool {
|
||||||
|
|
||||||
pub fn get_int_type(&mut self, signed: bool, bits: u16) -> Index {
|
pub fn get_int_type(&mut self, signed: bool, bits: u16) -> Index {
|
||||||
let key = match signed {
|
let key = match signed {
|
||||||
true => Key::SIntType { bits },
|
true => Key::SIntType { bit_width: bits },
|
||||||
false => Key::UIntType { bits },
|
false => Key::UIntType { bit_width: bits },
|
||||||
};
|
};
|
||||||
|
|
||||||
self.get_or_insert(key)
|
self.get_or_insert(key)
|
||||||
|
|
|
@ -1909,7 +1909,8 @@ fn interned_type_and_value_to_comptime_number(
|
||||||
|
|
||||||
let ty_key = ip.get_key(ty);
|
let ty_key = ip.get_key(ty);
|
||||||
match ty_key {
|
match ty_key {
|
||||||
intern::Key::SIntType { bits } | intern::Key::UIntType { bits } => {
|
intern::Key::SIntType { bit_width: bits }
|
||||||
|
| intern::Key::UIntType { bit_width: bits } => {
|
||||||
let ty = IntegralType::new(false, bits);
|
let ty = IntegralType::new(false, bits);
|
||||||
match ip.get_key(val) {
|
match ip.get_key(val) {
|
||||||
intern::Key::SIntSmall { bits } => {
|
intern::Key::SIntSmall { bits } => {
|
||||||
|
@ -2191,7 +2192,7 @@ pub mod ast_gen {
|
||||||
pub fn new() -> Parser {
|
pub fn new() -> Parser {
|
||||||
Self {
|
Self {
|
||||||
ast: Ast::new(),
|
ast: Ast::new(),
|
||||||
intern: intern::InternPool::create(),
|
intern: intern::InternPool::new(),
|
||||||
syms: crate::symbol_table::syms2::Symbols::new(),
|
syms: crate::symbol_table::syms2::Symbols::new(),
|
||||||
scopes: Vec::new(),
|
scopes: Vec::new(),
|
||||||
errors: Vec::new(),
|
errors: Vec::new(),
|
||||||
|
@ -4252,12 +4253,12 @@ pub mod ir_gen {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{symbol_table::syms2::Symbols, triples::*};
|
use crate::{symbol_table::syms2::Symbols, triples::*};
|
||||||
|
|
||||||
struct IRGen {
|
struct IRGen<'a> {
|
||||||
ast: Ast,
|
ast: Ast,
|
||||||
syms: Symbols,
|
syms: Symbols,
|
||||||
intern: InternPool,
|
intern: InternPool,
|
||||||
ir: IR,
|
ir: IR<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IRGen {}
|
impl IRGen<'_> {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
use std::{io::Read, path::PathBuf};
|
use std::{io::Read, path::PathBuf, sync::Arc};
|
||||||
|
|
||||||
use clap::Command;
|
use clap::Command;
|
||||||
use compiler::{
|
use compiler::{
|
||||||
|
ast2::intern::InternPool,
|
||||||
lexer::Tokenizer,
|
lexer::Tokenizer,
|
||||||
parser::Tree,
|
parser::Tree,
|
||||||
triples::{MirBuilder, IR},
|
triples::{MirBuilder, IR},
|
||||||
|
@ -62,7 +63,8 @@ fn main() {
|
||||||
}
|
}
|
||||||
"ir" => {
|
"ir" => {
|
||||||
let mut tree = ast_tree(&tokens);
|
let mut tree = ast_tree(&tokens);
|
||||||
let mut ir = IR::new();
|
let mut intern = InternPool::new();
|
||||||
|
let mut ir = IR::new(&mut intern);
|
||||||
let builder = ir.build(&mut tree);
|
let builder = ir.build(&mut tree);
|
||||||
let mut buf = String::new();
|
let mut buf = String::new();
|
||||||
builder.render(&mut buf).unwrap();
|
builder.render(&mut buf).unwrap();
|
||||||
|
@ -70,7 +72,8 @@ fn main() {
|
||||||
}
|
}
|
||||||
"mir" => {
|
"mir" => {
|
||||||
let mut tree = ast_tree(&tokens);
|
let mut tree = ast_tree(&tokens);
|
||||||
let mut ir = IR::new();
|
let mut intern = InternPool::new();
|
||||||
|
let mut ir = IR::new(&mut intern);
|
||||||
ir.build(&mut tree);
|
ir.build(&mut tree);
|
||||||
|
|
||||||
let mut mir = MirBuilder::new(&ir, tree.strings);
|
let mut mir = MirBuilder::new(&ir, tree.strings);
|
||||||
|
@ -90,8 +93,9 @@ fn main() {
|
||||||
}
|
}
|
||||||
"asm" => {
|
"asm" => {
|
||||||
let mut tree = ast_tree(&tokens);
|
let mut tree = ast_tree(&tokens);
|
||||||
let mut ir = IR::new();
|
let mut intern = InternPool::new();
|
||||||
ir.build(&mut tree);
|
let mut ir = IR::new(&mut intern);
|
||||||
|
_ = ir.build(&mut tree);
|
||||||
|
|
||||||
let mut mir = MirBuilder::new(&ir, tree.strings);
|
let mut mir = MirBuilder::new(&ir, tree.strings);
|
||||||
mir.build();
|
mir.build();
|
||||||
|
|
|
@ -9,7 +9,8 @@
|
||||||
iter_array_chunks,
|
iter_array_chunks,
|
||||||
int_roundings,
|
int_roundings,
|
||||||
if_let_guard,
|
if_let_guard,
|
||||||
debug_closure_helpers
|
debug_closure_helpers,
|
||||||
|
macro_metavar_expr
|
||||||
)]
|
)]
|
||||||
#![allow(unused_macros)]
|
#![allow(unused_macros)]
|
||||||
|
|
||||||
|
|
17
src/mir.rs
17
src/mir.rs
|
@ -12,6 +12,7 @@ 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::string_table::{Index as StringsIndex, StringTable};
|
use crate::string_table::{Index as StringsIndex, StringTable};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
|
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
|
||||||
|
@ -1107,18 +1108,22 @@ impl Mir {
|
||||||
pub fn gen_extend_integer(
|
pub fn gen_extend_integer(
|
||||||
&mut self,
|
&mut self,
|
||||||
src: u32,
|
src: u32,
|
||||||
from: IntegralType,
|
from: intern::TypeInfo,
|
||||||
to: IntegralType,
|
to: intern::TypeInfo,
|
||||||
) -> u32 {
|
) -> u32 {
|
||||||
// example: u4 -> (byte, false, 4)
|
// example: u4 -> (byte, false, 4)
|
||||||
// 1111_1111 << 4 = 1111_0000
|
// 1111_1111 << 4 = 1111_0000
|
||||||
// mask = 0000_1111;
|
// mask = 0000_1111;
|
||||||
// shift = 8 - 4;
|
// shift = 8 - 4;
|
||||||
let src_ty = Type::from_bitsize_int(from.bits as u32);
|
let src_ty = Type::from_bitsize_int(from.bitsize);
|
||||||
let truncated =
|
let truncated = self.gen_truncate_integer(
|
||||||
self.gen_truncate_integer(src, src_ty, from.signed, from.bits);
|
src,
|
||||||
|
src_ty,
|
||||||
|
from.signed,
|
||||||
|
from.bitsize as u16,
|
||||||
|
);
|
||||||
|
|
||||||
let dst_ty = Type::from_bitsize_int(to.bits as u32);
|
let dst_ty = Type::from_bitsize_int(to.bitsize);
|
||||||
if to.signed {
|
if to.signed {
|
||||||
self.gen_sign_extend(dst_ty, truncated)
|
self.gen_sign_extend(dst_ty, truncated)
|
||||||
} else {
|
} else {
|
||||||
|
|
619
src/triples.rs
619
src/triples.rs
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue