authorgravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-02-12 21:12:18+01:00
committergravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-02-14 22:09:44+01:00
log783e216e7d49ce30032cd768ca266f5f08773bf4
tree13bc364a2fec50885949698da74ebc83241d21af
parent1c37622659f70115b698b5924472c2268bca63a8
signaturelock-open Commit is signed but in an unrecognized format.

stage2 AArch64: Fix issue in binOp and add regression test


2 files changed, 61 insertions(+), 19 deletions(-)

src/arch/aarch64/CodeGen.zig+17-1
...@@ -981,13 +981,19 @@ fn binOpRegister(...@@ -981,13 +981,19 @@ fn binOpRegister(
981 if (lhs_is_register) self.register_manager.freezeRegs(&.{lhs.register});981 if (lhs_is_register) self.register_manager.freezeRegs(&.{lhs.register});
982 if (rhs_is_register) self.register_manager.freezeRegs(&.{rhs.register});982 if (rhs_is_register) self.register_manager.freezeRegs(&.{rhs.register});
983983
984 const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];
985
984 const lhs_reg = if (lhs_is_register) lhs.register else blk: {986 const lhs_reg = if (lhs_is_register) lhs.register else blk: {
985 const track_inst: ?Air.Inst.Index = if (maybe_inst) |inst| inst: {987 const track_inst: ?Air.Inst.Index = if (maybe_inst) |inst| inst: {
986 const bin_op = self.air.instructions.items(.data)[inst].bin_op;988 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
987 break :inst Air.refToIndex(bin_op.lhs).?;989 break :inst Air.refToIndex(bin_op.lhs).?;
988 } else null;990 } else null;
991
989 const reg = try self.register_manager.allocReg(track_inst);992 const reg = try self.register_manager.allocReg(track_inst);
990 self.register_manager.freezeRegs(&.{reg});993 self.register_manager.freezeRegs(&.{reg});
994
995 if (track_inst) |inst| branch.inst_table.putAssumeCapacity(inst, .{ .register = reg });
996
991 break :blk reg;997 break :blk reg;
992 };998 };
993 defer self.register_manager.unfreezeRegs(&.{lhs_reg});999 defer self.register_manager.unfreezeRegs(&.{lhs_reg});
...@@ -997,8 +1003,12 @@ fn binOpRegister(...@@ -997,8 +1003,12 @@ fn binOpRegister(
997 const bin_op = self.air.instructions.items(.data)[inst].bin_op;1003 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
998 break :inst Air.refToIndex(bin_op.rhs).?;1004 break :inst Air.refToIndex(bin_op.rhs).?;
999 } else null;1005 } else null;
1006
1000 const reg = try self.register_manager.allocReg(track_inst);1007 const reg = try self.register_manager.allocReg(track_inst);
1001 self.register_manager.freezeRegs(&.{reg});1008 self.register_manager.freezeRegs(&.{reg});
1009
1010 if (track_inst) |inst| branch.inst_table.putAssumeCapacity(inst, .{ .register = reg });
1011
1002 break :blk reg;1012 break :blk reg;
1003 };1013 };
1004 defer self.register_manager.unfreezeRegs(&.{rhs_reg});1014 defer self.register_manager.unfreezeRegs(&.{rhs_reg});
...@@ -1077,6 +1087,8 @@ fn binOpImmediate(...@@ -1077,6 +1087,8 @@ fn binOpImmediate(
10771087
1078 if (lhs_is_register) self.register_manager.freezeRegs(&.{lhs.register});1088 if (lhs_is_register) self.register_manager.freezeRegs(&.{lhs.register});
10791089
1090 const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];
1091
1080 const lhs_reg = if (lhs_is_register) lhs.register else blk: {1092 const lhs_reg = if (lhs_is_register) lhs.register else blk: {
1081 const track_inst: ?Air.Inst.Index = if (maybe_inst) |inst| inst: {1093 const track_inst: ?Air.Inst.Index = if (maybe_inst) |inst| inst: {
1082 const bin_op = self.air.instructions.items(.data)[inst].bin_op;1094 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
...@@ -1084,8 +1096,12 @@ fn binOpImmediate(...@@ -1084,8 +1096,12 @@ fn binOpImmediate(
1084 if (lhs_and_rhs_swapped) bin_op.rhs else bin_op.lhs,1096 if (lhs_and_rhs_swapped) bin_op.rhs else bin_op.lhs,
1085 ).?;1097 ).?;
1086 } else null;1098 } else null;
1099
1087 const reg = try self.register_manager.allocReg(track_inst);1100 const reg = try self.register_manager.allocReg(track_inst);
1088 self.register_manager.freezeRegs(&.{reg});1101 self.register_manager.freezeRegs(&.{reg});
1102
1103 if (track_inst) |inst| branch.inst_table.putAssumeCapacity(inst, .{ .register = reg });
1104
1089 break :blk reg;1105 break :blk reg;
1090 };1106 };
1091 defer self.register_manager.unfreezeRegs(&.{lhs_reg});1107 defer self.register_manager.unfreezeRegs(&.{lhs_reg});
...@@ -3141,7 +3157,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -3141,7 +3157,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
3141 .tag = .cset,3157 .tag = .cset,
3142 .data = .{ .r_cond = .{3158 .data = .{ .r_cond = .{
3143 .rd = reg,3159 .rd = reg,
3144 .cond = condition,3160 .cond = condition.negate(),
3145 } },3161 } },
3146 });3162 });
3147 },3163 },
test/stage2/aarch64.zig+44-18
...@@ -17,15 +17,8 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -17,15 +17,8 @@ pub fn addCases(ctx: *TestContext) !void {
17 var case = ctx.exe("linux_aarch64 hello world", linux_aarch64);17 var case = ctx.exe("linux_aarch64 hello world", linux_aarch64);
18 // Regular old hello world18 // Regular old hello world
19 case.addCompareOutput(19 case.addCompareOutput(
20 \\pub export fn _start() noreturn {20 \\pub fn main() void {
21 \\ print();21 \\ print();
22 \\ exit();
23 \\}
24 \\
25 \\fn doNothing() void {}
26 \\
27 \\fn answer() u64 {
28 \\ return 0x1234abcd1234abcd;
29 \\}22 \\}
30 \\23 \\
31 \\fn print() void {24 \\fn print() void {
...@@ -38,16 +31,6 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -38,16 +31,6 @@ pub fn addCases(ctx: *TestContext) !void {
38 \\ : "memory", "cc"31 \\ : "memory", "cc"
39 \\ );32 \\ );
40 \\}33 \\}
41 \\
42 \\fn exit() noreturn {
43 \\ asm volatile ("svc #0"
44 \\ :
45 \\ : [number] "{x8}" (93),
46 \\ [arg1] "{x0}" (0)
47 \\ : "memory", "cc"
48 \\ );
49 \\ unreachable;
50 \\}
51 ,34 ,
52 "Hello, World!\n",35 "Hello, World!\n",
53 );36 );
...@@ -129,6 +112,49 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -129,6 +112,49 @@ pub fn addCases(ctx: *TestContext) !void {
129 );112 );
130 }113 }
131114
115 {
116 var case = ctx.exe("large add function", linux_aarch64);
117
118 case.addCompareOutput(
119 \\pub fn main() void {
120 \\ assert(add(3, 4) == 791);
121 \\}
122 \\
123 \\fn add(a: u32, b: u32) u32 {
124 \\ const x: u32 = blk: {
125 \\ const c = a + b; // 7
126 \\ const d = a + c; // 10
127 \\ const e = d + b; // 14
128 \\ const f = d + e; // 24
129 \\ const g = e + f; // 38
130 \\ const h = f + g; // 62
131 \\ const i = g + h; // 100
132 \\ const j = i + d; // 110
133 \\ const k = i + j; // 210
134 \\ const l = k + c; // 217
135 \\ const m = l + d; // 227
136 \\ const n = m + e; // 241
137 \\ const o = n + f; // 265
138 \\ const p = o + g; // 303
139 \\ const q = p + h; // 365
140 \\ const r = q + i; // 465
141 \\ const s = r + j; // 575
142 \\ const t = s + k; // 785
143 \\ break :blk t;
144 \\ };
145 \\ const y = x + a; // 788
146 \\ const z = y + a; // 791
147 \\ return z;
148 \\}
149 \\
150 \\fn assert(ok: bool) void {
151 \\ if (!ok) unreachable;
152 \\}
153 ,
154 "",
155 );
156 }
157
132 // macOS tests158 // macOS tests
133 {159 {
134 var case = ctx.exe("hello world with updates", macos_aarch64);160 var case = ctx.exe("hello world with updates", macos_aarch64);