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, ident,
lexer::TokenKind, lexer::TokenKind,
parser::{self, Pos}, parser::{self, Pos},
Size,
}, },
core::{num::NonZeroU32, ops::Range}, core::{num::NonZeroU32, ops::Range},
}; };
@ -381,6 +382,19 @@ mod ty {
pub fn is_struct(&self) -> bool { pub fn is_struct(&self) -> bool {
matches!(self.expand(), Kind::Struct(_)) 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)] #[derive(PartialEq, Eq, Default, Debug, Clone, Copy)]
@ -1244,13 +1258,6 @@ impl Types {
fn size_of(&self, ty: ty::Id) -> Size { fn size_of(&self, ty: ty::Id) -> Size {
match ty.expand() { 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) => { ty::Kind::Slice(arr) => {
let arr = &self.ins.slices[arr as usize]; let arr = &self.ins.slices[arr as usize];
match arr.len { match arr.len {
@ -1269,6 +1276,7 @@ impl Types {
self.ins.structs[stru as usize].size.set(oiter.offset); self.ins.structs[stru as usize].size.set(oiter.offset);
oiter.offset oiter.offset
} }
_ if let Some(size) = ty.simple_size() => size,
ty => unimplemented!("size_of: {:?}", ty), ty => unimplemented!("size_of: {:?}", ty),
} }
} }

View file

@ -389,6 +389,11 @@ impl Nodes {
return Some(self[self[target].inputs[2]].inputs[1]); 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 if let Kind::BinOp { op } = fuc.nodes[cond].kind
&& let Some((op, swapped)) = op.cond_op(node.ty.is_signed()) && 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); let rel = Reloc::new(self.code.len(), 3, 2);
self.jump_relocs.push((node.outputs[!swapped as usize], rel)); self.jump_relocs.push((node.outputs[!swapped as usize], rel));
let &[lhs, rhs] = allocs else { unreachable!() };
self.emit(op(atr(lhs), atr(rhs), 0)); self.emit(op(atr(lhs), atr(rhs), 0));
} else { } else {
todo!() todo!()
@ -1656,7 +1674,7 @@ impl<'a> Codegen<'a> {
} }
} }
Expr::Number { value, .. } => Some(self.ci.nodes.new_node_lit( 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 }, Kind::CInt { value },
[VOID], [VOID],
)), )),
@ -2560,13 +2578,36 @@ impl<'a> Codegen<'a> {
#[track_caller] #[track_caller]
fn binop_ty(&mut self, pos: Pos, lhs: &mut Value, rhs: &mut Value, op: TokenKind) -> ty::Id { fn binop_ty(&mut self, pos: Pos, lhs: &mut Value, rhs: &mut Value, op: TokenKind) -> ty::Id {
if let Some(upcasted) = lhs.ty.try_upcast(rhs.ty, ty::TyCheck::BinOp) { if let Some(upcasted) = lhs.ty.try_upcast(rhs.ty, ty::TyCheck::BinOp) {
if lhs.ty != upcasted { log::info!(
lhs.ty = upcasted; "{} {} {}",
lhs.id = self.ci.nodes.new_node(upcasted, Kind::Extend, [VOID, lhs.id]); 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 { } else if rhs.ty != upcasted {
rhs.ty = upcasted; Some(rhs)
rhs.id = self.ci.nodes.new_node(upcasted, Kind::Extend, [VOID, rhs.id]); } 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 upcasted
} else { } else {
let ty = self.ty_display(lhs.ty); let ty = self.ty_display(lhs.ty);
@ -2588,6 +2629,8 @@ impl<'a> Codegen<'a> {
&& upcasted == expected && upcasted == expected
{ {
if src.ty != upcasted { if src.ty != upcasted {
debug_assert!(src.ty.is_integer());
debug_assert!(upcasted.is_integer());
src.ty = upcasted; src.ty = upcasted;
src.id = self.ci.nodes.new_node(upcasted, Kind::Extend, [VOID, src.id]); src.id = self.ci.nodes.new_node(upcasted, Kind::Extend, [VOID, src.id]);
} }
@ -3437,7 +3480,7 @@ mod tests {
// Purely Testing Examples; // Purely Testing Examples;
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;

View file

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

View file

@ -14,12 +14,14 @@ str_len:
LI64 r6, 0d LI64 r6, 0d
LI64 r1, 0d LI64 r1, 0d
2: LD r8, r2, 0a, 1h 2: LD r8, r2, 0a, 1h
ANDI r8, r8, 255d
ANDI r6, r6, 255d
JNE r8, r6, :0 JNE r8, r6, :0
JMP :1 JMP :1
0: ADDI64 r2, r2, 1d 0: ADDI64 r2, r2, 1d
ADDI64 r1, r1, 1d ADDI64 r1, r1, 1d
JMP :2 JMP :2
1: JALA r0, r31, 0a 1: JALA r0, r31, 0a
code size: 201 code size: 223
ret: 16 ret: 16
status: Ok(()) 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 LI64 r7, 0d
ADDI64 r4, r254, 0d ADDI64 r4, r254, 0d
2: JLTU r7, r5, :0 2: JLTU r7, r5, :0
LD r1, r254, 42a, 1h LD r2, r254, 42a, 1h
ANDI r1, r2, 255d
JMP :1 JMP :1
0: ADDI64 r3, r7, 1d 0: ADDI64 r8, r7, 1d
ADD64 r2, r7, r4 ADD64 r3, r7, r4
ST r6, r2, 0a, 1h ST r6, r3, 0a, 1h
CP r7, r3 CP r7, r8
JMP :2 JMP :2
1: ADDI64 r254, r254, 128d 1: ADDI64 r254, r254, 128d
JALA r0, r31, 0a JALA r0, r31, 0a
code size: 141 code size: 152
ret: 69 ret: 69
status: Ok(()) status: Ok(())

View file

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

View file

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