authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-02-20 20:46:39+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-02-22 21:56:34+01:00
log5ba66911faf71cc6bab7f9329474ed15804e783d
tree2a8b771e1c0099472abc271abce516929cf38883
parent71dda25f14f2eb8315cd42f3edabd9386b4fd012

x64: add basic impl of shl for integers


1 files changed, 52 insertions(+), 5 deletions(-)

src/arch/x86_64/CodeGen.zig+52-5
......@@ -1605,11 +1605,58 @@ fn airXor(self: *Self, inst: Air.Inst.Index) !void {
16051605
16061606fn airShl(self: *Self, inst: Air.Inst.Index) !void {
16071607 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 });
16131660}
16141661
16151662fn airShlSat(self: *Self, inst: Air.Inst.Index) !void {