authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-08-24 16:09:52-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-08-26 20:54:49-07:00
logdec706c243ab7d0c2e87fd64c77cda9cd8847520
tree7abbba3ade3fc9fb83159fd80ff91758db9da589
parent5a8c5e322b67c16be6cdcec7621c4a59ae86dd85

spork8: coding style conformance


1 files changed, 125 insertions(+), 68 deletions(-)

src/codegen/spork8/CodeGen.zig+125-68
......@@ -187,7 +187,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
187187
188188fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
189189 const air_tags = cg.air.instructions.items(.tag);
190 return switch (air_tags[@intFromEnum(inst)]) {
190 return switch (air_tags[@backingInt(inst)]) {
191191 .inferred_alloc, .inferred_alloc_comptime => unreachable,
192192
193193 .add,
......@@ -431,7 +431,7 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
431431 .legalize_vec_store_elem,
432432 .legalize_vec_elem_val,
433433 .legalize_compiler_rt_call,
434 => |tag| return cg.fail("TODO: implement spork8 inst: {s}", .{@tagName(tag)}),
434 => |tag| return cg.fail("TODO: implement spork8 inst: {t}", .{tag}),
435435
436436 .unreach => cg.airUnreachable(inst),
437437 .assembly => cg.airAssembly(inst),
......@@ -473,21 +473,21 @@ fn airAssembly(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
473473 while (it.next()) |input| {
474474 const constraint = input.constraint;
475475 if (!mem.eql(u8, constraint, "I")) {
476 return cg.fail("Assembly constraint {q} not supported", .{constraint});
476 return cg.fail("assembly constraint {q} not supported", .{constraint});
477477 }
478478 const operand = input.operand.toInterned() orelse {
479 return cg.fail("Immediate argument to inline assembly must be compile-time value", .{});
479 return cg.fail("immediate argument to inline assembly must be compile-time value", .{});
480480 };
481481 const name = input.name;
482482
483483 const value = switch (zcu.intern_pool.indexToKey(operand)) {
484484 .int => |val| v: {
485485 if (val.ty != .u8_type) {
486 return cg.fail("Non-u8 type used in inline assembly value: {}", .{val.ty});
486 return cg.fail("non-u8 type used in inline assembly value: {}", .{val.ty});
487487 }
488488 break :v val.storage.u64;
489489 },
490 else => return cg.fail("Non-int operands not supported", .{}),
490 else => return cg.fail("non-int operands not supported", .{}),
491491 };
492492
493493 try constValues.put(zcu.gpa, name, @intCast(value));
......@@ -500,18 +500,19 @@ fn airAssembly(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
500500 var tokens = mem.tokenizeScalar(u8, line, ' ');
501501 // If there's no tokens, then it must be a blank line, so just skip it.
502502 const op = tokens.next() orelse continue;
503 const instType = std.meta.stringToEnum(AsmInstType, op) orelse return cg.fail("Invalid asm instruction: {q}", .{op});
503 const instType = std.meta.stringToEnum(AsmInstType, op) orelse return cg.fail("invalid asm instruction: {q}", .{op});
504504 switch (instType) {
505505 .LoadI => {
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", .{});
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) orelse return cg.fail("Constraint name {q} not included in constraints for inline asm", .{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 return cg.fail("Couldn't parse u8 from LoadI immediate value", .{});
514 break :v std.fmt.parseInt(u8, value, 0) catch |err|
515 return cg.fail("invalid LoadI immediate value: {t}", .{err});
515516 }
516517 };
517518 if (register != .OutA) {
......@@ -548,62 +549,118 @@ fn extraLen(cg: *const CodeGen) u32 {
548549}
549550
550551const AsmInstType = enum(u8) {
551 SetPageReg, // Set the memory address high byte to a register value.
552 SetPageI, // Set the memory address high byte to a constant value.
553 SetAddrReg, // Set the memory address low byte to a register value.
554 SetAddrI, // Set the memory address low byte to a constant value.
555 Load, // Load a value from a constant address into a register.
556 LoadI, // Load a constant value into a register.
557 LoadP, // Load a value from a constant address (setting low byte only) into a register.
558 LoadInc, // Load a value from the currently set memory address into a register, and increment the address n times.
559 LoadStck, // Load a value from an offset on the current stack frame into a register.
560 Store, // Store a value to a constant address from a register.
561 StoreI, // Store a constant value into a constant address.
562 StoreP, // Store a value to a constant address (low byte only) from a register.
563 StoreInc, // Store a value from the currently set memory address from a register, and increment the address n times.
564 StoreStck, // Store a value to an offset on the current stack frame, from a register.
565 StoreNStck, // Store a value to an offset on the next stack frame, from a register.
566 StorePStck, // Store a value to an offset on the previous stack frame, from a register.
567 StoreStckI, // Store a constant value to an offset on the current stack frame.
568 StoreNStckI, // Store a constant value to an offset on the next stack frame.
569 StorePStckI, // Store a constant value to an offset on the previous stack frame.
570 Copy, // Copy a value from one register to another register.
571 Jump, // Jump to a constant location.
572 JumpReg, // Jump to a register A (high byte) + register B (low byte).
573 JumpMem, // Jump to a location pointed to by memory at the current memory address (high byte first).
574 Call, // Call a function.
575 Return, // Return from a function.
576 CmpI, // Compare A to a constant value (sets flags, but discards result).
577 CmpAndI, // Compare A to a constant value with bitwise AND (sets flags, but discards result).
578 Cmp, // Compare A to a value from memory (sets flags, but discards result).
579 CmpAnd, // Compare A to a value in memory with bitwise AND (sets flags, but discards result).
580 CmpReg, // Compare A to a value from a register (sets flags, but discards result).
581 CmpAndReg, // Compare A to a value from a register with bitwise AND (sets flags, but discards result).
582 ShiftL, // Shift B left by 1.
583 ShiftR, // Shift B right by 1.
584 RotateL, // Rotate B left by 1.
585 RotateR, // Rotate B right by 1.
586 AddI, // Add a constant value to A.
587 SubI, // Subtract a constant value from A.
588 AndI, // Bitwise-AND A with a constant value.
589 AddINF, // Add a constant value to A, without updating flags.
590 SubINF, // Subtract a constant value from A, without updating flags.
591 AndINF, // Bitwise-AND A with a constant value, without updating flags.
592 AccumulateAdd, // Add register B to A -> A.
593 AccumulateSub, // Subtract register B from A -> A.
594 AccumulateAnd, // A & B -> A.
595 OrI, // Bitwise OR B with A -> A.
596 XorI, // Bitwise OR a constant value with A -> A.
597 Not, // Invert register A.
598 Add, // Add a value from memory to A.
599 Sub, // Subtract a value from memory from A.
600 And, // AND A with a value from memory.
601 Or, // OR A with a value from memory.
602 Xor, // XOR A with a value from memory.
603 Nop, // No-op.
604 Nop1, // No-op with 1 extra clock cycle.
605 Nop2, // No-op with 2 extra clock cycles.
606 Halt, // Halt - stop the program forever (until reset).
552 /// Set the memory address high byte to a register value.
553 SetPageReg,
554 /// Set the memory address high byte to a constant value.
555 SetPageI,
556 /// Set the memory address low byte to a register value.
557 SetAddrReg,
558 /// Set the memory address low byte to a constant value.
559 SetAddrI,
560 /// Load a value from a constant address into a register.
561 Load,
562 /// Load a constant value into a register.
563 LoadI,
564 /// Load a value from a constant address (setting low byte only) into a register.
565 LoadP,
566 /// Load a value from the currently set memory address into a register, and increment the address n times.
567 LoadInc,
568 /// Load a value from an offset on the current stack frame into a register.
569 LoadStck,
570 /// Store a value to a constant address from a register.
571 Store,
572 /// Store a constant value into a constant address.
573 StoreI,
574 /// Store a value to a constant address (low byte only) from a register.
575 StoreP,
576 /// Store a value from the currently set memory address from a register, and increment the address n times.
577 StoreInc,
578 /// Store a value to an offset on the current stack frame, from a register.
579 StoreStck,
580 /// Store a value to an offset on the next stack frame, from a register.
581 StoreNStck,
582 /// Store a value to an offset on the previous stack frame, from a register.
583 StorePStck,
584 /// Store a constant value to an offset on the current stack frame.
585 StoreStckI,
586 /// Store a constant value to an offset on the next stack frame.
587 StoreNStckI,
588 /// Store a constant value to an offset on the previous stack frame.
589 StorePStckI,
590 /// Copy a value from one register to another register.
591 Copy,
592 /// Jump to a constant location.
593 Jump,
594 /// Jump to a register A (high byte) + register B (low byte).
595 JumpReg,
596 /// Jump to a location pointed to by memory at the current memory address (high byte first).
597 JumpMem,
598 /// Call a function.
599 Call,
600 /// Return from a function.
601 Return,
602 /// Compare A to a constant value (sets flags, but discards result).
603 CmpI,
604 /// Compare A to a constant value with bitwise AND (sets flags, but discards result).
605 CmpAndI,
606 /// Compare A to a value from memory (sets flags, but discards result).
607 Cmp,
608 /// Compare A to a value in memory with bitwise AND (sets flags, but discards result).
609 CmpAnd,
610 /// Compare A to a value from a register (sets flags, but discards result).
611 CmpReg,
612 /// Compare A to a value from a register with bitwise AND (sets flags, but discards result).
613 CmpAndReg,
614 /// Shift B left by 1.
615 ShiftL,
616 /// Shift B right by 1.
617 ShiftR,
618 /// Rotate B left by 1.
619 RotateL,
620 /// Rotate B right by 1.
621 RotateR,
622 /// Add a constant value to A.
623 AddI,
624 /// Subtract a constant value from A.
625 SubI,
626 /// Bitwise-AND A with a constant value.
627 AndI,
628 /// Add a constant value to A, without updating flags.
629 AddINF,
630 /// Subtract a constant value from A, without updating flags.
631 SubINF,
632 /// Bitwise-AND A with a constant value, without updating flags.
633 AndINF,
634 /// Add register B to A -> A.
635 AccumulateAdd,
636 /// Subtract register B from A -> A.
637 AccumulateSub,
638 /// A & B -> A.
639 AccumulateAnd,
640 /// Bitwise OR B with A -> A.
641 OrI,
642 /// Bitwise OR a constant value with A -> A.
643 XorI,
644 /// Invert register A.
645 Not,
646 /// Add a value from memory to A.
647 Add,
648 /// Subtract a value from memory from A.
649 Sub,
650 /// AND A with a value from memory.
651 And,
652 /// OR A with a value from memory.
653 Or,
654 /// XOR A with a value from memory.
655 Xor,
656 /// No-op.
657 Nop,
658 /// No-op with 1 extra clock cycle.
659 Nop1,
660 /// No-op with 2 extra clock cycles.
661 Nop2,
662 /// Halt - stop the program forever (until reset).
663 Halt,
607664};
608665
609666const Register = enum(u8) {