| ... | @@ -1138,6 +1138,8 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1138,6 +1138,8 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void { |
| 1138 | } }, | 1138 | } }, |
| 1139 | }); | 1139 | }); |
| 1140 | | 1140 | |
| | 1141 | try self.truncRegister(dest_reg, dest_reg, int_info.signedness, int_info.bits); |
| | 1142 | |
| 1141 | break :result MCValue{ .register = dest_reg }; | 1143 | break :result MCValue{ .register = dest_reg }; |
| 1142 | } else { | 1144 | } else { |
| 1143 | return self.fail("TODO AArch64 not on integers > u64/i64", .{}); | 1145 | return self.fail("TODO AArch64 not on integers > u64/i64", .{}); |
| ... | @@ -1516,11 +1518,8 @@ fn binOp( | ... | @@ -1516,11 +1518,8 @@ fn binOp( |
| 1516 | const int_info = lhs_ty.intInfo(self.target.*); | 1518 | const int_info = lhs_ty.intInfo(self.target.*); |
| 1517 | if (int_info.bits <= 64) { | 1519 | if (int_info.bits <= 64) { |
| 1518 | const result_reg = result.register; | 1520 | const result_reg = result.register; |
| 1519 | | 1521 | try self.truncRegister(result_reg, result_reg, int_info.signedness, int_info.bits); |
| 1520 | if (int_info.bits < 64) { | 1522 | return result; |
| 1521 | try self.truncRegister(result_reg, result_reg, int_info.signedness, int_info.bits); | | |
| 1522 | return result; | | |
| 1523 | } else return result; | | |
| 1524 | } else { | 1523 | } else { |
| 1525 | return self.fail("TODO binary operations on integers > u64/i64", .{}); | 1524 | return self.fail("TODO binary operations on integers > u64/i64", .{}); |
| 1526 | } | 1525 | } |
| ... | @@ -1554,8 +1553,8 @@ fn binOp( | ... | @@ -1554,8 +1553,8 @@ fn binOp( |
| 1554 | else => unreachable, | 1553 | else => unreachable, |
| 1555 | } | 1554 | } |
| 1556 | }, | 1555 | }, |
| 1557 | .shl, | 1556 | .shl_exact, |
| 1558 | .shr, | 1557 | .shr_exact, |
| 1559 | => { | 1558 | => { |
| 1560 | switch (lhs_ty.zigTypeTag()) { | 1559 | switch (lhs_ty.zigTypeTag()) { |
| 1561 | .Vector => return self.fail("TODO binary operations on vectors", .{}), | 1560 | .Vector => return self.fail("TODO binary operations on vectors", .{}), |
| ... | @@ -1565,16 +1564,16 @@ fn binOp( | ... | @@ -1565,16 +1564,16 @@ fn binOp( |
| 1565 | const rhs_immediate_ok = rhs == .immediate; | 1564 | const rhs_immediate_ok = rhs == .immediate; |
| 1566 | | 1565 | |
| 1567 | const mir_tag_register: Mir.Inst.Tag = switch (tag) { | 1566 | const mir_tag_register: Mir.Inst.Tag = switch (tag) { |
| 1568 | .shl => .lsl_register, | 1567 | .shl_exact => .lsl_register, |
| 1569 | .shr => switch (lhs_ty.intInfo(self.target.*).signedness) { | 1568 | .shr_exact => switch (int_info.signedness) { |
| 1570 | .signed => Mir.Inst.Tag.asr_register, | 1569 | .signed => Mir.Inst.Tag.asr_register, |
| 1571 | .unsigned => Mir.Inst.Tag.lsr_register, | 1570 | .unsigned => Mir.Inst.Tag.lsr_register, |
| 1572 | }, | 1571 | }, |
| 1573 | else => unreachable, | 1572 | else => unreachable, |
| 1574 | }; | 1573 | }; |
| 1575 | const mir_tag_immediate: Mir.Inst.Tag = switch (tag) { | 1574 | const mir_tag_immediate: Mir.Inst.Tag = switch (tag) { |
| 1576 | .shl => .lsl_immediate, | 1575 | .shl_exact => .lsl_immediate, |
| 1577 | .shr => switch (lhs_ty.intInfo(self.target.*).signedness) { | 1576 | .shr_exact => switch (int_info.signedness) { |
| 1578 | .signed => Mir.Inst.Tag.asr_immediate, | 1577 | .signed => Mir.Inst.Tag.asr_immediate, |
| 1579 | .unsigned => Mir.Inst.Tag.lsr_immediate, | 1578 | .unsigned => Mir.Inst.Tag.lsr_immediate, |
| 1580 | }, | 1579 | }, |
| ... | @@ -1593,6 +1592,38 @@ fn binOp( | ... | @@ -1593,6 +1592,38 @@ fn binOp( |
| 1593 | else => unreachable, | 1592 | else => unreachable, |
| 1594 | } | 1593 | } |
| 1595 | }, | 1594 | }, |
| | 1595 | .shl, |
| | 1596 | .shr, |
| | 1597 | => { |
| | 1598 | const base_tag: Air.Inst.Tag = switch (tag) { |
| | 1599 | .shl => .shl_exact, |
| | 1600 | .shr => .shr_exact, |
| | 1601 | else => unreachable, |
| | 1602 | }; |
| | 1603 | |
| | 1604 | // Generate a shl_exact/shr_exact |
| | 1605 | const result = try self.binOp(base_tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty); |
| | 1606 | |
| | 1607 | // Truncate if necessary |
| | 1608 | switch (tag) { |
| | 1609 | .shr => return result, |
| | 1610 | .shl => switch (lhs_ty.zigTypeTag()) { |
| | 1611 | .Vector => return self.fail("TODO binary operations on vectors", .{}), |
| | 1612 | .Int => { |
| | 1613 | const int_info = lhs_ty.intInfo(self.target.*); |
| | 1614 | if (int_info.bits <= 64) { |
| | 1615 | const result_reg = result.register; |
| | 1616 | try self.truncRegister(result_reg, result_reg, int_info.signedness, int_info.bits); |
| | 1617 | return result; |
| | 1618 | } else { |
| | 1619 | return self.fail("TODO binary operations on integers > u64/i64", .{}); |
| | 1620 | } |
| | 1621 | }, |
| | 1622 | else => unreachable, |
| | 1623 | }, |
| | 1624 | else => unreachable, |
| | 1625 | } |
| | 1626 | }, |
| 1596 | .bool_and, | 1627 | .bool_and, |
| 1597 | .bool_or, | 1628 | .bool_or, |
| 1598 | => { | 1629 | => { |