adding more tests, fixing pointer math, and integer upcasting

This commit is contained in:
Jakub Doka 2024-10-20 21:50:08 +02:00
parent 11c8755b18
commit 8528bef8cf
No known key found for this signature in database
GPG key ID: C6E9A89936B8C143
9 changed files with 157 additions and 46 deletions

View file

@ -247,6 +247,7 @@ mod ty {
ident,
lexer::TokenKind,
parser::{self, Pos},
Size,
},
core::{num::NonZeroU32, ops::Range},
};
@ -381,6 +382,19 @@ mod ty {
pub fn is_struct(&self) -> bool {
matches!(self.expand(), Kind::Struct(_))
}
pub(crate) fn simple_size(&self) -> Option<Size> {
Some(match self.expand() {
Kind::Ptr(_) => 8,
Kind::Builtin(VOID) => 0,
Kind::Builtin(NEVER) => 0,
Kind::Builtin(INT | UINT) => 8,
Kind::Builtin(I32 | U32 | TYPE) => 4,
Kind::Builtin(I16 | U16) => 2,
Kind::Builtin(I8 | U8 | BOOL) => 1,
_ => return None,
})
}
}
#[derive(PartialEq, Eq, Default, Debug, Clone, Copy)]
@ -1244,13 +1258,6 @@ impl Types {
fn size_of(&self, ty: ty::Id) -> Size {
match ty.expand() {
ty::Kind::Ptr(_) => 8,
ty::Kind::Builtin(ty::VOID) => 0,
ty::Kind::Builtin(ty::NEVER) => 0,
ty::Kind::Builtin(ty::INT | ty::UINT) => 8,
ty::Kind::Builtin(ty::I32 | ty::U32 | ty::TYPE) => 4,
ty::Kind::Builtin(ty::I16 | ty::U16) => 2,
ty::Kind::Builtin(ty::I8 | ty::U8 | ty::BOOL) => 1,
ty::Kind::Slice(arr) => {
let arr = &self.ins.slices[arr as usize];
match arr.len {
@ -1269,6 +1276,7 @@ impl Types {
self.ins.structs[stru as usize].size.set(oiter.offset);
oiter.offset
}
_ if let Some(size) = ty.simple_size() => size,
ty => unimplemented!("size_of: {:?}", ty),
}
}

View file

@ -389,6 +389,11 @@ impl Nodes {
return Some(self[self[target].inputs[2]].inputs[1]);
}
}
K::Extend => {
if self[target].ty.simple_size() == self[self[target].inputs[1]].ty.simple_size() {
return Some(self[target].inputs[1]);
}
}
_ => {}
}
@ -1094,9 +1099,22 @@ impl ItemCtx {
if let Kind::BinOp { op } = fuc.nodes[cond].kind
&& let Some((op, swapped)) = op.cond_op(node.ty.is_signed())
{
let &[lhs, rhs] = allocs else { unreachable!() };
let &[_, lhsn, rhsn] = fuc.nodes[cond].inputs.as_slice() else {
unreachable!()
};
let lhsn_size = fuc.nodes[lhsn].ty.simple_size().unwrap() as u64;
if lhsn_size < 8 {
let mask = (1u64 << (lhsn_size * 8)) - 1;
self.emit(instrs::andi(atr(lhs), atr(lhs), mask));
}
let rhsn_size = fuc.nodes[rhsn].ty.simple_size().unwrap() as u64;
if rhsn_size < 8 {
let mask = (1u64 << (rhsn_size * 8)) - 1;
self.emit(instrs::andi(atr(rhs), atr(rhs), mask));
}
let rel = Reloc::new(self.code.len(), 3, 2);
self.jump_relocs.push((node.outputs[!swapped as usize], rel));
let &[lhs, rhs] = allocs else { unreachable!() };
self.emit(op(atr(lhs), atr(rhs), 0));
} else {
todo!()
@ -1656,7 +1674,7 @@ impl<'a> Codegen<'a> {
}
}
Expr::Number { value, .. } => Some(self.ci.nodes.new_node_lit(
ctx.ty.filter(|ty| ty.is_integer() || ty.is_pointer()).unwrap_or(ty::Id::INT),
ctx.ty.filter(|ty| ty.is_integer()).unwrap_or(ty::Id::INT),
Kind::CInt { value },
[VOID],
)),
@ -2560,13 +2578,36 @@ impl<'a> Codegen<'a> {
#[track_caller]
fn binop_ty(&mut self, pos: Pos, lhs: &mut Value, rhs: &mut Value, op: TokenKind) -> ty::Id {
if let Some(upcasted) = lhs.ty.try_upcast(rhs.ty, ty::TyCheck::BinOp) {
if lhs.ty != upcasted {
lhs.ty = upcasted;
lhs.id = self.ci.nodes.new_node(upcasted, Kind::Extend, [VOID, lhs.id]);
log::info!(
"{} {} {}",
self.ty_display(lhs.ty),
self.ty_display(rhs.ty),
self.ty_display(upcasted)
);
let to_correct = if lhs.ty != upcasted {
Some(lhs)
} else if rhs.ty != upcasted {
rhs.ty = upcasted;
rhs.id = self.ci.nodes.new_node(upcasted, Kind::Extend, [VOID, rhs.id]);
Some(rhs)
} else {
None
};
if let Some(oper) = to_correct {
oper.ty = upcasted;
oper.id = self.ci.nodes.new_node(upcasted, Kind::Extend, [VOID, oper.id]);
if matches!(op, TokenKind::Add | TokenKind::Sub)
&& let Some(elem) = self.tys.base_of(upcasted)
{
let value = self.tys.size_of(elem) as i64;
let cnst =
self.ci.nodes.new_node_nop(ty::Id::INT, Kind::CInt { value }, [VOID]);
oper.id =
self.ci.nodes.new_node(upcasted, Kind::BinOp { op: TokenKind::Mul }, [
VOID, oper.id, cnst,
]);
}
}
upcasted
} else {
let ty = self.ty_display(lhs.ty);
@ -2588,6 +2629,8 @@ impl<'a> Codegen<'a> {
&& upcasted == expected
{
if src.ty != upcasted {
debug_assert!(src.ty.is_integer());
debug_assert!(upcasted.is_integer());
src.ty = upcasted;
src.id = self.ci.nodes.new_node(upcasted, Kind::Extend, [VOID, src.id]);
}
@ -3437,7 +3480,7 @@ mod tests {
// Purely Testing Examples;
wide_ret;
comptime_min_reg_leak;
//different_types;
different_types;
//struct_return_from_module_function;
sort_something_viredly;
//structs_in_registers;

View file

@ -1,6 +1,6 @@
main:
ADDI64 r254, r254, -100d
ST r31, r254, 28a, 72h
ADDI64 r254, r254, -108d
ST r31, r254, 28a, 80h
LI64 r32, 4d
LI64 r33, 1d
LI64 r34, 2d
@ -18,9 +18,10 @@ main:
ST r32, r254, 16a, 8h
JAL r31, r0, :pass
LD r39, r254, 27a, 1h
ADD64 r1, r39, r1
LD r31, r254, 28a, 72h
ADDI64 r254, r254, 100d
ANDI r40, r39, 255d
ADD64 r1, r1, r40
LD r31, r254, 28a, 80h
ADDI64 r254, r254, 108d
JALA r0, r31, 0a
pass:
LD r3, r2, 8a, 8h
@ -31,6 +32,6 @@ pass:
ADD64 r11, r3, r9
ADD64 r1, r8, r11
JALA r0, r31, 0a
code size: 337
code size: 348
ret: 8
status: Ok(())

View file

@ -14,12 +14,14 @@ str_len:
LI64 r6, 0d
LI64 r1, 0d
2: LD r8, r2, 0a, 1h
ANDI r8, r8, 255d
ANDI r6, r6, 255d
JNE r8, r6, :0
JMP :1
0: ADDI64 r2, r2, 1d
ADDI64 r1, r1, 1d
JMP :2
1: JALA r0, r31, 0a
code size: 201
code size: 223
ret: 16
status: Ok(())

View file

@ -0,0 +1,54 @@
main:
ADDI64 r254, r254, -24d
LI64 r9, 2d
LI64 r8, 0d
LI64 r6, 0d
LI64 r7, 255d
ADDI64 r10, r254, 0d
ADDI64 r10, r254, 8d
ST r7, r254, 8a, 1h
ST r6, r254, 9a, 1h
ST r6, r254, 10a, 1h
ST r7, r254, 11a, 1h
LD r3, r254, 8a, 4h
ADDI64 r12, r254, 12d
ST r3, r254, 12a, 4h
ST r8, r254, 0a, 4h
ST r9, r254, 4a, 4h
LD r1, r254, 0a, 8h
ST r1, r254, 16a, 8h
LD r3, r254, 20a, 4h
ANDI r3, r3, 4294967295d
ANDI r9, r9, 4294967295d
JEQ r3, r9, :0
LI64 r1, 0d
JMP :1
0: ADDI64 r10, r12, 8d
ADDI64 r10, r10, -4d
LD r1, r10, 0a, 4h
ANDI r1, r1, 4294967295d
ANDI r8, r8, 4294967295d
JEQ r1, r8, :2
LI64 r1, 64d
JMP :1
2: LD r7, r254, 15a, 1h
ANDI r9, r7, 255d
LD r6, r254, 14a, 1h
ANDI r8, r6, 255d
LD r5, r254, 13a, 1h
ANDI r7, r5, 255d
LD r3, r254, 12a, 1h
ANDI r6, r3, 255d
LD r4, r254, 20a, 4h
LD r5, r254, 16a, 4h
ADD32 r10, r4, r5
ADD32 r11, r10, r6
ADD32 r3, r11, r7
ADD32 r7, r3, r8
ADD32 r11, r7, r9
ANDI r1, r11, 4294967295d
1: ADDI64 r254, r254, 24d
JALA r0, r31, 0a
code size: 529
ret: 512
status: Ok(())

View file

@ -5,15 +5,16 @@ main:
LI64 r7, 0d
ADDI64 r4, r254, 0d
2: JLTU r7, r5, :0
LD r1, r254, 42a, 1h
LD r2, r254, 42a, 1h
ANDI r1, r2, 255d
JMP :1
0: ADDI64 r3, r7, 1d
ADD64 r2, r7, r4
ST r6, r2, 0a, 1h
CP r7, r3
0: ADDI64 r8, r7, 1d
ADD64 r3, r7, r4
ST r6, r3, 0a, 1h
CP r7, r8
JMP :2
1: ADDI64 r254, r254, 128d
JALA r0, r31, 0a
code size: 141
code size: 152
ret: 69
status: Ok(())

View file

@ -1,21 +1,21 @@
drop:
JALA r0, r31, 0a
main:
ADDI64 r254, r254, -56d
ST r31, r254, 8a, 48h
ADDI64 r254, r254, -48d
ST r31, r254, 8a, 40h
LI64 r32, 1d
ADDI64 r33, r254, 0d
ADDI64 r34, r33, 1000d
ADDI64 r35, r34, -1000d
ADDI64 r34, r33, 8000d
ADDI64 r34, r34, -8000d
ST r32, r254, 0a, 8h
CP r2, r35
CP r2, r34
JAL r31, r0, :modify
CP r2, r32
JAL r31, r0, :drop
LD r36, r35, 0a, 8h
ADDI64 r1, r36, -2d
LD r31, r254, 8a, 48h
ADDI64 r254, r254, 56d
LD r35, r34, 0a, 8h
ADDI64 r1, r35, -2d
LD r31, r254, 8a, 40h
ADDI64 r254, r254, 48d
JALA r0, r31, 0a
modify:
LI64 r3, 2d

View file

@ -31,21 +31,23 @@ fib_iter:
JMP :2
1: JALA r0, r31, 0a
main:
ADDI64 r254, r254, -34d
ST r31, r254, 2a, 32h
ADDI64 r254, r254, -50d
ST r31, r254, 2a, 48h
LI64 r32, 10d
ADDI64 r33, r254, 0d
ST r32, r254, 0a, 1h
ST r32, r254, 1a, 1h
LD r2, r254, 0a, 1h
LD r34, r254, 0a, 1h
ANDI r2, r34, 255d
JAL r31, r0, :fib
CP r34, r1
LD r2, r254, 1a, 1h
CP r35, r1
LD r36, r254, 1a, 1h
ANDI r2, r36, 255d
JAL r31, r0, :fib_iter
SUB64 r1, r34, r1
LD r31, r254, 2a, 32h
ADDI64 r254, r254, 34d
SUB64 r1, r35, r1
LD r31, r254, 2a, 48h
ADDI64 r254, r254, 50d
JALA r0, r31, 0a
code size: 354
code size: 376
ret: 0
status: Ok(())