| ... | ... | @@ -1605,11 +1605,58 @@ fn airXor(self: *Self, inst: Air.Inst.Index) !void { |
| 1605 | 1605 | |
| 1606 | 1606 | fn airShl(self: *Self, inst: Air.Inst.Index) !void { |
| 1607 | 1607 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 1608 | | const result: MCValue = if (self.liveness.isUnused(inst)) |
| 1609 | | .dead |
| 1610 | | else |
| 1611 | | return self.fail("TODO implement shl for {}", .{self.target.cpu.arch}); |
| 1612 | | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 1608 | if (self.liveness.isUnused(inst)) { |
| 1609 | return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 1610 | } |
| 1611 | |
| 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 | 1662 | fn airShlSat(self: *Self, inst: Air.Inst.Index) !void { |