| ... | @@ -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 | }; |
| 487 | | 488 | |
| 488 | pub const ShiftWidth = enum(u1) { | 489 | pub const ShiftWidth = enum(u1) { |
| 489 | Shift32, | 490 | shift32, |
| 490 | Shift64, | 491 | shift64, |
| 491 | }; | 492 | }; |
| 492 | | 493 | |
| 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; |
| 510 | | 511 | |
| 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 | } |
| 514 | | 548 | |
| 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 | } |
| 529 | | 563 | |
| 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 | } |
| 581 | | 615 | |
| 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); |
| 584 | | 618 | |
| 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); |
| 587 | | 621 | |
| 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 | } |
| 604 | | 639 | |
| 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) { |
| 893 | | 946 | |
| 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 | |
| | 961 | test "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 | } |