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) {
216216 reserved: u8 = 0b00000000,
217217 rs2: u5,
218218 },
219 format_3b: packed struct {
219 format_3b: struct {
220220 op: u2,
221221 rd: u5,
222222 op3: u6,
......@@ -233,7 +233,7 @@ pub const Instruction = union(enum) {
233233 reserved2: u8 = 0b00000000,
234234 rs2: u5,
235235 },
236 format_3d: packed struct {
236 format_3d: struct {
237237 op: u2,
238238 reserved: u5 = 0b00000,
239239 op3: u6,
......@@ -251,7 +251,7 @@ pub const Instruction = union(enum) {
251251 reserved: u5 = 0b00000,
252252 rs2: u5,
253253 },
254 format_3f: packed struct {
254 format_3f: struct {
255255 op: u2,
256256 rd: u5,
257257 op3: u6,
......@@ -270,7 +270,7 @@ pub const Instruction = union(enum) {
270270 rs2: u5,
271271 },
272272 format_3h: packed struct {
273 op: u2,
273 op: u2 = 0b10,
274274 fixed1: u5 = 0b00000,
275275 op3: u6 = 0b101000,
276276 fixed2: u5 = 0b01111,
......@@ -336,8 +336,9 @@ pub const Instruction = union(enum) {
336336 op: u2,
337337 fixed: u3 = 0b000,
338338 cc1: u1,
339 cc0: i1,
339 cc0: u1,
340340 op3: u6,
341 rs1: u5,
341342 opf: u9,
342343 rs2: u5,
343344 },
......@@ -381,7 +382,7 @@ pub const Instruction = union(enum) {
381382 reserved: u6 = 0b000000,
382383 rs2: u5,
383384 },
384 format_4b: packed struct {
385 format_4b: struct {
385386 op: u2 = 0b10,
386387 rd: u5,
387388 op3: u6,
......@@ -403,7 +404,7 @@ pub const Instruction = union(enum) {
403404 reserved: u6 = 0b000000,
404405 rs2: u5,
405406 },
406 format_4d: packed struct {
407 format_4d: struct {
407408 op: u2 = 0b10,
408409 rd: u5,
409410 op3: u6,
......@@ -486,8 +487,8 @@ pub const Instruction = union(enum) {
486487 };
487488
488489 pub const ShiftWidth = enum(u1) {
489 Shift32,
490 Shift64,
490 shift32,
491 shift64,
491492 };
492493
493494 pub const MemOrderingConstraint = packed struct {
......@@ -509,7 +510,40 @@ pub const Instruction = union(enum) {
509510 pub const Condition = u4;
510511
511512 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 };
513547 }
514548
515549 fn format1(disp: i32) Instruction {
......@@ -527,12 +561,12 @@ pub const Instruction = union(enum) {
527561 };
528562 }
529563
530 fn format2a(op2: u3, rd: Register, imm: i22) Instruction {
564 fn format2a(op2: u3, rd: Register, imm: u22) Instruction {
531565 return Instruction{
532566 .format_2a = .{
533567 .rd = rd.enc(),
534568 .op2 = op2,
535 .imm22 = @bitCast(u22, imm),
569 .imm22 = imm,
536570 },
537571 };
538572 }
......@@ -580,17 +614,18 @@ pub const Instruction = union(enum) {
580614 }
581615
582616 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
585619 // In SPARC, branch target needs to be aligned to 4 bytes.
586620 assert(udisp % 4 == 0);
587621
588622 // Discard the last two bits since those are implicitly zero,
589623 // and split it into low and high parts.
590 const udisp_hi = @truncate(u2, (udisp & 0b1100_0000_0000_0000) >> 14);
591 const udisp_lo = @truncate(u14, udisp & 0b0011_1111_1111_1111);
624 const udisp_truncated = @truncate(u16, udisp >> 2);
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);
592627 return Instruction{
593 .format_2a = .{
628 .format_2d = .{
594629 .a = @boolToInt(annul),
595630 .rcond = @enumToInt(rcond),
596631 .op2 = op2,
......@@ -602,9 +637,10 @@ pub const Instruction = union(enum) {
602637 };
603638 }
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 {
606641 return Instruction{
607642 .format_3a = .{
643 .op = op,
608644 .rd = rd.enc(),
609645 .op3 = op3,
610646 .rs1 = rs1.enc(),
......@@ -612,9 +648,10 @@ pub const Instruction = union(enum) {
612648 },
613649 };
614650 }
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 {
616652 return Instruction{
617653 .format_3b = .{
654 .op = op,
618655 .rd = rd.enc(),
619656 .op3 = op3,
620657 .rs1 = rs1.enc(),
......@@ -622,27 +659,30 @@ pub const Instruction = union(enum) {
622659 },
623660 };
624661 }
625 fn format3c(op3: u6, rs1: Register, rs2: Register) Instruction {
662 fn format3c(op: u2, op3: u6, rs1: Register, rs2: Register) Instruction {
626663 return Instruction{
627664 .format_3c = .{
665 .op = op,
628666 .op3 = op3,
629667 .rs1 = rs1.enc(),
630668 .rs2 = rs2.enc(),
631669 },
632670 };
633671 }
634 fn format3d(op3: u6, rs1: Register, imm: i13) Instruction {
672 fn format3d(op: u2, op3: u6, rs1: Register, imm: i13) Instruction {
635673 return Instruction{
636674 .format_3d = .{
675 .op = op,
637676 .op3 = op3,
638677 .rs1 = rs1.enc(),
639678 .simm13 = @bitCast(u13, imm),
640679 },
641680 };
642681 }
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 {
644683 return Instruction{
645684 .format_3e = .{
685 .op = op,
646686 .rd = rd.enc(),
647687 .op3 = op3,
648688 .rs1 = rs1.enc(),
......@@ -651,9 +691,10 @@ pub const Instruction = union(enum) {
651691 },
652692 };
653693 }
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 {
655695 return Instruction{
656696 .format_3f = .{
697 .op = op,
657698 .rd = rd.enc(),
658699 .op3 = op3,
659700 .rs1 = rs1.enc(),
......@@ -662,9 +703,10 @@ pub const Instruction = union(enum) {
662703 },
663704 };
664705 }
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 {
666707 return Instruction{
667708 .format_3g = .{
709 .op = op,
668710 .rd = rd.enc(),
669711 .op3 = op3,
670712 .rs1 = rs1.enc(),
......@@ -680,9 +722,10 @@ pub const Instruction = union(enum) {
680722 },
681723 };
682724 }
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 {
684726 return Instruction{
685727 .format_3i = .{
728 .op = op,
686729 .rd = rd.enc(),
687730 .op3 = op3,
688731 .rs1 = rs1.enc(),
......@@ -691,18 +734,20 @@ pub const Instruction = union(enum) {
691734 },
692735 };
693736 }
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 {
695738 return Instruction{
696739 .format_3j = .{
740 .op = op,
697741 .impl_dep1 = impl_dep1,
698742 .op3 = op3,
699743 .impl_dep2 = impl_dep2,
700744 },
701745 };
702746 }
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 {
704748 return Instruction{
705749 .format_3k = .{
750 .op = op,
706751 .rd = rd.enc(),
707752 .op3 = op3,
708753 .rs1 = rs1.enc(),
......@@ -711,29 +756,32 @@ pub const Instruction = union(enum) {
711756 },
712757 };
713758 }
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 {
715760 return Instruction{
716761 .format_3l = .{
762 .op = op,
717763 .rd = rd.enc(),
718764 .op3 = op3,
719765 .rs1 = rs1.enc(),
720 .shift_count = shift_count,
766 .shcnt32 = shift_count,
721767 },
722768 };
723769 }
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 {
725771 return Instruction{
726772 .format_3m = .{
773 .op = op,
727774 .rd = rd.enc(),
728775 .op3 = op3,
729776 .rs1 = rs1.enc(),
730 .shift_count = shift_count,
777 .shcnt64 = shift_count,
731778 },
732779 };
733780 }
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 {
735782 return Instruction{
736783 .format_3n = .{
784 .op = op,
737785 .rd = rd.enc(),
738786 .op3 = op3,
739787 .opf = opf,
......@@ -741,11 +789,12 @@ pub const Instruction = union(enum) {
741789 },
742790 };
743791 }
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 {
745793 const ccr_cc1 = @truncate(u1, @enumToInt(ccr) >> 1);
746794 const ccr_cc0 = @truncate(u1, @enumToInt(ccr));
747795 return Instruction{
748796 .format_3o = .{
797 .op = op,
749798 .cc1 = ccr_cc1,
750799 .cc0 = ccr_cc0,
751800 .op3 = op3,
......@@ -755,9 +804,10 @@ pub const Instruction = union(enum) {
755804 },
756805 };
757806 }
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 {
759808 return Instruction{
760809 .format_3p = .{
810 .op = op,
761811 .rd = rd.enc(),
762812 .op3 = op3,
763813 .rs1 = rs1.enc(),
......@@ -766,26 +816,29 @@ pub const Instruction = union(enum) {
766816 },
767817 };
768818 }
769 fn format3q(op3: u6, rs1: Register, rd: Register) Instruction {
819 fn format3q(op: u2, op3: u6, rs1: Register, rd: Register) Instruction {
770820 return Instruction{
771821 .format_3q = .{
822 .op = op,
772823 .rd = rd.enc(),
773824 .op3 = op3,
774825 .rs1 = rs1.enc(),
775826 },
776827 };
777828 }
778 fn format3r(op3: u6, fcn: u5) Instruction {
829 fn format3r(op: u2, op3: u6, fcn: u5) Instruction {
779830 return Instruction{
780831 .format_3r = .{
832 .op = op,
781833 .fcn = fcn,
782834 .op3 = op3,
783835 },
784836 };
785837 }
786 fn format3s(op3: u6, rd: Register) Instruction {
838 fn format3s(op: u2, op3: u6, rd: Register) Instruction {
787839 return Instruction{
788840 .format_3s = .{
841 .op = op,
789842 .rd = rd.enc(),
790843 .op3 = op3,
791844 },
......@@ -796,7 +849,7 @@ pub const Instruction = union(enum) {
796849 const ccr_cc1 = @truncate(u1, @enumToInt(ccr) >> 1);
797850 const ccr_cc0 = @truncate(u1, @enumToInt(ccr));
798851 return Instruction{
799 .format4a = .{
852 .format_4a = .{
800853 .rd = rd.enc(),
801854 .op3 = op3,
802855 .rs1 = rs1.enc(),
......@@ -811,7 +864,7 @@ pub const Instruction = union(enum) {
811864 const ccr_cc1 = @truncate(u1, @enumToInt(ccr) >> 1);
812865 const ccr_cc0 = @truncate(u1, @enumToInt(ccr));
813866 return Instruction{
814 .format4b = .{
867 .format_4b = .{
815868 .rd = rd.enc(),
816869 .op3 = op3,
817870 .rs1 = rs1.enc(),
......@@ -827,7 +880,7 @@ pub const Instruction = union(enum) {
827880 const ccr_cc1 = @truncate(u1, @enumToInt(ccr) >> 1);
828881 const ccr_cc0 = @truncate(u1, @enumToInt(ccr));
829882 return Instruction{
830 .format4c = .{
883 .format_4c = .{
831884 .rd = rd.enc(),
832885 .op3 = op3,
833886 .cc2 = ccr_cc2,
......@@ -844,7 +897,7 @@ pub const Instruction = union(enum) {
844897 const ccr_cc1 = @truncate(u1, @enumToInt(ccr) >> 1);
845898 const ccr_cc0 = @truncate(u1, @enumToInt(ccr));
846899 return Instruction{
847 .format4d = .{
900 .format_4d = .{
848901 .rd = rd.enc(),
849902 .op3 = op3,
850903 .cc2 = ccr_cc2,
......@@ -860,7 +913,7 @@ pub const Instruction = union(enum) {
860913 const ccr_cc1 = @truncate(u1, @enumToInt(ccr) >> 1);
861914 const ccr_cc0 = @truncate(u1, @enumToInt(ccr));
862915 return Instruction{
863 .format4e = .{
916 .format_4e = .{
864917 .rd = rd.enc(),
865918 .op3 = op3,
866919 .rs1 = rs1.enc(),
......@@ -880,7 +933,7 @@ pub const Instruction = union(enum) {
880933 rd: Register,
881934 ) Instruction {
882935 return Instruction{
883 .format4f = .{
936 .format_4f = .{
884937 .rd = rd.enc(),
885938 .op3 = op3,
886939 .rs1 = rs1.enc(),
......@@ -893,7 +946,7 @@ pub const Instruction = union(enum) {
893946
894947 fn format4g(op3: u6, opf_low: u6, opf_cc: u3, cond: Condition, rs2: Register, rd: Register) Instruction {
895948 return Instruction{
896 .format4g = .{
949 .format_4g = .{
897950 .rd = rd.enc(),
898951 .op3 = op3,
899952 .cond = cond,
......@@ -904,3 +957,145 @@ pub const Instruction = union(enum) {
904957 };
905958 }
906959};
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}