okay now it works

This commit is contained in:
Jakub Doka 2024-10-24 09:43:07 +02:00
parent 41b70bec43
commit cb9d7f7d1e
No known key found for this signature in database
GPG key ID: C6E9A89936B8C143
23 changed files with 571 additions and 704 deletions

View file

@ -158,7 +158,6 @@ Ty := struct {
// comment // comment
a: int, a: int,
b: int,
} }
Ty2 := struct { Ty2 := struct {
@ -174,7 +173,7 @@ main := fn(): int {
return 9001 return 9001
} }
finst := Ty2.{ty: .{a: 4, b: 1}, c: 3} finst := Ty2.{ty: .{a: 4}, c: 3}
inst := odher_pass(finst) inst := odher_pass(finst)
if inst.c == 3 { if inst.c == 3 {
return pass(&inst.ty) return pass(&inst.ty)
@ -183,7 +182,7 @@ main := fn(): int {
} }
pass := fn(t: ^Ty): int { pass := fn(t: ^Ty): int {
return t.a - t.b return t.a
} }
odher_pass := fn(t: Ty2): Ty2 { odher_pass := fn(t: Ty2): Ty2 {
@ -701,93 +700,29 @@ min := fn(a: int, b: int): int {
#### inline_test #### inline_test
```hb ```hb
Point := struct {x: int, y: int} fna := fn(a: int, b: int, c: int): int return a + b + c
Buffer := struct {}
Transform := Point
ColorBGRA := Point
line := fn(buffer: Buffer, p0: Point, p1: Point, color: ColorBGRA, thickness: int): void { scalar_values := fn(): int {
if true { return @inline(fna, 1, @inline(fna, 2, 3, 4), -10)
if p0.x > p1.x {
@inline(line_low, buffer, p1, p0, color)
} else {
@inline(line_low, buffer, p0, p1, color)
}
} else {
if p0.y > p1.y {
// blah, test leading new line on directives
@inline(line_high, buffer, p1, p0, color)
} else {
@inline(line_high, buffer, p0, p1, color)
}
}
return
} }
line_low := fn(buffer: Buffer, p0: Point, p1: Point, color: ColorBGRA): void { A := struct {a: int}
return AB := struct {a: A, b: int}
mangle := fn(a: A, ab: AB): int {
return a.a + ab.a.a - ab.b
} }
line_high := fn(buffer: Buffer, p0: Point, p1: Point, color: ColorBGRA): void { structs := fn(): int {
return return @inline(mangle, .(0), .(.(@inline(mangle, .(20), .(.(5), 5))), 20))
}
screenidx := @use("screen.hb").screenidx
rect_line := fn(buffer: Buffer, pos: Point, tr: Transform, color: ColorBGRA, thickness: int): void {
t := 0
y := 0
x := 0
loop if t == thickness break else {
y = pos.y
x = pos.x
loop if y == pos.y + tr.x break else {
//a := 1 + @inline(screenidx, 10)
//a = 1 + @inline(screenidx, 2)
y += 1
}
t += 1
}
return
}
random := @use("random.hb")
example := fn(): void {
loop {
random_x := @inline(random.integer, 0, 1024)
random_y := random.integer(0, 768)
a := @inline(screenidx, random_x)
break
}
return
} }
main := fn(): int { main := fn(): int {
line(.(), .(0, 0), .(0, 0), .(0, 0), 10) if scalar_values() != 0 return 1
rect_line(.(), .(0, 0), .(0, 0), .(0, 0), 10) if structs() != 0 return structs()
example()
return 0 return 0
} }
// in module: screen.hb
screenidx := fn(orange: int): int {
return orange
}
// in module: random.hb
integer := fn(min: int, max: int): int {
rng := @as(int, 4)
if max == 0 {
return rng % (max - min + 1) + min
} else {
return rng
}
}
``` ```
#### inlined_generic_functions #### inlined_generic_functions

View file

@ -277,7 +277,7 @@ impl Value {
} }
fn imm(value: u64) -> Self { fn imm(value: u64) -> Self {
Self { ty: ty::Id::UINT, loc: Loc::ct(value) } Self { ty: ty::Id::INT, loc: Loc::ct(value) }
} }
fn ty(ty: ty::Id) -> Self { fn ty(ty: ty::Id) -> Self {
@ -2147,7 +2147,7 @@ impl Codegen {
self.ci.vars.push(Variable { id: arg.id, value: Value { ty, loc } }); self.ci.vars.push(Variable { id: arg.id, value: Value { ty, loc } });
} }
if let PLoc::Ref(..) = ret { if let Some(PLoc::Ref(..)) = ret {
let reg = self.ci.regs.allocate(); let reg = self.ci.regs.allocate();
self.ci.emit(instrs::cp(reg.get(), 1)); self.ci.emit(instrs::cp(reg.get(), 1));
self.ci.ret_reg = reg; self.ci.ret_reg = reg;
@ -2180,18 +2180,18 @@ impl Codegen {
return Loc::default(); return Loc::default();
} }
let (src, dst) = match parama.next(ty, &self.tys) { let (src, dst) = match parama.next(ty, &self.tys) {
PLoc::None => (Loc::default(), Loc::default()), None => (Loc::default(), Loc::default()),
PLoc::Reg(r, _) if flags & idfl::REFERENCED == 0 => { Some(PLoc::Reg(r, _)) if flags & idfl::REFERENCED == 0 => {
(Loc::reg(r), Loc::reg(self.ci.regs.allocate())) (Loc::reg(r), Loc::reg(self.ci.regs.allocate()))
} }
PLoc::Reg(r, _) => (Loc::reg(r), Loc::stack(self.ci.stack.allocate(size))), Some(PLoc::Reg(r, _)) => (Loc::reg(r), Loc::stack(self.ci.stack.allocate(size))),
PLoc::WideReg(r, _) => (Loc::reg(r), Loc::stack(self.ci.stack.allocate(size))), Some(PLoc::WideReg(r, _)) => (Loc::reg(r), Loc::stack(self.ci.stack.allocate(size))),
PLoc::Ref(ptr, _) if flags & (idfl::MUTABLE | idfl::REFERENCED) == 0 => { Some(PLoc::Ref(ptr, _)) if flags & (idfl::MUTABLE | idfl::REFERENCED) == 0 => {
let reg = self.ci.regs.allocate(); let reg = self.ci.regs.allocate();
self.ci.emit(instrs::cp(reg.get(), ptr)); self.ci.emit(instrs::cp(reg.get(), ptr));
return Loc::reg(reg).into_derefed(); return Loc::reg(reg).into_derefed();
} }
PLoc::Ref(ptr, _) => { Some(PLoc::Ref(ptr, _)) => {
(Loc::reg(ptr).into_derefed(), Loc::stack(self.ci.stack.allocate(size))) (Loc::reg(ptr).into_derefed(), Loc::stack(self.ci.stack.allocate(size)))
} }
}; };
@ -2267,11 +2267,11 @@ impl Codegen {
fn pass_arg(&mut self, value: &Value, parama: &mut ParamAlloc) { fn pass_arg(&mut self, value: &Value, parama: &mut ParamAlloc) {
match parama.next(value.ty, &self.tys) { match parama.next(value.ty, &self.tys) {
PLoc::None => {} None => {}
PLoc::Reg(r, _) | PLoc::WideReg(r, _) => { Some(PLoc::Reg(r, _) | PLoc::WideReg(r, _)) => {
self.store_typed(&value.loc, Loc::reg(r), value.ty) self.store_typed(&value.loc, Loc::reg(r), value.ty)
} }
PLoc::Ref(ptr, _) => { Some(PLoc::Ref(ptr, _)) => {
let Loc::Rt { reg, stack, offset, .. } = &value.loc else { unreachable!() }; let Loc::Rt { reg, stack, offset, .. } = &value.loc else { unreachable!() };
self.stack_offset(ptr, reg.get(), stack.as_ref(), *offset as _); self.stack_offset(ptr, reg.get(), stack.as_ref(), *offset as _);
} }

View file

@ -267,7 +267,7 @@ mod ty {
pub const ECA: Func = Func::MAX; pub const ECA: Func = Func::MAX;
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Default)] #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Default, PartialOrd, Ord)]
pub struct Tuple(pub u32); pub struct Tuple(pub u32);
impl Tuple { impl Tuple {
@ -295,6 +295,36 @@ mod ty {
pub fn empty() -> Self { pub fn empty() -> Self {
Self(0) Self(0)
} }
pub fn args(self) -> ArgIter {
ArgIter(self.range())
}
}
pub struct ArgIter(Range<usize>);
pub enum Arg {
Type(Id),
Value(Id),
}
impl ArgIter {
pub(crate) fn next(&mut self, tys: &Types) -> Option<Arg> {
let ty = tys.ins.args[self.0.next()?];
if ty == Id::TYPE {
return Some(Arg::Type(tys.ins.args[self.0.next().unwrap()]));
}
Some(Arg::Value(ty))
}
pub(crate) fn next_value(&mut self, tys: &Types) -> Option<Id> {
loop {
match self.next(tys)? {
Arg::Type(_) => continue,
Arg::Value(id) => break Some(id),
}
}
}
} }
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
@ -411,7 +441,7 @@ mod ty {
} }
} }
pub fn loc(&self, tys: &Types) -> Loc { pub(crate) fn loc(&self, tys: &Types) -> Loc {
match self.expand() { match self.expand() {
Kind::Ptr(_) | Kind::Builtin(_) => Loc::Reg, Kind::Ptr(_) | Kind::Builtin(_) => Loc::Reg,
Kind::Struct(_) if tys.size_of(*self) == 0 => Loc::Reg, Kind::Struct(_) if tys.size_of(*self) == 0 => Loc::Reg,
@ -794,7 +824,6 @@ impl Array {
} }
enum PLoc { enum PLoc {
None,
Reg(u8, u16), Reg(u8, u16),
WideReg(u8, u16), WideReg(u8, u16),
Ref(u8, u32), Ref(u8, u32),
@ -803,13 +832,13 @@ enum PLoc {
struct ParamAlloc(Range<u8>); struct ParamAlloc(Range<u8>);
impl ParamAlloc { impl ParamAlloc {
pub fn next(&mut self, ty: ty::Id, tys: &Types) -> PLoc { pub fn next(&mut self, ty: ty::Id, tys: &Types) -> Option<PLoc> {
match tys.size_of(ty) { Some(match tys.size_of(ty) {
0 => PLoc::None, 0 => return None,
size @ 1..=8 => PLoc::Reg(self.0.next().unwrap(), size as _), size @ 1..=8 => PLoc::Reg(self.0.next().unwrap(), size as _),
size @ 9..=16 => PLoc::WideReg(self.0.next_chunk::<2>().unwrap()[0], size as _), size @ 9..=16 => PLoc::WideReg(self.0.next_chunk::<2>().unwrap()[0], size as _),
size @ 17.. => PLoc::Ref(self.0.next().unwrap(), size), size @ 17.. => PLoc::Ref(self.0.next().unwrap(), size),
} })
} }
} }
@ -878,6 +907,8 @@ pub struct TypeIns {
funcs: Vec<Func>, funcs: Vec<Func>,
args: Vec<ty::Id>, args: Vec<ty::Id>,
globals: Vec<Global>, globals: Vec<Global>,
// TODO: use ctx map
strings: HashMap<Vec<u8>, ty::Global>,
structs: Vec<Struct>, structs: Vec<Struct>,
fields: Vec<Field>, fields: Vec<Field>,
ptrs: Vec<Ptr>, ptrs: Vec<Ptr>,
@ -1239,12 +1270,10 @@ impl Types {
instrs::disasm(&mut sluce, &functions, output, eca_handler) instrs::disasm(&mut sluce, &functions, output, eca_handler)
} }
fn parama(&self, ret: impl Into<ty::Id>) -> (PLoc, ParamAlloc) { fn parama(&self, ret: impl Into<ty::Id>) -> (Option<PLoc>, ParamAlloc) {
let mut iter = ParamAlloc(1..12); let mut iter = ParamAlloc(1..12);
let ret = iter.next(ret.into(), self); let ret = iter.next(ret.into(), self);
if let PLoc::None = ret { iter.0.start += ret.is_none() as u8;
iter.0.start += 1;
}
(ret, iter) (ret, iter)
} }

View file

@ -11,7 +11,7 @@ use {
CtorField, Expr, ExprRef, FileId, Pos, CtorField, Expr, ExprRef, FileId, Pos,
}, },
reg, task, reg, task,
ty::{self, ArrayLen, Loc, Tuple}, ty::{self, Arg, ArrayLen, Loc, Tuple},
vc::{BitSet, Vc}, vc::{BitSet, Vc},
Comptime, Func, Global, HashMap, Offset, OffsetIter, PLoc, Reloc, Sig, SymKey, TypeParser, Comptime, Func, Global, HashMap, Offset, OffsetIter, PLoc, Reloc, Sig, SymKey, TypeParser,
TypedReloc, Types, TypedReloc, Types,
@ -587,7 +587,7 @@ impl Nodes {
Kind::BinOp { op } | Kind::UnOp { op } => { Kind::BinOp { op } | Kind::UnOp { op } => {
write!(out, "{:>4}: ", op.name()) write!(out, "{:>4}: ", op.name())
} }
Kind::Call { func, argc: _ } => { Kind::Call { func, args: _ } => {
write!(out, "call: {func} {} ", self[node].depth) write!(out, "call: {func} {} ", self[node].depth)
} }
Kind::Global { global } => write!(out, "glob: {global:<5}"), Kind::Global { global } => write!(out, "glob: {global:<5}"),
@ -1038,7 +1038,7 @@ pub enum Kind {
// [ctrl, ...args] // [ctrl, ...args]
Call { Call {
func: ty::Func, func: ty::Func,
argc: u32, args: ty::Tuple,
}, },
// [ctrl] // [ctrl]
Idk, Idk,
@ -1262,11 +1262,12 @@ impl ItemCtx {
debug_assert_eq!(self.jump_relocs.len(), 0); debug_assert_eq!(self.jump_relocs.len(), 0);
debug_assert_eq!(self.code.len(), 0); debug_assert_eq!(self.code.len(), 0);
self.call_count = 0;
self.file = file; self.file = file;
self.ret = ret; self.ret = ret;
self.task_base = task_base; self.task_base = task_base;
self.call_count = 0;
self.nodes.clear(); self.nodes.clear();
self.scope.vars.clear(); self.scope.vars.clear();
@ -1342,12 +1343,16 @@ impl ItemCtx {
}; };
let (retl, mut parama) = tys.parama(sig.ret); let (retl, mut parama) = tys.parama(sig.ret);
for (ti, &arg) in sig.args.range().zip(fuc.nodes[VOID].outputs.iter().skip(2)) { let mut typs = sig.args.args();
let ty = tys.ins.args[ti]; let mut args = fuc.nodes[VOID].outputs[2..].iter();
let (rg, size) = match parama.next(ty, tys) { while let Some(aty) = typs.next(tys) {
let Arg::Value(ty) = aty else { continue };
let Some(loc) = parama.next(ty, tys) else { continue };
let &arg = args.next().unwrap();
let (rg, size) = match loc {
PLoc::WideReg(rg, size) => (rg, size), PLoc::WideReg(rg, size) => (rg, size),
PLoc::Reg(rg, size) if ty.loc(tys) == Loc::Stack => (rg, size), PLoc::Reg(rg, size) if ty.loc(tys) == Loc::Stack => (rg, size),
PLoc::Reg(..) | PLoc::Ref(..) | PLoc::None => continue, PLoc::Reg(..) | PLoc::Ref(..) => continue,
}; };
self.emit(instrs::st(rg, reg::STACK_PTR, fuc.nodes[arg].offset as _, size)); self.emit(instrs::st(rg, reg::STACK_PTR, fuc.nodes[arg].offset as _, size));
self.emit(instrs::addi64(rg, reg::STACK_PTR, fuc.nodes[arg].offset as _)); self.emit(instrs::addi64(rg, reg::STACK_PTR, fuc.nodes[arg].offset as _));
@ -1423,15 +1428,19 @@ impl ItemCtx {
} }
Kind::Return => { Kind::Return => {
match retl { match retl {
PLoc::Reg(r, size) if sig.ret.loc(tys) == Loc::Stack => { Some(PLoc::Reg(r, size)) if sig.ret.loc(tys) == Loc::Stack => {
self.emit(instrs::ld(r, atr(allocs[0]), 0, size)) self.emit(instrs::ld(r, atr(allocs[0]), 0, size))
} }
PLoc::None | PLoc::Reg(..) => {} None | Some(PLoc::Reg(..)) => {}
PLoc::WideReg(r, size) => { Some(PLoc::WideReg(r, size)) => {
self.emit(instrs::ld(r, atr(allocs[0]), 0, size)) self.emit(instrs::ld(r, atr(allocs[0]), 0, size))
} }
PLoc::Ref(r, size) => { Some(PLoc::Ref(_, size)) => {
self.emit(instrs::bmc(atr(allocs[0]), r, size.try_into().unwrap())); self.emit(instrs::bmc(
atr(allocs[0]),
atr(allocs[1]),
size.try_into().expect("TODO: handle huge copies"),
));
} }
} }
@ -1486,26 +1495,27 @@ impl ItemCtx {
} }
} }
} }
Kind::Call { argc, func } => { Kind::Call { args, func } => {
let (ret, mut parama) = tys.parama(node.ty); let (ret, mut parama) = tys.parama(node.ty);
let has_ret = !matches!(ret, PLoc::None) as usize; let has_ret = ret.is_some() as usize;
let mut iter = allocs[has_ret..].iter(); let mut args = args.args();
for &i in node.inputs[1..][..argc as usize].iter() { let mut allocs = allocs[has_ret..].iter();
let ty = fuc.nodes[i].ty; while let Some(arg) = args.next(tys) {
let loc = parama.next(ty, tys); let Arg::Value(ty) = arg else { continue };
if let PLoc::None = loc { let Some(loc) = parama.next(ty, tys) else { continue };
continue;
} let &arg = allocs.next().unwrap();
let &arg = iter.next().unwrap();
let (rg, size) = match loc { let (rg, size) = match loc {
PLoc::Reg(rg, size) if ty.loc(tys) == Loc::Stack => (rg, size), PLoc::Reg(rg, size) if ty.loc(tys) == Loc::Stack => (rg, size),
PLoc::WideReg(rg, size) => (rg, size), PLoc::WideReg(rg, size) => (rg, size),
PLoc::None | PLoc::Ref(..) | PLoc::Reg(..) => continue, PLoc::Ref(..) | PLoc::Reg(..) => continue,
}; };
self.emit(instrs::ld(rg, atr(arg), 0, size)); self.emit(instrs::ld(rg, atr(arg), 0, size));
} }
debug_assert!(!matches!(ret, PLoc::Ref(..)) || iter.next().is_some()); debug_assert!(
!matches!(ret, Some(PLoc::Ref(..))) || allocs.next().is_some()
);
if func == ty::ECA { if func == ty::ECA {
self.emit(instrs::eca()); self.emit(instrs::eca());
@ -1517,7 +1527,7 @@ impl ItemCtx {
self.emit(instrs::jal(reg::RET_ADDR, reg::ZERO, 0)); self.emit(instrs::jal(reg::RET_ADDR, reg::ZERO, 0));
} }
if let PLoc::WideReg(r, size) = ret { if let Some(PLoc::WideReg(r, size)) = ret {
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));
} }
@ -1609,10 +1619,11 @@ impl ItemCtx {
self.nodes.graphviz(tys, files); self.nodes.graphviz(tys, files);
debug_assert!(self.code.is_empty()); debug_assert!(self.code.is_empty());
let tail = std::mem::take(&mut self.call_count) == 0;
'_open_function: { '_open_function: {
self.emit(instrs::addi64(reg::STACK_PTR, reg::STACK_PTR, 0)); self.emit(instrs::addi64(reg::STACK_PTR, reg::STACK_PTR, 0));
self.emit(instrs::st(reg::RET_ADDR, reg::STACK_PTR, 0, 0)); self.emit(instrs::st(reg::RET_ADDR + tail as u8, reg::STACK_PTR, 0, 0));
} }
let mut stack_size = 0; let mut stack_size = 0;
@ -1655,7 +1666,7 @@ impl ItemCtx {
let mut stripped_prelude_size = 0; let mut stripped_prelude_size = 0;
'_close_function: { '_close_function: {
let pushed = (saved as i64 + (core::mem::take(&mut self.call_count) != 0) as i64) * 8; let pushed = (saved as i64 + !tail as i64) * 8;
let stack = stack_size as i64; let stack = stack_size as i64;
match (pushed, stack) { match (pushed, stack) {
@ -1679,7 +1690,12 @@ impl ItemCtx {
write_reloc(&mut self.code, 3 + 8 + 3, stack, 8); write_reloc(&mut self.code, 3 + 8 + 3, stack, 8);
write_reloc(&mut self.code, 3 + 8 + 3 + 8, pushed, 2); write_reloc(&mut self.code, 3 + 8 + 3 + 8, pushed, 2);
self.emit(instrs::ld(reg::RET_ADDR, reg::STACK_PTR, stack as _, pushed as _)); self.emit(instrs::ld(
reg::RET_ADDR + tail as u8,
reg::STACK_PTR,
stack as _,
pushed as _,
));
self.emit(instrs::addi64(reg::STACK_PTR, reg::STACK_PTR, (pushed + stack) as _)); self.emit(instrs::addi64(reg::STACK_PTR, reg::STACK_PTR, (pushed + stack) as _));
} }
self.relocs.iter_mut().for_each(|r| r.reloc.offset -= stripped_prelude_size as u32); self.relocs.iter_mut().for_each(|r| r.reloc.offset -= stripped_prelude_size as u32);
@ -2013,7 +2029,7 @@ impl<'a> Codegen<'a> {
.collect(); .collect();
} }
fn store_mem(&mut self, region: Nid, value: Nid) -> Nid { fn store_mem(&mut self, region: Nid, ty: ty::Id, value: Nid) -> Nid {
if value == NEVER { if value == NEVER {
return NEVER; return NEVER;
} }
@ -2037,7 +2053,7 @@ impl<'a> Codegen<'a> {
vc.push(load); vc.push(load);
} }
} }
let store = self.ci.nodes.new_node_nop(self.tof(value), Kind::Stre, vc); let store = self.ci.nodes.new_node_nop(ty, Kind::Stre, vc);
self.ci.scope.store.set_value(store, &mut self.ci.nodes); self.ci.scope.store.set_value(store, &mut self.ci.nodes);
let opted = self.ci.nodes.late_peephole(store); let opted = self.ci.nodes.late_peephole(store);
self.ci.scope.store.set_value_remove(opted, &mut self.ci.nodes); self.ci.scope.store.set_value_remove(opted, &mut self.ci.nodes);
@ -2158,9 +2174,15 @@ impl<'a> Codegen<'a> {
let mut data = Vec::<u8>::with_capacity(literal.len()); let mut data = Vec::<u8>::with_capacity(literal.len());
crate::endoce_string(literal, &mut data, report).unwrap(); crate::endoce_string(literal, &mut data, report).unwrap();
let global = self.tys.ins.globals.len() as ty::Global;
let ty = self.tys.make_ptr(ty::Id::U8); let ty = self.tys.make_ptr(ty::Id::U8);
self.tys.ins.globals.push(Global { data, ty, ..Default::default() }); let global = match self.tys.ins.strings.entry(data.clone()) {
hash_map::Entry::Occupied(occupied_entry) => *occupied_entry.get(),
hash_map::Entry::Vacant(vacant_entry) => {
let global = self.tys.ins.globals.len() as ty::Global;
self.tys.ins.globals.push(Global { data, ty, ..Default::default() });
*vacant_entry.insert(global)
}
};
let global = self.ci.nodes.new_node(ty, Kind::Global { global }, [VOID]); let global = self.ci.nodes.new_node(ty, Kind::Global { global }, [VOID]);
Some(Value::new(global).ty(ty)) Some(Value::new(global).ty(ty))
} }
@ -2278,7 +2300,7 @@ impl<'a> Codegen<'a> {
} }
let stack = self.ci.nodes.new_node_nop(val.ty, Kind::Stck, [VOID, MEM]); let stack = self.ci.nodes.new_node_nop(val.ty, Kind::Stck, [VOID, MEM]);
self.store_mem(stack, val.id); self.store_mem(stack, val.ty, val.id);
Some(Value::new(stack).ty(self.tys.make_ptr(val.ty))) Some(Value::new(stack).ty(self.tys.make_ptr(val.ty)))
} }
@ -2308,7 +2330,7 @@ impl<'a> Codegen<'a> {
let mut right = self.expr(right)?; let mut right = self.expr(right)?;
if right.ty.loc(&self.tys) == Loc::Stack { if right.ty.loc(&self.tys) == Loc::Stack {
let stck = self.ci.nodes.new_node_nop(right.ty, Kind::Stck, [VOID, MEM]); let stck = self.ci.nodes.new_node_nop(right.ty, Kind::Stck, [VOID, MEM]);
self.store_mem(stck, right.id); self.store_mem(stck, right.ty, right.id);
right.id = stck; right.id = stck;
right.ptr = true; right.ptr = true;
} }
@ -2326,12 +2348,13 @@ impl<'a> Codegen<'a> {
if var.ptr { if var.ptr {
let val = var.value(); let val = var.value();
self.store_mem(val, value.id); let ty = var.ty;
self.store_mem(val, ty, value.id);
} else { } else {
var.set_value_remove(value.id, &mut self.ci.nodes); var.set_value_remove(value.id, &mut self.ci.nodes);
} }
} else if dest.ptr { } else if dest.ptr {
self.store_mem(dest.id, value.id); self.store_mem(dest.id, dest.ty, value.id);
} else { } else {
self.report(left.pos(), "cannot assign to this expression"); self.report(left.pos(), "cannot assign to this expression");
} }
@ -2373,7 +2396,6 @@ impl<'a> Codegen<'a> {
Some(Value::ptr(dst).ty(lhs.ty)) Some(Value::ptr(dst).ty(lhs.ty))
} }
_ => { _ => {
self.ci.nodes.unlock(lhs.id);
self.report( self.report(
left.pos(), left.pos(),
fa!("'{0} {op} {0}' is not supported", self.ty_display(lhs.ty),), fa!("'{0} {op} {0}' is not supported", self.ty_display(lhs.ty),),
@ -2422,7 +2444,7 @@ impl<'a> Codegen<'a> {
Expr::Directive { name: "sizeof", args: [ty], .. } => { Expr::Directive { name: "sizeof", args: [ty], .. } => {
let ty = self.ty(ty); let ty = self.ty(ty);
Some(self.ci.nodes.new_node_lit( Some(self.ci.nodes.new_node_lit(
ty::Id::INT, ty::Id::UINT,
Kind::CInt { value: self.tys.size_of(ty) as _ }, Kind::CInt { value: self.tys.size_of(ty) as _ },
[VOID], [VOID],
)) ))
@ -2430,7 +2452,7 @@ impl<'a> Codegen<'a> {
Expr::Directive { name: "alignof", args: [ty], .. } => { Expr::Directive { name: "alignof", args: [ty], .. } => {
let ty = self.ty(ty); let ty = self.ty(ty);
Some(self.ci.nodes.new_node_lit( Some(self.ci.nodes.new_node_lit(
ty::Id::INT, ty::Id::UINT,
Kind::CInt { value: self.tys.align_of(ty) as _ }, Kind::CInt { value: self.tys.align_of(ty) as _ },
[VOID], [VOID],
)) ))
@ -2488,14 +2510,7 @@ impl<'a> Codegen<'a> {
}; };
if self.tys.size_of(val.ty) <= self.tys.size_of(ty) { if self.tys.size_of(val.ty) <= self.tys.size_of(ty) {
self.report( return Some(val);
pos,
fa!(
"truncating '{}' into '{}' has no effect",
self.ty_display(val.ty),
self.ty_display(ty)
),
);
} }
let value = (1i64 << self.tys.size_of(val.ty)) - 1; let value = (1i64 << self.tys.size_of(val.ty)) - 1;
@ -2508,7 +2523,7 @@ impl<'a> Codegen<'a> {
let ctx = Ctx::default().with_ty(ty); let ctx = Ctx::default().with_ty(ty);
let mut val = self.raw_expr_ctx(expr, ctx)?; let mut val = self.raw_expr_ctx(expr, ctx)?;
self.strip_var(&mut val); self.strip_var(&mut val);
self.assert_ty(expr.pos(), &mut val, ty, "hited expr"); self.assert_ty(expr.pos(), &mut val, ty, "hinted expr");
Some(val) Some(val)
} }
Expr::Directive { pos, name: "eca", args } => { Expr::Directive { pos, name: "eca", args } => {
@ -2522,13 +2537,17 @@ impl<'a> Codegen<'a> {
}; };
let mut inps = Vc::from([NEVER]); let mut inps = Vc::from([NEVER]);
let arg_base = self.tys.tmp.args.len();
for arg in args { for arg in args {
let value = self.expr(arg)?; let value = self.expr(arg)?;
self.tys.tmp.args.push(value.ty);
debug_assert_ne!(self.ci.nodes[value.id].kind, Kind::Stre); debug_assert_ne!(self.ci.nodes[value.id].kind, Kind::Stre);
self.ci.nodes.lock(value.id); self.ci.nodes.lock(value.id);
inps.push(value.id); inps.push(value.id);
} }
let args = self.tys.pack_args(arg_base).expect("TODO");
for &n in inps.iter().skip(1) { for &n in inps.iter().skip(1) {
self.ci.nodes.unlock(n); self.ci.nodes.unlock(n);
} }
@ -2557,14 +2576,14 @@ impl<'a> Codegen<'a> {
} }
}; };
let argc = args.len() as u32;
inps[0] = self.ci.ctrl; 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, args }, inps);
self.store_mem(VOID, VOID); self.store_mem(VOID, ty::Id::VOID, VOID);
alt_value.or(Some(Value::new(self.ci.ctrl).ty(ty))) alt_value.or(Some(Value::new(self.ci.ctrl).ty(ty)))
} }
//Expr::Directive { name: "inline", args: [func, args @ ..], .. }
Expr::Call { func, args, .. } => { Expr::Call { func, args, .. } => {
self.ci.call_count += 1; self.ci.call_count += 1;
let ty = self.ty(func); let ty = self.ty(func);
@ -2598,14 +2617,14 @@ impl<'a> Codegen<'a> {
} }
let mut inps = Vc::from([NEVER]); let mut inps = Vc::from([NEVER]);
let mut tys = sig.args.range(); let mut tys = sig.args.args();
for (arg, carg) in args.iter().zip(cargs) { let mut cargs = cargs.iter();
let ty = self.tys.ins.args[tys.next().unwrap()]; let mut args = args.iter();
if ty == ty::Id::TYPE { while let Some(ty) = tys.next(&self.tys) {
tys.next().unwrap(); let carg = cargs.next().unwrap();
continue; let arg = args.next().unwrap();
} let Arg::Value(ty) = ty else { 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));
@ -2614,7 +2633,6 @@ impl<'a> Codegen<'a> {
inps.push(value.id); inps.push(value.id);
} }
let argc = inps.len() as u32 - 1;
for &n in inps.iter().skip(1) { for &n in inps.iter().skip(1) {
self.ci.nodes.unlock(n); self.ci.nodes.unlock(n);
} }
@ -2644,9 +2662,10 @@ impl<'a> Codegen<'a> {
}; };
inps[0] = self.ci.ctrl; 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, args: sig.args }, inps);
self.store_mem(VOID, VOID); self.store_mem(VOID, ty::Id::VOID, VOID);
alt_value.or(Some(Value::new(self.ci.ctrl).ty(sig.ret))) alt_value.or(Some(Value::new(self.ci.ctrl).ty(sig.ret)))
} }
@ -2657,7 +2676,7 @@ impl<'a> Codegen<'a> {
func.pos(), func.pos(),
fa!( fa!(
"first argument to @inline should be a function, "first argument to @inline should be a function,
but here its '{}'", but here its '{}'",
self.ty_display(ty) self.ty_display(ty)
), ),
); );
@ -2687,37 +2706,48 @@ impl<'a> Codegen<'a> {
); );
} }
let prev_var_base = let mut tys = sig.args.args();
std::mem::replace(&mut self.ci.inline_var_base, self.ci.scope.vars.len()); let mut args = args.iter();
let mut sig_args = sig.args.range(); let mut cargs = cargs.iter();
for (arg, carg) in args.iter().zip(cargs) { let var_base = self.ci.scope.vars.len();
let ty = self.tys.ins.args[sig_args.next().unwrap()]; while let Some(aty) = tys.next(&self.tys) {
if ty == ty::Id::TYPE { let arg = args.next().unwrap();
self.ci.scope.vars.push(Variable::new( let carg = cargs.next().unwrap();
carg.id, match aty {
self.tys.ins.args[sig_args.next().unwrap()], Arg::Type(id) => {
false, self.ci.scope.vars.push(Variable::new(
NEVER, carg.id,
&mut self.ci.nodes, id,
)); false,
continue; NEVER,
&mut self.ci.nodes,
));
}
Arg::Value(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!(value.id, 0);
self.assert_ty(
arg.pos(),
&mut value,
ty,
fa!("argument {}", carg.name),
);
self.ci.scope.vars.push(Variable::new(
carg.id,
ty,
value.ptr,
value.id,
&mut self.ci.nodes,
));
}
} }
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!(value.id, 0);
self.assert_ty(arg.pos(), &mut value, ty, fa!("argument {}", carg.name));
self.ci.scope.vars.push(Variable::new(
carg.id,
ty,
value.ptr,
value.id,
&mut self.ci.nodes,
));
} }
let prev_var_base =
std::mem::replace(&mut self.ci.inline_var_base, self.ci.scope.vars.len());
let prev_ret = self.ci.ret.replace(sig.ret); let prev_ret = self.ci.ret.replace(sig.ret);
let prev_inline_ret = self.ci.inline_ret.take(); let prev_inline_ret = self.ci.inline_ret.take();
let prev_file = core::mem::replace(&mut self.ci.file, file); let prev_file = core::mem::replace(&mut self.ci.file, file);
@ -2727,17 +2757,17 @@ impl<'a> Codegen<'a> {
self.report( self.report(
body.pos(), body.pos(),
"expected all paths in the fucntion to return \ "expected all paths in the fucntion to return \
or the return type to be 'void'", or the return type to be 'void'",
); );
} }
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(self.ci.inline_var_base..) { self.ci.inline_var_base = prev_var_base;
for var in self.ci.scope.vars.drain(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( core::mem::replace(&mut self.ci.inline_ret, prev_inline_ret).map(
|(v, ctrl, scope)| { |(v, ctrl, scope)| {
@ -2745,7 +2775,11 @@ impl<'a> Codegen<'a> {
self.ci.nodes.unlock(v.id); self.ci.nodes.unlock(v.id);
self.ci.scope.clear(&mut self.ci.nodes); self.ci.scope.clear(&mut self.ci.nodes);
self.ci.scope = scope; self.ci.scope = scope;
std::println!("{:?}", self.ci.nodes[ctrl]); self.ci
.scope
.vars
.drain(var_base..)
.for_each(|v| v.remove(&mut self.ci.nodes));
self.ci.ctrl = ctrl; self.ci.ctrl = ctrl;
v v
}, },
@ -2774,10 +2808,11 @@ impl<'a> Codegen<'a> {
break; break;
}; };
let value = self.expr_ctx(field, Ctx::default().with_ty(ty))?; let mut value = self.expr_ctx(field, Ctx::default().with_ty(ty))?;
_ = self.assert_ty(field.pos(), &mut value, ty, "tuple field");
let mem = self.offset(mem, offset); let mem = self.offset(mem, offset);
self.store_mem(mem, value.id); self.store_mem(mem, ty, value.id);
} }
let field_list = offs let field_list = offs
@ -2824,7 +2859,7 @@ impl<'a> Codegen<'a> {
let mut value = self.expr_ctx(field, Ctx::default().with_ty(elem))?; let mut value = self.expr_ctx(field, Ctx::default().with_ty(elem))?;
_ = self.assert_ty(field.pos(), &mut value, elem, "array value"); _ = self.assert_ty(field.pos(), &mut value, elem, "array value");
let mem = self.offset(mem, offset); let mem = self.offset(mem, offset);
self.store_mem(mem, value.id); self.store_mem(mem, elem, value.id);
} }
Some(Value::ptr(mem).ty(aty)) Some(Value::ptr(mem).ty(aty))
@ -2896,7 +2931,7 @@ impl<'a> Codegen<'a> {
let value = self.expr_ctx(&field.value, Ctx::default().with_ty(ty))?; let value = self.expr_ctx(&field.value, Ctx::default().with_ty(ty))?;
let mem = self.offset(mem, offset); let mem = self.offset(mem, offset);
self.store_mem(mem, value.id); self.store_mem(mem, ty, value.id);
} }
let field_list = self let field_list = self
@ -3146,7 +3181,7 @@ impl<'a> Codegen<'a> {
let lhs = self.load_mem(lhs, ty); let lhs = self.load_mem(lhs, ty);
let rhs = self.load_mem(rhs, ty); let rhs = self.load_mem(rhs, ty);
let res = self.ci.nodes.new_node(ty, Kind::BinOp { op }, [VOID, lhs, rhs]); let res = self.ci.nodes.new_node(ty, Kind::BinOp { op }, [VOID, lhs, rhs]);
self.store_mem(dst, res); self.store_mem(dst, ty, res);
} }
ty::Kind::Struct(is) => { ty::Kind::Struct(is) => {
if !self.struct_op(pos, op, is, dst, lhs, rhs) { if !self.struct_op(pos, op, is, dst, lhs, rhs) {
@ -3389,33 +3424,41 @@ 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))
}; };
let mut sig_args = sig.args.range(); let mut tys = sig.args.args();
for arg in args.iter() { let mut args = args.iter();
let ty = self.tys.ins.args[sig_args.next().unwrap()]; while let Some(aty) = tys.next(&self.tys) {
if ty == ty::Id::TYPE { let arg = args.next().unwrap();
self.ci.scope.vars.push(Variable::new( match aty {
arg.id, Arg::Type(ty) => {
self.tys.ins.args[sig_args.next().unwrap()], self.ci.scope.vars.push(Variable::new(
false, arg.id,
NEVER, ty,
&mut self.ci.nodes, false,
)); NEVER,
continue; &mut self.ci.nodes,
));
}
Arg::Value(ty) => {
let mut deps = Vc::from([VOID]);
if ty.loc(&self.tys) == Loc::Stack && self.tys.size_of(ty) <= 16 {
deps.push(MEM);
}
// TODO: whe we not using the deps?
let value = self.ci.nodes.new_node_nop(ty, Kind::Arg, deps);
let ptr = ty.loc(&self.tys) == Loc::Stack;
self.ci.scope.vars.push(Variable::new(
arg.id,
ty,
ptr,
value,
&mut self.ci.nodes,
));
}
} }
let mut deps = Vc::from([VOID]);
if ty.loc(&self.tys) == Loc::Stack && self.tys.size_of(ty) <= 16 {
deps.push(MEM);
}
// TODO: whe we not using the deps?
let value = self.ci.nodes.new_node_nop(ty, Kind::Arg, deps);
let ptr = ty.loc(&self.tys) == Loc::Stack;
self.ci.scope.vars.push(Variable::new(arg.id, ty, ptr, value, &mut self.ci.nodes));
} }
if self.expr(body).is_some() && sig.ret == ty::Id::VOID { if self.expr(body).is_some() && sig.ret == ty::Id::VOID {
@ -3640,7 +3683,6 @@ impl<'a> Function<'a> {
self.nodes[nid] self.nodes[nid]
); );
debug_assert_eq!(self.nodes[nid].lock_rc, 0, "{:?}", 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); 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)
} }
@ -3729,19 +3771,22 @@ impl<'a> Function<'a> {
} }
Kind::Return => { Kind::Return => {
let ops = match self.tys.parama(self.sig.ret).0 { let ops = match self.tys.parama(self.sig.ret).0 {
PLoc::None => vec![], None => vec![],
PLoc::Reg(..) if self.sig.ret.loc(self.tys) == Loc::Stack => { Some(PLoc::Reg(..)) if self.sig.ret.loc(self.tys) == Loc::Stack => {
vec![self.urg(self.nodes[node.inputs[1]].inputs[1])] vec![self.urg(self.nodes[node.inputs[1]].inputs[1])]
} }
PLoc::Reg(r, ..) => { Some(PLoc::Reg(r, ..)) => {
vec![regalloc2::Operand::reg_fixed_use( vec![regalloc2::Operand::reg_fixed_use(
self.rg(node.inputs[1]), self.rg(node.inputs[1]),
regalloc2::PReg::new(r as _, regalloc2::RegClass::Int), regalloc2::PReg::new(r as _, regalloc2::RegClass::Int),
)] )]
} }
PLoc::WideReg(..) | PLoc::Ref(..) => { Some(PLoc::WideReg(..)) => {
vec![self.urg(self.nodes[node.inputs[1]].inputs[1])] vec![self.urg(self.nodes[node.inputs[1]].inputs[1])]
} }
Some(PLoc::Ref(..)) => {
vec![self.urg(self.nodes[node.inputs[1]].inputs[1]), self.urg(MEM)]
}
}; };
self.add_instr(nid, ops); self.add_instr(nid, ops);
@ -3769,21 +3814,15 @@ impl<'a> Function<'a> {
Kind::Entry => { Kind::Entry => {
self.nodes[nid].ralloc_backref = self.add_block(nid); self.nodes[nid].ralloc_backref = self.add_block(nid);
let (_, mut parama) = self.tys.parama(self.sig.ret); let (ret, mut parama) = self.tys.parama(self.sig.ret);
let mut typs = self.sig.args.args();
let argc = self.sig.args.range().len()
- self.tys.ins.args[self.sig.args.range()]
.iter()
.filter(|&&ty| ty == ty::Id::TYPE)
.count()
* 2;
#[allow(clippy::unnecessary_to_owned)] #[allow(clippy::unnecessary_to_owned)]
for arg in self.nodes[VOID].outputs[2..][..argc].to_owned() { let mut args = self.nodes[VOID].outputs[2..].to_owned().into_iter();
let ty = self.nodes[arg].ty; while let Some(ty) = typs.next_value(self.tys) {
let arg = args.next().unwrap();
match parama.next(ty, self.tys) { match parama.next(ty, self.tys) {
PLoc::None => {} None => {}
PLoc::Reg(r, _) | PLoc::WideReg(r, _) | PLoc::Ref(r, _) => { Some(PLoc::Reg(r, _) | PLoc::WideReg(r, _) | PLoc::Ref(r, _)) => {
self.add_instr(NEVER, vec![regalloc2::Operand::reg_fixed_def( self.add_instr(NEVER, vec![regalloc2::Operand::reg_fixed_def(
self.rg(arg), self.rg(arg),
regalloc2::PReg::new(r as _, regalloc2::RegClass::Int), regalloc2::PReg::new(r as _, regalloc2::RegClass::Int),
@ -3792,6 +3831,13 @@ impl<'a> Function<'a> {
} }
} }
if let Some(PLoc::Ref(r, ..)) = ret {
self.add_instr(NEVER, vec![regalloc2::Operand::reg_fixed_def(
self.rg(MEM),
regalloc2::PReg::new(r as _, regalloc2::RegClass::Int),
)]);
}
for o in node.outputs.into_iter().rev() { for o in node.outputs.into_iter().rev() {
self.emit_node(o, nid); self.emit_node(o, nid);
} }
@ -3835,21 +3881,25 @@ impl<'a> Function<'a> {
let ops = vec![self.drg(nid), self.urg(node.inputs[1])]; let ops = vec![self.drg(nid), self.urg(node.inputs[1])];
self.add_instr(nid, ops); self.add_instr(nid, ops);
} }
Kind::Call { argc, .. } => { Kind::Call { args, .. } => {
self.nodes[nid].ralloc_backref = self.nodes[prev].ralloc_backref; self.nodes[nid].ralloc_backref = self.nodes[prev].ralloc_backref;
let mut ops = vec![]; let mut ops = vec![];
let (ret, mut parama) = self.tys.parama(node.ty); let (ret, mut parama) = self.tys.parama(node.ty);
if !matches!(ret, PLoc::None) { if ret.is_some() {
ops.push(regalloc2::Operand::reg_fixed_def( ops.push(regalloc2::Operand::reg_fixed_def(
self.rg(nid), self.rg(nid),
regalloc2::PReg::new(1, regalloc2::RegClass::Int), regalloc2::PReg::new(1, regalloc2::RegClass::Int),
)); ));
} }
for &(mut i) in node.inputs[1..][..argc as usize].iter() {
let ty = self.nodes[i].ty; let mut tys = args.args();
match parama.next(ty, self.tys) { let mut args = node.inputs[1..].iter();
PLoc::None => {} while let Some(ty) = tys.next_value(self.tys) {
let mut i = *args.next().unwrap();
let Some(loc) = parama.next(ty, self.tys) else { continue };
match loc {
PLoc::Reg(r, _) if ty.loc(self.tys) == Loc::Reg => { 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),
@ -3870,7 +3920,6 @@ 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],
@ -3887,7 +3936,7 @@ impl<'a> Function<'a> {
} }
} }
if let PLoc::Ref(r, _) = ret { if let Some(PLoc::Ref(r, _)) = ret {
ops.push(regalloc2::Operand::reg_fixed_use( ops.push(regalloc2::Operand::reg_fixed_use(
self.rg(*node.inputs.last().unwrap()), self.rg(*node.inputs.last().unwrap()),
regalloc2::PReg::new(r as _, regalloc2::RegClass::Int), regalloc2::PReg::new(r as _, regalloc2::RegClass::Int),
@ -4048,7 +4097,7 @@ impl regalloc2::Function for Function<'_> {
let node = &self.nodes[self.instrs[insn.index()].nid]; let node = &self.nodes[self.instrs[insn.index()].nid];
if matches!(node.kind, Kind::Call { .. }) { if matches!(node.kind, Kind::Call { .. }) {
let mut set = regalloc2::PRegSet::default(); let mut set = regalloc2::PRegSet::default();
let returns = !matches!(self.tys.parama(node.ty).0, PLoc::None); let returns = self.tys.parama(node.ty).0.is_some();
for i in 1 + returns as usize..13 { for i in 1 + returns as usize..13 {
set.add(regalloc2::PReg::new(i, regalloc2::RegClass::Int)); set.add(regalloc2::PReg::new(i, regalloc2::RegClass::Int));
} }
@ -4323,7 +4372,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

@ -1,31 +1,31 @@
main: main:
ADDI64 r254, r254, -152d ADDI64 r254, r254, -64d
ST r31, r254, 56a, 96h ST r31, r254, 56a, 8h
LI64 r32, 4d LI64 r9, 4d
LI64 r33, 1d LI64 r7, 1d
LI64 r34, 2d LI64 r6, 2d
LI64 r35, 3d LI64 r10, 3d
LI64 r36, 1d LI64 r8, 1d
LI64 r37, 0d LI64 r11, 0d
ADDI64 r2, r254, 0d ADDI64 r2, r254, 0d
ADDI64 r38, r254, 24d ADDI64 r3, r254, 24d
ADDI64 r39, r254, 48d ADDI64 r4, r254, 48d
ADDI64 r40, r254, 52d ADDI64 r12, r254, 52d
ST r37, r254, 52a, 1h ST r11, r254, 52a, 1h
ST r37, r254, 53a, 1h ST r11, r254, 53a, 1h
ST r35, r254, 54a, 1h ST r10, r254, 54a, 1h
ST r33, r254, 55a, 1h ST r7, r254, 55a, 1h
BMC r40, r39, 4h BMC r12, r4, 4h
ST r36, r254, 24a, 8h ST r8, r254, 24a, 8h
ST r34, r254, 32a, 8h ST r6, r254, 32a, 8h
ST r32, r254, 40a, 8h ST r9, r254, 40a, 8h
BMC r38, r2, 24h BMC r3, r2, 24h
JAL r31, r0, :pass JAL r31, r0, :pass
LD r41, r254, 51a, 1h LD r8, r254, 51a, 1h
ANDI r42, r41, 255d ANDI r10, r8, 255d
ADD64 r1, r1, r42 ADD64 r1, r1, r10
LD r31, r254, 56a, 96h LD r31, r254, 56a, 8h
ADDI64 r254, r254, 152d ADDI64 r254, r254, 64d
JALA r0, r31, 0a JALA r0, r31, 0a
pass: pass:
LD r3, r2, 8a, 8h LD r3, r2, 8a, 8h

View file

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

View file

@ -2,20 +2,20 @@ cond:
LI64 r1, 0d LI64 r1, 0d
JALA r0, r31, 0a JALA r0, r31, 0a
main: main:
ADDI64 r254, r254, -32d ADDI64 r254, r254, -16d
ST r31, r254, 8a, 24h ST r31, r254, 8a, 8h
JAL r31, r0, :cond JAL r31, r0, :cond
LI64 r32, 0d LI64 r6, 0d
CP r33, r32 CP r8, r6
JNE r1, r33, :0 JNE r1, r8, :0
CP r32, r33 CP r6, r8
CP r1, r32 CP r1, r6
JMP :1 JMP :1
0: LI64 r1, 2d 0: LI64 r1, 2d
1: ADDI64 r33, r254, 0d 1: ADDI64 r8, r254, 0d
ST r1, r254, 0a, 8h ST r1, r254, 0a, 8h
LD r31, r254, 8a, 24h LD r31, r254, 8a, 8h
ADDI64 r254, r254, 32d ADDI64 r254, r254, 16d
JALA r0, r31, 0a JALA r0, r31, 0a
code size: 158 code size: 158
ret: 0 ret: 0

View file

@ -16,56 +16,56 @@ continue_and_state_change:
3: JMP :6 3: JMP :6
5: JALA r0, r31, 0a 5: JALA r0, r31, 0a
main: main:
ADDI64 r254, r254, -80d ADDI64 r254, r254, -64d
ST r31, r254, 0a, 80h ST r31, r254, 0a, 64h
LI64 r32, 0d LI64 r32, 0d
CP r2, r32 CP r2, r32
JAL r31, r0, :multiple_breaks JAL r31, r0, :multiple_breaks
CP r33, r1 CP r3, r1
LI64 r1, 3d LI64 r1, 3d
LI64 r34, 1d LI64 r6, 1d
JEQ r33, r1, :0 JEQ r3, r1, :0
CP r1, r34 CP r1, r6
JMP :1 JMP :1
0: CP r35, r1 0: CP r33, r6
CP r36, r34 CP r34, r1
LI64 r37, 4d LI64 r35, 4d
CP r2, r37 CP r2, r35
JAL r31, r0, :multiple_breaks JAL r31, r0, :multiple_breaks
CP r38, r37 CP r36, r35
LI64 r39, 10d LI64 r37, 10d
JEQ r1, r39, :2 JEQ r1, r37, :2
LI64 r1, 2d LI64 r1, 2d
JMP :1 JMP :1
2: CP r2, r32 2: CP r2, r32
JAL r31, r0, :state_change_in_break JAL r31, r0, :state_change_in_break
JEQ r1, r32, :3 JEQ r1, r32, :3
CP r1, r35 CP r1, r34
JMP :1 JMP :1
3: CP r2, r38 3: CP r2, r36
JAL r31, r0, :state_change_in_break JAL r31, r0, :state_change_in_break
JEQ r1, r39, :4 JEQ r1, r37, :4
CP r1, r38 CP r1, r36
JMP :1 JMP :1
4: CP r2, r39 4: CP r2, r37
JAL r31, r0, :continue_and_state_change JAL r31, r0, :continue_and_state_change
JEQ r1, r39, :5 JEQ r1, r37, :5
LI64 r1, 5d LI64 r1, 5d
JMP :1 JMP :1
5: CP r2, r35 5: CP r2, r34
JAL r31, r0, :continue_and_state_change JAL r31, r0, :continue_and_state_change
JEQ r1, r32, :6 JEQ r1, r32, :6
LI64 r1, 6d LI64 r1, 6d
JMP :1 JMP :1
6: CP r1, r32 6: CP r1, r32
CP r40, r36 CP r38, r33
8: JNE r1, r40, :7 8: JNE r1, r38, :7
JMP :7 JMP :7
7: CP r2, r32 7: CP r2, r32
JAL r31, r0, :continue_and_state_change JAL r31, r0, :continue_and_state_change
JMP :8 JMP :8
1: LD r31, r254, 0a, 80h 1: LD r31, r254, 0a, 64h
ADDI64 r254, r254, 80d ADDI64 r254, r254, 64d
JALA r0, r31, 0a JALA r0, r31, 0a
multiple_breaks: multiple_breaks:
LI64 r6, 3d LI64 r6, 3d

View file

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

View file

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

View file

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

View file

@ -1,130 +1,18 @@
deinit: test.hb:19:27: 'int * uint' is not supported
ADDI64 r254, r254, -64d free(@bitcast(vec.data), vec.cap * @sizeof(Elem), @alignof(Elem));
ST r31, r254, 24a, 40h ^
LI64 r4, 8d test.hb:19:52: expected argument align to be of type int, got uint
LD r32, r2, 16a, 8h free(@bitcast(vec.data), vec.cap * @sizeof(Elem), @alignof(Elem));
CP r33, r2 ^
MUL64 r3, r32, r4 test.hb:32:43: 'int * uint' is not supported
CP r34, r33 new_alloc := @as(^Elem, @bitcast(malloc(vec.cap * @sizeof(Elem), @alignof(Elem))))
LD r2, r34, 0a, 8h ^
JAL r31, r0, :free test.hb:32:68: expected argument align to be of type int, got uint
ADDI64 r35, r254, 0d new_alloc := @as(^Elem, @bitcast(malloc(vec.cap * @sizeof(Elem), @alignof(Elem))))
CP r1, r35 ^
JAL r31, r0, :new test.hb:46:29: 'int * uint' is not supported
CP r2, r33 free(@bitcast(vec.data), vec.len * @sizeof(Elem), @alignof(Elem))
BMC r35, r2, 24h ^
LD r31, r254, 24a, 40h test.hb:46:54: expected argument align to be of type int, got uint
ADDI64 r254, r254, 64d free(@bitcast(vec.data), vec.len * @sizeof(Elem), @alignof(Elem))
JALA r0, r31, 0a ^
free:
CP r10, r2
LRA r7, r0, :FREE_SYS_CALL
LD r2, r7, 0a, 8h
CP r5, r4
CP r4, r3
CP r3, r10
ECA
JALA r0, r31, 0a
main:
ADDI64 r254, r254, -88d
ST r31, r254, 48a, 40h
ADDI64 r32, r254, 24d
CP r1, r32
JAL r31, r0, :new
LI64 r3, 69d
ADDI64 r33, r254, 0d
BMC r32, r33, 24h
CP r2, r33
JAL r31, r0, :push
LD r34, r254, 0a, 8h
LD r35, r34, 0a, 8h
CP r2, r33
JAL r31, r0, :deinit
CP r1, r35
LD r31, r254, 48a, 40h
ADDI64 r254, r254, 88d
JALA r0, r31, 0a
malloc:
CP r9, r2
LRA r5, r0, :MALLOC_SYS_CALL
LD r2, r5, 0a, 8h
CP r4, r3
CP r3, r9
ECA
JALA r0, r31, 0a
new:
ADDI64 r254, r254, -24d
LI64 r2, 0d
ADDI64 r3, r254, 0d
ST r2, r254, 0a, 8h
ST r2, r254, 8a, 8h
ST r2, r254, 16a, 8h
BMC r3, r1, 24h
ADDI64 r254, r254, 24d
JALA r0, r31, 0a
push:
ADDI64 r254, r254, -184d
ST r31, r254, 0a, 184h
CP r32, r3
LI64 r33, 1d
LI64 r34, 8d
LD r35, r2, 16a, 8h
LD r36, r2, 8a, 8h
CP r37, r2
JNE r35, r36, :0
LI64 r38, 0d
JNE r35, r38, :1
CP r39, r33
JMP :2
1: MULI64 r39, r35, 2d
2: MUL64 r2, r39, r34
ST r39, r37, 16a, 8h
CP r3, r34
JAL r31, r0, :malloc
JNE r1, r38, :3
CP r1, r38
JMP :4
3: CP r40, r37
CP r41, r1
CP r1, r38
LD r42, r40, 8a, 8h
MUL64 r43, r42, r34
LD r44, r40, 0a, 8h
ADD64 r45, r44, r43
CP r46, r41
9: JNE r45, r44, :5
LD r46, r40, 8a, 8h
JEQ r46, r1, :6
LD r2, r40, 0a, 8h
MUL64 r3, r46, r34
CP r4, r34
JAL r31, r0, :free
CP r38, r41
JMP :7
6: CP r38, r41
7: ST r38, r40, 0a, 8h
JMP :8
5: CP r38, r41
ADDI64 r47, r44, 8d
LD r48, r44, 0a, 8h
ADDI64 r49, r46, 8d
ST r48, r46, 0a, 8h
CP r44, r47
CP r46, r49
JMP :9
0: CP r40, r37
8: LD r50, r40, 8a, 8h
MUL64 r51, r50, r34
LD r38, r40, 0a, 8h
ADD64 r1, r38, r51
CP r3, r32
ST r3, r1, 0a, 8h
LD r52, r40, 8a, 8h
ADD64 r53, r52, r33
ST r53, r40, 8a, 8h
4: LD r31, r254, 0a, 184h
ADDI64 r254, r254, 184d
JALA r0, r31, 0a
code size: 963
ret: 69
status: Ok(())

View file

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

View file

@ -1,98 +1,55 @@
example:
ADDI64 r254, r254, -8d
ST r31, r254, 0a, 8h
LI64 r3, 768d
LI64 r2, 0d
JAL r31, r0, :integer
LD r31, r254, 0a, 8h
ADDI64 r254, r254, 8d
JALA r0, r31, 0a
integer:
LI64 r6, 0d
LI64 r1, 4d
JNE r3, r6, :0
SUB64 r10, r3, r2
ADDI64 r12, r10, 1d
DIRS64 r0, r3, r1, r12
ADD64 r1, r3, r2
JMP :0
0: JALA r0, r31, 0a
line:
ADDI64 r254, r254, -48d
ST r2, r254, 32a, 16h
ADDI64 r2, r254, 32d
ST r4, r254, 16a, 16h
ADDI64 r4, r254, 16d
ST r6, r254, 0a, 16h
ADDI64 r6, r254, 0d
LD r9, r4, 0a, 8h
LD r11, r2, 0a, 8h
JGTS r11, r9, :0
JMP :0
0: ADDI64 r254, r254, 48d
JALA r0, r31, 0a
main: main:
ADDI64 r254, r254, -184d ADDI64 r254, r254, -16d
ST r31, r254, 96a, 88h ST r31, r254, 0a, 16h
LI64 r32, 10d JAL r31, r0, :scalar_values
LI64 r33, 0d LI64 r3, 0d
ADDI64 r34, r254, 48d CP r8, r3
ADDI64 r35, r254, 64d JEQ r1, r8, :0
ADDI64 r36, r254, 80d LI64 r1, 1d
LD r37, r254, 96a, 0h
ST r33, r254, 80a, 8h
ST r33, r254, 88a, 8h
ST r33, r254, 64a, 8h
ST r33, r254, 72a, 8h
ST r33, r254, 48a, 8h
ST r33, r254, 56a, 8h
CP r8, r32
LD r2, r36, 0a, 16h
LD r4, r35, 0a, 16h
LD r6, r34, 0a, 16h
JAL r31, r0, :line
ADDI64 r38, r254, 0d
ADDI64 r39, r254, 16d
ADDI64 r40, r254, 32d
LD r41, r254, 48a, 0h
ST r33, r254, 32a, 8h
ST r33, r254, 40a, 8h
ST r33, r254, 16a, 8h
ST r33, r254, 24a, 8h
ST r33, r254, 0a, 8h
ST r33, r254, 8a, 8h
CP r8, r32
LD r2, r40, 0a, 16h
LD r4, r39, 0a, 16h
LD r6, r38, 0a, 16h
JAL r31, r0, :rect_line
JAL r31, r0, :example
CP r1, r33
LD r31, r254, 96a, 88h
ADDI64 r254, r254, 184d
JALA r0, r31, 0a
rect_line:
ADDI64 r254, r254, -48d
ST r2, r254, 32a, 16h
ADDI64 r2, r254, 32d
ST r4, r254, 16a, 16h
ADDI64 r4, r254, 16d
ST r6, r254, 0a, 16h
ADDI64 r6, r254, 0d
LI64 r10, 0d
LD r12, r2, 8a, 8h
LD r4, r4, 0a, 8h
ADD64 r6, r4, r12
3: JNE r10, r8, :0
JMP :1 JMP :1
0: CP r9, r12 0: CP r32, r8
4: JNE r6, r9, :2 JAL r31, r0, :structs
ADDI64 r10, r10, 1d CP r3, r32
JMP :3 JEQ r1, r3, :2
2: ADDI64 r9, r9, 1d JAL r31, r0, :structs
JMP :4 JMP :1
1: ADDI64 r254, r254, 48d 2: CP r1, r3
CP r32, r3
1: LD r31, r254, 0a, 16h
ADDI64 r254, r254, 16d
JALA r0, r31, 0a JALA r0, r31, 0a
code size: 930 scalar_values:
LI64 r1, 0d
JALA r0, r31, 0a
structs:
ADDI64 r254, r254, -64d
LI64 r9, 5d
LI64 r7, 20d
LI64 r4, 0d
ADDI64 r12, r254, 0d
ADDI64 r1, r254, 8d
ADDI64 r10, r254, 24d
ADDI64 r10, r254, 32d
ADDI64 r11, r254, 40d
ADDI64 r2, r254, 56d
ST r4, r254, 56a, 8h
ST r7, r254, 24a, 8h
ST r9, r254, 0a, 8h
BMC r12, r1, 8h
ST r9, r254, 16a, 8h
LD r1, r254, 8a, 8h
LD r2, r254, 24a, 8h
ADD64 r5, r1, r2
SUB64 r5, r5, r9
ST r5, r254, 32a, 8h
BMC r10, r11, 8h
ST r7, r254, 48a, 8h
LD r12, r254, 40a, 8h
LD r1, r254, 56a, 8h
ADD64 r4, r12, r1
SUB64 r1, r4, r7
ADDI64 r254, r254, 64d
JALA r0, r31, 0a
code size: 449
ret: 0 ret: 0
status: Ok(()) status: Ok(())

View file

@ -1,6 +1,6 @@
integer_range: integer_range:
ADDI64 r254, r254, -16d ADDI64 r254, r254, -16d
ST r31, r254, 0a, 16h ST r32, r254, 0a, 16h
CP r32, r2 CP r32, r2
CP r33, r3 CP r33, r3
LI64 r3, 4d LI64 r3, 4d
@ -12,7 +12,7 @@ integer_range:
ADDI64 r3, r11, 1d ADDI64 r3, r11, 1d
DIRU64 r0, r3, r1, r3 DIRU64 r0, r3, r1, r3
ADD64 r1, r3, r2 ADD64 r1, r3, r2
LD r31, r254, 0a, 16h LD r32, r254, 0a, 16h
ADDI64 r254, r254, 16d ADDI64 r254, r254, 16d
JALA r0, r31, 0a JALA r0, r31, 0a
main: main:

View file

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

View file

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

View file

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

View file

@ -1,6 +1,6 @@
main: main:
ADDI64 r254, r254, -440d ADDI64 r254, r254, -440d
ST r31, r254, 352a, 88h ST r32, r254, 352a, 88h
LI64 r4, 4d LI64 r4, 4d
LI64 r9, 1d LI64 r9, 1d
LI64 r7, 3d LI64 r7, 3d
@ -137,7 +137,7 @@ main:
LD r3, r254, 8a, 8h LD r3, r254, 8a, 8h
LD r4, r254, 0a, 8h LD r4, r254, 0a, 8h
ADD64 r1, r3, r4 ADD64 r1, r3, r4
1: LD r31, r254, 352a, 88h 1: LD r32, r254, 352a, 88h
ADDI64 r254, r254, 440d ADDI64 r254, r254, 440d
JALA r0, r31, 0a JALA r0, r31, 0a
code size: 1460 code size: 1460

View file

@ -4,14 +4,15 @@ fib:
CP r32, r2 CP r32, r2
LI64 r33, 2d LI64 r33, 2d
JLTS r2, r33, :0 JLTS r2, r33, :0
CP r34, r32 CP r6, r32
ADDI64 r2, r34, -1d ADDI64 r2, r6, -1d
JAL r31, r0, :fib JAL r31, r0, :fib
CP r2, r32 CP r2, r32
CP r34, r1 CP r34, r1
SUB64 r2, r2, r33 SUB64 r2, r2, r33
JAL r31, r0, :fib JAL r31, r0, :fib
ADD64 r1, r1, r34 CP r6, r34
ADD64 r1, r1, r6
JMP :1 JMP :1
0: CP r1, r32 0: CP r1, r32
1: LD r31, r254, 0a, 32h 1: LD r31, r254, 0a, 32h
@ -31,25 +32,26 @@ fib_iter:
JMP :2 JMP :2
1: JALA r0, r31, 0a 1: JALA r0, r31, 0a
main: main:
ADDI64 r254, r254, -60d ADDI64 r254, r254, -20d
ST r31, r254, 4a, 56h ST r31, r254, 4a, 16h
LI64 r32, 10d LI64 r2, 10d
ADDI64 r33, r254, 0d ADDI64 r4, r254, 0d
ADDI64 r34, r254, 2d ADDI64 r3, r254, 2d
ST r32, r254, 2a, 1h ST r2, r254, 2a, 1h
ST r32, r254, 3a, 1h ST r2, r254, 3a, 1h
BMC r34, r33, 2h BMC r3, r4, 2h
LD r35, r254, 0a, 1h LD r10, r254, 0a, 1h
ANDI r2, r35, 255d ANDI r2, r10, 255d
JAL r31, r0, :fib JAL r31, r0, :fib
CP r36, r1 CP r32, r1
LD r37, r254, 1a, 1h LD r4, r254, 1a, 1h
ANDI r2, r37, 255d ANDI r2, r4, 255d
JAL r31, r0, :fib_iter JAL r31, r0, :fib_iter
SUB64 r1, r36, r1 CP r11, r32
LD r31, r254, 4a, 56h SUB64 r1, r11, r1
ADDI64 r254, r254, 60d LD r31, r254, 4a, 16h
ADDI64 r254, r254, 20d
JALA r0, r31, 0a JALA r0, r31, 0a
code size: 392 code size: 398
ret: 0 ret: 0
status: Ok(()) status: Ok(())

View file

@ -10,28 +10,28 @@ foo:
ADDI64 r254, r254, 16d ADDI64 r254, r254, 16d
JALA r0, r31, 0a JALA r0, r31, 0a
main: main:
ADDI64 r254, r254, -144d ADDI64 r254, r254, -72d
ST r31, r254, 48a, 96h ST r31, r254, 48a, 24h
ADDI64 r32, r254, 32d ADDI64 r2, r254, 32d
JAL r31, r0, :foo JAL r31, r0, :foo
ST r1, r254, 32a, 16h ST r1, r254, 32a, 16h
ADDI64 r33, r254, 16d ADDI64 r8, r254, 16d
LD r34, r254, 32a, 8h LD r32, r254, 32a, 8h
JAL r31, r0, :foo JAL r31, r0, :foo
ST r1, r254, 16a, 16h ST r1, r254, 16a, 16h
ADDI64 r35, r254, 0d ADDI64 r3, r254, 0d
LD r36, r254, 24a, 4h LD r33, r254, 24a, 4h
JAL r31, r0, :foo JAL r31, r0, :foo
ST r1, r254, 0a, 16h ST r1, r254, 0a, 16h
LI64 r37, 7d LI64 r9, 7d
LD r38, r254, 12a, 4h LD r10, r254, 12a, 4h
ANDI r39, r38, 4294967295d ANDI r11, r10, 4294967295d
ANDI r40, r36, 4294967295d ANDI r8, r33, 4294967295d
ADD64 r41, r34, r40 ADD64 r12, r32, r8
ADD64 r42, r41, r39 ADD64 r3, r12, r11
SUB64 r1, r37, r42 SUB64 r1, r9, r3
LD r31, r254, 48a, 96h LD r31, r254, 48a, 24h
ADDI64 r254, r254, 144d ADDI64 r254, r254, 72d
JALA r0, r31, 0a JALA r0, r31, 0a
code size: 359 code size: 359
ret: 0 ret: 0

View file

@ -1,38 +1,39 @@
main: main:
ADDI64 r254, r254, -176d ADDI64 r254, r254, -96d
ST r31, r254, 112a, 64h ST r31, r254, 72a, 24h
LI64 r32, 3d LI64 r32, 3d
LI64 r33, 1d LI64 r3, 4d
LI64 r34, 4d ADDI64 r33, r254, 16d
ADDI64 r35, r254, 24d ADDI64 r8, r254, 32d
ADDI64 r36, r254, 48d ADDI64 r9, r254, 48d
ADDI64 r37, r254, 72d ST r3, r254, 48a, 8h
ST r34, r254, 72a, 8h ADDI64 r7, r254, 56d
ST r33, r254, 80a, 8h BMC r9, r7, 8h
ADDI64 r2, r254, 88d ST r32, r254, 64a, 8h
BMC r37, r2, 16h BMC r7, r8, 16h
ST r32, r254, 104a, 8h LD r3, r7, 0a, 16h
BMC r2, r36, 24h
CP r1, r35
JAL r31, r0, :odher_pass JAL r31, r0, :odher_pass
ST r1, r254, 16a, 16h
ADDI64 r2, r254, 0d ADDI64 r2, r254, 0d
BMC r35, r2, 24h BMC r33, r2, 16h
LD r38, r254, 16a, 8h LD r10, r254, 8a, 8h
JNE r38, r32, :0 JNE r10, 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, 112a, 64h 1: LD r31, r254, 72a, 24h
ADDI64 r254, r254, 176d ADDI64 r254, r254, 96d
JALA r0, r31, 0a JALA r0, r31, 0a
odher_pass: odher_pass:
BMC r2, r1, 24h ADDI64 r254, r254, -16d
ST r3, r254, 0a, 16h
ADDI64 r3, r254, 0d
LD r1, r3, 0a, 16h
ADDI64 r254, r254, 16d
JALA r0, r31, 0a JALA r0, r31, 0a
pass: pass:
LD r4, r2, 8a, 8h LD r1, r2, 0a, 8h
LD r5, r2, 0a, 8h
SUB64 r1, r5, r4
JALA r0, r31, 0a JALA r0, r31, 0a
code size: 313 code size: 350
ret: 3 ret: 4
status: Ok(()) status: Ok(())

View file

@ -1,48 +1,48 @@
main: main:
ADDI64 r254, r254, -80d ADDI64 r254, r254, -48d
ST r31, r254, 32a, 48h ST r31, r254, 32a, 16h
LI64 r4, 0d LI64 r4, 0d
ADDI64 r32, r254, 16d ADDI64 r32, r254, 16d
CP r3, r4 CP r3, r4
JAL r31, r0, :maina JAL r31, r0, :maina
ST r1, r254, 16a, 16h ST r1, r254, 16a, 16h
ADDI64 r33, r254, 0d ADDI64 r7, r254, 0d
BMC r32, r33, 16h BMC r32, r7, 16h
LD r34, r254, 12a, 1h LD r1, r254, 12a, 1h
LD r35, r254, 3a, 1h LD r11, r254, 3a, 1h
SUB8 r36, r35, r34 SUB8 r2, r11, r1
ANDI r1, r36, 255d ANDI r1, r2, 255d
LD r31, r254, 32a, 48h LD r31, r254, 32a, 16h
ADDI64 r254, r254, 80d ADDI64 r254, r254, 48d
JALA r0, r31, 0a JALA r0, r31, 0a
maina: maina:
ADDI64 r254, r254, -120d ADDI64 r254, r254, -56d
ST r31, r254, 40a, 80h ST r31, r254, 40a, 16h
ADDI64 r32, r254, 36d ADDI64 r32, r254, 36d
JAL r31, r0, :small_struct JAL r31, r0, :small_struct
LI64 r33, 1d LI64 r2, 1d
LI64 r34, 3d LI64 r3, 3d
LI64 r35, 0d LI64 r1, 0d
ADDI64 r36, r254, 0d ADDI64 r6, r254, 0d
ADDI64 r37, r36, 8d ADDI64 r8, r6, 8d
ADDI64 r38, r254, 16d ADDI64 r7, r254, 16d
ADDI64 r39, r254, 24d ADDI64 r4, r254, 24d
ADDI64 r40, r254, 32d ADDI64 r5, r254, 32d
BMC r32, r40, 4h BMC r32, r5, 4h
ST r35, r254, 24a, 1h ST r1, r254, 24a, 1h
ST r35, r254, 25a, 1h ST r1, r254, 25a, 1h
ST r35, r254, 26a, 1h ST r1, r254, 26a, 1h
ST r34, r254, 27a, 1h ST r3, r254, 27a, 1h
ST r33, r254, 28a, 1h ST r2, r254, 28a, 1h
ST r35, r254, 29a, 1h ST r1, r254, 29a, 1h
ST r35, r254, 30a, 1h ST r1, r254, 30a, 1h
ST r35, r254, 31a, 1h ST r1, r254, 31a, 1h
BMC r39, r38, 8h BMC r4, r7, 8h
BMC r39, r36, 8h BMC r4, r6, 8h
BMC r38, r37, 8h BMC r7, r8, 8h
LD r1, r36, 0a, 16h LD r1, r6, 0a, 16h
LD r31, r254, 40a, 80h LD r31, r254, 40a, 16h
ADDI64 r254, r254, 120d ADDI64 r254, r254, 56d
JALA r0, r31, 0a JALA r0, r31, 0a
small_struct: small_struct:
ADDI64 r254, r254, -4d ADDI64 r254, r254, -4d