Compare commits

...

22 commits

Author SHA1 Message Date
peony 5964857423 Merge remote-tracking branch 'holey-bytes-main/trunk' into trunk 2024-11-07 21:32:24 +01:00
Jakub Doka 0374848b28
fixing formatter not reporting errors 2024-11-07 17:02:22 +01:00
Jakub Doka 513d2c7127
removing log line 2024-11-07 16:42:57 +01:00
Jakub Doka 9d2f419140
fixing messed up flag calculation 2024-11-07 16:39:15 +01:00
Jakub Doka f535ea7b0a
ups, left log lines 2024-11-07 16:05:16 +01:00
Jakub Doka be6d0d3f18
removing wrong graph query in a peephole 2024-11-07 10:47:31 +01:00
Jakub Doka 2718ef8523
ups 2024-11-07 10:43:45 +01:00
Jakub Doka 3ee78f3a31
fixing bugs from the new tests 2024-11-07 10:43:29 +01:00
Jakub Doka 2bac7c1fb3
saving 2024-11-07 08:53:11 +01:00
mlokis 79a3f1ab2b Merge pull request 'various tests' (#23) from koniifer/holey-bytes:trunk into trunk
Reviewed-on: https://git.ablecorp.us/AbleOS/holey-bytes/pulls/23
Reviewed-by: mlokis <mlokis@email.com>
2024-11-07 01:49:56 -06:00
koniifer b15e66b2af test broken sin function 2024-11-06 17:35:01 +00:00
koniifer d2ba7cc101 returning optional issues test 2024-11-06 15:17:03 +00:00
koniifer d3ee72306e optional from eca test 2024-11-05 18:07:04 +00:00
Jakub Doka 87cb77a553
making a Backend trait to separate the different backends we will have in the fucture 2024-11-05 14:52:30 +01:00
Jakub Doka 276d1bb0cf
fixing tab indentation in error messages and depell not displaying errors 2024-11-05 09:41:57 +01:00
Jakub Doka 5cce904135
fixing struct null check on function arguments 2024-11-04 19:57:15 +01:00
Jakub Doka 3338d50672
nasty bug with rescheduled load 2024-11-04 19:18:37 +01:00
Jakub Doka 2e36f32ae0
fixing very sneaky bug 2024-11-04 12:38:47 +01:00
Jakub Doka e8f1d2af8c
allowing 0 idk 2024-11-03 22:54:05 +01:00
Jakub Doka 999b25df8b
adding '_ = <expr>' syntax 2024-11-03 22:27:37 +01:00
Jakub Doka 61250c906a
comparison of non null types to null are now errors 2024-11-03 21:31:46 +01:00
Jakub Doka 44fc9c3e2e
deferring all null checks after the peepholes 2024-11-03 21:13:24 +01:00
53 changed files with 3780 additions and 2201 deletions

1
.gitignore vendored
View file

@ -9,4 +9,5 @@ db.sqlite-journal
# assets
/depell/src/*.gz
/depell/src/*.wasm
#**/*-sv.rs
/bytecode/src/instrs.rs

52
Cargo.lock generated
View file

@ -276,15 +276,15 @@ dependencies = [
[[package]]
name = "bytes"
version = "1.7.2"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3"
checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da"
[[package]]
name = "cc"
version = "1.1.30"
version = "1.1.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b16803a61b81d9eabb7eae2588776c4c1e584b738ede45fdbb4c972cec1e9945"
checksum = "baee610e9452a8f6f0a1b6194ec09ff9e2d85dea54432acdae41aa0761c95d70"
dependencies = [
"jobserver",
"libc",
@ -721,9 +721,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
[[package]]
name = "hyper"
version = "1.4.1"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05"
checksum = "bbbff0a806a4728c99295b254c8838933b5b082d75e3cb70c8dab21fdfbcfa9a"
dependencies = [
"bytes",
"futures-channel",
@ -741,9 +741,9 @@ dependencies = [
[[package]]
name = "hyper-util"
version = "0.1.9"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41296eb09f183ac68eec06e03cdbea2e759633d4067b2f6552fc2e009bcad08b"
checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4"
dependencies = [
"bytes",
"futures-util",
@ -979,18 +979,18 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
[[package]]
name = "pin-project"
version = "1.1.6"
version = "1.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf123a161dde1e524adf36f90bc5d8d3462824a9c43553ad07a8183161189ec"
checksum = "be57f64e946e500c8ee36ef6331845d40a93055567ec57e8fae13efd33759b95"
dependencies = [
"pin-project-internal",
]
[[package]]
name = "pin-project-internal"
version = "1.1.6"
version = "1.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4502d8515ca9f32f1fb543d987f63d95a14934883db45bdb48060b6b69257f8"
checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c"
dependencies = [
"proc-macro2",
"quote",
@ -999,9 +999,9 @@ dependencies = [
[[package]]
name = "pin-project-lite"
version = "0.2.14"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff"
[[package]]
name = "pin-utils"
@ -1073,9 +1073,9 @@ dependencies = [
[[package]]
name = "regex"
version = "1.11.0"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8"
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
dependencies = [
"aho-corasick",
"memchr",
@ -1162,9 +1162,9 @@ dependencies = [
[[package]]
name = "rustls"
version = "0.23.14"
version = "0.23.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "415d9944693cb90382053259f89fbb077ea730ad7273047ec63b19bc9b160ba8"
checksum = "eee87ff5d9b36712a58574e12e9f0ea80f915a5b0ac518d322b24a465617925e"
dependencies = [
"aws-lc-rs",
"once_cell",
@ -1185,9 +1185,9 @@ dependencies = [
[[package]]
name = "rustls-pki-types"
version = "1.9.0"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e696e35370c65c9c541198af4543ccd580cf17fc25d8e05c5a242b202488c55"
checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b"
[[package]]
name = "rustls-webpki"
@ -1203,9 +1203,9 @@ dependencies = [
[[package]]
name = "rustversion"
version = "1.0.17"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6"
checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248"
[[package]]
name = "ryu"
@ -1241,9 +1241,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.128"
version = "1.0.132"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8"
checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03"
dependencies = [
"itoa",
"memchr",
@ -1366,9 +1366,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
[[package]]
name = "tokio"
version = "1.40.0"
version = "1.41.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998"
checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33"
dependencies = [
"backtrace",
"bytes",

View file

@ -6,7 +6,7 @@ use {
alloc::{string::String, vec::Vec},
hblang::{
parser::FileId,
son::{Codegen, CodegenCtx},
son::{hbvm::HbvmBackend, Codegen, CodegenCtx},
},
};
@ -55,8 +55,9 @@ unsafe fn compile_and_run(mut fuel: usize) {
files
};
let mut ctx = CodegenCtx::default();
let files = {
let mut ctx = hblang::parser::Ctx::default();
let paths = files.iter().map(|f| f.path).collect::<Vec<_>>();
let mut loader = |path: &str, _: &str, kind| match kind {
hblang::parser::FileKind::Module => Ok(paths.binary_search(&path).unwrap() as FileId),
@ -69,7 +70,7 @@ unsafe fn compile_and_run(mut fuel: usize) {
f.path,
// since 'free' does nothing this is fine
String::from_raw_parts(f.code.as_mut_ptr(), f.code.len(), f.code.len()),
&mut ctx,
&mut ctx.parser,
&mut loader,
)
})
@ -77,9 +78,15 @@ unsafe fn compile_and_run(mut fuel: usize) {
};
let mut ct = {
let mut ctx = CodegenCtx::default();
let mut c = Codegen::new(&files, &mut ctx);
c.generate(root as FileId);
let mut backend = HbvmBackend::default();
Codegen::new(&mut backend, &files, &mut ctx).generate(root as FileId);
if !ctx.parser.errors.borrow().is_empty() {
log::error!("{}", ctx.parser.errors.borrow());
return;
}
let mut c = Codegen::new(&mut backend, &files, &mut ctx);
c.assemble_comptime()
};

47
f.txt
View file

@ -1,47 +0,0 @@
start: 0
46-c65535: +: [0, 38, 45] [47]
45-c65535: &: [0, 43, 44] [46]
44-c65535: cint: #255 [0] [45]
43-c65535: load: [0, 42, 23] [45]
42-c65535: +: [0, 22, 18] [43]
39-c65535: stre: [0, 0, 36, 37] [47]
39-c65535: stre: [0, 0, 36, 37] [47]
37-c65535: stre: [0, 35, 36, 3] [38, 39]
36-c65535: stck: [0, 3] [37, 38, 39]
35-c65535: load: [0, 24, 34] [37]
34-c65535: stre: [0, 31, 33, 30] [35, 47]
33-c65535: +: [0, 24, 32] [34]
32-c65535: cint: #16 [0] [33]
31-c65535: cint: #4 [0] [34]
30-c65535: stre: [0, 27, 29, 26] [34]
29-c65535: +: [0, 24, 28] [30]
28-c65535: cint: #8 [0] [29]
27-c65535: cint: #2 [0] [30]
26-c65535: stre: [0, 25, 24, 3] [30]
25-c65535: cint: #1 [0] [26]
24-c65535: stck: [0, 3] [26, 29, 33, 35]
23-c65535: stre: [0, 21, 22, 3] [43, 47]
22-c65535: stck: [0, 3] [23, 42]
21-c65535: load: [0, 6, 20] [23]
20-c65535: stre: [0, 17, 19, 14] [21, 47]
19-c65535: +: [0, 6, 18] [20]
18-c65535: cint: #3 [0] [19, 42]
17-c65535: cint: #1 [0] [20]
14-c65535: stre: [0, 5, 13, 11] [20]
13-c65535: +: [0, 6, 12] [14]
12-c65535: cint: #2 [0] [13]
11-c65535: stre: [0, 7, 10, 8] [14]
10-c65535: +: [0, 6, 9] [11]
9-c65535: cint: #1 [0] [10]
8-c65535: stre: [0, 7, 6, 3] [11]
7-c65535: cint: #0 [0] [8, 11]
6-c65535: stck: [0, 3] [8, 10, 13, 19, 21]
5-c65535: cint: #511 [0] [14]
4-c65535: loops: [0] []
3-c65535: mem: [0] [6, 8, 22, 23, 24, 26, 36, 37, 47]
2-c65535: ctrl: entry [0] [38]
b2: 0 0 [38]
38-c65535: call: 1 0 [2, 36, 37] [46, 47]
47-c65535: ret: [38, 46, 3, 20, 23, 34, 39] [1]

38
f1.txt
View file

@ -1,38 +0,0 @@
start: 0
34-c65535: stre: [0, 31, 51, 30] [39, 47, 38]
51-c65535: +: [0, 36, 32] [34]
32-c65535: cint: #16 [0] [51]
31-c65535: cint: #4 [0] [34]
30-c65535: stre: [0, 27, 50, 26] [34]
50-c65535: +: [0, 36, 28] [30]
28-c65535: cint: #8 [0] [50]
27-c65535: cint: #2 [0] [30]
26-c65535: stre: [0, 25, 36, 3] [30]
25-c65535: cint: #1 [0] [26, 46]
39-c65535: stre: [0, 0, 36, 34] [47]
36-c65535: stck: [0, 3] [51, 38, 39, 26, 50]
22-c65535: stck: [0, 3] [49, 42, 8, 48]
39-c65535: stre: [0, 0, 36, 34] [47]
20-c65535: stre: [0, 17, 42, 14] [47, 47]
46-c65535: +: [0, 38, 25] [47]
18-c65535: cint: #3 [0] [42]
17-c65535: cint: #1 [0] [20]
14-c65535: stre: [0, 5, 49, 11] [20]
49-c65535: +: [0, 22, 12] [14]
12-c65535: cint: #2 [0] [49]
11-c65535: stre: [0, 7, 48, 8] [14]
48-c65535: +: [0, 22, 9] [11]
9-c65535: cint: #1 [0] [48]
8-c65535: stre: [0, 7, 22, 3] [11]
7-c65535: cint: #0 [0] [8, 11]
42-c65535: +: [0, 22, 18] [20]
5-c65535: cint: #511 [0] [14]
4-c65535: loops: [0] []
3-c65535: mem: [0] [47, 8, 22, 26, 36]
2-c65535: ctrl: entry [0] [38]
b2: 0 0 [38]
38-c65535: call: 1 0 [2, 36, 34] [46, 47]
47-c65535: ret: [38, 46, 3, 20, 20, 34, 39] [1]

39
f2.txt
View file

@ -1,39 +0,0 @@
start: 0
42-c65535: +: [0, 22, 18] [43, 20]
36-c65535: stck: [0, 3] [51, 38, 39, 26, 50]
39-c65535: stre: [0, 0, 36, 34] [47]
34-c65535: stre: [0, 31, 51, 30] [39, 47, 38]
51-c65535: +: [0, 36, 32] [34]
32-c65535: cint: #16 [0] [51]
31-c65535: cint: #4 [0] [34]
30-c65535: stre: [0, 27, 50, 26] [34]
50-c65535: +: [0, 36, 28] [30]
28-c65535: cint: #8 [0] [50]
27-c65535: cint: #2 [0] [30]
26-c65535: stre: [0, 25, 36, 3] [30]
25-c65535: cint: #1 [0] [26]
39-c65535: stre: [0, 0, 36, 34] [47]
45-c65535: &: [0, 43, 44] [46]
22-c65535: stck: [0, 3] [49, 42, 8, 48]
44-c65535: cint: #255 [0] [45]
20-c65535: stre: [0, 17, 42, 14] [47, 47, 43]
46-c65535: +: [0, 38, 45] [47]
18-c65535: cint: #3 [0] [42]
17-c65535: cint: #1 [0] [20]
14-c65535: stre: [0, 5, 49, 11] [20]
49-c65535: +: [0, 22, 12] [14]
12-c65535: cint: #2 [0] [49]
11-c65535: stre: [0, 7, 48, 8] [14]
48-c65535: +: [0, 22, 9] [11]
9-c65535: cint: #1 [0] [48]
8-c65535: stre: [0, 7, 22, 3] [11]
7-c65535: cint: #0 [0] [8, 11]
43-c65535: load: [0, 42, 20] [45]
5-c65535: cint: #511 [0] [14]
4-c65535: loops: [0] []
3-c65535: mem: [0] [47, 8, 22, 26, 36]
2-c65535: ctrl: entry [0] [38]
b2: 0 0 [38]
38-c65535: call: 1 0 [2, 36, 34] [46, 47]
47-c65535: ret: [38, 46, 3, 20, 20, 34, 39] [1]

File diff suppressed because one or more lines are too long

View file

@ -346,6 +346,7 @@ impl<'a> Formatter<'a> {
self.fmt(val, f)
}
Expr::Return { val: None, .. } => f.write_str("return"),
Expr::Wildcard { .. } => f.write_str("_"),
Expr::Ident { pos, is_ct, .. } => {
if is_ct {
f.write_str("$")?;

View file

@ -1,7 +1,7 @@
use {
crate::{
parser::{self, Ast, Ctx, FileKind},
son,
son::{self, hbvm::HbvmBackend},
},
alloc::{string::String, vec::Vec},
core::{fmt::Write, num::NonZeroUsize, ops::Deref},
@ -81,16 +81,27 @@ pub fn run_compiler(root_file: &str, options: Options, out: &mut Vec<u8>) -> std
}
if options.fmt {
if !parsed.errors.is_empty() {
*out = parsed.errors.into_bytes();
return Err(std::io::Error::other("parsing fialed"));
}
for parsed in parsed.ast {
format_ast(parsed)?;
}
} else if options.fmt_stdout {
if !parsed.errors.is_empty() {
*out = parsed.errors.into_bytes();
return Err(std::io::Error::other("parsing fialed"));
}
let ast = parsed.ast.into_iter().next().unwrap();
write!(out, "{ast}").unwrap();
} else {
let mut backend = HbvmBackend::default();
let mut ctx = crate::son::CodegenCtx::default();
*ctx.parser.errors.get_mut() = parsed.errors;
let mut codegen = son::Codegen::new(&parsed.ast, &mut ctx);
let mut codegen = son::Codegen::new(&mut backend, &parsed.ast, &mut ctx);
codegen.push_embeds(parsed.embeds);
codegen.generate(0);
@ -100,12 +111,12 @@ pub fn run_compiler(root_file: &str, options: Options, out: &mut Vec<u8>) -> std
return Err(std::io::Error::other("compilation faoled"));
}
codegen.assemble(out);
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);
let mut disasm = String::new();
codegen.disasm(&mut disasm, out).map_err(|e| io::Error::other(e.to_string()))?;
*out = disasm.into_bytes();
}
}

View file

@ -2,7 +2,7 @@ use {
crate::{
lexer::TokenKind,
parser,
son::{Codegen, CodegenCtx},
son::{hbvm::HbvmBackend, Codegen, CodegenCtx},
},
alloc::string::String,
core::{fmt::Write, hash::BuildHasher, ops::Range},
@ -133,7 +133,8 @@ pub fn fuzz(seed_range: Range<u64>) {
assert!(ctx.parser.errors.get_mut().is_empty());
let mut cdg = Codegen::new(core::slice::from_ref(&parsed), &mut ctx);
let mut backend = HbvmBackend::default();
let mut cdg = Codegen::new(&mut backend, core::slice::from_ref(&parsed), &mut ctx);
cdg.generate(0);
}
}

View file

@ -148,6 +148,7 @@ pub enum TokenKind {
RBrack = b']',
Xor = b'^',
Tick = b'`',
Under = b'_',
// Unused = a-z
LBrace = b'{',
Bor = b'|',
@ -308,6 +309,7 @@ gen_token_kind! {
Null = b"null",
Idk = b"idk",
Die = b"die",
Under = b"_",
#[punkt]
Ctor = ".{",
Tupl = ".(",

View file

@ -219,26 +219,6 @@ mod ctx_map {
}
}
mod task {
use super::Offset;
pub fn unpack(offset: Offset) -> Result<Offset, usize> {
if offset >> 31 != 0 {
Err((offset & !(1 << 31)) as usize)
} else {
Ok(offset)
}
}
pub fn is_done(offset: Offset) -> bool {
unpack(offset).is_ok()
}
pub fn id(index: usize) -> Offset {
1 << 31 | index as u32
}
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default, Debug)]
pub struct Ident(u32);
@ -567,6 +547,7 @@ mod ty {
};)*
}
#[expect(dead_code)]
impl Id {
$(pub const $name: Self = Kind::Builtin($name).compress();)*
}
@ -758,7 +739,7 @@ pub enum SymKey<'a> {
}
#[derive(Clone, Copy)]
struct Sig {
pub struct Sig {
args: ty::Tuple,
ret: ty::Id,
}
@ -769,10 +750,7 @@ struct Func {
base: Option<ty::Func>,
expr: ExprRef,
sig: Option<Sig>,
offset: Offset,
// TODO: change to indices into common vec
relocs: Vec<TypedReloc>,
code: Vec<u8>,
comp_state: [CompState; 2],
}
impl Default for Func {
@ -783,13 +761,19 @@ impl Default for Func {
base: None,
expr: Default::default(),
sig: None,
offset: u32::MAX,
relocs: Default::default(),
code: Default::default(),
comp_state: Default::default(),
}
}
}
#[derive(Default, PartialEq, Eq)]
enum CompState {
#[default]
Dead,
Queued(usize),
Compiled,
}
#[derive(Clone, Copy)]
struct TypedReloc {
target: ty::Id,
@ -801,7 +785,6 @@ struct Global {
file: FileId,
name: Ident,
ty: ty::Id,
offset: Offset,
data: Vec<u8>,
}
@ -809,7 +792,6 @@ impl Default for Global {
fn default() -> Self {
Self {
ty: Default::default(),
offset: u32::MAX,
data: Default::default(),
file: u32::MAX,
name: Default::default(),
@ -947,9 +929,6 @@ impl IdentInterner {
#[derive(Default)]
struct TypesTmp {
fields: Vec<Field>,
frontier: Vec<ty::Id>,
globals: Vec<ty::Global>,
funcs: Vec<ty::Func>,
args: Vec<ty::Id>,
}
@ -968,6 +947,7 @@ pub struct TypeIns {
struct FTask {
file: FileId,
id: ty::Func,
ct: bool,
}
struct StringRef(ty::Global);
@ -982,7 +962,7 @@ impl ctx_map::CtxEntry for StringRef {
}
#[derive(Default)]
struct Types {
pub struct Types {
syms: ctx_map::CtxMap<ty::Id>,
names: IdentInterner,
strings: ctx_map::CtxMap<StringRef>,
@ -1222,12 +1202,6 @@ impl Types {
&self.ins.fields[self.struct_field_range(strct)]
}
fn reassemble(&mut self, buf: &mut Vec<u8>) {
self.ins.funcs.iter_mut().for_each(|f| f.offset = u32::MAX);
self.ins.globals.iter_mut().for_each(|g| g.offset = u32::MAX);
self.assemble(buf)
}
fn parama(&self, ret: impl Into<ty::Id>) -> (Option<PLoc>, ParamAlloc) {
let mut iter = ParamAlloc(1..12);
let ret = iter.next(ret.into(), self);
@ -1395,9 +1369,6 @@ impl Types {
self.ins.slices.clear();
debug_assert_eq!(self.tmp.fields.len(), 0);
debug_assert_eq!(self.tmp.frontier.len(), 0);
debug_assert_eq!(self.tmp.globals.len(), 0);
debug_assert_eq!(self.tmp.funcs.len(), 0);
debug_assert_eq!(self.tmp.args.len(), 0);
debug_assert_eq!(self.tasks.len(), 0);

View file

@ -392,6 +392,7 @@ impl<'a, 'b> Parser<'a, 'b> {
let (id, is_first) = self.resolve_ident(token);
E::Ident { pos, is_ct: token.kind == T::CtIdent, id, is_first }
}
T::Under => E::Wildcard { pos },
T::If => E::If {
pos,
cond: self.ptr_expr()?,
@ -800,6 +801,9 @@ generate_expr! {
pos: Pos,
val: Option<&'a Self>,
},
Wildcard {
pos: Pos,
},
/// note: ':unicode:' is any utf-8 character except ascii
/// `'[a-zA-Z_:unicode:][a-zA-Z0-9_:unicode:]*'`
Ident {
@ -1163,14 +1167,16 @@ fn report_to(file: &str, path: &str, pos: Pos, msg: &dyn fmt::Display, out: &mut
let line = &file[file[..pos as usize].rfind('\n').map_or(0, |i| i + 1)
..file[pos as usize..].find('\n').map_or(file.len(), |i| i + pos as usize)];
col += line.matches('\t').count() * 3;
col += line.chars().take_while(|c| c.is_whitespace()).filter(|&c| c == '\t').count() * 3;
let mut has_non_whitespace = false;
for char in line.chars() {
if char == '\t' {
if char == '\t' && !has_non_whitespace {
_ = out.write_str(" ");
} else {
_ = out.write_char(char);
}
has_non_whitespace |= !char.is_whitespace();
}
_ = out.write_char('\n');
for _ in 0..col - 1 {

View file

@ -1,150 +1,2 @@
use {crate::reg::Reg, alloc::vec::Vec, core::ops::Range};
type Nid = u16;
pub trait Ctx {
fn uses_of(&self, nid: Nid) -> impl Iterator<Item = Nid>;
fn params_of(&self, nid: Nid) -> impl Iterator<Item = Nid>;
fn args_of(&self, nid: Nid) -> impl Iterator<Item = Nid>;
fn dom_of(&self, nid: Nid) -> Nid;
}
pub struct Env<'a, C: Ctx> {
ctx: &'a C,
func: &'a Func,
res: &'a mut Res,
}
impl<'a, C: Ctx> Env<'a, C> {
pub fn new(ctx: &'a C, func: &'a Func, res: &'a mut Res) -> Self {
Self { ctx, func, res }
}
pub fn run(&mut self) {
self.res.reg_to_node.clear();
self.res.reg_to_node.resize(self.func.instrs.len(), 0);
let mut bundle = Bundle::new(self.func.instrs.len());
for &inst in &self.func.instrs {
for uinst in self.ctx.uses_of(inst) {
let mut cursor = self.ctx.dom_of(uinst);
while cursor != self.ctx.dom_of(inst) {
let mut range = self.func.blocks
[self.func.id_to_block[cursor as usize] as usize]
.range
.clone();
range.start = range.start.max(inst as usize);
range.end = range.end.min(uinst as usize);
bundle.add(range);
cursor = self.ctx.dom_of(cursor);
}
}
match self.res.bundles.iter_mut().enumerate().find(|(_, b)| !b.overlaps(&bundle)) {
Some((i, other)) => {
other.merge(&bundle);
bundle.clear();
self.res.reg_to_node[inst as usize] = i as Reg;
}
None => {
self.res.reg_to_node[inst as usize] = self.res.bundles.len() as Reg;
self.res.bundles.push(bundle);
bundle = Bundle::new(self.func.instrs.len());
}
}
}
}
}
pub struct Res {
bundles: Vec<Bundle>,
pub reg_to_node: Vec<Reg>,
}
pub struct Bundle {
//unit_range: Range<usize>,
//set: BitSet,
taken: Vec<bool>,
}
impl Bundle {
fn new(size: usize) -> Self {
Self { taken: vec![false; size] }
}
fn add(&mut self, range: Range<usize>) {
self.taken[range].fill(true);
}
fn overlaps(&self, other: &Self) -> bool {
self.taken.iter().zip(other.taken.iter()).any(|(a, b)| a & b)
}
fn merge(&mut self, other: &Self) {
debug_assert!(!self.overlaps(other));
self.taken.iter_mut().zip(other.taken.iter()).for_each(|(a, b)| *a = *b);
}
fn clear(&mut self) {
self.taken.fill(false);
}
//fn overlaps(&self, other: &Self) -> bool {
// if self.unit_range.start >= other.unit_range.end
// || self.unit_range.end <= other.unit_range.start
// {
// return false;
// }
// let [mut a, mut b] = [self, other];
// if a.unit_range.start > b.unit_range.start {
// mem::swap(&mut a, &mut b);
// }
// let [mut tmp_a, mut tmp_b] = [0; 2];
// let [units_a, units_b] = [a.set.units(&mut tmp_a), b.set.units(&mut tmp_b)];
// let len = a.unit_range.len().min(b.unit_range.len());
// let [units_a, units_b] =
// [&units_a[b.unit_range.start - a.unit_range.start..][..len], &units_b[..len]];
// units_a.iter().zip(units_b).any(|(&a, &b)| a & b != 0)
//}
//fn merge(mut self, mut other: Self) -> Self {
// debug_assert!(!self.overlaps(&other));
// if self.unit_range.start > other.unit_range.start {
// mem::swap(&mut self, &mut other);
// }
// let final_range = self.unit_range.start..self.unit_range.end.max(other.unit_range.end);
// self.set.reserve(final_range.len());
// let mut tmp = 0;
// let other_units = other.set.units(&mut tmp);
// match self.set.units_mut() {
// Ok(units) => {
// units[other.unit_range.start - self.unit_range.start..]
// .iter_mut()
// .zip(other_units)
// .for_each(|(a, b)| *a |= b);
// }
// Err(view) => view.add_mask(tmp),
// }
// self
//}
}
pub struct Func {
pub blocks: Vec<Block>,
pub instrs: Vec<Nid>,
pub id_to_instr: Vec<Nid>,
pub id_to_block: Vec<Nid>,
}
pub struct Block {
pub range: Range<usize>,
pub start_id: Nid,
pub eld_id: Nid,
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,903 @@
use {
super::{HbvmBackend, Nid, Nodes},
crate::{
lexer::TokenKind,
parser,
reg::{self, Reg},
son::{debug_assert_matches, Kind, ARG_START, MEM, VOID},
ty::{self, Arg, Loc},
utils::{BitSet, Vc},
Offset, PLoc, Reloc, Sig, TypedReloc, Types,
},
alloc::{borrow::ToOwned, vec::Vec},
core::{mem, ops::Range},
hbbytecode::{self as instrs},
};
impl HbvmBackend {
pub fn emit_body_code_my(
&mut self,
nodes: &mut Nodes,
sig: Sig,
tys: &Types,
files: &[parser::Ast],
) -> (usize, bool) {
let mut fuc = Function::new(nodes, tys, sig);
log::info!("{fuc:?}");
let mut res = mem::take(&mut self.ralloc_my);
Env::new(&fuc, &fuc.func, &mut res).run();
'_open_function: {
self.emit(instrs::addi64(reg::STACK_PTR, reg::STACK_PTR, 0));
self.emit(instrs::st(reg::RET_ADDR + fuc.tail as u8, reg::STACK_PTR, 0, 0));
}
let reg_offset = if fuc.tail { reg::RET + 12 } else { reg::RET_ADDR + 1 };
res.node_to_reg.iter_mut().filter(|r| **r != 0).for_each(|r| {
*r += reg_offset - 1;
if fuc.tail && *r >= reg::RET_ADDR {
*r += 1;
}
});
let atr = |allc: Nid| res.node_to_reg[allc as usize];
//for (id, node) in fuc.nodes.iter() {
// if node.kind == Kind::Phi {
// debug_assert_eq!(atr(node.inputs[1]), atr(node.inputs[2]));
// debug_assert_eq!(atr(id), atr(node.inputs[2]));
// }
//}
let (retl, mut parama) = tys.parama(sig.ret);
let mut typs = sig.args.args();
let mut args = fuc.nodes[VOID].outputs[ARG_START..].iter();
while let Some(aty) = typs.next(tys) {
let Arg::Value(ty) = aty else { continue };
let Some(loc) = parama.next(ty, tys) else { continue };
let &arg = args.next().unwrap();
let (rg, size) = match loc {
PLoc::WideReg(rg, size) => (rg, size),
PLoc::Reg(rg, size) if ty.loc(tys) == Loc::Stack => (rg, size),
PLoc::Reg(r, ..) | PLoc::Ref(r, ..) => {
self.emit(instrs::cp(atr(arg), r));
continue;
}
};
self.emit(instrs::st(rg, reg::STACK_PTR, self.offsets[arg as usize] as _, size));
if fuc.nodes[arg].lock_rc == 0 {
self.emit(instrs::addi64(rg, reg::STACK_PTR, self.offsets[arg as usize] as _));
}
self.emit(instrs::cp(atr(arg), rg));
}
for (i, block) in fuc.func.blocks.iter().enumerate() {
self.offsets[block.entry as usize] = self.code.len() as _;
for &nid in &fuc.func.instrs[block.range.clone()] {
if nid == VOID {
continue;
}
let node = &fuc.nodes[nid];
let extend = |base: ty::Id, dest: ty::Id, from: Nid, to: Nid| {
let (bsize, dsize) = (tys.size_of(base), tys.size_of(dest));
debug_assert!(bsize <= 8, "{}", ty::Display::new(tys, files, base));
debug_assert!(dsize <= 8, "{}", ty::Display::new(tys, files, dest));
if bsize == dsize {
return Default::default();
}
match (base.is_signed(), dest.is_signed()) {
(true, true) => {
let op = [instrs::sxt8, instrs::sxt16, instrs::sxt32]
[bsize.ilog2() as usize];
op(atr(to), atr(from))
}
_ => {
let mask = (1u64 << (bsize * 8)) - 1;
instrs::andi(atr(to), atr(from), mask)
}
}
};
match node.kind {
Kind::If => {
let &[_, cnd] = node.inputs.as_slice() else { unreachable!() };
if let Kind::BinOp { op } = fuc.nodes[cnd].kind
&& let Some((op, swapped)) =
op.cond_op(fuc.nodes[fuc.nodes[cnd].inputs[1]].ty)
{
let &[_, lhs, rhs] = fuc.nodes[cnd].inputs.as_slice() else {
unreachable!()
};
self.emit(extend(fuc.nodes[lhs].ty, fuc.nodes[lhs].ty.extend(), 0, 0));
self.emit(extend(fuc.nodes[rhs].ty, fuc.nodes[rhs].ty.extend(), 1, 1));
let rel = Reloc::new(self.code.len(), 3, 2);
self.jump_relocs.push((node.outputs[!swapped as usize], rel));
self.emit(op(atr(lhs), atr(rhs), 0));
} else {
self.emit(extend(fuc.nodes[cnd].ty, fuc.nodes[cnd].ty.extend(), 0, 0));
let rel = Reloc::new(self.code.len(), 3, 2);
self.jump_relocs.push((node.outputs[0], rel));
self.emit(instrs::jne(atr(cnd), reg::ZERO, 0));
}
}
Kind::Loop | Kind::Region => {
if (mem::replace(&mut fuc.backrefs[nid as usize], u16::MAX) != u16::MAX)
^ (node.kind == Kind::Loop)
{
let index = (node.kind == Kind::Loop) as usize + 1;
for &out in node.outputs.iter() {
if fuc.nodes[out].is_data_phi()
&& atr(out) != atr(fuc.nodes[out].inputs[index])
{
self.emit(instrs::cp(
atr(out),
atr(fuc.nodes[out].inputs[index]),
));
}
}
let rel = Reloc::new(self.code.len(), 1, 4);
self.jump_relocs.push((nid, rel));
self.emit(instrs::jmp(0));
} else {
let index = (node.kind != Kind::Loop) as usize + 1;
for &out in node.outputs.iter() {
if fuc.nodes[out].is_data_phi()
&& atr(out) != atr(fuc.nodes[out].inputs[index])
{
self.emit(instrs::cp(
atr(out),
atr(fuc.nodes[out].inputs[index]),
));
}
}
}
}
Kind::Return => {
let &[_, mut ret, ..] = node.inputs.as_slice() else { unreachable!() };
match retl {
None => {}
Some(PLoc::Reg(r, _)) if sig.ret.loc(tys) == Loc::Reg => {
self.emit(instrs::cp(r, atr(ret)));
}
Some(PLoc::Reg(r, size)) | Some(PLoc::WideReg(r, size)) => {
ret = match fuc.nodes[ret].kind {
Kind::Load { .. } => fuc.nodes[ret].inputs[1],
_ => ret,
};
self.emit(instrs::ld(r, atr(ret), 0, size))
}
Some(PLoc::Ref(_, size)) => {
ret = match fuc.nodes[ret].kind {
Kind::Load { .. } => fuc.nodes[ret].inputs[1],
_ => ret,
};
let [src, dst] = [atr(ret), atr(MEM)];
if let Ok(size) = u16::try_from(size) {
self.emit(instrs::bmc(src, dst, size));
} else {
for _ in 0..size / u16::MAX as u32 {
self.emit(instrs::bmc(src, dst, u16::MAX));
self.emit(instrs::addi64(src, src, u16::MAX as _));
self.emit(instrs::addi64(dst, dst, u16::MAX as _));
}
self.emit(instrs::bmc(src, dst, size as u16));
self.emit(instrs::addi64(src, src, size.wrapping_neg() as _));
self.emit(instrs::addi64(dst, dst, size.wrapping_neg() as _));
}
}
}
if i != fuc.func.blocks.len() - 1 {
let rel = Reloc::new(self.code.len(), 1, 4);
self.ret_relocs.push(rel);
self.emit(instrs::jmp(0));
}
}
Kind::Die => self.emit(instrs::un()),
Kind::CInt { value } if node.ty.is_float() => {
self.emit(match node.ty {
ty::Id::F32 => instrs::li32(
atr(nid),
(f64::from_bits(value as _) as f32).to_bits(),
),
ty::Id::F64 => instrs::li64(atr(nid), value as _),
_ => unreachable!(),
});
}
Kind::CInt { value } => self.emit(match tys.size_of(node.ty) {
1 => instrs::li8(atr(nid), value as _),
2 => instrs::li16(atr(nid), value as _),
4 => instrs::li32(atr(nid), value as _),
_ => instrs::li64(atr(nid), value as _),
}),
Kind::UnOp { op } => {
let op = op
.unop(node.ty, fuc.nodes[node.inputs[1]].ty)
.expect("TODO: unary operator not supported");
self.emit(op(atr(nid), atr(node.inputs[1])));
}
Kind::BinOp { .. } if node.lock_rc != 0 => {}
Kind::BinOp { op } => {
let &[.., lhs, rhs] = node.inputs.as_slice() else { unreachable!() };
if let Kind::CInt { value } = fuc.nodes[rhs].kind
&& fuc.nodes[rhs].lock_rc != 0
&& let Some(op) = op.imm_binop(node.ty)
{
self.emit(op(atr(nid), atr(lhs), value as _));
} else if let Some(op) =
op.binop(node.ty).or(op.float_cmp(fuc.nodes[lhs].ty))
{
self.emit(op(atr(nid), atr(lhs), atr(rhs)));
} else if let Some(against) = op.cmp_against() {
let op_ty = fuc.nodes[lhs].ty;
self.emit(extend(fuc.nodes[lhs].ty, fuc.nodes[lhs].ty.extend(), 0, 0));
self.emit(extend(fuc.nodes[rhs].ty, fuc.nodes[rhs].ty.extend(), 1, 1));
if op_ty.is_float() && matches!(op, TokenKind::Le | TokenKind::Ge) {
let opop = match op {
TokenKind::Le => TokenKind::Gt,
TokenKind::Ge => TokenKind::Lt,
_ => unreachable!(),
};
let op_fn = opop.float_cmp(op_ty).unwrap();
self.emit(op_fn(atr(nid), atr(lhs), atr(rhs)));
self.emit(instrs::not(atr(nid), atr(nid)));
} else if op_ty.is_integer() {
let op_fn =
if op_ty.is_signed() { instrs::cmps } else { instrs::cmpu };
self.emit(op_fn(atr(nid), atr(lhs), atr(rhs)));
self.emit(instrs::cmpui(atr(nid), atr(nid), against));
if matches!(op, TokenKind::Eq | TokenKind::Lt | TokenKind::Gt) {
self.emit(instrs::not(atr(nid), atr(nid)));
}
} else {
todo!("unhandled operator: {op}");
}
} else {
todo!("unhandled operator: {op}");
}
}
Kind::Call { args, func } => {
let (ret, mut parama) = tys.parama(node.ty);
let mut args = args.args();
let mut allocs = node.inputs[1..].iter();
while let Some(arg) = args.next(tys) {
let Arg::Value(ty) = arg else { continue };
let Some(loc) = parama.next(ty, tys) else { continue };
let mut arg = *allocs.next().unwrap();
let (rg, size) = match loc {
PLoc::Reg(rg, size) if ty.loc(tys) == Loc::Stack => (rg, size),
PLoc::WideReg(rg, size) => (rg, size),
PLoc::Ref(r, ..) => {
arg = match fuc.nodes[arg].kind {
Kind::Load { .. } => fuc.nodes[arg].inputs[1],
_ => arg,
};
self.emit(instrs::cp(r, atr(arg)));
continue;
}
PLoc::Reg(r, ..) => {
self.emit(instrs::cp(r, atr(arg)));
continue;
}
};
arg = match fuc.nodes[arg].kind {
Kind::Load { .. } => fuc.nodes[arg].inputs[1],
_ => arg,
};
self.emit(instrs::ld(rg, atr(arg), 0, size));
}
debug_assert!(
!matches!(ret, Some(PLoc::Ref(..))) || allocs.next().is_some()
);
if func == ty::ECA {
self.emit(instrs::eca());
} else {
self.relocs.push(TypedReloc {
target: ty::Kind::Func(func).compress(),
reloc: Reloc::new(self.code.len(), 3, 4),
});
self.emit(instrs::jal(reg::RET_ADDR, reg::ZERO, 0));
}
match ret {
Some(PLoc::WideReg(r, size)) => {
debug_assert_eq!(
fuc.nodes[*node.inputs.last().unwrap()].kind,
Kind::Stck
);
let stck = self.offsets[*node.inputs.last().unwrap() as usize];
self.emit(instrs::st(r, reg::STACK_PTR, stck as _, size));
}
Some(PLoc::Reg(r, size)) if node.ty.loc(tys) == Loc::Stack => {
debug_assert_eq!(
fuc.nodes[*node.inputs.last().unwrap()].kind,
Kind::Stck
);
let stck = self.offsets[*node.inputs.last().unwrap() as usize];
self.emit(instrs::st(r, reg::STACK_PTR, stck as _, size));
}
Some(PLoc::Reg(r, ..)) => self.emit(instrs::cp(atr(nid), r)),
None | Some(PLoc::Ref(..)) => {}
}
}
Kind::Global { global } => {
let reloc = Reloc::new(self.code.len(), 3, 4);
self.relocs.push(TypedReloc {
target: ty::Kind::Global(global).compress(),
reloc,
});
self.emit(instrs::lra(atr(nid), 0, 0));
}
Kind::Stck => {
let base = reg::STACK_PTR;
let offset = self.offsets[nid as usize];
self.emit(instrs::addi64(atr(nid), base, offset as _));
}
Kind::Load => {
let mut region = node.inputs[1];
let mut offset = 0;
if fuc.nodes[region].kind == (Kind::BinOp { op: TokenKind::Add })
&& let Kind::CInt { value } =
fuc.nodes[fuc.nodes[region].inputs[2]].kind
{
region = fuc.nodes[region].inputs[1];
offset = value as Offset;
}
let size = tys.size_of(node.ty);
if node.ty.loc(tys) != Loc::Stack {
let (base, offset) = match fuc.nodes[region].kind {
Kind::Stck => {
(reg::STACK_PTR, self.offsets[region as usize] + offset)
}
_ => (atr(region), offset),
};
self.emit(instrs::ld(atr(nid), base, offset as _, size as _));
}
}
Kind::Stre if node.inputs[1] == VOID => {}
Kind::Stre => {
let mut region = node.inputs[2];
let mut offset = 0;
let size = u16::try_from(tys.size_of(node.ty)).expect("TODO");
if fuc.nodes[region].kind == (Kind::BinOp { op: TokenKind::Add })
&& let Kind::CInt { value } =
fuc.nodes[fuc.nodes[region].inputs[2]].kind
&& node.ty.loc(tys) == Loc::Reg
{
region = fuc.nodes[region].inputs[1];
offset = value as Offset;
}
let nd = &fuc.nodes[region];
let value = node.inputs[1];
let (base, offset, src) = match nd.kind {
Kind::Stck if node.ty.loc(tys) == Loc::Reg => {
(reg::STACK_PTR, self.offsets[region as usize] + offset, value)
}
_ => (atr(region), offset, match fuc.nodes[value].kind {
Kind::Load { .. } => fuc.nodes[value].inputs[1],
_ => value,
}),
};
match node.ty.loc(tys) {
Loc::Reg => self.emit(instrs::st(atr(src), base, offset as _, size)),
Loc::Stack => {
debug_assert_eq!(offset, 0);
self.emit(instrs::bmc(atr(src), base, size))
}
}
}
Kind::Mem => self.emit(instrs::cp(atr(MEM), reg::RET)),
Kind::Arg => {}
e @ (Kind::Start
| Kind::Entry
| Kind::End
| Kind::Loops
| Kind::Then
| Kind::Else
| Kind::Phi
| Kind::Assert { .. }) => unreachable!("{e:?}"),
}
}
}
self.ralloc_my = res;
let bundle_count = self.ralloc_my.bundles.len() + (reg_offset as usize);
(
if fuc.tail {
bundle_count.saturating_sub(reg::RET_ADDR as _)
} else {
assert!(bundle_count < reg::STACK_PTR as usize, "TODO: spill memory");
self.ralloc_my.bundles.len()
},
fuc.tail,
)
}
}
pub struct Function<'a> {
sig: Sig,
tail: bool,
backrefs: Vec<u16>,
nodes: &'a mut Nodes,
tys: &'a Types,
visited: BitSet,
func: Func,
}
impl Function<'_> {
fn vreg_count(&self) -> usize {
self.nodes.values.len()
}
fn uses_of(&self, nid: Nid, buf: &mut Vec<Nid>) {
if self.nodes[nid].kind.is_cfg() && !matches!(self.nodes[nid].kind, Kind::Call { .. }) {
return;
}
self.nodes[nid]
.outputs
.iter()
.filter(|&&n| self.nodes.is_data_dep(nid, n))
.collect_into(buf);
}
fn phi_inputs_of(&self, nid: Nid, buf: &mut Vec<Nid>) {
match self.nodes[nid].kind {
Kind::Region => {
for &inp in self.nodes[nid].outputs.as_slice() {
if self.nodes[inp].is_data_phi() {
buf.extend(&self.nodes[inp].inputs[1..]);
buf.push(inp);
}
}
}
Kind::Loop => {
for &inp in self.nodes[nid].outputs.as_slice() {
if self.nodes[inp].is_data_phi() {
buf.push(self.nodes[inp].inputs[1]);
buf.push(inp);
buf.push(self.nodes[inp].inputs[2]);
}
}
}
_ => {}
}
}
fn instr_of(&self, nid: Nid) -> Option<Nid> {
if self.nodes[nid].kind == Kind::Phi || self.nodes[nid].lock_rc != 0 {
return None;
}
debug_assert_ne!(self.backrefs[nid as usize], Nid::MAX, "{:?}", self.nodes[nid]);
Some(self.backrefs[nid as usize])
}
fn block_of(&self, nid: Nid) -> Nid {
debug_assert!(self.nodes[nid].kind.starts_basic_block());
self.backrefs[nid as usize]
}
fn idom_of(&self, mut nid: Nid) -> Nid {
while !self.nodes[nid].kind.starts_basic_block() {
nid = self.nodes.idom(nid);
}
nid
}
fn use_block(&self, inst: Nid, uinst: Nid) -> Nid {
let mut block = self.nodes.use_block(inst, uinst);
while !self.nodes[block].kind.starts_basic_block() {
block = self.nodes.idom(block);
}
block
}
}
impl core::fmt::Debug for Function<'_> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
for block in &self.func.blocks {
writeln!(f, "{:?}", self.nodes[block.entry].kind)?;
for &instr in &self.func.instrs[block.range.clone()] {
writeln!(f, "{:?}", self.nodes[instr].kind)?;
}
}
Ok(())
}
}
impl<'a> Function<'a> {
fn new(nodes: &'a mut Nodes, tys: &'a Types, sig: Sig) -> Self {
let mut s = Self {
backrefs: vec![u16::MAX; nodes.values.len()],
tail: true,
nodes,
tys,
sig,
visited: Default::default(),
func: Default::default(),
};
s.visited.clear(s.nodes.values.len());
s.emit_node(VOID);
s
}
fn add_block(&mut self, entry: Nid) {
self.func
.blocks
.push(Block { range: self.func.instrs.len()..self.func.instrs.len(), entry });
self.backrefs[entry as usize] = self.func.blocks.len() as u16 - 1;
}
fn close_block(&mut self, exit: Nid) {
if !matches!(self.nodes[exit].kind, Kind::Loop | Kind::Region) {
self.add_instr(exit);
} else {
self.func.instrs.push(exit);
}
let prev = self.func.blocks.last_mut().unwrap();
prev.range.end = self.func.instrs.len();
}
fn add_instr(&mut self, nid: Nid) {
debug_assert_ne!(self.nodes[nid].kind, Kind::Loop);
self.backrefs[nid as usize] = self.func.instrs.len() as u16;
self.func.instrs.push(nid);
}
fn emit_node(&mut self, nid: Nid) {
if matches!(self.nodes[nid].kind, Kind::Region | Kind::Loop) {
match (self.nodes[nid].kind, self.visited.set(nid)) {
(Kind::Loop, false) | (Kind::Region, true) => {
self.close_block(nid);
return;
}
_ => {}
}
} else if !self.visited.set(nid) {
return;
}
if self.nodes.is_never_used(nid, self.tys) {
self.nodes.lock(nid);
return;
}
let mut node = self.nodes[nid].clone();
match node.kind {
Kind::Start => {
debug_assert_matches!(self.nodes[node.outputs[0]].kind, Kind::Entry);
self.add_block(VOID);
self.emit_node(node.outputs[0])
}
Kind::If => {
let &[_, cond] = node.inputs.as_slice() else { unreachable!() };
let &[mut then, mut else_] = node.outputs.as_slice() else { unreachable!() };
if let Kind::BinOp { op } = self.nodes[cond].kind
&& let Some((_, swapped)) = op.cond_op(node.ty)
&& swapped
{
mem::swap(&mut then, &mut else_);
}
self.close_block(nid);
self.emit_node(then);
self.emit_node(else_);
}
Kind::Region | Kind::Loop => {
self.close_block(nid);
self.add_block(nid);
self.reschedule_block(nid, &mut node.outputs);
for o in node.outputs.into_iter().rev() {
self.emit_node(o);
}
}
Kind::Return | Kind::Die => {
self.close_block(nid);
self.emit_node(node.outputs[0]);
}
Kind::Entry => {
let (ret, mut parama) = self.tys.parama(self.sig.ret);
let mut typs = self.sig.args.args();
#[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();
debug_assert_eq!(self.nodes[arg].kind, Kind::Arg);
match parama.next(ty, self.tys) {
None => {}
Some(_) => self.add_instr(arg),
}
}
if let Some(PLoc::Ref(..)) = ret {
self.add_instr(MEM);
}
self.reschedule_block(nid, &mut node.outputs);
for o in node.outputs.into_iter().rev() {
self.emit_node(o);
}
}
Kind::Then | Kind::Else => {
self.add_block(nid);
self.reschedule_block(nid, &mut node.outputs);
for o in node.outputs.into_iter().rev() {
self.emit_node(o);
}
}
Kind::Call { func, .. } => {
self.tail &= func == ty::ECA;
self.add_instr(nid);
self.reschedule_block(nid, &mut node.outputs);
for o in node.outputs.into_iter().rev() {
if self.nodes[o].inputs[0] == nid
|| (matches!(self.nodes[o].kind, Kind::Loop | Kind::Region)
&& self.nodes[o].inputs[1] == nid)
{
self.emit_node(o);
}
}
}
Kind::CInt { .. }
| Kind::BinOp { .. }
| Kind::UnOp { .. }
| Kind::Global { .. }
| Kind::Load { .. }
| Kind::Stre
| Kind::Stck => self.add_instr(nid),
Kind::End | Kind::Phi | Kind::Arg | Kind::Mem | Kind::Loops => {}
Kind::Assert { .. } => unreachable!(),
}
}
fn reschedule_block(&mut self, from: Nid, outputs: &mut Vc) {
let from = Some(&from);
let mut buf = Vec::with_capacity(outputs.len());
let mut seen = BitSet::default();
seen.clear(self.nodes.values.len());
for &o in outputs.iter() {
if !self.nodes.is_cfg(o) {
continue;
}
seen.set(o);
let mut cursor = buf.len();
buf.push(o);
while let Some(&n) = buf.get(cursor) {
for &i in &self.nodes[n].inputs[1..] {
if from == self.nodes[i].inputs.first()
&& self.nodes[i]
.outputs
.iter()
.all(|&o| self.nodes[o].inputs.first() != from || seen.get(o))
&& seen.set(i)
{
buf.push(i);
}
}
cursor += 1;
}
}
for &o in outputs.iter() {
if !seen.set(o) {
continue;
}
let mut cursor = buf.len();
buf.push(o);
while let Some(&n) = buf.get(cursor) {
for &i in &self.nodes[n].inputs[1..] {
if from == self.nodes[i].inputs.first()
&& self.nodes[i]
.outputs
.iter()
.all(|&o| self.nodes[o].inputs.first() != from || seen.get(o))
&& seen.set(i)
{
buf.push(i);
}
}
cursor += 1;
}
}
debug_assert!(
outputs.len() == buf.len() || outputs.len() == buf.len() + 1,
"{:?} {:?}",
outputs,
buf
);
if buf.len() + 1 == outputs.len() {
outputs.remove(outputs.len() - 1);
}
outputs.copy_from_slice(&buf);
}
}
pub struct Env<'a> {
ctx: &'a Function<'a>,
func: &'a Func,
res: &'a mut Res,
}
impl<'a> Env<'a> {
pub fn new(ctx: &'a Function<'a>, func: &'a Func, res: &'a mut Res) -> Self {
Self { ctx, func, res }
}
pub fn run(&mut self) {
self.res.bundles.clear();
self.res.node_to_reg.clear();
self.res.node_to_reg.resize(self.ctx.vreg_count(), 0);
debug_assert!(self.res.dfs_buf.is_empty());
debug_assert!(self.res.use_buf.is_empty());
debug_assert!(self.res.phi_input_buf.is_empty());
let mut bundle = Bundle::new(self.func.instrs.len());
let mut visited = BitSet::with_capacity(self.ctx.nodes.values.len());
let mut use_buf = mem::take(&mut self.res.use_buf);
let mut phi_input_buf = mem::take(&mut self.res.phi_input_buf);
for block in &self.func.blocks {
self.ctx.phi_inputs_of(block.entry, &mut phi_input_buf);
for param in phi_input_buf.drain(..) {
if !visited.set(param) {
continue;
}
self.append_bundle(param, &mut bundle, &mut use_buf);
}
}
self.res.phi_input_buf = phi_input_buf;
for &inst in &self.func.instrs {
if visited.get(inst) || inst == 0 {
continue;
}
self.append_bundle(inst, &mut bundle, &mut use_buf);
}
self.res.use_buf = use_buf;
}
fn append_bundle(&mut self, inst: Nid, bundle: &mut Bundle, use_buf: &mut Vec<Nid>) {
let mut dom = self.ctx.idom_of(inst);
if self.ctx.nodes[dom].kind == Kind::Loop && self.ctx.nodes[inst].kind == Kind::Phi {
dom = self.ctx.nodes.idom(dom);
dom = self.ctx.idom_of(dom);
}
self.ctx.uses_of(inst, use_buf);
for uinst in use_buf.drain(..) {
let cursor = self.ctx.use_block(inst, uinst);
self.reverse_cfg_dfs(cursor, dom, |_, n, b| {
let mut range = b.range.clone();
range.start =
range.start.max(self.ctx.instr_of(inst).map_or(0, |n| n + 1) as usize);
range.end = range.end.min(
self.ctx
.instr_of(uinst)
.filter(|_| self.ctx.nodes.loop_depth(dom) == self.ctx.nodes.loop_depth(n))
.map_or(Nid::MAX, |n| n + 1) as usize,
);
bundle.add(range);
});
}
match self.res.bundles.iter_mut().enumerate().find(|(_, b)| !b.overlaps(bundle)) {
Some((i, other)) => {
other.merge(bundle);
bundle.clear();
self.res.node_to_reg[inst as usize] = i as Reg + 1;
}
None => {
self.res.bundles.push(mem::replace(bundle, Bundle::new(self.func.instrs.len())));
self.res.node_to_reg[inst as usize] = self.res.bundles.len() as Reg;
}
}
}
fn reverse_cfg_dfs(
&mut self,
from: Nid,
until: Nid,
mut each: impl FnMut(&mut Self, Nid, &Block),
) {
debug_assert!(self.res.dfs_buf.is_empty());
self.res.dfs_buf.push(from);
self.res.dfs_seem.clear(self.ctx.nodes.values.len());
while let Some(nid) = self.res.dfs_buf.pop() {
each(self, nid, &self.func.blocks[self.ctx.block_of(nid) as usize]);
if nid == until {
continue;
}
match self.ctx.nodes[nid].kind {
Kind::Then | Kind::Else | Kind::Region | Kind::Loop => {
for &n in self.ctx.nodes[nid].inputs.iter() {
let d = self.ctx.idom_of(n);
if self.res.dfs_seem.set(d) {
self.res.dfs_buf.push(d);
}
}
}
Kind::Start => {}
_ => unreachable!(),
}
}
}
}
#[derive(Default)]
pub struct Res {
pub bundles: Vec<Bundle>,
pub node_to_reg: Vec<Reg>,
use_buf: Vec<Nid>,
phi_input_buf: Vec<Nid>,
dfs_buf: Vec<Nid>,
dfs_seem: BitSet,
}
pub struct Bundle {
taken: Vec<bool>,
}
impl Bundle {
fn new(size: usize) -> Self {
Self { taken: vec![false; size] }
}
fn add(&mut self, range: Range<usize>) {
self.taken[range].fill(true);
}
fn overlaps(&self, other: &Self) -> bool {
self.taken.iter().zip(other.taken.iter()).any(|(a, b)| a & b)
}
fn merge(&mut self, other: &Self) {
debug_assert!(!self.overlaps(other));
self.taken.iter_mut().zip(other.taken.iter()).for_each(|(a, b)| *a |= *b);
}
fn clear(&mut self) {
self.taken.fill(false);
}
}
#[derive(Default)]
pub struct Func {
pub blocks: Vec<Block>,
pub instrs: Vec<Nid>,
}
pub struct Block {
pub range: Range<usize>,
pub entry: Nid,
}

File diff suppressed because it is too large Load diff

View file

@ -62,6 +62,12 @@ impl BitSet {
const INLINE_ELEMS: usize = Self::UNIT - 1;
const UNIT: usize = core::mem::size_of::<usize>() * 8;
pub fn with_capacity(len: usize) -> Self {
let mut s = Self::default();
s.reserve(len);
s
}
fn is_inline(&self) -> bool {
unsafe { self.inline & Self::FLAG != 0 }
}

View file

@ -0,0 +1,44 @@
main:
ADDI64 r254, r254, -24d
ST r31, r254, 0a, 24h
LI32 r32, 1148846080w
CP r2, r32
JAL r31, r0, :sin
FMUL32 r33, r1, r32
FTI32 r1, r33, 1b
LD r31, r254, 0a, 24h
ADDI64 r254, r254, 24d
JALA r0, r31, 0a
sin:
LI32 r4, 1124073472w
LI32 r5, 1078530011w
FMUL32 r7, r2, r4
FDIV32 r9, r7, r5
FTI32 r11, r9, 1b
ANDI r10, r11, 255d
ITF64 r5, r11
MULI64 r4, r10, 4d
LRA r3, r0, :SIN_TABLE
LI32 r7, 1086918619w
FC64T32 r9, r5, 1b
ADDI64 r5, r11, 64d
ADD64 r8, r3, r4
LI32 r1, 1132462080w
FMUL32 r6, r9, r7
ANDI r7, r5, 255d
LI32 r5, 1056964608w
LD r4, r8, 0a, 4h
FDIV32 r8, r6, r1
MULI64 r6, r7, 4d
FMUL32 r10, r4, r5
FSUB32 r11, r2, r8
ADD64 r9, r3, r6
FMUL32 r2, r11, r10
LD r12, r9, 0a, 4h
FSUB32 r5, r12, r2
FMUL32 r7, r5, r11
FADD32 r1, r4, r7
JALA r0, r31, 0a
code size: 1303
ret: 826
status: Ok(())

View file

@ -1,17 +1,17 @@
main:
ADDI64 r254, r254, -40d
ST r31, r254, 24a, 16h
ADDI64 r254, r254, -56d
ST r31, r254, 24a, 32h
LI64 r32, 1d
ADDI64 r2, r254, 0d
ST r32, r254, 0a, 8h
LI64 r5, 2d
ST r5, r254, 8a, 8h
LI64 r8, 4d
ST r8, r254, 16a, 8h
LI64 r33, 2d
ST r33, r254, 8a, 8h
LI64 r34, 4d
ST r34, r254, 16a, 8h
JAL r31, r0, :pass
ADD64 r1, r1, r32
LD r31, r254, 24a, 16h
ADDI64 r254, r254, 40d
LD r31, r254, 24a, 32h
ADDI64 r254, r254, 56d
JALA r0, r31, 0a
pass:
LD r4, r2, 8a, 8h

View file

@ -6,8 +6,7 @@ main:
CP r32, r1
LRA r2, r0, :"fff\0"
JAL r31, r0, :str_len
CP r10, r32
ADD64 r1, r1, r10
ADD64 r1, r1, r32
LD r31, r254, 0a, 16h
ADDI64 r254, r254, 16d
JALA r0, r31, 0a
@ -23,6 +22,6 @@ str_len:
ADDI64 r1, r1, 1d
JMP :2
1: JALA r0, r31, 0a
code size: 219
code size: 216
ret: 16
status: Ok(())

View file

@ -2,18 +2,18 @@ cond:
LI64 r1, 0d
JALA r0, r31, 0a
main:
ADDI64 r254, r254, -8d
ST r31, r254, 0a, 8h
ADDI64 r254, r254, -24d
ST r31, r254, 0a, 24h
JAL r31, r0, :cond
LI64 r5, 0d
CP r7, r5
JNE r1, r7, :0
CP r5, r7
CP r1, r5
LI64 r32, 0d
CP r33, r32
JNE r1, r33, :0
CP r32, r33
CP r1, r32
JMP :1
0: LI64 r1, 2d
1: LD r31, r254, 0a, 8h
ADDI64 r254, r254, 8d
1: LD r31, r254, 0a, 24h
ADDI64 r254, r254, 24d
JALA r0, r31, 0a
code size: 134
ret: 0

View file

@ -8,12 +8,13 @@ main:
LI64 r6, 6d
LI64 r5, 5d
LI64 r2, 1d
LD r3, r4, 0a, 16h
CP r3, r4
LD r3, r3, 0a, 16h
ECA
LI64 r1, 0d
ADDI64 r254, r254, 16d
JALA r0, r31, 0a
ev: Ecall
code size: 152
code size: 155
ret: 0
status: Ok(())

View file

@ -30,50 +30,50 @@ infinite_loop:
ADDI64 r254, r254, 24d
JALA r0, r31, 0a
main:
ADDI64 r254, r254, -56d
ST r31, r254, 0a, 56h
ADDI64 r254, r254, -64d
ST r31, r254, 0a, 64h
LI64 r32, 0d
CP r2, r32
JAL r31, r0, :multiple_breaks
CP r2, r1
CP r33, r1
LI64 r1, 3d
JEQ r2, r1, :0
JEQ r33, r1, :0
LI64 r1, 1d
JMP :1
0: CP r33, r1
LI64 r34, 4d
CP r2, r34
0: CP r34, r1
LI64 r35, 4d
CP r2, r35
JAL r31, r0, :multiple_breaks
CP r35, r34
LI64 r36, 10d
JEQ r1, r36, :2
CP r36, r35
LI64 r37, 10d
JEQ r1, r37, :2
LI64 r1, 2d
JMP :1
2: CP r2, r32
JAL r31, r0, :state_change_in_break
JEQ r1, r32, :3
CP r1, r33
CP r1, r34
JMP :1
3: CP r2, r35
3: CP r2, r36
JAL r31, r0, :state_change_in_break
JEQ r1, r36, :4
CP r1, r35
JEQ r1, r37, :4
CP r1, r36
JMP :1
4: CP r2, r36
4: CP r2, r37
JAL r31, r0, :continue_and_state_change
JEQ r1, r36, :5
JEQ r1, r37, :5
LI64 r1, 5d
JMP :1
5: CP r2, r33
5: CP r2, r34
JAL r31, r0, :continue_and_state_change
JEQ r1, r32, :6
LI64 r1, 6d
JMP :1
6: CP r37, r32
6: CP r38, r32
JAL r31, r0, :infinite_loop
CP r1, r37
1: LD r31, r254, 0a, 56h
ADDI64 r254, r254, 56d
CP r1, r38
1: LD r31, r254, 0a, 64h
ADDI64 r254, r254, 64d
JALA r0, r31, 0a
multiple_breaks:
LI64 r6, 3d

View file

@ -6,42 +6,40 @@ check_platform:
ADDI64 r254, r254, 8d
JALA r0, r31, 0a
main:
ADDI64 r254, r254, -48d
ST r31, r254, 0a, 48h
ADDI64 r254, r254, -64d
ST r31, r254, 0a, 64h
JAL r31, r0, :check_platform
LI64 r32, 0d
LI64 r33, 30d
LI64 r34, 100d
CP r10, r32
CP r35, r32
CP r36, r32
5: JLTU r10, r33, :0
ADDI64 r35, r35, 1d
CP r37, r32
5: JLTU r35, r33, :0
ADDI64 r36, r36, 1d
CP r2, r32
CP r3, r35
CP r3, r36
CP r4, r33
JAL r31, r0, :set_pixel
CP r2, r36
JEQ r1, r2, :1
JEQ r1, r37, :1
CP r1, r32
JMP :2
1: CP r5, r32
CP r36, r2
JNE r35, r34, :3
CP r1, r36
1: CP r38, r32
JNE r36, r34, :3
CP r1, r37
JMP :2
3: CP r1, r36
CP r10, r5
3: CP r1, r37
CP r35, r38
JMP :4
0: CP r1, r36
CP r5, r32
0: CP r1, r37
CP r38, r32
ADDI64 r1, r1, 1d
ADDI64 r10, r10, 1d
4: CP r32, r5
CP r36, r1
ADDI64 r35, r35, 1d
4: CP r32, r38
CP r37, r1
JMP :5
2: LD r31, r254, 0a, 48h
ADDI64 r254, r254, 48d
2: LD r31, r254, 0a, 64h
ADDI64 r254, r254, 64d
JALA r0, r31, 0a
set_pixel:
MUL64 r7, r3, r4
@ -50,6 +48,6 @@ set_pixel:
x86_fb_ptr:
LI64 r1, 100d
JALA r0, r31, 0a
code size: 336
code size: 330
ret: 3000
status: Ok(())

View file

@ -12,11 +12,10 @@ main:
CP r32, r1
LI64 r2, 20d
JAL r31, r0, :add_two
CP r10, r32
ADD64 r1, r1, r10
ADD64 r1, r1, r32
LD r31, r254, 0a, 16h
ADDI64 r254, r254, 16d
JALA r0, r31, 0a
code size: 155
code size: 152
ret: 33
status: Ok(())

View file

@ -5,8 +5,8 @@ add:
ADD32 r1, r2, r3
JALA r0, r31, 0a
main:
ADDI64 r254, r254, -16d
ST r31, r254, 0a, 16h
ADDI64 r254, r254, -24d
ST r31, r254, 0a, 24h
LI32 r3, 2w
CP r2, r3
JAL r31, r0, :add
@ -14,12 +14,11 @@ main:
LI64 r3, 3d
LI64 r2, 1d
JAL r31, r0, :add
CP r2, r32
ANDI r11, r2, 4294967295d
SUB64 r1, r11, r1
LD r31, r254, 0a, 16h
ADDI64 r254, r254, 16d
ANDI r33, r32, 4294967295d
SUB64 r1, r33, r1
LD r31, r254, 0a, 24h
ADDI64 r254, r254, 24d
JALA r0, r31, 0a
code size: 161
code size: 158
ret: 0
status: Ok(())

View file

@ -1,17 +1,17 @@
deinit:
ADDI64 r254, r254, -16d
ST r31, r254, 0a, 16h
ADDI64 r254, r254, -32d
ST r31, r254, 0a, 32h
CP r32, r2
LD r5, r2, 16a, 8h
LD r33, r2, 16a, 8h
LI64 r4, 8d
MUL64 r3, r5, r4
CP r5, r32
LD r2, r5, 0a, 8h
MUL64 r3, r33, r4
CP r34, r32
LD r2, r34, 0a, 8h
JAL r31, r0, :free
CP r1, r32
JAL r31, r0, :new
LD r31, r254, 0a, 16h
ADDI64 r254, r254, 16d
LD r31, r254, 0a, 32h
ADDI64 r254, r254, 32d
JALA r0, r31, 0a
free:
CP r10, r2
@ -23,21 +23,21 @@ free:
ECA
JALA r0, r31, 0a
main:
ADDI64 r254, r254, -48d
ST r31, r254, 24a, 24h
ADDI64 r254, r254, -56d
ST r31, r254, 24a, 32h
ADDI64 r32, r254, 0d
CP r1, r32
JAL r31, r0, :new
LI64 r3, 69d
CP r2, r32
JAL r31, r0, :push
LD r9, r254, 0a, 8h
LD r33, r9, 0a, 8h
LD r33, r254, 0a, 8h
LD r34, r33, 0a, 8h
CP r2, r32
JAL r31, r0, :deinit
CP r1, r33
LD r31, r254, 24a, 24h
ADDI64 r254, r254, 48d
CP r1, r34
LD r31, r254, 24a, 32h
ADDI64 r254, r254, 56d
JALA r0, r31, 0a
malloc:
CP r9, r2
@ -58,69 +58,69 @@ new:
ADDI64 r254, r254, 24d
JALA r0, r31, 0a
push:
ADDI64 r254, r254, -72d
ST r31, r254, 0a, 72h
ADDI64 r254, r254, -192d
ST r31, r254, 0a, 192h
CP r32, r3
LI64 r33, 1d
LD r6, r2, 8a, 8h
LD r8, r2, 16a, 8h
CP r34, r2
JNE r8, r6, :0
LI64 r35, 0d
JNE r8, r35, :1
CP r36, r33
LD r34, r2, 8a, 8h
LD r35, r2, 16a, 8h
CP r36, r2
JNE r35, r34, :0
LI64 r37, 0d
JNE r35, r37, :1
CP r38, r33
JMP :2
1: MULI64 r36, r8, 2d
2: LI64 r37, 8d
MUL64 r2, r36, r37
CP r3, r37
1: MULI64 r38, r35, 2d
2: LI64 r39, 8d
MUL64 r2, r38, r39
CP r3, r39
JAL r31, r0, :malloc
CP r38, r1
CP r39, r34
ST r36, r39, 16a, 8h
CP r40, r1
LI64 r1, 0d
CP r7, r38
JNE r7, r1, :3
CP r41, r40
JNE r41, r1, :3
JMP :4
3: CP r38, r7
LD r8, r39, 8a, 8h
MULI64 r10, r8, 8d
LD r3, r39, 0a, 8h
ADD64 r7, r3, r10
CP r5, r38
9: LD r2, r39, 0a, 8h
LD r10, r39, 8a, 8h
JNE r7, r3, :5
JEQ r10, r35, :6
CP r4, r37
MUL64 r3, r10, r4
3: CP r40, r41
CP r42, r36
ST r38, r42, 16a, 8h
LD r36, r42, 8a, 8h
MULI64 r43, r36, 8d
LD r44, r42, 0a, 8h
ADD64 r45, r44, r43
CP r46, r40
9: LD r2, r42, 0a, 8h
LD r47, r42, 8a, 8h
JNE r45, r44, :5
JEQ r47, r37, :6
CP r4, r39
MUL64 r3, r47, r4
JAL r31, r0, :free
CP r6, r38
CP r1, r40
JMP :7
6: CP r6, r38
7: ST r6, r39, 0a, 8h
6: CP r1, r40
7: ST r1, r42, 0a, 8h
JMP :8
5: CP r4, r37
CP r6, r38
ADDI64 r8, r5, 8d
ADDI64 r9, r3, 8d
LD r10, r3, 0a, 8h
ST r10, r5, 0a, 8h
CP r3, r9
CP r5, r8
5: CP r1, r40
CP r4, r39
ADDI64 r41, r46, 8d
ADDI64 r48, r44, 8d
LD r49, r44, 0a, 8h
ST r49, r46, 0a, 8h
CP r44, r48
CP r46, r41
JMP :9
0: CP r39, r34
8: LD r5, r39, 8a, 8h
MULI64 r7, r5, 8d
LD r6, r39, 0a, 8h
ADD64 r1, r6, r7
0: CP r42, r36
8: LD r50, r42, 8a, 8h
MULI64 r51, r50, 8d
LD r52, r42, 0a, 8h
ADD64 r1, r52, r51
CP r3, r32
ST r3, r1, 0a, 8h
LD r2, r39, 8a, 8h
ADD64 r3, r2, r33
ST r3, r39, 8a, 8h
4: LD r31, r254, 0a, 72h
ADDI64 r254, r254, 72d
LD r53, r42, 8a, 8h
ADD64 r54, r53, r33
ST r54, r42, 8a, 8h
4: LD r31, r254, 0a, 192h
ADDI64 r254, r254, 192d
JALA r0, r31, 0a
code size: 955
ret: 69

View file

@ -4,15 +4,15 @@ clobber:
ST r3, r1, 0a, 8h
JALA r0, r31, 0a
main:
ADDI64 r254, r254, -16d
ST r31, r254, 0a, 16h
ADDI64 r254, r254, -24d
ST r31, r254, 0a, 24h
LRA r32, r0, :var
LI64 r3, 2d
ST r3, r32, 0a, 8h
LI64 r33, 2d
ST r33, r32, 0a, 8h
JAL r31, r0, :clobber
LD r1, r32, 0a, 8h
LD r31, r254, 0a, 16h
ADDI64 r254, r254, 16d
LD r31, r254, 0a, 24h
ADDI64 r254, r254, 24d
JALA r0, r31, 0a
code size: 166
ret: 0

View file

@ -1,22 +1,21 @@
fib:
ADDI64 r254, r254, -32d
ST r31, r254, 0a, 32h
ADDI64 r254, r254, -40d
ST r31, r254, 0a, 40h
LI64 r1, 1d
LI64 r32, 2d
JGTU r2, r32, :0
JMP :1
0: CP r6, r2
SUB64 r2, r6, r1
CP r33, r6
0: CP r33, r2
SUB64 r2, r33, r1
CP r34, r33
JAL r31, r0, :fib
CP r2, r33
CP r34, r1
CP r2, r34
CP r35, r1
SUB64 r2, r2, r32
JAL r31, r0, :fib
CP r8, r34
ADD64 r1, r1, r8
1: LD r31, r254, 0a, 32h
ADDI64 r254, r254, 32d
ADD64 r1, r1, r35
1: LD r31, r254, 0a, 40h
ADDI64 r254, r254, 40d
JALA r0, r31, 0a
main:
ADDI64 r254, r254, -8d
@ -26,6 +25,6 @@ main:
LD r31, r254, 0a, 8h
ADDI64 r254, r254, 8d
JALA r0, r31, 0a
code size: 214
code size: 211
ret: 55
status: Ok(())

View file

@ -1,22 +1,21 @@
main:
ADDI64 r254, r254, -16d
ST r31, r254, 0a, 16h
ADDI64 r254, r254, -32d
ST r31, r254, 0a, 32h
JAL r31, r0, :scalar_values
LI64 r3, 0d
CP r8, r3
JEQ r1, r8, :0
LI64 r32, 0d
CP r33, r32
JEQ r1, r33, :0
LI64 r1, 1d
JMP :1
0: CP r32, r8
JAL r31, r0, :structs
CP r3, r32
JEQ r1, r3, :2
0: JAL r31, r0, :structs
CP r34, r33
JEQ r1, r34, :2
JAL r31, r0, :structs
JMP :1
2: CP r1, r3
CP r32, r3
1: LD r31, r254, 0a, 16h
ADDI64 r254, r254, 16d
2: CP r1, r34
CP r33, r34
1: LD r31, r254, 0a, 32h
ADDI64 r254, r254, 32d
JALA r0, r31, 0a
scalar_values:
LI64 r1, 0d
@ -24,17 +23,17 @@ scalar_values:
structs:
ADDI64 r254, r254, -32d
LI64 r1, 5d
ST r1, r254, 0a, 8h
ST r1, r254, 8a, 8h
LD r5, r254, 0a, 8h
ST r1, r254, 16a, 8h
ST r1, r254, 24a, 8h
LD r5, r254, 16a, 8h
ADDI64 r7, r5, 15d
ST r7, r254, 16a, 8h
ST r7, r254, 0a, 8h
LI64 r10, 20d
ST r10, r254, 24a, 8h
LD r1, r254, 16a, 8h
ST r10, r254, 8a, 8h
LD r1, r254, 0a, 8h
SUB64 r1, r1, r10
ADDI64 r254, r254, 32d
JALA r0, r31, 0a
code size: 310
code size: 307
ret: 0
status: Ok(())

View file

@ -0,0 +1,109 @@
main:
ADDI64 r254, r254, -106d
ST r31, r254, 58a, 48h
ADDI64 r32, r254, 33d
ADDI64 r2, r254, 34d
ADDI64 r6, r254, 1d
LI64 r33, 0d
ADDI64 r4, r254, 17d
ST r32, r254, 34a, 8h
LI64 r34, 100d
ADDI64 r7, r254, 0d
LI8 r35, 1b
ST r33, r254, 1a, 8h
ST r33, r254, 17a, 8h
ST r34, r254, 42a, 8h
LI8 r36, 0b
ST r35, r254, 0a, 1h
ST r33, r254, 9a, 8h
ST r33, r254, 25a, 8h
ST r34, r254, 50a, 8h
ST r36, r254, 33a, 1h
CP r3, r4
CP r5, r6
LD r3, r3, 0a, 16h
LD r5, r5, 0a, 16h
LD r7, r7, 0a, 1h
JAL r31, r0, :put_filled_rect
LD r31, r254, 58a, 48h
ADDI64 r254, r254, 106d
JALA r0, r31, 0a
put_filled_rect:
ADDI64 r254, r254, -212d
ST r32, r254, 108a, 104h
ST r3, r254, 92a, 16h
ADDI64 r3, r254, 92d
ST r5, r254, 76a, 16h
ADDI64 r5, r254, 76d
ST r7, r254, 75a, 1h
ADDI64 r7, r254, 75d
LI64 r8, 25d
LI64 r32, 2d
LI64 r6, 8d
ADDI64 r33, r254, 25d
ADDI64 r34, r254, 50d
LI8 r35, 5b
ST r35, r254, 25a, 1h
LD r36, r5, 0a, 8h
ST r36, r254, 26a, 4h
LI64 r37, 1d
ST r37, r254, 30a, 4h
ST r7, r254, 34a, 8h
ST r35, r254, 50a, 1h
ST r36, r254, 51a, 4h
ST r37, r254, 55a, 4h
ST r7, r254, 59a, 8h
CP r38, r7
LD r7, r3, 8a, 8h
LD r39, r5, 8a, 8h
ADD64 r11, r39, r7
SUB64 r4, r11, r37
LD r40, r2, 8a, 8h
MUL64 r5, r40, r4
LD r9, r2, 0a, 8h
ADD64 r10, r9, r5
LD r2, r3, 0a, 8h
ADD64 r41, r2, r10
MUL64 r3, r40, r7
ADD64 r4, r9, r3
ADD64 r42, r2, r4
3: JGTU r39, r37, :0
JNE r39, r37, :1
ADDI64 r4, r254, 0d
ST r35, r254, 0a, 1h
ST r36, r254, 1a, 4h
ST r37, r254, 5a, 4h
ST r38, r254, 9a, 8h
ST r42, r254, 17a, 8h
CP r2, r6
CP r3, r32
CP r5, r8
ECA
JMP :1
1: JMP :2
0: CP r3, r32
CP r43, r6
CP r44, r8
ST r42, r254, 67a, 8h
CP r2, r43
CP r4, r34
CP r5, r44
ECA
ST r41, r254, 42a, 8h
CP r2, r43
CP r3, r32
CP r4, r33
CP r5, r44
ECA
ADD64 r42, r40, r42
SUB64 r41, r41, r40
SUB64 r39, r39, r32
CP r6, r43
CP r8, r44
JMP :3
2: LD r32, r254, 108a, 104h
ADDI64 r254, r254, 212d
JALA r0, r31, 0a
code size: 917
ret: 0
status: Ok(())

View file

@ -1,16 +1,16 @@
main:
ADDI64 r254, r254, -24d
ST r31, r254, 16a, 8h
ADDI64 r254, r254, -32d
ST r31, r254, 16a, 16h
ADDI64 r3, r254, 0d
ADDI64 r2, r254, 8d
LI64 r4, 0d
ST r4, r254, 0a, 8h
ST r4, r254, 8a, 8h
LI64 r32, 0d
ST r32, r254, 0a, 8h
ST r32, r254, 8a, 8h
LI64 r4, 1024d
JAL r31, r0, :set
ANDI r1, r1, 4294967295d
LD r31, r254, 16a, 8h
ADDI64 r254, r254, 24d
LD r31, r254, 16a, 16h
ADDI64 r254, r254, 32d
JALA r0, r31, 0a
set:
CP r1, r4

View file

@ -0,0 +1,27 @@
main:
ADDI64 r254, r254, -32d
ST r31, r254, 0a, 32h
JAL r31, r0, :opaque
CP r32, r1
JAL r31, r0, :opaque
LI64 r33, 0d
CP r1, r32
JNE r1, r33, :0
CP r32, r1
LI64 r1, 0d
CP r34, r32
JMP :1
0: CP r34, r1
LD r1, r34, 0a, 8h
1: JEQ r34, r33, :2
LD r1, r34, 0a, 8h
JMP :2
2: LD r31, r254, 0a, 32h
ADDI64 r254, r254, 32d
JALA r0, r31, 0a
opaque:
LI64 r1, 0d
JALA r0, r31, 0a
code size: 183
ret: 0
status: Ok(())

View file

@ -0,0 +1,6 @@
test.hb:4:17: unwrap is not needed since the value is (provably) never null, remove it, or replace with '@as(<expr_ty>, <opt_expr>)'
ptr := @unwrap(always_nn)
^
test.hb:6:16: unwrap is incorrect since the value is (provably) always null, make sure your logic is correct
ptr = @unwrap(always_n)
^

View file

@ -1,6 +1,26 @@
test.hb:15:4: can't prove the value is not 'null', use '@unwrap(<opt>)' if you believe compiler is stupid, or explicitly check for null and handle it ('if <opt> == null { /* handle */ } else { /* use opt */ }')
*ptr += 1
^
test.hb:15:4: can't prove the value is not 'null', use '@unwrap(<opt>)' if you believe compiler is stupid, or explicitly check for null and handle it ('if <opt> == null { /* handle */ } else { /* use opt */ }')
*ptr += 1
^
get_ptr:
ADDI64 r254, r254, -8d
ADDI64 r1, r254, 0d
ADDI64 r254, r254, 8d
JALA r0, r31, 0a
main:
ADDI64 r254, r254, -40d
ST r31, r254, 0a, 40h
JAL r31, r0, :get_ptr
LI64 r32, 0d
JNE r1, r32, :0
LI64 r1, 0d
JMP :1
0: LI64 r33, 10d
CP r34, r1
2: LD r1, r34, 0a, 8h
JEQ r1, r33, :1
ADDI64 r35, r1, 1d
ST r35, r34, 0a, 8h
JMP :2
1: LD r31, r254, 0a, 40h
ADDI64 r254, r254, 40d
JALA r0, r31, 0a
code size: 208
ret: 10
status: Ok(())

View file

@ -0,0 +1,65 @@
main:
ADDI64 r254, r254, -122d
ST r31, r254, 26a, 96h
JAL r31, r0, :returner_fn
CP r32, r1
ADDI64 r1, r254, 2d
JAL r31, r0, :returner_bn
ADDI64 r33, r254, 0d
JAL r31, r0, :returner_cn
ST r1, r254, 0a, 2h
LI8 r34, 0b
LI8 r35, 0b
LD r36, r254, 2a, 1h
CP r1, r32
ANDI r37, r37, 255d
ANDI r1, r1, 255d
CMPU r37, r1, r34
CMPUI r37, r37, 0d
ANDI r38, r38, 255d
ANDI r36, r36, 255d
CMPU r38, r36, r35
CMPUI r38, r38, 0d
LD r39, r254, 0a, 1h
AND r40, r38, r37
ANDI r41, r41, 255d
ANDI r39, r39, 255d
CMPU r41, r39, r35
CMPUI r41, r41, 0d
AND r42, r41, r40
ANDI r42, r42, 255d
JNE r42, r0, :0
LI64 r1, 0d
JMP :1
0: LI64 r1, 1d
1: LD r31, r254, 26a, 96h
ADDI64 r254, r254, 122d
JALA r0, r31, 0a
returner_bn:
ADDI64 r254, r254, -24d
LI8 r6, 1b
ADDI64 r5, r254, 0d
ST r6, r254, 0a, 1h
LI64 r6, 0d
ST r6, r254, 8a, 8h
ST r6, r254, 16a, 8h
BMC r5, r1, 24h
ADDI64 r254, r254, 24d
JALA r0, r31, 0a
returner_cn:
ADDI64 r254, r254, -2d
LI8 r4, 1b
ADDI64 r3, r254, 0d
ST r4, r254, 0a, 1h
LI8 r4, 0b
ST r4, r254, 1a, 1h
LD r1, r3, 0a, 2h
ADDI64 r254, r254, 2d
JALA r0, r31, 0a
returner_fn:
LD r1, r254, 0a, 0h
ORI r1, r1, 128d
JALA r0, r31, 0a
code size: 546
ret: 1
status: Ok(())

View file

@ -2,86 +2,134 @@ decide:
LI8 r1, 1b
JALA r0, r31, 0a
main:
ADDI64 r254, r254, -136d
ST r31, r254, 80a, 56h
ADDI64 r254, r254, -224d
ST r31, r254, 80a, 144h
JAL r31, r0, :decide
LI64 r4, 0d
ADDI64 r32, r254, 72d
LI64 r32, 0d
ADDI64 r2, r254, 72d
CP r33, r2
ANDI r1, r1, 255d
JNE r1, r0, :0
CP r33, r4
CP r34, r32
JMP :1
0: CP r33, r32
1: JNE r33, r4, :2
0: CP r34, r33
1: JNE r34, r32, :2
LI64 r1, 9001d
JMP :3
2: JAL r31, r0, :decide
LI8 r34, 0b
LI8 r35, 1b
LI8 r35, 0b
ANDI r1, r1, 255d
JNE r1, r0, :4
ST r35, r254, 56a, 1h
LD r9, r33, 0a, 8h
ST r9, r254, 64a, 8h
LI8 r36, 1b
ST r36, r254, 56a, 1h
LD r36, r34, 0a, 8h
ST r36, r254, 64a, 8h
JMP :5
4: ST r34, r254, 56a, 1h
5: LD r6, r254, 56a, 1h
ANDI r6, r6, 255d
ANDI r34, r34, 255d
JEQ r6, r34, :6
4: ST r35, r254, 56a, 1h
5: LD r37, r254, 56a, 1h
ANDI r37, r37, 255d
ANDI r35, r35, 255d
JEQ r37, r35, :6
LI64 r1, 42d
JMP :3
6: JAL r31, r0, :decide
LI32 r2, 0w
LI32 r38, 0w
ANDI r1, r1, 255d
JNE r1, r0, :7
CP r36, r2
CP r39, r38
JMP :8
7: LI32 r36, 8388609w
8: ANDI r36, r36, 4294967295d
ANDI r2, r2, 4294967295d
JNE r36, r2, :9
7: LI32 r39, 2147483649w
8: ANDI r39, r39, 4294967295d
ANDI r38, r38, 4294967295d
JNE r39, r38, :9
LI64 r1, 69d
JMP :3
9: JAL r31, r0, :decide
LI64 r3, 0d
LI64 r37, 1d
9: ADDI64 r3, r254, 40d
CP r40, r3
JAL r31, r0, :new_foo
ST r1, r254, 40a, 16h
LI64 r32, 0d
LD r41, r254, 40a, 8h
JNE r41, r32, :10
LI64 r1, 999d
JMP :3
10: LRA r4, r0, :"foo\0"
CP r3, r40
CP r2, r3
LD r2, r2, 0a, 16h
JAL r31, r0, :use_foo
ADDI64 r42, r254, 0d
JAL r31, r0, :no_foo
ST r1, r254, 0a, 16h
JAL r31, r0, :decide
ANDI r1, r1, 255d
JNE r1, r0, :10
ST r3, r254, 16a, 8h
JMP :11
10: ST r32, r254, 16a, 8h
ST r37, r254, 24a, 8h
ST r37, r254, 72a, 8h
11: LD r2, r254, 16a, 8h
JNE r2, r3, :12
JNE r1, r0, :11
CP r2, r33
JMP :12
11: CP r2, r33
ST r2, r254, 0a, 8h
LI64 r43, 1d
ST r43, r254, 8a, 8h
ST r43, r254, 72a, 8h
12: LD r44, r254, 0a, 8h
JNE r44, r32, :13
LI64 r1, 34d
JMP :3
12: JAL r31, r0, :decide
ADDI64 r10, r254, 32d
13: ADDI64 r1, r254, 16d
JAL r31, r0, :new_bar
JAL r31, r0, :decide
ANDI r1, r1, 255d
JNE r1, r0, :13
ADDI64 r11, r254, 0d
ST r32, r254, 0a, 8h
ST r37, r254, 8a, 8h
ST r35, r254, 32a, 1h
ADDI64 r12, r10, 8d
BMC r11, r12, 16h
JMP :14
13: ST r34, r254, 32a, 1h
14: LD r11, r254, 32a, 1h
ANDI r11, r11, 255d
ANDI r34, r34, 255d
JEQ r11, r34, :15
JNE r1, r0, :14
JMP :15
14: ST r35, r254, 16a, 1h
15: LD r45, r254, 16a, 1h
ANDI r45, r45, 255d
ANDI r35, r35, 255d
JEQ r45, r35, :16
LI64 r1, 420d
JMP :3
15: LD r5, r254, 16a, 8h
LD r7, r5, 0a, 8h
ANDI r9, r36, 65535d
SUB64 r1, r9, r7
3: LD r31, r254, 80a, 56h
ADDI64 r254, r254, 136d
16: LD r46, r254, 0a, 8h
LD r47, r46, 0a, 8h
ANDI r48, r39, 65535d
SUB64 r1, r48, r47
3: LD r31, r254, 80a, 144h
ADDI64 r254, r254, 224d
JALA r0, r31, 0a
code size: 729
new_bar:
ADDI64 r254, r254, -24d
LI8 r8, 1b
ADDI64 r7, r254, 0d
ST r8, r254, 0a, 1h
ST r2, r254, 8a, 8h
LI64 r9, 1d
ST r9, r254, 16a, 8h
BMC r7, r1, 24h
ADDI64 r254, r254, 24d
JALA r0, r31, 0a
new_foo:
ADDI64 r254, r254, -24d
ADDI64 r3, r254, 0d
ADDI64 r2, r254, 8d
ST r3, r254, 8a, 8h
LI64 r5, 0d
ST r5, r254, 16a, 8h
LD r1, r2, 0a, 16h
ADDI64 r254, r254, 24d
JALA r0, r31, 0a
no_foo:
ADDI64 r254, r254, -16d
ADDI64 r1, r254, 0d
LI64 r3, 0d
ST r3, r254, 0a, 8h
LD r1, r1, 0a, 16h
ADDI64 r254, r254, 16d
JALA r0, r31, 0a
use_foo:
ADDI64 r254, r254, -16d
ST r2, r254, 0a, 16h
ADDI64 r2, r254, 0d
ADDI64 r254, r254, 16d
JALA r0, r31, 0a
code size: 1143
ret: 0
status: Ok(())

View file

@ -2,14 +2,14 @@ inb:
CP r1, r2
JALA r0, r31, 0a
main:
ADDI64 r254, r254, -24d
ST r31, r254, 0a, 24h
ADDI64 r254, r254, -32d
ST r31, r254, 0a, 32h
LI64 r32, 0d
LI64 r33, 100d
4: CP r2, r33
JAL r31, r0, :inb
ANDI r7, r1, 2d
JNE r7, r32, :0
ANDI r34, r1, 2d
JNE r34, r32, :0
LI64 r2, 96d
CP r3, r32
JAL r31, r0, :outb
@ -20,8 +20,8 @@ main:
JMP :2
1: JMP :3
0: JMP :4
2: LD r31, r254, 0a, 24h
ADDI64 r254, r254, 24d
2: LD r31, r254, 0a, 32h
ADDI64 r254, r254, 32d
JALA r0, r31, 0a
outb:
JALA r0, r31, 0a

View file

@ -0,0 +1,22 @@
main:
ADDI64 r254, r254, -16d
ADDI64 r3, r254, 0d
LI64 r6, 0d
CP r3, r6
CP r4, r6
CP r5, r6
ECA
ST r1, r254, 0a, 16h
LI8 r8, 0b
LD r9, r254, 0a, 1h
ANDI r9, r9, 255d
ANDI r8, r8, 255d
JNE r9, r8, :0
UN
0: LD r1, r254, 8a, 8h
ADDI64 r254, r254, 16d
JALA r0, r31, 0a
unknown ecall: 0
code size: 142
ret: 0
status: Err(Unreachable)

View file

@ -1,23 +1,23 @@
main:
ADDI64 r254, r254, -48d
ST r31, r254, 40a, 8h
LI64 r4, 4d
ADDI64 r3, r254, 24d
ADDI64 r6, r254, 0d
ST r4, r254, 24a, 8h
LI64 r5, 1d
ST r5, r254, 32a, 8h
ST r5, r254, 16a, 8h
BMC r3, r6, 16h
ADDI64 r254, r254, -104d
ST r31, r254, 40a, 64h
LI64 r32, 4d
ADDI64 r33, r254, 24d
ADDI64 r34, r254, 0d
ST r32, r254, 24a, 8h
LI64 r35, 1d
ST r35, r254, 32a, 8h
ST r35, r254, 16a, 8h
BMC r33, r34, 16h
JAL r31, r0, :opaque
ST r1, r254, 0a, 16h
LD r4, r254, 8a, 8h
LD r6, r254, 16a, 8h
ADD64 r8, r6, r4
LD r6, r254, 0a, 8h
SUB64 r1, r6, r8
LD r31, r254, 40a, 8h
ADDI64 r254, r254, 48d
LD r36, r254, 8a, 8h
LD r37, r254, 16a, 8h
ADD64 r38, r37, r36
LD r37, r254, 0a, 8h
SUB64 r1, r37, r38
LD r31, r254, 40a, 64h
ADDI64 r254, r254, 104d
JALA r0, r31, 0a
opaque:
ADDI64 r254, r254, -16d

View file

@ -3,17 +3,17 @@ clobber:
ST r3, r2, 0a, 8h
JALA r0, r31, 0a
main:
ADDI64 r254, r254, -16d
ST r31, r254, 8a, 8h
ADDI64 r254, r254, -40d
ST r31, r254, 8a, 32h
ADDI64 r2, r254, 0d
LI64 r3, 2d
ST r3, r254, 0a, 8h
LI64 r32, 2d
ST r32, r254, 0a, 8h
JAL r31, r0, :clobber
LD r8, r254, 0a, 8h
LI64 r9, 4d
SUB64 r1, r9, r8
LD r31, r254, 8a, 8h
ADDI64 r254, r254, 16d
LD r33, r254, 0a, 8h
LI64 r34, 4d
SUB64 r1, r34, r33
LD r31, r254, 8a, 32h
ADDI64 r254, r254, 40d
JALA r0, r31, 0a
code size: 169
ret: 0

View file

@ -1,18 +1,18 @@
drop:
JALA r0, r31, 0a
main:
ADDI64 r254, r254, -24d
ST r31, r254, 8a, 16h
ADDI64 r254, r254, -32d
ST r31, r254, 8a, 24h
ADDI64 r2, r254, 0d
LI64 r32, 1d
ST r32, r254, 0a, 8h
JAL r31, r0, :modify
CP r2, r32
JAL r31, r0, :drop
LD r8, r254, 0a, 8h
ADDI64 r1, r8, -2d
LD r31, r254, 8a, 16h
ADDI64 r254, r254, 24d
LD r33, r254, 0a, 8h
ADDI64 r1, r33, -2d
LD r31, r254, 8a, 24h
ADDI64 r254, r254, 32d
JALA r0, r31, 0a
modify:
LI64 r3, 2d

View file

@ -1,3 +1,6 @@
test.hb:3:16: type 'int' cannot be uninitialized, use a zero value instead ('null' in case of pointers)
a := @as(int, idk)
^
main:
LI64 r1, 0d
JALA r0, r31, 0a
code size: 29
ret: 0
status: Ok(())

View file

@ -1,6 +1,6 @@
create_back_buffer:
ADDI64 r254, r254, -48d
ST r31, r254, 0a, 48h
ADDI64 r254, r254, -56d
ST r31, r254, 0a, 56h
LI64 r32, 255d
JGTS r2, r32, :0
JAL r31, r0, :request_page
@ -9,23 +9,23 @@ create_back_buffer:
LI8 r34, 255b
CP r2, r34
JAL r31, r0, :request_page
CP r35, r1
LI64 r36, 0d
LI64 r35, 0d
CP r2, r33
SUB64 r33, r2, r32
5: JGTS r33, r36, :2
CP r1, r35
SUB64 r36, r2, r32
5: JGTS r36, r35, :2
JMP :1
2: JLTS r33, r32, :3
2: CP r37, r1
JLTS r36, r32, :3
CP r2, r34
JAL r31, r0, :request_page
JMP :4
3: CP r2, r33
3: CP r2, r36
JAL r31, r0, :request_page
4: SUB64 r33, r33, r32
4: SUB64 r36, r36, r32
CP r1, r37
JMP :5
1: LD r31, r254, 0a, 48h
ADDI64 r254, r254, 48d
1: LD r31, r254, 0a, 56h
ADDI64 r254, r254, 56d
JALA r0, r31, 0a
main:
ADDI64 r254, r254, -8d

View file

@ -1,22 +1,22 @@
main:
ADDI64 r254, r254, -12d
ST r31, r254, 4a, 8h
ADDI64 r2, r254, 0d
ADDI64 r254, r254, -100d
ST r31, r254, 4a, 96h
ADDI64 r32, r254, 0d
JAL r31, r0, :random_color
ST r1, r254, 0a, 4h
LD r5, r254, 0a, 1h
LD r8, r254, 1a, 1h
LD r12, r254, 2a, 1h
ANDI r9, r5, 255d
ANDI r1, r8, 255d
LD r6, r254, 3a, 1h
ANDI r5, r12, 255d
ADD64 r4, r1, r9
ANDI r10, r6, 255d
ADD64 r9, r4, r5
ADD64 r1, r9, r10
LD r31, r254, 4a, 8h
ADDI64 r254, r254, 12d
LD r33, r254, 0a, 1h
LD r34, r254, 1a, 1h
LD r35, r254, 2a, 1h
ANDI r36, r33, 255d
ANDI r37, r34, 255d
LD r38, r254, 3a, 1h
ANDI r39, r35, 255d
ADD64 r40, r37, r36
ANDI r41, r38, 255d
ADD64 r42, r40, r39
ADD64 r1, r42, r41
LD r31, r254, 4a, 96h
ADDI64 r254, r254, 100d
JALA r0, r31, 0a
random_color:
LRA r1, r0, :white

View file

@ -0,0 +1,31 @@
get_format:
ADDI64 r254, r254, -16d
LI8 r5, 1b
ADDI64 r4, r254, 0d
LRA r3, r0, :BMP
ST r5, r254, 0a, 1h
LD r6, r3, 0a, 8h
ST r6, r254, 8a, 8h
LD r1, r4, 0a, 16h
ADDI64 r254, r254, 16d
JALA r0, r31, 0a
main:
ADDI64 r254, r254, -48d
ST r31, r254, 16a, 32h
ADDI64 r32, r254, 0d
JAL r31, r0, :get_format
ST r1, r254, 0a, 16h
LI8 r33, 0b
LD r34, r254, 0a, 1h
ANDI r34, r34, 255d
ANDI r33, r33, 255d
JNE r34, r33, :0
LI64 r1, 1d
JMP :1
0: LD r1, r254, 8a, 8h
1: LD r31, r254, 16a, 32h
ADDI64 r254, r254, 48d
JALA r0, r31, 0a
code size: 283
ret: 0
status: Ok(())

View file

@ -1,25 +1,25 @@
main:
ADDI64 r254, r254, -12d
ST r31, r254, 4a, 8h
LRA r1, r0, :white
ADDI64 r4, r254, 0d
LD r2, r1, 0a, 4h
ADDI64 r254, r254, -36d
ST r31, r254, 4a, 32h
LRA r32, r0, :white
ADDI64 r33, r254, 0d
LD r2, r32, 0a, 4h
JAL r31, r0, :u32_to_color
ST r1, r254, 0a, 4h
LD r9, r254, 0a, 1h
ANDI r1, r9, 255d
LD r31, r254, 4a, 8h
ADDI64 r254, r254, 12d
LD r34, r254, 0a, 1h
ANDI r1, r34, 255d
LD r31, r254, 4a, 32h
ADDI64 r254, r254, 36d
JALA r0, r31, 0a
u32_to_color:
ADDI64 r254, r254, -12d
ST r31, r254, 4a, 8h
ADDI64 r254, r254, -20d
ST r31, r254, 4a, 16h
JAL r31, r0, :u32_to_u32
ADDI64 r5, r254, 0d
ADDI64 r32, r254, 0d
ST r1, r254, 0a, 4h
LD r1, r5, 0a, 4h
LD r31, r254, 4a, 8h
ADDI64 r254, r254, 12d
LD r1, r32, 0a, 4h
LD r31, r254, 4a, 16h
ADDI64 r254, r254, 20d
JALA r0, r31, 0a
u32_to_u32:
CP r1, r2

View file

@ -4,15 +4,14 @@ fib:
CP r32, r2
LI64 r33, 2d
JLTU r2, r33, :0
CP r6, r32
ADDI64 r2, r6, -1d
CP r34, r32
ADDI64 r2, r34, -1d
JAL r31, r0, :fib
CP r2, r32
CP r34, r1
SUB64 r2, r2, r33
JAL r31, r0, :fib
CP r6, r34
ADD64 r1, r1, r6
ADD64 r1, r1, r34
JMP :1
0: CP r1, r32
1: LD r31, r254, 0a, 32h
@ -41,11 +40,10 @@ main:
CP r2, r32
CP r33, r1
JAL r31, r0, :fib_iter
CP r9, r33
SUB64 r1, r9, r1
SUB64 r1, r33, r1
LD r31, r254, 0a, 24h
ADDI64 r254, r254, 24d
JALA r0, r31, 0a
code size: 306
code size: 300
ret: 0
status: Ok(())

View file

@ -10,28 +10,28 @@ foo:
ADDI64 r254, r254, 16d
JALA r0, r31, 0a
main:
ADDI64 r254, r254, -56d
ST r31, r254, 48a, 8h
ADDI64 r2, r254, 32d
ADDI64 r254, r254, -128d
ST r31, r254, 48a, 80h
ADDI64 r32, r254, 32d
JAL r31, r0, :foo
ST r1, r254, 32a, 16h
ADDI64 r7, r254, 16d
ADDI64 r33, r254, 16d
JAL r31, r0, :foo
ST r1, r254, 16a, 16h
ADDI64 r2, r254, 0d
ADDI64 r34, r254, 0d
JAL r31, r0, :foo
ST r1, r254, 0a, 16h
LD r1, r254, 24a, 4h
LD r7, r254, 12a, 4h
ANDI r4, r1, 4294967295d
LD r1, r254, 32a, 8h
ANDI r11, r7, 4294967295d
ADD64 r8, r1, r4
ADD64 r2, r8, r11
LI64 r3, 7d
SUB64 r1, r3, r2
LD r31, r254, 48a, 8h
ADDI64 r254, r254, 56d
LD r35, r254, 24a, 4h
LD r36, r254, 12a, 4h
ANDI r37, r35, 4294967295d
LD r35, r254, 32a, 8h
ANDI r38, r36, 4294967295d
ADD64 r39, r35, r37
ADD64 r40, r39, r38
LI64 r34, 7d
SUB64 r1, r34, r40
LD r31, r254, 48a, 80h
ADDI64 r254, r254, 128d
JALA r0, r31, 0a
code size: 355
ret: 0

View file

@ -1,23 +1,24 @@
main:
ADDI64 r254, r254, -56d
ST r31, r254, 32a, 24h
LI64 r3, 4d
ADDI64 r2, r254, 16d
ST r3, r254, 16a, 8h
LI64 r32, 3d
ST r32, r254, 24a, 8h
ADDI64 r33, r254, 0d
LD r3, r2, 0a, 16h
ADDI64 r254, r254, -72d
ST r31, r254, 32a, 40h
LI64 r32, 4d
ADDI64 r4, r254, 16d
ST r32, r254, 16a, 8h
LI64 r33, 3d
ST r33, r254, 24a, 8h
ADDI64 r34, r254, 0d
CP r3, r4
LD r3, r3, 0a, 16h
JAL r31, r0, :odher_pass
ST r1, r254, 0a, 16h
LD r2, r254, 8a, 8h
JNE r2, r32, :0
CP r2, r33
LD r35, r254, 8a, 8h
JNE r35, r33, :0
CP r2, r34
JAL r31, r0, :pass
JMP :1
0: LI64 r1, 0d
1: LD r31, r254, 32a, 24h
ADDI64 r254, r254, 56d
1: LD r31, r254, 32a, 40h
ADDI64 r254, r254, 72d
JALA r0, r31, 0a
odher_pass:
ADDI64 r254, r254, -16d
@ -29,6 +30,6 @@ odher_pass:
pass:
LD r1, r2, 0a, 8h
JALA r0, r31, 0a
code size: 305
code size: 308
ret: 4
status: Ok(())

View file

@ -1,47 +1,47 @@
main:
ADDI64 r254, r254, -24d
ST r31, r254, 16a, 8h
ADDI64 r3, r254, 0d
ADDI64 r254, r254, -56d
ST r31, r254, 16a, 40h
ADDI64 r32, r254, 0d
LI64 r4, 0d
CP r3, r4
JAL r31, r0, :maina
ST r1, r254, 0a, 16h
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
LD r33, r254, 12a, 1h
LD r34, r254, 3a, 1h
SUB8 r35, r34, r33
ANDI r1, r35, 255d
LD r31, r254, 16a, 40h
ADDI64 r254, r254, 56d
JALA r0, r31, 0a
maina:
ADDI64 r254, r254, -28d
ST r31, r254, 20a, 8h
ADDI64 r5, r254, 16d
ADDI64 r254, r254, -68d
ST r31, r254, 20a, 48h
ADDI64 r32, r254, 16d
JAL r31, r0, :small_struct
ST r1, r254, 16a, 4h
LI8 r9, 0b
ADDI64 r1, r254, 0d
ST r9, r254, 0a, 1h
ST r9, r254, 1a, 1h
ST r9, r254, 2a, 1h
LI8 r3, 3b
ST r3, r254, 3a, 1h
LI8 r6, 1b
ST r6, r254, 4a, 1h
ST r9, r254, 5a, 1h
ST r9, r254, 6a, 1h
ST r9, r254, 7a, 1h
ST r9, r254, 8a, 1h
ST r9, r254, 9a, 1h
ST r9, r254, 10a, 1h
ST r3, r254, 11a, 1h
ST r6, r254, 12a, 1h
ST r9, r254, 13a, 1h
ST r9, r254, 14a, 1h
ST r9, r254, 15a, 1h
LD r1, r1, 0a, 16h
LD r31, r254, 20a, 8h
ADDI64 r254, r254, 28d
LI8 r33, 0b
ADDI64 r34, r254, 0d
ST r33, r254, 0a, 1h
ST r33, r254, 1a, 1h
ST r33, r254, 2a, 1h
LI8 r35, 3b
ST r35, r254, 3a, 1h
LI8 r36, 1b
ST r36, r254, 4a, 1h
ST r33, r254, 5a, 1h
ST r33, r254, 6a, 1h
ST r33, r254, 7a, 1h
ST r33, r254, 8a, 1h
ST r33, r254, 9a, 1h
ST r33, r254, 10a, 1h
ST r35, r254, 11a, 1h
ST r36, r254, 12a, 1h
ST r33, r254, 13a, 1h
ST r33, r254, 14a, 1h
ST r33, r254, 15a, 1h
LD r1, r34, 0a, 16h
LD r31, r254, 20a, 48h
ADDI64 r254, r254, 68d
JALA r0, r31, 0a
small_struct:
ADDI64 r254, r254, -4d