| ... | ... | @@ -512,13 +512,13 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 512 | 512 | switch (air_tags[inst]) { |
| 513 | 513 | // zig fmt: off |
| 514 | 514 | .add, .ptr_add => try self.airBinOp(inst), |
| 515 | | .addwrap => try self.airAddWrap(inst), |
| 515 | .addwrap => try self.airBinOp(inst), |
| 516 | 516 | .add_sat => try self.airAddSat(inst), |
| 517 | 517 | .sub, .ptr_sub => try self.airBinOp(inst), |
| 518 | | .subwrap => try self.airSubWrap(inst), |
| 518 | .subwrap => try self.airBinOp(inst), |
| 519 | 519 | .sub_sat => try self.airSubSat(inst), |
| 520 | 520 | .mul => try self.airBinOp(inst), |
| 521 | | .mulwrap => try self.airMulWrap(inst), |
| 521 | .mulwrap => try self.airBinOp(inst), |
| 522 | 522 | .mul_sat => try self.airMulSat(inst), |
| 523 | 523 | .rem => try self.airRem(inst), |
| 524 | 524 | .mod => try self.airMod(inst), |
| ... | ... | @@ -1531,6 +1531,39 @@ fn binOp( |
| 1531 | 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 | 1567 | // Bitwise operations on integers |
| 1535 | 1568 | .bit_and, |
| 1536 | 1569 | .bit_or, |
| ... | ... | @@ -1633,36 +1666,18 @@ fn airBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 1633 | 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 | 1669 | fn airAddSat(self: *Self, inst: Air.Inst.Index) !void { |
| 1643 | 1670 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 1644 | 1671 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement add_sat for {}", .{self.target.cpu.arch}); |
| 1645 | 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 | 1675 | fn airSubSat(self: *Self, inst: Air.Inst.Index) !void { |
| 1655 | 1676 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 1656 | 1677 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement sub_sat for {}", .{self.target.cpu.arch}); |
| 1657 | 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 | 1681 | fn airMulSat(self: *Self, inst: Air.Inst.Index) !void { |
| 1667 | 1682 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 1668 | 1683 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement mul_sat for {}", .{self.target.cpu.arch}); |