authorgravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-10-04 17:27:54+02:00
committergravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-10-20 16:14:52+02:00
logea7a60116d2ddb30a1684b67d892cb72f631a9f3
treee40f7fccef8488fd9a89dfd1b61053c473946e33
parentd8fddb535ca425be8db42e3d86e3715cc6ebad56
signaturelock-open Commit is signed but in an unrecognized format.

stage2 AArch64: move add+sub to new allocRegs mechanism


1 files changed, 108 insertions(+), 90 deletions(-)

src/arch/aarch64/CodeGen.zig+108-90
...@@ -1582,7 +1582,7 @@ fn binOpImmediateNew(...@@ -1582,7 +1582,7 @@ fn binOpImmediateNew(
1582 self: *Self,1582 self: *Self,
1583 mir_tag: Mir.Inst.Tag,1583 mir_tag: Mir.Inst.Tag,
1584 lhs_bind: ReadArg.Bind,1584 lhs_bind: ReadArg.Bind,
1585 rhs_immediate: u32,1585 rhs_immediate: u64,
1586 lhs_ty: Type,1586 lhs_ty: Type,
1587 lhs_and_rhs_swapped: bool,1587 lhs_and_rhs_swapped: bool,
1588 maybe_inst: ?Air.Inst.Index,1588 maybe_inst: ?Air.Inst.Index,
...@@ -1910,57 +1910,6 @@ fn binOp(...@@ -1910,57 +1910,6 @@ fn binOp(
1910) InnerError!MCValue {1910) InnerError!MCValue {
1911 const mod = self.bin_file.options.module.?;1911 const mod = self.bin_file.options.module.?;
1912 switch (tag) {1912 switch (tag) {
1913 .add,
1914 .sub,
1915 => {
1916 switch (lhs_ty.zigTypeTag()) {
1917 .Float => return self.fail("TODO binary operations on floats", .{}),
1918 .Vector => return self.fail("TODO binary operations on vectors", .{}),
1919 .Int => {
1920 assert(lhs_ty.eql(rhs_ty, mod));
1921 const int_info = lhs_ty.intInfo(self.target.*);
1922 if (int_info.bits <= 64) {
1923 // Only say yes if the operation is
1924 // commutative, i.e. we can swap both of the
1925 // operands
1926 const lhs_immediate_ok = switch (tag) {
1927 .add => lhs == .immediate and lhs.immediate <= std.math.maxInt(u12),
1928 .sub => false,
1929 else => unreachable,
1930 };
1931 const rhs_immediate_ok = switch (tag) {
1932 .add,
1933 .sub,
1934 => rhs == .immediate and rhs.immediate <= std.math.maxInt(u12),
1935 else => unreachable,
1936 };
1937
1938 const mir_tag_register: Mir.Inst.Tag = switch (tag) {
1939 .add => .add_shifted_register,
1940 .sub => .sub_shifted_register,
1941 else => unreachable,
1942 };
1943 const mir_tag_immediate: Mir.Inst.Tag = switch (tag) {
1944 .add => .add_immediate,
1945 .sub => .sub_immediate,
1946 else => unreachable,
1947 };
1948
1949 if (rhs_immediate_ok) {
1950 return try self.binOpImmediate(mir_tag_immediate, lhs, rhs, lhs_ty, false, metadata);
1951 } else if (lhs_immediate_ok) {
1952 // swap lhs and rhs
1953 return try self.binOpImmediate(mir_tag_immediate, rhs, lhs, rhs_ty, true, metadata);
1954 } else {
1955 return try self.binOpRegister(mir_tag_register, lhs, rhs, lhs_ty, rhs_ty, metadata);
1956 }
1957 } else {
1958 return self.fail("TODO binary operations on int with bits > 64", .{});
1959 }
1960 },
1961 else => unreachable,
1962 }
1963 },
1964 .mul => {1913 .mul => {
1965 switch (lhs_ty.zigTypeTag()) {1914 switch (lhs_ty.zigTypeTag()) {
1966 .Vector => return self.fail("TODO binary operations on vectors", .{}),1915 .Vector => return self.fail("TODO binary operations on vectors", .{}),
...@@ -2134,8 +2083,18 @@ fn binOp(...@@ -2134,8 +2083,18 @@ fn binOp(
2134 else => unreachable,2083 else => unreachable,
2135 };2084 };
21362085
2086 const lhs_bind = if (metadata) |md|
2087 ReadArg.Bind{ .inst = md.lhs }
2088 else
2089 ReadArg.Bind{ .mcv = lhs };
2090 const rhs_bind = if (metadata) |md|
2091 ReadArg.Bind{ .inst = md.rhs }
2092 else
2093 ReadArg.Bind{ .mcv = rhs };
2094
2137 // Generate an add/sub/mul2095 // Generate an add/sub/mul
2138 const result = try self.binOp(base_tag, lhs, rhs, lhs_ty, rhs_ty, metadata);2096 const maybe_inst: ?Air.Inst.Index = if (metadata) |md| md.inst else null;
2097 const result = try self.addSub(base_tag, lhs_bind, rhs_bind, lhs_ty, rhs_ty, maybe_inst);
21392098
2140 // Truncate if necessary2099 // Truncate if necessary
2141 switch (lhs_ty.zigTypeTag()) {2100 switch (lhs_ty.zigTypeTag()) {
...@@ -2304,21 +2263,93 @@ fn binOp(...@@ -2304,21 +2263,93 @@ fn binOp(
2304 }2263 }
2305}2264}
23062265
2266fn addSub(
2267 self: *Self,
2268 tag: Air.Inst.Tag,
2269 lhs_bind: ReadArg.Bind,
2270 rhs_bind: ReadArg.Bind,
2271 lhs_ty: Type,
2272 rhs_ty: Type,
2273 maybe_inst: ?Air.Inst.Index,
2274) InnerError!MCValue {
2275 const mod = self.bin_file.options.module.?;
2276 switch (lhs_ty.zigTypeTag()) {
2277 .Float => return self.fail("TODO binary operations on floats", .{}),
2278 .Vector => return self.fail("TODO binary operations on vectors", .{}),
2279 .Int => {
2280 assert(lhs_ty.eql(rhs_ty, mod));
2281 const int_info = lhs_ty.intInfo(self.target.*);
2282 if (int_info.bits <= 64) {
2283 const lhs_immediate = try lhs_bind.resolveToImmediate(self);
2284 const rhs_immediate = try rhs_bind.resolveToImmediate(self);
2285
2286 // Only say yes if the operation is
2287 // commutative, i.e. we can swap both of the
2288 // operands
2289 const lhs_immediate_ok = switch (tag) {
2290 .add => if (lhs_immediate) |imm| imm <= std.math.maxInt(u12) else false,
2291 .sub => false,
2292 else => unreachable,
2293 };
2294 const rhs_immediate_ok = switch (tag) {
2295 .add,
2296 .sub,
2297 => if (rhs_immediate) |imm| imm <= std.math.maxInt(u12) else false,
2298 else => unreachable,
2299 };
2300
2301 const mir_tag_register: Mir.Inst.Tag = switch (tag) {
2302 .add => .add_shifted_register,
2303 .sub => .sub_shifted_register,
2304 else => unreachable,
2305 };
2306 const mir_tag_immediate: Mir.Inst.Tag = switch (tag) {
2307 .add => .add_immediate,
2308 .sub => .sub_immediate,
2309 else => unreachable,
2310 };
2311
2312 if (rhs_immediate_ok) {
2313 return try self.binOpImmediateNew(mir_tag_immediate, lhs_bind, rhs_immediate.?, lhs_ty, false, maybe_inst);
2314 } else if (lhs_immediate_ok) {
2315 // swap lhs and rhs
2316 return try self.binOpImmediateNew(mir_tag_immediate, rhs_bind, lhs_immediate.?, rhs_ty, true, maybe_inst);
2317 } else {
2318 return try self.binOpRegisterNew(mir_tag_register, lhs_bind, rhs_bind, lhs_ty, rhs_ty, maybe_inst);
2319 }
2320 } else {
2321 return self.fail("TODO binary operations on int with bits > 64", .{});
2322 }
2323 },
2324 else => unreachable,
2325 }
2326}
2327
2307fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {2328fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
2308 const bin_op = self.air.instructions.items(.data)[inst].bin_op;2329 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
2309 const lhs = try self.resolveInst(bin_op.lhs);
2310 const rhs = try self.resolveInst(bin_op.rhs);
2311 const lhs_ty = self.air.typeOf(bin_op.lhs);2330 const lhs_ty = self.air.typeOf(bin_op.lhs);
2312 const rhs_ty = self.air.typeOf(bin_op.rhs);2331 const rhs_ty = self.air.typeOf(bin_op.rhs);
23132332
2314 const result: MCValue = if (self.liveness.isUnused(inst))2333 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2315 .dead2334 const lhs_bind: ReadArg.Bind = .{ .inst = bin_op.lhs };
2316 else2335 const rhs_bind: ReadArg.Bind = .{ .inst = bin_op.rhs };
2317 try self.binOp(tag, lhs, rhs, lhs_ty, rhs_ty, BinOpMetadata{2336
2318 .inst = inst,2337 break :result switch (tag) {
2319 .lhs = bin_op.lhs,2338 .add => try self.addSub(tag, lhs_bind, rhs_bind, lhs_ty, rhs_ty, inst),
2320 .rhs = bin_op.rhs,2339 .sub => try self.addSub(tag, lhs_bind, rhs_bind, lhs_ty, rhs_ty, inst),
2321 });2340
2341 else => blk: {
2342 const lhs = try self.resolveInst(bin_op.lhs);
2343 const rhs = try self.resolveInst(bin_op.rhs);
2344
2345 break :blk try self.binOp(tag, lhs, rhs, lhs_ty, rhs_ty, BinOpMetadata{
2346 .inst = inst,
2347 .lhs = bin_op.lhs,
2348 .rhs = bin_op.rhs,
2349 });
2350 },
2351 };
2352 };
2322 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });2353 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
2323}2354}
23242355
...@@ -2364,8 +2395,8 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -2364,8 +2395,8 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {
2364 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;2395 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
2365 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;2396 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
2366 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2397 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2367 const lhs = try self.resolveInst(extra.lhs);2398 const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };
2368 const rhs = try self.resolveInst(extra.rhs);2399 const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };
2369 const lhs_ty = self.air.typeOf(extra.lhs);2400 const lhs_ty = self.air.typeOf(extra.lhs);
2370 const rhs_ty = self.air.typeOf(extra.rhs);2401 const rhs_ty = self.air.typeOf(extra.rhs);
23712402
...@@ -2392,7 +2423,7 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -2392,7 +2423,7 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {
2392 .sub_with_overflow => .sub,2423 .sub_with_overflow => .sub,
2393 else => unreachable,2424 else => unreachable,
2394 };2425 };
2395 const dest = try self.binOp(base_tag, lhs, rhs, lhs_ty, rhs_ty, null);2426 const dest = try self.addSub(base_tag, lhs_bind, rhs_bind, lhs_ty, rhs_ty, null);
2396 const dest_reg = dest.register;2427 const dest_reg = dest.register;
2397 const dest_reg_lock = self.register_manager.lockRegAssumeUnused(dest_reg);2428 const dest_reg_lock = self.register_manager.lockRegAssumeUnused(dest_reg);
2398 defer self.register_manager.unlockReg(dest_reg_lock);2429 defer self.register_manager.unlockReg(dest_reg_lock);
...@@ -2422,18 +2453,21 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -2422,18 +2453,21 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {
2422 break :result MCValue{ .stack_offset = stack_offset };2453 break :result MCValue{ .stack_offset = stack_offset };
2423 },2454 },
2424 32, 64 => {2455 32, 64 => {
2456 const lhs_immediate = try lhs_bind.resolveToImmediate(self);
2457 const rhs_immediate = try rhs_bind.resolveToImmediate(self);
2458
2425 // Only say yes if the operation is2459 // Only say yes if the operation is
2426 // commutative, i.e. we can swap both of the2460 // commutative, i.e. we can swap both of the
2427 // operands2461 // operands
2428 const lhs_immediate_ok = switch (tag) {2462 const lhs_immediate_ok = switch (tag) {
2429 .add_with_overflow => lhs == .immediate and lhs.immediate <= std.math.maxInt(u12),2463 .add_with_overflow => if (lhs_immediate) |imm| imm <= std.math.maxInt(u12) else false,
2430 .sub_with_overflow => false,2464 .sub_with_overflow => false,
2431 else => unreachable,2465 else => unreachable,
2432 };2466 };
2433 const rhs_immediate_ok = switch (tag) {2467 const rhs_immediate_ok = switch (tag) {
2434 .add_with_overflow,2468 .add_with_overflow,
2435 .sub_with_overflow,2469 .sub_with_overflow,
2436 => rhs == .immediate and rhs.immediate <= std.math.maxInt(u12),2470 => if (rhs_immediate) |imm| imm <= std.math.maxInt(u12) else false,
2437 else => unreachable,2471 else => unreachable,
2438 };2472 };
24392473
...@@ -2453,12 +2487,12 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -2453,12 +2487,12 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {
24532487
2454 const dest = blk: {2488 const dest = blk: {
2455 if (rhs_immediate_ok) {2489 if (rhs_immediate_ok) {
2456 break :blk try self.binOpImmediate(mir_tag_immediate, lhs, rhs, lhs_ty, false, null);2490 break :blk try self.binOpImmediateNew(mir_tag_immediate, lhs_bind, rhs_immediate.?, lhs_ty, false, null);
2457 } else if (lhs_immediate_ok) {2491 } else if (lhs_immediate_ok) {
2458 // swap lhs and rhs2492 // swap lhs and rhs
2459 break :blk try self.binOpImmediate(mir_tag_immediate, rhs, lhs, rhs_ty, true, null);2493 break :blk try self.binOpImmediateNew(mir_tag_immediate, rhs_bind, lhs_immediate.?, rhs_ty, true, null);
2460 } else {2494 } else {
2461 break :blk try self.binOpRegister(mir_tag_register, lhs, rhs, lhs_ty, rhs_ty, null);2495 break :blk try self.binOpRegisterNew(mir_tag_register, lhs_bind, rhs_bind, lhs_ty, rhs_ty, null);
2462 }2496 }
2463 };2497 };
24642498
...@@ -3650,26 +3684,10 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde...@@ -3650,26 +3684,10 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde
3650 break :result MCValue{ .ptr_stack_offset = off - struct_field_offset };3684 break :result MCValue{ .ptr_stack_offset = off - struct_field_offset };
3651 },3685 },
3652 else => {3686 else => {
3653 const offset_reg = try self.copyToTmpRegister(ptr_ty, .{3687 const lhs_bind: ReadArg.Bind = .{ .mcv = mcv };
3654 .immediate = struct_field_offset,3688 const rhs_bind: ReadArg.Bind = .{ .mcv = .{ .immediate = struct_field_offset } };
3655 });
3656 const offset_reg_lock = self.register_manager.lockRegAssumeUnused(offset_reg);
3657 defer self.register_manager.unlockReg(offset_reg_lock);
3658
3659 const addr_reg = try self.copyToTmpRegister(ptr_ty, mcv);
3660 const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
3661 defer self.register_manager.unlockReg(addr_reg_lock);
36623689
3663 const dest = try self.binOp(3690 break :result try self.addSub(.add, lhs_bind, rhs_bind, Type.usize, Type.usize, null);
3664 .add,
3665 .{ .register = addr_reg },
3666 .{ .register = offset_reg },
3667 Type.usize,
3668 Type.usize,
3669 null,
3670 );
3671
3672 break :result dest;
3673 },3691 },
3674 }3692 }
3675 };3693 };