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 {...@@ -187,7 +187,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
187187
188fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {188fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
189 const air_tags = cg.air.instructions.items(.tag);189 const air_tags = cg.air.instructions.items(.tag);
190 return switch (air_tags[@intFromEnum(inst)]) {190 return switch (air_tags[@backingInt(inst)]) {
191 .inferred_alloc, .inferred_alloc_comptime => unreachable,191 .inferred_alloc, .inferred_alloc_comptime => unreachable,
192192
193 .add,193 .add,
...@@ -431,7 +431,7 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -431,7 +431,7 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
431 .legalize_vec_store_elem,431 .legalize_vec_store_elem,
432 .legalize_vec_elem_val,432 .legalize_vec_elem_val,
433 .legalize_compiler_rt_call,433 .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
436 .unreach => cg.airUnreachable(inst),436 .unreach => cg.airUnreachable(inst),
437 .assembly => cg.airAssembly(inst),437 .assembly => cg.airAssembly(inst),
...@@ -473,21 +473,21 @@ fn airAssembly(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -473,21 +473,21 @@ fn airAssembly(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
473 while (it.next()) |input| {473 while (it.next()) |input| {
474 const constraint = input.constraint;474 const constraint = input.constraint;
475 if (!mem.eql(u8, constraint, "I")) {475 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});
477 }477 }
478 const operand = input.operand.toInterned() orelse {478 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", .{});
480 };480 };
481 const name = input.name;481 const name = input.name;
482482
483 const value = switch (zcu.intern_pool.indexToKey(operand)) {483 const value = switch (zcu.intern_pool.indexToKey(operand)) {
484 .int => |val| v: {484 .int => |val| v: {
485 if (val.ty != .u8_type) {485 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});
487 }487 }
488 break :v val.storage.u64;488 break :v val.storage.u64;
489 },489 },
490 else => return cg.fail("Non-int operands not supported", .{}),490 else => return cg.fail("non-int operands not supported", .{}),
491 };491 };
492492
493 try constValues.put(zcu.gpa, name, @intCast(value));493 try constValues.put(zcu.gpa, name, @intCast(value));
...@@ -500,18 +500,19 @@ fn airAssembly(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -500,18 +500,19 @@ fn airAssembly(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
500 var tokens = mem.tokenizeScalar(u8, line, ' ');500 var tokens = mem.tokenizeScalar(u8, line, ' ');
501 // If there's no tokens, then it must be a blank line, so just skip it.501 // If there's no tokens, then it must be a blank line, so just skip it.
502 const op = tokens.next() orelse continue;502 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});
504 switch (instType) {504 switch (instType) {
505 .LoadI => {505 .LoadI => {
506 const registerString = tokens.next() orelse return cg.fail("Missing register for LoadI instruction", .{});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});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", .{});508 const value = tokens.next() orelse return cg.fail("missing immediate value for LoadI", .{});
509 const intValue = v: {509 const intValue = v: {
510 if (mem.startsWith(u8, value, "%[")) {510 if (mem.startsWith(u8, value, "%[")) {
511 const name = value[2 .. value.len - 1];511 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});
513 } else {513 } 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});
515 }516 }
516 };517 };
517 if (register != .OutA) {518 if (register != .OutA) {
...@@ -548,62 +549,118 @@ fn extraLen(cg: *const CodeGen) u32 {...@@ -548,62 +549,118 @@ fn extraLen(cg: *const CodeGen) u32 {
548}549}
549550
550const AsmInstType = enum(u8) {551const AsmInstType = enum(u8) {
551 SetPageReg, // Set the memory address high byte to a register value.552 /// Set the memory address high byte to a register value.
552 SetPageI, // Set the memory address high byte to a constant value.553 SetPageReg,
553 SetAddrReg, // Set the memory address low byte to a register value.554 /// Set the memory address high byte to a constant value.
554 SetAddrI, // Set the memory address low byte to a constant value.555 SetPageI,
555 Load, // Load a value from a constant address into a register.556 /// Set the memory address low byte to a register value.
556 LoadI, // Load a constant value into a register.557 SetAddrReg,
557 LoadP, // Load a value from a constant address (setting low byte only) into a register.558 /// Set the memory address low byte to a constant value.
558 LoadInc, // Load a value from the currently set memory address into a register, and increment the address n times.559 SetAddrI,
559 LoadStck, // Load a value from an offset on the current stack frame into a register.560 /// Load a value from a constant address into a register.
560 Store, // Store a value to a constant address from a register.561 Load,
561 StoreI, // Store a constant value into a constant address.562 /// Load a constant value into a register.
562 StoreP, // Store a value to a constant address (low byte only) from a register.563 LoadI,
563 StoreInc, // Store a value from the currently set memory address from a register, and increment the address n times.564 /// Load a value from a constant address (setting low byte only) into a register.
564 StoreStck, // Store a value to an offset on the current stack frame, from a register.565 LoadP,
565 StoreNStck, // Store a value to an offset on the next stack frame, from a register.566 /// Load a value from the currently set memory address into a register, and increment the address n times.
566 StorePStck, // Store a value to an offset on the previous stack frame, from a register.567 LoadInc,
567 StoreStckI, // Store a constant value to an offset on the current stack frame.568 /// Load a value from an offset on the current stack frame into a register.
568 StoreNStckI, // Store a constant value to an offset on the next stack frame.569 LoadStck,
569 StorePStckI, // Store a constant value to an offset on the previous stack frame.570 /// Store a value to a constant address from a register.
570 Copy, // Copy a value from one register to another register.571 Store,
571 Jump, // Jump to a constant location.572 /// Store a constant value into a constant address.
572 JumpReg, // Jump to a register A (high byte) + register B (low byte).573 StoreI,
573 JumpMem, // Jump to a location pointed to by memory at the current memory address (high byte first).574 /// Store a value to a constant address (low byte only) from a register.
574 Call, // Call a function.575 StoreP,
575 Return, // Return from a function.576 /// Store a value from the currently set memory address from a register, and increment the address n times.
576 CmpI, // Compare A to a constant value (sets flags, but discards result).577 StoreInc,
577 CmpAndI, // Compare A to a constant value with bitwise AND (sets flags, but discards result).578 /// Store a value to an offset on the current stack frame, from a register.
578 Cmp, // Compare A to a value from memory (sets flags, but discards result).579 StoreStck,
579 CmpAnd, // Compare A to a value in memory with bitwise AND (sets flags, but discards result).580 /// Store a value to an offset on the next stack frame, from a register.
580 CmpReg, // Compare A to a value from a register (sets flags, but discards result).581 StoreNStck,
581 CmpAndReg, // Compare A to a value from a register with bitwise AND (sets flags, but discards result).582 /// Store a value to an offset on the previous stack frame, from a register.
582 ShiftL, // Shift B left by 1.583 StorePStck,
583 ShiftR, // Shift B right by 1.584 /// Store a constant value to an offset on the current stack frame.
584 RotateL, // Rotate B left by 1.585 StoreStckI,
585 RotateR, // Rotate B right by 1.586 /// Store a constant value to an offset on the next stack frame.
586 AddI, // Add a constant value to A.587 StoreNStckI,
587 SubI, // Subtract a constant value from A.588 /// Store a constant value to an offset on the previous stack frame.
588 AndI, // Bitwise-AND A with a constant value.589 StorePStckI,
589 AddINF, // Add a constant value to A, without updating flags.590 /// Copy a value from one register to another register.
590 SubINF, // Subtract a constant value from A, without updating flags.591 Copy,
591 AndINF, // Bitwise-AND A with a constant value, without updating flags.592 /// Jump to a constant location.
592 AccumulateAdd, // Add register B to A -> A.593 Jump,
593 AccumulateSub, // Subtract register B from A -> A.594 /// Jump to a register A (high byte) + register B (low byte).
594 AccumulateAnd, // A & B -> A.595 JumpReg,
595 OrI, // Bitwise OR B with A -> A.596 /// Jump to a location pointed to by memory at the current memory address (high byte first).
596 XorI, // Bitwise OR a constant value with A -> A.597 JumpMem,
597 Not, // Invert register A.598 /// Call a function.
598 Add, // Add a value from memory to A.599 Call,
599 Sub, // Subtract a value from memory from A.600 /// Return from a function.
600 And, // AND A with a value from memory.601 Return,
601 Or, // OR A with a value from memory.602 /// Compare A to a constant value (sets flags, but discards result).
602 Xor, // XOR A with a value from memory.603 CmpI,
603 Nop, // No-op.604 /// Compare A to a constant value with bitwise AND (sets flags, but discards result).
604 Nop1, // No-op with 1 extra clock cycle.605 CmpAndI,
605 Nop2, // No-op with 2 extra clock cycles.606 /// Compare A to a value from memory (sets flags, but discards result).
606 Halt, // Halt - stop the program forever (until reset).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,
607};664};
608665
609const Register = enum(u8) {666const Register = enum(u8) {