authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-05-10 18:16:14+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-05-10 18:16:14+02:00
loga9514ae1732df1fdc142b602e62ab0d12f693afa
treefe15f8544601e0c44b1ac5eea02e6175f1b10d22
parent6a4e445f5aaadf8e87ec08499c84f1d5f279e8b3

x64: handle immediate as RHS of shift bin ops


1 files changed, 35 insertions(+), 15 deletions(-)

src/arch/x86_64/CodeGen.zig+35-15
...@@ -1659,6 +1659,8 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void {...@@ -1659,6 +1659,8 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void {
1659 return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none });1659 return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none });
1660 }1660 }
16611661
1662 try self.spillRegisters(1, .{.rcx});
1663
1662 const tag = self.air.instructions.items(.tag)[inst];1664 const tag = self.air.instructions.items(.tag)[inst];
1663 const lhs = try self.resolveInst(bin_op.lhs);1665 const lhs = try self.resolveInst(bin_op.lhs);
1664 const rhs = try self.resolveInst(bin_op.rhs);1666 const rhs = try self.resolveInst(bin_op.rhs);
...@@ -2981,7 +2983,7 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -2981,7 +2983,7 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {
2981}2983}
29822984
2983/// Result is always a register.2985/// Result is always a register.
2984/// Clobbers .rcx therefore care is needed to spill .rcx upfront.2986/// Clobbers .rcx for non-immediate rhs, therefore care is needed to spill .rcx upfront.
2985/// Asserts .rcx is free.2987/// Asserts .rcx is free.
2986fn genShiftBinOp(2988fn genShiftBinOp(
2987 self: *Self,2989 self: *Self,
...@@ -2999,12 +3001,7 @@ fn genShiftBinOp(...@@ -2999,12 +3001,7 @@ fn genShiftBinOp(
2999 return self.fail("TODO implement genShiftBinOp for {}", .{lhs_ty.fmtDebug()});3001 return self.fail("TODO implement genShiftBinOp for {}", .{lhs_ty.fmtDebug()});
3000 }3002 }
30013003
3002 assert(self.register_manager.isRegFree(.rcx));3004 assert(rhs_ty.abiSize(self.target.*) == 1);
3003
3004 try self.register_manager.getReg(.rcx, null);
3005 try self.genSetReg(rhs_ty, .rcx, rhs);
3006 const rcx_lock = self.register_manager.lockRegAssumeUnused(.rcx);
3007 defer self.register_manager.unlockReg(rcx_lock);
30083005
3009 const int_info = lhs_ty.intInfo(self.target.*);3006 const int_info = lhs_ty.intInfo(self.target.*);
3010 const signedness = int_info.signedness;3007 const signedness = int_info.signedness;
...@@ -3021,6 +3018,29 @@ fn genShiftBinOp(...@@ -3021,6 +3018,29 @@ fn genShiftBinOp(
3021 };3018 };
3022 defer if (rhs_lock) |lock| self.register_manager.unlockReg(lock);3019 defer if (rhs_lock) |lock| self.register_manager.unlockReg(lock);
30233020
3021 const flags: u2 = blk: {
3022 if (rhs.isImmediate()) {
3023 const flags: u2 = switch (rhs.immediate) {
3024 0 => unreachable, // TODO is this valid?
3025 1 => 0b00,
3026 else => 0b10,
3027 };
3028 break :blk flags;
3029 }
3030
3031 assert(self.register_manager.isRegFree(.rcx));
3032
3033 try self.register_manager.getReg(.rcx, null);
3034 try self.genSetReg(rhs_ty, .rcx, rhs);
3035 const rcx_lock = self.register_manager.lockRegAssumeUnused(.rcx);
3036 defer self.register_manager.unlockReg(rcx_lock);
3037
3038 break :blk 0b01;
3039 };
3040 const data: Mir.Inst.Data = if (rhs.isImmediate()) .{
3041 .imm = @intCast(u8, rhs.immediate),
3042 } else undefined;
3043
3024 const dst: MCValue = blk: {3044 const dst: MCValue = blk: {
3025 if (maybe_inst) |inst| {3045 if (maybe_inst) |inst| {
3026 const bin_op = self.air.instructions.items(.data)[inst].bin_op;3046 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
...@@ -3040,9 +3060,9 @@ fn genShiftBinOp(...@@ -3040,9 +3060,9 @@ fn genShiftBinOp(
3040 .tag = .sal,3060 .tag = .sal,
3041 .ops = (Mir.Ops{3061 .ops = (Mir.Ops{
3042 .reg1 = dst.register,3062 .reg1 = dst.register,
3043 .flags = 0b01,3063 .flags = flags,
3044 }).encode(),3064 }).encode(),
3045 .data = undefined,3065 .data = data,
3046 });3066 });
3047 },3067 },
3048 .unsigned => {3068 .unsigned => {
...@@ -3050,9 +3070,9 @@ fn genShiftBinOp(...@@ -3050,9 +3070,9 @@ fn genShiftBinOp(
3050 .tag = .shl,3070 .tag = .shl,
3051 .ops = (Mir.Ops{3071 .ops = (Mir.Ops{
3052 .reg1 = dst.register,3072 .reg1 = dst.register,
3053 .flags = 0b01,3073 .flags = flags,
3054 }).encode(),3074 }).encode(),
3055 .data = undefined,3075 .data = data,
3056 });3076 });
3057 },3077 },
3058 },3078 },
...@@ -3062,9 +3082,9 @@ fn genShiftBinOp(...@@ -3062,9 +3082,9 @@ fn genShiftBinOp(
3062 .tag = .sar,3082 .tag = .sar,
3063 .ops = (Mir.Ops{3083 .ops = (Mir.Ops{
3064 .reg1 = dst.register,3084 .reg1 = dst.register,
3065 .flags = 0b01,3085 .flags = flags,
3066 }).encode(),3086 }).encode(),
3067 .data = undefined,3087 .data = data,
3068 });3088 });
3069 },3089 },
3070 .unsigned => {3090 .unsigned => {
...@@ -3072,9 +3092,9 @@ fn genShiftBinOp(...@@ -3072,9 +3092,9 @@ fn genShiftBinOp(
3072 .tag = .shr,3092 .tag = .shr,
3073 .ops = (Mir.Ops{3093 .ops = (Mir.Ops{
3074 .reg1 = dst.register,3094 .reg1 = dst.register,
3075 .flags = 0b01,3095 .flags = flags,
3076 }).encode(),3096 }).encode(),
3077 .data = undefined,3097 .data = data,
3078 });3098 });
3079 },3099 },
3080 },3100 },