| ... | ... | @@ -561,33 +561,38 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 561 | 561 | |
| 562 | 562 | switch (air_tags[inst]) { |
| 563 | 563 | // zig fmt: off |
| 564 | | .add => try self.airBinOp(inst, .add), |
| 565 | | .addwrap => try self.airBinOp(inst, .addwrap), |
| 566 | | .sub => try self.airBinOp(inst, .sub), |
| 567 | | .subwrap => try self.airBinOp(inst, .subwrap), |
| 568 | | .mul => try self.airBinOp(inst, .mul), |
| 569 | | .mulwrap => try self.airBinOp(inst, .mulwrap), |
| 570 | | .shl => try self.airBinOp(inst, .shl), |
| 571 | | .shl_exact => try self.airBinOp(inst, .shl_exact), |
| 572 | | .bool_and => try self.airBinOp(inst, .bool_and), |
| 573 | | .bool_or => try self.airBinOp(inst, .bool_or), |
| 574 | | .bit_and => try self.airBinOp(inst, .bit_and), |
| 575 | | .bit_or => try self.airBinOp(inst, .bit_or), |
| 576 | | .xor => try self.airBinOp(inst, .xor), |
| 577 | | .shr => try self.airBinOp(inst, .shr), |
| 578 | | .shr_exact => try self.airBinOp(inst, .shr_exact), |
| 579 | | |
| 580 | | .ptr_add => try self.airPtrArithmetic(inst, .ptr_add), |
| 581 | | .ptr_sub => try self.airPtrArithmetic(inst, .ptr_sub), |
| 564 | .add => try self.airBinOp(inst, .add), |
| 565 | .addwrap => try self.airBinOp(inst, .addwrap), |
| 566 | .sub => try self.airBinOp(inst, .sub), |
| 567 | .subwrap => try self.airBinOp(inst, .subwrap), |
| 568 | .mul => try self.airBinOp(inst, .mul), |
| 569 | .mulwrap => try self.airBinOp(inst, .mulwrap), |
| 570 | .shl => try self.airBinOp(inst, .shl), |
| 571 | .shl_exact => try self.airBinOp(inst, .shl_exact), |
| 572 | .bool_and => try self.airBinOp(inst, .bool_and), |
| 573 | .bool_or => try self.airBinOp(inst, .bool_or), |
| 574 | .bit_and => try self.airBinOp(inst, .bit_and), |
| 575 | .bit_or => try self.airBinOp(inst, .bit_or), |
| 576 | .xor => try self.airBinOp(inst, .xor), |
| 577 | .shr => try self.airBinOp(inst, .shr), |
| 578 | .shr_exact => try self.airBinOp(inst, .shr_exact), |
| 579 | .div_float => try self.airBinOp(inst, .div_float), |
| 580 | .div_trunc => try self.airBinOp(inst, .div_trunc), |
| 581 | .div_floor => try self.airBinOp(inst, .div_floor), |
| 582 | .div_exact => try self.airBinOp(inst, .div_exact), |
| 583 | .rem => try self.airBinOp(inst, .rem), |
| 584 | .mod => try self.airBinOp(inst, .mod), |
| 585 | |
| 586 | .ptr_add => try self.airPtrArithmetic(inst, .ptr_add), |
| 587 | .ptr_sub => try self.airPtrArithmetic(inst, .ptr_sub), |
| 588 | |
| 589 | .min => try self.airMin(inst), |
| 590 | .max => try self.airMax(inst), |
| 582 | 591 | |
| 583 | 592 | .add_sat => try self.airAddSat(inst), |
| 584 | 593 | .sub_sat => try self.airSubSat(inst), |
| 585 | 594 | .mul_sat => try self.airMulSat(inst), |
| 586 | | .rem => try self.airRem(inst), |
| 587 | | .mod => try self.airMod(inst), |
| 588 | 595 | .shl_sat => try self.airShlSat(inst), |
| 589 | | .min => try self.airMin(inst), |
| 590 | | .max => try self.airMax(inst), |
| 591 | 596 | .slice => try self.airSlice(inst), |
| 592 | 597 | |
| 593 | 598 | .sqrt, |
| ... | ... | @@ -612,8 +617,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 612 | 617 | .mul_with_overflow => try self.airMulWithOverflow(inst), |
| 613 | 618 | .shl_with_overflow => try self.airShlWithOverflow(inst), |
| 614 | 619 | |
| 615 | | .div_float, .div_trunc, .div_floor, .div_exact => try self.airDiv(inst), |
| 616 | | |
| 617 | 620 | .cmp_lt => try self.airCmp(inst, .lt), |
| 618 | 621 | .cmp_lte => try self.airCmp(inst, .lte), |
| 619 | 622 | .cmp_eq => try self.airCmp(inst, .eq), |
| ... | ... | @@ -1391,6 +1394,8 @@ fn binOpRegister( |
| 1391 | 1394 | .lsl_register, |
| 1392 | 1395 | .asr_register, |
| 1393 | 1396 | .lsr_register, |
| 1397 | .sdiv, |
| 1398 | .udiv, |
| 1394 | 1399 | => .{ .rrr = .{ |
| 1395 | 1400 | .rd = dest_reg, |
| 1396 | 1401 | .rn = lhs_reg, |
| ... | ... | @@ -1629,6 +1634,67 @@ fn binOp( |
| 1629 | 1634 | else => unreachable, |
| 1630 | 1635 | } |
| 1631 | 1636 | }, |
| 1637 | .div_float => { |
| 1638 | switch (lhs_ty.zigTypeTag()) { |
| 1639 | .Float => return self.fail("TODO div_float", .{}), |
| 1640 | .Vector => return self.fail("TODO div_float on vectors", .{}), |
| 1641 | else => unreachable, |
| 1642 | } |
| 1643 | }, |
| 1644 | .div_trunc, .div_floor, .div_exact => { |
| 1645 | switch (lhs_ty.zigTypeTag()) { |
| 1646 | .Float => return self.fail("TODO div on floats", .{}), |
| 1647 | .Vector => return self.fail("TODO div on vectors", .{}), |
| 1648 | .Int => { |
| 1649 | assert(lhs_ty.eql(rhs_ty, mod)); |
| 1650 | const int_info = lhs_ty.intInfo(self.target.*); |
| 1651 | if (int_info.bits <= 64) { |
| 1652 | switch (int_info.signedness) { |
| 1653 | .signed => { |
| 1654 | switch (tag) { |
| 1655 | .div_trunc, .div_exact => { |
| 1656 | // TODO optimize integer division by constants |
| 1657 | return try self.binOpRegister(.sdiv, lhs, rhs, lhs_ty, rhs_ty, metadata); |
| 1658 | }, |
| 1659 | .div_floor => return self.fail("TODO div_floor on signed integers", .{}), |
| 1660 | else => unreachable, |
| 1661 | } |
| 1662 | }, |
| 1663 | .unsigned => { |
| 1664 | // TODO optimize integer division by constants |
| 1665 | return try self.binOpRegister(.udiv, lhs, rhs, lhs_ty, rhs_ty, metadata); |
| 1666 | }, |
| 1667 | } |
| 1668 | } else { |
| 1669 | return self.fail("TODO integer division for ints with bits > 64", .{}); |
| 1670 | } |
| 1671 | }, |
| 1672 | else => unreachable, |
| 1673 | } |
| 1674 | }, |
| 1675 | .rem, .mod => { |
| 1676 | switch (lhs_ty.zigTypeTag()) { |
| 1677 | .Float => return self.fail("TODO rem/mod on floats", .{}), |
| 1678 | .Vector => return self.fail("TODO rem/mod on vectors", .{}), |
| 1679 | .Int => { |
| 1680 | assert(lhs_ty.eql(rhs_ty, mod)); |
| 1681 | const int_info = lhs_ty.intInfo(self.target.*); |
| 1682 | if (int_info.bits <= 32) { |
| 1683 | switch (int_info.signedness) { |
| 1684 | .signed => { |
| 1685 | return self.fail("TODO rem/mod on signed integers", .{}); |
| 1686 | }, |
| 1687 | .unsigned => { |
| 1688 | return self.fail("TODO rem/mod on unsigned integers", .{}); |
| 1689 | }, |
| 1690 | } |
| 1691 | } else { |
| 1692 | return self.fail("TODO rem/mod for integers with bits > 64", .{}); |
| 1693 | } |
| 1694 | }, |
| 1695 | else => unreachable, |
| 1696 | } |
| 1697 | }, |
| 1632 | 1698 | .addwrap, |
| 1633 | 1699 | .subwrap, |
| 1634 | 1700 | .mulwrap, |
| ... | ... | @@ -2300,24 +2366,6 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 2300 | 2366 | return self.finishAir(inst, result, .{ extra.lhs, extra.rhs, .none }); |
| 2301 | 2367 | } |
| 2302 | 2368 | |
| 2303 | | fn airDiv(self: *Self, inst: Air.Inst.Index) !void { |
| 2304 | | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 2305 | | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement div for {}", .{self.target.cpu.arch}); |
| 2306 | | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 2307 | | } |
| 2308 | | |
| 2309 | | fn airRem(self: *Self, inst: Air.Inst.Index) !void { |
| 2310 | | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 2311 | | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement rem for {}", .{self.target.cpu.arch}); |
| 2312 | | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 2313 | | } |
| 2314 | | |
| 2315 | | fn airMod(self: *Self, inst: Air.Inst.Index) !void { |
| 2316 | | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 2317 | | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement mod for {}", .{self.target.cpu.arch}); |
| 2318 | | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 2319 | | } |
| 2320 | | |
| 2321 | 2369 | fn airShlSat(self: *Self, inst: Air.Inst.Index) !void { |
| 2322 | 2370 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 2323 | 2371 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement shl_sat for {}", .{self.target.cpu.arch}); |