| ... | @@ -1605,11 +1605,58 @@ fn airXor(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1605,11 +1605,58 @@ fn airXor(self: *Self, inst: Air.Inst.Index) !void { |
| 1605 | | 1605 | |
| 1606 | fn airShl(self: *Self, inst: Air.Inst.Index) !void { | 1606 | fn airShl(self: *Self, inst: Air.Inst.Index) !void { |
| 1607 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; | 1607 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 1608 | const result: MCValue = if (self.liveness.isUnused(inst)) | 1608 | if (self.liveness.isUnused(inst)) { |
| 1609 | .dead | 1609 | return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 1610 | else | 1610 | } |
| 1611 | return self.fail("TODO implement shl for {}", .{self.target.cpu.arch}); | 1611 | |
| 1612 | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); | 1612 | const ty = self.air.typeOfIndex(inst); |
| | 1613 | const tag = self.air.instructions.items(.tag)[inst]; |
| | 1614 | switch (tag) { |
| | 1615 | .shl_exact => return self.fail("TODO implement {} for type {}", .{ tag, ty }), |
| | 1616 | .shl => {}, |
| | 1617 | else => unreachable, |
| | 1618 | } |
| | 1619 | |
| | 1620 | if (ty.zigTypeTag() != .Int) { |
| | 1621 | return self.fail("TODO implement .shl for type {}", .{ty}); |
| | 1622 | } |
| | 1623 | if (ty.abiSize(self.target.*) > 8) { |
| | 1624 | return self.fail("TODO implement .shl for integers larger than 8 bytes", .{}); |
| | 1625 | } |
| | 1626 | |
| | 1627 | // TODO look into reusing the operands |
| | 1628 | // TODO audit register allocation mechanics |
| | 1629 | const shift = try self.resolveInst(bin_op.rhs); |
| | 1630 | const shift_ty = self.air.typeOf(bin_op.rhs); |
| | 1631 | |
| | 1632 | blk: { |
| | 1633 | switch (shift) { |
| | 1634 | .register => |reg| { |
| | 1635 | if (reg.to64() == .rcx) break :blk; |
| | 1636 | }, |
| | 1637 | else => {}, |
| | 1638 | } |
| | 1639 | try self.register_manager.getReg(.rcx, null); |
| | 1640 | try self.genSetReg(shift_ty, .rcx, shift); |
| | 1641 | } |
| | 1642 | self.register_manager.freezeRegs(&.{.rcx}); |
| | 1643 | defer self.register_manager.unfreezeRegs(&.{.rcx}); |
| | 1644 | |
| | 1645 | const value = try self.resolveInst(bin_op.lhs); |
| | 1646 | value.freezeIfRegister(&self.register_manager); |
| | 1647 | defer value.unfreezeIfRegister(&self.register_manager); |
| | 1648 | |
| | 1649 | const dst_mcv = try self.copyToRegisterWithInstTracking(inst, ty, value); |
| | 1650 | _ = try self.addInst(.{ |
| | 1651 | .tag = .sal, |
| | 1652 | .ops = (Mir.Ops{ |
| | 1653 | .reg1 = dst_mcv.register, |
| | 1654 | .flags = 0b01, |
| | 1655 | }).encode(), |
| | 1656 | .data = undefined, |
| | 1657 | }); |
| | 1658 | |
| | 1659 | return self.finishAir(inst, dst_mcv, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 1613 | } | 1660 | } |
| 1614 | | 1661 | |
| 1615 | fn airShlSat(self: *Self, inst: Air.Inst.Index) !void { | 1662 | fn airShlSat(self: *Self, inst: Air.Inst.Index) !void { |