authorgravatar for ben@happyspork.comBen Anderman <ben@happyspork.com> 2026-08-23 15:09:11-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-08-26 20:54:49-07:00
log66014c3de19a49d0c1001dfbbef5a85c375f4e32
tree76cede8e3b0f2a27e656b2a9e32e7c08864ec659
parenta95b6d22efa89e2496201ed4b02788426638bbf5

Add error handling to Spork8 codegen


2 files changed, 8 insertions(+), 79 deletions(-)

src/codegen/spork8/CodeGen.zig+8-8
......@@ -491,8 +491,6 @@ fn airAssembly(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
491491 };
492492
493493 try constValues.put(zcu.gpa, name, @intCast(value));
494
495 // return cg.fail("TODO: Constraint={q}, name={q}, value={}", .{ constraint, name, value });
496494 }
497495 }
498496
......@@ -500,22 +498,24 @@ fn airAssembly(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
500498 var lines = mem.tokenizeScalar(u8, unwrapped_asm.source, '\n');
501499 while (lines.next()) |line| {
502500 var tokens = mem.tokenizeScalar(u8, line, ' ');
503 const op = tokens.next().?;
501 // If there's no tokens, then it must be a blank line, so just skip it.
502 const op = tokens.next() orelse continue;
504503 const instType = std.meta.stringToEnum(AsmInstType, op) orelse return cg.fail("Invalid asm instruction: {q}", .{op});
505504 switch (instType) {
506505 .LoadI => {
507 const register = std.meta.stringToEnum(Register, tokens.next().?).?;
508 const value = tokens.next().?;
506 const registerString = tokens.next() orelse return cg.fail("Missing register for LoadI instruction", .{});
507 const register = std.meta.stringToEnum(Register, registerString) orelse return cg.fail("Invalid register: {q}", .{registerString});
508 const value = tokens.next() orelse return cg.fail("Missing immediate value for LoadI", .{});
509509 const intValue = v: {
510510 if (mem.startsWith(u8, value, "%[")) {
511511 const name = value[2 .. value.len - 1];
512 break :v constValues.get(name).?;
512 break :v constValues.get(name) orelse return cg.fail("Constraint name {q} not included in constraints for inline asm", .{name});
513513 } else {
514 break :v std.fmt.parseInt(u8, value, 0) catch unreachable;
514 break :v std.fmt.parseInt(u8, value, 0) catch return cg.fail("Couldn't parse u8 from LoadI immediate value", .{});
515515 }
516516 };
517517 if (register != .OutA) {
518 return cg.fail("TODO: other variants of LoadI", .{});
518 return cg.fail("TODO: support other variants of LoadI", .{});
519519 }
520520 try cg.addTagImm8(.load_i_outa, intValue);
521521 },
src/codegen/spork8/Mir.zig-71
......@@ -52,74 +52,3 @@ pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void {
5252 mir.instructions.deinit(gpa);
5353 mir.* = undefined;
5454}
55
56const AsmInstType = enum(u8) {
57 SetPageReg, // Set the memory address high byte to a register value.
58 SetPageI, // Set the memory address high byte to a constant value.
59 SetAddrReg, // Set the memory address low byte to a register value.
60 SetAddrI, // Set the memory address low byte to a constant value.
61 Load, // Load a value from a constant address into a register.
62 LoadI, // Load a constant value into a register.
63 LoadP, // Load a value from a constant address (setting low byte only) into a register.
64 LoadInc, // Load a value from the currently set memory address into a register, and increment the address n times.
65 LoadStck, // Load a value from an offset on the current stack frame into a register.
66 Store, // Store a value to a constant address from a register.
67 StoreI, // Store a constant value into a constant address.
68 StoreP, // Store a value to a constant address (low byte only) from a register.
69 StoreInc, // Store a value from the currently set memory address from a register, and increment the address n times.
70 StoreStck, // Store a value to an offset on the current stack frame, from a register.
71 StoreNStck, // Store a value to an offset on the next stack frame, from a register.
72 StorePStck, // Store a value to an offset on the previous stack frame, from a register.
73 StoreStckI, // Store a constant value to an offset on the current stack frame.
74 StoreNStckI, // Store a constant value to an offset on the next stack frame.
75 StorePStckI, // Store a constant value to an offset on the previous stack frame.
76 Copy, // Copy a value from one register to another register.
77 Jump, // Jump to a constant location.
78 JumpReg, // Jump to a register A (high byte) + register B (low byte).
79 JumpMem, // Jump to a location pointed to by memory at the current memory address (high byte first).
80 Call, // Call a function.
81 Return, // Return from a function.
82 CmpI, // Compare A to a constant value (sets flags, but discards result).
83 CmpAndI, // Compare A to a constant value with bitwise AND (sets flags, but discards result).
84 Cmp, // Compare A to a value from memory (sets flags, but discards result).
85 CmpAnd, // Compare A to a value in memory with bitwise AND (sets flags, but discards result).
86 CmpReg, // Compare A to a value from a register (sets flags, but discards result).
87 CmpAndReg, // Compare A to a value from a register with bitwise AND (sets flags, but discards result).
88 ShiftL, // Shift B left by 1.
89 ShiftR, // Shift B right by 1.
90 RotateL, // Rotate B left by 1.
91 RotateR, // Rotate B right by 1.
92 AddI, // Add a constant value to A.
93 SubI, // Subtract a constant value from A.
94 AndI, // Bitwise-AND A with a constant value.
95 AddINF, // Add a constant value to A, without updating flags.
96 SubINF, // Subtract a constant value from A, without updating flags.
97 AndINF, // Bitwise-AND A with a constant value, without updating flags.
98 AccumulateAdd, // Add register B to A -> A.
99 AccumulateSub, // Subtract register B from A -> A.
100 AccumulateAnd, // A & B -> A.
101 OrI, // Bitwise OR B with A -> A.
102 XorI, // Bitwise OR a constant value with A -> A.
103 Not, // Invert register A.
104 Add, // Add a value from memory to A.
105 Sub, // Subtract a value from memory from A.
106 And, // AND A with a value from memory.
107 Or, // OR A with a value from memory.
108 Xor, // XOR A with a value from memory.
109 Nop, // No-op.
110 Nop1, // No-op with 1 extra clock cycle.
111 Nop2, // No-op with 2 extra clock cycles.
112 Halt, // Halt - stop the program forever (until reset).
113};
114
115const Registers = enum(u8) {
116 A,
117 B,
118 C,
119 PCnt,
120 MAdr,
121 Stack,
122 OutA,
123 Shift,
124 Swap,
125};