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 {...@@ -1193,7 +1193,7 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void {
1193/// Asserts that generating an instruction of that form is possible.1193/// Asserts that generating an instruction of that form is possible.
1194fn binOpRegister(1194fn binOpRegister(
1195 self: *Self,1195 self: *Self,
1196 tag: Air.Inst.Tag,1196 mir_tag: Mir.Inst.Tag,
1197 maybe_inst: ?Air.Inst.Index,1197 maybe_inst: ?Air.Inst.Index,
1198 lhs: MCValue,1198 lhs: MCValue,
1199 rhs: MCValue,1199 rhs: MCValue,
...@@ -1256,38 +1256,9 @@ fn binOpRegister(...@@ -1256,38 +1256,9 @@ fn binOpRegister(
1256 if (!lhs_is_register) try self.genSetReg(lhs_ty, lhs_reg, lhs);1256 if (!lhs_is_register) try self.genSetReg(lhs_ty, lhs_reg, lhs);
1257 if (!rhs_is_register) try self.genSetReg(rhs_ty, rhs_reg, rhs);1257 if (!rhs_is_register) try self.genSetReg(rhs_ty, rhs_reg, rhs);
12581258
1259 const mir_tag: Mir.Inst.Tag = switch (tag) {1259 const mir_data: Mir.Inst.Data = switch (mir_tag) {
1260 .add,1260 .add_shifted_register,
1261 .ptr_add,1261 .sub_shifted_register,
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,
1291 => .{ .rrr_imm6_shift = .{1262 => .{ .rrr_imm6_shift = .{
1292 .rd = dest_reg,1263 .rd = dest_reg,
1293 .rn = lhs_reg,1264 .rn = lhs_reg,
...@@ -1295,27 +1266,24 @@ fn binOpRegister(...@@ -1295,27 +1266,24 @@ fn binOpRegister(
1295 .imm6 = 0,1266 .imm6 = 0,
1296 .shift = .lsl,1267 .shift = .lsl,
1297 } },1268 } },
1298 .cmp_eq => .{ .rr_imm6_shift = .{1269 .cmp_shifted_register => .{ .rr_imm6_shift = .{
1299 .rn = lhs_reg,1270 .rn = lhs_reg,
1300 .rm = rhs_reg,1271 .rm = rhs_reg,
1301 .imm6 = 0,1272 .imm6 = 0,
1302 .shift = .lsl,1273 .shift = .lsl,
1303 } },1274 } },
1304 .mul,1275 .mul,
1305 .shl,1276 .lsl_register,
1306 .shl_exact,1277 .asr_register,
1307 .shr,1278 .lsr_register,
1308 .shr_exact,
1309 => .{ .rrr = .{1279 => .{ .rrr = .{
1310 .rd = dest_reg,1280 .rd = dest_reg,
1311 .rn = lhs_reg,1281 .rn = lhs_reg,
1312 .rm = rhs_reg,1282 .rm = rhs_reg,
1313 } },1283 } },
1314 .bit_and,1284 .and_shifted_register,
1315 .bool_and,1285 .orr_shifted_register,
1316 .bit_or,1286 .eor_shifted_register,
1317 .bool_or,
1318 .xor,
1319 => .{ .rrr_imm6_logical_shift = .{1287 => .{ .rrr_imm6_logical_shift = .{
1320 .rd = dest_reg,1288 .rd = dest_reg,
1321 .rn = lhs_reg,1289 .rn = lhs_reg,
...@@ -1348,7 +1316,7 @@ fn binOpRegister(...@@ -1348,7 +1316,7 @@ fn binOpRegister(
1348/// Asserts that generating an instruction of that form is possible.1316/// Asserts that generating an instruction of that form is possible.
1349fn binOpImmediate(1317fn binOpImmediate(
1350 self: *Self,1318 self: *Self,
1351 tag: Air.Inst.Tag,1319 mir_tag: Mir.Inst.Tag,
1352 maybe_inst: ?Air.Inst.Index,1320 maybe_inst: ?Air.Inst.Index,
1353 lhs: MCValue,1321 lhs: MCValue,
1354 rhs: MCValue,1322 rhs: MCValue,
...@@ -1379,8 +1347,8 @@ fn binOpImmediate(...@@ -1379,8 +1347,8 @@ fn binOpImmediate(
1379 };1347 };
1380 defer self.register_manager.unfreezeRegs(&.{lhs_reg});1348 defer self.register_manager.unfreezeRegs(&.{lhs_reg});
13811349
1382 const dest_reg = switch (tag) {1350 const dest_reg = switch (mir_tag) {
1383 .cmp_eq => undefined, // cmp has no destination register1351 .cmp_immediate => undefined, // cmp has no destination register
1384 else => if (maybe_inst) |inst| blk: {1352 else => if (maybe_inst) |inst| blk: {
1385 const bin_op = self.air.instructions.items(.data)[inst].bin_op;1353 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
13861354
...@@ -1400,39 +1368,23 @@ fn binOpImmediate(...@@ -1400,39 +1368,23 @@ fn binOpImmediate(
14001368
1401 if (!lhs_is_register) try self.genSetReg(lhs_ty, lhs_reg, lhs);1369 if (!lhs_is_register) try self.genSetReg(lhs_ty, lhs_reg, lhs);
14021370
1403 const mir_tag: Mir.Inst.Tag = switch (tag) {1371 const mir_data: Mir.Inst.Data = switch (mir_tag) {
1404 .add => .add_immediate,1372 .add_immediate,
1405 .sub => .sub_immediate,1373 .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,
1421 => .{ .rr_imm12_sh = .{1374 => .{ .rr_imm12_sh = .{
1422 .rd = dest_reg,1375 .rd = dest_reg,
1423 .rn = lhs_reg,1376 .rn = lhs_reg,
1424 .imm12 = @intCast(u12, rhs.immediate),1377 .imm12 = @intCast(u12, rhs.immediate),
1425 } },1378 } },
1426 .shl,1379 .lsl_immediate,
1427 .shl_exact,1380 .asr_immediate,
1428 .shr,1381 .lsr_immediate,
1429 .shr_exact,
1430 => .{ .rr_shift = .{1382 => .{ .rr_shift = .{
1431 .rd = dest_reg,1383 .rd = dest_reg,
1432 .rn = lhs_reg,1384 .rn = lhs_reg,
1433 .shift = @intCast(u6, rhs.immediate),1385 .shift = @intCast(u6, rhs.immediate),
1434 } },1386 } },
1435 .cmp_eq => .{ .r_imm12_sh = .{1387 .cmp_immediate => .{ .r_imm12_sh = .{
1436 .rn = lhs_reg,1388 .rn = lhs_reg,
1437 .imm12 = @intCast(u12, rhs.immediate),1389 .imm12 = @intCast(u12, rhs.immediate),
1438 } },1390 } },
...@@ -1470,7 +1422,6 @@ fn binOp(...@@ -1470,7 +1422,6 @@ fn binOp(
1470) InnerError!MCValue {1422) InnerError!MCValue {
1471 const target = self.target.*;1423 const target = self.target.*;
1472 switch (tag) {1424 switch (tag) {
1473 // Arithmetic operations on integers and floats
1474 .add,1425 .add,
1475 .sub,1426 .sub,
1476 .cmp_eq,1427 .cmp_eq,
...@@ -1498,13 +1449,26 @@ fn binOp(...@@ -1498,13 +1449,26 @@ fn binOp(
1498 else => unreachable,1449 else => unreachable,
1499 };1450 };
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
1501 if (rhs_immediate_ok) {1465 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);
1503 } else if (lhs_immediate_ok) {1467 } else if (lhs_immediate_ok) {
1504 // swap lhs and rhs1468 // 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);
1506 } else {1470 } 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);
1508 }1472 }
1509 } else {1473 } else {
1510 return self.fail("TODO binary operations on int with bits > 64", .{});1474 return self.fail("TODO binary operations on int with bits > 64", .{});
...@@ -1523,7 +1487,7 @@ fn binOp(...@@ -1523,7 +1487,7 @@ fn binOp(
1523 // TODO add optimisations for multiplication1487 // TODO add optimisations for multiplication
1524 // with immediates, for example a * 2 can be1488 // with immediates, for example a * 2 can be
1525 // lowered to a << 11489 // 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);
1527 } else {1491 } else {
1528 return self.fail("TODO binary operations on int with bits > 64", .{});1492 return self.fail("TODO binary operations on int with bits > 64", .{});
1529 }1493 }
...@@ -1564,7 +1528,6 @@ fn binOp(...@@ -1564,7 +1528,6 @@ fn binOp(
1564 else => unreachable,1528 else => unreachable,
1565 }1529 }
1566 },1530 },
1567 // Bitwise operations on integers
1568 .bit_and,1531 .bit_and,
1569 .bit_or,1532 .bit_or,
1570 .xor,1533 .xor,
...@@ -1576,7 +1539,14 @@ fn binOp(...@@ -1576,7 +1539,14 @@ fn binOp(
1576 const int_info = lhs_ty.intInfo(self.target.*);1539 const int_info = lhs_ty.intInfo(self.target.*);
1577 if (int_info.bits <= 64) {1540 if (int_info.bits <= 64) {
1578 // TODO implement bitwise operations with immediates1541 // 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);
1580 } else {1550 } else {
1581 return self.fail("TODO binary operations on int with bits > 64", .{});1551 return self.fail("TODO binary operations on int with bits > 64", .{});
1582 }1552 }
...@@ -1594,10 +1564,27 @@ fn binOp(...@@ -1594,10 +1564,27 @@ fn binOp(
1594 if (int_info.bits <= 64) {1564 if (int_info.bits <= 64) {
1595 const rhs_immediate_ok = rhs == .immediate;1565 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
1597 if (rhs_immediate_ok) {1584 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);
1599 } else {1586 } 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);
1601 }1588 }
1602 } else {1589 } else {
1603 return self.fail("TODO binary operations on int with bits > 64", .{});1590 return self.fail("TODO binary operations on int with bits > 64", .{});
...@@ -1614,7 +1601,13 @@ fn binOp(...@@ -1614,7 +1601,13 @@ fn binOp(
1614 assert(lhs != .immediate); // should have been handled by Sema1601 assert(lhs != .immediate); // should have been handled by Sema
1615 assert(rhs != .immediate); // should have been handled by Sema1602 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);
1618 },1611 },
1619 else => unreachable,1612 else => unreachable,
1620 }1613 }
...@@ -1632,9 +1625,9 @@ fn binOp(...@@ -1632,9 +1625,9 @@ fn binOp(
1632 const elem_size = elem_ty.abiSize(self.target.*);1625 const elem_size = elem_ty.abiSize(self.target.*);
16331626
1634 if (elem_size == 1) {1627 if (elem_size == 1) {
1635 const base_tag: Air.Inst.Tag = switch (tag) {1628 const base_tag: Mir.Inst.Tag = switch (tag) {
1636 .ptr_add => .add,1629 .ptr_add => .add_shifted_register,
1637 .ptr_sub => .sub,1630 .ptr_sub => .sub_shifted_register,
1638 else => unreachable,1631 else => unreachable,
1639 };1632 };
16401633