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