From bb41da484f8c0112ba2d4781ac9533d2bba2d306 Mon Sep 17 00:00:00 2001 From: mlokr Date: Sun, 8 Sep 2024 12:00:07 +0200 Subject: [PATCH] adding global mutatuon to the test --- hblang/README.md | 1 + hblang/src/codegen.rs | 2 +- hblang/src/son.rs | 302 ++++++++++++------ hblang/tests/codegen_tests_fb_driver.txt | 36 ++- .../tests/codegen_tests_global_variables.txt | 17 +- hblang/tests/codegen_tests_loops.txt | 3 +- hblang/tests/son_tests_fb_driver.txt | 42 +-- hblang/tests/son_tests_functions.txt | 16 +- hblang/tests/son_tests_if_statements.txt | 29 +- hblang/tests/son_tests_loops.txt | 13 +- 10 files changed, 287 insertions(+), 174 deletions(-) diff --git a/hblang/README.md b/hblang/README.md index a4d1b6ec4..29447a11c 100644 --- a/hblang/README.md +++ b/hblang/README.md @@ -217,6 +217,7 @@ fib := fn(n: int): int { } main := fn(): int { + complex_global_var += 5 return complex_global_var } ``` diff --git a/hblang/src/codegen.rs b/hblang/src/codegen.rs index 5ca66a52d..87af96feb 100644 --- a/hblang/src/codegen.rs +++ b/hblang/src/codegen.rs @@ -2106,7 +2106,7 @@ impl Codegen { } E::BinOp { left, op, right } if op != T::Decl => 'ops: { 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() })?; diff --git a/hblang/src/son.rs b/hblang/src/son.rs index 563b617ca..18c68b71d 100644 --- a/hblang/src/son.rs +++ b/hblang/src/son.rs @@ -13,16 +13,17 @@ use { HashMap, }, core::fmt, + hbvm::mem::softpaging::lookup, std::{ cell::RefCell, collections::{hash_map, BTreeMap}, + default, fmt::Display, hash::{Hash as _, Hasher}, - intrinsics::unreachable, mem, ops::{self, Range}, 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(&self, state: &mut H) { + state.write_u64(self.hash); + } +} + struct Nodes { values: Vec>, visited: BitSet, free: u32, - lookup: HashMap, + lookup: std::collections::hash_map::HashMap< + LookupEntry, + (), + std::hash::BuildHasherDefault, + >, } impl Default for Nodes { @@ -504,7 +537,7 @@ impl Nodes { let node = Node { inputs: inps.into(), - kind: kind.clone(), + kind, color: 0, depth: u32::MAX, lock_rc: 0, @@ -512,15 +545,17 @@ impl Nodes { outputs: vec![], }; - let mut hasher = crate::FnvHasher::default(); - node.key().hash(&mut hasher); + let mut lookup_meta = None; + 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 { - hash_map::RawEntryMut::Occupied(mut o) => return *o.get_key_value().0, - hash_map::RawEntryMut::Vacant(v) => v, - }; + lookup_meta = Some((entry, hash)); + } if self.free == u32::MAX { self.free = self.values.len() as _; @@ -532,40 +567,48 @@ impl Nodes { debug_assert_ne!(d, 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(); - *entry.insert(free, ()).0 + + if let Some((entry, hash)) = lookup_meta { + entry.insert(LookupEntry { nid: free, hash }, ()); + } + free } fn find_node<'a>( - lookup: &'a mut HashMap, + lookup: &'a mut std::collections::hash_map::HashMap< + LookupEntry, + (), + std::hash::BuildHasherDefault, + >, values: &[Result], node: &Node, - ) -> (hash_map::RawEntryMut<'a, u32, (), std::hash::BuildHasherDefault>, u64) - { + ) -> ( + hash_map::RawEntryMut<'a, LookupEntry, (), std::hash::BuildHasherDefault>, + u64, + ) { let mut hasher = crate::FnvHasher::default(); node.key().hash(&mut hasher); let hash = hasher.finish(); - - ( - lookup - .raw_entry_mut() - .from_hash(hash, |&n| values[n as usize].as_ref().unwrap().key() == node.key()), - hash, - ) + let entry = lookup + .raw_entry_mut() + .from_hash(hash, |n| values[n.nid as usize].as_ref().unwrap().key() == node.key()); + (entry, hash) } fn remove_node_lookup(&mut self, target: Nid) { - match Self::find_node( - &mut self.lookup, - &self.values, - &self.values[target as usize].as_ref().unwrap(), - ) - .0 - { - hash_map::RawEntryMut::Occupied(o) => o.remove(), - hash_map::RawEntryMut::Vacant(_) => unreachable!(), - }; + if self[target].kind != Kind::Phi || self[target].inputs[2] != 0 { + match Self::find_node( + &mut self.lookup, + &self.values, + self.values[target as usize].as_ref().unwrap(), + ) + .0 + { + hash_map::RawEntryMut::Occupied(o) => o.remove(), + hash_map::RawEntryMut::Vacant(_) => unreachable!(), + }; + } } fn new_node(&mut self, ty: impl Into, kind: Kind, inps: impl Into>) -> Nid { @@ -619,12 +662,20 @@ impl Nodes { Kind::Call { .. } => {} Kind::If => return self.peephole_if(target), Kind::Region => {} - Kind::Phi => {} + Kind::Phi => return self.peephole_phi(target), Kind::Loop => {} } None } + fn peephole_phi(&mut self, target: Nid) -> Option { + if self[target].inputs[1] == self[target].inputs[2] { + return Some(self[target].inputs[1]); + } + + None + } + fn peephole_if(&mut self, target: Nid) -> Option { let cond = self[target].inputs[1]; if let Kind::ConstInt { value } = self[cond].kind { @@ -720,7 +771,7 @@ impl Nodes { } 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 @@ -731,11 +782,13 @@ impl Nodes { } fn replace(&mut self, target: Nid, with: Nid) { + let mut back_press = 0; 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 rpl = self.modify_input(out, index, with); - self[with].outputs.push(rpl); + let prev_len = self[target].outputs.len(); + self.modify_input(out, index, with); + back_press += (self[target].outputs.len() != prev_len) as usize; } self.remove(target); @@ -750,17 +803,19 @@ impl Nodes { let (entry, hash) = Self::find_node( &mut self.lookup, &self.values, - &self.values[target as usize].as_ref().unwrap(), + self.values[target as usize].as_ref().unwrap(), ); match entry { 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.replace(target, rpl); rpl } 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(); self[prev].outputs.swap_remove(index); self[with].outputs.push(target); @@ -913,8 +968,28 @@ impl Nodes { failed = true; } + let mut allowed_cfgs = 1 + (node.kind == Kind::If) as usize; 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] { Ok(other) => other, Err(_) => { @@ -923,10 +998,11 @@ impl Nodes { continue; } }; - occurs += self[o].inputs.iter().filter(|&&el| el == i).count(); - if occurs == 0 { + let occurs = self[o].inputs.iter().filter(|&&el| el == i).count(); + let self_occurs = self[i].outputs.iter().filter(|&&el| el == o).count(); + if occurs != self_occurs { log::err!( - "the edge is not bidirectional: {i} {:?} {o} {:?}", + "the edge is not bidirectional: {i} {:?} {self_occurs} {o} {:?} {occurs}", node.kind, other.kind ); @@ -961,11 +1037,19 @@ impl Nodes { return true; } } - return false; + false } self.visited.clear(self.values.len()); 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 for Nodes { @@ -1625,16 +1709,23 @@ impl Codegen { }; 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 inps = [loob.node, loob.scope[index].value, loob.scope[index].value]; - self.ci.nodes.unlock(inps[1]); - let ty = self.ci.nodes[inps[1]].ty; - // TODO: dont apply peepholes here - let phy = self.ci.nodes.new_node(ty, Kind::Phi, inps); - self.ci.nodes[phy].lock_rc += 2; - self.ci.vars[index].value = phy; - loob.scope[index].value = phy; + if self.ci.nodes[loob.scope[index].value].kind != Kind::Phi + || self.ci.nodes[loob.scope[index].value].inputs[0] != loob.node + { + self.ci.nodes.unlock(self.ci.vars[index].value); + let inps = [loob.node, loob.scope[index].value, 0]; + self.ci.nodes.unlock(inps[1]); + let ty = self.ci.nodes[inps[1]].ty; + 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); @@ -1751,8 +1842,12 @@ impl Codegen { let ty = self.ci.nodes[else_var.value].ty; debug_assert_eq!( - ty, self.ci.nodes[then_var.value].ty, - "TODO: typecheck properly" + ty, + 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]; @@ -1826,33 +1921,35 @@ impl Codegen { self.ci.nodes.check_scope_integrity(&self.ci.vars); self.ci.nodes.check_scope_integrity(&break_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) { - 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); - let phy = self.ci.nodes.modify_input(scope_var.value, 2, loop_var.value); - self.ci.nodes.unlock_remove(dest_var.value); - dest_var.value = phy; + + if loop_var.value != 0 { + 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); @@ -2198,7 +2295,7 @@ impl Codegen { fn color_control(&mut self, mut ctrl: Nid) -> Option { for _ in 0..30 { - match self.ci.nodes[ctrl].kind.clone() { + match self.ci.nodes[ctrl].kind { Kind::Start => unreachable!(), Kind::End => unreachable!(), Kind::Return => { @@ -2250,7 +2347,7 @@ impl Codegen { (None, Some(n)) | (Some(n), None) => n, (Some(l), Some(r)) if l == r => l, (Some(left), Some(right)) => { - todo!() + todo!("{:?} {:?}", self.ci.nodes[left], self.ci.nodes[right]); } }; @@ -2258,14 +2355,12 @@ impl Codegen { return Some(dest); } - debug_assert!(left_unreachable.is_none() || right_unreachable.is_none()); - debug_assert_eq!(self.ci.nodes[dest].kind, Kind::Region); for i in 0..self.ci.nodes[dest].outputs.len() { let o = self.ci.nodes[dest].outputs[i]; 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; } } @@ -2284,15 +2379,15 @@ impl Codegen { } for i in 0..self.ci.nodes[ctrl].outputs.len() { - let maybe_phy = self.ci.nodes[ctrl].outputs[i]; - let Node { kind: Kind::Phi, ref inputs, .. } = self.ci.nodes[maybe_phy] + let maybe_phi = self.ci.nodes[ctrl].outputs[i]; + let Node { kind: Kind::Phi, ref inputs, .. } = self.ci.nodes[maybe_phi] else { continue; }; _ = self.color_expr_consume(inputs[1]); - self.ci.nodes[maybe_phy].depth = self.ci.loop_depth; - self.ci.set_next_color(maybe_phy); + self.ci.nodes[maybe_phi].depth = self.ci.loop_depth; + self.ci.set_next_color(maybe_phi); } 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() { - self.color_phy(self.ci.nodes[ctrl].outputs[i]); + self.color_phi(self.ci.nodes[ctrl].outputs[i]); } self.ci.loop_depth -= 1; @@ -2321,8 +2416,8 @@ impl Codegen { unreachable!() } - fn color_phy(&mut self, maybe_phy: Nid) { - let Node { kind: Kind::Phi, ref inputs, .. } = self.ci.nodes[maybe_phy] else { + fn color_phi(&mut self, maybe_phi: Nid) { + let Node { kind: Kind::Phi, ref inputs, .. } = self.ci.nodes[maybe_phi] else { return; }; let &[region, left, right] = inputs.as_slice() else { unreachable!() }; @@ -2330,14 +2425,14 @@ impl Codegen { let lcolor = self.color_expr_consume(left); let rcolor = self.color_expr_consume(right); - if self.ci.nodes[maybe_phy].color != 0 { - // loop phy + if self.ci.nodes[maybe_phi].color != 0 { + // loop phi if let Some(c) = rcolor && !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 { let color = match (lcolor, rcolor) { @@ -2348,7 +2443,7 @@ impl Codegen { 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 { for _ in 0..30 { - match self.ci.nodes[ctrl].kind.clone() { + match self.ci.nodes[ctrl].kind { Kind::Start => unreachable!(), Kind::End => unreachable!(), Kind::Return => { @@ -2439,14 +2534,14 @@ impl Codegen { let mut parama = self.tys.parama(ret); for i in 1..self.ci.nodes[ctrl].inputs.len() { 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, 1..=8 => Loc { reg: parama.next() }, s => todo!("{s}"), }; - self.ci.regs.mark_leaked(node_loc!(self, arg).reg); 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); @@ -2770,8 +2865,7 @@ impl Codegen { if color.rc == 0 { if color.depth != self.ci.loop_depth { self.ci.delayed_frees.push(node.color); - } else { - debug_assert_ne!(color.loc, Loc::default(), "{:?}", node); + } else if color.loc != Loc::default() { self.ci.regs.free(color.loc.reg); } } diff --git a/hblang/tests/codegen_tests_fb_driver.txt b/hblang/tests/codegen_tests_fb_driver.txt index bc44c2c86..51591dbdf 100644 --- a/hblang/tests/codegen_tests_fb_driver.txt +++ b/hblang/tests/codegen_tests_fb_driver.txt @@ -1,6 +1,6 @@ main: - ADDI64 r254, r254, -64d - ST r31, r254, 0a, 64h + ADDI64 r254, r254, -80d + ST r31, r254, 0a, 80h JAL r31, r0, :check_platform CP r32, r1 LI64 r33, 100d @@ -17,29 +17,31 @@ main: CP r3, r36 CP r4, r33 JAL r31, r0, :set_pixel - CP r37, r35 - ADDI64 r37, r37, 1d - CP r35, r37 + CP r37, r1 + CP r38, r35 + ADDI64 r38, r38, 1d + CP r35, r38 JMP :1 0: CP r2, r35 CP r3, r36 CP r4, r33 JAL r31, r0, :set_pixel + CP r38, r1 LI64 r35, 0d - CP r37, r36 - ADDI64 r37, r37, 1d - CP r36, r37 - 1: CP r37, r36 - CP r38, r33 - CMPS r37, r37, r38 - CMPUI r37, r37, 0d - NOT r37, r37 - JEQ r37, r0, :2 + CP r39, r36 + ADDI64 r39, r39, 1d + CP r36, r39 + 1: CP r39, r36 + CP r40, r33 + CMPS r39, r39, r40 + CMPUI r39, r39, 0d + NOT r39, r39 + JEQ r39, r0, :2 JMP :3 2: JMP :4 3: LI64 r1, 0d - LD r31, r254, 0a, 64h - ADDI64 r254, r254, 64d + LD r31, r254, 0a, 80h + ADDI64 r254, r254, 80d JALA r0, r31, 0a set_pixel: ADDI64 r254, r254, -32d @@ -67,6 +69,6 @@ x86_fb_ptr: LD r31, r254, 0a, 8h ADDI64 r254, r254, 8d JALA r0, r31, 0a -code size: 505 +code size: 511 ret: 0 status: Ok(()) diff --git a/hblang/tests/codegen_tests_global_variables.txt b/hblang/tests/codegen_tests_global_variables.txt index 5a7e35cc3..34aee7e86 100644 --- a/hblang/tests/codegen_tests_global_variables.txt +++ b/hblang/tests/codegen_tests_global_variables.txt @@ -1,11 +1,16 @@ main: - ADDI64 r254, r254, -16d - ST r31, r254, 0a, 16h + ADDI64 r254, r254, -32d + 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 LD r1, r32, 0a, 8h - LD r31, r254, 0a, 16h - ADDI64 r254, r254, 16d + LD r31, r254, 0a, 32h + ADDI64 r254, r254, 32d JALA r0, r31, 0a -code size: 267 -ret: 50 +code size: 318 +ret: 55 status: Ok(()) diff --git a/hblang/tests/codegen_tests_loops.txt b/hblang/tests/codegen_tests_loops.txt index ac8523d43..c2c67d476 100644 --- a/hblang/tests/codegen_tests_loops.txt +++ b/hblang/tests/codegen_tests_loops.txt @@ -27,12 +27,11 @@ fib: CP r35, r32 ADDI64 r35, r35, -1d CP r32, r35 - LI64 r35, 0d JMP :2 1: CP r1, r33 LD r31, r254, 0a, 48h ADDI64 r254, r254, 48d JALA r0, r31, 0a -code size: 258 +code size: 248 ret: 55 status: Ok(()) diff --git a/hblang/tests/son_tests_fb_driver.txt b/hblang/tests/son_tests_fb_driver.txt index b74389438..9a293421f 100644 --- a/hblang/tests/son_tests_fb_driver.txt +++ b/hblang/tests/son_tests_fb_driver.txt @@ -1,6 +1,6 @@ main: - ADDI64 r254, r254, -104d - ST r31, r254, 0a, 104h + ADDI64 r254, r254, -96d + ST r31, r254, 0a, 96h JAL r31, r0, :check_platform LI64 r32, 0d CP r33, r32 @@ -12,25 +12,30 @@ main: CP r39, r37 4: ADDI64 r40, r35, 1d JGTS r33, r40, :0 + CP r2, r33 + CP r3, r33 + CP r4, r37 JAL r31, r0, :set_pixel - CP r41, r4 - ADDI64 r42, r3, 1d - CP r43, r3 + CP r41, r37 + ADDI64 r33, r33, 1d + CP r42, r33 JMP :1 - 0: JAL r31, r0, :set_pixel - CP r41, r4 - CP r42, r32 - ADDI64 r43, r3, 1d - 1: JNE r43, r41, :2 + 0: CP r2, r33 + CP r3, r38 + CP r4, r39 + JAL r31, r0, :set_pixel + CP r41, r39 + CP r33, r32 + ADDI64 r42, r38, 1d + 1: JNE r42, r41, :2 JMP :3 - 2: CP r2, r42 - CP r35, r34 - CP r4, r36 - CP r3, r43 - CP r4, r41 + 2: CP r35, r34 + CP r37, r36 + CP r38, r42 + CP r39, r41 JMP :4 - 3: LD r31, r254, 0a, 104h - ADDI64 r254, r254, 104d + 3: LD r31, r254, 0a, 96h + ADDI64 r254, r254, 96d JALA r0, r31, 0a set_pixel: ADDI64 r254, r254, -8d @@ -53,6 +58,7 @@ x86_fb_ptr: LD r31, r254, 0a, 8h ADDI64 r254, r254, 8d JALA r0, r31, 0a -code size: 422 +timed out +code size: 437 ret: 0 status: Ok(()) diff --git a/hblang/tests/son_tests_functions.txt b/hblang/tests/son_tests_functions.txt index 4df4a4926..4dec00959 100644 --- a/hblang/tests/son_tests_functions.txt +++ b/hblang/tests/son_tests_functions.txt @@ -1,14 +1,16 @@ main: - ADDI64 r254, r254, -16d - ST r31, r254, 0a, 16h - LI64 r2, 10d + ADDI64 r254, r254, -24d + ST r31, r254, 0a, 24h + LI64 r32, 10d + CP r2, r32 JAL r31, r0, :add_one CP r32, r1 - LI64 r2, 20d + LI64 r33, 20d + CP r2, r33 JAL r31, r0, :add_two ADD64 r1, r1, r32 - LD r31, r254, 0a, 16h - ADDI64 r254, r254, 16d + LD r31, r254, 0a, 24h + ADDI64 r254, r254, 24d JALA r0, r31, 0a add_two: ADDI64 r254, r254, -8d @@ -26,6 +28,6 @@ add_one: LD r31, r254, 0a, 8h ADDI64 r254, r254, 8d JALA r0, r31, 0a -code size: 254 +code size: 260 ret: 33 status: Ok(()) diff --git a/hblang/tests/son_tests_if_statements.txt b/hblang/tests/son_tests_if_statements.txt index 2100773b0..b522299d2 100644 --- a/hblang/tests/son_tests_if_statements.txt +++ b/hblang/tests/son_tests_if_statements.txt @@ -1,28 +1,31 @@ main: - ADDI64 r254, r254, -8d - ST r31, r254, 0a, 8h - LI64 r2, 10d + ADDI64 r254, r254, -16d + ST r31, r254, 0a, 16h + LI64 r32, 10d + CP r2, r32 JAL r31, r0, :fib - LD r31, r254, 0a, 8h - ADDI64 r254, r254, 8d + LD r31, r254, 0a, 16h + ADDI64 r254, r254, 16d JALA r0, r31, 0a fib: - ADDI64 r254, r254, -32d - ST r31, r254, 0a, 32h + ADDI64 r254, r254, -40d + ST r31, r254, 0a, 40h CP r32, r2 LI64 r33, 2d JGTS r32, r33, :0 LI64 r1, 1d JMP :1 - 0: ADDI64 r2, r32, -1d + 0: ADDI64 r34, r32, -1d + CP r2, r34 JAL r31, r0, :fib CP r34, r1 - SUB64 r2, r32, r33 + SUB64 r35, r32, r33 + CP r2, r35 JAL r31, r0, :fib - ADD64 r1, r1, r34 - 1: LD r31, r254, 0a, 32h - ADDI64 r254, r254, 32d + ADD64 r1, r34, r1 + 1: LD r31, r254, 0a, 40h + ADDI64 r254, r254, 40d JALA r0, r31, 0a -code size: 212 +code size: 221 ret: 55 status: Ok(()) diff --git a/hblang/tests/son_tests_loops.txt b/hblang/tests/son_tests_loops.txt index ca9141075..4bc890d4c 100644 --- a/hblang/tests/son_tests_loops.txt +++ b/hblang/tests/son_tests_loops.txt @@ -1,10 +1,11 @@ main: - ADDI64 r254, r254, -8d - ST r31, r254, 0a, 8h - LI64 r2, 10d + ADDI64 r254, r254, -16d + ST r31, r254, 0a, 16h + LI64 r32, 10d + CP r2, r32 JAL r31, r0, :fib - LD r31, r254, 0a, 8h - ADDI64 r254, r254, 8d + LD r31, r254, 0a, 16h + ADDI64 r254, r254, 16d JALA r0, r31, 0a fib: ADDI64 r254, r254, -56d @@ -25,6 +26,6 @@ fib: 1: LD r31, r254, 0a, 56h ADDI64 r254, r254, 56d JALA r0, r31, 0a -code size: 204 +code size: 207 ret: 55 status: Ok(())