authorgravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-04-17 20:47:01+02:00
committergravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-04-19 22:40:50+02:00
logcbb13c023eb24d08b7f46119fad5e2aa1c7a63bb
tree690844c1171c5f3218850fc2f250a356fa75dc92
parent0a909a6712fac386c635043d0a25539f69b3998f
signaturelock-open Commit is signed but in an unrecognized format.

stage2 AArch64: change binOp lowering mechanism to use Mir tags

Mirrors e2e69803dc16efe11a6d42c6c49853e16a41fd0c for AArch64

1 files changed, 75 insertions(+), 82 deletions(-)

src/arch/aarch64/CodeGen.zig+75-82
......@@ -1193,7 +1193,7 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void {
11931193/// Asserts that generating an instruction of that form is possible.
11941194fn binOpRegister(
11951195 self: *Self,
1196 tag: Air.Inst.Tag,
1196 mir_tag: Mir.Inst.Tag,
11971197 maybe_inst: ?Air.Inst.Index,
11981198 lhs: MCValue,
11991199 rhs: MCValue,
......@@ -1256,38 +1256,9 @@ fn binOpRegister(
12561256 if (!lhs_is_register) try self.genSetReg(lhs_ty, lhs_reg, lhs);
12571257 if (!rhs_is_register) try self.genSetReg(rhs_ty, rhs_reg, rhs);
12581258
1259 const mir_tag: Mir.Inst.Tag = switch (tag) {
1260 .add,
1261 .ptr_add,
1262 => .add_shifted_register,
1263 .sub,
1264 .ptr_sub,
1265 => .sub_shifted_register,
1266 .cmp_eq => .cmp_shifted_register,
1267 .mul => .mul,
1268 .bit_and,
1269 .bool_and,
1270 => .and_shifted_register,
1271 .bit_or,
1272 .bool_or,
1273 => .orr_shifted_register,
1274 .shl,
1275 .shl_exact,
1276 => .lsl_register,
1277 .shr,
1278 .shr_exact,
1279 => switch (lhs_ty.intInfo(self.target.*).signedness) {
1280 .signed => Mir.Inst.Tag.asr_register,
1281 .unsigned => Mir.Inst.Tag.lsr_register,
1282 },
1283 .xor => .eor_shifted_register,
1284 else => unreachable,
1285 };
1286 const mir_data: Mir.Inst.Data = switch (tag) {
1287 .add,
1288 .sub,
1289 .ptr_add,
1290 .ptr_sub,
1259 const mir_data: Mir.Inst.Data = switch (mir_tag) {
1260 .add_shifted_register,
1261 .sub_shifted_register,
12911262 => .{ .rrr_imm6_shift = .{
12921263 .rd = dest_reg,
12931264 .rn = lhs_reg,
......@@ -1295,27 +1266,24 @@ fn binOpRegister(
12951266 .imm6 = 0,
12961267 .shift = .lsl,
12971268 } },
1298 .cmp_eq => .{ .rr_imm6_shift = .{
1269 .cmp_shifted_register => .{ .rr_imm6_shift = .{
12991270 .rn = lhs_reg,
13001271 .rm = rhs_reg,
13011272 .imm6 = 0,
13021273 .shift = .lsl,
13031274 } },
13041275 .mul,
1305 .shl,
1306 .shl_exact,
1307 .shr,
1308 .shr_exact,
1276 .lsl_register,
1277 .asr_register,
1278 .lsr_register,
13091279 => .{ .rrr = .{
13101280 .rd = dest_reg,
13111281 .rn = lhs_reg,
13121282 .rm = rhs_reg,
13131283 } },
1314 .bit_and,
1315 .bool_and,
1316 .bit_or,
1317 .bool_or,
1318 .xor,
1284 .and_shifted_register,
1285 .orr_shifted_register,
1286 .eor_shifted_register,
13191287 => .{ .rrr_imm6_logical_shift = .{
13201288 .rd = dest_reg,
13211289 .rn = lhs_reg,
......@@ -1348,7 +1316,7 @@ fn binOpRegister(
13481316/// Asserts that generating an instruction of that form is possible.
13491317fn binOpImmediate(
13501318 self: *Self,
1351 tag: Air.Inst.Tag,
1319 mir_tag: Mir.Inst.Tag,
13521320 maybe_inst: ?Air.Inst.Index,
13531321 lhs: MCValue,
13541322 rhs: MCValue,
......@@ -1379,8 +1347,8 @@ fn binOpImmediate(
13791347 };
13801348 defer self.register_manager.unfreezeRegs(&.{lhs_reg});
13811349
1382 const dest_reg = switch (tag) {
1383 .cmp_eq => undefined, // cmp has no destination register
1350 const dest_reg = switch (mir_tag) {
1351 .cmp_immediate => undefined, // cmp has no destination register
13841352 else => if (maybe_inst) |inst| blk: {
13851353 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
13861354
......@@ -1400,39 +1368,23 @@ fn binOpImmediate(
14001368
14011369 if (!lhs_is_register) try self.genSetReg(lhs_ty, lhs_reg, lhs);
14021370
1403 const mir_tag: Mir.Inst.Tag = switch (tag) {
1404 .add => .add_immediate,
1405 .sub => .sub_immediate,
1406 .shl,
1407 .shl_exact,
1408 => .lsl_immediate,
1409 .shr,
1410 .shr_exact,
1411 => switch (lhs_ty.intInfo(self.target.*).signedness) {
1412 .signed => Mir.Inst.Tag.asr_immediate,
1413 .unsigned => Mir.Inst.Tag.lsr_immediate,
1414 },
1415 .cmp_eq => .cmp_immediate,
1416 else => unreachable,
1417 };
1418 const mir_data: Mir.Inst.Data = switch (tag) {
1419 .add,
1420 .sub,
1371 const mir_data: Mir.Inst.Data = switch (mir_tag) {
1372 .add_immediate,
1373 .sub_immediate,
14211374 => .{ .rr_imm12_sh = .{
14221375 .rd = dest_reg,
14231376 .rn = lhs_reg,
14241377 .imm12 = @intCast(u12, rhs.immediate),
14251378 } },
1426 .shl,
1427 .shl_exact,
1428 .shr,
1429 .shr_exact,
1379 .lsl_immediate,
1380 .asr_immediate,
1381 .lsr_immediate,
14301382 => .{ .rr_shift = .{
14311383 .rd = dest_reg,
14321384 .rn = lhs_reg,
14331385 .shift = @intCast(u6, rhs.immediate),
14341386 } },
1435 .cmp_eq => .{ .r_imm12_sh = .{
1387 .cmp_immediate => .{ .r_imm12_sh = .{
14361388 .rn = lhs_reg,
14371389 .imm12 = @intCast(u12, rhs.immediate),
14381390 } },
......@@ -1470,7 +1422,6 @@ fn binOp(
14701422) InnerError!MCValue {
14711423 const target = self.target.*;
14721424 switch (tag) {
1473 // Arithmetic operations on integers and floats
14741425 .add,
14751426 .sub,
14761427 .cmp_eq,
......@@ -1498,13 +1449,26 @@ fn binOp(
14981449 else => unreachable,
14991450 };
15001451
1452 const mir_tag_register: Mir.Inst.Tag = switch (tag) {
1453 .add => .add_shifted_register,
1454 .sub => .sub_shifted_register,
1455 .cmp_eq => .cmp_shifted_register,
1456 else => unreachable,
1457 };
1458 const mir_tag_immediate: Mir.Inst.Tag = switch (tag) {
1459 .add => .add_immediate,
1460 .sub => .sub_immediate,
1461 .cmp_eq => .cmp_immediate,
1462 else => unreachable,
1463 };
1464
15011465 if (rhs_immediate_ok) {
1502 return try self.binOpImmediate(tag, maybe_inst, lhs, rhs, lhs_ty, false);
1466 return try self.binOpImmediate(mir_tag_immediate, maybe_inst, lhs, rhs, lhs_ty, false);
15031467 } else if (lhs_immediate_ok) {
15041468 // swap lhs and rhs
1505 return try self.binOpImmediate(tag, maybe_inst, rhs, lhs, rhs_ty, true);
1469 return try self.binOpImmediate(mir_tag_immediate, maybe_inst, rhs, lhs, rhs_ty, true);
15061470 } else {
1507 return try self.binOpRegister(tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty);
1471 return try self.binOpRegister(mir_tag_register, maybe_inst, lhs, rhs, lhs_ty, rhs_ty);
15081472 }
15091473 } else {
15101474 return self.fail("TODO binary operations on int with bits > 64", .{});
......@@ -1523,7 +1487,7 @@ fn binOp(
15231487 // TODO add optimisations for multiplication
15241488 // with immediates, for example a * 2 can be
15251489 // lowered to a << 1
1526 return try self.binOpRegister(tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty);
1490 return try self.binOpRegister(.mul, maybe_inst, lhs, rhs, lhs_ty, rhs_ty);
15271491 } else {
15281492 return self.fail("TODO binary operations on int with bits > 64", .{});
15291493 }
......@@ -1564,7 +1528,6 @@ fn binOp(
15641528 else => unreachable,
15651529 }
15661530 },
1567 // Bitwise operations on integers
15681531 .bit_and,
15691532 .bit_or,
15701533 .xor,
......@@ -1576,7 +1539,14 @@ fn binOp(
15761539 const int_info = lhs_ty.intInfo(self.target.*);
15771540 if (int_info.bits <= 64) {
15781541 // TODO implement bitwise operations with immediates
1579 return try self.binOpRegister(tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty);
1542 const mir_tag: Mir.Inst.Tag = switch (tag) {
1543 .bit_and => .and_shifted_register,
1544 .bit_or => .orr_shifted_register,
1545 .xor => .eor_shifted_register,
1546 else => unreachable,
1547 };
1548
1549 return try self.binOpRegister(mir_tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty);
15801550 } else {
15811551 return self.fail("TODO binary operations on int with bits > 64", .{});
15821552 }
......@@ -1594,10 +1564,27 @@ fn binOp(
15941564 if (int_info.bits <= 64) {
15951565 const rhs_immediate_ok = rhs == .immediate;
15961566
1567 const mir_tag_register: Mir.Inst.Tag = switch (tag) {
1568 .shl => .lsl_register,
1569 .shr => switch (lhs_ty.intInfo(self.target.*).signedness) {
1570 .signed => Mir.Inst.Tag.asr_register,
1571 .unsigned => Mir.Inst.Tag.lsr_register,
1572 },
1573 else => unreachable,
1574 };
1575 const mir_tag_immediate: Mir.Inst.Tag = switch (tag) {
1576 .shl => .lsl_immediate,
1577 .shr => switch (lhs_ty.intInfo(self.target.*).signedness) {
1578 .signed => Mir.Inst.Tag.asr_immediate,
1579 .unsigned => Mir.Inst.Tag.lsr_immediate,
1580 },
1581 else => unreachable,
1582 };
1583
15971584 if (rhs_immediate_ok) {
1598 return try self.binOpImmediate(tag, maybe_inst, lhs, rhs, lhs_ty, false);
1585 return try self.binOpImmediate(mir_tag_immediate, maybe_inst, lhs, rhs, lhs_ty, false);
15991586 } else {
1600 return try self.binOpRegister(tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty);
1587 return try self.binOpRegister(mir_tag_register, maybe_inst, lhs, rhs, lhs_ty, rhs_ty);
16011588 }
16021589 } else {
16031590 return self.fail("TODO binary operations on int with bits > 64", .{});
......@@ -1614,7 +1601,13 @@ fn binOp(
16141601 assert(lhs != .immediate); // should have been handled by Sema
16151602 assert(rhs != .immediate); // should have been handled by Sema
16161603
1617 return try self.binOpRegister(tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty);
1604 const mir_tag_register: Mir.Inst.Tag = switch (tag) {
1605 .bool_and => .and_shifted_register,
1606 .bool_or => .orr_shifted_register,
1607 else => unreachable,
1608 };
1609
1610 return try self.binOpRegister(mir_tag_register, maybe_inst, lhs, rhs, lhs_ty, rhs_ty);
16181611 },
16191612 else => unreachable,
16201613 }
......@@ -1632,9 +1625,9 @@ fn binOp(
16321625 const elem_size = elem_ty.abiSize(self.target.*);
16331626
16341627 if (elem_size == 1) {
1635 const base_tag: Air.Inst.Tag = switch (tag) {
1636 .ptr_add => .add,
1637 .ptr_sub => .sub,
1628 const base_tag: Mir.Inst.Tag = switch (tag) {
1629 .ptr_add => .add_shifted_register,
1630 .ptr_sub => .sub_shifted_register,
16381631 else => unreachable,
16391632 };
16401633