zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 5ba66911faf71cc6bab7f9329474ed15804e783d (tree)
parent 71dda25f14f2eb8315cd42f3edabd9386b4fd012
Author: Jakub Konka <kubkon@jakubkonka.com>
Date:   Sun, 20 Feb 2022 20:46:39 +0100

x64: add basic impl of shl for integers

Diffstat:
Msrc/arch/x86_64/CodeGen.zig | 57++++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 52 insertions(+), 5 deletions(-)

diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig @@ -1605,11 +1605,58 @@ fn airXor(self: *Self, inst: Air.Inst.Index) !void { fn airShl(self: *Self, inst: Air.Inst.Index) !void { const bin_op = self.air.instructions.items(.data)[inst].bin_op; - const result: MCValue = if (self.liveness.isUnused(inst)) - .dead - else - return self.fail("TODO implement shl for {}", .{self.target.cpu.arch}); - return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); + if (self.liveness.isUnused(inst)) { + return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none }); + } + + const ty = self.air.typeOfIndex(inst); + const tag = self.air.instructions.items(.tag)[inst]; + switch (tag) { + .shl_exact => return self.fail("TODO implement {} for type {}", .{ tag, ty }), + .shl => {}, + else => unreachable, + } + + if (ty.zigTypeTag() != .Int) { + return self.fail("TODO implement .shl for type {}", .{ty}); + } + if (ty.abiSize(self.target.*) > 8) { + return self.fail("TODO implement .shl for integers larger than 8 bytes", .{}); + } + + // TODO look into reusing the operands + // TODO audit register allocation mechanics + const shift = try self.resolveInst(bin_op.rhs); + const shift_ty = self.air.typeOf(bin_op.rhs); + + blk: { + switch (shift) { + .register => |reg| { + if (reg.to64() == .rcx) break :blk; + }, + else => {}, + } + try self.register_manager.getReg(.rcx, null); + try self.genSetReg(shift_ty, .rcx, shift); + } + self.register_manager.freezeRegs(&.{.rcx}); + defer self.register_manager.unfreezeRegs(&.{.rcx}); + + const value = try self.resolveInst(bin_op.lhs); + value.freezeIfRegister(&self.register_manager); + defer value.unfreezeIfRegister(&self.register_manager); + + const dst_mcv = try self.copyToRegisterWithInstTracking(inst, ty, value); + _ = try self.addInst(.{ + .tag = .sal, + .ops = (Mir.Ops{ + .reg1 = dst_mcv.register, + .flags = 0b01, + }).encode(), + .data = undefined, + }); + + return self.finishAir(inst, dst_mcv, .{ bin_op.lhs, bin_op.rhs, .none }); } fn airShlSat(self: *Self, inst: Air.Inst.Index) !void {