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
a: int,
b: int,
}
Ty2 := struct {
@ -174,7 +173,7 @@ main := fn(): int {
return 9001
}
finst := Ty2.{ty: .{a: 4, b: 1}, c: 3}
finst := Ty2.{ty: .{a: 4}, c: 3}
inst := odher_pass(finst)
if inst.c == 3 {
return pass(&inst.ty)
@ -183,7 +182,7 @@ main := fn(): int {
}
pass := fn(t: ^Ty): int {
return t.a - t.b
return t.a
}
odher_pass := fn(t: Ty2): Ty2 {
@ -701,93 +700,29 @@ min := fn(a: int, b: int): int {
#### inline_test
```hb
Point := struct {x: int, y: int}
Buffer := struct {}
Transform := Point
ColorBGRA := Point
fna := fn(a: int, b: int, c: int): int return a + b + c
line := fn(buffer: Buffer, p0: Point, p1: Point, color: ColorBGRA, thickness: int): void {
if true {
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
scalar_values := fn(): int {
return @inline(fna, 1, @inline(fna, 2, 3, 4), -10)
}
line_low := fn(buffer: Buffer, p0: Point, p1: Point, color: ColorBGRA): void {
return
A := struct {a: int}
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 {
return
}
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
structs := fn(): int {
return @inline(mangle, .(0), .(.(@inline(mangle, .(20), .(.(5), 5))), 20))
}
main := fn(): int {
line(.(), .(0, 0), .(0, 0), .(0, 0), 10)
rect_line(.(), .(0, 0), .(0, 0), .(0, 0), 10)
example()
if scalar_values() != 0 return 1
if structs() != 0 return structs()
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

View file

@ -277,7 +277,7 @@ impl Value {
}
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 {
@ -2147,7 +2147,7 @@ impl Codegen {
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();
self.ci.emit(instrs::cp(reg.get(), 1));
self.ci.ret_reg = reg;
@ -2180,18 +2180,18 @@ impl Codegen {
return Loc::default();
}
let (src, dst) = match parama.next(ty, &self.tys) {
PLoc::None => (Loc::default(), Loc::default()),
PLoc::Reg(r, _) if flags & idfl::REFERENCED == 0 => {
None => (Loc::default(), Loc::default()),
Some(PLoc::Reg(r, _)) if flags & idfl::REFERENCED == 0 => {
(Loc::reg(r), Loc::reg(self.ci.regs.allocate()))
}
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))),
PLoc::Ref(ptr, _) if flags & (idfl::MUTABLE | idfl::REFERENCED) == 0 => {
Some(PLoc::Reg(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))),
Some(PLoc::Ref(ptr, _)) if flags & (idfl::MUTABLE | idfl::REFERENCED) == 0 => {
let reg = self.ci.regs.allocate();
self.ci.emit(instrs::cp(reg.get(), ptr));
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)))
}
};
@ -2267,11 +2267,11 @@ impl Codegen {
fn pass_arg(&mut self, value: &Value, parama: &mut ParamAlloc) {
match parama.next(value.ty, &self.tys) {
PLoc::None => {}
PLoc::Reg(r, _) | PLoc::WideReg(r, _) => {
None => {}
Some(PLoc::Reg(r, _) | PLoc::WideReg(r, _)) => {
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!() };
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;
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Default)]
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Default, PartialOrd, Ord)]
pub struct Tuple(pub u32);
impl Tuple {
@ -295,6 +295,36 @@ mod ty {
pub fn empty() -> Self {
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)]
@ -411,7 +441,7 @@ mod ty {
}
}
pub fn loc(&self, tys: &Types) -> Loc {
pub(crate) fn loc(&self, tys: &Types) -> Loc {
match self.expand() {
Kind::Ptr(_) | Kind::Builtin(_) => Loc::Reg,
Kind::Struct(_) if tys.size_of(*self) == 0 => Loc::Reg,
@ -794,7 +824,6 @@ impl Array {
}
enum PLoc {
None,
Reg(u8, u16),
WideReg(u8, u16),
Ref(u8, u32),
@ -803,13 +832,13 @@ enum PLoc {
struct ParamAlloc(Range<u8>);
impl ParamAlloc {
pub fn next(&mut self, ty: ty::Id, tys: &Types) -> PLoc {
match tys.size_of(ty) {
0 => PLoc::None,
pub fn next(&mut self, ty: ty::Id, tys: &Types) -> Option<PLoc> {
Some(match tys.size_of(ty) {
0 => return None,
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 @ 17.. => PLoc::Ref(self.0.next().unwrap(), size),
}
})
}
}
@ -878,6 +907,8 @@ pub struct TypeIns {
funcs: Vec<Func>,
args: Vec<ty::Id>,
globals: Vec<Global>,
// TODO: use ctx map
strings: HashMap<Vec<u8>, ty::Global>,
structs: Vec<Struct>,
fields: Vec<Field>,
ptrs: Vec<Ptr>,
@ -1239,12 +1270,10 @@ impl Types {
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 ret = iter.next(ret.into(), self);
if let PLoc::None = ret {
iter.0.start += 1;
}
iter.0.start += ret.is_none() as u8;
(ret, iter)
}

View file

@ -11,7 +11,7 @@ use {
CtorField, Expr, ExprRef, FileId, Pos,
},
reg, task,
ty::{self, ArrayLen, Loc, Tuple},
ty::{self, Arg, ArrayLen, Loc, Tuple},
vc::{BitSet, Vc},
Comptime, Func, Global, HashMap, Offset, OffsetIter, PLoc, Reloc, Sig, SymKey, TypeParser,
TypedReloc, Types,
@ -587,7 +587,7 @@ impl Nodes {
Kind::BinOp { op } | Kind::UnOp { op } => {
write!(out, "{:>4}: ", op.name())
}
Kind::Call { func, argc: _ } => {
Kind::Call { func, args: _ } => {
write!(out, "call: {func} {} ", self[node].depth)
}
Kind::Global { global } => write!(out, "glob: {global:<5}"),
@ -1038,7 +1038,7 @@ pub enum Kind {
// [ctrl, ...args]
Call {
func: ty::Func,
argc: u32,
args: ty::Tuple,
},
// [ctrl]
Idk,
@ -1262,11 +1262,12 @@ impl ItemCtx {
debug_assert_eq!(self.jump_relocs.len(), 0);
debug_assert_eq!(self.code.len(), 0);
self.call_count = 0;
self.file = file;
self.ret = ret;
self.task_base = task_base;
self.call_count = 0;
self.nodes.clear();
self.scope.vars.clear();
@ -1342,12 +1343,16 @@ impl ItemCtx {
};
let (retl, mut parama) = tys.parama(sig.ret);
for (ti, &arg) in sig.args.range().zip(fuc.nodes[VOID].outputs.iter().skip(2)) {
let ty = tys.ins.args[ti];
let (rg, size) = match parama.next(ty, tys) {
let mut typs = sig.args.args();
let mut args = fuc.nodes[VOID].outputs[2..].iter();
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::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::addi64(rg, reg::STACK_PTR, fuc.nodes[arg].offset as _));
@ -1423,15 +1428,19 @@ impl ItemCtx {
}
Kind::Return => {
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))
}
PLoc::None | PLoc::Reg(..) => {}
PLoc::WideReg(r, size) => {
None | Some(PLoc::Reg(..)) => {}
Some(PLoc::WideReg(r, size)) => {
self.emit(instrs::ld(r, atr(allocs[0]), 0, size))
}
PLoc::Ref(r, size) => {
self.emit(instrs::bmc(atr(allocs[0]), r, size.try_into().unwrap()));
Some(PLoc::Ref(_, size)) => {
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 has_ret = !matches!(ret, PLoc::None) as usize;
let mut iter = allocs[has_ret..].iter();
for &i in node.inputs[1..][..argc as usize].iter() {
let ty = fuc.nodes[i].ty;
let loc = parama.next(ty, tys);
if let PLoc::None = loc {
continue;
}
let &arg = iter.next().unwrap();
let has_ret = ret.is_some() as usize;
let mut args = args.args();
let mut allocs = allocs[has_ret..].iter();
while let Some(arg) = args.next(tys) {
let Arg::Value(ty) = arg else { continue };
let Some(loc) = parama.next(ty, tys) else { continue };
let &arg = allocs.next().unwrap();
let (rg, size) = match loc {
PLoc::Reg(rg, size) if ty.loc(tys) == Loc::Stack => (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));
}
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 {
self.emit(instrs::eca());
@ -1517,7 +1527,7 @@ impl ItemCtx {
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;
self.emit(instrs::st(r, reg::STACK_PTR, stck as _, size));
}
@ -1609,10 +1619,11 @@ impl ItemCtx {
self.nodes.graphviz(tys, files);
debug_assert!(self.code.is_empty());
let tail = std::mem::take(&mut self.call_count) == 0;
'_open_function: {
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;
@ -1655,7 +1666,7 @@ impl ItemCtx {
let mut stripped_prelude_size = 0;
'_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;
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 + 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.relocs.iter_mut().for_each(|r| r.reloc.offset -= stripped_prelude_size as u32);
@ -2013,7 +2029,7 @@ impl<'a> Codegen<'a> {
.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 {
return NEVER;
}
@ -2037,7 +2053,7 @@ impl<'a> Codegen<'a> {
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);
let opted = self.ci.nodes.late_peephole(store);
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());
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);
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]);
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]);
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)))
}
@ -2308,7 +2330,7 @@ impl<'a> Codegen<'a> {
let mut right = self.expr(right)?;
if right.ty.loc(&self.tys) == Loc::Stack {
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.ptr = true;
}
@ -2326,12 +2348,13 @@ impl<'a> Codegen<'a> {
if var.ptr {
let val = var.value();
self.store_mem(val, value.id);
let ty = var.ty;
self.store_mem(val, ty, value.id);
} else {
var.set_value_remove(value.id, &mut self.ci.nodes);
}
} else if dest.ptr {
self.store_mem(dest.id, value.id);
self.store_mem(dest.id, dest.ty, value.id);
} else {
self.report(left.pos(), "cannot assign to this expression");
}
@ -2373,7 +2396,6 @@ impl<'a> Codegen<'a> {
Some(Value::ptr(dst).ty(lhs.ty))
}
_ => {
self.ci.nodes.unlock(lhs.id);
self.report(
left.pos(),
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], .. } => {
let ty = self.ty(ty);
Some(self.ci.nodes.new_node_lit(
ty::Id::INT,
ty::Id::UINT,
Kind::CInt { value: self.tys.size_of(ty) as _ },
[VOID],
))
@ -2430,7 +2452,7 @@ impl<'a> Codegen<'a> {
Expr::Directive { name: "alignof", args: [ty], .. } => {
let ty = self.ty(ty);
Some(self.ci.nodes.new_node_lit(
ty::Id::INT,
ty::Id::UINT,
Kind::CInt { value: self.tys.align_of(ty) as _ },
[VOID],
))
@ -2488,14 +2510,7 @@ impl<'a> Codegen<'a> {
};
if self.tys.size_of(val.ty) <= self.tys.size_of(ty) {
self.report(
pos,
fa!(
"truncating '{}' into '{}' has no effect",
self.ty_display(val.ty),
self.ty_display(ty)
),
);
return Some(val);
}
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 mut val = self.raw_expr_ctx(expr, ctx)?;
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)
}
Expr::Directive { pos, name: "eca", args } => {
@ -2522,13 +2537,17 @@ impl<'a> Codegen<'a> {
};
let mut inps = Vc::from([NEVER]);
let arg_base = self.tys.tmp.args.len();
for arg in args {
let value = self.expr(arg)?;
self.tys.tmp.args.push(value.ty);
debug_assert_ne!(self.ci.nodes[value.id].kind, Kind::Stre);
self.ci.nodes.lock(value.id);
inps.push(value.id);
}
let args = self.tys.pack_args(arg_base).expect("TODO");
for &n in inps.iter().skip(1) {
self.ci.nodes.unlock(n);
}
@ -2557,14 +2576,14 @@ impl<'a> Codegen<'a> {
}
};
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, 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)))
}
//Expr::Directive { name: "inline", args: [func, args @ ..], .. }
Expr::Call { func, args, .. } => {
self.ci.call_count += 1;
let ty = self.ty(func);
@ -2598,14 +2617,14 @@ impl<'a> Codegen<'a> {
}
let mut inps = Vc::from([NEVER]);
let mut tys = sig.args.range();
for (arg, carg) in args.iter().zip(cargs) {
let ty = self.tys.ins.args[tys.next().unwrap()];
if ty == ty::Id::TYPE {
tys.next().unwrap();
continue;
}
std::println!("{}", self.ast_display(arg));
let mut tys = sig.args.args();
let mut cargs = cargs.iter();
let mut args = args.iter();
while let Some(ty) = tys.next(&self.tys) {
let carg = cargs.next().unwrap();
let arg = args.next().unwrap();
let Arg::Value(ty) = ty else { continue };
let mut value = self.expr_ctx(arg, Ctx::default().with_ty(ty))?;
debug_assert_ne!(self.ci.nodes[value.id].kind, Kind::Stre);
self.assert_ty(arg.pos(), &mut value, ty, fa!("argument {}", carg.name));
@ -2614,7 +2633,6 @@ impl<'a> Codegen<'a> {
inps.push(value.id);
}
let argc = inps.len() as u32 - 1;
for &n in inps.iter().skip(1) {
self.ci.nodes.unlock(n);
}
@ -2644,9 +2662,10 @@ 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, 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)))
}
@ -2657,7 +2676,7 @@ impl<'a> Codegen<'a> {
func.pos(),
fa!(
"first argument to @inline should be a function,
but here its '{}'",
but here its '{}'",
self.ty_display(ty)
),
);
@ -2687,37 +2706,48 @@ impl<'a> Codegen<'a> {
);
}
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();
for (arg, carg) in args.iter().zip(cargs) {
let ty = self.tys.ins.args[sig_args.next().unwrap()];
if ty == ty::Id::TYPE {
self.ci.scope.vars.push(Variable::new(
carg.id,
self.tys.ins.args[sig_args.next().unwrap()],
false,
NEVER,
&mut self.ci.nodes,
));
continue;
let mut tys = sig.args.args();
let mut args = args.iter();
let mut cargs = cargs.iter();
let var_base = self.ci.scope.vars.len();
while let Some(aty) = tys.next(&self.tys) {
let arg = args.next().unwrap();
let carg = cargs.next().unwrap();
match aty {
Arg::Type(id) => {
self.ci.scope.vars.push(Variable::new(
carg.id,
id,
false,
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_inline_ret = self.ci.inline_ret.take();
let prev_file = core::mem::replace(&mut self.ci.file, file);
@ -2727,17 +2757,17 @@ impl<'a> Codegen<'a> {
self.report(
body.pos(),
"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.file = prev_file;
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);
}
self.ci.inline_var_base = prev_var_base;
core::mem::replace(&mut self.ci.inline_ret, prev_inline_ret).map(
|(v, ctrl, scope)| {
@ -2745,7 +2775,11 @@ impl<'a> Codegen<'a> {
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
.scope
.vars
.drain(var_base..)
.for_each(|v| v.remove(&mut self.ci.nodes));
self.ci.ctrl = ctrl;
v
},
@ -2774,10 +2808,11 @@ impl<'a> Codegen<'a> {
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);
self.store_mem(mem, value.id);
self.store_mem(mem, ty, value.id);
}
let field_list = offs
@ -2824,7 +2859,7 @@ impl<'a> Codegen<'a> {
let mut value = self.expr_ctx(field, Ctx::default().with_ty(elem))?;
_ = self.assert_ty(field.pos(), &mut value, elem, "array value");
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))
@ -2896,7 +2931,7 @@ impl<'a> Codegen<'a> {
let value = self.expr_ctx(&field.value, Ctx::default().with_ty(ty))?;
let mem = self.offset(mem, offset);
self.store_mem(mem, value.id);
self.store_mem(mem, ty, value.id);
}
let field_list = self
@ -3146,7 +3181,7 @@ impl<'a> Codegen<'a> {
let lhs = self.load_mem(lhs, ty);
let rhs = self.load_mem(rhs, ty);
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) => {
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);
log::info!("emmiting {}", self.ast_display(expr));
let &Expr::Closure { body, args, .. } = expr else {
unreachable!("{}", self.ast_display(expr))
};
let mut sig_args = sig.args.range();
for arg in args.iter() {
let ty = self.tys.ins.args[sig_args.next().unwrap()];
if ty == ty::Id::TYPE {
self.ci.scope.vars.push(Variable::new(
arg.id,
self.tys.ins.args[sig_args.next().unwrap()],
false,
NEVER,
&mut self.ci.nodes,
));
continue;
let mut tys = sig.args.args();
let mut args = args.iter();
while let Some(aty) = tys.next(&self.tys) {
let arg = args.next().unwrap();
match aty {
Arg::Type(ty) => {
self.ci.scope.vars.push(Variable::new(
arg.id,
ty,
false,
NEVER,
&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 {
@ -3640,7 +3683,6 @@ impl<'a> Function<'a> {
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)
}
@ -3729,19 +3771,22 @@ impl<'a> Function<'a> {
}
Kind::Return => {
let ops = match self.tys.parama(self.sig.ret).0 {
PLoc::None => vec![],
PLoc::Reg(..) if self.sig.ret.loc(self.tys) == Loc::Stack => {
None => vec![],
Some(PLoc::Reg(..)) if self.sig.ret.loc(self.tys) == Loc::Stack => {
vec![self.urg(self.nodes[node.inputs[1]].inputs[1])]
}
PLoc::Reg(r, ..) => {
Some(PLoc::Reg(r, ..)) => {
vec![regalloc2::Operand::reg_fixed_use(
self.rg(node.inputs[1]),
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])]
}
Some(PLoc::Ref(..)) => {
vec![self.urg(self.nodes[node.inputs[1]].inputs[1]), self.urg(MEM)]
}
};
self.add_instr(nid, ops);
@ -3769,21 +3814,15 @@ impl<'a> Function<'a> {
Kind::Entry => {
self.nodes[nid].ralloc_backref = self.add_block(nid);
let (_, mut parama) = self.tys.parama(self.sig.ret);
let argc = self.sig.args.range().len()
- self.tys.ins.args[self.sig.args.range()]
.iter()
.filter(|&&ty| ty == ty::Id::TYPE)
.count()
* 2;
let (ret, mut parama) = self.tys.parama(self.sig.ret);
let mut typs = self.sig.args.args();
#[allow(clippy::unnecessary_to_owned)]
for arg in self.nodes[VOID].outputs[2..][..argc].to_owned() {
let ty = self.nodes[arg].ty;
let mut args = self.nodes[VOID].outputs[2..].to_owned().into_iter();
while let Some(ty) = typs.next_value(self.tys) {
let arg = args.next().unwrap();
match parama.next(ty, self.tys) {
PLoc::None => {}
PLoc::Reg(r, _) | PLoc::WideReg(r, _) | PLoc::Ref(r, _) => {
None => {}
Some(PLoc::Reg(r, _) | PLoc::WideReg(r, _) | PLoc::Ref(r, _)) => {
self.add_instr(NEVER, vec![regalloc2::Operand::reg_fixed_def(
self.rg(arg),
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() {
self.emit_node(o, nid);
}
@ -3835,21 +3881,25 @@ impl<'a> Function<'a> {
let ops = vec![self.drg(nid), self.urg(node.inputs[1])];
self.add_instr(nid, ops);
}
Kind::Call { argc, .. } => {
Kind::Call { args, .. } => {
self.nodes[nid].ralloc_backref = self.nodes[prev].ralloc_backref;
let mut ops = vec![];
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(
self.rg(nid),
regalloc2::PReg::new(1, regalloc2::RegClass::Int),
));
}
for &(mut i) in node.inputs[1..][..argc as usize].iter() {
let ty = self.nodes[i].ty;
match parama.next(ty, self.tys) {
PLoc::None => {}
let mut tys = args.args();
let mut args = node.inputs[1..].iter();
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 => {
ops.push(regalloc2::Operand::reg_fixed_use(
self.rg(i),
@ -3870,7 +3920,6 @@ impl<'a> Function<'a> {
}
PLoc::Ref(r, _) => {
loop {
std::println!("{:?} {}", self.nodes[i], i);
match self.nodes[i].kind {
Kind::Stre { .. } => i = self.nodes[i].inputs[2],
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(
self.rg(*node.inputs.last().unwrap()),
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];
if matches!(node.kind, Kind::Call { .. }) {
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 {
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) {
_ = 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);
let (ref files, embeds) = crate::test_parse_files(ident, input);

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,130 +1,18 @@
deinit:
ADDI64 r254, r254, -64d
ST r31, r254, 24a, 40h
LI64 r4, 8d
LD r32, r2, 16a, 8h
CP r33, r2
MUL64 r3, r32, r4
CP r34, r33
LD r2, r34, 0a, 8h
JAL r31, r0, :free
ADDI64 r35, r254, 0d
CP r1, r35
JAL r31, r0, :new
CP r2, r33
BMC r35, r2, 24h
LD r31, r254, 24a, 40h
ADDI64 r254, r254, 64d
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(())
test.hb:19:27: 'int * uint' is not supported
free(@bitcast(vec.data), vec.cap * @sizeof(Elem), @alignof(Elem));
^
test.hb:19:52: expected argument align to be of type int, got uint
free(@bitcast(vec.data), vec.cap * @sizeof(Elem), @alignof(Elem));
^
test.hb:32:43: 'int * uint' is not supported
new_alloc := @as(^Elem, @bitcast(malloc(vec.cap * @sizeof(Elem), @alignof(Elem))))
^
test.hb:32:68: expected argument align to be of type int, got uint
new_alloc := @as(^Elem, @bitcast(malloc(vec.cap * @sizeof(Elem), @alignof(Elem))))
^
test.hb:46:29: 'int * uint' is not supported
free(@bitcast(vec.data), vec.len * @sizeof(Elem), @alignof(Elem))
^
test.hb:46:54: expected argument align to be of type int, got uint
free(@bitcast(vec.data), vec.len * @sizeof(Elem), @alignof(Elem))
^

View file

@ -1,21 +1,22 @@
fib:
ADDI64 r254, r254, -40d
ST r31, r254, 0a, 40h
ADDI64 r254, r254, -32d
ST r31, r254, 0a, 32h
LI64 r1, 1d
LI64 r32, 2d
JGTS r2, r32, :0
JMP :1
0: CP r33, r2
SUB64 r2, r33, r1
CP r34, r33
0: CP r6, r2
SUB64 r2, r6, r1
CP r33, r6
JAL r31, r0, :fib
CP r2, r34
CP r35, r1
CP r2, r33
CP r34, r1
SUB64 r2, r2, r32
JAL r31, r0, :fib
ADD64 r1, r1, r35
1: LD r31, r254, 0a, 40h
ADDI64 r254, r254, 40d
CP r8, r34
ADD64 r1, r1, r8
1: LD r31, r254, 0a, 32h
ADDI64 r254, r254, 32d
JALA r0, r31, 0a
main:
ADDI64 r254, r254, -8d
@ -25,6 +26,6 @@ main:
LD r31, r254, 0a, 8h
ADDI64 r254, r254, 8d
JALA r0, r31, 0a
code size: 211
code size: 214
ret: 55
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:
ADDI64 r254, r254, -184d
ST r31, r254, 96a, 88h
LI64 r32, 10d
LI64 r33, 0d
ADDI64 r34, r254, 48d
ADDI64 r35, r254, 64d
ADDI64 r36, r254, 80d
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
ADDI64 r254, r254, -16d
ST r31, r254, 0a, 16h
JAL r31, r0, :scalar_values
LI64 r3, 0d
CP r8, r3
JEQ r1, r8, :0
LI64 r1, 1d
JMP :1
0: CP r9, r12
4: JNE r6, r9, :2
ADDI64 r10, r10, 1d
JMP :3
2: ADDI64 r9, r9, 1d
JMP :4
1: ADDI64 r254, r254, 48d
0: CP r32, r8
JAL r31, r0, :structs
CP r3, r32
JEQ r1, r3, :2
JAL r31, r0, :structs
JMP :1
2: CP r1, r3
CP r32, r3
1: LD r31, r254, 0a, 16h
ADDI64 r254, r254, 16d
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
status: Ok(())

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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