Compare commits

..

2 commits

Author SHA1 Message Date
Jakub Doka 4bfb5f192e
fixing the matrix 2024-10-30 13:45:19 +01:00
Jakub Doka ea628c1278
saving 2024-10-29 20:38:33 +01:00
11 changed files with 292 additions and 185 deletions

View file

@ -198,14 +198,18 @@ impl Nodes {
} }
let mut deepest = VOID; let mut deepest = VOID;
for i in 1..self[node].inputs.len() { for i in 0..self[node].inputs.len() {
let inp = self[node].inputs[i]; let inp = self[node].inputs[i];
if self.idepth(inp) > self.idepth(deepest) { if self.idepth(inp) > self.idepth(deepest) {
if matches!(self[inp].kind, Kind::Call { .. }) {
deepest = inp;
} else {
deepest = self.idom(inp); deepest = self.idom(inp);
} }
} }
}
if deepest == VOID { if deepest == self[node].inputs[0] {
return; return;
} }
@ -326,6 +330,14 @@ impl Nodes {
} }
} }
if self[node].kind == Kind::Load {
min = self.find_antideps(node, min);
}
if self[node].kind == Kind::Stre {
self[node].antidep = self[node].inputs[0];
}
if self[min].kind.ends_basic_block() { if self[min].kind.ends_basic_block() {
min = self.idom(min); min = self.idom(min);
} }
@ -340,6 +352,67 @@ impl Nodes {
self[min].outputs.push(node); self[min].outputs.push(node);
} }
fn find_antideps(&mut self, load: Nid, mut min: Nid) -> Nid {
debug_assert!(self[load].kind == Kind::Load);
let (aclass, _) = self.aclass_index(self[load].inputs[1]);
let mut cursor = min;
while cursor != self[load].inputs[0] {
self[cursor].antidep = load;
if self[cursor].clobbers.contains(&aclass) {
min = self[cursor].inputs[0];
break;
}
cursor = self.idom(cursor);
}
if self[load].inputs[2] == MEM {
return min;
}
for out in self[self[load].inputs[2]].outputs.clone() {
match self[out].kind {
Kind::Stre => {
let mut cursor = self[out].inputs[0];
while cursor != self[out].antidep {
if self[cursor].antidep == load {
min = self.common_dom(min, cursor);
if min == cursor {
self.bind(load, out);
}
break;
}
cursor = self.idom(cursor);
}
break;
}
Kind::Phi => {
let n = self[out].inputs[1..]
.iter()
.position(|&n| n == self[load].inputs[2])
.unwrap();
let mut cursor = self[self[out].inputs[0]].inputs[n];
while cursor != self[out].antidep {
if self[cursor].antidep == load {
min = self.common_dom(min, cursor);
break;
}
cursor = self.idom(cursor);
}
}
_ => {}
}
}
min
}
fn bind(&mut self, from: Nid, to: Nid) {
self[from].outputs.push(to);
self[to].inputs.push(from);
}
fn use_block(&mut self, target: Nid, from: Nid) -> Nid { fn use_block(&mut self, target: Nid, from: Nid) -> Nid {
if self[from].kind != Kind::Phi { if self[from].kind != Kind::Phi {
return self.idom(from); return self.idom(from);
@ -405,7 +478,6 @@ impl Nodes {
to_class to_class
.last_store .last_store
.set_remove(self.new_node(ty::Id::VOID, Kind::Phi, inps), self); .set_remove(self.new_node(ty::Id::VOID, Kind::Phi, inps), self);
to_class.loads.drain(..).for_each(|d| _ = d.remove(self));
} }
} }
} }
@ -439,12 +511,18 @@ impl Nodes {
if node.ty != ty::Id::VOID { if node.ty != ty::Id::VOID {
writeln!( writeln!(
out, out,
" node{i}[label=\"{i} {} {}\" 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),
node.aclass,
node.mem,
)?; )?;
} else { } else {
writeln!(out, " node{i}[label=\"{i} {}\" color={color}]", node.kind,)?; writeln!(
out,
" node{i}[label=\"{i} {} {} {}\" color={color}]",
node.kind, node.aclass, node.mem,
)?;
} }
for (j, &o) in node.outputs.iter().enumerate() { for (j, &o) in node.outputs.iter().enumerate() {
@ -675,14 +753,8 @@ impl Nodes {
stack.iter().skip(prev_len).for_each(|&n| self.lock(n)); stack.iter().skip(prev_len).for_each(|&n| self.lock(n));
} }
pub fn aclass_index(&self, mut region: Nid) -> (usize, Nid) { pub fn aclass_index(&self, region: Nid) -> (usize, Nid) {
loop { (self[region].aclass, self[region].mem)
region = match self[region].kind {
Kind::BinOp { op: TokenKind::Add | TokenKind::Sub } => self[region].inputs[1],
Kind::Phi if self[region].inputs[2] == 0 => self[region].inputs[1],
_ => break (self[region].aclass, region),
};
}
} }
fn peephole(&mut self, target: Nid) -> Option<Nid> { fn peephole(&mut self, target: Nid) -> Option<Nid> {
@ -943,11 +1015,51 @@ impl Nodes {
return Some(self.new_node(self[lhs].ty, Kind::Stre, vc)); return Some(self.new_node(self[lhs].ty, Kind::Stre, vc));
} }
} }
K::Stck => {
if let &[mut a, mut b] = self[target].outputs.as_slice() {
if self[a].kind == Kind::Load {
mem::swap(&mut a, &mut b);
}
if matches!(self[a].kind, Kind::Call { .. })
&& self[a].inputs.last() == Some(&target)
&& self[b].kind == Kind::Load
&& let &[store] = self[b].outputs.as_slice()
&& self[store].kind == Kind::Stre
{
let len = self[a].inputs.len();
let stre = self[store].inputs[3];
if stre != MEM {
self[a].inputs.push(stre);
self[a].inputs.swap(len - 1, len);
self[stre].outputs.push(a);
}
return Some(self[store].inputs[2]);
}
}
}
K::Stre => { K::Stre => {
let &[_, value, region, store, ..] = self[target].inputs.as_slice() else { let &[_, value, region, store, ..] = self[target].inputs.as_slice() else {
unreachable!() unreachable!()
}; };
if self[value].kind == Kind::Load && self[value].inputs[1] == region {
return Some(store);
}
let mut cursor = target;
while self[cursor].kind == Kind::Stre
&& self[cursor].inputs[1] != VOID
&& let &[next_store] = self[cursor].outputs.as_slice()
{
if self[next_store].inputs[2] == region
&& self[next_store].ty == self[target].ty
{
return Some(store);
}
cursor = next_store;
}
'eliminate: { 'eliminate: {
if self[target].outputs.is_empty() { if self[target].outputs.is_empty() {
break 'eliminate; break 'eliminate;
@ -1066,6 +1178,10 @@ impl Nodes {
if self[store].kind == Kind::Stre if self[store].kind == Kind::Stre
&& self[store].inputs[2] == region && self[store].inputs[2] == region
&& self[store].ty == self[target].ty && self[store].ty == self[target].ty
&& self[store]
.outputs
.iter()
.all(|&n| !matches!(self[n].kind, Kind::Call { .. }))
{ {
return Some(self[store].inputs[1]); return Some(self[store].inputs[1]);
} }
@ -1076,6 +1192,10 @@ impl Nodes {
while cursor != MEM while cursor != MEM
&& self[cursor].kind == Kind::Stre && self[cursor].kind == Kind::Stre
&& self[cursor].inputs[1] != VOID && self[cursor].inputs[1] != VOID
&& self[cursor]
.outputs
.iter()
.all(|&n| !matches!(self[n].kind, Kind::Call { .. }))
{ {
if self[cursor].inputs[2] == region && self[cursor].ty == self[target].ty { if self[cursor].inputs[2] == region && self[cursor].ty == self[target].ty {
return Some(self[cursor].inputs[1]); return Some(self[cursor].inputs[1]);
@ -1354,8 +1474,11 @@ impl Nodes {
self.load_loop_var(index, lvar, loops); self.load_loop_var(index, lvar, loops);
if !self[lvar.value()].is_lazy_phi(node) { if !self[lvar.value()].is_lazy_phi(node) {
let inps = [node, lvar.value(), VOID]; let lvalue = lvar.value();
let inps = [node, lvalue, VOID];
lvar.set_value(self.new_node_nop(lvar.ty, Kind::Phi, inps), self); lvar.set_value(self.new_node_nop(lvar.ty, Kind::Phi, inps), self);
self[lvar.value()].aclass = self[lvalue].aclass;
self[lvar.value()].mem = self[lvalue].mem;
} }
var.set_value(lvar.value(), self); var.set_value(lvar.value(), self);
} }
@ -1538,6 +1661,7 @@ pub struct Node {
inputs: Vc, inputs: Vc,
outputs: Vc, outputs: Vc,
peep_triggers: Vc, peep_triggers: Vc,
clobbers: Vec<usize>,
ty: ty::Id, ty: ty::Id,
offset: Offset, offset: Offset,
ralloc_backref: RallocBRef, ralloc_backref: RallocBRef,
@ -1545,6 +1669,8 @@ pub struct Node {
lock_rc: LockRc, lock_rc: LockRc,
loop_depth: LoopDepth, loop_depth: LoopDepth,
aclass: usize, aclass: usize,
mem: Nid,
antidep: Nid,
} }
impl Node { impl Node {
@ -1562,7 +1688,7 @@ impl Node {
fn is_not_gvnd(&self) -> bool { fn is_not_gvnd(&self) -> bool {
(self.kind == Kind::Phi && self.inputs[2] == 0) (self.kind == Kind::Phi && self.inputs[2] == 0)
|| matches!(self.kind, Kind::Arg | Kind::Stck) || matches!(self.kind, Kind::Arg | Kind::Stck | Kind::Stre)
|| self.kind.is_cfg() || self.kind.is_cfg()
} }
@ -1719,24 +1845,21 @@ impl Variable {
#[derive(Default, Clone)] #[derive(Default, Clone)]
pub struct AClass { pub struct AClass {
last_store: StrongRef, last_store: StrongRef,
loads: Vec<StrongRef>, clobber: StrongRef,
} }
impl AClass { impl AClass {
fn dup(&self, nodes: &mut Nodes) -> Self { fn dup(&self, nodes: &mut Nodes) -> Self {
Self { Self { last_store: self.last_store.dup(nodes), clobber: self.clobber.dup(nodes) }
last_store: self.last_store.dup(nodes),
loads: self.loads.iter().map(|v| v.dup(nodes)).collect(),
}
} }
fn remove(mut self, nodes: &mut Nodes) { fn remove(self, nodes: &mut Nodes) {
self.last_store.remove(nodes); self.last_store.remove(nodes);
self.loads.drain(..).for_each(|n| _ = n.remove(nodes)); self.clobber.remove(nodes);
} }
fn new(nodes: &mut Nodes) -> Self { fn new(nodes: &mut Nodes) -> Self {
Self { last_store: StrongRef::new(MEM, nodes), loads: Default::default() } Self { last_store: StrongRef::new(MEM, nodes), clobber: StrongRef::new(VOID, nodes) }
} }
} }
@ -2071,6 +2194,7 @@ impl<'a> Codegen<'a> {
fn new_stack(&mut self, ty: ty::Id) -> Nid { fn new_stack(&mut self, ty: ty::Id) -> Nid {
let stck = self.ci.nodes.new_node_nop(ty, Kind::Stck, [VOID, MEM]); let stck = self.ci.nodes.new_node_nop(ty, Kind::Stck, [VOID, MEM]);
self.ci.nodes[stck].aclass = self.ci.scope.aclasses.len(); self.ci.nodes[stck].aclass = self.ci.scope.aclasses.len();
self.ci.nodes[stck].mem = stck;
self.ci.scope.aclasses.push(AClass::new(&mut self.ci.nodes)); self.ci.scope.aclasses.push(AClass::new(&mut self.ci.nodes));
stck stck
} }
@ -2089,7 +2213,6 @@ impl<'a> Codegen<'a> {
if value_index != 0 { if value_index != 0 {
// simply switch the class to the default one // simply switch the class to the default one
let aclass = &mut self.ci.scope.aclasses[value_index]; let aclass = &mut self.ci.scope.aclasses[value_index];
let loads = mem::take(&mut aclass.loads);
self.ci.nodes.load_loop_aclass(value_index, aclass, &mut self.ci.loops); self.ci.nodes.load_loop_aclass(value_index, aclass, &mut self.ci.loops);
let last_store = aclass.last_store.get(); let last_store = aclass.last_store.get();
let mut cursor = last_store; let mut cursor = last_store;
@ -2106,23 +2229,13 @@ impl<'a> Codegen<'a> {
} }
self.ci.scope.aclasses[0].last_store.set(last_store, &mut self.ci.nodes); self.ci.scope.aclasses[0].last_store.set(last_store, &mut self.ci.nodes);
} }
self.ci.scope.aclasses[0].loads.extend(loads);
self.ci.nodes[value_region].aclass = 0; self.ci.nodes[value_region].aclass = 0;
} }
let (index, _) = self.ci.nodes.aclass_index(region); let (index, _) = self.ci.nodes.aclass_index(region);
let aclass = &mut self.ci.scope.aclasses[index]; let aclass = &mut self.ci.scope.aclasses[index];
self.ci.nodes.load_loop_aclass(index, aclass, &mut self.ci.loops); self.ci.nodes.load_loop_aclass(index, aclass, &mut self.ci.loops);
let mut vc = Vc::from([VOID, value, region, aclass.last_store.get()]); let vc = Vc::from([aclass.clobber.get(), value, region, aclass.last_store.get()]);
for load in aclass.loads.drain(..) {
if load.get() == value {
load.soft_remove(&mut self.ci.nodes);
continue;
}
if let Some(load) = load.remove(&mut self.ci.nodes) {
vc.push(load);
}
}
mem::take(&mut aclass.last_store).soft_remove(&mut self.ci.nodes); mem::take(&mut aclass.last_store).soft_remove(&mut self.ci.nodes);
let store = self.ci.nodes.new_node(ty, Kind::Stre, vc); let store = self.ci.nodes.new_node(ty, Kind::Stre, vc);
aclass.last_store = StrongRef::new(store, &mut self.ci.nodes); aclass.last_store = StrongRef::new(store, &mut self.ci.nodes);
@ -2146,10 +2259,8 @@ impl<'a> Codegen<'a> {
let (index, _) = self.ci.nodes.aclass_index(region); let (index, _) = self.ci.nodes.aclass_index(region);
let aclass = &mut self.ci.scope.aclasses[index]; let aclass = &mut self.ci.scope.aclasses[index];
self.ci.nodes.load_loop_aclass(index, aclass, &mut self.ci.loops); self.ci.nodes.load_loop_aclass(index, aclass, &mut self.ci.loops);
let vc = [VOID, region, aclass.last_store.get()]; let vc = [aclass.clobber.get(), region, aclass.last_store.get()];
let load = self.ci.nodes.new_node(ty, Kind::Load, vc); self.ci.nodes.new_node(ty, Kind::Load, vc)
aclass.loads.push(StrongRef::new(load, &mut self.ci.nodes));
load
} }
pub fn generate(&mut self, entry: FileId) { pub fn generate(&mut self, entry: FileId) {
@ -2505,9 +2616,13 @@ 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(pos, &mut lhs, &mut rhs, op); let (ty, aclass, mem) = self.binop_ty(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(ty.bin_ret(op), Kind::BinOp { op }, inps)) let bop =
self.ci.nodes.new_node_lit(ty.bin_ret(op), Kind::BinOp { op }, inps);
self.ci.nodes[bop.id].aclass = aclass;
self.ci.nodes[bop.id].mem = mem;
Some(bop)
} }
ty::Kind::Struct(s) if op.is_homogenous() => { ty::Kind::Struct(s) if op.is_homogenous() => {
self.ci.nodes.lock(lhs.id); self.ci.nodes.lock(lhs.id);
@ -2557,9 +2672,13 @@ impl<'a> Codegen<'a> {
let inps = [VOID, idx.id, size]; let inps = [VOID, idx.id, size];
let offset = let offset =
self.ci.nodes.new_node(ty::Id::INT, Kind::BinOp { op: TokenKind::Mul }, inps); self.ci.nodes.new_node(ty::Id::INT, Kind::BinOp { op: TokenKind::Mul }, inps);
let (aclass, mem) = self.ci.nodes.aclass_index(bs.id);
let inps = [VOID, bs.id, offset]; let inps = [VOID, bs.id, offset];
let ptr = let ptr =
self.ci.nodes.new_node(ty::Id::INT, Kind::BinOp { op: TokenKind::Add }, inps); self.ci.nodes.new_node(ty::Id::INT, Kind::BinOp { op: TokenKind::Add }, inps);
self.ci.nodes[ptr].aclass = aclass;
self.ci.nodes[ptr].mem = mem;
Some(Value::ptr(ptr).ty(elem)) Some(Value::ptr(ptr).ty(elem))
} }
Expr::Embed { id, .. } => { Expr::Embed { id, .. } => {
@ -2768,7 +2887,7 @@ impl<'a> Codegen<'a> {
&mut self.ci.nodes, &mut self.ci.nodes,
); );
self.add_clobber_stores(&clobbered_aliases); self.add_clobber_stores(clobbered_aliases);
alt_value.or(Some(Value::new(self.ci.ctrl.get()).ty(ty))) alt_value.or(Some(Value::new(self.ci.ctrl.get()).ty(ty)))
} }
@ -2844,7 +2963,7 @@ impl<'a> Codegen<'a> {
&mut self.ci.nodes, &mut self.ci.nodes,
); );
self.add_clobber_stores(&clobbered_aliases); self.add_clobber_stores(clobbered_aliases);
alt_value.or(Some(Value::new(self.ci.ctrl.get()).ty(sig.ret))) alt_value.or(Some(Value::new(self.ci.ctrl.get()).ty(sig.ret)))
} }
@ -3418,10 +3537,10 @@ impl<'a> Codegen<'a> {
if let Some(base) = self.tys.base_of(value.ty) { if let Some(base) = self.tys.base_of(value.ty) {
clobbered_aliases.push(self.ci.nodes.aclass_index(value.id).0); clobbered_aliases.push(self.ci.nodes.aclass_index(value.id).0);
if base.has_pointers(self.tys) { if base.has_pointers(self.tys) {
clobbered_aliases.push(0); clobbered_aliases.push(DEFAULT_ACLASS);
} }
} else if value.ty.has_pointers(self.tys) { } else if value.ty.has_pointers(self.tys) {
clobbered_aliases.push(0); clobbered_aliases.push(DEFAULT_ACLASS);
} }
} }
@ -3430,31 +3549,14 @@ impl<'a> Codegen<'a> {
let aclass = &mut self.ci.scope.aclasses[clobbered]; let aclass = &mut self.ci.scope.aclasses[clobbered];
self.ci.nodes.load_loop_aclass(clobbered, aclass, &mut self.ci.loops); self.ci.nodes.load_loop_aclass(clobbered, aclass, &mut self.ci.loops);
inps.push(aclass.last_store.get()); inps.push(aclass.last_store.get());
aclass.loads.retain_mut(|load| {
if inps.contains(&load.get()) {
return true;
}
if let Some(load) = mem::take(load).remove(&mut self.ci.nodes) {
inps.push(load);
}
false
});
} }
} }
fn add_clobber_stores(&mut self, clobbered_aliases: &[usize]) { fn add_clobber_stores(&mut self, clobbered_aliases: Vec<usize>) {
for &clobbered in clobbered_aliases.iter() { for &clobbered in clobbered_aliases.iter() {
if clobbered == DEFAULT_ACLASS { self.ci.scope.aclasses[clobbered].clobber.set(self.ci.ctrl.get(), &mut self.ci.nodes);
continue;
}
let aclass = self.ci.scope.aclasses[clobbered].last_store.get();
if aclass == MEM {
continue;
}
self.store_mem(self.ci.nodes[aclass].inputs[2], ty::Id::VOID, VOID);
} }
self.ci.nodes[self.ci.ctrl.get()].clobbers = clobbered_aliases;
} }
fn struct_op( fn struct_op(
@ -3625,8 +3727,12 @@ impl<'a> Codegen<'a> {
} }
let off = self.ci.nodes.new_node_nop(ty::Id::INT, Kind::CInt { value: off as i64 }, [VOID]); let off = self.ci.nodes.new_node_nop(ty::Id::INT, Kind::CInt { value: off as i64 }, [VOID]);
let (aclass, mem) = self.ci.nodes.aclass_index(val);
let inps = [VOID, val, off]; let inps = [VOID, val, off];
self.ci.nodes.new_node(ty::Id::INT, Kind::BinOp { op: TokenKind::Add }, inps) let seted = self.ci.nodes.new_node(ty::Id::INT, Kind::BinOp { op: TokenKind::Add }, inps);
self.ci.nodes[seted].aclass = aclass;
self.ci.nodes[seted].mem = mem;
seted
} }
fn strip_var(&mut self, n: &mut Value) { fn strip_var(&mut self, n: &mut Value) {
@ -3782,17 +3888,23 @@ impl<'a> Codegen<'a> {
#[must_use] #[must_use]
#[track_caller] #[track_caller]
fn binop_ty(&mut self, pos: Pos, lhs: &mut Value, rhs: &mut Value, op: TokenKind) -> ty::Id { fn binop_ty(
&mut self,
pos: Pos,
lhs: &mut Value,
rhs: &mut Value,
op: TokenKind,
) -> (ty::Id, usize, Nid) {
if let Some(upcasted) = lhs.ty.try_upcast(rhs.ty) { if let Some(upcasted) = lhs.ty.try_upcast(rhs.ty) {
let to_correct = if lhs.ty != upcasted { let to_correct = if lhs.ty != upcasted {
Some(lhs) Some((lhs, rhs))
} else if rhs.ty != upcasted { } else if rhs.ty != upcasted {
Some(rhs) Some((rhs, lhs))
} else { } else {
None None
}; };
if let Some(oper) = to_correct { if let Some((oper, other)) = to_correct {
if self.tys.size_of(upcasted) > self.tys.size_of(oper.ty) { if self.tys.size_of(upcasted) > self.tys.size_of(oper.ty) {
self.extend(oper, upcasted); self.extend(oper, upcasted);
} }
@ -3806,15 +3918,16 @@ impl<'a> Codegen<'a> {
self.ci.nodes.new_node(upcasted, Kind::BinOp { op: TokenKind::Mul }, [ self.ci.nodes.new_node(upcasted, Kind::BinOp { op: TokenKind::Mul }, [
VOID, oper.id, cnst, VOID, oper.id, cnst,
]); ]);
return (upcasted, self.ci.nodes[other.id].aclass, self.ci.nodes[other.id].mem);
} }
} }
upcasted (upcasted, DEFAULT_ACLASS, VOID)
} else { } else {
let ty = self.ty_display(lhs.ty); let ty = self.ty_display(lhs.ty);
let expected = self.ty_display(rhs.ty); let expected = self.ty_display(rhs.ty);
self.report(pos, fa!("'{ty} {op} {expected}' is not supported")); self.report(pos, fa!("'{ty} {op} {expected}' is not supported"));
ty::Id::NEVER (ty::Id::NEVER, DEFAULT_ACLASS, VOID)
} }
} }

View file

@ -408,12 +408,20 @@ impl ItemCtx {
} }
if let Some(PLoc::WideReg(r, size)) = ret { if let Some(PLoc::WideReg(r, size)) = ret {
debug_assert_eq!(
fuc.nodes[*node.inputs.last().unwrap()].kind,
Kind::Stck
);
let stck = fuc.nodes[*node.inputs.last().unwrap()].offset; let stck = fuc.nodes[*node.inputs.last().unwrap()].offset;
self.emit(instrs::st(r, reg::STACK_PTR, stck as _, size)); self.emit(instrs::st(r, reg::STACK_PTR, stck as _, size));
} }
if let Some(PLoc::Reg(r, size)) = ret if let Some(PLoc::Reg(r, size)) = ret
&& node.ty.loc(tys) == Loc::Stack && node.ty.loc(tys) == Loc::Stack
{ {
debug_assert_eq!(
fuc.nodes[*node.inputs.last().unwrap()].kind,
Kind::Stck
);
let stck = fuc.nodes[*node.inputs.last().unwrap()].offset; let stck = fuc.nodes[*node.inputs.last().unwrap()].offset;
self.emit(instrs::st(r, reg::STACK_PTR, stck as _, size)); self.emit(instrs::st(r, reg::STACK_PTR, stck as _, size));
} }

View file

@ -1,20 +1,17 @@
deinit: deinit:
ADDI64 r254, r254, -48d ADDI64 r254, r254, -16d
ST r31, r254, 24a, 24h ST r31, r254, 0a, 16h
LD r5, r2, 16a, 8h
CP r32, r2 CP r32, r2
LD r5, r2, 16a, 8h
LI64 r4, 8d LI64 r4, 8d
MUL64 r3, r5, r4 MUL64 r3, r5, r4
CP r5, r32 CP r5, r32
LD r2, r5, 0a, 8h LD r2, r5, 0a, 8h
JAL r31, r0, :free JAL r31, r0, :free
ADDI64 r33, r254, 0d CP r1, r32
CP r1, r33
JAL r31, r0, :new JAL r31, r0, :new
CP r2, r32 LD r31, r254, 0a, 16h
BMC r33, r2, 24h ADDI64 r254, r254, 16d
LD r31, r254, 24a, 24h
ADDI64 r254, r254, 48d
JALA r0, r31, 0a JALA r0, r31, 0a
free: free:
CP r10, r2 CP r10, r2
@ -26,23 +23,21 @@ free:
ECA ECA
JALA r0, r31, 0a JALA r0, r31, 0a
main: main:
ADDI64 r254, r254, -80d ADDI64 r254, r254, -48d
ST r31, r254, 48a, 32h ST r31, r254, 24a, 24h
ADDI64 r32, r254, 24d ADDI64 r32, r254, 0d
CP r1, r32 CP r1, r32
JAL r31, r0, :new JAL r31, r0, :new
ADDI64 r33, r254, 0d
BMC r32, r33, 24h
LI64 r3, 69d LI64 r3, 69d
CP r2, r33 CP r2, r32
JAL r31, r0, :push JAL r31, r0, :push
LD r12, r254, 0a, 8h LD r9, r254, 0a, 8h
LD r34, r12, 0a, 8h LD r33, r9, 0a, 8h
CP r2, r33 CP r2, r32
JAL r31, r0, :deinit JAL r31, r0, :deinit
CP r1, r34 CP r1, r33
LD r31, r254, 48a, 32h LD r31, r254, 24a, 24h
ADDI64 r254, r254, 80d ADDI64 r254, r254, 48d
JALA r0, r31, 0a JALA r0, r31, 0a
malloc: malloc:
CP r9, r2 CP r9, r2
@ -92,12 +87,12 @@ push:
LD r12, r38, 0a, 8h LD r12, r38, 0a, 8h
ADD64 r11, r12, r8 ADD64 r11, r12, r8
CP r3, r39 CP r3, r39
9: JNE r11, r12, :5 9: LD r2, r38, 0a, 8h
LD r8, r38, 8a, 8h LD r8, r38, 8a, 8h
JNE r11, r12, :5
JEQ r8, r1, :6 JEQ r8, r1, :6
CP r4, r37 CP r4, r37
MUL64 r3, r8, r4 MUL64 r3, r8, r4
LD r2, r38, 0a, 8h
JAL r31, r0, :free JAL r31, r0, :free
CP r5, r39 CP r5, r39
JMP :7 JMP :7
@ -126,6 +121,6 @@ push:
4: LD r31, r254, 0a, 72h 4: LD r31, r254, 0a, 72h
ADDI64 r254, r254, 72d ADDI64 r254, r254, 72d
JALA r0, r31, 0a JALA r0, r31, 0a
code size: 980 code size: 945
ret: 69 ret: 69
status: Ok(()) status: Ok(())

View file

@ -4,9 +4,9 @@ main:
LI64 r6, 128d LI64 r6, 128d
LI64 r7, 0d LI64 r7, 0d
ADDI64 r4, r254, 0d ADDI64 r4, r254, 0d
2: JLTU r7, r6, :0 2: LD r12, r254, 42a, 1h
LD r1, r254, 42a, 1h JLTU r7, r6, :0
ANDI r1, r1, 255d ANDI r1, r12, 255d
JMP :1 JMP :1
0: ADDI64 r3, r7, 1d 0: ADDI64 r3, r7, 1d
ADD64 r7, r4, r7 ADD64 r7, r4, r7

View file

@ -1,25 +1,23 @@
main: main:
ADDI64 r254, r254, -72d ADDI64 r254, r254, -48d
ST r31, r254, 56a, 16h ST r31, r254, 40a, 8h
ADDI64 r32, r254, 0d 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
JAL r31, r0, :opaque JAL r31, r0, :opaque
ST r1, r254, 0a, 16h ST r1, r254, 0a, 16h
LI64 r6, 4d LD r4, r254, 8a, 8h
ADDI64 r5, r254, 40d LD r6, r254, 16a, 8h
ADDI64 r8, r254, 16d ADD64 r8, r6, r4
ST r6, r254, 40a, 8h LD r6, r254, 0a, 8h
LI64 r7, 1d SUB64 r1, r6, r8
ST r7, r254, 48a, 8h LD r31, r254, 40a, 8h
ST r7, r254, 32a, 8h ADDI64 r254, r254, 48d
BMC r5, r8, 16h
BMC r32, r8, 16h
LD r7, r254, 24a, 8h
LD r9, r254, 32a, 8h
ADD64 r11, r9, r7
LD r9, r254, 16a, 8h
SUB64 r1, r9, r11
LD r31, r254, 56a, 16h
ADDI64 r254, r254, 72d
JALA r0, r31, 0a JALA r0, r31, 0a
opaque: opaque:
ADDI64 r254, r254, -16d ADDI64 r254, r254, -16d
@ -31,6 +29,6 @@ opaque:
LD r1, r2, 0a, 16h LD r1, r2, 0a, 16h
ADDI64 r254, r254, 16d ADDI64 r254, r254, 16d
JALA r0, r31, 0a JALA r0, r31, 0a
code size: 339 code size: 323
ret: 0 ret: 0
status: Ok(()) status: Ok(())

View file

@ -1,29 +1,27 @@
main: main:
ADDI64 r254, r254, -24d ADDI64 r254, r254, -12d
ST r31, r254, 8a, 16h ST r31, r254, 4a, 8h
ADDI64 r32, r254, 4d ADDI64 r2, r254, 0d
JAL r31, r0, :random_color JAL r31, r0, :random_color
ST r1, r254, 4a, 4h ST r1, r254, 0a, 4h
ADDI64 r5, r254, 0d LD r5, r254, 0a, 1h
BMC r32, r5, 4h LD r8, r254, 1a, 1h
LD r8, r254, 0a, 1h LD r12, r254, 2a, 1h
LD r11, r254, 1a, 1h ANDI r9, r5, 255d
LD r3, r254, 2a, 1h ANDI r1, r8, 255d
ANDI r12, r8, 255d LD r6, r254, 3a, 1h
ANDI r4, r11, 255d ANDI r5, r12, 255d
LD r9, r254, 3a, 1h ADD64 r4, r1, r9
ANDI r8, r3, 255d ANDI r10, r6, 255d
ADD64 r7, r4, r12 ADD64 r9, r4, r5
ANDI r1, r9, 255d ADD64 r1, r9, r10
ADD64 r12, r7, r8 LD r31, r254, 4a, 8h
ADD64 r1, r12, r1 ADDI64 r254, r254, 12d
LD r31, r254, 8a, 16h
ADDI64 r254, r254, 24d
JALA r0, r31, 0a JALA r0, r31, 0a
random_color: random_color:
LRA r1, r0, :white LRA r1, r0, :white
LD r1, r1, 0a, 4h LD r1, r1, 0a, 4h
JALA r0, r31, 0a JALA r0, r31, 0a
code size: 257 code size: 241
ret: 1020 ret: 1020
status: Ok(()) status: Ok(())

View file

@ -1,14 +1,12 @@
main: main:
ADDI64 r254, r254, -4d ADDI64 r254, r254, -4d
LRA r1, r0, :black LRA r2, r0, :white
ADDI64 r3, r254, 0d ADDI64 r3, r254, 0d
LRA r5, r0, :white BMC r2, r3, 4h
BMC r1, r3, 4h LD r6, r254, 3a, 1h
BMC r5, r3, 4h ANDI r1, r6, 255d
LD r9, r254, 3a, 1h
ANDI r1, r9, 255d
ADDI64 r254, r254, 4d ADDI64 r254, r254, 4d
JALA r0, r31, 0a JALA r0, r31, 0a
code size: 108 code size: 92
ret: 255 ret: 255
status: Ok(()) status: Ok(())

View file

@ -8,8 +8,8 @@ main:
6: JNE r8, r7, :0 6: JNE r8, r7, :0
LI64 r7, 2d LI64 r7, 2d
CP r8, r4 CP r8, r4
4: JNE r8, r6, :1 4: LD r1, r254, 0a, 8h
LD r1, r254, 0a, 8h JNE r8, r6, :1
JMP :2 JMP :2
1: MUL64 r10, r8, r7 1: MUL64 r10, r8, r7
ADD64 r8, r8, r6 ADD64 r8, r8, r6
@ -19,14 +19,14 @@ main:
5: JNE r2, r7, :3 5: JNE r2, r7, :3
JMP :4 JMP :4
3: ADD64 r1, r2, r6 3: ADD64 r1, r2, r6
ADD64 r11, r10, r2 ADD64 r11, r9, r2
ADD64 r12, r9, r2 MULI64 r3, r11, 8d
MULI64 r2, r11, 8d ADD64 r12, r10, r2
ADD64 r11, r5, r3
MULI64 r12, r12, 8d MULI64 r12, r12, 8d
ADD64 r11, r5, r2
ADD64 r12, r5, r12 ADD64 r12, r5, r12
BMC r12, r11, 8h
BMC r11, r12, 8h BMC r11, r12, 8h
BMC r12, r11, 8h
CP r2, r1 CP r2, r1
JMP :5 JMP :5
0: ADD64 r11, r8, r6 0: ADD64 r11, r8, r6

View file

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

View file

@ -8,9 +8,9 @@ main:
4: JLTU r9, r8, :0 4: JLTU r9, r8, :0
LI64 r4, 10d LI64 r4, 10d
CP r7, r6 CP r7, r6
3: JLTU r7, r4, :1 3: LD r9, r254, 2048a, 1h
LD r10, r254, 2048a, 1h JLTU r7, r4, :1
ANDI r1, r10, 255d ANDI r1, r9, 255d
JMP :2 JMP :2
1: ADD64 r12, r7, r6 1: ADD64 r12, r7, r6
MULI64 r1, r7, 1024d MULI64 r1, r7, 1024d

View file

@ -1,19 +1,17 @@
main: main:
ADDI64 r254, r254, -48d ADDI64 r254, r254, -24d
ST r31, r254, 32a, 16h ST r31, r254, 16a, 8h
ADDI64 r32, r254, 16d ADDI64 r3, r254, 0d
LI64 r4, 0d LI64 r4, 0d
CP r3, r4 CP r3, r4
JAL r31, r0, :maina JAL r31, r0, :maina
ST r1, r254, 16a, 16h ST r1, r254, 0a, 16h
ADDI64 r7, r254, 0d LD r8, r254, 12a, 1h
BMC r32, r7, 16h LD r9, r254, 3a, 1h
LD r11, r254, 12a, 1h SUB8 r11, r9, r8
LD r12, r254, 3a, 1h ANDI r1, r11, 255d
SUB8 r2, r12, r11 LD r31, r254, 16a, 8h
ANDI r1, r2, 255d ADDI64 r254, r254, 24d
LD r31, r254, 32a, 16h
ADDI64 r254, r254, 48d
JALA r0, r31, 0a JALA r0, r31, 0a
maina: maina:
ADDI64 r254, r254, -36d ADDI64 r254, r254, -36d
@ -50,6 +48,6 @@ small_struct:
LD r1, r3, 0a, 4h LD r1, r3, 0a, 4h
ADDI64 r254, r254, 4d ADDI64 r254, r254, 4d
JALA r0, r31, 0a JALA r0, r31, 0a
code size: 514 code size: 498
ret: 2 ret: 2
status: Ok(()) status: Ok(())