| ... | @@ -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: off | 513 | // 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 integers | 1567 | // 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 | } |
| 1635 | | 1668 | |
| 1636 | fn 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 | | | |
| 1642 | fn airAddSat(self: *Self, inst: Air.Inst.Index) !void { | 1669 | fn 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 | } |
| 1647 | | 1674 | |
| 1648 | fn 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 | | | |
| 1654 | fn airSubSat(self: *Self, inst: Air.Inst.Index) !void { | 1675 | fn 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 | } |
| 1659 | | 1680 | |
| 1660 | fn 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 | | | |
| 1666 | fn airMulSat(self: *Self, inst: Air.Inst.Index) !void { | 1681 | fn 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}); |