authorgravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-04-17 18:57:30+02:00
committergravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-04-19 22:40:50+02:00
log0a909a6712fac386c635043d0a25539f69b3998f
tree15a0618dcb3a8421b8adba4c134c261b0df1966f
parentd9d9fea6aee7fd0f4dadb53e41f9884330229051
signaturelock-open Commit is signed but in an unrecognized format.

stage2 AArch64: implement addwrap, subwrap, mulwrap


2 files changed, 36 insertions(+), 29 deletions(-)

src/arch/aarch64/CodeGen.zig+36-21
...@@ -512,13 +512,13 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -512,13 +512,13 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
512 switch (air_tags[inst]) {512 switch (air_tags[inst]) {
513 // zig fmt: off513 // zig fmt: off
514 .add, .ptr_add => try self.airBinOp(inst),514 .add, .ptr_add => try self.airBinOp(inst),
515 .addwrap => try self.airAddWrap(inst),515 .addwrap => try self.airBinOp(inst),
516 .add_sat => try self.airAddSat(inst),516 .add_sat => try self.airAddSat(inst),
517 .sub, .ptr_sub => try self.airBinOp(inst),517 .sub, .ptr_sub => try self.airBinOp(inst),
518 .subwrap => try self.airSubWrap(inst),518 .subwrap => try self.airBinOp(inst),
519 .sub_sat => try self.airSubSat(inst),519 .sub_sat => try self.airSubSat(inst),
520 .mul => try self.airBinOp(inst),520 .mul => try self.airBinOp(inst),
521 .mulwrap => try self.airMulWrap(inst),521 .mulwrap => try self.airBinOp(inst),
522 .mul_sat => try self.airMulSat(inst),522 .mul_sat => try self.airMulSat(inst),
523 .rem => try self.airRem(inst),523 .rem => try self.airRem(inst),
524 .mod => try self.airMod(inst),524 .mod => try self.airMod(inst),
...@@ -1531,6 +1531,39 @@ fn binOp(...@@ -1531,6 +1531,39 @@ fn binOp(
1531 else => unreachable,1531 else => unreachable,
1532 }1532 }
1533 },1533 },
1534 .addwrap,
1535 .subwrap,
1536 .mulwrap,
1537 => {
1538 const base_tag: Air.Inst.Tag = switch (tag) {
1539 .addwrap => .add,
1540 .subwrap => .sub,
1541 .mulwrap => .mul,
1542 else => unreachable,
1543 };
1544
1545 // Generate an add/sub/mul
1546 const result = try self.binOp(base_tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty);
1547
1548 // Truncate if necessary
1549 switch (lhs_ty.zigTypeTag()) {
1550 .Vector => return self.fail("TODO binary operations on vectors", .{}),
1551 .Int => {
1552 const int_info = lhs_ty.intInfo(self.target.*);
1553 if (int_info.bits <= 64) {
1554 const result_reg = result.register;
1555
1556 if (int_info.bits < 64) {
1557 try self.truncRegister(result_reg, result_reg, int_info.signedness, int_info.bits);
1558 return result;
1559 } else return result;
1560 } else {
1561 return self.fail("TODO binary operations on integers > u64/i64", .{});
1562 }
1563 },
1564 else => unreachable,
1565 }
1566 },
1534 // Bitwise operations on integers1567 // Bitwise operations on integers
1535 .bit_and,1568 .bit_and,
1536 .bit_or,1569 .bit_or,
...@@ -1633,36 +1666,18 @@ fn airBinOp(self: *Self, inst: Air.Inst.Index) !void {...@@ -1633,36 +1666,18 @@ fn airBinOp(self: *Self, inst: Air.Inst.Index) !void {
1633 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });1666 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
1634}1667}
16351668
1636fn airAddWrap(self: *Self, inst: Air.Inst.Index) !void {
1637 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1638 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement addwrap for {}", .{self.target.cpu.arch});
1639 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
1640}
1641
1642fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {1669fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {
1643 const bin_op = self.air.instructions.items(.data)[inst].bin_op;1670 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1644 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement add_sat for {}", .{self.target.cpu.arch});1671 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement add_sat for {}", .{self.target.cpu.arch});
1645 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });1672 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
1646}1673}
16471674
1648fn airSubWrap(self: *Self, inst: Air.Inst.Index) !void {
1649 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1650 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement subwrap for {}", .{self.target.cpu.arch});
1651 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
1652}
1653
1654fn airSubSat(self: *Self, inst: Air.Inst.Index) !void {1675fn airSubSat(self: *Self, inst: Air.Inst.Index) !void {
1655 const bin_op = self.air.instructions.items(.data)[inst].bin_op;1676 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1656 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement sub_sat for {}", .{self.target.cpu.arch});1677 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement sub_sat for {}", .{self.target.cpu.arch});
1657 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });1678 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
1658}1679}
16591680
1660fn airMulWrap(self: *Self, inst: Air.Inst.Index) !void {
1661 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1662 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement mulwrap for {}", .{self.target.cpu.arch});
1663 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
1664}
1665
1666fn airMulSat(self: *Self, inst: Air.Inst.Index) !void {1681fn airMulSat(self: *Self, inst: Air.Inst.Index) !void {
1667 const bin_op = self.air.instructions.items(.data)[inst].bin_op;1682 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1668 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement mul_sat for {}", .{self.target.cpu.arch});1683 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement mul_sat for {}", .{self.target.cpu.arch});
test/behavior/math.zig-8
...@@ -499,8 +499,6 @@ fn mod(comptime T: type, a: T, b: T) T {...@@ -499,8 +499,6 @@ fn mod(comptime T: type, a: T, b: T) T {
499}499}
500500
501test "unsigned wrapping" {501test "unsigned wrapping" {
502 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
503
504 try testUnsignedWrappingEval(maxInt(u32));502 try testUnsignedWrappingEval(maxInt(u32));
505 comptime try testUnsignedWrappingEval(maxInt(u32));503 comptime try testUnsignedWrappingEval(maxInt(u32));
506}504}
...@@ -512,8 +510,6 @@ fn testUnsignedWrappingEval(x: u32) !void {...@@ -512,8 +510,6 @@ fn testUnsignedWrappingEval(x: u32) !void {
512}510}
513511
514test "signed wrapping" {512test "signed wrapping" {
515 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
516
517 try testSignedWrappingEval(maxInt(i32));513 try testSignedWrappingEval(maxInt(i32));
518 comptime try testSignedWrappingEval(maxInt(i32));514 comptime try testSignedWrappingEval(maxInt(i32));
519}515}
...@@ -525,8 +521,6 @@ fn testSignedWrappingEval(x: i32) !void {...@@ -525,8 +521,6 @@ fn testSignedWrappingEval(x: i32) !void {
525}521}
526522
527test "signed negation wrapping" {523test "signed negation wrapping" {
528 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
529
530 try testSignedNegationWrappingEval(minInt(i16));524 try testSignedNegationWrappingEval(minInt(i16));
531 comptime try testSignedNegationWrappingEval(minInt(i16));525 comptime try testSignedNegationWrappingEval(minInt(i16));
532}526}
...@@ -537,8 +531,6 @@ fn testSignedNegationWrappingEval(x: i16) !void {...@@ -537,8 +531,6 @@ fn testSignedNegationWrappingEval(x: i16) !void {
537}531}
538532
539test "unsigned negation wrapping" {533test "unsigned negation wrapping" {
540 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
541
542 try testUnsignedNegationWrappingEval(1);534 try testUnsignedNegationWrappingEval(1);
543 comptime try testUnsignedNegationWrappingEval(1);535 comptime try testUnsignedNegationWrappingEval(1);
544}536}