adding global mutatuon to the test

This commit is contained in:
mlokr 2024-09-08 12:00:07 +02:00
parent ee30069195
commit bb41da484f
No known key found for this signature in database
GPG key ID: DEA147DDEE644993
10 changed files with 287 additions and 174 deletions

View file

@ -217,6 +217,7 @@ fib := fn(n: int): int {
} }
main := fn(): int { main := fn(): int {
complex_global_var += 5
return complex_global_var return complex_global_var
} }
``` ```

View file

@ -2106,7 +2106,7 @@ impl Codegen {
} }
E::BinOp { left, op, right } if op != T::Decl => 'ops: { E::BinOp { left, op, right } if op != T::Decl => 'ops: {
let left = self.expr_ctx(left, Ctx { let left = self.expr_ctx(left, Ctx {
ty: ctx.ty.filter(|_| dbg!(dbg!(op).is_homogenous())), ty: ctx.ty.filter(|_| op.is_homogenous()),
..Default::default() ..Default::default()
})?; })?;

View file

@ -13,16 +13,17 @@ use {
HashMap, HashMap,
}, },
core::fmt, core::fmt,
hbvm::mem::softpaging::lookup,
std::{ std::{
cell::RefCell, cell::RefCell,
collections::{hash_map, BTreeMap}, collections::{hash_map, BTreeMap},
default,
fmt::Display, fmt::Display,
hash::{Hash as _, Hasher}, hash::{Hash as _, Hasher},
intrinsics::unreachable,
mem, mem,
ops::{self, Range}, ops::{self, Range},
rc::Rc, rc::Rc,
usize, u32, usize,
}, },
}; };
@ -463,11 +464,43 @@ mod ty {
} }
} }
struct LookupEntry {
nid: u32,
hash: u64,
}
#[derive(Default)]
struct IdentityHash(u64);
impl std::hash::Hasher for IdentityHash {
fn finish(&self) -> u64 {
self.0
}
fn write(&mut self, _: &[u8]) {
unimplemented!()
}
fn write_u64(&mut self, i: u64) {
self.0 = i;
}
}
impl std::hash::Hash for LookupEntry {
fn hash<H: Hasher>(&self, state: &mut H) {
state.write_u64(self.hash);
}
}
struct Nodes { struct Nodes {
values: Vec<Result<Node, u32>>, values: Vec<Result<Node, u32>>,
visited: BitSet, visited: BitSet,
free: u32, free: u32,
lookup: HashMap<Nid, ()>, lookup: std::collections::hash_map::HashMap<
LookupEntry,
(),
std::hash::BuildHasherDefault<IdentityHash>,
>,
} }
impl Default for Nodes { impl Default for Nodes {
@ -504,7 +537,7 @@ impl Nodes {
let node = Node { let node = Node {
inputs: inps.into(), inputs: inps.into(),
kind: kind.clone(), kind,
color: 0, color: 0,
depth: u32::MAX, depth: u32::MAX,
lock_rc: 0, lock_rc: 0,
@ -512,15 +545,17 @@ impl Nodes {
outputs: vec![], outputs: vec![],
}; };
let mut hasher = crate::FnvHasher::default(); let mut lookup_meta = None;
node.key().hash(&mut hasher); if node.kind != Kind::Phi || node.inputs[2] != 0 {
let (raw_entry, hash) = Self::find_node(&mut self.lookup, &self.values, &node);
let (raw_entry, _) = Self::find_node(&mut self.lookup, &self.values, &node); let entry = match raw_entry {
hash_map::RawEntryMut::Occupied(mut o) => return o.get_key_value().0.nid,
hash_map::RawEntryMut::Vacant(v) => v,
};
let entry = match raw_entry { lookup_meta = Some((entry, hash));
hash_map::RawEntryMut::Occupied(mut o) => return *o.get_key_value().0, }
hash_map::RawEntryMut::Vacant(v) => v,
};
if self.free == u32::MAX { if self.free == u32::MAX {
self.free = self.values.len() as _; self.free = self.values.len() as _;
@ -532,40 +567,48 @@ impl Nodes {
debug_assert_ne!(d, free); debug_assert_ne!(d, free);
self.values[d as usize].as_mut().unwrap().outputs.push(free); self.values[d as usize].as_mut().unwrap().outputs.push(free);
} }
self.free = mem::replace(&mut self.values[free as usize], Ok(node)).unwrap_err(); self.free = mem::replace(&mut self.values[free as usize], Ok(node)).unwrap_err();
*entry.insert(free, ()).0
if let Some((entry, hash)) = lookup_meta {
entry.insert(LookupEntry { nid: free, hash }, ());
}
free
} }
fn find_node<'a>( fn find_node<'a>(
lookup: &'a mut HashMap<Nid, ()>, lookup: &'a mut std::collections::hash_map::HashMap<
LookupEntry,
(),
std::hash::BuildHasherDefault<IdentityHash>,
>,
values: &[Result<Node, u32>], values: &[Result<Node, u32>],
node: &Node, node: &Node,
) -> (hash_map::RawEntryMut<'a, u32, (), std::hash::BuildHasherDefault<crate::FnvHasher>>, u64) ) -> (
{ hash_map::RawEntryMut<'a, LookupEntry, (), std::hash::BuildHasherDefault<IdentityHash>>,
u64,
) {
let mut hasher = crate::FnvHasher::default(); let mut hasher = crate::FnvHasher::default();
node.key().hash(&mut hasher); node.key().hash(&mut hasher);
let hash = hasher.finish(); let hash = hasher.finish();
let entry = lookup
( .raw_entry_mut()
lookup .from_hash(hash, |n| values[n.nid as usize].as_ref().unwrap().key() == node.key());
.raw_entry_mut() (entry, hash)
.from_hash(hash, |&n| values[n as usize].as_ref().unwrap().key() == node.key()),
hash,
)
} }
fn remove_node_lookup(&mut self, target: Nid) { fn remove_node_lookup(&mut self, target: Nid) {
match Self::find_node( if self[target].kind != Kind::Phi || self[target].inputs[2] != 0 {
&mut self.lookup, match Self::find_node(
&self.values, &mut self.lookup,
&self.values[target as usize].as_ref().unwrap(), &self.values,
) self.values[target as usize].as_ref().unwrap(),
.0 )
{ .0
hash_map::RawEntryMut::Occupied(o) => o.remove(), {
hash_map::RawEntryMut::Vacant(_) => unreachable!(), hash_map::RawEntryMut::Occupied(o) => o.remove(),
}; hash_map::RawEntryMut::Vacant(_) => unreachable!(),
};
}
} }
fn new_node(&mut self, ty: impl Into<ty::Id>, kind: Kind, inps: impl Into<Vec<u32>>) -> Nid { fn new_node(&mut self, ty: impl Into<ty::Id>, kind: Kind, inps: impl Into<Vec<u32>>) -> Nid {
@ -619,12 +662,20 @@ impl Nodes {
Kind::Call { .. } => {} Kind::Call { .. } => {}
Kind::If => return self.peephole_if(target), Kind::If => return self.peephole_if(target),
Kind::Region => {} Kind::Region => {}
Kind::Phi => {} Kind::Phi => return self.peephole_phi(target),
Kind::Loop => {} Kind::Loop => {}
} }
None None
} }
fn peephole_phi(&mut self, target: Nid) -> Option<Nid> {
if self[target].inputs[1] == self[target].inputs[2] {
return Some(self[target].inputs[1]);
}
None
}
fn peephole_if(&mut self, target: Nid) -> Option<Nid> { fn peephole_if(&mut self, target: Nid) -> Option<Nid> {
let cond = self[target].inputs[1]; let cond = self[target].inputs[1];
if let Kind::ConstInt { value } = self[cond].kind { if let Kind::ConstInt { value } = self[cond].kind {
@ -720,7 +771,7 @@ impl Nodes {
} }
if changed { if changed {
return Some(self.new_node(self[target].ty, self[target].kind.clone(), [lhs, rhs])); return Some(self.new_node(self[target].ty, self[target].kind, [lhs, rhs]));
} }
None None
@ -731,11 +782,13 @@ impl Nodes {
} }
fn replace(&mut self, target: Nid, with: Nid) { fn replace(&mut self, target: Nid, with: Nid) {
let mut back_press = 0;
for i in 0..self[target].outputs.len() { for i in 0..self[target].outputs.len() {
let out = self[target].outputs[i]; let out = self[target].outputs[i - back_press];
let index = self[out].inputs.iter().position(|&p| p == target).unwrap(); let index = self[out].inputs.iter().position(|&p| p == target).unwrap();
let rpl = self.modify_input(out, index, with); let prev_len = self[target].outputs.len();
self[with].outputs.push(rpl); self.modify_input(out, index, with);
back_press += (self[target].outputs.len() != prev_len) as usize;
} }
self.remove(target); self.remove(target);
@ -750,17 +803,19 @@ impl Nodes {
let (entry, hash) = Self::find_node( let (entry, hash) = Self::find_node(
&mut self.lookup, &mut self.lookup,
&self.values, &self.values,
&self.values[target as usize].as_ref().unwrap(), self.values[target as usize].as_ref().unwrap(),
); );
match entry { match entry {
hash_map::RawEntryMut::Occupied(mut other) => { hash_map::RawEntryMut::Occupied(mut other) => {
let rpl = *other.get_key_value().0; log::dbg!("rplc");
let rpl = other.get_key_value().0.nid;
self[target].inputs[inp_index] = prev; self[target].inputs[inp_index] = prev;
self.replace(target, rpl); self.replace(target, rpl);
rpl rpl
} }
hash_map::RawEntryMut::Vacant(slot) => { hash_map::RawEntryMut::Vacant(slot) => {
slot.insert_hashed_nocheck(hash, target, ()); log::dbg!("mod");
slot.insert(LookupEntry { nid: target, hash }, ());
let index = self[prev].outputs.iter().position(|&o| o == target).unwrap(); let index = self[prev].outputs.iter().position(|&o| o == target).unwrap();
self[prev].outputs.swap_remove(index); self[prev].outputs.swap_remove(index);
self[with].outputs.push(target); self[with].outputs.push(target);
@ -913,8 +968,28 @@ impl Nodes {
failed = true; failed = true;
} }
let mut allowed_cfgs = 1 + (node.kind == Kind::If) as usize;
for &o in &node.outputs { for &o in &node.outputs {
let mut occurs = 0; if self.is_cfg(i) {
if allowed_cfgs == 0 && self.is_cfg(o) {
log::err!(
"multiple cfg outputs detected: {:?} -> {:?}",
node.kind,
self[o].kind
);
failed = true;
} else {
allowed_cfgs += self.is_cfg(o) as usize;
}
}
if matches!(node.kind, Kind::Region | Kind::Loop)
&& !self.is_cfg(o)
&& self[o].kind != Kind::Phi
{
log::err!("unexpected output node on region: {:?}", self[o].kind);
failed = true;
}
let other = match &self.values[o as usize] { let other = match &self.values[o as usize] {
Ok(other) => other, Ok(other) => other,
Err(_) => { Err(_) => {
@ -923,10 +998,11 @@ impl Nodes {
continue; continue;
} }
}; };
occurs += self[o].inputs.iter().filter(|&&el| el == i).count(); let occurs = self[o].inputs.iter().filter(|&&el| el == i).count();
if occurs == 0 { let self_occurs = self[i].outputs.iter().filter(|&&el| el == o).count();
if occurs != self_occurs {
log::err!( log::err!(
"the edge is not bidirectional: {i} {:?} {o} {:?}", "the edge is not bidirectional: {i} {:?} {self_occurs} {o} {:?} {occurs}",
node.kind, node.kind,
other.kind other.kind
); );
@ -961,11 +1037,19 @@ impl Nodes {
return true; return true;
} }
} }
return false; false
} }
self.visited.clear(self.values.len()); self.visited.clear(self.values.len());
climb_impl(self, from, &mut for_each) climb_impl(self, from, &mut for_each)
} }
fn late_peephole(&mut self, target: Nid) -> Nid {
if let Some(id) = self.peephole(target) {
self.replace(target, id);
return id;
}
target
}
} }
impl ops::Index<u32> for Nodes { impl ops::Index<u32> for Nodes {
@ -1625,16 +1709,23 @@ impl Codegen {
}; };
if self.ci.vars[index].value == 0 { if self.ci.vars[index].value == 0 {
self.ci.nodes.unlock(self.ci.vars[index].value);
let loob = self.ci.loops.last_mut().unwrap(); let loob = self.ci.loops.last_mut().unwrap();
let inps = [loob.node, loob.scope[index].value, loob.scope[index].value]; if self.ci.nodes[loob.scope[index].value].kind != Kind::Phi
self.ci.nodes.unlock(inps[1]); || self.ci.nodes[loob.scope[index].value].inputs[0] != loob.node
let ty = self.ci.nodes[inps[1]].ty; {
// TODO: dont apply peepholes here self.ci.nodes.unlock(self.ci.vars[index].value);
let phy = self.ci.nodes.new_node(ty, Kind::Phi, inps); let inps = [loob.node, loob.scope[index].value, 0];
self.ci.nodes[phy].lock_rc += 2; self.ci.nodes.unlock(inps[1]);
self.ci.vars[index].value = phy; let ty = self.ci.nodes[inps[1]].ty;
loob.scope[index].value = phy; let phi = self.ci.nodes.new_node_nop(ty, Kind::Phi, inps);
self.ci.nodes[phi].lock_rc += 2;
self.ci.vars[index].value = phi;
loob.scope[index].value = phi;
} else {
self.ci.nodes.unlock_remove(self.ci.vars[index].value);
self.ci.vars[index].value = loob.scope[index].value;
self.ci.nodes.lock(self.ci.vars[index].value);
}
} }
self.ci.nodes.check_scope_integrity(&self.ci.vars); self.ci.nodes.check_scope_integrity(&self.ci.vars);
@ -1751,8 +1842,12 @@ impl Codegen {
let ty = self.ci.nodes[else_var.value].ty; let ty = self.ci.nodes[else_var.value].ty;
debug_assert_eq!( debug_assert_eq!(
ty, self.ci.nodes[then_var.value].ty, ty,
"TODO: typecheck properly" self.ci.nodes[then_var.value].ty,
"TODO: typecheck properly: {} != {}\n{}",
self.ty_display(ty),
self.ty_display(self.ci.nodes[then_var.value].ty),
self.errors.borrow()
); );
let inps = [self.ci.ctrl, then_var.value, else_var.value]; let inps = [self.ci.ctrl, then_var.value, else_var.value];
@ -1826,33 +1921,35 @@ impl Codegen {
self.ci.nodes.check_scope_integrity(&self.ci.vars); self.ci.nodes.check_scope_integrity(&self.ci.vars);
self.ci.nodes.check_scope_integrity(&break_scope); self.ci.nodes.check_scope_integrity(&break_scope);
self.ci.nodes.check_scope_integrity(&scope); self.ci.nodes.check_scope_integrity(&scope);
for ((dest_var, scope_var), loop_var) in for ((dest_var, mut scope_var), loop_var) in
self.ci.vars.iter_mut().zip(scope).zip(break_scope) self.ci.vars.iter_mut().zip(scope).zip(break_scope)
{ {
if loop_var.value == 0 {
self.ci.nodes.unlock(loop_var.value);
debug_assert!(loop_var.value == dest_var.value);
self.ci.nodes.unlock(dest_var.value);
dest_var.value = scope_var.value;
continue;
}
debug_assert_eq!(self.ci.nodes[scope_var.value].kind, Kind::Phi);
if scope_var.value == loop_var.value {
let orig = self.ci.nodes[scope_var.value].inputs[1];
self.ci.nodes.lock(orig);
self.ci.nodes.unlock(loop_var.value);
self.ci.nodes.unlock_remove(scope_var.value);
self.ci.nodes.unlock_remove(dest_var.value);
dest_var.value = orig;
continue;
}
self.ci.nodes.unlock(loop_var.value); self.ci.nodes.unlock(loop_var.value);
let phy = self.ci.nodes.modify_input(scope_var.value, 2, loop_var.value);
self.ci.nodes.unlock_remove(dest_var.value); if loop_var.value != 0 {
dest_var.value = phy; self.ci.nodes.unlock(scope_var.value);
if loop_var.value != scope_var.value {
scope_var.value =
self.ci.nodes.modify_input(scope_var.value, 2, loop_var.value);
self.ci.nodes.lock(scope_var.value);
} else {
let phi = &self.ci.nodes[scope_var.value];
debug_assert_eq!(phi.kind, Kind::Phi);
debug_assert_eq!(phi.inputs[2], 0);
let prev = phi.inputs[1];
self.ci.nodes.replace(scope_var.value, prev);
scope_var.value = prev;
self.ci.nodes.lock(prev);
}
}
if dest_var.value == 0 {
self.ci.nodes.unlock_remove(dest_var.value);
dest_var.value = scope_var.value;
self.ci.nodes.lock(dest_var.value);
}
self.ci.nodes.unlock_remove(scope_var.value);
} }
self.ci.nodes.unlock(self.ci.ctrl); self.ci.nodes.unlock(self.ci.ctrl);
@ -2198,7 +2295,7 @@ impl Codegen {
fn color_control(&mut self, mut ctrl: Nid) -> Option<Nid> { fn color_control(&mut self, mut ctrl: Nid) -> Option<Nid> {
for _ in 0..30 { for _ in 0..30 {
match self.ci.nodes[ctrl].kind.clone() { match self.ci.nodes[ctrl].kind {
Kind::Start => unreachable!(), Kind::Start => unreachable!(),
Kind::End => unreachable!(), Kind::End => unreachable!(),
Kind::Return => { Kind::Return => {
@ -2250,7 +2347,7 @@ impl Codegen {
(None, Some(n)) | (Some(n), None) => n, (None, Some(n)) | (Some(n), None) => n,
(Some(l), Some(r)) if l == r => l, (Some(l), Some(r)) if l == r => l,
(Some(left), Some(right)) => { (Some(left), Some(right)) => {
todo!() todo!("{:?} {:?}", self.ci.nodes[left], self.ci.nodes[right]);
} }
}; };
@ -2258,14 +2355,12 @@ impl Codegen {
return Some(dest); return Some(dest);
} }
debug_assert!(left_unreachable.is_none() || right_unreachable.is_none());
debug_assert_eq!(self.ci.nodes[dest].kind, Kind::Region); debug_assert_eq!(self.ci.nodes[dest].kind, Kind::Region);
for i in 0..self.ci.nodes[dest].outputs.len() { for i in 0..self.ci.nodes[dest].outputs.len() {
let o = self.ci.nodes[dest].outputs[i]; let o = self.ci.nodes[dest].outputs[i];
if self.ci.nodes[o].kind == Kind::Phi { if self.ci.nodes[o].kind == Kind::Phi {
self.color_phy(o); self.color_phi(o);
self.ci.nodes[o].depth = self.ci.loop_depth; self.ci.nodes[o].depth = self.ci.loop_depth;
} }
} }
@ -2284,15 +2379,15 @@ impl Codegen {
} }
for i in 0..self.ci.nodes[ctrl].outputs.len() { for i in 0..self.ci.nodes[ctrl].outputs.len() {
let maybe_phy = self.ci.nodes[ctrl].outputs[i]; let maybe_phi = self.ci.nodes[ctrl].outputs[i];
let Node { kind: Kind::Phi, ref inputs, .. } = self.ci.nodes[maybe_phy] let Node { kind: Kind::Phi, ref inputs, .. } = self.ci.nodes[maybe_phi]
else { else {
continue; continue;
}; };
_ = self.color_expr_consume(inputs[1]); _ = self.color_expr_consume(inputs[1]);
self.ci.nodes[maybe_phy].depth = self.ci.loop_depth; self.ci.nodes[maybe_phi].depth = self.ci.loop_depth;
self.ci.set_next_color(maybe_phy); self.ci.set_next_color(maybe_phi);
} }
self.ci.nodes[ctrl].lock_rc = self.ci.code.len() as _; self.ci.nodes[ctrl].lock_rc = self.ci.code.len() as _;
@ -2307,7 +2402,7 @@ impl Codegen {
); );
for i in 0..self.ci.nodes[ctrl].outputs.len() { for i in 0..self.ci.nodes[ctrl].outputs.len() {
self.color_phy(self.ci.nodes[ctrl].outputs[i]); self.color_phi(self.ci.nodes[ctrl].outputs[i]);
} }
self.ci.loop_depth -= 1; self.ci.loop_depth -= 1;
@ -2321,8 +2416,8 @@ impl Codegen {
unreachable!() unreachable!()
} }
fn color_phy(&mut self, maybe_phy: Nid) { fn color_phi(&mut self, maybe_phi: Nid) {
let Node { kind: Kind::Phi, ref inputs, .. } = self.ci.nodes[maybe_phy] else { let Node { kind: Kind::Phi, ref inputs, .. } = self.ci.nodes[maybe_phi] else {
return; return;
}; };
let &[region, left, right] = inputs.as_slice() else { unreachable!() }; let &[region, left, right] = inputs.as_slice() else { unreachable!() };
@ -2330,14 +2425,14 @@ impl Codegen {
let lcolor = self.color_expr_consume(left); let lcolor = self.color_expr_consume(left);
let rcolor = self.color_expr_consume(right); let rcolor = self.color_expr_consume(right);
if self.ci.nodes[maybe_phy].color != 0 { if self.ci.nodes[maybe_phi].color != 0 {
// loop phy // loop phi
if let Some(c) = rcolor if let Some(c) = rcolor
&& !self.ci.nodes.climb_expr(right, |i, n| { && !self.ci.nodes.climb_expr(right, |i, n| {
matches!(n.kind, Kind::Phi) && n.inputs[0] == region && i != maybe_phy matches!(n.kind, Kind::Phi) && n.inputs[0] == region && i != maybe_phi
}) })
{ {
self.ci.recolor(right, c, self.ci.nodes[maybe_phy].color); self.ci.recolor(right, c, self.ci.nodes[maybe_phi].color);
} }
} else { } else {
let color = match (lcolor, rcolor) { let color = match (lcolor, rcolor) {
@ -2348,7 +2443,7 @@ impl Codegen {
lc lc
} }
}; };
self.ci.set_color(maybe_phy, color); self.ci.set_color(maybe_phi, color);
} }
} }
@ -2396,7 +2491,7 @@ impl Codegen {
fn emit_control(&mut self, mut ctrl: Nid) -> Option<Nid> { fn emit_control(&mut self, mut ctrl: Nid) -> Option<Nid> {
for _ in 0..30 { for _ in 0..30 {
match self.ci.nodes[ctrl].kind.clone() { match self.ci.nodes[ctrl].kind {
Kind::Start => unreachable!(), Kind::Start => unreachable!(),
Kind::End => unreachable!(), Kind::End => unreachable!(),
Kind::Return => { Kind::Return => {
@ -2439,14 +2534,14 @@ impl Codegen {
let mut parama = self.tys.parama(ret); let mut parama = self.tys.parama(ret);
for i in 1..self.ci.nodes[ctrl].inputs.len() { for i in 1..self.ci.nodes[ctrl].inputs.len() {
let arg = self.ci.nodes[ctrl].inputs[i]; let arg = self.ci.nodes[ctrl].inputs[i];
node_loc!(self, arg) = match self.tys.size_of(self.tof(arg)) {
let dst = match self.tys.size_of(self.tof(arg)) {
0 => continue, 0 => continue,
1..=8 => Loc { reg: parama.next() }, 1..=8 => Loc { reg: parama.next() },
s => todo!("{s}"), s => todo!("{s}"),
}; };
self.ci.regs.mark_leaked(node_loc!(self, arg).reg);
self.emit_expr_consume(arg); self.emit_expr_consume(arg);
self.ci.nodes[arg].depth = 0; self.ci.emit(instrs::cp(dst.reg, node_loc!(self, arg).reg));
} }
let reloc = Reloc::new(self.ci.code.len(), 3, 4); let reloc = Reloc::new(self.ci.code.len(), 3, 4);
@ -2770,8 +2865,7 @@ impl Codegen {
if color.rc == 0 { if color.rc == 0 {
if color.depth != self.ci.loop_depth { if color.depth != self.ci.loop_depth {
self.ci.delayed_frees.push(node.color); self.ci.delayed_frees.push(node.color);
} else { } else if color.loc != Loc::default() {
debug_assert_ne!(color.loc, Loc::default(), "{:?}", node);
self.ci.regs.free(color.loc.reg); self.ci.regs.free(color.loc.reg);
} }
} }

View file

@ -1,6 +1,6 @@
main: main:
ADDI64 r254, r254, -64d ADDI64 r254, r254, -80d
ST r31, r254, 0a, 64h ST r31, r254, 0a, 80h
JAL r31, r0, :check_platform JAL r31, r0, :check_platform
CP r32, r1 CP r32, r1
LI64 r33, 100d LI64 r33, 100d
@ -17,29 +17,31 @@ main:
CP r3, r36 CP r3, r36
CP r4, r33 CP r4, r33
JAL r31, r0, :set_pixel JAL r31, r0, :set_pixel
CP r37, r35 CP r37, r1
ADDI64 r37, r37, 1d CP r38, r35
CP r35, r37 ADDI64 r38, r38, 1d
CP r35, r38
JMP :1 JMP :1
0: CP r2, r35 0: CP r2, r35
CP r3, r36 CP r3, r36
CP r4, r33 CP r4, r33
JAL r31, r0, :set_pixel JAL r31, r0, :set_pixel
CP r38, r1
LI64 r35, 0d LI64 r35, 0d
CP r37, r36 CP r39, r36
ADDI64 r37, r37, 1d ADDI64 r39, r39, 1d
CP r36, r37 CP r36, r39
1: CP r37, r36 1: CP r39, r36
CP r38, r33 CP r40, r33
CMPS r37, r37, r38 CMPS r39, r39, r40
CMPUI r37, r37, 0d CMPUI r39, r39, 0d
NOT r37, r37 NOT r39, r39
JEQ r37, r0, :2 JEQ r39, r0, :2
JMP :3 JMP :3
2: JMP :4 2: JMP :4
3: LI64 r1, 0d 3: LI64 r1, 0d
LD r31, r254, 0a, 64h LD r31, r254, 0a, 80h
ADDI64 r254, r254, 64d ADDI64 r254, r254, 80d
JALA r0, r31, 0a JALA r0, r31, 0a
set_pixel: set_pixel:
ADDI64 r254, r254, -32d ADDI64 r254, r254, -32d
@ -67,6 +69,6 @@ x86_fb_ptr:
LD r31, r254, 0a, 8h LD r31, r254, 0a, 8h
ADDI64 r254, r254, 8d ADDI64 r254, r254, 8d
JALA r0, r31, 0a JALA r0, r31, 0a
code size: 505 code size: 511
ret: 0 ret: 0
status: Ok(()) status: Ok(())

View file

@ -1,11 +1,16 @@
main: main:
ADDI64 r254, r254, -16d ADDI64 r254, r254, -32d
ST r31, r254, 0a, 16h ST r31, r254, 0a, 32h
LRA r32, r0, :complex_global_var
LRA r33, r0, :complex_global_var
LD r34, r33, 0a, 8h
ADDI64 r34, r34, 5d
ST r34, r32, 0a, 8h
LRA r32, r0, :complex_global_var LRA r32, r0, :complex_global_var
LD r1, r32, 0a, 8h LD r1, r32, 0a, 8h
LD r31, r254, 0a, 16h LD r31, r254, 0a, 32h
ADDI64 r254, r254, 16d ADDI64 r254, r254, 32d
JALA r0, r31, 0a JALA r0, r31, 0a
code size: 267 code size: 318
ret: 50 ret: 55
status: Ok(()) status: Ok(())

View file

@ -27,12 +27,11 @@ fib:
CP r35, r32 CP r35, r32
ADDI64 r35, r35, -1d ADDI64 r35, r35, -1d
CP r32, r35 CP r32, r35
LI64 r35, 0d
JMP :2 JMP :2
1: CP r1, r33 1: CP r1, r33
LD r31, r254, 0a, 48h LD r31, r254, 0a, 48h
ADDI64 r254, r254, 48d ADDI64 r254, r254, 48d
JALA r0, r31, 0a JALA r0, r31, 0a
code size: 258 code size: 248
ret: 55 ret: 55
status: Ok(()) status: Ok(())

View file

@ -1,6 +1,6 @@
main: main:
ADDI64 r254, r254, -104d ADDI64 r254, r254, -96d
ST r31, r254, 0a, 104h ST r31, r254, 0a, 96h
JAL r31, r0, :check_platform JAL r31, r0, :check_platform
LI64 r32, 0d LI64 r32, 0d
CP r33, r32 CP r33, r32
@ -12,25 +12,30 @@ main:
CP r39, r37 CP r39, r37
4: ADDI64 r40, r35, 1d 4: ADDI64 r40, r35, 1d
JGTS r33, r40, :0 JGTS r33, r40, :0
CP r2, r33
CP r3, r33
CP r4, r37
JAL r31, r0, :set_pixel JAL r31, r0, :set_pixel
CP r41, r4 CP r41, r37
ADDI64 r42, r3, 1d ADDI64 r33, r33, 1d
CP r43, r3 CP r42, r33
JMP :1 JMP :1
0: JAL r31, r0, :set_pixel 0: CP r2, r33
CP r41, r4 CP r3, r38
CP r42, r32 CP r4, r39
ADDI64 r43, r3, 1d JAL r31, r0, :set_pixel
1: JNE r43, r41, :2 CP r41, r39
CP r33, r32
ADDI64 r42, r38, 1d
1: JNE r42, r41, :2
JMP :3 JMP :3
2: CP r2, r42 2: CP r35, r34
CP r35, r34 CP r37, r36
CP r4, r36 CP r38, r42
CP r3, r43 CP r39, r41
CP r4, r41
JMP :4 JMP :4
3: LD r31, r254, 0a, 104h 3: LD r31, r254, 0a, 96h
ADDI64 r254, r254, 104d ADDI64 r254, r254, 96d
JALA r0, r31, 0a JALA r0, r31, 0a
set_pixel: set_pixel:
ADDI64 r254, r254, -8d ADDI64 r254, r254, -8d
@ -53,6 +58,7 @@ x86_fb_ptr:
LD r31, r254, 0a, 8h LD r31, r254, 0a, 8h
ADDI64 r254, r254, 8d ADDI64 r254, r254, 8d
JALA r0, r31, 0a JALA r0, r31, 0a
code size: 422 timed out
code size: 437
ret: 0 ret: 0
status: Ok(()) status: Ok(())

View file

@ -1,14 +1,16 @@
main: main:
ADDI64 r254, r254, -16d ADDI64 r254, r254, -24d
ST r31, r254, 0a, 16h ST r31, r254, 0a, 24h
LI64 r2, 10d LI64 r32, 10d
CP r2, r32
JAL r31, r0, :add_one JAL r31, r0, :add_one
CP r32, r1 CP r32, r1
LI64 r2, 20d LI64 r33, 20d
CP r2, r33
JAL r31, r0, :add_two JAL r31, r0, :add_two
ADD64 r1, r1, r32 ADD64 r1, r1, r32
LD r31, r254, 0a, 16h LD r31, r254, 0a, 24h
ADDI64 r254, r254, 16d ADDI64 r254, r254, 24d
JALA r0, r31, 0a JALA r0, r31, 0a
add_two: add_two:
ADDI64 r254, r254, -8d ADDI64 r254, r254, -8d
@ -26,6 +28,6 @@ add_one:
LD r31, r254, 0a, 8h LD r31, r254, 0a, 8h
ADDI64 r254, r254, 8d ADDI64 r254, r254, 8d
JALA r0, r31, 0a JALA r0, r31, 0a
code size: 254 code size: 260
ret: 33 ret: 33
status: Ok(()) status: Ok(())

View file

@ -1,28 +1,31 @@
main: main:
ADDI64 r254, r254, -8d ADDI64 r254, r254, -16d
ST r31, r254, 0a, 8h ST r31, r254, 0a, 16h
LI64 r2, 10d LI64 r32, 10d
CP r2, r32
JAL r31, r0, :fib JAL r31, r0, :fib
LD r31, r254, 0a, 8h LD r31, r254, 0a, 16h
ADDI64 r254, r254, 8d ADDI64 r254, r254, 16d
JALA r0, r31, 0a JALA r0, r31, 0a
fib: fib:
ADDI64 r254, r254, -32d ADDI64 r254, r254, -40d
ST r31, r254, 0a, 32h ST r31, r254, 0a, 40h
CP r32, r2 CP r32, r2
LI64 r33, 2d LI64 r33, 2d
JGTS r32, r33, :0 JGTS r32, r33, :0
LI64 r1, 1d LI64 r1, 1d
JMP :1 JMP :1
0: ADDI64 r2, r32, -1d 0: ADDI64 r34, r32, -1d
CP r2, r34
JAL r31, r0, :fib JAL r31, r0, :fib
CP r34, r1 CP r34, r1
SUB64 r2, r32, r33 SUB64 r35, r32, r33
CP r2, r35
JAL r31, r0, :fib JAL r31, r0, :fib
ADD64 r1, r1, r34 ADD64 r1, r34, r1
1: LD r31, r254, 0a, 32h 1: LD r31, r254, 0a, 40h
ADDI64 r254, r254, 32d ADDI64 r254, r254, 40d
JALA r0, r31, 0a JALA r0, r31, 0a
code size: 212 code size: 221
ret: 55 ret: 55
status: Ok(()) status: Ok(())

View file

@ -1,10 +1,11 @@
main: main:
ADDI64 r254, r254, -8d ADDI64 r254, r254, -16d
ST r31, r254, 0a, 8h ST r31, r254, 0a, 16h
LI64 r2, 10d LI64 r32, 10d
CP r2, r32
JAL r31, r0, :fib JAL r31, r0, :fib
LD r31, r254, 0a, 8h LD r31, r254, 0a, 16h
ADDI64 r254, r254, 8d ADDI64 r254, r254, 16d
JALA r0, r31, 0a JALA r0, r31, 0a
fib: fib:
ADDI64 r254, r254, -56d ADDI64 r254, r254, -56d
@ -25,6 +26,6 @@ fib:
1: LD r31, r254, 0a, 56h 1: LD r31, r254, 0a, 56h
ADDI64 r254, r254, 56d ADDI64 r254, r254, 56d
JALA r0, r31, 0a JALA r0, r31, 0a
code size: 204 code size: 207
ret: 55 ret: 55
status: Ok(()) status: Ok(())