authorgravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-02-19 20:13:46+01:00
committergravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-02-21 22:44:47+01:00
log19c683fab01f6f7141166b7fea2c5932a819a727
tree7921288bd698d301c70485a13feeaa89f2d9f839
parenta9154a7eaf3e126ade91732df3ee14f3988b08f5
signaturelock-open Commit is signed but in an unrecognized format.

stage2 AArch64: distinguish between sp/wsp and xzr/wzr


3 files changed, 84 insertions(+), 56 deletions(-)

src/arch/aarch64/CodeGen.zig+3-3
...@@ -372,7 +372,7 @@ fn gen(self: *Self) !void {...@@ -372,7 +372,7 @@ fn gen(self: *Self) !void {
372 .data = .{ .load_store_register_pair = .{372 .data = .{ .load_store_register_pair = .{
373 .rt = .x29,373 .rt = .x29,
374 .rt2 = .x30,374 .rt2 = .x30,
375 .rn = Register.sp,375 .rn = .sp,
376 .offset = Instruction.LoadStorePairOffset.pre_index(-16),376 .offset = Instruction.LoadStorePairOffset.pre_index(-16),
377 } },377 } },
378 });378 });
...@@ -407,7 +407,7 @@ fn gen(self: *Self) !void {...@@ -407,7 +407,7 @@ fn gen(self: *Self) !void {
407 self.saved_regs_stack_space = 16;407 self.saved_regs_stack_space = 16;
408 inline for (callee_preserved_regs) |reg| {408 inline for (callee_preserved_regs) |reg| {
409 if (self.register_manager.isRegAllocated(reg)) {409 if (self.register_manager.isRegAllocated(reg)) {
410 saved_regs |= @as(u32, 1) << reg.id();410 saved_regs |= @as(u32, 1) << @intCast(u5, reg.id());
411 self.saved_regs_stack_space += 8;411 self.saved_regs_stack_space += 8;
412 }412 }
413 }413 }
...@@ -475,7 +475,7 @@ fn gen(self: *Self) !void {...@@ -475,7 +475,7 @@ fn gen(self: *Self) !void {
475 .data = .{ .load_store_register_pair = .{475 .data = .{ .load_store_register_pair = .{
476 .rt = .x29,476 .rt = .x29,
477 .rt2 = .x30,477 .rt2 = .x30,
478 .rn = Register.sp,478 .rn = .sp,
479 .offset = Instruction.LoadStorePairOffset.post_index(16),479 .offset = Instruction.LoadStorePairOffset.post_index(16),
480 } },480 } },
481 });481 });
src/arch/aarch64/Emit.zig+2-2
...@@ -909,7 +909,7 @@ fn mirPushPopRegs(emit: *Emit, inst: Mir.Inst.Index) !void {...@@ -909,7 +909,7 @@ fn mirPushPopRegs(emit: *Emit, inst: Mir.Inst.Index) !void {
909 var other_reg: Register = undefined;909 var other_reg: Register = undefined;
910 while (i > 0) : (i -= 1) {910 while (i > 0) : (i -= 1) {
911 const reg = @intToEnum(Register, i - 1);911 const reg = @intToEnum(Register, i - 1);
912 if (reg_list & @as(u32, 1) << reg.id() != 0) {912 if (reg_list & @as(u32, 1) << @intCast(u5, reg.id()) != 0) {
913 if (count % 2 == 0) {913 if (count % 2 == 0) {
914 if (count == number_of_regs - 1) {914 if (count == number_of_regs - 1) {
915 try emit.writeInstruction(Instruction.ldr(915 try emit.writeInstruction(Instruction.ldr(
...@@ -939,7 +939,7 @@ fn mirPushPopRegs(emit: *Emit, inst: Mir.Inst.Index) !void {...@@ -939,7 +939,7 @@ fn mirPushPopRegs(emit: *Emit, inst: Mir.Inst.Index) !void {
939 var other_reg: Register = undefined;939 var other_reg: Register = undefined;
940 while (i < 32) : (i += 1) {940 while (i < 32) : (i += 1) {
941 const reg = @intToEnum(Register, i);941 const reg = @intToEnum(Register, i);
942 if (reg_list & @as(u32, 1) << reg.id() != 0) {942 if (reg_list & @as(u32, 1) << @intCast(u5, reg.id()) != 0) {
943 if (count % 2 == 0) {943 if (count % 2 == 0) {
944 if (count == number_of_regs - 1) {944 if (count == number_of_regs - 1) {
945 try emit.writeInstruction(Instruction.str(945 try emit.writeInstruction(Instruction.str(
src/arch/aarch64/bits.zig+79-51
...@@ -7,7 +7,7 @@ const testing = std.testing;...@@ -7,7 +7,7 @@ const testing = std.testing;
7// zig fmt: off7// zig fmt: off
88
9/// General purpose registers in the AArch64 instruction set9/// General purpose registers in the AArch64 instruction set
10pub const Register = enum(u6) {10pub const Register = enum(u7) {
11 // 64-bit registers11 // 64-bit registers
12 x0, x1, x2, x3, x4, x5, x6, x7,12 x0, x1, x2, x3, x4, x5, x6, x7,
13 x8, x9, x10, x11, x12, x13, x14, x15,13 x8, x9, x10, x11, x12, x13, x14, x15,
...@@ -20,10 +20,23 @@ pub const Register = enum(u6) {...@@ -20,10 +20,23 @@ pub const Register = enum(u6) {
20 w16, w17, w18, w19, w20, w21, w22, w23,20 w16, w17, w18, w19, w20, w21, w22, w23,
21 w24, w25, w26, w27, w28, w29, w30, wzr,21 w24, w25, w26, w27, w28, w29, w30, wzr,
2222
23 pub const sp = Register.xzr;23 // Stack pointer
24 sp, wsp,
2425
25 pub fn id(self: Register) u5 {26 pub fn id(self: Register) u6 {
26 return @truncate(u5, @enumToInt(self));27 return switch (@enumToInt(self)) {
28 0...63 => return @as(u6, @truncate(u5, @enumToInt(self))),
29 64...65 => 32,
30 else => unreachable,
31 };
32 }
33
34 pub fn enc(self: Register) u5 {
35 return switch (@enumToInt(self)) {
36 0...63 => return @truncate(u5, @enumToInt(self)),
37 64...65 => 31,
38 else => unreachable,
39 };
27 }40 }
2841
29 /// Returns the bit-width of the register.42 /// Returns the bit-width of the register.
...@@ -31,17 +44,32 @@ pub const Register = enum(u6) {...@@ -31,17 +44,32 @@ pub const Register = enum(u6) {
31 return switch (@enumToInt(self)) {44 return switch (@enumToInt(self)) {
32 0...31 => 64,45 0...31 => 64,
33 32...63 => 32,46 32...63 => 32,
47 64 => 64,
48 65 => 32,
49 else => unreachable,
34 };50 };
35 }51 }
3652
37 /// Convert from any register to its 64 bit alias.53 /// Convert from any register to its 64 bit alias.
38 pub fn to64(self: Register) Register {54 pub fn to64(self: Register) Register {
39 return @intToEnum(Register, self.id());55 return switch (@enumToInt(self)) {
56 0...31 => self,
57 32...63 => @intToEnum(Register, @enumToInt(self) - 32),
58 64 => .sp,
59 65 => .sp,
60 else => unreachable,
61 };
40 }62 }
4163
42 /// Convert from any register to its 32 bit alias.64 /// Convert from any register to its 32 bit alias.
43 pub fn to32(self: Register) Register {65 pub fn to32(self: Register) Register {
44 return @intToEnum(Register, @as(u6, self.id()) + 32);66 return switch (@enumToInt(self)) {
67 0...31 => @intToEnum(Register, @enumToInt(self) + 32),
68 32...63 => self,
69 64 => .wsp,
70 65 => .wsp,
71 else => unreachable,
72 };
45 }73 }
4674
47 /// Returns the index into `callee_preserved_regs`.75 /// Returns the index into `callee_preserved_regs`.
...@@ -53,7 +81,7 @@ pub const Register = enum(u6) {...@@ -53,7 +81,7 @@ pub const Register = enum(u6) {
53 }81 }
5482
55 pub fn dwarfLocOp(self: Register) u8 {83 pub fn dwarfLocOp(self: Register) u8 {
56 return @as(u8, self.id()) + DW.OP.reg0;84 return @as(u8, self.enc()) + DW.OP.reg0;
57 }85 }
58};86};
5987
...@@ -76,15 +104,15 @@ pub const callee_preserved_regs = callee_preserved_regs_impl.callee_preserved_re...@@ -76,15 +104,15 @@ pub const callee_preserved_regs = callee_preserved_regs_impl.callee_preserved_re
76pub const c_abi_int_param_regs = [_]Register{ .x0, .x1, .x2, .x3, .x4, .x5, .x6, .x7 };104pub const c_abi_int_param_regs = [_]Register{ .x0, .x1, .x2, .x3, .x4, .x5, .x6, .x7 };
77pub const c_abi_int_return_regs = [_]Register{ .x0, .x1, .x2, .x3, .x4, .x5, .x6, .x7 };105pub const c_abi_int_return_regs = [_]Register{ .x0, .x1, .x2, .x3, .x4, .x5, .x6, .x7 };
78106
79test "Register.id" {107test "Register.enc" {
80 try testing.expectEqual(@as(u5, 0), Register.x0.id());108 try testing.expectEqual(@as(u5, 0), Register.x0.enc());
81 try testing.expectEqual(@as(u5, 0), Register.w0.id());109 try testing.expectEqual(@as(u5, 0), Register.w0.enc());
82110
83 try testing.expectEqual(@as(u5, 31), Register.xzr.id());111 try testing.expectEqual(@as(u5, 31), Register.xzr.enc());
84 try testing.expectEqual(@as(u5, 31), Register.wzr.id());112 try testing.expectEqual(@as(u5, 31), Register.wzr.enc());
85113
86 try testing.expectEqual(@as(u5, 31), Register.sp.id());114 try testing.expectEqual(@as(u5, 31), Register.sp.enc());
87 try testing.expectEqual(@as(u5, 31), Register.sp.id());115 try testing.expectEqual(@as(u5, 31), Register.sp.enc());
88}116}
89117
90test "Register.size" {118test "Register.size" {
...@@ -479,7 +507,7 @@ pub const Instruction = union(enum) {...@@ -479,7 +507,7 @@ pub const Instruction = union(enum) {
479 assert(shift % 16 == 0 and shift <= 16);507 assert(shift % 16 == 0 and shift <= 16);
480 return Instruction{508 return Instruction{
481 .move_wide_immediate = .{509 .move_wide_immediate = .{
482 .rd = rd.id(),510 .rd = rd.enc(),
483 .imm16 = imm16,511 .imm16 = imm16,
484 .hw = @intCast(u2, shift / 16),512 .hw = @intCast(u2, shift / 16),
485 .opc = opc,513 .opc = opc,
...@@ -491,7 +519,7 @@ pub const Instruction = union(enum) {...@@ -491,7 +519,7 @@ pub const Instruction = union(enum) {
491 assert(shift % 16 == 0 and shift <= 48);519 assert(shift % 16 == 0 and shift <= 48);
492 return Instruction{520 return Instruction{
493 .move_wide_immediate = .{521 .move_wide_immediate = .{
494 .rd = rd.id(),522 .rd = rd.enc(),
495 .imm16 = imm16,523 .imm16 = imm16,
496 .hw = @intCast(u2, shift / 16),524 .hw = @intCast(u2, shift / 16),
497 .opc = opc,525 .opc = opc,
...@@ -508,7 +536,7 @@ pub const Instruction = union(enum) {...@@ -508,7 +536,7 @@ pub const Instruction = union(enum) {
508 const imm21_u = @bitCast(u21, imm21);536 const imm21_u = @bitCast(u21, imm21);
509 return Instruction{537 return Instruction{
510 .pc_relative_address = .{538 .pc_relative_address = .{
511 .rd = rd.id(),539 .rd = rd.enc(),
512 .immlo = @truncate(u2, imm21_u),540 .immlo = @truncate(u2, imm21_u),
513 .immhi = @truncate(u19, imm21_u >> 2),541 .immhi = @truncate(u19, imm21_u >> 2),
514 .op = op,542 .op = op,
...@@ -580,7 +608,7 @@ pub const Instruction = union(enum) {...@@ -580,7 +608,7 @@ pub const Instruction = union(enum) {
580 pub fn reg(rm: Register) LoadStoreOffset {608 pub fn reg(rm: Register) LoadStoreOffset {
581 return .{609 return .{
582 .register = .{610 .register = .{
583 .rm = rm.id(),611 .rm = rm.enc(),
584 .shift = .{612 .shift = .{
585 .lsl = 0,613 .lsl = 0,
586 },614 },
...@@ -592,7 +620,7 @@ pub const Instruction = union(enum) {...@@ -592,7 +620,7 @@ pub const Instruction = union(enum) {
592 assert(rm.size() == 32 and (shift == 0 or shift == 2));620 assert(rm.size() == 32 and (shift == 0 or shift == 2));
593 return .{621 return .{
594 .register = .{622 .register = .{
595 .rm = rm.id(),623 .rm = rm.enc(),
596 .shift = .{624 .shift = .{
597 .uxtw = shift,625 .uxtw = shift,
598 },626 },
...@@ -604,7 +632,7 @@ pub const Instruction = union(enum) {...@@ -604,7 +632,7 @@ pub const Instruction = union(enum) {
604 assert(rm.size() == 64 and (shift == 0 or shift == 3));632 assert(rm.size() == 64 and (shift == 0 or shift == 3));
605 return .{633 return .{
606 .register = .{634 .register = .{
607 .rm = rm.id(),635 .rm = rm.enc(),
608 .shift = .{636 .shift = .{
609 .lsl = shift,637 .lsl = shift,
610 },638 },
...@@ -616,7 +644,7 @@ pub const Instruction = union(enum) {...@@ -616,7 +644,7 @@ pub const Instruction = union(enum) {
616 assert(rm.size() == 32 and (shift == 0 or shift == 2));644 assert(rm.size() == 32 and (shift == 0 or shift == 2));
617 return .{645 return .{
618 .register = .{646 .register = .{
619 .rm = rm.id(),647 .rm = rm.enc(),
620 .shift = .{648 .shift = .{
621 .sxtw = shift,649 .sxtw = shift,
622 },650 },
...@@ -628,7 +656,7 @@ pub const Instruction = union(enum) {...@@ -628,7 +656,7 @@ pub const Instruction = union(enum) {
628 assert(rm.size() == 64 and (shift == 0 or shift == 3));656 assert(rm.size() == 64 and (shift == 0 or shift == 3));
629 return .{657 return .{
630 .register = .{658 .register = .{
631 .rm = rm.id(),659 .rm = rm.enc(),
632 .shift = .{660 .shift = .{
633 .sxtx = shift,661 .sxtx = shift,
634 },662 },
...@@ -676,8 +704,8 @@ pub const Instruction = union(enum) {...@@ -676,8 +704,8 @@ pub const Instruction = union(enum) {
676 };704 };
677 return Instruction{705 return Instruction{
678 .load_store_register = .{706 .load_store_register = .{
679 .rt = rt.id(),707 .rt = rt.enc(),
680 .rn = rn.id(),708 .rn = rn.enc(),
681 .offset = off,709 .offset = off,
682 .opc = opc,710 .opc = opc,
683 .op1 = op1,711 .op1 = op1,
...@@ -711,9 +739,9 @@ pub const Instruction = union(enum) {...@@ -711,9 +739,9 @@ pub const Instruction = union(enum) {
711 const imm7 = @truncate(u7, @bitCast(u9, offset >> 2));739 const imm7 = @truncate(u7, @bitCast(u9, offset >> 2));
712 return Instruction{740 return Instruction{
713 .load_store_register_pair = .{741 .load_store_register_pair = .{
714 .rt1 = rt1.id(),742 .rt1 = rt1.enc(),
715 .rn = rn.id(),743 .rn = rn.enc(),
716 .rt2 = rt2.id(),744 .rt2 = rt2.enc(),
717 .imm7 = imm7,745 .imm7 = imm7,
718 .load = @boolToInt(load),746 .load = @boolToInt(load),
719 .encoding = encoding,747 .encoding = encoding,
...@@ -726,9 +754,9 @@ pub const Instruction = union(enum) {...@@ -726,9 +754,9 @@ pub const Instruction = union(enum) {
726 const imm7 = @truncate(u7, @bitCast(u9, offset >> 3));754 const imm7 = @truncate(u7, @bitCast(u9, offset >> 3));
727 return Instruction{755 return Instruction{
728 .load_store_register_pair = .{756 .load_store_register_pair = .{
729 .rt1 = rt1.id(),757 .rt1 = rt1.enc(),
730 .rn = rn.id(),758 .rn = rn.enc(),
731 .rt2 = rt2.id(),759 .rt2 = rt2.enc(),
732 .imm7 = imm7,760 .imm7 = imm7,
733 .load = @boolToInt(load),761 .load = @boolToInt(load),
734 .encoding = encoding,762 .encoding = encoding,
...@@ -743,7 +771,7 @@ pub const Instruction = union(enum) {...@@ -743,7 +771,7 @@ pub const Instruction = union(enum) {
743 fn loadLiteral(rt: Register, imm19: u19) Instruction {771 fn loadLiteral(rt: Register, imm19: u19) Instruction {
744 return Instruction{772 return Instruction{
745 .load_literal = .{773 .load_literal = .{
746 .rt = rt.id(),774 .rt = rt.enc(),
747 .imm19 = imm19,775 .imm19 = imm19,
748 .opc = switch (rt.size()) {776 .opc = switch (rt.size()) {
749 32 => 0b00,777 32 => 0b00,
...@@ -782,7 +810,7 @@ pub const Instruction = union(enum) {...@@ -782,7 +810,7 @@ pub const Instruction = union(enum) {
782 return Instruction{810 return Instruction{
783 .unconditional_branch_register = .{811 .unconditional_branch_register = .{
784 .op4 = op4,812 .op4 = op4,
785 .rn = rn.id(),813 .rn = rn.enc(),
786 .op3 = op3,814 .op3 = op3,
787 .op2 = op2,815 .op2 = op2,
788 .opc = opc,816 .opc = opc,
...@@ -818,10 +846,10 @@ pub const Instruction = union(enum) {...@@ -818,10 +846,10 @@ pub const Instruction = union(enum) {
818 assert(amount < 32);846 assert(amount < 32);
819 return Instruction{847 return Instruction{
820 .logical_shifted_register = .{848 .logical_shifted_register = .{
821 .rd = rd.id(),849 .rd = rd.enc(),
822 .rn = rn.id(),850 .rn = rn.enc(),
823 .imm6 = amount,851 .imm6 = amount,
824 .rm = rm.id(),852 .rm = rm.enc(),
825 .n = n,853 .n = n,
826 .shift = @enumToInt(shift),854 .shift = @enumToInt(shift),
827 .opc = opc,855 .opc = opc,
...@@ -832,10 +860,10 @@ pub const Instruction = union(enum) {...@@ -832,10 +860,10 @@ pub const Instruction = union(enum) {
832 64 => {860 64 => {
833 return Instruction{861 return Instruction{
834 .logical_shifted_register = .{862 .logical_shifted_register = .{
835 .rd = rd.id(),863 .rd = rd.enc(),
836 .rn = rn.id(),864 .rn = rn.enc(),
837 .imm6 = amount,865 .imm6 = amount,
838 .rm = rm.id(),866 .rm = rm.enc(),
839 .n = n,867 .n = n,
840 .shift = @enumToInt(shift),868 .shift = @enumToInt(shift),
841 .opc = opc,869 .opc = opc,
...@@ -857,8 +885,8 @@ pub const Instruction = union(enum) {...@@ -857,8 +885,8 @@ pub const Instruction = union(enum) {
857 ) Instruction {885 ) Instruction {
858 return Instruction{886 return Instruction{
859 .add_subtract_immediate = .{887 .add_subtract_immediate = .{
860 .rd = rd.id(),888 .rd = rd.enc(),
861 .rn = rn.id(),889 .rn = rn.enc(),
862 .imm12 = imm12,890 .imm12 = imm12,
863 .sh = @boolToInt(shift),891 .sh = @boolToInt(shift),
864 .s = s,892 .s = s,
...@@ -885,10 +913,10 @@ pub const Instruction = union(enum) {...@@ -885,10 +913,10 @@ pub const Instruction = union(enum) {
885 ) Instruction {913 ) Instruction {
886 return Instruction{914 return Instruction{
887 .add_subtract_shifted_register = .{915 .add_subtract_shifted_register = .{
888 .rd = rd.id(),916 .rd = rd.enc(),
889 .rn = rn.id(),917 .rn = rn.enc(),
890 .imm6 = imm6,918 .imm6 = imm6,
891 .rm = rm.id(),919 .rm = rm.enc(),
892 .shift = @enumToInt(shift),920 .shift = @enumToInt(shift),
893 .s = s,921 .s = s,
894 .op = op,922 .op = op,
...@@ -926,7 +954,7 @@ pub const Instruction = union(enum) {...@@ -926,7 +954,7 @@ pub const Instruction = union(enum) {
926 assert(offset & 0b11 == 0b00);954 assert(offset & 0b11 == 0b00);
927 return Instruction{955 return Instruction{
928 .compare_and_branch = .{956 .compare_and_branch = .{
929 .rt = rt.id(),957 .rt = rt.enc(),
930 .imm19 = @bitCast(u19, @intCast(i19, offset >> 2)),958 .imm19 = @bitCast(u19, @intCast(i19, offset >> 2)),
931 .op = op,959 .op = op,
932 .sf = switch (rt.size()) {960 .sf = switch (rt.size()) {
...@@ -949,11 +977,11 @@ pub const Instruction = union(enum) {...@@ -949,11 +977,11 @@ pub const Instruction = union(enum) {
949 ) Instruction {977 ) Instruction {
950 return Instruction{978 return Instruction{
951 .conditional_select = .{979 .conditional_select = .{
952 .rd = rd.id(),980 .rd = rd.enc(),
953 .rn = rn.id(),981 .rn = rn.enc(),
954 .op2 = op2,982 .op2 = op2,
955 .cond = @enumToInt(cond),983 .cond = @enumToInt(cond),
956 .rm = rm.id(),984 .rm = rm.enc(),
957 .s = s,985 .s = s,
958 .op = op,986 .op = op,
959 .sf = switch (rd.size()) {987 .sf = switch (rd.size()) {
...@@ -976,11 +1004,11 @@ pub const Instruction = union(enum) {...@@ -976,11 +1004,11 @@ pub const Instruction = union(enum) {
976 ) Instruction {1004 ) Instruction {
977 return Instruction{1005 return Instruction{
978 .data_processing_3_source = .{1006 .data_processing_3_source = .{
979 .rd = rd.id(),1007 .rd = rd.enc(),
980 .rn = rn.id(),1008 .rn = rn.enc(),
981 .ra = ra.id(),1009 .ra = ra.enc(),
982 .o0 = o0,1010 .o0 = o0,
983 .rm = rm.id(),1011 .rm = rm.enc(),
984 .op31 = op31,1012 .op31 = op31,
985 .op54 = op54,1013 .op54 = op54,
986 .sf = switch (rd.size()) {1014 .sf = switch (rd.size()) {