sweeping trought more tests

This commit is contained in:
Jakub Doka 2024-10-21 19:57:55 +02:00
parent bc817c4ea2
commit 35d34dca54
No known key found for this signature in database
GPG key ID: C6E9A89936B8C143
10 changed files with 232 additions and 61 deletions

View file

@ -273,7 +273,7 @@ main := fn(): int {
align_of_Type_in_bytes := @alignof(foo.Type) align_of_Type_in_bytes := @alignof(foo.Type)
hardcoded_pointer := @as(^u8, @bitcast(10)) hardcoded_pointer := @as(^u8, @bitcast(10))
ecall_that_returns_int := @as(int, @eca(1, foo.Type.(10, 20), 5, 6)) ecall_that_returns_int := @as(int, @eca(1, foo.Type.(10, 20), 5, 6))
embedded_array := @as(^[u8; 15], @embed("text.txt")) embedded_array := @as([u8; 15], @embed("text.txt"))
return @inline(foo.foo) return @inline(foo.foo)
} }

View file

@ -22,7 +22,6 @@ use {
fmt::{self, Debug, Display, Write}, fmt::{self, Debug, Display, Write},
format_args as fa, mem, format_args as fa, mem,
ops::{self}, ops::{self},
usize,
}, },
hashbrown::hash_map, hashbrown::hash_map,
regalloc2::VReg, regalloc2::VReg,
@ -262,13 +261,6 @@ impl Nodes {
changed = true; changed = true;
} }
if let K::CInt { value } = self[lhs].kind
&& op == T::Sub
{
let lhs = self.new_node_nop(ty, K::CInt { value: -value }, [ctrl]);
return Some(self.new_node(ty, K::BinOp { op: T::Add }, [ctrl, rhs, lhs]));
}
if let K::CInt { value } = self[rhs].kind { if let K::CInt { value } = self[rhs].kind {
match (op, value) { match (op, value) {
(T::Add | T::Sub | T::Shl, 0) | (T::Mul | T::Div, 1) => return Some(lhs), (T::Add | T::Sub | T::Shl, 0) | (T::Mul | T::Div, 1) => return Some(lhs),
@ -1252,18 +1244,17 @@ impl ItemCtx {
} }
} }
Kind::Call { argc, func } => { Kind::Call { argc, func } => {
std::dbg!(node.ty.simple_size());
let (ret, mut parama) = tys.parama(node.ty); let (ret, mut parama) = tys.parama(node.ty);
debug_assert_eq!( let has_ret = !matches!(ret, PLoc::None) as usize;
allocs.len(), let mut iter = allocs[has_ret..].iter();
argc as usize for &i in node.inputs[1..][..argc as usize].iter() {
+ !matches!(ret, PLoc::Reg(..) | PLoc::None) as usize
+ !matches!(ret, PLoc::None) as usize
);
for (&i, &arg) in node.inputs[1..][..argc as usize].iter().zip(&allocs[1..])
{
let ty = fuc.nodes[i].ty; let ty = fuc.nodes[i].ty;
let (rg, size) = match parama.next(ty, tys) { let loc = parama.next(ty, tys);
if let PLoc::None = loc {
continue;
}
let &arg = iter.next().unwrap();
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::None | PLoc::Ref(..) | PLoc::Reg(..) => continue,
@ -1271,6 +1262,8 @@ impl ItemCtx {
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());
if func == ty::ECA { if func == ty::ECA {
self.emit(instrs::eca()); self.emit(instrs::eca());
} else { } else {
@ -1588,9 +1581,63 @@ impl TypeParser for Codegen<'_> {
&mut self.tys &mut self.tys
} }
#[expect(unused)] fn eval_const(&mut self, file: FileId, expr: &Expr, ret: ty::Id) -> u64 {
fn eval_const(&mut self, file: FileId, expr: &Expr, ty: ty::Id) -> u64 { self.pool.push_ci(file, Some(ret), self.tasks.len(), &mut self.ci);
todo!()
let prev_err_len = self.errors.borrow().len();
self.expr(&Expr::Return { pos: expr.pos(), val: Some(expr) });
self.ci.finalize();
if self.errors.borrow().len() == prev_err_len {
self.ci.emit_body(&mut self.tys, self.files, Sig { args: Tuple::empty(), ret });
self.ci.code.truncate(self.ci.code.len() - instrs::jala(0, 0, 0).0);
self.ci.emit(instrs::tx());
let func = Func {
file,
name: 0,
expr: ExprRef::new(expr),
relocs: core::mem::take(&mut self.ci.relocs),
code: core::mem::take(&mut self.ci.code),
..Default::default()
};
self.pool.pop_ci(&mut self.ci);
self.complete_call_graph();
// TODO: return them back
let fuc = self.tys.ins.funcs.len() as ty::Func;
self.tys.ins.funcs.push(func);
self.tys.dump_reachable(fuc, &mut self.ct.code);
#[cfg(debug_assertions)]
{
let mut vc = String::new();
if let Err(e) = self.tys.disasm(&self.ct.code, self.files, &mut vc, |_| {}) {
panic!("{e} {}", vc);
} else {
log::trace!("{}", vc);
}
}
let prev_pc = self.ct.push_pc(self.tys.ins.funcs[fuc as usize].offset);
loop {
match self.ct.vm.run().expect("TODO") {
hbvm::VmRunOk::End => break,
hbvm::VmRunOk::Timer => todo!(),
hbvm::VmRunOk::Ecall => todo!(),
hbvm::VmRunOk::Breakpoint => todo!(),
}
}
self.ct.pop_pc(prev_pc);
self.ct.vm.read_reg(reg::RET).0
} else {
self.pool.pop_ci(&mut self.ci);
1
}
} }
fn infer_type(&mut self, expr: &Expr) -> ty::Id { fn infer_type(&mut self, expr: &Expr) -> ty::Id {
@ -2022,8 +2069,8 @@ impl<'a> Codegen<'a> {
} }
Expr::Embed { id, .. } => { Expr::Embed { id, .. } => {
let glob = &self.tys.ins.globals[id as usize]; let glob = &self.tys.ins.globals[id as usize];
let ty = self.tys.make_ptr(glob.ty); let g = self.ci.nodes.new_node(glob.ty, Kind::Global { global: id }, [VOID]);
Some(self.ci.nodes.new_node_lit(ty, Kind::Global { global: id }, [VOID])) Some(Value::ptr(g).ty(glob.ty))
} }
Expr::Directive { name: "sizeof", args: [ty], .. } => { Expr::Directive { name: "sizeof", args: [ty], .. } => {
let ty = self.ty(ty); let ty = self.ty(ty);
@ -2110,8 +2157,12 @@ impl<'a> Codegen<'a> {
Some(self.ci.nodes.new_node_lit(ty, Kind::BinOp { op: TokenKind::Band }, inps)) Some(self.ci.nodes.new_node_lit(ty, Kind::BinOp { op: TokenKind::Band }, inps))
} }
Expr::Directive { name: "as", args: [ty, expr], .. } => { Expr::Directive { name: "as", args: [ty, expr], .. } => {
let ctx = Ctx::default().with_ty(self.ty(ty)); let ty = self.ty(ty);
self.raw_expr_ctx(expr, ctx) 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");
Some(val)
} }
Expr::Directive { pos, name: "eca", args } => { Expr::Directive { pos, name: "eca", args } => {
let Some(ty) = ctx.ty else { let Some(ty) = ctx.ty else {
@ -3720,6 +3771,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);
let (ref files, embeds) = crate::test_parse_files(ident, input); let (ref files, embeds) = crate::test_parse_files(ident, input);
let mut codegen = super::Codegen { files, ..Default::default() }; let mut codegen = super::Codegen { files, ..Default::default() };
@ -3778,17 +3830,17 @@ mod tests {
wide_ret; wide_ret;
comptime_min_reg_leak; comptime_min_reg_leak;
different_types; different_types;
//struct_return_from_module_function; struct_return_from_module_function;
sort_something_viredly; sort_something_viredly;
//structs_in_registers; structs_in_registers;
comptime_function_from_another_file; comptime_function_from_another_file;
inline_test; inline_test;
//inlined_generic_functions; //inlined_generic_functions;
//some_generic_code; //some_generic_code;
//integer_inference_issues; integer_inference_issues;
writing_into_string; writing_into_string;
//request_page; request_page;
//tests_ptr_to_ptr_copy; tests_ptr_to_ptr_copy;
// Just Testing Optimizations; // Just Testing Optimizations;
const_folding_with_arg; const_folding_with_arg;

View file

@ -0,0 +1,19 @@
main:
ADDI64 r254, r254, -16d
LI64 r5, 5d
LI64 r7, 20d
LI64 r2, 1d
LI64 r4, 10d
LI64 r6, 6d
ADDI64 r8, r254, 0d
ST r4, r254, 0a, 8h
ST r7, r254, 8a, 8h
LD r3, r8, 0a, 16h
ECA
LI64 r1, 0d
ADDI64 r254, r254, 16d
JALA r0, r31, 0a
ev: Ecall
code size: 152
ret: 0
status: Ok(())

View file

@ -30,13 +30,13 @@ line:
JMP :0 JMP :0
0: JALA r0, r31, 0a 0: JALA r0, r31, 0a
main: main:
ADDI64 r254, r254, -112d ADDI64 r254, r254, -160d
ST r31, r254, 96a, 16h ST r31, r254, 96a, 64h
LI64 r32, 10d LI64 r32, 10d
LI64 r1, 0d LI64 r1, 0d
ADDI64 r7, r254, 48d ADDI64 r33, r254, 48d
ADDI64 r5, r254, 64d ADDI64 r34, r254, 64d
ADDI64 r3, r254, 80d ADDI64 r35, r254, 80d
ST r1, r254, 80a, 8h ST r1, r254, 80a, 8h
ST r1, r254, 88a, 8h ST r1, r254, 88a, 8h
ST r1, r254, 64a, 8h ST r1, r254, 64a, 8h
@ -44,16 +44,13 @@ main:
ST r1, r254, 48a, 8h ST r1, r254, 48a, 8h
ST r1, r254, 56a, 8h ST r1, r254, 56a, 8h
CP r8, r32 CP r8, r32
CP r2, r3 LD r2, r35, 0a, 16h
CP r4, r5 LD r4, r34, 0a, 16h
CP r6, r7 LD r6, r33, 0a, 16h
LD r2, r2, 0a, 16h
LD r4, r4, 0a, 16h
LD r6, r6, 0a, 16h
JAL r31, r0, :line JAL r31, r0, :line
ADDI64 r7, r254, 0d ADDI64 r36, r254, 0d
ADDI64 r5, r254, 16d ADDI64 r37, r254, 16d
ADDI64 r3, r254, 32d ADDI64 r38, r254, 32d
ST r1, r254, 32a, 8h ST r1, r254, 32a, 8h
ST r1, r254, 40a, 8h ST r1, r254, 40a, 8h
ST r1, r254, 16a, 8h ST r1, r254, 16a, 8h
@ -61,16 +58,13 @@ main:
ST r1, r254, 0a, 8h ST r1, r254, 0a, 8h
ST r1, r254, 8a, 8h ST r1, r254, 8a, 8h
CP r8, r32 CP r8, r32
CP r2, r3 LD r2, r38, 0a, 16h
CP r4, r5 LD r4, r37, 0a, 16h
CP r6, r7 LD r6, r36, 0a, 16h
LD r2, r2, 0a, 16h
LD r4, r4, 0a, 16h
LD r6, r6, 0a, 16h
JAL r31, r0, :rect_line JAL r31, r0, :rect_line
JAL r31, r0, :example JAL r31, r0, :example
LD r31, r254, 96a, 16h LD r31, r254, 96a, 64h
ADDI64 r254, r254, 112d ADDI64 r254, r254, 160d
JALA r0, r31, 0a JALA r0, r31, 0a
rect_line: rect_line:
ST r2, r254, 0a, 16h ST r2, r254, 0a, 16h
@ -92,6 +86,6 @@ rect_line:
2: ADDI64 r9, r9, 1d 2: ADDI64 r9, r9, 1d
JMP :4 JMP :4
1: JALA r0, r31, 0a 1: JALA r0, r31, 0a
code size: 875 code size: 857
ret: 4 ret: 4
status: Ok(()) status: Ok(())

View file

@ -0,0 +1,29 @@
integer_range:
ADDI64 r254, r254, -16d
ST r31, r254, 0a, 16h
CP r32, r2
CP r33, r3
LI64 r3, 4d
LI64 r2, 3d
ECA
CP r2, r32
CP r3, r33
SUB64 r11, r3, r2
ADDI64 r3, r11, 1d
DIRU64 r0, r3, r1, r3
ADD64 r1, r3, r2
LD r31, r254, 0a, 16h
ADDI64 r254, r254, 16d
JALA r0, r31, 0a
main:
ADDI64 r254, r254, -8d
ST r31, r254, 0a, 8h
LI64 r3, 1000d
LI64 r2, 0d
JAL r31, r0, :integer_range
LD r31, r254, 0a, 8h
ADDI64 r254, r254, 8d
JALA r0, r31, 0a
code size: 210
ret: 42
status: Ok(())

View file

@ -3,17 +3,18 @@ clobber:
ST r3, r2, 0a, 8h ST r3, r2, 0a, 8h
JALA r0, r31, 0a JALA r0, r31, 0a
main: main:
ADDI64 r254, r254, -32d ADDI64 r254, r254, -40d
ST r31, r254, 8a, 24h ST r31, r254, 8a, 32h
LI64 r32, 2d LI64 r32, 2d
ADDI64 r2, r254, 0d ADDI64 r2, r254, 0d
ST r32, r254, 0a, 8h ST r32, r254, 0a, 8h
JAL r31, r0, :clobber JAL r31, r0, :clobber
LD r33, r254, 0a, 8h LI64 r33, 4d
ADDI64 r1, r33, -4d LD r34, r254, 0a, 8h
LD r31, r254, 8a, 24h SUB64 r1, r33, r34
ADDI64 r254, r254, 32d LD r31, r254, 8a, 32h
ADDI64 r254, r254, 40d
JALA r0, r31, 0a JALA r0, r31, 0a
code size: 166 code size: 169
ret: 0 ret: 0
status: Ok(()) status: Ok(())

View file

View file

@ -0,0 +1,38 @@
foo:
ADDI64 r254, r254, -16d
LI64 r3, 2d
LI64 r5, 3d
ADDI64 r4, r254, 0d
ST r5, r254, 0a, 8h
ST r3, r254, 8a, 4h
ST r3, r254, 12a, 4h
LD r1, r4, 0a, 16h
ADDI64 r254, r254, 16d
JALA r0, r31, 0a
main:
ADDI64 r254, r254, -144d
ST r31, r254, 48a, 96h
ADDI64 r32, r254, 32d
JAL r31, r0, :foo
ST r1, r254, 32a, 16h
ADDI64 r33, r254, 16d
LD r34, r254, 32a, 8h
JAL r31, r0, :foo
ST r1, r254, 16a, 16h
ADDI64 r35, r254, 0d
LD r36, 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
JALA r0, r31, 0a
code size: 359
ret: 0
status: Ok(())

View file

@ -0,0 +1,8 @@
main:
LRA r1, r0, :MAGENTA
LD r3, r1, 2a, 1h
ANDI r1, r3, 255d
JALA r0, r31, 0a
code size: 54
ret: 205
status: Ok(())

View file

@ -0,0 +1,30 @@
main:
ADDI64 r254, r254, -10240d
LI64 r7, 64d
LI64 r5, 1024d
LI64 r9, 1d
LI64 r8, 0d
ADDI64 r6, r254, 0d
4: JLTU r8, r5, :0
LI64 r7, 10d
CP r8, r9
3: JLTU r8, r7, :1
LD r9, r254, 2048a, 1h
ANDI r1, r9, 255d
JMP :2
1: ADD64 r3, r8, r9
MUL64 r2, r8, r5
ADD64 r4, r2, r6
BMC r6, r4, 1024h
CP r8, r3
JMP :3
0: ADD64 r2, r8, r9
ADD64 r12, r8, r6
ST r7, r12, 0a, 1h
CP r8, r2
JMP :4
2: ADDI64 r254, r254, 10240d
JALA r0, r31, 0a
code size: 198
ret: 64
status: Ok(())