should work better

This commit is contained in:
Jakub Doka 2024-10-23 12:26:07 +02:00
parent f013e90936
commit 41b70bec43
No known key found for this signature in database
GPG key ID: C6E9A89936B8C143
6 changed files with 213 additions and 91 deletions

View file

@ -743,8 +743,8 @@ rect_line := fn(buffer: Buffer, pos: Point, tr: Transform, color: ColorBGRA, thi
y = pos.y y = pos.y
x = pos.x x = pos.x
loop if y == pos.y + tr.x break else { loop if y == pos.y + tr.x break else {
a := 1 + @inline(screenidx, 10) //a := 1 + @inline(screenidx, 10)
a = 1 + @inline(screenidx, 2) //a = 1 + @inline(screenidx, 2)
y += 1 y += 1
} }
t += 1 t += 1
@ -958,7 +958,15 @@ main := fn(): int {
return 6 return 6
} }
f := 0
loop { loop {
if f == 1 {
f = 0
} else {
f = 1
}
f = continue_and_state_change(0)
} }
} }

View file

@ -94,6 +94,12 @@ pub fn run_compiler(root_file: &str, options: Options, out: &mut Vec<u8>) -> std
codegen.push_embeds(parsed.embeds); codegen.push_embeds(parsed.embeds);
codegen.generate(0); codegen.generate(0);
if !codegen.errors.borrow().is_empty() {
log::error!("{}", codegen.errors.borrow());
return Err(std::io::Error::other("compilation faoled"));
}
if options.dump_asm { if options.dump_asm {
codegen codegen
.disasm(unsafe { std::mem::transmute::<&mut Vec<u8>, &mut String>(out) }) .disasm(unsafe { std::mem::transmute::<&mut Vec<u8>, &mut String>(out) })

View file

@ -3,7 +3,7 @@ fn main() -> std::io::Result<()> {
use std::io::Write; use std::io::Write;
log::set_logger(&hblang::Logger).unwrap(); log::set_logger(&hblang::Logger).unwrap();
log::set_max_level(log::LevelFilter::Error); log::set_max_level(log::LevelFilter::Info);
let args = std::env::args().collect::<Vec<_>>(); let args = std::env::args().collect::<Vec<_>>();
let args = args.iter().map(String::as_str).collect::<Vec<_>>(); let args = args.iter().map(String::as_str).collect::<Vec<_>>();

View file

@ -27,7 +27,7 @@ use {
hashbrown::hash_map, hashbrown::hash_map,
hbbytecode::DisasmError, hbbytecode::DisasmError,
regalloc2::VReg, regalloc2::VReg,
std::{borrow::ToOwned, panic}, std::borrow::ToOwned,
}; };
const VOID: Nid = 0; const VOID: Nid = 0;
@ -108,39 +108,41 @@ impl Nodes {
for (i, node) in self.iter() { for (i, node) in self.iter() {
let color = match () { let color = match () {
_ if self[i].lock_rc != 0 => "red", _ if node.lock_rc == Nid::MAX => "orange",
_ if self[i].outputs.is_empty() => "purple", _ if node.lock_rc == Nid::MAX - 1 => "blue",
_ if self[i].is_mem() => "green", _ if node.lock_rc != 0 => "red",
_ if node.outputs.is_empty() => "purple",
_ if node.is_mem() => "green",
_ if self.is_cfg(i) => "yellow", _ if self.is_cfg(i) => "yellow",
_ => "white", _ => "white",
}; };
let mut dest = i; let dest = i;
let mut index_override = None; //let mut index_override = None;
if !matches!(node.kind, Kind::Then | Kind::Else) { //if !matches!(node.kind, Kind::Then | Kind::Else) {
if node.ty != ty::Id::VOID { if node.ty != ty::Id::VOID {
writeln!( writeln!(
out, out,
" node{i}[label=\"{} {}\" color={color}]", " node{i}[label=\"{i} {} {}\" color={color}]",
node.kind, node.kind,
ty::Display::new(tys, files, node.ty) ty::Display::new(tys, files, node.ty)
)?; )?;
} else {
writeln!(out, " node{i}[label=\"{}\" color={color}]", node.kind,)?;
}
} else { } else {
dest = node.inputs[0]; writeln!(out, " node{i}[label=\"{i} {}\" color={color}]", node.kind,)?;
index_override = if node.kind == Kind::Then { Some(0) } else { Some(1) };
} }
//} else {
// dest = node.inputs[0];
if node.kind == Kind::If { // index_override = if node.kind == Kind::Then { Some(0) } else { Some(1) };
continue; //}
}
//if node.kind == Kind::If {
// continue;
//}
for (j, &o) in node.outputs.iter().enumerate() { for (j, &o) in node.outputs.iter().enumerate() {
let j = index_override.unwrap_or(j); //let j = index_override.unwrap_or(j);
let color = if self.is_cfg(i) && self.is_cfg(o) { "red" } else { "lightgray" }; let color = if self.is_cfg(i) && self.is_cfg(o) { "red" } else { "lightgray" };
let index = self[o].inputs.iter().position(|&inp| i == inp).unwrap(); let index = self[o].inputs.iter().position(|&inp| i == inp).unwrap();
let style = if index == 0 && !self.is_cfg(o) { "style=dotted" } else { "" }; let style = if index == 0 && !self.is_cfg(o) { "style=dotted" } else { "" };
@ -205,6 +207,26 @@ impl Nodes {
let node = let node =
Node { ralloc_backref: u16::MAX, inputs: inps.into(), kind, ty, ..Default::default() }; Node { ralloc_backref: u16::MAX, inputs: inps.into(), kind, ty, ..Default::default() };
if node.kind == Kind::Phi && node.ty != ty::Id::VOID {
debug_assert_ne!(
self[node.inputs[1]].ty,
ty::Id::VOID,
"{:?} {:?}",
self[node.inputs[1]],
node.ty.expand(),
);
if self[node.inputs[0]].kind != Kind::Loop {
debug_assert_ne!(
self[node.inputs[2]].ty,
ty::Id::VOID,
"{:?} {:?}",
self[node.inputs[2]],
node.ty.expand(),
);
}
}
let mut lookup_meta = None; let mut lookup_meta = None;
if !node.is_not_gvnd() { if !node.is_not_gvnd() {
let (raw_entry, hash) = self.lookup.entry(node.key(), &self.values); let (raw_entry, hash) = self.lookup.entry(node.key(), &self.values);
@ -857,6 +879,7 @@ impl Nodes {
self.values.iter_mut().flat_map(Result::as_mut) self.values.iter_mut().flat_map(Result::as_mut)
} }
#[allow(dead_code)]
fn eliminate_stack_temporaries(&mut self) { fn eliminate_stack_temporaries(&mut self) {
if !cfg!(debug_assertions) { if !cfg!(debug_assertions) {
return; return;
@ -1192,7 +1215,7 @@ mod var {
impl Scope { impl Scope {
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut Variable> { pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut Variable> {
self.vars.iter_mut().chain(core::iter::once(&mut self.store)) core::iter::once(&mut self.store).chain(self.vars.iter_mut())
} }
pub fn dup(&self, nodes: &mut Nodes) -> Self { pub fn dup(&self, nodes: &mut Nodes) -> Self {
@ -1216,8 +1239,9 @@ struct ItemCtx {
file: FileId, file: FileId,
ret: Option<ty::Id>, ret: Option<ty::Id>,
task_base: usize, task_base: usize,
inline_var_base: usize,
inline_depth: u16, inline_depth: u16,
inline_ret: Option<(Value, Nid)>, inline_ret: Option<(Value, Nid, Scope)>,
nodes: Nodes, nodes: Nodes,
ctrl: Nid, ctrl: Nid,
call_count: u16, call_count: u16,
@ -1290,6 +1314,10 @@ impl ItemCtx {
}; };
regalloc2::run_with_ctx(&fuc, &ralloc.env, &options, &mut ralloc.ctx).unwrap_or_else( regalloc2::run_with_ctx(&fuc, &ralloc.env, &options, &mut ralloc.ctx).unwrap_or_else(
|err| { |err| {
if let regalloc2::RegAllocError::SSA(vreg, inst) = err {
fuc.nodes[vreg.vreg() as Nid].lock_rc = Nid::MAX;
fuc.nodes[fuc.instrs[inst.index()].nid].lock_rc = Nid::MAX - 1;
}
fuc.nodes.graphviz_in_browser(tys, files); fuc.nodes.graphviz_in_browser(tys, files);
panic!("{err}") panic!("{err}")
}, },
@ -1794,7 +1822,7 @@ pub struct Codegen<'a> {
#[expect(dead_code)] #[expect(dead_code)]
ralloc: Regalloc, ralloc: Regalloc,
ct: Comptime, ct: Comptime,
errors: RefCell<String>, pub errors: RefCell<String>,
} }
impl TypeParser for Codegen<'_> { impl TypeParser for Codegen<'_> {
@ -2018,8 +2046,16 @@ impl<'a> Codegen<'a> {
fn load_mem(&mut self, region: Nid, ty: ty::Id) -> Nid { fn load_mem(&mut self, region: Nid, ty: ty::Id) -> Nid {
debug_assert_ne!(region, VOID); debug_assert_ne!(region, VOID);
debug_assert_ne!({ self.ci.nodes[region].ty }, ty::Id::VOID, "{:?}", {
self.ci.nodes[region].lock_rc = Nid::MAX;
self.ci.nodes.graphviz_in_browser(&self.tys, self.files);
});
debug_assert!( debug_assert!(
self.ci.nodes[region].kind != Kind::Load || self.ci.nodes[region].ty.is_pointer() self.ci.nodes[region].kind != Kind::Load || self.ci.nodes[region].ty.is_pointer(),
"{:?} {} {}",
self.ci.nodes.graphviz_in_browser(&self.tys, self.files),
self.cfile().path,
self.ty_display(self.ci.nodes[region].ty)
); );
debug_assert!(self.ci.nodes[region].kind != Kind::Stre); debug_assert!(self.ci.nodes[region].kind != Kind::Stre);
let mut vc = Vc::from([VOID, region]); let mut vc = Vc::from([VOID, region]);
@ -2095,7 +2131,7 @@ impl<'a> Codegen<'a> {
if let Some(index) = self.ci.scope.vars.iter().rposition(|v| v.id == id) => if let Some(index) = self.ci.scope.vars.iter().rposition(|v| v.id == id) =>
{ {
let var = &mut self.ci.scope.vars[index]; let var = &mut self.ci.scope.vars[index];
self.ci.nodes.load_loop_var(index, var, &mut self.ci.loops); self.ci.nodes.load_loop_var(index + 1, var, &mut self.ci.loops);
Some(Value::var(index).ty(var.ty)) Some(Value::var(index).ty(var.ty))
} }
@ -2108,10 +2144,7 @@ impl<'a> Codegen<'a> {
let value = self.ci.nodes.new_node(gl.ty, Kind::Global { global }, [VOID]); let value = self.ci.nodes.new_node(gl.ty, Kind::Global { global }, [VOID]);
Some(Value::ptr(value).ty(gl.ty)) Some(Value::ptr(value).ty(gl.ty))
} }
_ => self.report_unhandled_ast( _ => Some(Value::new(Nid::MAX).ty(decl)),
expr,
format_args!("identifier evaluated to '{}'", self.ty_display(decl)),
),
} }
} }
Expr::Comment { .. } => Some(Value::VOID), Expr::Comment { .. } => Some(Value::VOID),
@ -2152,19 +2185,31 @@ impl<'a> Codegen<'a> {
self.ci.nodes[NEVER].inputs.push(self.ci.ctrl); self.ci.nodes[NEVER].inputs.push(self.ci.ctrl);
self.ci.nodes[self.ci.ctrl].outputs.push(NEVER); self.ci.nodes[self.ci.ctrl].outputs.push(NEVER);
} else if let Some((pv, ctrl)) = &mut self.ci.inline_ret { } else if let Some((pv, ctrl, scope)) = &mut self.ci.inline_ret {
self.ci.nodes.unlock(*ctrl); self.ci.nodes.unlock(*ctrl);
*ctrl = *ctrl =
self.ci.nodes.new_node(ty::Id::VOID, Kind::Region, [self.ci.ctrl, *ctrl]); self.ci.nodes.new_node(ty::Id::VOID, Kind::Region, [self.ci.ctrl, *ctrl]);
self.ci.nodes.lock(*ctrl); self.ci.nodes.lock(*ctrl);
self.ci.ctrl = *ctrl; Self::merge_scopes(
&mut self.ci.nodes,
&mut self.ci.loops,
*ctrl,
scope,
&mut self.ci.scope,
);
self.ci.nodes.unlock(pv.id); self.ci.nodes.unlock(pv.id);
pv.id = self.ci.nodes.new_node(value.ty, Kind::Phi, [*ctrl, value.id, pv.id]); pv.id = self.ci.nodes.new_node(value.ty, Kind::Phi, [*ctrl, value.id, pv.id]);
self.ci.nodes.lock(pv.id); self.ci.nodes.lock(pv.id);
self.ci.ctrl = *ctrl;
} else { } else {
self.ci.nodes.lock(value.id); self.ci.nodes.lock(value.id);
self.ci.nodes.lock(self.ci.ctrl); self.ci.nodes.lock(self.ci.ctrl);
self.ci.inline_ret = Some((value, self.ci.ctrl)); let mut scope = self.ci.scope.dup(&mut self.ci.nodes);
scope
.vars
.drain(self.ci.inline_var_base..)
.for_each(|v| v.remove(&mut self.ci.nodes));
self.ci.inline_ret = Some((value, self.ci.ctrl, scope));
} }
None None
@ -2174,6 +2219,19 @@ impl<'a> Codegen<'a> {
self.strip_var(&mut vtarget); self.strip_var(&mut vtarget);
let tty = vtarget.ty; let tty = vtarget.ty;
if let ty::Kind::Module(m) = tty.expand() {
return match self.find_type(pos, m, Err(name), self.files).expand() {
ty::Kind::Builtin(ty::NEVER) => Value::NEVER,
ty::Kind::Global(global) => {
let gl = &self.tys.ins.globals[global as usize];
let value =
self.ci.nodes.new_node(gl.ty, Kind::Global { global }, [VOID]);
Some(Value::ptr(value).ty(gl.ty))
}
v => Some(Value::new(Nid::MAX).ty(v.compress())),
};
}
let ty::Kind::Struct(s) = self.tys.base_of(tty).unwrap_or(tty).expand() else { let ty::Kind::Struct(s) = self.tys.base_of(tty).unwrap_or(tty).expand() else {
self.report( self.report(
pos, pos,
@ -2296,7 +2354,7 @@ impl<'a> Codegen<'a> {
self.ci.nodes.unlock(lhs.id); self.ci.nodes.unlock(lhs.id);
let mut rhs = rhs?; let mut rhs = rhs?;
self.strip_var(&mut rhs); self.strip_var(&mut rhs);
let ty = self.binop_ty(left.pos(), &mut rhs, &mut lhs, op); let ty = self.binop_ty(left.pos(), &mut lhs, &mut rhs, op);
let inps = [VOID, lhs.id, rhs.id]; let inps = [VOID, lhs.id, rhs.id];
Some(self.ci.nodes.new_node_lit( Some(self.ci.nodes.new_node_lit(
ty::bin_ret(ty, op), ty::bin_ret(ty, op),
@ -2463,7 +2521,7 @@ impl<'a> Codegen<'a> {
return Value::NEVER; return Value::NEVER;
}; };
let mut inps = Vc::from([self.ci.ctrl]); let mut inps = Vc::from([NEVER]);
for arg in args { for arg in args {
let value = self.expr(arg)?; let value = self.expr(arg)?;
debug_assert_ne!(self.ci.nodes[value.id].kind, Kind::Stre); debug_assert_ne!(self.ci.nodes[value.id].kind, Kind::Stre);
@ -2500,6 +2558,7 @@ impl<'a> Codegen<'a> {
}; };
let argc = args.len() as u32; let argc = args.len() as u32;
inps[0] = self.ci.ctrl;
self.ci.ctrl = self.ci.nodes.new_node(ty, Kind::Call { func: ty::ECA, argc }, inps); self.ci.ctrl = self.ci.nodes.new_node(ty, Kind::Call { func: ty::ECA, argc }, inps);
self.store_mem(VOID, VOID); self.store_mem(VOID, VOID);
@ -2538,7 +2597,7 @@ impl<'a> Codegen<'a> {
); );
} }
let mut inps = Vc::from([self.ci.ctrl]); let mut inps = Vc::from([NEVER]);
let mut tys = sig.args.range(); let mut tys = sig.args.range();
for (arg, carg) in args.iter().zip(cargs) { for (arg, carg) in args.iter().zip(cargs) {
let ty = self.tys.ins.args[tys.next().unwrap()]; let ty = self.tys.ins.args[tys.next().unwrap()];
@ -2546,6 +2605,7 @@ impl<'a> Codegen<'a> {
tys.next().unwrap(); tys.next().unwrap();
continue; continue;
} }
std::println!("{}", self.ast_display(arg));
let mut value = self.expr_ctx(arg, Ctx::default().with_ty(ty))?; let mut value = self.expr_ctx(arg, Ctx::default().with_ty(ty))?;
debug_assert_ne!(self.ci.nodes[value.id].kind, Kind::Stre); debug_assert_ne!(self.ci.nodes[value.id].kind, Kind::Stre);
self.assert_ty(arg.pos(), &mut value, ty, fa!("argument {}", carg.name)); self.assert_ty(arg.pos(), &mut value, ty, fa!("argument {}", carg.name));
@ -2583,6 +2643,7 @@ impl<'a> Codegen<'a> {
} }
}; };
inps[0] = self.ci.ctrl;
self.ci.ctrl = self.ci.nodes.new_node(sig.ret, Kind::Call { func: fu, argc }, inps); self.ci.ctrl = self.ci.nodes.new_node(sig.ret, Kind::Call { func: fu, argc }, inps);
self.store_mem(VOID, VOID); self.store_mem(VOID, VOID);
@ -2626,7 +2687,8 @@ impl<'a> Codegen<'a> {
); );
} }
let arg_base = self.ci.scope.vars.len(); let prev_var_base =
std::mem::replace(&mut self.ci.inline_var_base, self.ci.scope.vars.len());
let mut sig_args = sig.args.range(); let mut sig_args = sig.args.range();
for (arg, carg) in args.iter().zip(cargs) { for (arg, carg) in args.iter().zip(cargs) {
let ty = self.tys.ins.args[sig_args.next().unwrap()]; let ty = self.tys.ins.args[sig_args.next().unwrap()];
@ -2641,7 +2703,8 @@ impl<'a> Codegen<'a> {
continue; continue;
} }
let mut value = self.expr_ctx(arg, Ctx::default().with_ty(ty))?; let mut value = self.raw_expr_ctx(arg, Ctx::default().with_ty(ty))?;
self.strip_var(&mut value);
debug_assert_ne!(self.ci.nodes[value.id].kind, Kind::Stre); debug_assert_ne!(self.ci.nodes[value.id].kind, Kind::Stre);
debug_assert_ne!(value.id, 0); debug_assert_ne!(value.id, 0);
self.assert_ty(arg.pos(), &mut value, ty, fa!("argument {}", carg.name)); self.assert_ty(arg.pos(), &mut value, ty, fa!("argument {}", carg.name));
@ -2671,15 +2734,22 @@ impl<'a> Codegen<'a> {
self.ci.ret = prev_ret; self.ci.ret = prev_ret;
self.ci.file = prev_file; self.ci.file = prev_file;
self.ci.inline_depth -= 1; self.ci.inline_depth -= 1;
for var in self.ci.scope.vars.drain(arg_base..) { for var in self.ci.scope.vars.drain(self.ci.inline_var_base..) {
var.remove(&mut self.ci.nodes); var.remove(&mut self.ci.nodes);
} }
self.ci.inline_var_base = prev_var_base;
core::mem::replace(&mut self.ci.inline_ret, prev_inline_ret).map(|(v, ctrl)| { core::mem::replace(&mut self.ci.inline_ret, prev_inline_ret).map(
self.ci.nodes.unlock(ctrl); |(v, ctrl, scope)| {
self.ci.nodes.unlock(v.id); self.ci.nodes.unlock(ctrl);
v self.ci.nodes.unlock(v.id);
}) self.ci.scope.clear(&mut self.ci.nodes);
self.ci.scope = scope;
std::println!("{:?}", self.ci.nodes[ctrl]);
self.ci.ctrl = ctrl;
v
},
)
} }
Expr::Tupl { pos, ty, fields, .. } => { Expr::Tupl { pos, ty, fields, .. } => {
let Some(sty) = ty.map(|ty| self.ty(ty)).or(ctx.ty) else { let Some(sty) = ty.map(|ty| self.ty(ty)).or(ctx.ty) else {
@ -2912,8 +2982,27 @@ impl<'a> Codegen<'a> {
} }
if bre == Nid::MAX { if bre == Nid::MAX {
self.ci.ctrl = NEVER; for (loop_var, scope_var) in self.ci.scope.iter_mut().zip(scope.iter_mut()) {
if self.ci.nodes[scope_var.value()].is_lazy_phi(node) {
if loop_var.value() != scope_var.value() {
scope_var.set_value(
self.ci.nodes.modify_input(
scope_var.value(),
2,
loop_var.value(),
),
&mut self.ci.nodes,
);
} else {
let phi = &self.ci.nodes[scope_var.value()];
let prev = phi.inputs[1];
self.ci.nodes.replace(scope_var.value(), prev);
scope_var.set_value(prev, &mut self.ci.nodes);
}
}
}
scope.clear(&mut self.ci.nodes); scope.clear(&mut self.ci.nodes);
self.ci.ctrl = NEVER;
return None; return None;
} }
self.ci.ctrl = bre; self.ci.ctrl = bre;
@ -2954,6 +3043,7 @@ impl<'a> Codegen<'a> {
scope.clear(&mut self.ci.nodes); scope.clear(&mut self.ci.nodes);
bres.clear(&mut self.ci.nodes); bres.clear(&mut self.ci.nodes);
self.ci.scope.loads.drain(..).for_each(|l| _ = self.ci.nodes.unlock_remove(l));
self.ci.nodes.unlock(self.ci.ctrl); self.ci.nodes.unlock(self.ci.ctrl);
self.ci.nodes.unlock(node); self.ci.nodes.unlock(node);
@ -3253,6 +3343,7 @@ impl<'a> Codegen<'a> {
) { ) {
nodes.lock(ctrl); nodes.lock(ctrl);
for (i, (to_value, from_value)) in to.iter_mut().zip(from.iter_mut()).enumerate() { for (i, (to_value, from_value)) in to.iter_mut().zip(from.iter_mut()).enumerate() {
debug_assert_eq!(to_value.ty, from_value.ty);
if to_value.value() != from_value.value() { if to_value.value() != from_value.value() {
nodes.load_loop_var(i, from_value, loops); nodes.load_loop_var(i, from_value, loops);
nodes.load_loop_var(i, to_value, loops); nodes.load_loop_var(i, to_value, loops);
@ -3298,6 +3389,8 @@ impl<'a> Codegen<'a> {
self.pool.push_ci(file, Some(sig.ret), 0, &mut self.ci); self.pool.push_ci(file, Some(sig.ret), 0, &mut self.ci);
log::info!("emmiting {}", self.ast_display(expr));
let &Expr::Closure { body, args, .. } = expr else { let &Expr::Closure { body, args, .. } = expr else {
unreachable!("{}", self.ast_display(expr)) unreachable!("{}", self.ast_display(expr))
}; };
@ -3546,6 +3639,9 @@ impl<'a> Function<'a> {
"{:?}", "{:?}",
self.nodes[nid] self.nodes[nid]
); );
debug_assert_eq!(self.nodes[nid].lock_rc, 0, "{:?}", self.nodes[nid]);
debug_assert_ne!(nid, MEM);
debug_assert!(self.nodes[nid].kind != Kind::Phi || self.nodes[nid].ty != ty::Id::VOID);
regalloc2::VReg::new(nid as _, regalloc2::RegClass::Int) regalloc2::VReg::new(nid as _, regalloc2::RegClass::Int)
} }
@ -3754,13 +3850,13 @@ impl<'a> Function<'a> {
let ty = self.nodes[i].ty; let ty = self.nodes[i].ty;
match parama.next(ty, self.tys) { match parama.next(ty, self.tys) {
PLoc::None => {} PLoc::None => {}
PLoc::Reg(r, _) => { PLoc::Reg(r, _) if ty.loc(self.tys) == Loc::Reg => {
ops.push(regalloc2::Operand::reg_fixed_use( ops.push(regalloc2::Operand::reg_fixed_use(
self.rg(i), self.rg(i),
regalloc2::PReg::new(r as _, regalloc2::RegClass::Int), regalloc2::PReg::new(r as _, regalloc2::RegClass::Int),
)); ));
} }
PLoc::WideReg(..) => { PLoc::WideReg(..) | PLoc::Reg(..) => {
loop { loop {
match self.nodes[i].kind { match self.nodes[i].kind {
Kind::Stre { .. } => i = self.nodes[i].inputs[2], Kind::Stre { .. } => i = self.nodes[i].inputs[2],
@ -3774,6 +3870,7 @@ impl<'a> Function<'a> {
} }
PLoc::Ref(r, _) => { PLoc::Ref(r, _) => {
loop { loop {
std::println!("{:?} {}", self.nodes[i], i);
match self.nodes[i].kind { match self.nodes[i].kind {
Kind::Stre { .. } => i = self.nodes[i].inputs[2], Kind::Stre { .. } => i = self.nodes[i].inputs[2],
Kind::Load { .. } => i = self.nodes[i].inputs[1], Kind::Load { .. } => i = self.nodes[i].inputs[1],
@ -3860,7 +3957,11 @@ impl<'a> Function<'a> {
} }
let ops = match self.nodes[region].kind { let ops = match self.nodes[region].kind {
_ if node.ty.loc(self.tys) == Loc::Stack => { _ if node.ty.loc(self.tys) == Loc::Stack => {
vec![self.urg(region), self.urg(self.nodes[node.inputs[1]].inputs[1])] if self.nodes[node.inputs[1]].kind == Kind::Arg {
vec![self.urg(region), self.urg(node.inputs[1])]
} else {
vec![self.urg(region), self.urg(self.nodes[node.inputs[1]].inputs[1])]
}
} }
Kind::Stck => vec![self.urg(node.inputs[1])], Kind::Stck => vec![self.urg(node.inputs[1])],
_ => vec![self.urg(region), self.urg(node.inputs[1])], _ => vec![self.urg(region), self.urg(node.inputs[1])],
@ -4222,7 +4323,7 @@ mod tests {
fn generate(ident: &'static str, input: &'static str, output: &mut String) { fn generate(ident: &'static str, input: &'static str, output: &mut String) {
_ = log::set_logger(&crate::fs::Logger); _ = log::set_logger(&crate::fs::Logger);
//log::set_max_level(log::LevelFilter::Info); log::set_max_level(log::LevelFilter::Info);
// log::set_max_level(log::LevelFilter::Trace); // log::set_max_level(log::LevelFilter::Trace);
let (ref files, embeds) = crate::test_parse_files(ident, input); let (ref files, embeds) = crate::test_parse_files(ident, input);

View file

@ -21,47 +21,49 @@ main:
LI64 r32, 0d LI64 r32, 0d
CP r2, r32 CP r2, r32
JAL r31, r0, :multiple_breaks JAL r31, r0, :multiple_breaks
CP r33, r32 CP r33, r1
CP r34, r1
LI64 r1, 3d LI64 r1, 3d
JEQ r34, r1, :0 LI64 r34, 1d
LI64 r1, 1d JEQ r33, r1, :0
CP r1, r34
JMP :1 JMP :1
0: CP r35, r1 0: CP r35, r1
LI64 r36, 4d CP r36, r34
CP r2, r36 LI64 r37, 4d
CP r2, r37
JAL r31, r0, :multiple_breaks JAL r31, r0, :multiple_breaks
CP r37, r36 CP r38, r37
LI64 r38, 10d LI64 r39, 10d
JEQ r1, r38, :2 JEQ r1, r39, :2
LI64 r1, 2d LI64 r1, 2d
JMP :1 JMP :1
2: CP r2, r33 2: CP r2, r32
JAL r31, r0, :state_change_in_break JAL r31, r0, :state_change_in_break
CP r39, r1 JEQ r1, r32, :3
CP r1, r33
JEQ r39, r1, :3
CP r1, r35 CP r1, r35
JMP :1 JMP :1
3: CP r33, r1 3: CP r2, r38
CP r2, r37
JAL r31, r0, :state_change_in_break JAL r31, r0, :state_change_in_break
JEQ r1, r38, :4 JEQ r1, r39, :4
CP r1, r37 CP r1, r38
JMP :1 JMP :1
4: CP r2, r38 4: CP r2, r39
JAL r31, r0, :continue_and_state_change JAL r31, r0, :continue_and_state_change
JEQ r1, r38, :5 JEQ r1, r39, :5
LI64 r1, 5d LI64 r1, 5d
JMP :1 JMP :1
5: CP r2, r35 5: CP r2, r35
JAL r31, r0, :continue_and_state_change JAL r31, r0, :continue_and_state_change
CP r40, r1 JEQ r1, r32, :6
CP r1, r33
JEQ r40, r1, :6
LI64 r1, 6d LI64 r1, 6d
JMP :1 JMP :1
6: CP r1, r33 6: CP r1, r32
CP r40, r36
8: JNE r1, r40, :7
JMP :7
7: CP r2, r32
JAL r31, r0, :continue_and_state_change
JMP :8
1: LD r31, r254, 0a, 80h 1: LD r31, r254, 0a, 80h
ADDI64 r254, r254, 80d ADDI64 r254, r254, 80d
JALA r0, r31, 0a JALA r0, r31, 0a
@ -89,6 +91,7 @@ state_change_in_break:
2: ADDI64 r2, r2, 1d 2: ADDI64 r2, r2, 1d
JMP :4 JMP :4
3: JALA r0, r31, 0a 3: JALA r0, r31, 0a
code size: 569 timed out
ret: 0 code size: 585
ret: 10
status: Ok(()) status: Ok(())

View file

@ -18,17 +18,19 @@ integer:
JMP :0 JMP :0
0: JALA r0, r31, 0a 0: JALA r0, r31, 0a
line: line:
ST r2, r254, 0a, 16h ADDI64 r254, r254, -48d
ADDI64 r2, r254, 0d ST r2, r254, 32a, 16h
ST r4, r254, 0a, 16h ADDI64 r2, r254, 32d
ADDI64 r4, r254, 0d ST r4, r254, 16a, 16h
ADDI64 r4, r254, 16d
ST r6, r254, 0a, 16h ST r6, r254, 0a, 16h
ADDI64 r6, r254, 0d ADDI64 r6, r254, 0d
LD r9, r4, 0a, 8h LD r9, r4, 0a, 8h
LD r11, r2, 0a, 8h LD r11, r2, 0a, 8h
JGTS r11, r9, :0 JGTS r11, r9, :0
JMP :0 JMP :0
0: JALA r0, r31, 0a 0: ADDI64 r254, r254, 48d
JALA r0, r31, 0a
main: main:
ADDI64 r254, r254, -184d ADDI64 r254, r254, -184d
ST r31, r254, 96a, 88h ST r31, r254, 96a, 88h
@ -70,10 +72,11 @@ main:
ADDI64 r254, r254, 184d ADDI64 r254, r254, 184d
JALA r0, r31, 0a JALA r0, r31, 0a
rect_line: rect_line:
ST r2, r254, 0a, 16h ADDI64 r254, r254, -48d
ADDI64 r2, r254, 0d ST r2, r254, 32a, 16h
ST r4, r254, 0a, 16h ADDI64 r2, r254, 32d
ADDI64 r4, r254, 0d ST r4, r254, 16a, 16h
ADDI64 r4, r254, 16d
ST r6, r254, 0a, 16h ST r6, r254, 0a, 16h
ADDI64 r6, r254, 0d ADDI64 r6, r254, 0d
LI64 r10, 0d LI64 r10, 0d
@ -88,7 +91,8 @@ rect_line:
JMP :3 JMP :3
2: ADDI64 r9, r9, 1d 2: ADDI64 r9, r9, 1d
JMP :4 JMP :4
1: JALA r0, r31, 0a 1: ADDI64 r254, r254, 48d
code size: 886 JALA r0, r31, 0a
code size: 930
ret: 0 ret: 0
status: Ok(()) status: Ok(())