TOO MUCH!!!! InternPool use everywhere in old ast
This commit is contained in:
parent
7801fefa17
commit
7c01afbf2f
14
src/ast.rs
14
src/ast.rs
|
@ -1,6 +1,9 @@
|
||||||
use std::num::NonZero;
|
use std::num::NonZero;
|
||||||
|
|
||||||
use crate::string_table::{self, ImmOrIndex};
|
use crate::{
|
||||||
|
ast2::intern,
|
||||||
|
string_table::{self, ImmOrIndex},
|
||||||
|
};
|
||||||
|
|
||||||
pub type Node = NonZero<u32>;
|
pub type Node = NonZero<u32>;
|
||||||
|
|
||||||
|
@ -33,8 +36,8 @@ pub enum Tag {
|
||||||
PointerQualifier {
|
PointerQualifier {
|
||||||
constness: bool,
|
constness: bool,
|
||||||
},
|
},
|
||||||
IntegralType(IntegralType),
|
IntegralType(intern::Index),
|
||||||
PrimitiveType(PrimitiveType),
|
PrimitiveType(intern::Index),
|
||||||
FunctionDecl {
|
FunctionDecl {
|
||||||
/// FunctionProto
|
/// FunctionProto
|
||||||
proto: Node,
|
proto: Node,
|
||||||
|
@ -42,10 +45,11 @@ pub enum Tag {
|
||||||
body: Node,
|
body: Node,
|
||||||
},
|
},
|
||||||
Ident {
|
Ident {
|
||||||
name: string_table::Index,
|
name: intern::Index,
|
||||||
},
|
},
|
||||||
|
/// bytes might be an integer, float, double, or Bytes
|
||||||
Constant {
|
Constant {
|
||||||
bytes: ImmOrIndex,
|
bytes: intern::Index,
|
||||||
ty: Type,
|
ty: Type,
|
||||||
},
|
},
|
||||||
Block {
|
Block {
|
||||||
|
|
|
@ -6,7 +6,7 @@ use std::{
|
||||||
num::NonZero,
|
num::NonZero,
|
||||||
};
|
};
|
||||||
|
|
||||||
use intern::{InternPool, PointerFlags, StructFlags};
|
use intern::{InternPool, PointerFlags, StructFlags, AMD64_POINTER_TYPE_INFO};
|
||||||
use num_bigint::BigInt;
|
use num_bigint::BigInt;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -66,7 +66,7 @@ enum Tag {
|
||||||
TypeDeclRef,
|
TypeDeclRef,
|
||||||
/// `data` is an inlined key into the symbol table (scope: index, name: intern)
|
/// `data` is an inlined key into the symbol table (scope: index, name: intern)
|
||||||
TypeDeclRefUnresolved,
|
TypeDeclRefUnresolved,
|
||||||
/// `data` is an index to a Type and u32 PointerFlags
|
/// `data` is an index to a Type and u32 PointerFlags (extra offset)
|
||||||
PointerType,
|
PointerType,
|
||||||
/// `data` is an index to a length expression, and an underlying pointer type
|
/// `data` is an index to a length expression, and an underlying pointer type
|
||||||
ArrayType,
|
ArrayType,
|
||||||
|
@ -263,6 +263,7 @@ union Data {
|
||||||
two_interns: (intern::Index, intern::Index),
|
two_interns: (intern::Index, intern::Index),
|
||||||
intern_and_extra_offset: (intern::Index, u32),
|
intern_and_extra_offset: (intern::Index, u32),
|
||||||
index_and_extra_offset: (Index, u32),
|
index_and_extra_offset: (Index, u32),
|
||||||
|
index_and_opaque: (Index, u32),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -279,6 +280,7 @@ enum ExpandedData {
|
||||||
TwoInterns(intern::Index, intern::Index),
|
TwoInterns(intern::Index, intern::Index),
|
||||||
InternAndExtraOffset(intern::Index, usize),
|
InternAndExtraOffset(intern::Index, usize),
|
||||||
IndexAndExtraOffset(Index, usize),
|
IndexAndExtraOffset(Index, usize),
|
||||||
|
IndexAndOpaque(Index, u32),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExpandedData {
|
impl ExpandedData {
|
||||||
|
@ -324,6 +326,10 @@ impl ExpandedData {
|
||||||
let data = data.as_index_and_extra_offset();
|
let data = data.as_index_and_extra_offset();
|
||||||
Self::IndexAndExtraOffset(data.0, data.1)
|
Self::IndexAndExtraOffset(data.0, data.1)
|
||||||
}
|
}
|
||||||
|
fn from_index_and_opaque(data: Data) -> Self {
|
||||||
|
let data = data.as_index_and_opaque();
|
||||||
|
Self::IndexAndExtraOffset(data.0, data.1)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<(Tag, Data)> for ExpandedData {
|
impl From<(Tag, Data)> for ExpandedData {
|
||||||
|
@ -428,6 +434,10 @@ impl Data {
|
||||||
let (i, e) = unsafe { self.intern_and_extra_offset };
|
let (i, e) = unsafe { self.intern_and_extra_offset };
|
||||||
(i, e as usize)
|
(i, e as usize)
|
||||||
}
|
}
|
||||||
|
fn as_index_and_opaque(self) -> (Index, usize) {
|
||||||
|
let (i, e) = unsafe { self.index_and_opaque };
|
||||||
|
(i, e as usize)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Data {
|
impl Data {
|
||||||
|
@ -476,6 +486,11 @@ impl Data {
|
||||||
index_and_extra_offset: (index, offset),
|
index_and_extra_offset: (index, offset),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn index_and_opaque(index: Index, value: u32) -> Self {
|
||||||
|
Self {
|
||||||
|
index_and_opaque: (index, value),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Ast {
|
pub struct Ast {
|
||||||
|
@ -1822,7 +1837,7 @@ impl Ast {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn comptime_number_to_interned_type_and_value(
|
pub fn comptime_number_to_interned_type_and_value(
|
||||||
ip: &mut InternPool,
|
ip: &mut InternPool,
|
||||||
pointer_bits: u16,
|
pointer_bits: u16,
|
||||||
comptime: ComptimeNumber,
|
comptime: ComptimeNumber,
|
||||||
|
@ -1898,7 +1913,7 @@ fn comptime_number_to_interned_type_and_value(
|
||||||
(value, ty)
|
(value, ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn interned_type_and_value_to_comptime_number(
|
pub fn interned_type_and_value_to_comptime_number(
|
||||||
ip: &InternPool,
|
ip: &InternPool,
|
||||||
pointer_bits: u16,
|
pointer_bits: u16,
|
||||||
ty: intern::Index,
|
ty: intern::Index,
|
||||||
|
@ -1908,10 +1923,11 @@ fn interned_type_and_value_to_comptime_number(
|
||||||
use crate::comptime::*;
|
use crate::comptime::*;
|
||||||
|
|
||||||
let ty_key = ip.get_key(ty);
|
let ty_key = ip.get_key(ty);
|
||||||
|
let signed = ip.is_type_signed(ty, AMD64_POINTER_TYPE_INFO);
|
||||||
match ty_key {
|
match ty_key {
|
||||||
intern::Key::SIntType { bit_width: bits }
|
intern::Key::SIntType { bit_width: bits }
|
||||||
| intern::Key::UIntType { bit_width: bits } => {
|
| intern::Key::UIntType { bit_width: bits } => {
|
||||||
let ty = IntegralType::new(false, bits);
|
let ty = IntegralType::new(signed, bits);
|
||||||
match ip.get_key(val) {
|
match ip.get_key(val) {
|
||||||
intern::Key::SIntSmall { bits } => {
|
intern::Key::SIntSmall { bits } => {
|
||||||
ComptimeNumber::Integral(ComptimeInt::Native {
|
ComptimeNumber::Integral(ComptimeInt::Native {
|
||||||
|
@ -2467,7 +2483,7 @@ pub mod ast_gen {
|
||||||
});
|
});
|
||||||
let names = self.ast.extra[names]
|
let names = self.ast.extra[names]
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&i| intern::Index(i));
|
.map(|&i| intern::Index::from_u32(i));
|
||||||
|
|
||||||
self.intern.insert_or_replace_struct_type(
|
self.intern.insert_or_replace_struct_type(
|
||||||
name,
|
name,
|
||||||
|
@ -4248,17 +4264,16 @@ pub mod ast_gen {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod ir_gen {
|
pub mod ir_gen {
|
||||||
use intern::InternPool;
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{symbol_table::syms2::Symbols, triples::*};
|
use crate::{symbol_table::syms2::Symbols, triples::*};
|
||||||
|
|
||||||
struct IRGen<'a> {
|
struct IRGen {
|
||||||
ast: Ast,
|
ast: Ast,
|
||||||
syms: Symbols,
|
syms: Symbols,
|
||||||
intern: InternPool,
|
ir: IR,
|
||||||
ir: IR<'a>,
|
ip: intern::InternPool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IRGen<'_> {}
|
impl IRGen {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ fn ast_tree(tokens: &Tokenizer) -> Tree {
|
||||||
let mut tree = Tree::new();
|
let mut tree = Tree::new();
|
||||||
tree.parse(tokens.iter()).unwrap();
|
tree.parse(tokens.iter()).unwrap();
|
||||||
tree.fold_comptime();
|
tree.fold_comptime();
|
||||||
|
tree.intern_types();
|
||||||
|
|
||||||
tree
|
tree
|
||||||
}
|
}
|
||||||
|
@ -63,8 +64,7 @@ fn main() {
|
||||||
}
|
}
|
||||||
"ir" => {
|
"ir" => {
|
||||||
let mut tree = ast_tree(&tokens);
|
let mut tree = ast_tree(&tokens);
|
||||||
let mut intern = InternPool::new();
|
let mut ir = IR::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();
|
||||||
|
@ -72,15 +72,16 @@ fn main() {
|
||||||
}
|
}
|
||||||
"mir" => {
|
"mir" => {
|
||||||
let mut tree = ast_tree(&tokens);
|
let mut tree = ast_tree(&tokens);
|
||||||
let mut intern = InternPool::new();
|
let mut ir = IR::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.intern_pool);
|
||||||
mir.build();
|
mir.build();
|
||||||
|
|
||||||
let MirBuilder {
|
let MirBuilder {
|
||||||
strings, functions, ..
|
intern_pool: strings,
|
||||||
|
functions,
|
||||||
|
..
|
||||||
} = mir;
|
} = mir;
|
||||||
|
|
||||||
for (name, mir) in functions {
|
for (name, mir) in functions {
|
||||||
|
@ -93,16 +94,15 @@ fn main() {
|
||||||
}
|
}
|
||||||
"asm" => {
|
"asm" => {
|
||||||
let mut tree = ast_tree(&tokens);
|
let mut tree = ast_tree(&tokens);
|
||||||
let mut intern = InternPool::new();
|
let mut ir = IR::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.intern_pool);
|
||||||
mir.build();
|
mir.build();
|
||||||
|
|
||||||
let MirBuilder {
|
let MirBuilder {
|
||||||
globals,
|
globals,
|
||||||
strings,
|
intern_pool: strings,
|
||||||
functions,
|
functions,
|
||||||
..
|
..
|
||||||
} = mir;
|
} = mir;
|
||||||
|
|
232
src/parser.rs
232
src/parser.rs
|
@ -1,5 +1,3 @@
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use num_bigint::{BigInt, BigUint};
|
use num_bigint::{BigInt, BigUint};
|
||||||
|
|
||||||
|
@ -8,13 +6,14 @@ use crate::{
|
||||||
self, FloatingType, IntegralType, LetOrVar, Node, PrimitiveType, Tag,
|
self, FloatingType, IntegralType, LetOrVar, Node, PrimitiveType, Tag,
|
||||||
Type,
|
Type,
|
||||||
},
|
},
|
||||||
|
ast2::intern::{self, AMD64_POINTER_BITS},
|
||||||
common::NextIf,
|
common::NextIf,
|
||||||
comptime::{self, ComptimeNumber},
|
comptime::{self, ComptimeNumber},
|
||||||
error::{AnalysisError, AnalysisErrorTag},
|
error::{AnalysisError, AnalysisErrorTag},
|
||||||
lexer::{Radix, TokenIterator},
|
lexer::{Radix, TokenIterator},
|
||||||
string_table::{ImmOrIndex, Index, StringTable},
|
|
||||||
symbol_table::{SymbolKind, SymbolTable},
|
symbol_table::{SymbolKind, SymbolTable},
|
||||||
tokens::{Token, PRECEDENCE_MAP},
|
tokens::{Token, PRECEDENCE_MAP},
|
||||||
|
BitSize,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
|
@ -98,7 +97,7 @@ impl Nodes {
|
||||||
pub struct Tree {
|
pub struct Tree {
|
||||||
pub nodes: Nodes,
|
pub nodes: Nodes,
|
||||||
pub st: SymbolTable,
|
pub st: SymbolTable,
|
||||||
pub strings: StringTable,
|
pub intern_pool: intern::InternPool,
|
||||||
pub global_decls: Vec<Node>,
|
pub global_decls: Vec<Node>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,7 +136,7 @@ impl Tree {
|
||||||
Self {
|
Self {
|
||||||
nodes: Nodes::new(),
|
nodes: Nodes::new(),
|
||||||
st: SymbolTable::new(),
|
st: SymbolTable::new(),
|
||||||
strings: StringTable::new(),
|
intern_pool: intern::InternPool::new(),
|
||||||
global_decls: Vec::new(),
|
global_decls: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -318,14 +317,14 @@ impl Tree {
|
||||||
|
|
||||||
fn parse_ident(&mut self, tokens: &mut TokenIterator) -> Result<Node> {
|
fn parse_ident(&mut self, tokens: &mut TokenIterator) -> Result<Node> {
|
||||||
let ident = tokens.expect_token(Token::Ident)?;
|
let ident = tokens.expect_token(Token::Ident)?;
|
||||||
let name = self.strings.insert(ident.lexeme().as_bytes());
|
let name = self.intern_pool.insert_string(ident.lexeme());
|
||||||
Ok(self.nodes.push_tag(Tag::Ident { name }))
|
Ok(self.nodes.push_tag(Tag::Ident { name }))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ident_index(&self, node: Node) -> Index {
|
fn ident_index(&self, node: Node) -> intern::Index {
|
||||||
match &self.nodes[node] {
|
match &self.nodes[node] {
|
||||||
Tag::Ident { name } => *name,
|
Tag::Ident { name } => *name,
|
||||||
_ => Index::new(0, 0),
|
_ => intern::Index::EMPTY_STRING,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -335,10 +334,10 @@ impl Tree {
|
||||||
) -> Result<Node> {
|
) -> Result<Node> {
|
||||||
let token = tokens.next().ok_or(Error::UnexpectedEndOfTokens)?;
|
let token = tokens.next().ok_or(Error::UnexpectedEndOfTokens)?;
|
||||||
let prim = match token.token() {
|
let prim = match token.token() {
|
||||||
Token::Void => PrimitiveType::Void,
|
Token::Void => intern::Index::VOID,
|
||||||
Token::Bool => PrimitiveType::Bool,
|
Token::Bool => intern::Index::BOOL,
|
||||||
Token::F32 => PrimitiveType::FloatingType(FloatingType::Binary32),
|
Token::F32 => intern::Index::F32,
|
||||||
Token::F64 => PrimitiveType::FloatingType(FloatingType::Binary64),
|
Token::F64 => intern::Index::F64,
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Error::ExpectedPrimitiveType);
|
return Err(Error::ExpectedPrimitiveType);
|
||||||
}
|
}
|
||||||
|
@ -368,11 +367,14 @@ impl Tree {
|
||||||
let token = tokens.next().unwrap();
|
let token = tokens.next().unwrap();
|
||||||
match Self::try_parse_integral_type(token.lexeme())? {
|
match Self::try_parse_integral_type(token.lexeme())? {
|
||||||
Some(int) => {
|
Some(int) => {
|
||||||
Ok(self.nodes.push_tag(Tag::IntegralType(int)))
|
let ty =
|
||||||
|
self.intern_pool.get_int_type(int.signed, int.bits);
|
||||||
|
|
||||||
|
Ok(self.nodes.push_tag(Tag::IntegralType(ty)))
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
let name =
|
let name =
|
||||||
self.strings.insert(token.lexeme().as_bytes());
|
self.intern_pool.insert_string(token.lexeme());
|
||||||
Ok(self.nodes.push_tag(Tag::Ident { name }))
|
Ok(self.nodes.push_tag(Tag::Ident { name }))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -404,7 +406,8 @@ impl Tree {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let name_str = self.strings.get_str(self.ident_index(name)).to_owned();
|
let name_str =
|
||||||
|
self.intern_pool.get_str(self.ident_index(name)).to_owned();
|
||||||
let decl = self.nodes.reserve_node();
|
let decl = self.nodes.reserve_node();
|
||||||
|
|
||||||
let assignment = if tokens.eat_token(Token::Equal).is_some() {
|
let assignment = if tokens.eat_token(Token::Equal).is_some() {
|
||||||
|
@ -550,7 +553,7 @@ impl Tree {
|
||||||
let return_type = if tokens.eat_token(Token::MinusGreater).is_some() {
|
let return_type = if tokens.eat_token(Token::MinusGreater).is_some() {
|
||||||
self.parse_typename(tokens)?
|
self.parse_typename(tokens)?
|
||||||
} else {
|
} else {
|
||||||
self.nodes.push_tag(Tag::PrimitiveType(PrimitiveType::Void))
|
self.nodes.push_tag(Tag::PrimitiveType(intern::Index::VOID))
|
||||||
};
|
};
|
||||||
|
|
||||||
let proto = self.nodes.push_tag(Tag::FunctionProto {
|
let proto = self.nodes.push_tag(Tag::FunctionProto {
|
||||||
|
@ -1026,19 +1029,18 @@ impl Tree {
|
||||||
0..2 => {
|
0..2 => {
|
||||||
let (buf, _) =
|
let (buf, _) =
|
||||||
buf.split_at(core::mem::size_of::<u32>());
|
buf.split_at(core::mem::size_of::<u32>());
|
||||||
let dw = u32::from_le_bytes(buf.try_into().unwrap());
|
self.intern_pool.get_unsigned_integer(
|
||||||
ImmOrIndex::U32(dw)
|
u32::from_le_bytes(buf.try_into().unwrap()) as u64,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
0..4 => {
|
0..4 => {
|
||||||
let (buf, _) =
|
let (buf, _) =
|
||||||
buf.split_at(core::mem::size_of::<u64>());
|
buf.split_at(core::mem::size_of::<u64>());
|
||||||
let qw = u64::from_le_bytes(buf.try_into().unwrap());
|
self.intern_pool.get_unsigned_integer(
|
||||||
ImmOrIndex::U64(qw)
|
u64::from_le_bytes(buf.try_into().unwrap()),
|
||||||
}
|
)
|
||||||
0.. => {
|
|
||||||
let idx = self.strings.insert(bytes);
|
|
||||||
ImmOrIndex::Index(idx)
|
|
||||||
}
|
}
|
||||||
|
0.. => self.intern_pool.insert_bytes(&bytes),
|
||||||
};
|
};
|
||||||
|
|
||||||
let ty = match ty {
|
let ty = match ty {
|
||||||
|
@ -1059,8 +1061,16 @@ impl Tree {
|
||||||
);
|
);
|
||||||
|
|
||||||
let bytes = match ty {
|
let bytes = match ty {
|
||||||
FloatingType::Binary32 => ImmOrIndex::U32(bits as u32),
|
FloatingType::Binary32 => {
|
||||||
FloatingType::Binary64 => ImmOrIndex::U64(bits as u64),
|
self.intern_pool.get_or_insert(intern::Key::F32 {
|
||||||
|
bits: f32::from_bits(bits as u32),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
FloatingType::Binary64 => {
|
||||||
|
self.intern_pool.get_or_insert(intern::Key::F64 {
|
||||||
|
bits: f64::from_bits(bits),
|
||||||
|
})
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(self.nodes.push_tag(Tag::Constant {
|
Ok(self.nodes.push_tag(Tag::Constant {
|
||||||
|
@ -1210,7 +1220,7 @@ impl Tree {
|
||||||
|
|
||||||
pub fn get_ident_str(&self, node: Node) -> Option<&str> {
|
pub fn get_ident_str(&self, node: Node) -> Option<&str> {
|
||||||
match &self.nodes[node] {
|
match &self.nodes[node] {
|
||||||
Tag::Ident { name } => Some(self.strings.get_str(*name)),
|
Tag::Ident { name } => Some(self.intern_pool.get_str(*name)),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1218,7 +1228,9 @@ impl Tree {
|
||||||
fn get_typename_str(&self, node: Node) -> Option<String> {
|
fn get_typename_str(&self, node: Node) -> Option<String> {
|
||||||
match self.nodes.get_node(node) {
|
match self.nodes.get_node(node) {
|
||||||
Tag::IntegralType(i) => Some(i.to_string()),
|
Tag::IntegralType(i) => Some(i.to_string()),
|
||||||
Tag::Ident { name } => Some(self.strings.get_str(*name).to_owned()),
|
Tag::Ident { name } => {
|
||||||
|
Some(self.intern_pool.get_str(*name).to_owned())
|
||||||
|
}
|
||||||
Tag::Pointer { pointee } => self.get_typename_str(*pointee),
|
Tag::Pointer { pointee } => self.get_typename_str(*pointee),
|
||||||
Tag::PrimitiveType(prim) => Some(prim.to_string()),
|
Tag::PrimitiveType(prim) => Some(prim.to_string()),
|
||||||
_ => None,
|
_ => None,
|
||||||
|
@ -1429,7 +1441,7 @@ impl Tree {
|
||||||
writer,
|
writer,
|
||||||
"%{} = identifier(\"{}\")",
|
"%{} = identifier(\"{}\")",
|
||||||
node.get(),
|
node.get(),
|
||||||
self.strings.get_str(name)
|
self.intern_pool.get_str(name)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Tag::Block {
|
Tag::Block {
|
||||||
|
@ -1898,10 +1910,10 @@ impl Tree {
|
||||||
writeln_indented!(
|
writeln_indented!(
|
||||||
indent,
|
indent,
|
||||||
writer,
|
writer,
|
||||||
"%{} = constant{{ ty: {}, bytes: {}}}",
|
"%{} = constant{{ ty: {}, bytes: {:?}}}",
|
||||||
node.get(),
|
node.get(),
|
||||||
ty,
|
ty,
|
||||||
self.strings.display_idx(bytes)
|
self.intern_pool.get_key(bytes)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Tag::ExprStatement { expr } => {
|
Tag::ExprStatement { expr } => {
|
||||||
|
@ -2019,12 +2031,15 @@ impl Tree {
|
||||||
pointee: Box::new(self.type_of_node(*pointee)),
|
pointee: Box::new(self.type_of_node(*pointee)),
|
||||||
},
|
},
|
||||||
Tag::Constant { ty, .. } => ty.clone(),
|
Tag::Constant { ty, .. } => ty.clone(),
|
||||||
Tag::IntegralType(t) => Type::Integer(*t),
|
Tag::IntegralType(t) => {
|
||||||
Tag::PrimitiveType(t) => match t {
|
self.intern_pool.as_ast1_type(AMD64_POINTER_BITS, *t)
|
||||||
PrimitiveType::FloatingType(t) => Type::Floating(*t),
|
}
|
||||||
PrimitiveType::IntegralType(t) => Type::Integer(*t),
|
Tag::PrimitiveType(t) => match *t {
|
||||||
PrimitiveType::Bool => Type::bool(),
|
intern::Index::F32 => Type::Floating(FloatingType::Binary32),
|
||||||
PrimitiveType::Void => Type::void(),
|
intern::Index::F64 => Type::Floating(FloatingType::Binary64),
|
||||||
|
intern::Index::BOOL => Type::Bool,
|
||||||
|
intern::Index::VOID => Type::Void,
|
||||||
|
_ => self.intern_pool.as_ast1_type(AMD64_POINTER_BITS, *t),
|
||||||
},
|
},
|
||||||
Tag::Block { trailing_expr, .. } => trailing_expr
|
Tag::Block { trailing_expr, .. } => trailing_expr
|
||||||
.map(|n| self.type_of_node(n))
|
.map(|n| self.type_of_node(n))
|
||||||
|
@ -2197,45 +2212,16 @@ impl Tree {
|
||||||
pub fn value_of_comptime_node(&self, node: Node) -> Option<ComptimeNumber> {
|
pub fn value_of_comptime_node(&self, node: Node) -> Option<ComptimeNumber> {
|
||||||
match self.nodes.get_node(node) {
|
match self.nodes.get_node(node) {
|
||||||
Tag::Constant { bytes, ty } => {
|
Tag::Constant { bytes, ty } => {
|
||||||
let bytes = match bytes {
|
let ty =
|
||||||
ImmOrIndex::U64(v) => &v.to_le_bytes()[..],
|
self.intern_pool.from_ast1_type(AMD64_POINTER_BITS, ty);
|
||||||
|
let number =
|
||||||
|
crate::ast2::interned_type_and_value_to_comptime_number(
|
||||||
|
&self.intern_pool,
|
||||||
|
AMD64_POINTER_BITS,
|
||||||
|
ty,
|
||||||
|
*bytes,
|
||||||
|
);
|
||||||
|
|
||||||
ImmOrIndex::U32(v) => &v.to_le_bytes()[..],
|
|
||||||
ImmOrIndex::Index(idx) => self.strings.get_bytes(*idx),
|
|
||||||
};
|
|
||||||
|
|
||||||
let number: ComptimeNumber = match ty {
|
|
||||||
Type::Bool => (bytes[0] != 0).into(),
|
|
||||||
Type::ComptimeNumber => {
|
|
||||||
BigInt::from_bytes_le(num_bigint::Sign::Plus, bytes)
|
|
||||||
.into()
|
|
||||||
}
|
|
||||||
Type::Integer(ty) => {
|
|
||||||
if bytes.len() > core::mem::size_of::<u128>() {
|
|
||||||
let bits = BigInt::from_bytes_le(
|
|
||||||
num_bigint::Sign::Plus,
|
|
||||||
bytes,
|
|
||||||
);
|
|
||||||
(bits, *ty).into()
|
|
||||||
} else {
|
|
||||||
let mut buf = [0u8; core::mem::size_of::<u128>()];
|
|
||||||
buf[..bytes.len()].copy_from_slice(bytes);
|
|
||||||
let bits = u128::from_le_bytes(buf);
|
|
||||||
(bits, *ty).into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Type::Floating(ty) => match ty {
|
|
||||||
FloatingType::Binary32 => (f32::from_le_bytes(
|
|
||||||
(&bytes[..4]).try_into().unwrap(),
|
|
||||||
))
|
|
||||||
.into(),
|
|
||||||
FloatingType::Binary64 => (f64::from_le_bytes(
|
|
||||||
(&bytes[..8]).try_into().unwrap(),
|
|
||||||
))
|
|
||||||
.into(),
|
|
||||||
},
|
|
||||||
_ => unimplemented!(),
|
|
||||||
};
|
|
||||||
Some(number)
|
Some(number)
|
||||||
}
|
}
|
||||||
Tag::Block { .. } => todo!(),
|
Tag::Block { .. } => todo!(),
|
||||||
|
@ -2272,13 +2258,17 @@ impl Tree {
|
||||||
|_: &mut Tree, _| {},
|
|_: &mut Tree, _| {},
|
||||||
|tree: &mut Tree, node| {
|
|tree: &mut Tree, node| {
|
||||||
if let Ok(value) = tree.fold_comptime_inner(node, false) {
|
if let Ok(value) = tree.fold_comptime_inner(node, false) {
|
||||||
let (bytes, ty) = value.into_bytes_and_type();
|
let (value, ty) =
|
||||||
let idx = tree.strings.insert(bytes);
|
crate::ast2::comptime_number_to_interned_type_and_value(
|
||||||
|
&mut tree.intern_pool,
|
||||||
|
AMD64_POINTER_BITS,
|
||||||
|
value,
|
||||||
|
);
|
||||||
|
let ty =
|
||||||
|
tree.intern_pool.as_ast1_type(AMD64_POINTER_BITS, ty);
|
||||||
|
|
||||||
*tree.nodes.get_node_mut(node) = Tag::Constant {
|
*tree.nodes.get_node_mut(node) =
|
||||||
bytes: ImmOrIndex::Index(idx),
|
Tag::Constant { bytes: value, ty };
|
||||||
ty,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -2293,46 +2283,16 @@ impl Tree {
|
||||||
if self.is_node_comptime(decl, check_declrefs) {
|
if self.is_node_comptime(decl, check_declrefs) {
|
||||||
match self.nodes.get_node(decl) {
|
match self.nodes.get_node(decl) {
|
||||||
Tag::Constant { bytes, ty } => {
|
Tag::Constant { bytes, ty } => {
|
||||||
let bytes = match bytes {
|
let ty =
|
||||||
ImmOrIndex::U64(v) => &v.to_le_bytes()[..],
|
self.intern_pool.from_ast1_type(AMD64_POINTER_BITS, ty);
|
||||||
|
let number =
|
||||||
|
crate::ast2::interned_type_and_value_to_comptime_number(
|
||||||
|
&self.intern_pool,
|
||||||
|
AMD64_POINTER_BITS,
|
||||||
|
ty,
|
||||||
|
*bytes,
|
||||||
|
);
|
||||||
|
|
||||||
ImmOrIndex::U32(v) => &v.to_le_bytes()[..],
|
|
||||||
ImmOrIndex::Index(idx) => self.strings.get_bytes(*idx),
|
|
||||||
};
|
|
||||||
|
|
||||||
let number: ComptimeNumber = match ty {
|
|
||||||
Type::Bool => (bytes[0] != 0).into(),
|
|
||||||
Type::ComptimeNumber => {
|
|
||||||
BigInt::from_bytes_le(num_bigint::Sign::Plus, bytes)
|
|
||||||
.into()
|
|
||||||
}
|
|
||||||
Type::Integer(ty) => {
|
|
||||||
if bytes.len() > core::mem::size_of::<u128>() {
|
|
||||||
let bits = BigInt::from_bytes_le(
|
|
||||||
num_bigint::Sign::Plus,
|
|
||||||
bytes,
|
|
||||||
);
|
|
||||||
(bits, *ty).into()
|
|
||||||
} else {
|
|
||||||
let mut buf =
|
|
||||||
[0u8; core::mem::size_of::<u128>()];
|
|
||||||
buf[..bytes.len()].copy_from_slice(bytes);
|
|
||||||
let bits = u128::from_le_bytes(buf);
|
|
||||||
(bits, *ty).into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Type::Floating(ty) => match ty {
|
|
||||||
FloatingType::Binary32 => (f32::from_le_bytes(
|
|
||||||
(&bytes[..4]).try_into().unwrap(),
|
|
||||||
))
|
|
||||||
.into(),
|
|
||||||
FloatingType::Binary64 => (f64::from_le_bytes(
|
|
||||||
(&bytes[..8]).try_into().unwrap(),
|
|
||||||
))
|
|
||||||
.into(),
|
|
||||||
},
|
|
||||||
_ => unimplemented!(),
|
|
||||||
};
|
|
||||||
return Ok(number);
|
return Ok(number);
|
||||||
}
|
}
|
||||||
Tag::Negate { lhs } => {
|
Tag::Negate { lhs } => {
|
||||||
|
@ -2515,6 +2475,20 @@ impl Tree {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn intern_types(&mut self) {
|
||||||
|
for decl in self.global_decls.clone() {
|
||||||
|
ast::tree_visitor::Visitor::new(
|
||||||
|
decl,
|
||||||
|
|_: &mut Tree, _| {},
|
||||||
|
|tree: &mut Tree, node| {
|
||||||
|
let ty = tree.type_of_node(node);
|
||||||
|
tree.intern_pool.insert_ast1_type(AMD64_POINTER_BITS, &ty);
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.visit_mut(self);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn fold_comptime(&mut self) {
|
pub fn fold_comptime(&mut self) {
|
||||||
for decl in self.global_decls.clone() {
|
for decl in self.global_decls.clone() {
|
||||||
match self.nodes.get_node(decl) {
|
match self.nodes.get_node(decl) {
|
||||||
|
@ -2565,9 +2539,10 @@ impl Tree {
|
||||||
};
|
};
|
||||||
if let Some(expr) = trailing_expr {
|
if let Some(expr) = trailing_expr {
|
||||||
let ty = self.nodes.push_tag(Tag::PrimitiveType(
|
let ty = self.nodes.push_tag(Tag::PrimitiveType(
|
||||||
peer_t
|
self.intern_pool.from_ast1_type(
|
||||||
.as_primitive_type()
|
AMD64_POINTER_BITS,
|
||||||
.expect("comptime cannot be cast into a non-primitive type"),
|
&peer_t,
|
||||||
|
),
|
||||||
));
|
));
|
||||||
let expr = self.nodes.push_tag(Tag::ExplicitCast {
|
let expr = self.nodes.push_tag(Tag::ExplicitCast {
|
||||||
lhs: expr,
|
lhs: expr,
|
||||||
|
@ -2589,7 +2564,16 @@ impl Tree {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Tag::Constant { bytes, ty } => {
|
Tag::Constant { bytes, ty } => {
|
||||||
let bits = self.strings.count_bits(bytes);
|
let bits = match self.intern_pool.get_key(bytes) {
|
||||||
|
intern::Key::F32 { .. } => 32,
|
||||||
|
intern::Key::F64 { .. } => 64,
|
||||||
|
intern::Key::UInt64 { bits } => bits.bits(),
|
||||||
|
intern::Key::UIntSmall { bits } => bits.bits(),
|
||||||
|
intern::Key::Bytes { bytes } => bytes.bits(),
|
||||||
|
_ => {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
};
|
||||||
if bits < ty.bit_width() as u32 {
|
if bits < ty.bit_width() as u32 {
|
||||||
errors.push(AnalysisError::new(
|
errors.push(AnalysisError::new(
|
||||||
AnalysisErrorTag::InsufficientBitsInTypeForConstant(
|
AnalysisErrorTag::InsufficientBitsInTypeForConstant(
|
||||||
|
|
440
src/triples.rs
440
src/triples.rs
|
@ -159,15 +159,17 @@ pub enum Inst {
|
||||||
/// list of arguments
|
/// list of arguments
|
||||||
/// start, (inlinetype)end
|
/// start, (inlinetype)end
|
||||||
Call(Node),
|
Call(Node),
|
||||||
/// Value
|
/// (name: intern, ty: intern)
|
||||||
/// lhs
|
/// lhs: value node
|
||||||
GlobalConstant(StringsIndex, intern::Index),
|
GlobalConstant(intern::Index, intern::Index),
|
||||||
/// u32
|
/// u32
|
||||||
ConstantU32,
|
ConstantU32,
|
||||||
/// lo, hi
|
/// lo, hi
|
||||||
ConstantU64,
|
ConstantU64,
|
||||||
/// index
|
/// index
|
||||||
ConstantMultiByte,
|
ConstantMultiByte,
|
||||||
|
/// type, value
|
||||||
|
Constant,
|
||||||
/// size, align
|
/// size, align
|
||||||
Alloca,
|
Alloca,
|
||||||
/// src
|
/// src
|
||||||
|
@ -233,9 +235,10 @@ pub enum Inst {
|
||||||
impl Inst {
|
impl Inst {
|
||||||
fn is_constant(self) -> bool {
|
fn is_constant(self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Inst::ConstantU32 | Inst::ConstantU64 | Inst::ConstantMultiByte => {
|
Inst::ConstantU32
|
||||||
true
|
| Inst::ConstantU64
|
||||||
}
|
| Inst::ConstantMultiByte
|
||||||
|
| Inst::Constant => true,
|
||||||
|
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
|
@ -263,11 +266,14 @@ impl Data {
|
||||||
fn as_u64(&self) -> u64 {
|
fn as_u64(&self) -> u64 {
|
||||||
self.lhs as u64 | (self.rhs as u64) << u32::BITS as u64
|
self.lhs as u64 | (self.rhs as u64) << u32::BITS as u64
|
||||||
}
|
}
|
||||||
fn as_index(&self) -> StringsIndex {
|
fn as_index(&self) -> intern::Index {
|
||||||
crate::string_table::Index {
|
intern::Index::from_u32(self.lhs)
|
||||||
start: self.lhs,
|
}
|
||||||
end: self.rhs,
|
fn as_index_index(&self) -> (intern::Index, intern::Index) {
|
||||||
}
|
(
|
||||||
|
intern::Index::from_u32(self.lhs),
|
||||||
|
intern::Index::from_u32(self.rhs),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
fn as_lhs_rhs(&self) -> (u32, u32) {
|
fn as_lhs_rhs(&self) -> (u32, u32) {
|
||||||
(self.lhs, self.rhs)
|
(self.lhs, self.rhs)
|
||||||
|
@ -297,6 +303,24 @@ impl From<crate::string_table::ImmOrIndex> for Data {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<intern::Index> for Data {
|
||||||
|
fn from(value: intern::Index) -> Self {
|
||||||
|
Self {
|
||||||
|
lhs: value.into_u32(),
|
||||||
|
rhs: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<(intern::Index, intern::Index)> for Data {
|
||||||
|
fn from(value: (intern::Index, intern::Index)) -> Self {
|
||||||
|
Self {
|
||||||
|
lhs: value.0.into_u32(),
|
||||||
|
rhs: value.1.into_u32(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<crate::string_table::Index> for Data {
|
impl From<crate::string_table::Index> for Data {
|
||||||
fn from(value: crate::string_table::Index) -> Self {
|
fn from(value: crate::string_table::Index) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
@ -306,15 +330,15 @@ impl From<crate::string_table::Index> for Data {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct IRBuilder<'tree, 'ir, 'intern> {
|
pub struct IRBuilder<'tree, 'ir> {
|
||||||
ir: &'ir mut IR<'intern>,
|
ir: &'ir mut IR,
|
||||||
tree: &'tree mut Tree,
|
tree: &'tree mut Tree,
|
||||||
type_map: HashMap<AstNode, Type>,
|
type_map: HashMap<AstNode, Type>,
|
||||||
lookup: HashMap<AstNode, NodeOrList>,
|
lookup: HashMap<AstNode, NodeOrList>,
|
||||||
fixup: Vec<Node>,
|
fixup: Vec<Node>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl core::ops::Index<Node> for IR<'_> {
|
impl core::ops::Index<Node> for IR {
|
||||||
type Output = Inst;
|
type Output = Inst;
|
||||||
|
|
||||||
fn index(&self, index: Node) -> &Self::Output {
|
fn index(&self, index: Node) -> &Self::Output {
|
||||||
|
@ -322,8 +346,8 @@ impl core::ops::Index<Node> for IR<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
|
impl<'tree, 'ir> IRBuilder<'tree, 'ir> {
|
||||||
fn new(ir: &'ir mut IR<'intern>, tree: &'tree mut Tree) -> Self {
|
fn new(ir: &'ir mut IR, tree: &'tree mut Tree) -> Self {
|
||||||
Self {
|
Self {
|
||||||
ir,
|
ir,
|
||||||
tree,
|
tree,
|
||||||
|
@ -333,6 +357,13 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn intern_pool_mut(&mut self) -> &mut InternPool {
|
||||||
|
&mut self.tree.intern_pool
|
||||||
|
}
|
||||||
|
fn intern_pool(&self) -> &InternPool {
|
||||||
|
&self.tree.intern_pool
|
||||||
|
}
|
||||||
|
|
||||||
fn peer_type_of_nodes(&self, lhs: AstNode, rhs: AstNode) -> Option<Type> {
|
fn peer_type_of_nodes(&self, lhs: AstNode, rhs: AstNode) -> Option<Type> {
|
||||||
let lty = self.tree.type_of_node(lhs);
|
let lty = self.tree.type_of_node(lhs);
|
||||||
let rty = self.tree.type_of_node(rhs);
|
let rty = self.tree.type_of_node(rhs);
|
||||||
|
@ -396,8 +427,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
|
||||||
let size = ty.size_of();
|
let size = ty.size_of();
|
||||||
let align = ty.align_of();
|
let align = ty.align_of();
|
||||||
let ty = self
|
let ty = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.intern_pool
|
|
||||||
.from_ast1_type(AMD64_POINTER_BITS, &ty);
|
.from_ast1_type(AMD64_POINTER_BITS, &ty);
|
||||||
let ir = self.ir.push(
|
let ir = self.ir.push(
|
||||||
Inst::Parameter(ty),
|
Inst::Parameter(ty),
|
||||||
|
@ -414,8 +444,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
|
||||||
if value != !0 {
|
if value != !0 {
|
||||||
let ty = self.tree.type_of_node(*body);
|
let ty = self.tree.type_of_node(*body);
|
||||||
let ty = self
|
let ty = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.intern_pool
|
|
||||||
.from_ast1_type(AMD64_POINTER_BITS, &ty);
|
.from_ast1_type(AMD64_POINTER_BITS, &ty);
|
||||||
self.ir.push(
|
self.ir.push(
|
||||||
Inst::ReturnValue(ty.into()),
|
Inst::ReturnValue(ty.into()),
|
||||||
|
@ -441,8 +470,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
|
||||||
let start = self.ir.nodes.len();
|
let start = self.ir.nodes.len();
|
||||||
for (arg, ty) in args {
|
for (arg, ty) in args {
|
||||||
let ty = self
|
let ty = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.intern_pool
|
|
||||||
.from_ast1_type(AMD64_POINTER_BITS, &ty);
|
.from_ast1_type(AMD64_POINTER_BITS, &ty);
|
||||||
_ = self.ir.push(
|
_ = self.ir.push(
|
||||||
Inst::Argument(ty.into()),
|
Inst::Argument(ty.into()),
|
||||||
|
@ -461,7 +489,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
|
||||||
));
|
));
|
||||||
|
|
||||||
let ty =
|
let ty =
|
||||||
self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty);
|
self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
|
||||||
self.ir.push(Inst::InlineType(ty.into()), None);
|
self.ir.push(Inst::InlineType(ty.into()), None);
|
||||||
|
|
||||||
let func = self.visit(*lhs);
|
let func = self.visit(*lhs);
|
||||||
|
@ -490,7 +518,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
|
||||||
Some(Data::new(ty.size_of(), ty.align_of())),
|
Some(Data::new(ty.size_of(), ty.align_of())),
|
||||||
);
|
);
|
||||||
let ty =
|
let ty =
|
||||||
self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty);
|
self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
|
||||||
|
|
||||||
if let Some(assignment) = assignment {
|
if let Some(assignment) = assignment {
|
||||||
let value = self.visit(*assignment);
|
let value = self.visit(*assignment);
|
||||||
|
@ -513,7 +541,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
|
||||||
variant!(self.tree.nodes.get_node(*name) => Tag::Ident { name });
|
variant!(self.tree.nodes.get_node(*name) => Tag::Ident { name });
|
||||||
|
|
||||||
let ty =
|
let ty =
|
||||||
self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty);
|
self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
|
||||||
let global = self.ir.push(
|
let global = self.ir.push(
|
||||||
Inst::GlobalConstant(*name, ty.into()),
|
Inst::GlobalConstant(*name, ty.into()),
|
||||||
Some(Data::lhs(value)),
|
Some(Data::lhs(value)),
|
||||||
|
@ -526,7 +554,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
|
||||||
Tag::GlobalRef(decl) => {
|
Tag::GlobalRef(decl) => {
|
||||||
let ty = self.tree.type_of_node(*decl);
|
let ty = self.tree.type_of_node(*decl);
|
||||||
let ty =
|
let ty =
|
||||||
self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty);
|
self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
|
||||||
let node = self.ir.push(
|
let node = self.ir.push(
|
||||||
Inst::ExternRef(ty.into()),
|
Inst::ExternRef(ty.into()),
|
||||||
Some(Data::lhs(decl.get())),
|
Some(Data::lhs(decl.get())),
|
||||||
|
@ -548,7 +576,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
|
||||||
let source = self.visit(*rhs);
|
let source = self.visit(*rhs);
|
||||||
|
|
||||||
let ty =
|
let ty =
|
||||||
self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty);
|
self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
|
||||||
self.ir
|
self.ir
|
||||||
.push(Inst::Store(ty.into()), Some(Data::new(source, dest)))
|
.push(Inst::Store(ty.into()), Some(Data::new(source, dest)))
|
||||||
}
|
}
|
||||||
|
@ -556,8 +584,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
|
||||||
if let Some(expr) = expr {
|
if let Some(expr) = expr {
|
||||||
let ty = self.tree.type_of_node(*expr);
|
let ty = self.tree.type_of_node(*expr);
|
||||||
let ty = self
|
let ty = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.intern_pool
|
|
||||||
.from_ast1_type(AMD64_POINTER_BITS, &ty);
|
.from_ast1_type(AMD64_POINTER_BITS, &ty);
|
||||||
let expr = self.visit(*expr);
|
let expr = self.visit(*expr);
|
||||||
self.ir.push(
|
self.ir.push(
|
||||||
|
@ -574,7 +601,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
|
||||||
self.tree.type_of_node(*lhs).pointee().unwrap().clone();
|
self.tree.type_of_node(*lhs).pointee().unwrap().clone();
|
||||||
let lhs = self.visit(*lhs);
|
let lhs = self.visit(*lhs);
|
||||||
let ty =
|
let ty =
|
||||||
self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty);
|
self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
|
||||||
self.ir.push(Inst::Load(ty.into()), Some(Data::lhs(lhs)))
|
self.ir.push(Inst::Load(ty.into()), Some(Data::lhs(lhs)))
|
||||||
}
|
}
|
||||||
Tag::Add { lhs, rhs } => {
|
Tag::Add { lhs, rhs } => {
|
||||||
|
@ -582,7 +609,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
|
||||||
let lhs = self.visit(*lhs);
|
let lhs = self.visit(*lhs);
|
||||||
let rhs = self.visit(*rhs);
|
let rhs = self.visit(*rhs);
|
||||||
let ty =
|
let ty =
|
||||||
self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty);
|
self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
|
||||||
self.ir
|
self.ir
|
||||||
.push(Inst::Add(ty.into()), Some(Data::new(lhs, rhs)))
|
.push(Inst::Add(ty.into()), Some(Data::new(lhs, rhs)))
|
||||||
}
|
}
|
||||||
|
@ -591,7 +618,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
|
||||||
let lhs = self.visit(*lhs);
|
let lhs = self.visit(*lhs);
|
||||||
let rhs = self.visit(*rhs);
|
let rhs = self.visit(*rhs);
|
||||||
let ty =
|
let ty =
|
||||||
self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty);
|
self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
|
||||||
self.ir
|
self.ir
|
||||||
.push(Inst::Sub(ty.into()), Some(Data::new(lhs, rhs)))
|
.push(Inst::Sub(ty.into()), Some(Data::new(lhs, rhs)))
|
||||||
}
|
}
|
||||||
|
@ -600,7 +627,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
|
||||||
let lhs = self.visit(*lhs);
|
let lhs = self.visit(*lhs);
|
||||||
let rhs = self.visit(*rhs);
|
let rhs = self.visit(*rhs);
|
||||||
let ty =
|
let ty =
|
||||||
self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty);
|
self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
|
||||||
self.ir
|
self.ir
|
||||||
.push(Inst::BitAnd(ty.into()), Some(Data::new(lhs, rhs)))
|
.push(Inst::BitAnd(ty.into()), Some(Data::new(lhs, rhs)))
|
||||||
}
|
}
|
||||||
|
@ -609,7 +636,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
|
||||||
let lhs = self.visit(*lhs);
|
let lhs = self.visit(*lhs);
|
||||||
let rhs = self.visit(*rhs);
|
let rhs = self.visit(*rhs);
|
||||||
let ty =
|
let ty =
|
||||||
self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty);
|
self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
|
||||||
self.ir
|
self.ir
|
||||||
.push(Inst::BitOr(ty.into()), Some(Data::new(lhs, rhs)))
|
.push(Inst::BitOr(ty.into()), Some(Data::new(lhs, rhs)))
|
||||||
}
|
}
|
||||||
|
@ -618,7 +645,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
|
||||||
let lhs = self.visit(*lhs);
|
let lhs = self.visit(*lhs);
|
||||||
let rhs = self.visit(*rhs);
|
let rhs = self.visit(*rhs);
|
||||||
let ty =
|
let ty =
|
||||||
self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty);
|
self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
|
||||||
self.ir
|
self.ir
|
||||||
.push(Inst::BitXOr(ty.into()), Some(Data::new(lhs, rhs)))
|
.push(Inst::BitXOr(ty.into()), Some(Data::new(lhs, rhs)))
|
||||||
}
|
}
|
||||||
|
@ -639,7 +666,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
|
||||||
.into();
|
.into();
|
||||||
|
|
||||||
let ty =
|
let ty =
|
||||||
self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty);
|
self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
|
||||||
let inst = match tag {
|
let inst = match tag {
|
||||||
Tag::Eq { .. } => Inst::Eq(ty),
|
Tag::Eq { .. } => Inst::Eq(ty),
|
||||||
Tag::NEq { .. } => Inst::Neq(ty),
|
Tag::NEq { .. } => Inst::Neq(ty),
|
||||||
|
@ -659,7 +686,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
|
||||||
let lhs = self.visit(*lhs);
|
let lhs = self.visit(*lhs);
|
||||||
let rhs = self.visit(*rhs);
|
let rhs = self.visit(*rhs);
|
||||||
let ty =
|
let ty =
|
||||||
self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty);
|
self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
|
||||||
self.ir
|
self.ir
|
||||||
.push(Inst::Mul(ty.into()), Some(Data::new(lhs, rhs)))
|
.push(Inst::Mul(ty.into()), Some(Data::new(lhs, rhs)))
|
||||||
}
|
}
|
||||||
|
@ -667,14 +694,14 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
|
||||||
let ty = self.tree.type_of_node(node);
|
let ty = self.tree.type_of_node(node);
|
||||||
let lhs = self.visit(*lhs);
|
let lhs = self.visit(*lhs);
|
||||||
let ty =
|
let ty =
|
||||||
self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty);
|
self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
|
||||||
self.ir.push(Inst::Negate(ty.into()), Some(Data::lhs(lhs)))
|
self.ir.push(Inst::Negate(ty.into()), Some(Data::lhs(lhs)))
|
||||||
}
|
}
|
||||||
Tag::Not { lhs } => {
|
Tag::Not { lhs } => {
|
||||||
let ty = self.tree.type_of_node(node);
|
let ty = self.tree.type_of_node(node);
|
||||||
let lhs = self.visit(*lhs);
|
let lhs = self.visit(*lhs);
|
||||||
let ty =
|
let ty =
|
||||||
self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty);
|
self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
|
||||||
self.ir.push(Inst::Not(ty.into()), Some(Data::lhs(lhs)))
|
self.ir.push(Inst::Not(ty.into()), Some(Data::lhs(lhs)))
|
||||||
}
|
}
|
||||||
Tag::Shl { lhs, rhs } => {
|
Tag::Shl { lhs, rhs } => {
|
||||||
|
@ -682,7 +709,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
|
||||||
let lhs = self.visit(*lhs);
|
let lhs = self.visit(*lhs);
|
||||||
let rhs = self.visit(*rhs);
|
let rhs = self.visit(*rhs);
|
||||||
let ty =
|
let ty =
|
||||||
self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty);
|
self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
|
||||||
self.ir
|
self.ir
|
||||||
.push(Inst::ShiftLeft(ty.into()), Some(Data::new(lhs, rhs)))
|
.push(Inst::ShiftLeft(ty.into()), Some(Data::new(lhs, rhs)))
|
||||||
}
|
}
|
||||||
|
@ -691,7 +718,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
|
||||||
let lhs = self.visit(*lhs);
|
let lhs = self.visit(*lhs);
|
||||||
let rhs = self.visit(*rhs);
|
let rhs = self.visit(*rhs);
|
||||||
let ty =
|
let ty =
|
||||||
self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty);
|
self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
|
||||||
self.ir.push(
|
self.ir.push(
|
||||||
Inst::ShiftRight(ty.into()),
|
Inst::ShiftRight(ty.into()),
|
||||||
Some(Data::new(lhs, rhs)),
|
Some(Data::new(lhs, rhs)),
|
||||||
|
@ -703,23 +730,17 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
|
||||||
// self.ir.push(Inst::Load(ty.into()), Some(Data::lhs(lhs)))
|
// self.ir.push(Inst::Load(ty.into()), Some(Data::lhs(lhs)))
|
||||||
// nothing happens here because lhs is of type pointer
|
// nothing happens here because lhs is of type pointer
|
||||||
let ty =
|
let ty =
|
||||||
self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty);
|
self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
|
||||||
self.ir.push(
|
self.ir.push(
|
||||||
Inst::GetElementPtr(ty.into()),
|
Inst::GetElementPtr(ty.into()),
|
||||||
Some(Data::new(lhs, 0)),
|
Some(Data::new(lhs, 0)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Tag::Constant { bytes, .. } => match bytes {
|
Tag::Constant { bytes, ty } => {
|
||||||
ImmOrIndex::U64(v) => {
|
let ty =
|
||||||
self.ir.push(Inst::ConstantU64, Some((*v).into()))
|
self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, ty);
|
||||||
}
|
self.ir.push(Inst::Constant, Some((ty, *bytes).into()))
|
||||||
ImmOrIndex::U32(v) => {
|
}
|
||||||
self.ir.push(Inst::ConstantU32, Some((*v).into()))
|
|
||||||
}
|
|
||||||
ImmOrIndex::Index(idx) => {
|
|
||||||
self.ir.push(Inst::ConstantMultiByte, Some((*idx).into()))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Tag::ExplicitCast { lhs, typename } => {
|
Tag::ExplicitCast { lhs, typename } => {
|
||||||
let l_ty = self.tree.type_of_node(*lhs).clone();
|
let l_ty = self.tree.type_of_node(*lhs).clone();
|
||||||
let r_ty = self.tree.type_of_node(*typename).clone();
|
let r_ty = self.tree.type_of_node(*typename).clone();
|
||||||
|
@ -731,12 +752,10 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
|
||||||
lhs
|
lhs
|
||||||
} else {
|
} else {
|
||||||
let l_ty = self
|
let l_ty = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.intern_pool
|
|
||||||
.from_ast1_type(AMD64_POINTER_BITS, &l_ty);
|
.from_ast1_type(AMD64_POINTER_BITS, &l_ty);
|
||||||
let r_ty = self
|
let r_ty = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.intern_pool
|
|
||||||
.from_ast1_type(AMD64_POINTER_BITS, &r_ty);
|
.from_ast1_type(AMD64_POINTER_BITS, &r_ty);
|
||||||
self.ir.push(
|
self.ir.push(
|
||||||
Inst::ExplicitCast(l_ty.into(), r_ty.into()),
|
Inst::ExplicitCast(l_ty.into(), r_ty.into()),
|
||||||
|
@ -750,14 +769,16 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
|
||||||
let condition = self.visit(*condition);
|
let condition = self.visit(*condition);
|
||||||
let br = self.ir.push(Inst::Branch(condition), None);
|
let br = self.ir.push(Inst::Branch(condition), None);
|
||||||
|
|
||||||
let label_lhs = self
|
let label_lhs = self.ir.push(
|
||||||
.ir
|
Inst::Label,
|
||||||
.push(Inst::Label, Some(StringsIndex::none().into()));
|
Some(intern::Index::EMPTY_STRING.into()),
|
||||||
|
);
|
||||||
let _ = self.visit(*body);
|
let _ = self.visit(*body);
|
||||||
let jmp = self.ir.push(Inst::Jump, None);
|
let jmp = self.ir.push(Inst::Jump, None);
|
||||||
let nojump = self
|
let nojump = self.ir.push(
|
||||||
.ir
|
Inst::Label,
|
||||||
.push(Inst::Label, Some(StringsIndex::none().into()));
|
Some(intern::Index::EMPTY_STRING.into()),
|
||||||
|
);
|
||||||
|
|
||||||
self.ir.data[br as usize] = Some(Data::new(label_lhs, nojump));
|
self.ir.data[br as usize] = Some(Data::new(label_lhs, nojump));
|
||||||
self.ir.data[jmp as usize] = Some(Data::lhs(nojump));
|
self.ir.data[jmp as usize] = Some(Data::lhs(nojump));
|
||||||
|
@ -771,26 +792,29 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
|
||||||
assert_eq!(self.tree.type_of_node(*condition), Type::Bool);
|
assert_eq!(self.tree.type_of_node(*condition), Type::Bool);
|
||||||
let ty = self.tree.peer_type_of_nodes_unwrap(*body, *else_expr);
|
let ty = self.tree.peer_type_of_nodes_unwrap(*body, *else_expr);
|
||||||
let ty =
|
let ty =
|
||||||
self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty);
|
self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
|
||||||
|
|
||||||
let condition = self.visit(*condition);
|
let condition = self.visit(*condition);
|
||||||
let br = self.ir.push(Inst::Branch(condition), None);
|
let br = self.ir.push(Inst::Branch(condition), None);
|
||||||
|
|
||||||
let label_lhs = self
|
let label_lhs = self.ir.push(
|
||||||
.ir
|
Inst::Label,
|
||||||
.push(Inst::Label, Some(StringsIndex::none().into()));
|
Some(intern::Index::EMPTY_STRING.into()),
|
||||||
|
);
|
||||||
let lhs = self.visit(*body);
|
let lhs = self.visit(*body);
|
||||||
let ljmp = self.ir.push(Inst::Jump, None);
|
let ljmp = self.ir.push(Inst::Jump, None);
|
||||||
let label_rhs = self
|
let label_rhs = self.ir.push(
|
||||||
.ir
|
Inst::Label,
|
||||||
.push(Inst::Label, Some(StringsIndex::none().into()));
|
Some(intern::Index::EMPTY_STRING.into()),
|
||||||
|
);
|
||||||
let rhs = self.visit(*else_expr);
|
let rhs = self.visit(*else_expr);
|
||||||
let rjmp = self.ir.push(Inst::Jump, None);
|
let rjmp = self.ir.push(Inst::Jump, None);
|
||||||
|
|
||||||
let nojump = self
|
let nojump = self.ir.push(
|
||||||
.ir
|
Inst::Label,
|
||||||
.push(Inst::Label, Some(StringsIndex::none().into()));
|
Some(intern::Index::EMPTY_STRING.into()),
|
||||||
let phi = if ty != self.ir.intern_pool.get_void_type() {
|
);
|
||||||
|
let phi = if ty != intern::Index::VOID {
|
||||||
self.ir.push(Inst::Phi2(ty), Some(Data::new(lhs, rhs)))
|
self.ir.push(Inst::Phi2(ty), Some(Data::new(lhs, rhs)))
|
||||||
} else {
|
} else {
|
||||||
br
|
br
|
||||||
|
@ -810,16 +834,15 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct IR<'a> {
|
pub struct IR {
|
||||||
nodes: Vec<Inst>,
|
nodes: Vec<Inst>,
|
||||||
data: Vec<Option<Data>>,
|
data: Vec<Option<Data>>,
|
||||||
intern_pool: &'a mut InternPool,
|
// intern_pool: &'a mut InternPool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> IR<'a> {
|
impl IR {
|
||||||
pub fn new(intern_pool: &'a mut InternPool) -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
intern_pool,
|
|
||||||
nodes: Vec::new(),
|
nodes: Vec::new(),
|
||||||
data: Vec::new(),
|
data: Vec::new(),
|
||||||
}
|
}
|
||||||
|
@ -834,10 +857,7 @@ impl<'a> IR<'a> {
|
||||||
pub fn build<'b, 'tree>(
|
pub fn build<'b, 'tree>(
|
||||||
&'b mut self,
|
&'b mut self,
|
||||||
tree: &'tree mut Tree,
|
tree: &'tree mut Tree,
|
||||||
) -> IRBuilder<'tree, 'b, 'a>
|
) -> IRBuilder<'tree, 'b> {
|
||||||
where
|
|
||||||
'a: 'b,
|
|
||||||
{
|
|
||||||
let global_decls = tree.global_decls.clone();
|
let global_decls = tree.global_decls.clone();
|
||||||
let mut builder = IRBuilder::new(self, tree);
|
let mut builder = IRBuilder::new(self, tree);
|
||||||
|
|
||||||
|
@ -873,7 +893,7 @@ impl<'a> IR<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IRBuilder<'_, '_, '_> {
|
impl IRBuilder<'_, '_> {
|
||||||
fn render_node<W: core::fmt::Write>(
|
fn render_node<W: core::fmt::Write>(
|
||||||
&self,
|
&self,
|
||||||
w: &mut W,
|
w: &mut W,
|
||||||
|
@ -886,7 +906,7 @@ impl IRBuilder<'_, '_, '_> {
|
||||||
let inst = self.ir.nodes[node as usize];
|
let inst = self.ir.nodes[node as usize];
|
||||||
match inst {
|
match inst {
|
||||||
Inst::Label => {
|
Inst::Label => {
|
||||||
let label = self.tree.strings.get_str(data.as_index());
|
let label = self.intern_pool().get_str(data.as_index());
|
||||||
writeln_indented!(
|
writeln_indented!(
|
||||||
indent - 1,
|
indent - 1,
|
||||||
w,
|
w,
|
||||||
|
@ -895,7 +915,7 @@ impl IRBuilder<'_, '_, '_> {
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
Inst::FunctionStart => {
|
Inst::FunctionStart => {
|
||||||
let label = self.tree.strings.get_str(data.as_index());
|
let label = self.intern_pool().get_str(data.as_index());
|
||||||
writeln_indented!(indent - 1, w, "%{} = func {label}:", node)?;
|
writeln_indented!(indent - 1, w, "%{} = func {label}:", node)?;
|
||||||
}
|
}
|
||||||
Inst::FunctionEnd => {
|
Inst::FunctionEnd => {
|
||||||
|
@ -931,6 +951,17 @@ impl IRBuilder<'_, '_, '_> {
|
||||||
}
|
}
|
||||||
writeln_indented!(indent, w, ")")?;
|
writeln_indented!(indent, w, ")")?;
|
||||||
}
|
}
|
||||||
|
Inst::Constant => {
|
||||||
|
let (ty, val) = data.as_index_index();
|
||||||
|
writeln_indented!(
|
||||||
|
indent,
|
||||||
|
w,
|
||||||
|
"%{} = const {} {}",
|
||||||
|
node,
|
||||||
|
self.intern_pool().display_key(ty),
|
||||||
|
self.intern_pool().display_key(val),
|
||||||
|
)?;
|
||||||
|
}
|
||||||
Inst::ConstantU32 => {
|
Inst::ConstantU32 => {
|
||||||
writeln_indented!(
|
writeln_indented!(
|
||||||
indent,
|
indent,
|
||||||
|
@ -950,7 +981,7 @@ impl IRBuilder<'_, '_, '_> {
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
Inst::ConstantMultiByte => {
|
Inst::ConstantMultiByte => {
|
||||||
let value = self.tree.strings.get_bytes(data.as_index());
|
let value = self.intern_pool().get_bytes(data.as_index());
|
||||||
writeln_indented!(
|
writeln_indented!(
|
||||||
indent,
|
indent,
|
||||||
w,
|
w,
|
||||||
|
@ -1159,8 +1190,9 @@ impl IRBuilder<'_, '_, '_> {
|
||||||
writeln_indented!(
|
writeln_indented!(
|
||||||
indent,
|
indent,
|
||||||
w,
|
w,
|
||||||
"%{node} = extern reference {ty} '{}'",
|
"%{node} = extern ref {} '{}'",
|
||||||
self.tree.strings.get_str(idx)
|
self.intern_pool().display_key(ty),
|
||||||
|
self.intern_pool().get_str(idx)
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
Inst::Branch(condition) => {
|
Inst::Branch(condition) => {
|
||||||
|
@ -1184,7 +1216,7 @@ impl IRBuilder<'_, '_, '_> {
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
Inst::GlobalConstant(name, ty) => {
|
Inst::GlobalConstant(name, ty) => {
|
||||||
let label = self.tree.strings.get_str(name);
|
let label = self.intern_pool().get_str(name);
|
||||||
let value = data.lhs;
|
let value = data.lhs;
|
||||||
writeln_indented!(
|
writeln_indented!(
|
||||||
indent,
|
indent,
|
||||||
|
@ -1207,18 +1239,18 @@ impl IRBuilder<'_, '_, '_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct IRIter<'a, 'b> {
|
struct IRIter<'a> {
|
||||||
ir: &'a IR<'b>,
|
ir: &'a IR,
|
||||||
offset: usize,
|
offset: usize,
|
||||||
item: Option<(Inst, Option<Data>)>,
|
item: Option<(Inst, Option<Data>)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IRIter<'_, '_> {
|
impl IRIter<'_> {
|
||||||
fn node(&self) -> u32 {
|
fn node(&self) -> u32 {
|
||||||
self.offset as Node
|
self.offset as Node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Iterator for IRIter<'_, '_> {
|
impl Iterator for IRIter<'_> {
|
||||||
type Item = (Inst, Option<Data>);
|
type Item = (Inst, Option<Data>);
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
@ -1232,23 +1264,25 @@ impl Iterator for IRIter<'_, '_> {
|
||||||
|
|
||||||
use crate::mir;
|
use crate::mir;
|
||||||
|
|
||||||
pub struct MirBuilder<'a, 'b> {
|
pub struct MirBuilder<'a> {
|
||||||
ir: IRIter<'a, 'b>,
|
ir: IRIter<'a>,
|
||||||
pub strings: StringTable,
|
pub intern_pool: intern::InternPool,
|
||||||
pub functions: HashMap<StringsIndex, mir::Mir>,
|
pub functions: HashMap<intern::Index, mir::Mir>,
|
||||||
pub globals: HashMap<StringsIndex, mir::Mir>,
|
pub globals: HashMap<intern::Index, mir::Mir>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct IrToMirMapping<'a> {
|
struct IrToMirMapping<'a> {
|
||||||
ir: &'a IR<'a>,
|
ir: &'a IR,
|
||||||
mapping: BTreeMap<Node, mir::NodeRef>,
|
mapping: BTreeMap<Node, mir::NodeRef>,
|
||||||
|
ip: &'a intern::InternPool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> IrToMirMapping<'a> {
|
impl<'a> IrToMirMapping<'a> {
|
||||||
fn new(ir: &'a IR) -> Self {
|
fn new(ir: &'a IR, ip: &'a intern::InternPool) -> Self {
|
||||||
Self {
|
Self {
|
||||||
ir,
|
ir,
|
||||||
mapping: BTreeMap::new(),
|
mapping: BTreeMap::new(),
|
||||||
|
ip,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn insert(&mut self, ir: Node, mir: mir::NodeRef) {
|
fn insert(&mut self, ir: Node, mir: mir::NodeRef) {
|
||||||
|
@ -1265,10 +1299,7 @@ impl<'a> IrToMirMapping<'a> {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"does this even get hit anymore???????????????????//"
|
"does this even get hit anymore???????????????????//"
|
||||||
);
|
);
|
||||||
let ty = self
|
let ty = self.ip.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
||||||
.ir
|
|
||||||
.intern_pool
|
|
||||||
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
|
||||||
let ext = mir::NodeRef(mir.gen_extern(Some(ty), name));
|
let ext = mir::NodeRef(mir.gen_extern(Some(ty), name));
|
||||||
self.insert(ir, ext);
|
self.insert(ir, ext);
|
||||||
Some(ext)
|
Some(ext)
|
||||||
|
@ -1278,23 +1309,30 @@ impl<'a> IrToMirMapping<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b> MirBuilder<'a, 'b> {
|
impl<'a> MirBuilder<'a> {
|
||||||
pub fn new(ir: &'a IR<'b>, strings: StringTable) -> MirBuilder<'a, 'b> {
|
pub fn new(ir: &'a IR, intern_pool: intern::InternPool) -> MirBuilder<'a> {
|
||||||
Self {
|
Self {
|
||||||
ir: IRIter {
|
ir: IRIter {
|
||||||
ir,
|
ir,
|
||||||
offset: 0,
|
offset: 0,
|
||||||
item: None,
|
item: None,
|
||||||
},
|
},
|
||||||
strings,
|
intern_pool,
|
||||||
functions: HashMap::new(),
|
functions: HashMap::new(),
|
||||||
globals: HashMap::new(),
|
globals: HashMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_function(&mut self, name: StringsIndex) {
|
fn intern_pool(&self) -> &intern::InternPool {
|
||||||
|
&self.intern_pool
|
||||||
|
}
|
||||||
|
fn intern_pool_mut(&mut self) -> &mut intern::InternPool {
|
||||||
|
&mut self.intern_pool
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_function(&mut self, name: intern::Index) {
|
||||||
let mut mir = mir::Mir::new(name);
|
let mut mir = mir::Mir::new(name);
|
||||||
let mut mapping = IrToMirMapping::new(&self.ir.ir);
|
let mut mapping = IrToMirMapping::new(&self.ir.ir, &self.intern_pool);
|
||||||
// map of label -> unresolved mir jump or branch instruction
|
// map of label -> unresolved mir jump or branch instruction
|
||||||
// stored as a tree of (label, unresolved)
|
// stored as a tree of (label, unresolved)
|
||||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
|
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
|
||||||
|
@ -1371,6 +1409,13 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
|
||||||
|
|
||||||
label
|
label
|
||||||
}
|
}
|
||||||
|
Inst::Constant => {
|
||||||
|
let (ty, val) = data.unwrap().as_index_index();
|
||||||
|
let mir_ty = self
|
||||||
|
.intern_pool()
|
||||||
|
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
||||||
|
mir.push_const(val, mir_ty)
|
||||||
|
}
|
||||||
Inst::ConstantU32 => mir.push(
|
Inst::ConstantU32 => mir.push(
|
||||||
mir::Inst::ConstantDWord,
|
mir::Inst::ConstantDWord,
|
||||||
mir::Data::imm32(data.unwrap().as_u32()),
|
mir::Data::imm32(data.unwrap().as_u32()),
|
||||||
|
@ -1381,7 +1426,7 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
|
||||||
),
|
),
|
||||||
Inst::ConstantMultiByte => {
|
Inst::ConstantMultiByte => {
|
||||||
let bytes =
|
let bytes =
|
||||||
self.strings.get_bytes(data.unwrap().as_index());
|
self.intern_pool().get_bytes(data.unwrap().as_index());
|
||||||
let mut buf = [0u8; 8];
|
let mut buf = [0u8; 8];
|
||||||
match bytes.len() {
|
match bytes.len() {
|
||||||
1 => mir.gen_u8(bytes[0]),
|
1 => mir.gen_u8(bytes[0]),
|
||||||
|
@ -1413,9 +1458,7 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
|
||||||
}
|
}
|
||||||
Inst::Load(ty) => {
|
Inst::Load(ty) => {
|
||||||
let ty = self
|
let ty = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.ir
|
|
||||||
.intern_pool
|
|
||||||
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
||||||
let src = mapping
|
let src = mapping
|
||||||
.get(&mut mir, data.unwrap().as_u32())
|
.get(&mut mir, data.unwrap().as_u32())
|
||||||
|
@ -1425,9 +1468,7 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
|
||||||
}
|
}
|
||||||
Inst::Store(ty) => {
|
Inst::Store(ty) => {
|
||||||
let ty = self
|
let ty = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.ir
|
|
||||||
.intern_pool
|
|
||||||
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
||||||
let (src, dst) = data.unwrap().as_lhs_rhs();
|
let (src, dst) = data.unwrap().as_lhs_rhs();
|
||||||
let src = mapping.get(&mut mir, src).unwrap().0;
|
let src = mapping.get(&mut mir, src).unwrap().0;
|
||||||
|
@ -1436,9 +1477,7 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
|
||||||
}
|
}
|
||||||
Inst::GetElementPtr(ty) => {
|
Inst::GetElementPtr(ty) => {
|
||||||
let ty = self
|
let ty = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.ir
|
|
||||||
.intern_pool
|
|
||||||
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
||||||
let (ptr, idx) = data.unwrap().as_lhs_rhs();
|
let (ptr, idx) = data.unwrap().as_lhs_rhs();
|
||||||
let src = mapping.get(&mut mir, ptr).unwrap().0;
|
let src = mapping.get(&mut mir, ptr).unwrap().0;
|
||||||
|
@ -1447,9 +1486,7 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
|
||||||
Inst::Parameter(ty) => {
|
Inst::Parameter(ty) => {
|
||||||
// let (size, _) = data.unwrap().as_lhs_rhs();
|
// let (size, _) = data.unwrap().as_lhs_rhs();
|
||||||
let ty = self
|
let ty = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.ir
|
|
||||||
.intern_pool
|
|
||||||
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
||||||
mir.gen_param(ty.into())
|
mir.gen_param(ty.into())
|
||||||
}
|
}
|
||||||
|
@ -1475,14 +1512,10 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let signed = self
|
let signed = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.ir
|
|
||||||
.intern_pool
|
|
||||||
.is_type_signed(ty, AMD64_POINTER_TYPE_INFO);
|
.is_type_signed(ty, AMD64_POINTER_TYPE_INFO);
|
||||||
let mir_ty = self
|
let mir_ty = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.ir
|
|
||||||
.intern_pool
|
|
||||||
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
||||||
mir.gen_cmp_byte(mir_ty, signed, ord, invert, lhs, rhs)
|
mir.gen_cmp_byte(mir_ty, signed, ord, invert, lhs, rhs)
|
||||||
}
|
}
|
||||||
|
@ -1492,14 +1525,10 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
|
||||||
let rhs = mapping.get(&mut mir, dst).unwrap().0;
|
let rhs = mapping.get(&mut mir, dst).unwrap().0;
|
||||||
|
|
||||||
let info = self
|
let info = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.ir
|
|
||||||
.intern_pool
|
|
||||||
.size_of_type(ty, AMD64_POINTER_TYPE_INFO);
|
.size_of_type(ty, AMD64_POINTER_TYPE_INFO);
|
||||||
let ty = self
|
let ty = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.ir
|
|
||||||
.intern_pool
|
|
||||||
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
||||||
|
|
||||||
match info.bitsize {
|
match info.bitsize {
|
||||||
|
@ -1524,14 +1553,10 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
|
||||||
let rhs = mapping.get(&mut mir, dst).unwrap().0;
|
let rhs = mapping.get(&mut mir, dst).unwrap().0;
|
||||||
|
|
||||||
let info = self
|
let info = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.ir
|
|
||||||
.intern_pool
|
|
||||||
.size_of_type(ty, AMD64_POINTER_TYPE_INFO);
|
.size_of_type(ty, AMD64_POINTER_TYPE_INFO);
|
||||||
let ty = self
|
let ty = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.ir
|
|
||||||
.intern_pool
|
|
||||||
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
||||||
let unalignment =
|
let unalignment =
|
||||||
mir_unalignment(info.signed, info.bitsize);
|
mir_unalignment(info.signed, info.bitsize);
|
||||||
|
@ -1547,14 +1572,10 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
|
||||||
let (lhs, rhs) = data.unwrap().as_lhs_rhs();
|
let (lhs, rhs) = data.unwrap().as_lhs_rhs();
|
||||||
|
|
||||||
let info = self
|
let info = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.ir
|
|
||||||
.intern_pool
|
|
||||||
.size_of_type(ty, AMD64_POINTER_TYPE_INFO);
|
.size_of_type(ty, AMD64_POINTER_TYPE_INFO);
|
||||||
let ty = self
|
let ty = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.ir
|
|
||||||
.intern_pool
|
|
||||||
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
||||||
let unalignment =
|
let unalignment =
|
||||||
mir_unalignment(info.signed, info.bitsize);
|
mir_unalignment(info.signed, info.bitsize);
|
||||||
|
@ -1573,14 +1594,10 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
|
||||||
let (lhs, rhs) = data.unwrap().as_lhs_rhs();
|
let (lhs, rhs) = data.unwrap().as_lhs_rhs();
|
||||||
|
|
||||||
let info = self
|
let info = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.ir
|
|
||||||
.intern_pool
|
|
||||||
.size_of_type(ty, AMD64_POINTER_TYPE_INFO);
|
.size_of_type(ty, AMD64_POINTER_TYPE_INFO);
|
||||||
let ty = self
|
let ty = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.ir
|
|
||||||
.intern_pool
|
|
||||||
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
||||||
let unalignment =
|
let unalignment =
|
||||||
mir_unalignment(info.signed, info.bitsize);
|
mir_unalignment(info.signed, info.bitsize);
|
||||||
|
@ -1599,14 +1616,10 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
|
||||||
let (lhs, rhs) = data.unwrap().as_lhs_rhs();
|
let (lhs, rhs) = data.unwrap().as_lhs_rhs();
|
||||||
|
|
||||||
let info = self
|
let info = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.ir
|
|
||||||
.intern_pool
|
|
||||||
.size_of_type(ty, AMD64_POINTER_TYPE_INFO);
|
.size_of_type(ty, AMD64_POINTER_TYPE_INFO);
|
||||||
let ty = self
|
let ty = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.ir
|
|
||||||
.intern_pool
|
|
||||||
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
||||||
let unalignment =
|
let unalignment =
|
||||||
mir_unalignment(info.signed, info.bitsize);
|
mir_unalignment(info.signed, info.bitsize);
|
||||||
|
@ -1625,14 +1638,10 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
|
||||||
let (lhs, rhs) = data.unwrap().as_lhs_rhs();
|
let (lhs, rhs) = data.unwrap().as_lhs_rhs();
|
||||||
|
|
||||||
let info = self
|
let info = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.ir
|
|
||||||
.intern_pool
|
|
||||||
.size_of_type(ty, AMD64_POINTER_TYPE_INFO);
|
.size_of_type(ty, AMD64_POINTER_TYPE_INFO);
|
||||||
let ty = self
|
let ty = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.ir
|
|
||||||
.intern_pool
|
|
||||||
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
||||||
let unalignment =
|
let unalignment =
|
||||||
mir_unalignment(info.signed, info.bitsize);
|
mir_unalignment(info.signed, info.bitsize);
|
||||||
|
@ -1658,14 +1667,10 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
|
||||||
let (lhs, rhs) = data.unwrap().as_lhs_rhs();
|
let (lhs, rhs) = data.unwrap().as_lhs_rhs();
|
||||||
|
|
||||||
let info = self
|
let info = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.ir
|
|
||||||
.intern_pool
|
|
||||||
.size_of_type(ty, AMD64_POINTER_TYPE_INFO);
|
.size_of_type(ty, AMD64_POINTER_TYPE_INFO);
|
||||||
let ty = self
|
let ty = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.ir
|
|
||||||
.intern_pool
|
|
||||||
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
||||||
let unalignment =
|
let unalignment =
|
||||||
mir_unalignment(info.signed, info.bitsize);
|
mir_unalignment(info.signed, info.bitsize);
|
||||||
|
@ -1701,14 +1706,10 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
|
||||||
let rhs = mapping.get(&mut mir, rhs).unwrap().0;
|
let rhs = mapping.get(&mut mir, rhs).unwrap().0;
|
||||||
|
|
||||||
let info = self
|
let info = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.ir
|
|
||||||
.intern_pool
|
|
||||||
.size_of_type(ty, AMD64_POINTER_TYPE_INFO);
|
.size_of_type(ty, AMD64_POINTER_TYPE_INFO);
|
||||||
let ty = self
|
let ty = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.ir
|
|
||||||
.intern_pool
|
|
||||||
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
||||||
let unalignment =
|
let unalignment =
|
||||||
mir_unalignment(info.signed, info.bitsize);
|
mir_unalignment(info.signed, info.bitsize);
|
||||||
|
@ -1726,14 +1727,10 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
|
||||||
let rhs = mapping.get(&mut mir, dst).unwrap().0;
|
let rhs = mapping.get(&mut mir, dst).unwrap().0;
|
||||||
|
|
||||||
let info = self
|
let info = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.ir
|
|
||||||
.intern_pool
|
|
||||||
.size_of_type(ty, AMD64_POINTER_TYPE_INFO);
|
.size_of_type(ty, AMD64_POINTER_TYPE_INFO);
|
||||||
let ty = self
|
let ty = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.ir
|
|
||||||
.intern_pool
|
|
||||||
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
||||||
let unalignment =
|
let unalignment =
|
||||||
mir_unalignment(info.signed, info.bitsize);
|
mir_unalignment(info.signed, info.bitsize);
|
||||||
|
@ -1755,14 +1752,10 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
|
||||||
let rhs = mapping.get(&mut mir, dst).unwrap().0;
|
let rhs = mapping.get(&mut mir, dst).unwrap().0;
|
||||||
|
|
||||||
let info = self
|
let info = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.ir
|
|
||||||
.intern_pool
|
|
||||||
.size_of_type(ty, AMD64_POINTER_TYPE_INFO);
|
.size_of_type(ty, AMD64_POINTER_TYPE_INFO);
|
||||||
let ty = self
|
let ty = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.ir
|
|
||||||
.intern_pool
|
|
||||||
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
||||||
let unalignment =
|
let unalignment =
|
||||||
mir_unalignment(info.signed, info.bitsize);
|
mir_unalignment(info.signed, info.bitsize);
|
||||||
|
@ -1783,14 +1776,10 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
|
||||||
let lhs = mapping.get(&mut mir, lhs).unwrap().0;
|
let lhs = mapping.get(&mut mir, lhs).unwrap().0;
|
||||||
|
|
||||||
let info = self
|
let info = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.ir
|
|
||||||
.intern_pool
|
|
||||||
.size_of_type(ty, AMD64_POINTER_TYPE_INFO);
|
.size_of_type(ty, AMD64_POINTER_TYPE_INFO);
|
||||||
let ty = self
|
let ty = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.ir
|
|
||||||
.intern_pool
|
|
||||||
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
||||||
let unalignment =
|
let unalignment =
|
||||||
mir_unalignment(info.signed, info.bitsize);
|
mir_unalignment(info.signed, info.bitsize);
|
||||||
|
@ -1807,14 +1796,10 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
|
||||||
let lhs = mapping.get(&mut mir, lhs).unwrap().0;
|
let lhs = mapping.get(&mut mir, lhs).unwrap().0;
|
||||||
|
|
||||||
let info = self
|
let info = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.ir
|
|
||||||
.intern_pool
|
|
||||||
.size_of_type(ty, AMD64_POINTER_TYPE_INFO);
|
.size_of_type(ty, AMD64_POINTER_TYPE_INFO);
|
||||||
let ty = self
|
let ty = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.ir
|
|
||||||
.intern_pool
|
|
||||||
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
||||||
let unalignment =
|
let unalignment =
|
||||||
mir_unalignment(info.signed, info.bitsize);
|
mir_unalignment(info.signed, info.bitsize);
|
||||||
|
@ -1831,27 +1816,19 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
|
||||||
let lhs = mapping.get(&mut mir, lhs).unwrap().0;
|
let lhs = mapping.get(&mut mir, lhs).unwrap().0;
|
||||||
|
|
||||||
let to_info = self
|
let to_info = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.ir
|
|
||||||
.intern_pool
|
|
||||||
.size_of_type(to, AMD64_POINTER_TYPE_INFO);
|
.size_of_type(to, AMD64_POINTER_TYPE_INFO);
|
||||||
let to_ty = self
|
let to_ty = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.ir
|
|
||||||
.intern_pool
|
|
||||||
.to_mir_type(to, AMD64_POINTER_TYPE_INFO);
|
.to_mir_type(to, AMD64_POINTER_TYPE_INFO);
|
||||||
let to_unalignment =
|
let to_unalignment =
|
||||||
mir_unalignment(to_info.signed, to_info.bitsize);
|
mir_unalignment(to_info.signed, to_info.bitsize);
|
||||||
|
|
||||||
let from_info = self
|
let from_info = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.ir
|
|
||||||
.intern_pool
|
|
||||||
.size_of_type(from, AMD64_POINTER_TYPE_INFO);
|
.size_of_type(from, AMD64_POINTER_TYPE_INFO);
|
||||||
let from_ty = self
|
let from_ty = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.ir
|
|
||||||
.intern_pool
|
|
||||||
.to_mir_type(from, AMD64_POINTER_TYPE_INFO);
|
.to_mir_type(from, AMD64_POINTER_TYPE_INFO);
|
||||||
let from_unalignment =
|
let from_unalignment =
|
||||||
mir_unalignment(from_info.signed, from_info.bitsize);
|
mir_unalignment(from_info.signed, from_info.bitsize);
|
||||||
|
@ -1890,9 +1867,7 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
|
||||||
let src = mapping.get(&mut mir, src).unwrap().0;
|
let src = mapping.get(&mut mir, src).unwrap().0;
|
||||||
|
|
||||||
let ty = self
|
let ty = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.ir
|
|
||||||
.intern_pool
|
|
||||||
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
||||||
|
|
||||||
mir.gen_ret_val(ty, src)
|
mir.gen_ret_val(ty, src)
|
||||||
|
@ -1963,18 +1938,14 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
|
||||||
|
|
||||||
variant!(&ir.nodes[end as usize -1] => Inst::InlineType(ty));
|
variant!(&ir.nodes[end as usize -1] => Inst::InlineType(ty));
|
||||||
let ty = self
|
let ty = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.ir
|
|
||||||
.intern_pool
|
|
||||||
.to_mir_type(*ty, AMD64_POINTER_TYPE_INFO);
|
.to_mir_type(*ty, AMD64_POINTER_TYPE_INFO);
|
||||||
|
|
||||||
let args = (start..(end - 1))
|
let args = (start..(end - 1))
|
||||||
.map(|arg| {
|
.map(|arg| {
|
||||||
variant!(&ir.nodes[arg as usize] => Inst::Argument(ty));
|
variant!(&ir.nodes[arg as usize] => Inst::Argument(ty));
|
||||||
let ty = self
|
let ty = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.ir
|
|
||||||
.intern_pool
|
|
||||||
.to_mir_type(*ty, AMD64_POINTER_TYPE_INFO);
|
.to_mir_type(*ty, AMD64_POINTER_TYPE_INFO);
|
||||||
let arg = ir.data[arg as usize].unwrap().lhs;
|
let arg = ir.data[arg as usize].unwrap().lhs;
|
||||||
let arg = mapping.get(&mut mir, arg).unwrap().0;
|
let arg = mapping.get(&mut mir, arg).unwrap().0;
|
||||||
|
@ -1989,18 +1960,14 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
|
||||||
let lhs = mapping.get(&mut mir, src).unwrap().0;
|
let lhs = mapping.get(&mut mir, src).unwrap().0;
|
||||||
let rhs = mapping.get(&mut mir, dst).unwrap().0;
|
let rhs = mapping.get(&mut mir, dst).unwrap().0;
|
||||||
let ty = self
|
let ty = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.ir
|
|
||||||
.intern_pool
|
|
||||||
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
||||||
|
|
||||||
mir.gen_phi2(ty, lhs, rhs)
|
mir.gen_phi2(ty, lhs, rhs)
|
||||||
}
|
}
|
||||||
Inst::GlobalConstant(name, ty) => {
|
Inst::GlobalConstant(name, ty) => {
|
||||||
let ty = self
|
let ty = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.ir
|
|
||||||
.intern_pool
|
|
||||||
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
||||||
let ext = mir.gen_extern(Some(ty), name);
|
let ext = mir.gen_extern(Some(ty), name);
|
||||||
|
|
||||||
|
@ -2011,9 +1978,7 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
|
||||||
}
|
}
|
||||||
Inst::ExternRef(ty) => {
|
Inst::ExternRef(ty) => {
|
||||||
let ty = self
|
let ty = self
|
||||||
.ir
|
.intern_pool()
|
||||||
.ir
|
|
||||||
.intern_pool
|
|
||||||
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
||||||
mir.gen_extern(Some(ty), data.unwrap().as_index())
|
mir.gen_extern(Some(ty), data.unwrap().as_index())
|
||||||
}
|
}
|
||||||
|
@ -2047,6 +2012,13 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
|
||||||
let data = self.ir.ir.data[value as usize];
|
let data = self.ir.ir.data[value as usize];
|
||||||
let inst = self.ir.ir.nodes[value as usize];
|
let inst = self.ir.ir.nodes[value as usize];
|
||||||
let _value = match inst {
|
let _value = match inst {
|
||||||
|
Inst::Constant => {
|
||||||
|
let (ty, val) = data.unwrap().as_index_index();
|
||||||
|
let mir_ty = self
|
||||||
|
.intern_pool()
|
||||||
|
.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
|
||||||
|
mir.push_const(val, mir_ty)
|
||||||
|
}
|
||||||
Inst::ConstantU32 => mir.push(
|
Inst::ConstantU32 => mir.push(
|
||||||
mir::Inst::ConstantDWord,
|
mir::Inst::ConstantDWord,
|
||||||
mir::Data::imm32(data.unwrap().as_u32()),
|
mir::Data::imm32(data.unwrap().as_u32()),
|
||||||
|
@ -2057,7 +2029,7 @@ impl<'a, 'b> MirBuilder<'a, 'b> {
|
||||||
),
|
),
|
||||||
Inst::ConstantMultiByte => {
|
Inst::ConstantMultiByte => {
|
||||||
let bytes = self
|
let bytes = self
|
||||||
.strings
|
.intern_pool()
|
||||||
.get_bytes(data.unwrap().as_index());
|
.get_bytes(data.unwrap().as_index());
|
||||||
let mut buf = [0u8; 8];
|
let mut buf = [0u8; 8];
|
||||||
match bytes.len() {
|
match bytes.len() {
|
||||||
|
@ -2121,7 +2093,7 @@ fn u10(x: i10) -> i10 {
|
||||||
println!("AST:\n{buf}");
|
println!("AST:\n{buf}");
|
||||||
|
|
||||||
let mut intern = InternPool::new();
|
let mut intern = InternPool::new();
|
||||||
let mut ir = IR::new(&mut intern);
|
let mut ir = IR::new();
|
||||||
{
|
{
|
||||||
let builder = ir.build(&mut tree);
|
let builder = ir.build(&mut tree);
|
||||||
let mut buf = String::new();
|
let mut buf = String::new();
|
||||||
|
@ -2129,7 +2101,7 @@ fn u10(x: i10) -> i10 {
|
||||||
println!("IR:\n{buf}");
|
println!("IR:\n{buf}");
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut mir = MirBuilder::new(&ir, tree.strings);
|
let mut mir = MirBuilder::new(&ir, tree.intern_pool);
|
||||||
mir.build();
|
mir.build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,4 +2,4 @@ fn main() -> i32 {
|
||||||
return RANDOM;
|
return RANDOM;
|
||||||
}
|
}
|
||||||
|
|
||||||
const RANDOM: i32 = 4 + (1 << 3);
|
const RANDOM: i32 = 4i32 + (1i32 << 3i32);
|
||||||
|
|
Loading…
Reference in a new issue