From 8528bef8cfac534b8c73463a8c5463a8c5e92aa6 Mon Sep 17 00:00:00 2001 From: Jakub Doka Date: Sun, 20 Oct 2024 21:50:08 +0200 Subject: [PATCH] adding more tests, fixing pointer math, and integer upcasting --- lang/src/lib.rs | 22 ++++--- lang/src/son.rs | 59 ++++++++++++++++--- lang/tests/son_tests_arrays.txt | 13 ++-- lang/tests/son_tests_c_strings.txt | 4 +- lang/tests/son_tests_different_types.txt | 54 +++++++++++++++++ lang/tests/son_tests_idk.txt | 13 ++-- lang/tests/son_tests_pointers.txt | 18 +++--- lang/tests/son_tests_struct_patterns.txt | 20 ++++--- ...sts_struct_return_from_module_function.txt | 0 9 files changed, 157 insertions(+), 46 deletions(-) create mode 100644 lang/tests/son_tests_different_types.txt create mode 100644 lang/tests/son_tests_struct_return_from_module_function.txt diff --git a/lang/src/lib.rs b/lang/src/lib.rs index 4d9d98b..93e7af9 100644 --- a/lang/src/lib.rs +++ b/lang/src/lib.rs @@ -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 { + 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), } } diff --git a/lang/src/son.rs b/lang/src/son.rs index 74b862f..1806ecd 100644 --- a/lang/src/son.rs +++ b/lang/src/son.rs @@ -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; diff --git a/lang/tests/son_tests_arrays.txt b/lang/tests/son_tests_arrays.txt index 5864511..ce669b1 100644 --- a/lang/tests/son_tests_arrays.txt +++ b/lang/tests/son_tests_arrays.txt @@ -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(()) diff --git a/lang/tests/son_tests_c_strings.txt b/lang/tests/son_tests_c_strings.txt index cdfc100..eaaf30e 100644 --- a/lang/tests/son_tests_c_strings.txt +++ b/lang/tests/son_tests_c_strings.txt @@ -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(()) diff --git a/lang/tests/son_tests_different_types.txt b/lang/tests/son_tests_different_types.txt new file mode 100644 index 0000000..a29fc93 --- /dev/null +++ b/lang/tests/son_tests_different_types.txt @@ -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(()) diff --git a/lang/tests/son_tests_idk.txt b/lang/tests/son_tests_idk.txt index 333fa7b..ed973f3 100644 --- a/lang/tests/son_tests_idk.txt +++ b/lang/tests/son_tests_idk.txt @@ -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(()) diff --git a/lang/tests/son_tests_pointers.txt b/lang/tests/son_tests_pointers.txt index 478a2f1..6964467 100644 --- a/lang/tests/son_tests_pointers.txt +++ b/lang/tests/son_tests_pointers.txt @@ -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 diff --git a/lang/tests/son_tests_struct_patterns.txt b/lang/tests/son_tests_struct_patterns.txt index de624bf..833bd01 100644 --- a/lang/tests/son_tests_struct_patterns.txt +++ b/lang/tests/son_tests_struct_patterns.txt @@ -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(()) diff --git a/lang/tests/son_tests_struct_return_from_module_function.txt b/lang/tests/son_tests_struct_return_from_module_function.txt new file mode 100644 index 0000000..e69de29