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 {
372372 .data = .{ .load_store_register_pair = .{
373373 .rt = .x29,
374374 .rt2 = .x30,
375 .rn = Register.sp,
375 .rn = .sp,
376376 .offset = Instruction.LoadStorePairOffset.pre_index(-16),
377377 } },
378378 });
......@@ -407,7 +407,7 @@ fn gen(self: *Self) !void {
407407 self.saved_regs_stack_space = 16;
408408 inline for (callee_preserved_regs) |reg| {
409409 if (self.register_manager.isRegAllocated(reg)) {
410 saved_regs |= @as(u32, 1) << reg.id();
410 saved_regs |= @as(u32, 1) << @intCast(u5, reg.id());
411411 self.saved_regs_stack_space += 8;
412412 }
413413 }
......@@ -475,7 +475,7 @@ fn gen(self: *Self) !void {
475475 .data = .{ .load_store_register_pair = .{
476476 .rt = .x29,
477477 .rt2 = .x30,
478 .rn = Register.sp,
478 .rn = .sp,
479479 .offset = Instruction.LoadStorePairOffset.post_index(16),
480480 } },
481481 });
src/arch/aarch64/Emit.zig+2-2
......@@ -909,7 +909,7 @@ fn mirPushPopRegs(emit: *Emit, inst: Mir.Inst.Index) !void {
909909 var other_reg: Register = undefined;
910910 while (i > 0) : (i -= 1) {
911911 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) {
913913 if (count % 2 == 0) {
914914 if (count == number_of_regs - 1) {
915915 try emit.writeInstruction(Instruction.ldr(
......@@ -939,7 +939,7 @@ fn mirPushPopRegs(emit: *Emit, inst: Mir.Inst.Index) !void {
939939 var other_reg: Register = undefined;
940940 while (i < 32) : (i += 1) {
941941 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) {
943943 if (count % 2 == 0) {
944944 if (count == number_of_regs - 1) {
945945 try emit.writeInstruction(Instruction.str(
src/arch/aarch64/bits.zig+79-51
......@@ -7,7 +7,7 @@ const testing = std.testing;
77// zig fmt: off
88
99/// General purpose registers in the AArch64 instruction set
10pub const Register = enum(u6) {
10pub const Register = enum(u7) {
1111 // 64-bit registers
1212 x0, x1, x2, x3, x4, x5, x6, x7,
1313 x8, x9, x10, x11, x12, x13, x14, x15,
......@@ -20,10 +20,23 @@ pub const Register = enum(u6) {
2020 w16, w17, w18, w19, w20, w21, w22, w23,
2121 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 return @truncate(u5, @enumToInt(self));
26 pub fn id(self: Register) u6 {
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 };
2740 }
2841
2942 /// Returns the bit-width of the register.
......@@ -31,17 +44,32 @@ pub const Register = enum(u6) {
3144 return switch (@enumToInt(self)) {
3245 0...31 => 64,
3346 32...63 => 32,
47 64 => 64,
48 65 => 32,
49 else => unreachable,
3450 };
3551 }
3652
3753 /// Convert from any register to its 64 bit alias.
3854 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 };
4062 }
4163
4264 /// Convert from any register to its 32 bit alias.
4365 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 };
4573 }
4674
4775 /// Returns the index into `callee_preserved_regs`.
......@@ -53,7 +81,7 @@ pub const Register = enum(u6) {
5381 }
5482
5583 pub fn dwarfLocOp(self: Register) u8 {
56 return @as(u8, self.id()) + DW.OP.reg0;
84 return @as(u8, self.enc()) + DW.OP.reg0;
5785 }
5886};
5987
......@@ -76,15 +104,15 @@ pub const callee_preserved_regs = callee_preserved_regs_impl.callee_preserved_re
76104pub const c_abi_int_param_regs = [_]Register{ .x0, .x1, .x2, .x3, .x4, .x5, .x6, .x7 };
77105pub const c_abi_int_return_regs = [_]Register{ .x0, .x1, .x2, .x3, .x4, .x5, .x6, .x7 };
78106
79test "Register.id" {
80 try testing.expectEqual(@as(u5, 0), Register.x0.id());
81 try testing.expectEqual(@as(u5, 0), Register.w0.id());
107test "Register.enc" {
108 try testing.expectEqual(@as(u5, 0), Register.x0.enc());
109 try testing.expectEqual(@as(u5, 0), Register.w0.enc());
82110
83 try testing.expectEqual(@as(u5, 31), Register.xzr.id());
84 try testing.expectEqual(@as(u5, 31), Register.wzr.id());
111 try testing.expectEqual(@as(u5, 31), Register.xzr.enc());
112 try testing.expectEqual(@as(u5, 31), Register.wzr.enc());
85113
86 try testing.expectEqual(@as(u5, 31), Register.sp.id());
87 try testing.expectEqual(@as(u5, 31), Register.sp.id());
114 try testing.expectEqual(@as(u5, 31), Register.sp.enc());
115 try testing.expectEqual(@as(u5, 31), Register.sp.enc());
88116}
89117
90118test "Register.size" {
......@@ -479,7 +507,7 @@ pub const Instruction = union(enum) {
479507 assert(shift % 16 == 0 and shift <= 16);
480508 return Instruction{
481509 .move_wide_immediate = .{
482 .rd = rd.id(),
510 .rd = rd.enc(),
483511 .imm16 = imm16,
484512 .hw = @intCast(u2, shift / 16),
485513 .opc = opc,
......@@ -491,7 +519,7 @@ pub const Instruction = union(enum) {
491519 assert(shift % 16 == 0 and shift <= 48);
492520 return Instruction{
493521 .move_wide_immediate = .{
494 .rd = rd.id(),
522 .rd = rd.enc(),
495523 .imm16 = imm16,
496524 .hw = @intCast(u2, shift / 16),
497525 .opc = opc,
......@@ -508,7 +536,7 @@ pub const Instruction = union(enum) {
508536 const imm21_u = @bitCast(u21, imm21);
509537 return Instruction{
510538 .pc_relative_address = .{
511 .rd = rd.id(),
539 .rd = rd.enc(),
512540 .immlo = @truncate(u2, imm21_u),
513541 .immhi = @truncate(u19, imm21_u >> 2),
514542 .op = op,
......@@ -580,7 +608,7 @@ pub const Instruction = union(enum) {
580608 pub fn reg(rm: Register) LoadStoreOffset {
581609 return .{
582610 .register = .{
583 .rm = rm.id(),
611 .rm = rm.enc(),
584612 .shift = .{
585613 .lsl = 0,
586614 },
......@@ -592,7 +620,7 @@ pub const Instruction = union(enum) {
592620 assert(rm.size() == 32 and (shift == 0 or shift == 2));
593621 return .{
594622 .register = .{
595 .rm = rm.id(),
623 .rm = rm.enc(),
596624 .shift = .{
597625 .uxtw = shift,
598626 },
......@@ -604,7 +632,7 @@ pub const Instruction = union(enum) {
604632 assert(rm.size() == 64 and (shift == 0 or shift == 3));
605633 return .{
606634 .register = .{
607 .rm = rm.id(),
635 .rm = rm.enc(),
608636 .shift = .{
609637 .lsl = shift,
610638 },
......@@ -616,7 +644,7 @@ pub const Instruction = union(enum) {
616644 assert(rm.size() == 32 and (shift == 0 or shift == 2));
617645 return .{
618646 .register = .{
619 .rm = rm.id(),
647 .rm = rm.enc(),
620648 .shift = .{
621649 .sxtw = shift,
622650 },
......@@ -628,7 +656,7 @@ pub const Instruction = union(enum) {
628656 assert(rm.size() == 64 and (shift == 0 or shift == 3));
629657 return .{
630658 .register = .{
631 .rm = rm.id(),
659 .rm = rm.enc(),
632660 .shift = .{
633661 .sxtx = shift,
634662 },
......@@ -676,8 +704,8 @@ pub const Instruction = union(enum) {
676704 };
677705 return Instruction{
678706 .load_store_register = .{
679 .rt = rt.id(),
680 .rn = rn.id(),
707 .rt = rt.enc(),
708 .rn = rn.enc(),
681709 .offset = off,
682710 .opc = opc,
683711 .op1 = op1,
......@@ -711,9 +739,9 @@ pub const Instruction = union(enum) {
711739 const imm7 = @truncate(u7, @bitCast(u9, offset >> 2));
712740 return Instruction{
713741 .load_store_register_pair = .{
714 .rt1 = rt1.id(),
715 .rn = rn.id(),
716 .rt2 = rt2.id(),
742 .rt1 = rt1.enc(),
743 .rn = rn.enc(),
744 .rt2 = rt2.enc(),
717745 .imm7 = imm7,
718746 .load = @boolToInt(load),
719747 .encoding = encoding,
......@@ -726,9 +754,9 @@ pub const Instruction = union(enum) {
726754 const imm7 = @truncate(u7, @bitCast(u9, offset >> 3));
727755 return Instruction{
728756 .load_store_register_pair = .{
729 .rt1 = rt1.id(),
730 .rn = rn.id(),
731 .rt2 = rt2.id(),
757 .rt1 = rt1.enc(),
758 .rn = rn.enc(),
759 .rt2 = rt2.enc(),
732760 .imm7 = imm7,
733761 .load = @boolToInt(load),
734762 .encoding = encoding,
......@@ -743,7 +771,7 @@ pub const Instruction = union(enum) {
743771 fn loadLiteral(rt: Register, imm19: u19) Instruction {
744772 return Instruction{
745773 .load_literal = .{
746 .rt = rt.id(),
774 .rt = rt.enc(),
747775 .imm19 = imm19,
748776 .opc = switch (rt.size()) {
749777 32 => 0b00,
......@@ -782,7 +810,7 @@ pub const Instruction = union(enum) {
782810 return Instruction{
783811 .unconditional_branch_register = .{
784812 .op4 = op4,
785 .rn = rn.id(),
813 .rn = rn.enc(),
786814 .op3 = op3,
787815 .op2 = op2,
788816 .opc = opc,
......@@ -818,10 +846,10 @@ pub const Instruction = union(enum) {
818846 assert(amount < 32);
819847 return Instruction{
820848 .logical_shifted_register = .{
821 .rd = rd.id(),
822 .rn = rn.id(),
849 .rd = rd.enc(),
850 .rn = rn.enc(),
823851 .imm6 = amount,
824 .rm = rm.id(),
852 .rm = rm.enc(),
825853 .n = n,
826854 .shift = @enumToInt(shift),
827855 .opc = opc,
......@@ -832,10 +860,10 @@ pub const Instruction = union(enum) {
832860 64 => {
833861 return Instruction{
834862 .logical_shifted_register = .{
835 .rd = rd.id(),
836 .rn = rn.id(),
863 .rd = rd.enc(),
864 .rn = rn.enc(),
837865 .imm6 = amount,
838 .rm = rm.id(),
866 .rm = rm.enc(),
839867 .n = n,
840868 .shift = @enumToInt(shift),
841869 .opc = opc,
......@@ -857,8 +885,8 @@ pub const Instruction = union(enum) {
857885 ) Instruction {
858886 return Instruction{
859887 .add_subtract_immediate = .{
860 .rd = rd.id(),
861 .rn = rn.id(),
888 .rd = rd.enc(),
889 .rn = rn.enc(),
862890 .imm12 = imm12,
863891 .sh = @boolToInt(shift),
864892 .s = s,
......@@ -885,10 +913,10 @@ pub const Instruction = union(enum) {
885913 ) Instruction {
886914 return Instruction{
887915 .add_subtract_shifted_register = .{
888 .rd = rd.id(),
889 .rn = rn.id(),
916 .rd = rd.enc(),
917 .rn = rn.enc(),
890918 .imm6 = imm6,
891 .rm = rm.id(),
919 .rm = rm.enc(),
892920 .shift = @enumToInt(shift),
893921 .s = s,
894922 .op = op,
......@@ -926,7 +954,7 @@ pub const Instruction = union(enum) {
926954 assert(offset & 0b11 == 0b00);
927955 return Instruction{
928956 .compare_and_branch = .{
929 .rt = rt.id(),
957 .rt = rt.enc(),
930958 .imm19 = @bitCast(u19, @intCast(i19, offset >> 2)),
931959 .op = op,
932960 .sf = switch (rt.size()) {
......@@ -949,11 +977,11 @@ pub const Instruction = union(enum) {
949977 ) Instruction {
950978 return Instruction{
951979 .conditional_select = .{
952 .rd = rd.id(),
953 .rn = rn.id(),
980 .rd = rd.enc(),
981 .rn = rn.enc(),
954982 .op2 = op2,
955983 .cond = @enumToInt(cond),
956 .rm = rm.id(),
984 .rm = rm.enc(),
957985 .s = s,
958986 .op = op,
959987 .sf = switch (rd.size()) {
......@@ -976,11 +1004,11 @@ pub const Instruction = union(enum) {
9761004 ) Instruction {
9771005 return Instruction{
9781006 .data_processing_3_source = .{
979 .rd = rd.id(),
980 .rn = rn.id(),
981 .ra = ra.id(),
1007 .rd = rd.enc(),
1008 .rn = rn.enc(),
1009 .ra = ra.enc(),
9821010 .o0 = o0,
983 .rm = rm.id(),
1011 .rm = rm.enc(),
9841012 .op31 = op31,
9851013 .op54 = op54,
9861014 .sf = switch (rd.size()) {