authorgravatar for koachan@protonmail.comKoakuma <koachan@protonmail.com> 2022-03-17 01:47:17+07:00
committergravatar for koachan@protonmail.comKoakuma <koachan@protonmail.com> 2022-03-17 01:47:17+07:00
logac50ac699f675b581dc374762310ea2dfb3f7427
tree786268b43c42d98d9a10548714cf7d5d567cb907
parentd9c33a610e2f081b6e8d64bfe34f6cb8be61a5b4

stage2 sparcv9: Add encoder test and packed struct workaround


1 files changed, 238 insertions(+), 43 deletions(-)

src/arch/sparcv9/bits.zig+238-43
...@@ -216,7 +216,7 @@ pub const Instruction = union(enum) {...@@ -216,7 +216,7 @@ pub const Instruction = union(enum) {
216 reserved: u8 = 0b00000000,216 reserved: u8 = 0b00000000,
217 rs2: u5,217 rs2: u5,
218 },218 },
219 format_3b: packed struct {219 format_3b: struct {
220 op: u2,220 op: u2,
221 rd: u5,221 rd: u5,
222 op3: u6,222 op3: u6,
...@@ -233,7 +233,7 @@ pub const Instruction = union(enum) {...@@ -233,7 +233,7 @@ pub const Instruction = union(enum) {
233 reserved2: u8 = 0b00000000,233 reserved2: u8 = 0b00000000,
234 rs2: u5,234 rs2: u5,
235 },235 },
236 format_3d: packed struct {236 format_3d: struct {
237 op: u2,237 op: u2,
238 reserved: u5 = 0b00000,238 reserved: u5 = 0b00000,
239 op3: u6,239 op3: u6,
...@@ -251,7 +251,7 @@ pub const Instruction = union(enum) {...@@ -251,7 +251,7 @@ pub const Instruction = union(enum) {
251 reserved: u5 = 0b00000,251 reserved: u5 = 0b00000,
252 rs2: u5,252 rs2: u5,
253 },253 },
254 format_3f: packed struct {254 format_3f: struct {
255 op: u2,255 op: u2,
256 rd: u5,256 rd: u5,
257 op3: u6,257 op3: u6,
...@@ -270,7 +270,7 @@ pub const Instruction = union(enum) {...@@ -270,7 +270,7 @@ pub const Instruction = union(enum) {
270 rs2: u5,270 rs2: u5,
271 },271 },
272 format_3h: packed struct {272 format_3h: packed struct {
273 op: u2,273 op: u2 = 0b10,
274 fixed1: u5 = 0b00000,274 fixed1: u5 = 0b00000,
275 op3: u6 = 0b101000,275 op3: u6 = 0b101000,
276 fixed2: u5 = 0b01111,276 fixed2: u5 = 0b01111,
...@@ -336,8 +336,9 @@ pub const Instruction = union(enum) {...@@ -336,8 +336,9 @@ pub const Instruction = union(enum) {
336 op: u2,336 op: u2,
337 fixed: u3 = 0b000,337 fixed: u3 = 0b000,
338 cc1: u1,338 cc1: u1,
339 cc0: i1,339 cc0: u1,
340 op3: u6,340 op3: u6,
341 rs1: u5,
341 opf: u9,342 opf: u9,
342 rs2: u5,343 rs2: u5,
343 },344 },
...@@ -381,7 +382,7 @@ pub const Instruction = union(enum) {...@@ -381,7 +382,7 @@ pub const Instruction = union(enum) {
381 reserved: u6 = 0b000000,382 reserved: u6 = 0b000000,
382 rs2: u5,383 rs2: u5,
383 },384 },
384 format_4b: packed struct {385 format_4b: struct {
385 op: u2 = 0b10,386 op: u2 = 0b10,
386 rd: u5,387 rd: u5,
387 op3: u6,388 op3: u6,
...@@ -403,7 +404,7 @@ pub const Instruction = union(enum) {...@@ -403,7 +404,7 @@ pub const Instruction = union(enum) {
403 reserved: u6 = 0b000000,404 reserved: u6 = 0b000000,
404 rs2: u5,405 rs2: u5,
405 },406 },
406 format_4d: packed struct {407 format_4d: struct {
407 op: u2 = 0b10,408 op: u2 = 0b10,
408 rd: u5,409 rd: u5,
409 op3: u6,410 op3: u6,
...@@ -486,8 +487,8 @@ pub const Instruction = union(enum) {...@@ -486,8 +487,8 @@ pub const Instruction = union(enum) {
486 };487 };
487488
488 pub const ShiftWidth = enum(u1) {489 pub const ShiftWidth = enum(u1) {
489 Shift32,490 shift32,
490 Shift64,491 shift64,
491 };492 };
492493
493 pub const MemOrderingConstraint = packed struct {494 pub const MemOrderingConstraint = packed struct {
...@@ -509,7 +510,40 @@ pub const Instruction = union(enum) {...@@ -509,7 +510,40 @@ pub const Instruction = union(enum) {
509 pub const Condition = u4;510 pub const Condition = u4;
510511
511 pub fn toU32(self: Instruction) u32 {512 pub fn toU32(self: Instruction) u32 {
512 return @bitCast(u32, self);513 // TODO: Remove this once packed structs work.
514 return switch (self) {
515 .format_1 => |v| @bitCast(u32, v),
516 .format_2a => |v| @bitCast(u32, v),
517 .format_2b => |v| @bitCast(u32, v),
518 .format_2c => |v| @bitCast(u32, v),
519 .format_2d => |v| @bitCast(u32, v),
520 .format_3a => |v| @bitCast(u32, v),
521 .format_3b => |v| (@as(u32, v.op) << 30) | (@as(u32, v.rd) << 25) | (@as(u32, v.op3) << 19) | (@as(u32, v.rs1) << 14) | (@as(u32, v.i) << 13) | @as(u32, v.simm13),
522 .format_3c => |v| @bitCast(u32, v),
523 .format_3d => |v| (@as(u32, v.op) << 30) | (@as(u32, v.reserved) << 25) | (@as(u32, v.op3) << 19) | (@as(u32, v.rs1) << 14) | (@as(u32, v.i) << 13) | @as(u32, v.simm13),
524 .format_3e => |v| @bitCast(u32, v),
525 .format_3f => |v| (@as(u32, v.op) << 30) | (@as(u32, v.rd) << 25) | (@as(u32, v.op3) << 19) | (@as(u32, v.rs1) << 14) | (@as(u32, v.i) << 13) | (@as(u32, v.rcond) << 10) | @as(u32, v.simm10),
526 .format_3g => |v| @bitCast(u32, v),
527 .format_3h => |v| @bitCast(u32, v),
528 .format_3i => |v| @bitCast(u32, v),
529 .format_3j => |v| @bitCast(u32, v),
530 .format_3k => |v| @bitCast(u32, v),
531 .format_3l => |v| @bitCast(u32, v),
532 .format_3m => |v| @bitCast(u32, v),
533 .format_3n => |v| @bitCast(u32, v),
534 .format_3o => |v| @bitCast(u32, v),
535 .format_3p => |v| @bitCast(u32, v),
536 .format_3q => |v| @bitCast(u32, v),
537 .format_3r => |v| @bitCast(u32, v),
538 .format_3s => |v| @bitCast(u32, v),
539 .format_4a => |v| @bitCast(u32, v),
540 .format_4b => |v| (@as(u32, v.op) << 30) | (@as(u32, v.rd) << 25) | (@as(u32, v.op3) << 19) | (@as(u32, v.rs1) << 14) | (@as(u32, v.i) << 13) | (@as(u32, v.cc1) << 12) | (@as(u32, v.cc0) << 11) | @as(u32, v.simm11),
541 .format_4c => |v| @bitCast(u32, v),
542 .format_4d => |v| (@as(u32, v.op) << 30) | (@as(u32, v.rd) << 25) | (@as(u32, v.op3) << 19) | (@as(u32, v.cc2) << 18) | (@as(u32, v.cond) << 14) | (@as(u32, v.i) << 13) | (@as(u32, v.cc1) << 12) | (@as(u32, v.cc0) << 11) | @as(u32, v.simm11),
543 .format_4e => |v| @bitCast(u32, v),
544 .format_4f => |v| @bitCast(u32, v),
545 .format_4g => |v| @bitCast(u32, v),
546 };
513 }547 }
514548
515 fn format1(disp: i32) Instruction {549 fn format1(disp: i32) Instruction {
...@@ -527,12 +561,12 @@ pub const Instruction = union(enum) {...@@ -527,12 +561,12 @@ pub const Instruction = union(enum) {
527 };561 };
528 }562 }
529563
530 fn format2a(op2: u3, rd: Register, imm: i22) Instruction {564 fn format2a(op2: u3, rd: Register, imm: u22) Instruction {
531 return Instruction{565 return Instruction{
532 .format_2a = .{566 .format_2a = .{
533 .rd = rd.enc(),567 .rd = rd.enc(),
534 .op2 = op2,568 .op2 = op2,
535 .imm22 = @bitCast(u22, imm),569 .imm22 = imm,
536 },570 },
537 };571 };
538 }572 }
...@@ -580,17 +614,18 @@ pub const Instruction = union(enum) {...@@ -580,17 +614,18 @@ pub const Instruction = union(enum) {
580 }614 }
581615
582 fn format2d(op2: u3, rcond: RCondition, annul: bool, pt: bool, rs1: Register, disp: i18) Instruction {616 fn format2d(op2: u3, rcond: RCondition, annul: bool, pt: bool, rs1: Register, disp: i18) Instruction {
583 const udisp = @truncate(u16, @bitCast(u18, disp) >> 2);617 const udisp = @bitCast(u18, disp);
584618
585 // In SPARC, branch target needs to be aligned to 4 bytes.619 // In SPARC, branch target needs to be aligned to 4 bytes.
586 assert(udisp % 4 == 0);620 assert(udisp % 4 == 0);
587621
588 // Discard the last two bits since those are implicitly zero,622 // Discard the last two bits since those are implicitly zero,
589 // and split it into low and high parts.623 // and split it into low and high parts.
590 const udisp_hi = @truncate(u2, (udisp & 0b1100_0000_0000_0000) >> 14);624 const udisp_truncated = @truncate(u16, udisp >> 2);
591 const udisp_lo = @truncate(u14, udisp & 0b0011_1111_1111_1111);625 const udisp_hi = @truncate(u2, (udisp_truncated & 0b1100_0000_0000_0000) >> 14);
626 const udisp_lo = @truncate(u14, udisp_truncated & 0b0011_1111_1111_1111);
592 return Instruction{627 return Instruction{
593 .format_2a = .{628 .format_2d = .{
594 .a = @boolToInt(annul),629 .a = @boolToInt(annul),
595 .rcond = @enumToInt(rcond),630 .rcond = @enumToInt(rcond),
596 .op2 = op2,631 .op2 = op2,
...@@ -602,9 +637,10 @@ pub const Instruction = union(enum) {...@@ -602,9 +637,10 @@ pub const Instruction = union(enum) {
602 };637 };
603 }638 }
604639
605 fn format3a(op3: u6, rs1: Register, rs2: Register, rd: Register) Instruction {640 fn format3a(op: u2, op3: u6, rs1: Register, rs2: Register, rd: Register) Instruction {
606 return Instruction{641 return Instruction{
607 .format_3a = .{642 .format_3a = .{
643 .op = op,
608 .rd = rd.enc(),644 .rd = rd.enc(),
609 .op3 = op3,645 .op3 = op3,
610 .rs1 = rs1.enc(),646 .rs1 = rs1.enc(),
...@@ -612,9 +648,10 @@ pub const Instruction = union(enum) {...@@ -612,9 +648,10 @@ pub const Instruction = union(enum) {
612 },648 },
613 };649 };
614 }650 }
615 fn format3b(op3: u6, rs1: Register, imm: i13, rd: Register) Instruction {651 fn format3b(op: u2, op3: u6, rs1: Register, imm: i13, rd: Register) Instruction {
616 return Instruction{652 return Instruction{
617 .format_3b = .{653 .format_3b = .{
654 .op = op,
618 .rd = rd.enc(),655 .rd = rd.enc(),
619 .op3 = op3,656 .op3 = op3,
620 .rs1 = rs1.enc(),657 .rs1 = rs1.enc(),
...@@ -622,27 +659,30 @@ pub const Instruction = union(enum) {...@@ -622,27 +659,30 @@ pub const Instruction = union(enum) {
622 },659 },
623 };660 };
624 }661 }
625 fn format3c(op3: u6, rs1: Register, rs2: Register) Instruction {662 fn format3c(op: u2, op3: u6, rs1: Register, rs2: Register) Instruction {
626 return Instruction{663 return Instruction{
627 .format_3c = .{664 .format_3c = .{
665 .op = op,
628 .op3 = op3,666 .op3 = op3,
629 .rs1 = rs1.enc(),667 .rs1 = rs1.enc(),
630 .rs2 = rs2.enc(),668 .rs2 = rs2.enc(),
631 },669 },
632 };670 };
633 }671 }
634 fn format3d(op3: u6, rs1: Register, imm: i13) Instruction {672 fn format3d(op: u2, op3: u6, rs1: Register, imm: i13) Instruction {
635 return Instruction{673 return Instruction{
636 .format_3d = .{674 .format_3d = .{
675 .op = op,
637 .op3 = op3,676 .op3 = op3,
638 .rs1 = rs1.enc(),677 .rs1 = rs1.enc(),
639 .simm13 = @bitCast(u13, imm),678 .simm13 = @bitCast(u13, imm),
640 },679 },
641 };680 };
642 }681 }
643 fn format3e(op3: u6, rcond: RCondition, rs1: Register, rs2: Register, rd: Register) Instruction {682 fn format3e(op: u2, op3: u6, rcond: RCondition, rs1: Register, rs2: Register, rd: Register) Instruction {
644 return Instruction{683 return Instruction{
645 .format_3e = .{684 .format_3e = .{
685 .op = op,
646 .rd = rd.enc(),686 .rd = rd.enc(),
647 .op3 = op3,687 .op3 = op3,
648 .rs1 = rs1.enc(),688 .rs1 = rs1.enc(),
...@@ -651,9 +691,10 @@ pub const Instruction = union(enum) {...@@ -651,9 +691,10 @@ pub const Instruction = union(enum) {
651 },691 },
652 };692 };
653 }693 }
654 fn format3f(op3: u6, rcond: RCondition, rs1: Register, imm: i10, rd: Register) Instruction {694 fn format3f(op: u2, op3: u6, rcond: RCondition, rs1: Register, imm: i10, rd: Register) Instruction {
655 return Instruction{695 return Instruction{
656 .format_3f = .{696 .format_3f = .{
697 .op = op,
657 .rd = rd.enc(),698 .rd = rd.enc(),
658 .op3 = op3,699 .op3 = op3,
659 .rs1 = rs1.enc(),700 .rs1 = rs1.enc(),
...@@ -662,9 +703,10 @@ pub const Instruction = union(enum) {...@@ -662,9 +703,10 @@ pub const Instruction = union(enum) {
662 },703 },
663 };704 };
664 }705 }
665 fn format3g(op3: u6, rs1: Register, rs2: Register, rd: Register) Instruction {706 fn format3g(op: u2, op3: u6, rs1: Register, rs2: Register, rd: Register) Instruction {
666 return Instruction{707 return Instruction{
667 .format_3g = .{708 .format_3g = .{
709 .op = op,
668 .rd = rd.enc(),710 .rd = rd.enc(),
669 .op3 = op3,711 .op3 = op3,
670 .rs1 = rs1.enc(),712 .rs1 = rs1.enc(),
...@@ -680,9 +722,10 @@ pub const Instruction = union(enum) {...@@ -680,9 +722,10 @@ pub const Instruction = union(enum) {
680 },722 },
681 };723 };
682 }724 }
683 fn format3i(op3: u6, rs1: Register, rs2: Register, rd: Register, asi: ASI) Instruction {725 fn format3i(op: u2, op3: u6, rs1: Register, rs2: Register, rd: Register, asi: ASI) Instruction {
684 return Instruction{726 return Instruction{
685 .format_3i = .{727 .format_3i = .{
728 .op = op,
686 .rd = rd.enc(),729 .rd = rd.enc(),
687 .op3 = op3,730 .op3 = op3,
688 .rs1 = rs1.enc(),731 .rs1 = rs1.enc(),
...@@ -691,18 +734,20 @@ pub const Instruction = union(enum) {...@@ -691,18 +734,20 @@ pub const Instruction = union(enum) {
691 },734 },
692 };735 };
693 }736 }
694 fn format3j(op3: u6, impl_dep1: u5, impl_dep2: u19) Instruction {737 fn format3j(op: u2, op3: u6, impl_dep1: u5, impl_dep2: u19) Instruction {
695 return Instruction{738 return Instruction{
696 .format_3j = .{739 .format_3j = .{
740 .op = op,
697 .impl_dep1 = impl_dep1,741 .impl_dep1 = impl_dep1,
698 .op3 = op3,742 .op3 = op3,
699 .impl_dep2 = impl_dep2,743 .impl_dep2 = impl_dep2,
700 },744 },
701 };745 };
702 }746 }
703 fn format3k(op3: u6, sw: ShiftWidth, rs1: Register, rs2: Register, rd: Register) Instruction {747 fn format3k(op: u2, op3: u6, sw: ShiftWidth, rs1: Register, rs2: Register, rd: Register) Instruction {
704 return Instruction{748 return Instruction{
705 .format_3k = .{749 .format_3k = .{
750 .op = op,
706 .rd = rd.enc(),751 .rd = rd.enc(),
707 .op3 = op3,752 .op3 = op3,
708 .rs1 = rs1.enc(),753 .rs1 = rs1.enc(),
...@@ -711,29 +756,32 @@ pub const Instruction = union(enum) {...@@ -711,29 +756,32 @@ pub const Instruction = union(enum) {
711 },756 },
712 };757 };
713 }758 }
714 fn format3l(op3: u6, rs1: Register, shift_count: u5, rd: Register) Instruction {759 fn format3l(op: u2, op3: u6, rs1: Register, shift_count: u5, rd: Register) Instruction {
715 return Instruction{760 return Instruction{
716 .format_3l = .{761 .format_3l = .{
762 .op = op,
717 .rd = rd.enc(),763 .rd = rd.enc(),
718 .op3 = op3,764 .op3 = op3,
719 .rs1 = rs1.enc(),765 .rs1 = rs1.enc(),
720 .shift_count = shift_count,766 .shcnt32 = shift_count,
721 },767 },
722 };768 };
723 }769 }
724 fn format3m(op3: u6, rs1: Register, shift_count: u6, rd: Register) Instruction {770 fn format3m(op: u2, op3: u6, rs1: Register, shift_count: u6, rd: Register) Instruction {
725 return Instruction{771 return Instruction{
726 .format_3m = .{772 .format_3m = .{
773 .op = op,
727 .rd = rd.enc(),774 .rd = rd.enc(),
728 .op3 = op3,775 .op3 = op3,
729 .rs1 = rs1.enc(),776 .rs1 = rs1.enc(),
730 .shift_count = shift_count,777 .shcnt64 = shift_count,
731 },778 },
732 };779 };
733 }780 }
734 fn format3n(op3: u6, opf: u9, rs2: Register, rd: Register) Instruction {781 fn format3n(op: u2, op3: u6, opf: u9, rs2: Register, rd: Register) Instruction {
735 return Instruction{782 return Instruction{
736 .format_3n = .{783 .format_3n = .{
784 .op = op,
737 .rd = rd.enc(),785 .rd = rd.enc(),
738 .op3 = op3,786 .op3 = op3,
739 .opf = opf,787 .opf = opf,
...@@ -741,11 +789,12 @@ pub const Instruction = union(enum) {...@@ -741,11 +789,12 @@ pub const Instruction = union(enum) {
741 },789 },
742 };790 };
743 }791 }
744 fn format3o(op3: u6, opf: u9, ccr: CCR, rs1: Register, rs2: Register) Instruction {792 fn format3o(op: u2, op3: u6, opf: u9, ccr: CCR, rs1: Register, rs2: Register) Instruction {
745 const ccr_cc1 = @truncate(u1, @enumToInt(ccr) >> 1);793 const ccr_cc1 = @truncate(u1, @enumToInt(ccr) >> 1);
746 const ccr_cc0 = @truncate(u1, @enumToInt(ccr));794 const ccr_cc0 = @truncate(u1, @enumToInt(ccr));
747 return Instruction{795 return Instruction{
748 .format_3o = .{796 .format_3o = .{
797 .op = op,
749 .cc1 = ccr_cc1,798 .cc1 = ccr_cc1,
750 .cc0 = ccr_cc0,799 .cc0 = ccr_cc0,
751 .op3 = op3,800 .op3 = op3,
...@@ -755,9 +804,10 @@ pub const Instruction = union(enum) {...@@ -755,9 +804,10 @@ pub const Instruction = union(enum) {
755 },804 },
756 };805 };
757 }806 }
758 fn format3p(op3: u6, opf: u9, rs1: Register, rs2: Register, rd: Register) Instruction {807 fn format3p(op: u2, op3: u6, opf: u9, rs1: Register, rs2: Register, rd: Register) Instruction {
759 return Instruction{808 return Instruction{
760 .format_3p = .{809 .format_3p = .{
810 .op = op,
761 .rd = rd.enc(),811 .rd = rd.enc(),
762 .op3 = op3,812 .op3 = op3,
763 .rs1 = rs1.enc(),813 .rs1 = rs1.enc(),
...@@ -766,26 +816,29 @@ pub const Instruction = union(enum) {...@@ -766,26 +816,29 @@ pub const Instruction = union(enum) {
766 },816 },
767 };817 };
768 }818 }
769 fn format3q(op3: u6, rs1: Register, rd: Register) Instruction {819 fn format3q(op: u2, op3: u6, rs1: Register, rd: Register) Instruction {
770 return Instruction{820 return Instruction{
771 .format_3q = .{821 .format_3q = .{
822 .op = op,
772 .rd = rd.enc(),823 .rd = rd.enc(),
773 .op3 = op3,824 .op3 = op3,
774 .rs1 = rs1.enc(),825 .rs1 = rs1.enc(),
775 },826 },
776 };827 };
777 }828 }
778 fn format3r(op3: u6, fcn: u5) Instruction {829 fn format3r(op: u2, op3: u6, fcn: u5) Instruction {
779 return Instruction{830 return Instruction{
780 .format_3r = .{831 .format_3r = .{
832 .op = op,
781 .fcn = fcn,833 .fcn = fcn,
782 .op3 = op3,834 .op3 = op3,
783 },835 },
784 };836 };
785 }837 }
786 fn format3s(op3: u6, rd: Register) Instruction {838 fn format3s(op: u2, op3: u6, rd: Register) Instruction {
787 return Instruction{839 return Instruction{
788 .format_3s = .{840 .format_3s = .{
841 .op = op,
789 .rd = rd.enc(),842 .rd = rd.enc(),
790 .op3 = op3,843 .op3 = op3,
791 },844 },
...@@ -796,7 +849,7 @@ pub const Instruction = union(enum) {...@@ -796,7 +849,7 @@ pub const Instruction = union(enum) {
796 const ccr_cc1 = @truncate(u1, @enumToInt(ccr) >> 1);849 const ccr_cc1 = @truncate(u1, @enumToInt(ccr) >> 1);
797 const ccr_cc0 = @truncate(u1, @enumToInt(ccr));850 const ccr_cc0 = @truncate(u1, @enumToInt(ccr));
798 return Instruction{851 return Instruction{
799 .format4a = .{852 .format_4a = .{
800 .rd = rd.enc(),853 .rd = rd.enc(),
801 .op3 = op3,854 .op3 = op3,
802 .rs1 = rs1.enc(),855 .rs1 = rs1.enc(),
...@@ -811,7 +864,7 @@ pub const Instruction = union(enum) {...@@ -811,7 +864,7 @@ pub const Instruction = union(enum) {
811 const ccr_cc1 = @truncate(u1, @enumToInt(ccr) >> 1);864 const ccr_cc1 = @truncate(u1, @enumToInt(ccr) >> 1);
812 const ccr_cc0 = @truncate(u1, @enumToInt(ccr));865 const ccr_cc0 = @truncate(u1, @enumToInt(ccr));
813 return Instruction{866 return Instruction{
814 .format4b = .{867 .format_4b = .{
815 .rd = rd.enc(),868 .rd = rd.enc(),
816 .op3 = op3,869 .op3 = op3,
817 .rs1 = rs1.enc(),870 .rs1 = rs1.enc(),
...@@ -827,7 +880,7 @@ pub const Instruction = union(enum) {...@@ -827,7 +880,7 @@ pub const Instruction = union(enum) {
827 const ccr_cc1 = @truncate(u1, @enumToInt(ccr) >> 1);880 const ccr_cc1 = @truncate(u1, @enumToInt(ccr) >> 1);
828 const ccr_cc0 = @truncate(u1, @enumToInt(ccr));881 const ccr_cc0 = @truncate(u1, @enumToInt(ccr));
829 return Instruction{882 return Instruction{
830 .format4c = .{883 .format_4c = .{
831 .rd = rd.enc(),884 .rd = rd.enc(),
832 .op3 = op3,885 .op3 = op3,
833 .cc2 = ccr_cc2,886 .cc2 = ccr_cc2,
...@@ -844,7 +897,7 @@ pub const Instruction = union(enum) {...@@ -844,7 +897,7 @@ pub const Instruction = union(enum) {
844 const ccr_cc1 = @truncate(u1, @enumToInt(ccr) >> 1);897 const ccr_cc1 = @truncate(u1, @enumToInt(ccr) >> 1);
845 const ccr_cc0 = @truncate(u1, @enumToInt(ccr));898 const ccr_cc0 = @truncate(u1, @enumToInt(ccr));
846 return Instruction{899 return Instruction{
847 .format4d = .{900 .format_4d = .{
848 .rd = rd.enc(),901 .rd = rd.enc(),
849 .op3 = op3,902 .op3 = op3,
850 .cc2 = ccr_cc2,903 .cc2 = ccr_cc2,
...@@ -860,7 +913,7 @@ pub const Instruction = union(enum) {...@@ -860,7 +913,7 @@ pub const Instruction = union(enum) {
860 const ccr_cc1 = @truncate(u1, @enumToInt(ccr) >> 1);913 const ccr_cc1 = @truncate(u1, @enumToInt(ccr) >> 1);
861 const ccr_cc0 = @truncate(u1, @enumToInt(ccr));914 const ccr_cc0 = @truncate(u1, @enumToInt(ccr));
862 return Instruction{915 return Instruction{
863 .format4e = .{916 .format_4e = .{
864 .rd = rd.enc(),917 .rd = rd.enc(),
865 .op3 = op3,918 .op3 = op3,
866 .rs1 = rs1.enc(),919 .rs1 = rs1.enc(),
...@@ -880,7 +933,7 @@ pub const Instruction = union(enum) {...@@ -880,7 +933,7 @@ pub const Instruction = union(enum) {
880 rd: Register,933 rd: Register,
881 ) Instruction {934 ) Instruction {
882 return Instruction{935 return Instruction{
883 .format4f = .{936 .format_4f = .{
884 .rd = rd.enc(),937 .rd = rd.enc(),
885 .op3 = op3,938 .op3 = op3,
886 .rs1 = rs1.enc(),939 .rs1 = rs1.enc(),
...@@ -893,7 +946,7 @@ pub const Instruction = union(enum) {...@@ -893,7 +946,7 @@ pub const Instruction = union(enum) {
893946
894 fn format4g(op3: u6, opf_low: u6, opf_cc: u3, cond: Condition, rs2: Register, rd: Register) Instruction {947 fn format4g(op3: u6, opf_low: u6, opf_cc: u3, cond: Condition, rs2: Register, rd: Register) Instruction {
895 return Instruction{948 return Instruction{
896 .format4g = .{949 .format_4g = .{
897 .rd = rd.enc(),950 .rd = rd.enc(),
898 .op3 = op3,951 .op3 = op3,
899 .cond = cond,952 .cond = cond,
...@@ -904,3 +957,145 @@ pub const Instruction = union(enum) {...@@ -904,3 +957,145 @@ pub const Instruction = union(enum) {
904 };957 };
905 }958 }
906};959};
960
961test "Serialize formats" {
962 const Testcase = struct {
963 inst: Instruction,
964 expected: u32,
965 };
966
967 // Note that the testcases might or might not be a valid instruction
968 // This is mostly just to check the behavior of the format packed structs
969 // since currently stage1 doesn't properly implement it in all cases
970 const testcases = [_]Testcase{
971 .{
972 .inst = Instruction.format1(4),
973 .expected = 0b01_000000000000000000000000000001,
974 },
975 .{
976 .inst = Instruction.format2a(4, .g0, 0),
977 .expected = 0b00_00000_100_0000000000000000000000,
978 },
979 .{
980 .inst = Instruction.format2b(6, 3, true, -4),
981 .expected = 0b00_1_0011_110_1111111111111111111111,
982 },
983 .{
984 .inst = Instruction.format2c(3, 0, false, true, .xcc, 8),
985 .expected = 0b00_0_0000_011_1_0_1_0000000000000000010,
986 },
987 .{
988 .inst = Instruction.format2d(7, .eq_zero, false, true, .o0, 20),
989 .expected = 0b00_0_0_001_111_00_1_01000_00000000000101,
990 },
991 .{
992 .inst = Instruction.format3a(3, 5, .g0, .o1, .l2),
993 .expected = 0b11_10010_000101_00000_0_00000000_01001,
994 },
995 .{
996 .inst = Instruction.format3b(3, 5, .g0, -1, .l2),
997 .expected = 0b11_10010_000101_00000_1_1111111111111,
998 },
999 .{
1000 .inst = Instruction.format3c(3, 5, .g0, .o1),
1001 .expected = 0b11_00000_000101_00000_0_00000000_01001,
1002 },
1003 .{
1004 .inst = Instruction.format3d(3, 5, .g0, 0),
1005 .expected = 0b11_00000_000101_00000_1_0000000000000,
1006 },
1007 .{
1008 .inst = Instruction.format3e(3, 5, .ne_zero, .g0, .o1, .l2),
1009 .expected = 0b11_10010_000101_00000_0_101_00000_01001,
1010 },
1011 .{
1012 .inst = Instruction.format3f(3, 5, .ne_zero, .g0, -1, .l2),
1013 .expected = 0b11_10010_000101_00000_1_101_1111111111,
1014 },
1015 .{
1016 .inst = Instruction.format3g(3, 5, .g0, .o1, .l2),
1017 .expected = 0b11_10010_000101_00000_1_00000000_01001,
1018 },
1019 .{
1020 .inst = Instruction.format3h(.{}, .{}),
1021 .expected = 0b10_00000_101000_01111_1_000000_000_0000,
1022 },
1023 .{
1024 .inst = Instruction.format3i(3, 5, .g0, .o1, .l2, .asi_primary_little),
1025 .expected = 0b11_10010_000101_00000_0_10001000_01001,
1026 },
1027 .{
1028 .inst = Instruction.format3j(3, 5, 31, 0),
1029 .expected = 0b11_11111_000101_0000000000000000000,
1030 },
1031 .{
1032 .inst = Instruction.format3k(3, 5, .shift32, .g0, .o1, .l2),
1033 .expected = 0b11_10010_000101_00000_0_0_0000000_01001,
1034 },
1035 .{
1036 .inst = Instruction.format3l(3, 5, .g0, 31, .l2),
1037 .expected = 0b11_10010_000101_00000_1_0_0000000_11111,
1038 },
1039 .{
1040 .inst = Instruction.format3m(3, 5, .g0, 63, .l2),
1041 .expected = 0b11_10010_000101_00000_1_1_000000_111111,
1042 },
1043 .{
1044 .inst = Instruction.format3n(3, 5, 0, .o1, .l2),
1045 .expected = 0b11_10010_000101_00000_000000000_01001,
1046 },
1047 .{
1048 .inst = Instruction.format3o(3, 5, 0, .xcc, .o1, .l2),
1049 .expected = 0b11_000_1_0_000101_01001_000000000_10010,
1050 },
1051 .{
1052 .inst = Instruction.format3p(3, 5, 0, .g0, .o1, .l2),
1053 .expected = 0b11_10010_000101_00000_000000000_01001,
1054 },
1055 .{
1056 .inst = Instruction.format3q(3, 5, .g0, .o1),
1057 .expected = 0b11_01001_000101_00000_00000000000000,
1058 },
1059 .{
1060 .inst = Instruction.format3r(3, 5, 4),
1061 .expected = 0b11_00100_000101_0000000000000000000,
1062 },
1063 .{
1064 .inst = Instruction.format3s(3, 5, .g0),
1065 .expected = 0b11_00000_000101_0000000000000000000,
1066 },
1067 .{
1068 .inst = Instruction.format4a(8, .xcc, .g0, .o1, .l2),
1069 .expected = 0b10_10010_001000_00000_0_1_0_000000_01001,
1070 },
1071 .{
1072 .inst = Instruction.format4b(8, .xcc, .g0, -1, .l2),
1073 .expected = 0b10_10010_001000_00000_1_1_0_11111111111,
1074 },
1075 .{
1076 .inst = Instruction.format4c(8, 0, .xcc, .g0, .o1),
1077 .expected = 0b10_01001_001000_1_0000_0_1_0_000000_00000,
1078 },
1079 .{
1080 .inst = Instruction.format4d(8, 0, .xcc, 0, .l2),
1081 .expected = 0b10_10010_001000_1_0000_1_1_0_00000000000
1082 },
1083 .{
1084 .inst = Instruction.format4e(8, .xcc, .g0, .o1, 0),
1085 .expected = 0b10_01001_001000_00000_1_1_0_0000_0000000,
1086 },
1087 .{
1088 .inst = Instruction.format4f(8, 4, .eq_zero, .g0, .o1, .l2),
1089 .expected = 0b10_10010_001000_00000_0_001_00100_01001,
1090 },
1091 .{
1092 .inst = Instruction.format4g(8, 4, 2, 0, .o1, .l2),
1093 .expected = 0b10_10010_001000_0_0000_010_000100_01001,
1094 },
1095 };
1096
1097 for (testcases) |case| {
1098 const actual = case.inst.toU32();
1099 try testing.expectEqual(case.expected, actual);
1100 }
1101}