| ... | ... | @@ -1659,6 +1659,8 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 1659 | 1659 | return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 1660 | 1660 | } |
| 1661 | 1661 | |
| 1662 | try self.spillRegisters(1, .{.rcx}); |
| 1663 | |
| 1662 | 1664 | const tag = self.air.instructions.items(.tag)[inst]; |
| 1663 | 1665 | const lhs = try self.resolveInst(bin_op.lhs); |
| 1664 | 1666 | const rhs = try self.resolveInst(bin_op.rhs); |
| ... | ... | @@ -2981,7 +2983,7 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 2981 | 2983 | } |
| 2982 | 2984 | |
| 2983 | 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 | 2987 | /// Asserts .rcx is free. |
| 2986 | 2988 | fn genShiftBinOp( |
| 2987 | 2989 | self: *Self, |
| ... | ... | @@ -2999,12 +3001,7 @@ fn genShiftBinOp( |
| 2999 | 3001 | return self.fail("TODO implement genShiftBinOp for {}", .{lhs_ty.fmtDebug()}); |
| 3000 | 3002 | } |
| 3001 | 3003 | |
| 3002 | | assert(self.register_manager.isRegFree(.rcx)); |
| 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); |
| 3004 | assert(rhs_ty.abiSize(self.target.*) == 1); |
| 3008 | 3005 | |
| 3009 | 3006 | const int_info = lhs_ty.intInfo(self.target.*); |
| 3010 | 3007 | const signedness = int_info.signedness; |
| ... | ... | @@ -3021,6 +3018,29 @@ fn genShiftBinOp( |
| 3021 | 3018 | }; |
| 3022 | 3019 | defer if (rhs_lock) |lock| self.register_manager.unlockReg(lock); |
| 3023 | 3020 | |
| 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 | 3044 | const dst: MCValue = blk: { |
| 3025 | 3045 | if (maybe_inst) |inst| { |
| 3026 | 3046 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| ... | ... | @@ -3040,9 +3060,9 @@ fn genShiftBinOp( |
| 3040 | 3060 | .tag = .sal, |
| 3041 | 3061 | .ops = (Mir.Ops{ |
| 3042 | 3062 | .reg1 = dst.register, |
| 3043 | | .flags = 0b01, |
| 3063 | .flags = flags, |
| 3044 | 3064 | }).encode(), |
| 3045 | | .data = undefined, |
| 3065 | .data = data, |
| 3046 | 3066 | }); |
| 3047 | 3067 | }, |
| 3048 | 3068 | .unsigned => { |
| ... | ... | @@ -3050,9 +3070,9 @@ fn genShiftBinOp( |
| 3050 | 3070 | .tag = .shl, |
| 3051 | 3071 | .ops = (Mir.Ops{ |
| 3052 | 3072 | .reg1 = dst.register, |
| 3053 | | .flags = 0b01, |
| 3073 | .flags = flags, |
| 3054 | 3074 | }).encode(), |
| 3055 | | .data = undefined, |
| 3075 | .data = data, |
| 3056 | 3076 | }); |
| 3057 | 3077 | }, |
| 3058 | 3078 | }, |
| ... | ... | @@ -3062,9 +3082,9 @@ fn genShiftBinOp( |
| 3062 | 3082 | .tag = .sar, |
| 3063 | 3083 | .ops = (Mir.Ops{ |
| 3064 | 3084 | .reg1 = dst.register, |
| 3065 | | .flags = 0b01, |
| 3085 | .flags = flags, |
| 3066 | 3086 | }).encode(), |
| 3067 | | .data = undefined, |
| 3087 | .data = data, |
| 3068 | 3088 | }); |
| 3069 | 3089 | }, |
| 3070 | 3090 | .unsigned => { |
| ... | ... | @@ -3072,9 +3092,9 @@ fn genShiftBinOp( |
| 3072 | 3092 | .tag = .shr, |
| 3073 | 3093 | .ops = (Mir.Ops{ |
| 3074 | 3094 | .reg1 = dst.register, |
| 3075 | | .flags = 0b01, |
| 3095 | .flags = flags, |
| 3076 | 3096 | }).encode(), |
| 3077 | | .data = undefined, |
| 3097 | .data = data, |
| 3078 | 3098 | }); |
| 3079 | 3099 | }, |
| 3080 | 3100 | }, |