forked from AbleOS/holey-bytes
removing old compiler
This commit is contained in:
parent
ce7bb001da
commit
b187af64a8
|
@ -14,7 +14,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gen_instrs(generated: &mut String) -> Result<(), Box<dyn std::error::Error>> {
|
fn gen_instrs(generated: &mut String) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
writeln!(generated, "#![allow(dead_code)] #![allow(clippy::upper_case_acronyms)]")?;
|
writeln!(generated, "#![expect(dead_code)]")?;
|
||||||
writeln!(generated, "use crate::*;")?;
|
writeln!(generated, "use crate::*;")?;
|
||||||
|
|
||||||
'_opcode_structs: {
|
'_opcode_structs: {
|
||||||
|
|
|
@ -665,7 +665,6 @@ mod db {
|
||||||
($vis:vis struct $name:ident {
|
($vis:vis struct $name:ident {
|
||||||
$($qname:ident: $code:expr,)*
|
$($qname:ident: $code:expr,)*
|
||||||
}) => {
|
}) => {
|
||||||
#[allow(dead_code)]
|
|
||||||
$vis struct $name<'a> {
|
$vis struct $name<'a> {
|
||||||
$($vis $qname: rusqlite::Statement<'a>,)*
|
$($vis $qname: rusqlite::Statement<'a>,)*
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,10 @@
|
||||||
|
|
||||||
use {
|
use {
|
||||||
alloc::{string::String, vec::Vec},
|
alloc::{string::String, vec::Vec},
|
||||||
hblang::{codegen::Codegen, parser::FileId},
|
hblang::{
|
||||||
|
parser::FileId,
|
||||||
|
son::{Codegen, CodegenCtx},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
@ -74,8 +77,8 @@ unsafe fn compile_and_run(mut fuel: usize) {
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut ct = {
|
let mut ct = {
|
||||||
let mut c = Codegen::default();
|
let mut ctx = CodegenCtx::default();
|
||||||
c.files = files;
|
let mut c = Codegen::new(&files, &mut ctx);
|
||||||
c.generate(root as FileId);
|
c.generate(root as FileId);
|
||||||
c.assemble_comptime()
|
c.assemble_comptime()
|
||||||
};
|
};
|
||||||
|
|
|
@ -104,7 +104,7 @@ pub struct ArenaAllocator<const SIZE: usize> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<const SIZE: usize> ArenaAllocator<SIZE> {
|
impl<const SIZE: usize> ArenaAllocator<SIZE> {
|
||||||
#[allow(clippy::new_without_default)]
|
#[expect(clippy::new_without_default)]
|
||||||
pub const fn new() -> Self {
|
pub const fn new() -> Self {
|
||||||
ArenaAllocator {
|
ArenaAllocator {
|
||||||
arena: UnsafeCell::new([0; SIZE]),
|
arena: UnsafeCell::new([0; SIZE]),
|
||||||
|
@ -112,7 +112,7 @@ impl<const SIZE: usize> ArenaAllocator<SIZE> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::missing_safety_doc)]
|
#[expect(clippy::missing_safety_doc)]
|
||||||
pub unsafe fn reset(&self) {
|
pub unsafe fn reset(&self) {
|
||||||
(*self.head.get()) = self.arena.get().cast::<u8>().add(SIZE);
|
(*self.head.get()) = self.arena.get().cast::<u8>().add(SIZE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,11 +20,9 @@ log = "0.4.22"
|
||||||
[dependencies.regalloc2]
|
[dependencies.regalloc2]
|
||||||
git = "https://github.com/jakubDoka/regalloc2"
|
git = "https://github.com/jakubDoka/regalloc2"
|
||||||
branch = "reuse-allocations"
|
branch = "reuse-allocations"
|
||||||
optional = true
|
|
||||||
features = ["trace-log"]
|
features = ["trace-log"]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["std", "opts"]
|
default = ["std"]
|
||||||
std = []
|
std = []
|
||||||
opts = ["regalloc2"]
|
|
||||||
no_log = ["log/max_level_off"]
|
no_log = ["log/max_level_off"]
|
||||||
|
|
2729
lang/src/codegen.rs
2729
lang/src/codegen.rs
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,5 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
ident,
|
|
||||||
lexer::{self, Lexer, TokenKind},
|
lexer::{self, Lexer, TokenKind},
|
||||||
parser::{self, CommentOr, CtorField, Expr, Poser, Radix, StructField},
|
parser::{self, CommentOr, CtorField, Expr, Poser, Radix, StructField},
|
||||||
},
|
},
|
||||||
|
@ -256,7 +255,7 @@ impl<'a> Formatter<'a> {
|
||||||
fields,
|
fields,
|
||||||
|s: &mut Self, CtorField { name, value, .. }: &_, f| {
|
|s: &mut Self, CtorField { name, value, .. }: &_, f| {
|
||||||
f.write_str(name)?;
|
f.write_str(name)?;
|
||||||
if !matches!(value, &Expr::Ident { id, .. } if *name == &self.source[ident::range(id)]) {
|
if !matches!(value, &Expr::Ident { id, .. } if *name == &self.source[id.range()]) {
|
||||||
f.write_str(": ")?;
|
f.write_str(": ")?;
|
||||||
s.fmt(value, f)?;
|
s.fmt(value, f)?;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
codegen,
|
|
||||||
parser::{self, Ast, Ctx, FileKind},
|
parser::{self, Ast, Ctx, FileKind},
|
||||||
son,
|
son,
|
||||||
},
|
},
|
||||||
|
@ -39,6 +38,7 @@ pub struct Options {
|
||||||
pub fmt: bool,
|
pub fmt: bool,
|
||||||
pub fmt_stdout: bool,
|
pub fmt_stdout: bool,
|
||||||
pub dump_asm: bool,
|
pub dump_asm: bool,
|
||||||
|
#[deprecated = "no longer has any effect"]
|
||||||
pub optimize: bool,
|
pub optimize: bool,
|
||||||
pub extra_threads: usize,
|
pub extra_threads: usize,
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,6 @@ impl Options {
|
||||||
|
|
||||||
Ok(Options {
|
Ok(Options {
|
||||||
fmt: args.contains(&"--fmt"),
|
fmt: args.contains(&"--fmt"),
|
||||||
optimize: args.contains(&"--optimize"),
|
|
||||||
fmt_stdout: args.contains(&"--fmt-stdout"),
|
fmt_stdout: args.contains(&"--fmt-stdout"),
|
||||||
dump_asm: args.contains(&"--dump-asm"),
|
dump_asm: args.contains(&"--dump-asm"),
|
||||||
extra_threads: args
|
extra_threads: args
|
||||||
|
@ -67,6 +66,7 @@ impl Options {
|
||||||
.transpose()?
|
.transpose()?
|
||||||
.map_or(1, NonZeroUsize::get)
|
.map_or(1, NonZeroUsize::get)
|
||||||
- 1,
|
- 1,
|
||||||
|
..Default::default()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,11 +81,6 @@ pub fn run_compiler(root_file: &str, options: Options, out: &mut Vec<u8>) -> std
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
if !options.optimize && !parsed.errors.is_empty() {
|
|
||||||
log::error!("{}", parsed.errors);
|
|
||||||
return Err(std::io::Error::other("parsing failed"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if options.fmt {
|
if options.fmt {
|
||||||
for parsed in parsed.ast {
|
for parsed in parsed.ast {
|
||||||
format_ast(parsed)?;
|
format_ast(parsed)?;
|
||||||
|
@ -93,7 +88,7 @@ pub fn run_compiler(root_file: &str, options: Options, out: &mut Vec<u8>) -> std
|
||||||
} else if options.fmt_stdout {
|
} else if options.fmt_stdout {
|
||||||
let ast = parsed.ast.into_iter().next().unwrap();
|
let ast = parsed.ast.into_iter().next().unwrap();
|
||||||
write!(out, "{ast}").unwrap();
|
write!(out, "{ast}").unwrap();
|
||||||
} else if options.optimize {
|
} else {
|
||||||
let mut ctx = crate::son::CodegenCtx::default();
|
let mut ctx = crate::son::CodegenCtx::default();
|
||||||
*ctx.parser.errors.get_mut() = parsed.errors;
|
*ctx.parser.errors.get_mut() = parsed.errors;
|
||||||
let mut codegen = son::Codegen::new(&parsed.ast, &mut ctx);
|
let mut codegen = son::Codegen::new(&parsed.ast, &mut ctx);
|
||||||
|
@ -106,19 +101,6 @@ pub fn run_compiler(root_file: &str, options: Options, out: &mut Vec<u8>) -> std
|
||||||
return Err(std::io::Error::other("compilation faoled"));
|
return Err(std::io::Error::other("compilation faoled"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if options.dump_asm {
|
|
||||||
codegen
|
|
||||||
.disasm(unsafe { std::mem::transmute::<&mut Vec<u8>, &mut String>(out) })
|
|
||||||
.map_err(|e| io::Error::other(e.to_string()))?;
|
|
||||||
} else {
|
|
||||||
codegen.assemble(out);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let mut codegen = codegen::Codegen::default();
|
|
||||||
codegen.files = parsed.ast;
|
|
||||||
codegen.push_embeds(parsed.embeds);
|
|
||||||
|
|
||||||
codegen.generate(0);
|
|
||||||
if options.dump_asm {
|
if options.dump_asm {
|
||||||
codegen
|
codegen
|
||||||
.disasm(unsafe { std::mem::transmute::<&mut Vec<u8>, &mut String>(out) })
|
.disasm(unsafe { std::mem::transmute::<&mut Vec<u8>, &mut String>(out) })
|
||||||
|
|
|
@ -4,8 +4,8 @@ use {
|
||||||
parser,
|
parser,
|
||||||
son::{Codegen, CodegenCtx},
|
son::{Codegen, CodegenCtx},
|
||||||
},
|
},
|
||||||
|
alloc::string::String,
|
||||||
core::{fmt::Write, hash::BuildHasher, ops::Range},
|
core::{fmt::Write, hash::BuildHasher, ops::Range},
|
||||||
std::string::String,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
|
|
@ -178,7 +178,7 @@ impl core::fmt::Debug for TokenKind {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TokenKind {
|
impl TokenKind {
|
||||||
#[allow(clippy::type_complexity)]
|
#[expect(clippy::type_complexity)]
|
||||||
pub fn cond_op(self, signed: bool) -> Option<(fn(u8, u8, i16) -> EncodedInstr, bool)> {
|
pub fn cond_op(self, signed: bool) -> Option<(fn(u8, u8, i16) -> EncodedInstr, bool)> {
|
||||||
use crate::instrs;
|
use crate::instrs;
|
||||||
Some((
|
Some((
|
||||||
|
@ -225,7 +225,6 @@ impl TokenKind {
|
||||||
Some(ops[size.ilog2() as usize])
|
Some(ops[size.ilog2() as usize])
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::type_complexity)]
|
|
||||||
pub fn imm_binop(self, signed: bool, size: u32) -> Option<fn(u8, u8, u64) -> EncodedInstr> {
|
pub fn imm_binop(self, signed: bool, size: u32) -> Option<fn(u8, u8, u64) -> EncodedInstr> {
|
||||||
use crate::instrs::*;
|
use crate::instrs::*;
|
||||||
macro_rules! def_op {
|
macro_rules! def_op {
|
||||||
|
|
125
lang/src/lib.rs
125
lang/src/lib.rs
|
@ -22,18 +22,17 @@
|
||||||
ptr_sub_ptr,
|
ptr_sub_ptr,
|
||||||
slice_from_ptr_range,
|
slice_from_ptr_range,
|
||||||
is_sorted,
|
is_sorted,
|
||||||
iter_next_chunk
|
iter_next_chunk,
|
||||||
|
pointer_is_aligned_to
|
||||||
)]
|
)]
|
||||||
#![feature(pointer_is_aligned_to)]
|
|
||||||
#![warn(clippy::dbg_macro)]
|
#![warn(clippy::dbg_macro)]
|
||||||
#![allow(stable_features, internal_features)]
|
#![expect(stable_features, internal_features)]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub use fs::*;
|
pub use fs::*;
|
||||||
use {
|
use {
|
||||||
self::{
|
self::{
|
||||||
ident::Ident,
|
|
||||||
lexer::TokenKind,
|
lexer::TokenKind,
|
||||||
parser::{idfl, CommentOr, Expr, ExprRef, FileId, Pos},
|
parser::{idfl, CommentOr, Expr, ExprRef, FileId, Pos},
|
||||||
ty::ArrayLen,
|
ty::ArrayLen,
|
||||||
|
@ -63,22 +62,17 @@ macro_rules! run_tests {
|
||||||
)*};
|
)*};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod codegen;
|
|
||||||
pub mod fmt;
|
pub mod fmt;
|
||||||
#[cfg(any(feature = "std", test))]
|
#[cfg(any(feature = "std", test))]
|
||||||
pub mod fs;
|
pub mod fs;
|
||||||
|
pub mod fuzz;
|
||||||
|
pub mod lexer;
|
||||||
pub mod parser;
|
pub mod parser;
|
||||||
#[cfg(feature = "opts")]
|
|
||||||
pub mod son;
|
pub mod son;
|
||||||
|
|
||||||
pub mod lexer;
|
|
||||||
#[cfg(feature = "opts")]
|
|
||||||
mod vc;
|
mod vc;
|
||||||
|
|
||||||
pub mod fuzz;
|
|
||||||
|
|
||||||
mod debug {
|
mod debug {
|
||||||
|
|
||||||
pub fn panicking() -> bool {
|
pub fn panicking() -> bool {
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
{
|
{
|
||||||
|
@ -185,12 +179,10 @@ mod ctx_map {
|
||||||
.map(|(k, _)| &k.value)
|
.map(|(k, _)| &k.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(not(feature = "opts"), expect(dead_code))]
|
|
||||||
pub fn clear(&mut self) {
|
pub fn clear(&mut self) {
|
||||||
self.inner.clear();
|
self.inner.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(not(feature = "opts"), expect(dead_code))]
|
|
||||||
pub fn remove(&mut self, value: &T, ctx: &T::Ctx) -> Option<T> {
|
pub fn remove(&mut self, value: &T, ctx: &T::Ctx) -> Option<T> {
|
||||||
let (entry, _) = self.entry(value.key(ctx), ctx);
|
let (entry, _) = self.entry(value.key(ctx), ctx);
|
||||||
match entry {
|
match entry {
|
||||||
|
@ -241,46 +233,55 @@ mod task {
|
||||||
unpack(offset).is_ok()
|
unpack(offset).is_ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(not(feature = "opts"), expect(dead_code))]
|
|
||||||
pub fn id(index: usize) -> Offset {
|
pub fn id(index: usize) -> Offset {
|
||||||
1 << 31 | index as u32
|
1 << 31 | index as u32
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mod ident {
|
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default, Debug)]
|
||||||
pub type Ident = u32;
|
pub struct Ident(u32);
|
||||||
|
|
||||||
|
impl Ident {
|
||||||
|
pub const INVALID: Self = Self(u32::MAX);
|
||||||
const LEN_BITS: u32 = 6;
|
const LEN_BITS: u32 = 6;
|
||||||
|
|
||||||
pub fn len(ident: u32) -> u32 {
|
pub fn len(self) -> u32 {
|
||||||
ident & ((1 << LEN_BITS) - 1)
|
self.0 & ((1 << Self::LEN_BITS) - 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_null(ident: u32) -> bool {
|
pub fn is_empty(self) -> bool {
|
||||||
(ident >> LEN_BITS) == 0
|
self.len() == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pos(ident: u32) -> u32 {
|
pub fn is_null(self) -> bool {
|
||||||
(ident >> LEN_BITS).saturating_sub(1)
|
(self.0 >> Self::LEN_BITS) == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(pos: u32, len: u32) -> Option<u32> {
|
pub fn pos(self) -> u32 {
|
||||||
(len < (1 << LEN_BITS)).then_some(((pos + 1) << LEN_BITS) | len)
|
(self.0 >> Self::LEN_BITS).saturating_sub(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn range(ident: u32) -> core::ops::Range<usize> {
|
pub fn new(pos: u32, len: u32) -> Option<Self> {
|
||||||
let (len, pos) = (len(ident) as usize, pos(ident) as usize);
|
(len < (1 << Self::LEN_BITS)).then_some(((pos + 1) << Self::LEN_BITS) | len).map(Self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn range(self) -> core::ops::Range<usize> {
|
||||||
|
let (len, pos) = (self.len() as usize, self.pos() as usize);
|
||||||
pos..pos + len
|
pos..pos + len
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn builtin(builtin: u32) -> Ident {
|
||||||
|
debug_assert!(Self(builtin).is_null());
|
||||||
|
Self(builtin)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mod ty {
|
mod ty {
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
ident,
|
|
||||||
lexer::TokenKind,
|
lexer::TokenKind,
|
||||||
parser::{self, Pos},
|
parser::{self, FileId, Pos},
|
||||||
Size, Types,
|
Ident, Size, Types,
|
||||||
},
|
},
|
||||||
core::{num::NonZeroU32, ops::Range},
|
core::{num::NonZeroU32, ops::Range},
|
||||||
};
|
};
|
||||||
|
@ -385,7 +386,9 @@ mod ty {
|
||||||
crate::SymKey::Decl(gb.file, gb.name)
|
crate::SymKey::Decl(gb.file, gb.name)
|
||||||
}
|
}
|
||||||
Kind::Slice(s) => crate::SymKey::Array(&ctx.slices[s as usize]),
|
Kind::Slice(s) => crate::SymKey::Array(&ctx.slices[s as usize]),
|
||||||
Kind::Module(_) | Kind::Builtin(_) => crate::SymKey::Decl(u32::MAX, u32::MAX),
|
Kind::Module(_) | Kind::Builtin(_) => {
|
||||||
|
crate::SymKey::Decl(FileId::MAX, Ident::INVALID)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -399,16 +402,24 @@ mod ty {
|
||||||
impl Id {
|
impl Id {
|
||||||
pub const DEFAULT_INT: Self = Self::UINT;
|
pub const DEFAULT_INT: Self = Self::UINT;
|
||||||
|
|
||||||
|
pub fn bin_ret(self, op: TokenKind) -> Id {
|
||||||
|
use TokenKind as T;
|
||||||
|
match op {
|
||||||
|
T::Lt | T::Gt | T::Le | T::Ge | T::Ne | T::Eq => BOOL.into(),
|
||||||
|
_ => self,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn is_signed(self) -> bool {
|
pub fn is_signed(self) -> bool {
|
||||||
(I8..=INT).contains(&self.repr()) || self.is_never()
|
matches!(self.repr(), I8..=INT) || self.is_never()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_unsigned(self) -> bool {
|
pub fn is_unsigned(self) -> bool {
|
||||||
(U8..=UINT).contains(&self.repr()) || self.is_never()
|
matches!(self.repr(), U8..=UINT) || self.is_never()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_integer(self) -> bool {
|
pub fn is_integer(self) -> bool {
|
||||||
(U8..=INT).contains(&self.repr()) || self.is_never()
|
matches!(self.repr(), U8..=INT) || self.is_never()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_never(self) -> bool {
|
pub fn is_never(self) -> bool {
|
||||||
|
@ -426,7 +437,7 @@ mod ty {
|
||||||
matches!(self.expand(), Kind::Ptr(_)) || self.is_never()
|
matches!(self.expand(), Kind::Ptr(_)) || self.is_never()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_upcast(self, ob: Self, kind: TyCheck) -> Option<Self> {
|
pub fn try_upcast(self, ob: Self) -> Option<Self> {
|
||||||
let (oa, ob) = (Self(self.0.min(ob.0)), Self(self.0.max(ob.0)));
|
let (oa, ob) = (Self(self.0.min(ob.0)), Self(self.0.max(ob.0)));
|
||||||
let (a, b) = (oa.strip_pointer(), ob.strip_pointer());
|
let (a, b) = (oa.strip_pointer(), ob.strip_pointer());
|
||||||
Some(match () {
|
Some(match () {
|
||||||
|
@ -437,7 +448,7 @@ mod ty {
|
||||||
_ if a.is_signed() && b.is_signed() || a.is_unsigned() && b.is_unsigned() => ob,
|
_ if a.is_signed() && b.is_signed() || a.is_unsigned() && b.is_unsigned() => ob,
|
||||||
_ if a.is_unsigned() && b.is_signed() && a.repr() - U8 < b.repr() - I8 => ob,
|
_ if a.is_unsigned() && b.is_signed() && a.repr() - U8 < b.repr() - I8 => ob,
|
||||||
_ if a.is_unsigned() && b.is_signed() && a.repr() - U8 > b.repr() - I8 => oa,
|
_ if a.is_unsigned() && b.is_signed() && a.repr() - U8 > b.repr() - I8 => oa,
|
||||||
_ if oa.is_integer() && ob.is_pointer() && kind == TyCheck::BinOp => ob,
|
_ if oa.is_integer() && ob.is_pointer() => ob,
|
||||||
_ => return None,
|
_ => return None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -498,13 +509,6 @@ mod ty {
|
||||||
Stack,
|
Stack,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Default, Debug, Clone, Copy)]
|
|
||||||
pub enum TyCheck {
|
|
||||||
BinOp,
|
|
||||||
#[default]
|
|
||||||
Assign,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<u64> for Id {
|
impl From<u64> for Id {
|
||||||
fn from(id: u64) -> Self {
|
fn from(id: u64) -> Self {
|
||||||
Self(unsafe { NonZeroU32::new_unchecked(id as _) })
|
Self(unsafe { NonZeroU32::new_unchecked(id as _) })
|
||||||
|
@ -544,7 +548,7 @@ mod ty {
|
||||||
};)*
|
};)*
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[expect(dead_code)]
|
||||||
impl Id {
|
impl Id {
|
||||||
$(pub const $name: Self = Kind::Builtin($name).compress();)*
|
$(pub const $name: Self = Kind::Builtin($name).compress();)*
|
||||||
}
|
}
|
||||||
|
@ -673,7 +677,7 @@ mod ty {
|
||||||
}
|
}
|
||||||
TK::Struct(idx) => {
|
TK::Struct(idx) => {
|
||||||
let record = &self.tys.ins.structs[idx as usize];
|
let record = &self.tys.ins.structs[idx as usize];
|
||||||
if ident::is_null(record.name) {
|
if record.name.is_null() {
|
||||||
f.write_str("[")?;
|
f.write_str("[")?;
|
||||||
idx.fmt(f)?;
|
idx.fmt(f)?;
|
||||||
f.write_str("]{")?;
|
f.write_str("]{")?;
|
||||||
|
@ -714,15 +718,6 @@ mod ty {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(not(feature = "opts"), expect(dead_code))]
|
|
||||||
pub fn bin_ret(ty: Id, op: TokenKind) -> Id {
|
|
||||||
use TokenKind as T;
|
|
||||||
match op {
|
|
||||||
T::Lt | T::Gt | T::Le | T::Ge | T::Ne | T::Eq => BOOL.into(),
|
|
||||||
_ => ty,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type EncodedInstr = (usize, [u8; instrs::MAX_SIZE]);
|
type EncodedInstr = (usize, [u8; instrs::MAX_SIZE]);
|
||||||
|
@ -752,7 +747,6 @@ struct Func {
|
||||||
file: FileId,
|
file: FileId,
|
||||||
name: Ident,
|
name: Ident,
|
||||||
base: Option<ty::Func>,
|
base: Option<ty::Func>,
|
||||||
computed: Option<ty::Id>,
|
|
||||||
expr: ExprRef,
|
expr: ExprRef,
|
||||||
sig: Option<Sig>,
|
sig: Option<Sig>,
|
||||||
offset: Offset,
|
offset: Offset,
|
||||||
|
@ -765,9 +759,8 @@ impl Default for Func {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
file: u32::MAX,
|
file: u32::MAX,
|
||||||
name: 0,
|
name: Default::default(),
|
||||||
base: None,
|
base: None,
|
||||||
computed: None,
|
|
||||||
expr: Default::default(),
|
expr: Default::default(),
|
||||||
sig: None,
|
sig: None,
|
||||||
offset: u32::MAX,
|
offset: u32::MAX,
|
||||||
|
@ -799,7 +792,7 @@ impl Default for Global {
|
||||||
offset: u32::MAX,
|
offset: u32::MAX,
|
||||||
data: Default::default(),
|
data: Default::default(),
|
||||||
file: u32::MAX,
|
file: u32::MAX,
|
||||||
name: 0,
|
name: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -884,7 +877,7 @@ impl ParamAlloc {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(packed)]
|
#[repr(packed)]
|
||||||
#[allow(dead_code)]
|
#[expect(dead_code)]
|
||||||
struct AbleOsExecutableHeader {
|
struct AbleOsExecutableHeader {
|
||||||
magic_number: [u8; 3],
|
magic_number: [u8; 3],
|
||||||
executable_version: u32,
|
executable_version: u32,
|
||||||
|
@ -901,7 +894,7 @@ impl ctx_map::CtxEntry for Ident {
|
||||||
type Key<'a> = &'a str;
|
type Key<'a> = &'a str;
|
||||||
|
|
||||||
fn key<'a>(&self, ctx: &'a Self::Ctx) -> Self::Key<'a> {
|
fn key<'a>(&self, ctx: &'a Self::Ctx) -> Self::Key<'a> {
|
||||||
unsafe { ctx.get_unchecked(ident::range(*self)) }
|
unsafe { ctx.get_unchecked(self.range()) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -917,7 +910,7 @@ impl IdentInterner {
|
||||||
match entry {
|
match entry {
|
||||||
hash_map::RawEntryMut::Occupied(o) => o.get_key_value().0.value,
|
hash_map::RawEntryMut::Occupied(o) => o.get_key_value().0.value,
|
||||||
hash_map::RawEntryMut::Vacant(v) => {
|
hash_map::RawEntryMut::Vacant(v) => {
|
||||||
let id = ident::new(self.strings.len() as _, ident.len() as _).unwrap();
|
let id = Ident::new(self.strings.len() as _, ident.len() as _).unwrap();
|
||||||
self.strings.push_str(ident);
|
self.strings.push_str(ident);
|
||||||
v.insert(ctx_map::Key { hash, value: id }, ());
|
v.insert(ctx_map::Key { hash, value: id }, ());
|
||||||
id
|
id
|
||||||
|
@ -926,7 +919,7 @@ impl IdentInterner {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ident_str(&self, ident: Ident) -> &str {
|
fn ident_str(&self, ident: Ident) -> &str {
|
||||||
&self.strings[ident::range(ident)]
|
&self.strings[ident.range()]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn project(&self, ident: &str) -> Option<Ident> {
|
fn project(&self, ident: &str) -> Option<Ident> {
|
||||||
|
@ -1052,9 +1045,9 @@ trait TypeParser {
|
||||||
ty::Kind::Struct(s) => &mut tys.ins.structs[s as usize].name,
|
ty::Kind::Struct(s) => &mut tys.ins.structs[s as usize].name,
|
||||||
ty::Kind::Func(s) => &mut tys.ins.funcs[s as usize].name,
|
ty::Kind::Func(s) => &mut tys.ins.funcs[s as usize].name,
|
||||||
ty::Kind::Global(s) => &mut tys.ins.globals[s as usize].name,
|
ty::Kind::Global(s) => &mut tys.ins.globals[s as usize].name,
|
||||||
_ => &mut 0,
|
_ => &mut Ident::default(),
|
||||||
};
|
};
|
||||||
if *nm == 0 {
|
if nm.is_null() {
|
||||||
*nm = name;
|
*nm = name;
|
||||||
}
|
}
|
||||||
tys.syms.insert(SymKey::Decl(file, name), ty, &tys.ins);
|
tys.syms.insert(SymKey::Decl(file, name), ty, &tys.ins);
|
||||||
|
@ -1088,7 +1081,7 @@ trait TypeParser {
|
||||||
let base = self.parse_ty(file, val, None, files);
|
let base = self.parse_ty(file, val, None, files);
|
||||||
self.tys().make_ptr(base)
|
self.tys().make_ptr(base)
|
||||||
}
|
}
|
||||||
Expr::Ident { id, .. } if ident::is_null(id) => id.into(),
|
Expr::Ident { id, .. } if id.is_null() => id.len().into(),
|
||||||
Expr::Ident { id, pos, .. } => self.find_type(pos, file, file, Ok(id), files),
|
Expr::Ident { id, pos, .. } => self.find_type(pos, file, file, Ok(id), files),
|
||||||
Expr::Field { target, pos, name }
|
Expr::Field { target, pos, name }
|
||||||
if let ty::Kind::Module(inside) =
|
if let ty::Kind::Module(inside) =
|
||||||
|
@ -1136,7 +1129,7 @@ trait TypeParser {
|
||||||
tys.ins.structs.push(Struct {
|
tys.ins.structs.push(Struct {
|
||||||
file,
|
file,
|
||||||
pos,
|
pos,
|
||||||
name: name.unwrap_or(0),
|
name: name.unwrap_or_default(),
|
||||||
field_start: tys.ins.fields.len() as _,
|
field_start: tys.ins.fields.len() as _,
|
||||||
explicit_alignment: packed.then_some(1),
|
explicit_alignment: packed.then_some(1),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
@ -1466,7 +1459,6 @@ impl Types {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(not(feature = "opts"), expect(dead_code))]
|
|
||||||
fn find_struct_field(&self, s: ty::Struct, name: &str) -> Option<usize> {
|
fn find_struct_field(&self, s: ty::Struct, name: &str) -> Option<usize> {
|
||||||
let name = self.names.project(name)?;
|
let name = self.names.project(name)?;
|
||||||
self.struct_fields(s).iter().position(|f| f.name == name)
|
self.struct_fields(s).iter().position(|f| f.name == name)
|
||||||
|
@ -1536,7 +1528,6 @@ impl OffsetIter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "opts", feature = "std"))]
|
|
||||||
type HashMap<K, V> = hashbrown::HashMap<K, V, FnvBuildHasher>;
|
type HashMap<K, V> = hashbrown::HashMap<K, V, FnvBuildHasher>;
|
||||||
type FnvBuildHasher = core::hash::BuildHasherDefault<FnvHasher>;
|
type FnvBuildHasher = core::hash::BuildHasherDefault<FnvHasher>;
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
fmt::Formatter,
|
fmt::Formatter,
|
||||||
ident::{self, Ident},
|
|
||||||
lexer::{self, Lexer, Token, TokenKind},
|
lexer::{self, Lexer, Token, TokenKind},
|
||||||
|
Ident,
|
||||||
},
|
},
|
||||||
alloc::{boxed::Box, string::String, vec::Vec},
|
alloc::{boxed::Box, string::String, vec::Vec},
|
||||||
core::{
|
core::{
|
||||||
|
@ -126,11 +126,8 @@ impl<'a, 'b> Parser<'a, 'b> {
|
||||||
let mut idents = core::mem::take(&mut self.ctx.idents);
|
let mut idents = core::mem::take(&mut self.ctx.idents);
|
||||||
for id in idents.drain(..) {
|
for id in idents.drain(..) {
|
||||||
self.report(
|
self.report(
|
||||||
ident::pos(id.ident),
|
id.ident.pos(),
|
||||||
format_args!(
|
format_args!("undeclared identifier: {}", self.lexer.slice(id.ident.range())),
|
||||||
"undeclared identifier: {}",
|
|
||||||
self.lexer.slice(ident::range(id.ident))
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
self.ctx.idents = idents;
|
self.ctx.idents = idents;
|
||||||
|
@ -217,7 +214,7 @@ impl<'a, 'b> Parser<'a, 'b> {
|
||||||
pos,
|
pos,
|
||||||
format_args!(
|
format_args!(
|
||||||
"out of order declaration not allowed: {}",
|
"out of order declaration not allowed: {}",
|
||||||
self.lexer.slice(ident::range(id))
|
self.lexer.slice(id.range())
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -229,7 +226,7 @@ impl<'a, 'b> Parser<'a, 'b> {
|
||||||
if core::mem::replace(&mut self.ctx.idents[index].declared, true) {
|
if core::mem::replace(&mut self.ctx.idents[index].declared, true) {
|
||||||
self.report(
|
self.report(
|
||||||
pos,
|
pos,
|
||||||
format_args!("redeclaration of identifier: {}", self.lexer.slice(ident::range(id))),
|
format_args!("redeclaration of identifier: {}", self.lexer.slice(id.range())),
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -242,7 +239,7 @@ impl<'a, 'b> Parser<'a, 'b> {
|
||||||
let name = self.lexer.slice(token.range());
|
let name = self.lexer.slice(token.range());
|
||||||
|
|
||||||
if let Some(builtin) = crate::ty::from_str(name) {
|
if let Some(builtin) = crate::ty::from_str(name) {
|
||||||
return (builtin, false);
|
return (Ident::builtin(builtin), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
let (i, id, bl) = match self
|
let (i, id, bl) = match self
|
||||||
|
@ -250,14 +247,14 @@ impl<'a, 'b> Parser<'a, 'b> {
|
||||||
.idents
|
.idents
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.rfind(|(_, elem)| self.lexer.slice(ident::range(elem.ident)) == name)
|
.rfind(|(_, elem)| self.lexer.slice(elem.ident.range()) == name)
|
||||||
{
|
{
|
||||||
Some((i, elem)) => (i, elem, false),
|
Some((i, elem)) => (i, elem, false),
|
||||||
None => {
|
None => {
|
||||||
let ident = match ident::new(token.start, name.len() as _) {
|
let ident = match Ident::new(token.start, name.len() as _) {
|
||||||
None => {
|
None => {
|
||||||
self.report(token.start, "identifier can at most have 64 characters");
|
self.report(token.start, "identifier can at most have 64 characters");
|
||||||
ident::new(token.start, 64).unwrap()
|
Ident::new(token.start, 63).unwrap()
|
||||||
}
|
}
|
||||||
Some(id) => id,
|
Some(id) => id,
|
||||||
};
|
};
|
||||||
|
@ -725,7 +722,7 @@ macro_rules! generate_expr {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pos(&self) -> Pos {
|
pub fn pos(&self) -> Pos {
|
||||||
#[allow(unused_variables)]
|
#[expect(unused_variables)]
|
||||||
match self {
|
match self {
|
||||||
$(Self::$variant { $($field),* } => generate_expr!(@first $(($field),)*).posi(),)*
|
$(Self::$variant { $($field),* } => generate_expr!(@first $(($field),)*).posi(),)*
|
||||||
}
|
}
|
||||||
|
@ -914,7 +911,7 @@ generate_expr! {
|
||||||
impl Expr<'_> {
|
impl Expr<'_> {
|
||||||
pub fn declares(&self, iden: Result<Ident, &str>, source: &str) -> Option<Ident> {
|
pub fn declares(&self, iden: Result<Ident, &str>, source: &str) -> Option<Ident> {
|
||||||
match *self {
|
match *self {
|
||||||
Self::Ident { id, .. } if iden == Ok(id) || iden == Err(&source[ident::range(id)]) => {
|
Self::Ident { id, .. } if iden == Ok(id) || iden == Err(&source[id.range()]) => {
|
||||||
Some(id)
|
Some(id)
|
||||||
}
|
}
|
||||||
Self::Ctor { fields, .. } => fields.iter().find_map(|f| f.value.declares(iden, source)),
|
Self::Ctor { fields, .. } => fields.iter().find_map(|f| f.value.declares(iden, source)),
|
||||||
|
@ -1192,7 +1189,7 @@ impl Ast {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ident_str(&self, ident: Ident) -> &str {
|
pub fn ident_str(&self, ident: Ident) -> &str {
|
||||||
&self.file[ident::range(ident)]
|
&self.file[ident.range()]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
106
lang/src/son.rs
106
lang/src/son.rs
|
@ -2,9 +2,7 @@ use {
|
||||||
self::strong_ref::StrongRef,
|
self::strong_ref::StrongRef,
|
||||||
crate::{
|
crate::{
|
||||||
ctx_map::CtxEntry,
|
ctx_map::CtxEntry,
|
||||||
debug,
|
debug, instrs,
|
||||||
ident::Ident,
|
|
||||||
instrs,
|
|
||||||
lexer::{self, TokenKind},
|
lexer::{self, TokenKind},
|
||||||
parser::{
|
parser::{
|
||||||
self,
|
self,
|
||||||
|
@ -14,8 +12,8 @@ use {
|
||||||
reg, task,
|
reg, task,
|
||||||
ty::{self, Arg, ArrayLen, Loc, Tuple},
|
ty::{self, Arg, ArrayLen, Loc, Tuple},
|
||||||
vc::{BitSet, Vc},
|
vc::{BitSet, Vc},
|
||||||
Comptime, FTask, Func, Global, HashMap, Offset, OffsetIter, PLoc, Reloc, Sig, StringRef,
|
Comptime, FTask, Func, Global, HashMap, Ident, Offset, OffsetIter, PLoc, Reloc, Sig,
|
||||||
SymKey, TypeParser, TypedReloc, Types,
|
StringRef, SymKey, TypeParser, TypedReloc, Types,
|
||||||
},
|
},
|
||||||
alloc::{borrow::ToOwned, string::String, vec::Vec},
|
alloc::{borrow::ToOwned, string::String, vec::Vec},
|
||||||
core::{
|
core::{
|
||||||
|
@ -28,7 +26,6 @@ use {
|
||||||
hashbrown::hash_map,
|
hashbrown::hash_map,
|
||||||
hbbytecode::DisasmError,
|
hbbytecode::DisasmError,
|
||||||
regalloc2::VReg,
|
regalloc2::VReg,
|
||||||
std::panic,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const VOID: Nid = 0;
|
const VOID: Nid = 0;
|
||||||
|
@ -146,26 +143,25 @@ impl Nodes {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
fn graphviz(&self, tys: &Types, files: &[parser::Ast]) {
|
fn graphviz(&self, tys: &Types, files: &[parser::Ast]) {
|
||||||
let out = &mut String::new();
|
let out = &mut String::new();
|
||||||
_ = self.graphviz_low(tys, files, out);
|
_ = self.graphviz_low(tys, files, out);
|
||||||
log::info!("{out}");
|
log::info!("{out}");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn graphviz_in_browser(&self, tys: &Types, files: &[parser::Ast]) {
|
fn graphviz_in_browser(&self, _tys: &Types, _files: &[parser::Ast]) {
|
||||||
#[cfg(all(debug_assertions, feature = "std"))]
|
#[cfg(all(debug_assertions, feature = "std"))]
|
||||||
{
|
{
|
||||||
// let out = &mut String::new();
|
let out = &mut String::new();
|
||||||
// _ = self.graphviz_low(tys, files, out);
|
_ = self.graphviz_low(_tys, _files, out);
|
||||||
// if !std::process::Command::new("brave")
|
if !std::process::Command::new("brave")
|
||||||
// .arg(format!("https://dreampuf.github.io/GraphvizOnline/#{out}"))
|
.arg(format!("https://dreampuf.github.io/GraphvizOnline/#{out}"))
|
||||||
// .status()
|
.status()
|
||||||
// .unwrap()
|
.unwrap()
|
||||||
// .success()
|
.success()
|
||||||
// {
|
{
|
||||||
// log::error!("{out}");
|
log::error!("{out}");
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,18 +173,6 @@ impl Nodes {
|
||||||
push_down(self, VOID);
|
push_down(self, VOID);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_low(&mut self, id: Nid) -> Node {
|
|
||||||
if cfg!(debug_assertions) {
|
|
||||||
let value =
|
|
||||||
mem::replace(&mut self.values[id as usize], Err((self.free, debug::trace())))
|
|
||||||
.unwrap();
|
|
||||||
self.free = id;
|
|
||||||
value
|
|
||||||
} else {
|
|
||||||
mem::replace(&mut self.values[id as usize], Err((Nid::MAX, debug::trace()))).unwrap()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn clear(&mut self) {
|
fn clear(&mut self) {
|
||||||
self.values.clear();
|
self.values.clear();
|
||||||
self.lookup.clear();
|
self.lookup.clear();
|
||||||
|
@ -257,25 +241,21 @@ impl Nodes {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_node_low(&mut self, ty: ty::Id, kind: Kind, inps: impl Into<Vc>) -> (Nid, bool) {
|
fn new_node(&mut self, ty: ty::Id, kind: Kind, inps: impl Into<Vc>) -> Nid {
|
||||||
let id = self.new_node_nop(ty, kind, inps);
|
let id = self.new_node_nop(ty, kind, inps);
|
||||||
if let Some(opt) = self.peephole(id) {
|
if let Some(opt) = self.peephole(id) {
|
||||||
debug_assert_ne!(opt, id);
|
debug_assert_ne!(opt, id);
|
||||||
self.lock(opt);
|
self.lock(opt);
|
||||||
self.remove(id);
|
self.remove(id);
|
||||||
self.unlock(opt);
|
self.unlock(opt);
|
||||||
(opt, true)
|
opt
|
||||||
} else {
|
} else {
|
||||||
(id, false)
|
id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_node(&mut self, ty: ty::Id, kind: Kind, inps: impl Into<Vc>) -> Nid {
|
|
||||||
self.new_node_low(ty, kind, inps).0
|
|
||||||
}
|
|
||||||
|
|
||||||
fn new_node_lit(&mut self, ty: ty::Id, kind: Kind, inps: impl Into<Vc>) -> Value {
|
fn new_node_lit(&mut self, ty: ty::Id, kind: Kind, inps: impl Into<Vc>) -> Value {
|
||||||
Value::new(self.new_node_low(ty, kind, inps).0).ty(ty)
|
Value::new(self.new_node(ty, kind, inps)).ty(ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lock(&mut self, target: Nid) {
|
fn lock(&mut self, target: Nid) {
|
||||||
|
@ -292,8 +272,6 @@ impl Nodes {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
debug_assert!(!matches!(self[target].kind, Kind::Call { .. }), "{:?}", self[target]);
|
|
||||||
|
|
||||||
for i in 0..self[target].inputs.len() {
|
for i in 0..self[target].inputs.len() {
|
||||||
let inp = self[target].inputs[i];
|
let inp = self[target].inputs[i];
|
||||||
let index = self[inp].outputs.iter().position(|&p| p == target).unwrap();
|
let index = self[inp].outputs.iter().position(|&p| p == target).unwrap();
|
||||||
|
@ -302,7 +280,15 @@ impl Nodes {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.remove_node_lookup(target);
|
self.remove_node_lookup(target);
|
||||||
self.remove_low(target);
|
|
||||||
|
if cfg!(debug_assertions) {
|
||||||
|
mem::replace(&mut self.values[target as usize], Err((Nid::MAX, debug::trace())))
|
||||||
|
.unwrap();
|
||||||
|
} else {
|
||||||
|
mem::replace(&mut self.values[target as usize], Err((self.free, debug::trace())))
|
||||||
|
.unwrap();
|
||||||
|
self.free = target;
|
||||||
|
}
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
@ -664,7 +650,7 @@ impl Nodes {
|
||||||
self.values.iter().enumerate().filter_map(|(i, s)| Some((i as _, s.as_ref().ok()?)))
|
self.values.iter().enumerate().filter_map(|(i, s)| Some((i as _, s.as_ref().ok()?)))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::format_in_format_args)]
|
#[expect(clippy::format_in_format_args)]
|
||||||
fn basic_blocks_instr(&mut self, out: &mut String, node: Nid) -> core::fmt::Result {
|
fn basic_blocks_instr(&mut self, out: &mut String, node: Nid) -> core::fmt::Result {
|
||||||
if self[node].kind != Kind::Loop && self[node].kind != Kind::Region {
|
if self[node].kind != Kind::Loop && self[node].kind != Kind::Region {
|
||||||
write!(out, " {node:>2}-c{:>2}: ", self[node].ralloc_backref)?;
|
write!(out, " {node:>2}-c{:>2}: ", self[node].ralloc_backref)?;
|
||||||
|
@ -913,7 +899,6 @@ impl Nodes {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
fn eliminate_stack_temporaries(&mut self) {
|
fn eliminate_stack_temporaries(&mut self) {
|
||||||
'o: for stack in self[MEM].outputs.clone() {
|
'o: for stack in self[MEM].outputs.clone() {
|
||||||
if self.values[stack as usize].is_err() || self[stack].kind != Kind::Stck {
|
if self.values[stack as usize].is_err() || self[stack].kind != Kind::Stck {
|
||||||
|
@ -1385,7 +1370,8 @@ impl ItemCtx {
|
||||||
let loops = self.nodes.new_node(ty::Id::VOID, Kind::Loops, [VOID]);
|
let loops = self.nodes.new_node(ty::Id::VOID, Kind::Loops, [VOID]);
|
||||||
debug_assert_eq!(loops, LOOPS);
|
debug_assert_eq!(loops, LOOPS);
|
||||||
self.nodes.lock(loops);
|
self.nodes.lock(loops);
|
||||||
self.scope.store = Variable::new(0, ty::Id::VOID, false, MEM, &mut self.nodes);
|
self.scope.store =
|
||||||
|
Variable::new(Ident::default(), ty::Id::VOID, false, MEM, &mut self.nodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn finalize(&mut self, stack: &mut Vec<Nid>) {
|
fn finalize(&mut self, stack: &mut Vec<Nid>) {
|
||||||
|
@ -2033,6 +2019,18 @@ impl<'a> Codegen<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emit_and_eval(&mut self, file: FileId, ret: ty::Id, ret_loc: &mut [u8]) -> u64 {
|
fn emit_and_eval(&mut self, file: FileId, ret: ty::Id, ret_loc: &mut [u8]) -> u64 {
|
||||||
|
let mut rets =
|
||||||
|
self.ci.nodes[NEVER].inputs.iter().filter(|&&i| self.ci.nodes[i].kind == Kind::Return);
|
||||||
|
if let Some(&ret) = rets.next()
|
||||||
|
&& rets.next().is_none()
|
||||||
|
&& let Kind::CInt { value } = self.ci.nodes[self.ci.nodes[ret].inputs[1]].kind
|
||||||
|
{
|
||||||
|
if let len @ 1..=8 = ret_loc.len() {
|
||||||
|
ret_loc.copy_from_slice(&value.to_ne_bytes()[..len])
|
||||||
|
}
|
||||||
|
return value as _;
|
||||||
|
}
|
||||||
|
|
||||||
if !self.complete_call_graph() {
|
if !self.complete_call_graph() {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -2048,7 +2046,6 @@ impl<'a> Codegen<'a> {
|
||||||
|
|
||||||
let func = Func {
|
let func = Func {
|
||||||
file,
|
file,
|
||||||
name: 0,
|
|
||||||
relocs: mem::take(&mut self.ci.relocs),
|
relocs: mem::take(&mut self.ci.relocs),
|
||||||
code: mem::take(&mut self.ci.code),
|
code: mem::take(&mut self.ci.code),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
@ -2145,6 +2142,13 @@ impl<'a> Codegen<'a> {
|
||||||
self.complete_call_graph();
|
self.complete_call_graph();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn assemble_comptime(&mut self) -> Comptime {
|
||||||
|
self.ct.code.clear();
|
||||||
|
self.tys.reassemble(&mut self.ct.code);
|
||||||
|
self.ct.reset();
|
||||||
|
core::mem::take(self.ct)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn assemble(&mut self, buf: &mut Vec<u8>) {
|
pub fn assemble(&mut self, buf: &mut Vec<u8>) {
|
||||||
self.tys.reassemble(buf);
|
self.tys.reassemble(buf);
|
||||||
}
|
}
|
||||||
|
@ -2450,11 +2454,7 @@ impl<'a> Codegen<'a> {
|
||||||
self.strip_var(&mut rhs);
|
self.strip_var(&mut rhs);
|
||||||
let ty = self.binop_ty(pos, &mut lhs, &mut rhs, op);
|
let ty = self.binop_ty(pos, &mut lhs, &mut rhs, op);
|
||||||
let inps = [VOID, lhs.id, rhs.id];
|
let inps = [VOID, lhs.id, rhs.id];
|
||||||
Some(self.ci.nodes.new_node_lit(
|
Some(self.ci.nodes.new_node_lit(ty.bin_ret(op), Kind::BinOp { op }, inps))
|
||||||
ty::bin_ret(ty, op),
|
|
||||||
Kind::BinOp { op },
|
|
||||||
inps,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
ty::Kind::Struct(s) if op.is_homogenous() => {
|
ty::Kind::Struct(s) if op.is_homogenous() => {
|
||||||
self.ci.nodes.lock(lhs.id);
|
self.ci.nodes.lock(lhs.id);
|
||||||
|
@ -3598,7 +3598,7 @@ impl<'a> Codegen<'a> {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
fn binop_ty(&mut self, pos: Pos, lhs: &mut Value, rhs: &mut Value, op: TokenKind) -> ty::Id {
|
fn binop_ty(&mut self, pos: Pos, lhs: &mut Value, rhs: &mut Value, op: TokenKind) -> ty::Id {
|
||||||
if let Some(upcasted) = lhs.ty.try_upcast(rhs.ty, ty::TyCheck::BinOp) {
|
if let Some(upcasted) = lhs.ty.try_upcast(rhs.ty) {
|
||||||
let to_correct = if lhs.ty != upcasted {
|
let to_correct = if lhs.ty != upcasted {
|
||||||
Some(lhs)
|
Some(lhs)
|
||||||
} else if rhs.ty != upcasted {
|
} else if rhs.ty != upcasted {
|
||||||
|
@ -3641,7 +3641,7 @@ impl<'a> Codegen<'a> {
|
||||||
expected: ty::Id,
|
expected: ty::Id,
|
||||||
hint: impl fmt::Display,
|
hint: impl fmt::Display,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
if let Some(upcasted) = src.ty.try_upcast(expected, ty::TyCheck::Assign)
|
if let Some(upcasted) = src.ty.try_upcast(expected)
|
||||||
&& upcasted == expected
|
&& upcasted == expected
|
||||||
{
|
{
|
||||||
if src.ty != upcasted {
|
if src.ty != upcasted {
|
||||||
|
@ -3999,7 +3999,7 @@ impl<'a> Function<'a> {
|
||||||
|
|
||||||
let (ret, mut parama) = self.tys.parama(self.sig.ret);
|
let (ret, mut parama) = self.tys.parama(self.sig.ret);
|
||||||
let mut typs = self.sig.args.args();
|
let mut typs = self.sig.args.args();
|
||||||
#[allow(clippy::unnecessary_to_owned)]
|
#[expect(clippy::unnecessary_to_owned)]
|
||||||
let mut args = self.nodes[VOID].outputs[ARG_START..].to_owned().into_iter();
|
let mut args = self.nodes[VOID].outputs[ARG_START..].to_owned().into_iter();
|
||||||
while let Some(ty) = typs.next_value(self.tys) {
|
while let Some(ty) = typs.next_value(self.tys) {
|
||||||
let arg = args.next().unwrap();
|
let arg = args.next().unwrap();
|
||||||
|
|
|
@ -24,12 +24,12 @@ main:
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
pass:
|
pass:
|
||||||
LD r4, r2, 8a, 8h
|
LD r4, r2, 8a, 8h
|
||||||
MULI64 r8, r4, 8d
|
MULI64 r7, r4, 8d
|
||||||
LD r5, r2, 0a, 8h
|
LD r5, r2, 0a, 8h
|
||||||
ADD64 r11, r8, r2
|
ADD64 r10, r7, r2
|
||||||
ADD64 r10, r4, r5
|
ADD64 r9, r4, r5
|
||||||
LD r11, r11, 0a, 8h
|
LD r1, r10, 0a, 8h
|
||||||
ADD64 r1, r11, r10
|
ADD64 r1, r1, r9
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
code size: 316
|
code size: 316
|
||||||
ret: 8
|
ret: 8
|
||||||
|
|
|
@ -25,15 +25,15 @@ main:
|
||||||
JEQ r2, r11, :2
|
JEQ r2, r11, :2
|
||||||
LI64 r1, 64d
|
LI64 r1, 64d
|
||||||
JMP :1
|
JMP :1
|
||||||
2: LD r10, r254, 0a, 1h
|
2: LD r11, r254, 0a, 1h
|
||||||
LD r9, r254, 4a, 4h
|
LD r9, r254, 4a, 4h
|
||||||
LD r11, r254, 8a, 4h
|
LD r12, r254, 8a, 4h
|
||||||
LD r5, r254, 1a, 1h
|
LD r5, r254, 1a, 1h
|
||||||
ANDI r4, r10, 255d
|
ANDI r4, r11, 255d
|
||||||
ADD32 r6, r11, r9
|
ADD32 r3, r12, r9
|
||||||
LD r11, r254, 2a, 1h
|
LD r11, r254, 2a, 1h
|
||||||
ANDI r10, r5, 255d
|
ANDI r10, r5, 255d
|
||||||
ADD32 r9, r6, r4
|
ADD32 r9, r3, r4
|
||||||
LD r5, r254, 3a, 1h
|
LD r5, r254, 3a, 1h
|
||||||
ANDI r4, r11, 255d
|
ANDI r4, r11, 255d
|
||||||
ADD32 r3, r9, r10
|
ADD32 r3, r9, r10
|
||||||
|
|
|
@ -86,12 +86,12 @@ push:
|
||||||
MULI64 r8, r6, 8d
|
MULI64 r8, r6, 8d
|
||||||
LD r12, r38, 0a, 8h
|
LD r12, r38, 0a, 8h
|
||||||
ADD64 r11, r12, r8
|
ADD64 r11, r12, r8
|
||||||
CP r8, r39
|
CP r3, r39
|
||||||
9: JNE r11, r12, :5
|
9: JNE r11, r12, :5
|
||||||
LD r5, r38, 8a, 8h
|
LD r8, r38, 8a, 8h
|
||||||
JEQ r5, r1, :6
|
JEQ r8, r1, :6
|
||||||
CP r4, r37
|
CP r4, r37
|
||||||
MUL64 r3, r5, r4
|
MUL64 r3, r8, r4
|
||||||
LD r2, r38, 0a, 8h
|
LD r2, r38, 0a, 8h
|
||||||
JAL r31, r0, :free
|
JAL r31, r0, :free
|
||||||
CP r5, r39
|
CP r5, r39
|
||||||
|
@ -101,11 +101,11 @@ push:
|
||||||
JMP :8
|
JMP :8
|
||||||
5: CP r4, r37
|
5: CP r4, r37
|
||||||
CP r5, r39
|
CP r5, r39
|
||||||
ADDI64 r6, r8, 8d
|
ADDI64 r6, r3, 8d
|
||||||
ADDI64 r7, r12, 8d
|
ADDI64 r7, r12, 8d
|
||||||
LD r9, r12, 0a, 8h
|
LD r8, r12, 0a, 8h
|
||||||
ST r9, r8, 0a, 8h
|
ST r8, r3, 0a, 8h
|
||||||
CP r8, r6
|
CP r3, r6
|
||||||
CP r12, r7
|
CP r12, r7
|
||||||
JMP :9
|
JMP :9
|
||||||
0: CP r38, r34
|
0: CP r38, r34
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
main:
|
main:
|
||||||
ADDI64 r254, r254, -128d
|
ADDI64 r254, r254, -128d
|
||||||
LI8 r7, 69b
|
LI8 r5, 69b
|
||||||
LI64 r6, 128d
|
LI64 r6, 128d
|
||||||
LI64 r8, 0d
|
LI64 r7, 0d
|
||||||
ADDI64 r4, r254, 0d
|
ADDI64 r4, r254, 0d
|
||||||
2: JLTU r8, r6, :0
|
2: JLTU r7, r6, :0
|
||||||
LD r3, r254, 42a, 1h
|
LD r1, r254, 42a, 1h
|
||||||
ANDI r1, r3, 255d
|
ANDI r1, r1, 255d
|
||||||
JMP :1
|
JMP :1
|
||||||
0: ADDI64 r5, r8, 1d
|
0: ADDI64 r3, r7, 1d
|
||||||
ADD64 r12, r4, r8
|
ADD64 r7, r4, r7
|
||||||
ST r7, r12, 0a, 1h
|
ST r5, r7, 0a, 1h
|
||||||
CP r8, r5
|
CP r7, r3
|
||||||
JMP :2
|
JMP :2
|
||||||
1: ADDI64 r254, r254, 128d
|
1: ADDI64 r254, r254, 128d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
main:
|
main:
|
||||||
LI64 r8, 6d
|
LI64 r7, 6d
|
||||||
LRA r4, r0, :gb
|
LRA r3, r0, :gb
|
||||||
LI64 r7, 0d
|
LI64 r6, 0d
|
||||||
LD r9, r4, 0a, 8h
|
LD r8, r3, 0a, 8h
|
||||||
CMPU r10, r9, r7
|
CMPU r9, r8, r6
|
||||||
CMPUI r10, r10, 0d
|
CMPUI r9, r9, 0d
|
||||||
ORI r12, r10, 0d
|
ORI r11, r9, 0d
|
||||||
ANDI r12, r12, 255d
|
ANDI r11, r11, 255d
|
||||||
JNE r12, r0, :0
|
JNE r11, r0, :0
|
||||||
CP r5, r8
|
CP r4, r7
|
||||||
JMP :1
|
JMP :1
|
||||||
0: LI64 r5, 1d
|
0: LI64 r4, 1d
|
||||||
1: SUB64 r1, r5, r8
|
1: SUB64 r1, r4, r7
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
code size: 131
|
code size: 131
|
||||||
ret: 0
|
ret: 0
|
||||||
|
|
|
@ -32,14 +32,14 @@ structs:
|
||||||
ST r7, r254, 16a, 8h
|
ST r7, r254, 16a, 8h
|
||||||
LD r11, r254, 0a, 8h
|
LD r11, r254, 0a, 8h
|
||||||
LD r1, r254, 8a, 8h
|
LD r1, r254, 8a, 8h
|
||||||
ADD64 r5, r1, r11
|
ADD64 r3, r1, r11
|
||||||
SUB64 r5, r5, r7
|
SUB64 r5, r3, r7
|
||||||
ST r5, r254, 24a, 8h
|
ST r5, r254, 24a, 8h
|
||||||
ST r4, r254, 32a, 8h
|
ST r4, r254, 32a, 8h
|
||||||
LD r9, r254, 40a, 8h
|
LD r9, r254, 40a, 8h
|
||||||
LD r11, r254, 24a, 8h
|
LD r11, r254, 24a, 8h
|
||||||
ADD64 r2, r11, r9
|
ADD64 r1, r11, r9
|
||||||
SUB64 r1, r2, r4
|
SUB64 r1, r1, r4
|
||||||
ADDI64 r254, r254, 48d
|
ADDI64 r254, r254, 48d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
code size: 373
|
code size: 373
|
||||||
|
|
|
@ -5,8 +5,9 @@ fib:
|
||||||
CP r10, r4
|
CP r10, r4
|
||||||
2: JNE r2, r5, :0
|
2: JNE r2, r5, :0
|
||||||
JMP :1
|
JMP :1
|
||||||
0: ADD64 r3, r10, r1
|
0: ADD64 r1, r10, r1
|
||||||
SUB64 r2, r2, r4
|
SUB64 r2, r2, r4
|
||||||
|
CP r3, r1
|
||||||
CP r1, r10
|
CP r1, r10
|
||||||
CP r10, r3
|
CP r10, r3
|
||||||
JMP :2
|
JMP :2
|
||||||
|
@ -19,6 +20,6 @@ main:
|
||||||
LD r31, r254, 0a, 8h
|
LD r31, r254, 0a, 8h
|
||||||
ADDI64 r254, r254, 8d
|
ADDI64 r254, r254, 8d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
code size: 150
|
code size: 153
|
||||||
ret: 55
|
ret: 55
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
|
@ -6,12 +6,12 @@ main:
|
||||||
ADDI64 r254, r254, -16d
|
ADDI64 r254, r254, -16d
|
||||||
ST r31, r254, 8a, 8h
|
ST r31, r254, 8a, 8h
|
||||||
ADDI64 r2, r254, 0d
|
ADDI64 r2, r254, 0d
|
||||||
LI64 r4, 2d
|
LI64 r3, 2d
|
||||||
ST r4, r254, 0a, 8h
|
ST r3, r254, 0a, 8h
|
||||||
JAL r31, r0, :clobber
|
JAL r31, r0, :clobber
|
||||||
LD r8, r254, 0a, 8h
|
LD r8, r254, 0a, 8h
|
||||||
LI64 r7, 4d
|
LI64 r9, 4d
|
||||||
SUB64 r1, r7, r8
|
SUB64 r1, r9, r8
|
||||||
LD r31, r254, 8a, 8h
|
LD r31, r254, 8a, 8h
|
||||||
ADDI64 r254, r254, 16d
|
ADDI64 r254, r254, 16d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
|
|
|
@ -1,41 +1,41 @@
|
||||||
main:
|
main:
|
||||||
ADDI64 r254, r254, -40d
|
ADDI64 r254, r254, -40d
|
||||||
LI64 r6, 4d
|
LI64 r6, 4d
|
||||||
LI64 r8, 1d
|
LI64 r7, 1d
|
||||||
LI64 r4, 0d
|
LI64 r4, 0d
|
||||||
ADDI64 r5, r254, 0d
|
ADDI64 r5, r254, 0d
|
||||||
CP r9, r4
|
CP r8, r4
|
||||||
6: JNE r9, r6, :0
|
6: JNE r8, r6, :0
|
||||||
LI64 r6, 2d
|
LI64 r6, 2d
|
||||||
ADDI64 r7, r254, 32d
|
ADDI64 r1, r254, 32d
|
||||||
CP r9, r4
|
CP r8, r4
|
||||||
4: JNE r9, r8, :1
|
4: JNE r8, r7, :1
|
||||||
LD r1, r254, 0a, 8h
|
LD r1, r254, 0a, 8h
|
||||||
JMP :2
|
JMP :2
|
||||||
1: MUL64 r12, r9, r6
|
1: MUL64 r11, r8, r6
|
||||||
ADD64 r9, r9, r8
|
ADD64 r8, r8, r7
|
||||||
SUB64 r10, r6, r9
|
SUB64 r9, r6, r8
|
||||||
MUL64 r10, r10, r6
|
MUL64 r9, r9, r6
|
||||||
CP r3, r4
|
CP r2, r4
|
||||||
5: JNE r3, r6, :3
|
5: JNE r2, r6, :3
|
||||||
JMP :4
|
JMP :4
|
||||||
3: ADD64 r11, r3, r8
|
3: ADD64 r3, r2, r7
|
||||||
ADD64 r1, r12, r3
|
ADD64 r10, r11, r2
|
||||||
MULI64 r1, r1, 8d
|
MULI64 r10, r10, 8d
|
||||||
ADD64 r2, r10, r3
|
ADD64 r2, r9, r2
|
||||||
ADD64 r1, r5, r1
|
ADD64 r10, r5, r10
|
||||||
MULI64 r2, r2, 8d
|
MULI64 r12, r2, 8d
|
||||||
ADD64 r2, r5, r2
|
ADD64 r12, r5, r12
|
||||||
BMC r1, r7, 8h
|
BMC r10, r1, 8h
|
||||||
BMC r2, r1, 8h
|
BMC r12, r10, 8h
|
||||||
BMC r7, r2, 8h
|
BMC r1, r12, 8h
|
||||||
CP r3, r11
|
CP r2, r3
|
||||||
JMP :5
|
JMP :5
|
||||||
0: ADD64 r2, r9, r8
|
0: ADD64 r1, r8, r7
|
||||||
MULI64 r12, r9, 8d
|
MULI64 r12, r8, 8d
|
||||||
ADD64 r7, r5, r12
|
ADD64 r9, r5, r12
|
||||||
ST r9, r7, 0a, 8h
|
ST r8, r9, 0a, 8h
|
||||||
CP r9, r2
|
CP r8, r1
|
||||||
JMP :6
|
JMP :6
|
||||||
2: ADDI64 r254, r254, 40d
|
2: ADDI64 r254, r254, 40d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
|
|
|
@ -30,82 +30,82 @@ main:
|
||||||
LD r7, r254, 150a, 1h
|
LD r7, r254, 150a, 1h
|
||||||
ADD8 r9, r7, r6
|
ADD8 r9, r7, r6
|
||||||
LD r11, r254, 148a, 1h
|
LD r11, r254, 148a, 1h
|
||||||
ADD8 r3, r11, r9
|
ADD8 r1, r11, r9
|
||||||
LI8 r4, 4b
|
LI8 r3, 4b
|
||||||
ADD8 r3, r3, r2
|
ADD8 r6, r1, r2
|
||||||
|
ANDI r6, r6, 255d
|
||||||
ANDI r3, r3, 255d
|
ANDI r3, r3, 255d
|
||||||
ANDI r4, r4, 255d
|
JEQ r6, r3, :0
|
||||||
JEQ r3, r4, :0
|
|
||||||
LI64 r1, 1008d
|
LI64 r1, 1008d
|
||||||
JMP :1
|
JMP :1
|
||||||
0: LI64 r11, 1d
|
0: LI64 r10, 1d
|
||||||
ADDI64 r2, r254, 80d
|
ADDI64 r1, r254, 80d
|
||||||
ST r11, r254, 80a, 8h
|
ST r10, r254, 80a, 8h
|
||||||
LI64 r3, 2d
|
LI64 r2, 2d
|
||||||
ST r3, r254, 88a, 8h
|
ST r2, r254, 88a, 8h
|
||||||
LI64 r7, 3d
|
LI64 r6, 3d
|
||||||
ST r7, r254, 32a, 8h
|
ST r6, r254, 32a, 8h
|
||||||
LI64 r10, 4d
|
LI64 r9, 4d
|
||||||
ST r10, r254, 40a, 8h
|
ST r9, r254, 40a, 8h
|
||||||
LD r4, r254, 32a, 8h
|
|
||||||
LD r5, r254, 80a, 8h
|
|
||||||
ADDI64 r3, r254, 0d
|
|
||||||
ADD64 r7, r4, r5
|
|
||||||
ST r7, r254, 0a, 8h
|
|
||||||
LD r11, r254, 40a, 8h
|
|
||||||
LD r12, r254, 88a, 8h
|
|
||||||
ADD64 r4, r11, r12
|
|
||||||
ST r4, r254, 8a, 8h
|
|
||||||
LD r6, r254, 80a, 8h
|
|
||||||
LD r7, r254, 32a, 8h
|
|
||||||
SUB64 r9, r7, r6
|
|
||||||
ST r9, r254, 16a, 8h
|
|
||||||
LD r1, r254, 88a, 8h
|
|
||||||
LD r4, r254, 40a, 8h
|
|
||||||
SUB64 r4, r4, r1
|
|
||||||
ST r4, r254, 24a, 8h
|
|
||||||
ADDI64 r7, r254, 112d
|
|
||||||
BMC r3, r7, 32h
|
|
||||||
LI64 r10, 0d
|
|
||||||
ST r10, r254, 96a, 8h
|
|
||||||
ST r10, r254, 104a, 8h
|
|
||||||
LD r3, r254, 32a, 8h
|
LD r3, r254, 32a, 8h
|
||||||
LD r4, r254, 96a, 8h
|
LD r4, r254, 80a, 8h
|
||||||
ADDI64 r10, r254, 48d
|
ADDI64 r2, r254, 0d
|
||||||
SUB64 r7, r4, r3
|
ADD64 r6, r3, r4
|
||||||
ST r7, r254, 48a, 8h
|
ST r6, r254, 0a, 8h
|
||||||
LD r11, r254, 40a, 8h
|
LD r10, r254, 40a, 8h
|
||||||
LD r12, r254, 104a, 8h
|
LD r11, r254, 88a, 8h
|
||||||
SUB64 r3, r12, r11
|
ADD64 r3, r10, r11
|
||||||
ST r3, r254, 56a, 8h
|
ST r3, r254, 8a, 8h
|
||||||
ADDI64 r12, r10, 16d
|
LD r5, r254, 80a, 8h
|
||||||
BMC r2, r12, 16h
|
LD r6, r254, 32a, 8h
|
||||||
LD r9, r254, 112a, 8h
|
SUB64 r8, r6, r5
|
||||||
LD r10, r254, 48a, 8h
|
ST r8, r254, 16a, 8h
|
||||||
ADD64 r12, r10, r9
|
LD r12, r254, 88a, 8h
|
||||||
ST r12, r254, 48a, 8h
|
LD r3, r254, 40a, 8h
|
||||||
LD r4, r254, 120a, 8h
|
SUB64 r3, r3, r12
|
||||||
LD r5, r254, 56a, 8h
|
ST r3, r254, 24a, 8h
|
||||||
ADD64 r7, r4, r5
|
ADDI64 r6, r254, 112d
|
||||||
ST r7, r254, 56a, 8h
|
BMC r2, r6, 32h
|
||||||
LD r12, r254, 128a, 8h
|
LI64 r9, 0d
|
||||||
|
ST r9, r254, 96a, 8h
|
||||||
|
ST r9, r254, 104a, 8h
|
||||||
|
LD r2, r254, 32a, 8h
|
||||||
|
LD r3, r254, 96a, 8h
|
||||||
|
ADDI64 r9, r254, 48d
|
||||||
|
SUB64 r6, r3, r2
|
||||||
|
ST r6, r254, 48a, 8h
|
||||||
|
LD r10, r254, 40a, 8h
|
||||||
|
LD r11, r254, 104a, 8h
|
||||||
|
SUB64 r2, r11, r10
|
||||||
|
ST r2, r254, 56a, 8h
|
||||||
|
ADDI64 r11, r9, 16d
|
||||||
|
BMC r1, r11, 16h
|
||||||
|
LD r8, r254, 112a, 8h
|
||||||
|
LD r9, r254, 48a, 8h
|
||||||
|
ADD64 r11, r9, r8
|
||||||
|
ST r11, r254, 48a, 8h
|
||||||
|
LD r3, r254, 120a, 8h
|
||||||
|
LD r4, r254, 56a, 8h
|
||||||
|
ADD64 r6, r3, r4
|
||||||
|
ST r6, r254, 56a, 8h
|
||||||
|
LD r11, r254, 128a, 8h
|
||||||
|
LD r12, r254, 64a, 8h
|
||||||
|
ADD64 r2, r11, r12
|
||||||
|
ST r2, r254, 64a, 8h
|
||||||
|
LD r6, r254, 136a, 8h
|
||||||
|
LD r7, r254, 72a, 8h
|
||||||
|
ADD64 r9, r6, r7
|
||||||
|
ST r9, r254, 72a, 8h
|
||||||
LD r1, r254, 64a, 8h
|
LD r1, r254, 64a, 8h
|
||||||
ADD64 r3, r12, r1
|
LD r2, r254, 48a, 8h
|
||||||
ST r3, r254, 64a, 8h
|
ADD64 r4, r1, r2
|
||||||
LD r7, r254, 136a, 8h
|
ST r4, r254, 152a, 8h
|
||||||
LD r8, r254, 72a, 8h
|
LD r8, r254, 72a, 8h
|
||||||
ADD64 r10, r7, r8
|
LD r9, r254, 56a, 8h
|
||||||
ST r10, r254, 72a, 8h
|
ADD64 r11, r8, r9
|
||||||
LD r2, r254, 64a, 8h
|
ST r11, r254, 160a, 8h
|
||||||
LD r3, r254, 48a, 8h
|
LD r2, r254, 152a, 8h
|
||||||
ADD64 r5, r2, r3
|
ADD64 r1, r2, r11
|
||||||
ST r5, r254, 152a, 8h
|
|
||||||
LD r9, r254, 72a, 8h
|
|
||||||
LD r10, r254, 56a, 8h
|
|
||||||
ADD64 r12, r9, r10
|
|
||||||
ST r12, r254, 160a, 8h
|
|
||||||
LD r3, r254, 152a, 8h
|
|
||||||
ADD64 r1, r3, r12
|
|
||||||
1: ADDI64 r254, r254, 168d
|
1: ADDI64 r254, r254, 168d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
code size: 1145
|
code size: 1145
|
||||||
|
|
|
@ -25,8 +25,9 @@ fib_iter:
|
||||||
CP r10, r4
|
CP r10, r4
|
||||||
2: JNE r2, r5, :0
|
2: JNE r2, r5, :0
|
||||||
JMP :1
|
JMP :1
|
||||||
0: ADD64 r3, r10, r1
|
0: ADD64 r1, r10, r1
|
||||||
SUB64 r2, r2, r4
|
SUB64 r2, r2, r4
|
||||||
|
CP r3, r1
|
||||||
CP r1, r10
|
CP r1, r10
|
||||||
CP r10, r3
|
CP r10, r3
|
||||||
JMP :2
|
JMP :2
|
||||||
|
@ -48,6 +49,6 @@ main:
|
||||||
LD r31, r254, 2a, 24h
|
LD r31, r254, 2a, 24h
|
||||||
ADDI64 r254, r254, 26d
|
ADDI64 r254, r254, 26d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
code size: 351
|
code size: 354
|
||||||
ret: 0
|
ret: 0
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
|
@ -15,19 +15,19 @@ main:
|
||||||
ADDI64 r2, r254, 32d
|
ADDI64 r2, r254, 32d
|
||||||
JAL r31, r0, :foo
|
JAL r31, r0, :foo
|
||||||
ST r1, r254, 32a, 16h
|
ST r1, r254, 32a, 16h
|
||||||
ADDI64 r8, r254, 16d
|
ADDI64 r7, r254, 16d
|
||||||
JAL r31, r0, :foo
|
JAL r31, r0, :foo
|
||||||
ST r1, r254, 16a, 16h
|
ST r1, r254, 16a, 16h
|
||||||
ADDI64 r2, r254, 0d
|
ADDI64 r2, r254, 0d
|
||||||
JAL r31, r0, :foo
|
JAL r31, r0, :foo
|
||||||
ST r1, r254, 0a, 16h
|
ST r1, r254, 0a, 16h
|
||||||
LD r2, r254, 24a, 4h
|
LD r1, r254, 24a, 4h
|
||||||
LD r7, r254, 12a, 4h
|
LD r7, r254, 12a, 4h
|
||||||
ANDI r5, r2, 4294967295d
|
ANDI r4, r1, 4294967295d
|
||||||
LD r1, r254, 32a, 8h
|
LD r1, r254, 32a, 8h
|
||||||
ANDI r11, r7, 4294967295d
|
ANDI r11, r7, 4294967295d
|
||||||
ADD64 r10, r1, r5
|
ADD64 r8, r1, r4
|
||||||
ADD64 r2, r10, r11
|
ADD64 r2, r8, r11
|
||||||
LI64 r3, 7d
|
LI64 r3, 7d
|
||||||
SUB64 r1, r3, r2
|
SUB64 r1, r3, r2
|
||||||
LD r31, r254, 48a, 8h
|
LD r31, r254, 48a, 8h
|
||||||
|
|
|
@ -2,26 +2,26 @@ main:
|
||||||
ADDI64 r254, r254, -10240d
|
ADDI64 r254, r254, -10240d
|
||||||
LI8 r6, 64b
|
LI8 r6, 64b
|
||||||
LI64 r7, 1024d
|
LI64 r7, 1024d
|
||||||
LI64 r9, 1d
|
LI64 r8, 1d
|
||||||
LI64 r8, 0d
|
LI64 r9, 0d
|
||||||
ADDI64 r5, r254, 0d
|
ADDI64 r5, r254, 0d
|
||||||
4: JLTU r8, r7, :0
|
4: JLTU r9, r7, :0
|
||||||
LI64 r6, 10d
|
LI64 r4, 10d
|
||||||
CP r7, r9
|
CP r6, r8
|
||||||
3: JLTU r7, r6, :1
|
3: JLTU r6, r4, :1
|
||||||
LD r12, r254, 2048a, 1h
|
LD r10, r254, 2048a, 1h
|
||||||
ANDI r1, r12, 255d
|
ANDI r1, r10, 255d
|
||||||
JMP :2
|
JMP :2
|
||||||
1: ADD64 r2, r7, r9
|
1: ADD64 r12, r6, r8
|
||||||
MULI64 r1, r7, 1024d
|
MULI64 r1, r6, 1024d
|
||||||
ADD64 r7, r5, r1
|
ADD64 r6, r5, r1
|
||||||
BMC r5, r7, 1024h
|
BMC r5, r6, 1024h
|
||||||
CP r7, r2
|
CP r6, r12
|
||||||
JMP :3
|
JMP :3
|
||||||
0: ADD64 r2, r8, r9
|
0: ADD64 r1, r9, r8
|
||||||
ADD64 r8, r5, r8
|
ADD64 r10, r5, r9
|
||||||
ST r6, r8, 0a, 1h
|
ST r6, r10, 0a, 1h
|
||||||
CP r8, r2
|
CP r9, r1
|
||||||
JMP :4
|
JMP :4
|
||||||
2: ADDI64 r254, r254, 10240d
|
2: ADDI64 r254, r254, 10240d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
|
|
|
@ -6,10 +6,10 @@ main:
|
||||||
CP r3, r4
|
CP r3, r4
|
||||||
JAL r31, r0, :maina
|
JAL r31, r0, :maina
|
||||||
ST r1, r254, 0a, 16h
|
ST r1, r254, 0a, 16h
|
||||||
LD r9, r254, 12a, 1h
|
LD r8, r254, 12a, 1h
|
||||||
LD r8, r254, 3a, 1h
|
LD r9, r254, 3a, 1h
|
||||||
SUB8 r12, r8, r9
|
SUB8 r11, r9, r8
|
||||||
ANDI r1, r12, 255d
|
ANDI r1, r11, 255d
|
||||||
LD r31, r254, 16a, 8h
|
LD r31, r254, 16a, 8h
|
||||||
ADDI64 r254, r254, 24d
|
ADDI64 r254, r254, 24d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
|
|
|
@ -99,7 +99,6 @@ impl<PfH: HandlePageFault, const OUT_PROG_EXEC: bool> SoftPagedMem<'_, PfH, OUT_
|
||||||
/// to a specified function.
|
/// to a specified function.
|
||||||
///
|
///
|
||||||
/// If page is not found, execute page fault trap handler.
|
/// If page is not found, execute page fault trap handler.
|
||||||
#[allow(clippy::too_many_arguments)] // Silence peasant
|
|
||||||
fn memory_access(
|
fn memory_access(
|
||||||
&mut self,
|
&mut self,
|
||||||
reason: MemoryAccessReason,
|
reason: MemoryAccessReason,
|
||||||
|
|
|
@ -17,9 +17,8 @@ use {
|
||||||
|
|
||||||
macro_rules! handler {
|
macro_rules! handler {
|
||||||
($self:expr, |$ty:ident ($($ident:pat),* $(,)?)| $expr:expr) => {{
|
($self:expr, |$ty:ident ($($ident:pat),* $(,)?)| $expr:expr) => {{
|
||||||
#[allow(unused_unsafe)]
|
let $ty($($ident),*) = $self.decode::<$ty>();
|
||||||
let $ty($($ident),*) = unsafe { $self.decode::<$ty>() };
|
let e = $expr;
|
||||||
#[allow(clippy::no_effect)] let e = $expr;
|
|
||||||
$self.bump_pc::<$ty>();
|
$self.bump_pc::<$ty>();
|
||||||
e
|
e
|
||||||
}};
|
}};
|
||||||
|
@ -475,22 +474,24 @@ where
|
||||||
/// Fused division-remainder
|
/// Fused division-remainder
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
unsafe fn dir<T: ValueVariant + CheckedDivRem>(&mut self) {
|
unsafe fn dir<T: ValueVariant + CheckedDivRem>(&mut self) {
|
||||||
handler!(self, |OpsRRRR(td, tr, a0, a1)| {
|
unsafe {
|
||||||
let a0 = self.read_reg(a0).cast::<T>();
|
handler!(self, |OpsRRRR(td, tr, a0, a1)| {
|
||||||
let a1 = self.read_reg(a1).cast::<T>();
|
let a0 = self.read_reg(a0).cast::<T>();
|
||||||
|
let a1 = self.read_reg(a1).cast::<T>();
|
||||||
|
|
||||||
if let Some(div) = a0.checked_div(a1) {
|
if let Some(div) = a0.checked_div(a1) {
|
||||||
self.write_reg(td, div);
|
self.write_reg(td, div);
|
||||||
} else {
|
} else {
|
||||||
self.write_reg(td, -1_i64);
|
self.write_reg(td, -1_i64);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(rem) = a0.checked_rem(a1) {
|
if let Some(rem) = a0.checked_rem(a1) {
|
||||||
self.write_reg(tr, rem);
|
self.write_reg(tr, rem);
|
||||||
} else {
|
} else {
|
||||||
self.write_reg(tr, a0);
|
self.write_reg(tr, a0);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fused multiply-add
|
/// Fused multiply-add
|
||||||
|
@ -499,22 +500,26 @@ where
|
||||||
where
|
where
|
||||||
T: ValueVariant + core::ops::Mul<Output = T> + core::ops::Add<Output = T>,
|
T: ValueVariant + core::ops::Mul<Output = T> + core::ops::Add<Output = T>,
|
||||||
{
|
{
|
||||||
handler!(self, |OpsRRRR(tg, a0, a1, a2)| {
|
unsafe {
|
||||||
let a0 = self.read_reg(a0).cast::<T>();
|
handler!(self, |OpsRRRR(tg, a0, a1, a2)| {
|
||||||
let a1 = self.read_reg(a1).cast::<T>();
|
let a0 = self.read_reg(a0).cast::<T>();
|
||||||
let a2 = self.read_reg(a2).cast::<T>();
|
let a1 = self.read_reg(a1).cast::<T>();
|
||||||
self.write_reg(tg, a0 * a1 + a2)
|
let a2 = self.read_reg(a2).cast::<T>();
|
||||||
});
|
self.write_reg(tg, a0 * a1 + a2)
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Float comparsion
|
/// Float comparsion
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
unsafe fn fcmp<T: PartialOrd + ValueVariant>(&mut self, nan: Ordering) {
|
unsafe fn fcmp<T: PartialOrd + ValueVariant>(&mut self, nan: Ordering) {
|
||||||
handler!(self, |OpsRRR(tg, a0, a1)| {
|
unsafe {
|
||||||
let a0 = self.read_reg(a0).cast::<T>();
|
handler!(self, |OpsRRR(tg, a0, a1)| {
|
||||||
let a1 = self.read_reg(a1).cast::<T>();
|
let a0 = self.read_reg(a0).cast::<T>();
|
||||||
self.write_reg(tg, (a0.partial_cmp(&a1).unwrap_or(nan) as i8 + 1) as u8)
|
let a1 = self.read_reg(a1).cast::<T>();
|
||||||
});
|
self.write_reg(tg, (a0.partial_cmp(&a1).unwrap_or(nan) as i8 + 1) as u8)
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calculate pc-relative address
|
/// Calculate pc-relative address
|
||||||
|
|
Loading…
Reference in a new issue