From 66014c3de19a49d0c1001dfbbef5a85c375f4e32 Mon Sep 17 00:00:00 2001 From: Ben Anderman Date: Sun, 23 Aug 2026 15:09:11 -0400 Subject: [PATCH] Add error handling to Spork8 codegen --- src/codegen/spork8/CodeGen.zig | 16 ++++---- src/codegen/spork8/Mir.zig | 71 ---------------------------------- 2 files changed, 8 insertions(+), 79 deletions(-) diff --git a/src/codegen/spork8/CodeGen.zig b/src/codegen/spork8/CodeGen.zig index 451175b42e300c2b5100cccedd0584566271f92b..184af44b4aaa0162b512c2f945a8869df4ba2305 100644 --- a/src/codegen/spork8/CodeGen.zig +++ b/src/codegen/spork8/CodeGen.zig @@ -491,8 +491,6 @@ fn airAssembly(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { }; try constValues.put(zcu.gpa, name, @intCast(value)); - - // return cg.fail("TODO: Constraint={q}, name={q}, value={}", .{ constraint, name, value }); } } @@ -500,22 +498,24 @@ fn airAssembly(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { var lines = mem.tokenizeScalar(u8, unwrapped_asm.source, '\n'); while (lines.next()) |line| { var tokens = mem.tokenizeScalar(u8, line, ' '); - const op = tokens.next().?; + // If there's no tokens, then it must be a blank line, so just skip it. + const op = tokens.next() orelse continue; const instType = std.meta.stringToEnum(AsmInstType, op) orelse return cg.fail("Invalid asm instruction: {q}", .{op}); switch (instType) { .LoadI => { - const register = std.meta.stringToEnum(Register, tokens.next().?).?; - const value = tokens.next().?; + const registerString = tokens.next() orelse return cg.fail("Missing register for LoadI instruction", .{}); + const register = std.meta.stringToEnum(Register, registerString) orelse return cg.fail("Invalid register: {q}", .{registerString}); + const value = tokens.next() orelse return cg.fail("Missing immediate value for LoadI", .{}); const intValue = v: { if (mem.startsWith(u8, value, "%[")) { const name = value[2 .. value.len - 1]; - break :v constValues.get(name).?; + break :v constValues.get(name) orelse return cg.fail("Constraint name {q} not included in constraints for inline asm", .{name}); } else { - break :v std.fmt.parseInt(u8, value, 0) catch unreachable; + break :v std.fmt.parseInt(u8, value, 0) catch return cg.fail("Couldn't parse u8 from LoadI immediate value", .{}); } }; if (register != .OutA) { - return cg.fail("TODO: other variants of LoadI", .{}); + return cg.fail("TODO: support other variants of LoadI", .{}); } try cg.addTagImm8(.load_i_outa, intValue); }, diff --git a/src/codegen/spork8/Mir.zig b/src/codegen/spork8/Mir.zig index 4034320a9336b40f3651c50aeedb5659237126ef..4f7b041a66dcb21702af27ddcd797acddbc6b86d 100644 --- a/src/codegen/spork8/Mir.zig +++ b/src/codegen/spork8/Mir.zig @@ -52,74 +52,3 @@ pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void { mir.instructions.deinit(gpa); mir.* = undefined; } - -const AsmInstType = enum(u8) { - SetPageReg, // Set the memory address high byte to a register value. - SetPageI, // Set the memory address high byte to a constant value. - SetAddrReg, // Set the memory address low byte to a register value. - SetAddrI, // Set the memory address low byte to a constant value. - Load, // Load a value from a constant address into a register. - LoadI, // Load a constant value into a register. - LoadP, // Load a value from a constant address (setting low byte only) into a register. - LoadInc, // Load a value from the currently set memory address into a register, and increment the address n times. - LoadStck, // Load a value from an offset on the current stack frame into a register. - Store, // Store a value to a constant address from a register. - StoreI, // Store a constant value into a constant address. - StoreP, // Store a value to a constant address (low byte only) from a register. - StoreInc, // Store a value from the currently set memory address from a register, and increment the address n times. - StoreStck, // Store a value to an offset on the current stack frame, from a register. - StoreNStck, // Store a value to an offset on the next stack frame, from a register. - StorePStck, // Store a value to an offset on the previous stack frame, from a register. - StoreStckI, // Store a constant value to an offset on the current stack frame. - StoreNStckI, // Store a constant value to an offset on the next stack frame. - StorePStckI, // Store a constant value to an offset on the previous stack frame. - Copy, // Copy a value from one register to another register. - Jump, // Jump to a constant location. - JumpReg, // Jump to a register A (high byte) + register B (low byte). - JumpMem, // Jump to a location pointed to by memory at the current memory address (high byte first). - Call, // Call a function. - Return, // Return from a function. - CmpI, // Compare A to a constant value (sets flags, but discards result). - CmpAndI, // Compare A to a constant value with bitwise AND (sets flags, but discards result). - Cmp, // Compare A to a value from memory (sets flags, but discards result). - CmpAnd, // Compare A to a value in memory with bitwise AND (sets flags, but discards result). - CmpReg, // Compare A to a value from a register (sets flags, but discards result). - CmpAndReg, // Compare A to a value from a register with bitwise AND (sets flags, but discards result). - ShiftL, // Shift B left by 1. - ShiftR, // Shift B right by 1. - RotateL, // Rotate B left by 1. - RotateR, // Rotate B right by 1. - AddI, // Add a constant value to A. - SubI, // Subtract a constant value from A. - AndI, // Bitwise-AND A with a constant value. - AddINF, // Add a constant value to A, without updating flags. - SubINF, // Subtract a constant value from A, without updating flags. - AndINF, // Bitwise-AND A with a constant value, without updating flags. - AccumulateAdd, // Add register B to A -> A. - AccumulateSub, // Subtract register B from A -> A. - AccumulateAnd, // A & B -> A. - OrI, // Bitwise OR B with A -> A. - XorI, // Bitwise OR a constant value with A -> A. - Not, // Invert register A. - Add, // Add a value from memory to A. - Sub, // Subtract a value from memory from A. - And, // AND A with a value from memory. - Or, // OR A with a value from memory. - Xor, // XOR A with a value from memory. - Nop, // No-op. - Nop1, // No-op with 1 extra clock cycle. - Nop2, // No-op with 2 extra clock cycles. - Halt, // Halt - stop the program forever (until reset). -}; - -const Registers = enum(u8) { - A, - B, - C, - PCnt, - MAdr, - Stack, - OutA, - Shift, - Swap, -}; -- 2.54.0