| ... | @@ -1089,8 +1089,15 @@ fn airBoolToInt(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1089,8 +1089,15 @@ fn airBoolToInt(self: *Self, inst: Air.Inst.Index) !void { |
| 1089 | | 1089 | |
| 1090 | fn airNot(self: *Self, inst: Air.Inst.Index) !void { | 1090 | fn airNot(self: *Self, inst: Air.Inst.Index) !void { |
| 1091 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 1091 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 1092 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 1092 | |
| 1093 | const operand = try self.resolveInst(ty_op.operand); | 1093 | if (self.liveness.isUnused(inst)) { |
| | 1094 | return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none }); |
| | 1095 | } |
| | 1096 | |
| | 1097 | const operand_ty = self.air.typeOf(ty_op.operand); |
| | 1098 | const operand = try self.resolveInst(ty_op.operand); |
| | 1099 | |
| | 1100 | const result: MCValue = result: { |
| 1094 | switch (operand) { | 1101 | switch (operand) { |
| 1095 | .dead => unreachable, | 1102 | .dead => unreachable, |
| 1096 | .unreach => unreachable, | 1103 | .unreach => unreachable, |
| ... | @@ -1122,7 +1129,28 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1122,7 +1129,28 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void { |
| 1122 | }, | 1129 | }, |
| 1123 | else => {}, | 1130 | else => {}, |
| 1124 | } | 1131 | } |
| 1125 | break :result try self.genBinOp(.not, inst, ty_op.operand, .bool_true); | 1132 | |
| | 1133 | const operand_lock: ?RegisterLock = switch (operand) { |
| | 1134 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| | 1135 | else => null, |
| | 1136 | }; |
| | 1137 | defer if (operand_lock) |lock| self.register_manager.unlockReg(lock); |
| | 1138 | |
| | 1139 | const dst_mcv: MCValue = blk: { |
| | 1140 | if (self.reuseOperand(inst, ty_op.operand, 0, operand) and operand.isRegister()) { |
| | 1141 | break :blk operand; |
| | 1142 | } |
| | 1143 | break :blk try self.copyToRegisterWithInstTracking(inst, operand_ty, operand); |
| | 1144 | }; |
| | 1145 | const dst_mcv_lock: ?RegisterLock = switch (dst_mcv) { |
| | 1146 | .register => |reg| self.register_manager.lockReg(reg), |
| | 1147 | else => null, |
| | 1148 | }; |
| | 1149 | defer if (dst_mcv_lock) |lock| self.register_manager.unlockReg(lock); |
| | 1150 | |
| | 1151 | try self.genBinOpMir(.xor, operand_ty, dst_mcv, .{ .immediate = 1 }); |
| | 1152 | |
| | 1153 | break :result dst_mcv; |
| 1126 | }; | 1154 | }; |
| 1127 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | 1155 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 1128 | } | 1156 | } |
| ... | @@ -1214,7 +1242,13 @@ fn airBinOp(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1214,7 +1242,13 @@ fn airBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 1214 | } | 1242 | } |
| 1215 | | 1243 | |
| 1216 | const tag = self.air.instructions.items(.tag)[inst]; | 1244 | const tag = self.air.instructions.items(.tag)[inst]; |
| 1217 | const result = try self.genBinOp(tag, inst, bin_op.lhs, bin_op.rhs); | 1245 | const lhs = try self.resolveInst(bin_op.lhs); |
| | 1246 | const rhs = try self.resolveInst(bin_op.rhs); |
| | 1247 | const lhs_ty = self.air.typeOf(bin_op.lhs); |
| | 1248 | const rhs_ty = self.air.typeOf(bin_op.rhs); |
| | 1249 | |
| | 1250 | const result = try self.genBinOp(tag, inst, lhs, rhs, lhs_ty, rhs_ty); |
| | 1251 | |
| 1218 | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); | 1252 | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 1219 | } | 1253 | } |
| 1220 | | 1254 | |
| ... | @@ -1263,7 +1297,10 @@ fn airAddWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1263,7 +1297,10 @@ fn airAddWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 1263 | try self.spillCompareFlagsIfOccupied(); | 1297 | try self.spillCompareFlagsIfOccupied(); |
| 1264 | self.compare_flags_inst = inst; | 1298 | self.compare_flags_inst = inst; |
| 1265 | | 1299 | |
| 1266 | const partial = try self.genBinOp(.add, inst, bin_op.lhs, bin_op.rhs); | 1300 | const lhs = try self.resolveInst(bin_op.lhs); |
| | 1301 | const rhs = try self.resolveInst(bin_op.rhs); |
| | 1302 | |
| | 1303 | const partial = try self.genBinOp(.add, null, lhs, rhs, ty, ty); |
| 1267 | const result: MCValue = switch (int_info.signedness) { | 1304 | const result: MCValue = switch (int_info.signedness) { |
| 1268 | .signed => .{ .register_overflow_signed = partial.register }, | 1305 | .signed => .{ .register_overflow_signed = partial.register }, |
| 1269 | .unsigned => .{ .register_overflow_unsigned = partial.register }, | 1306 | .unsigned => .{ .register_overflow_unsigned = partial.register }, |
| ... | @@ -1295,7 +1332,10 @@ fn airSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1295,7 +1332,10 @@ fn airSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 1295 | try self.spillCompareFlagsIfOccupied(); | 1332 | try self.spillCompareFlagsIfOccupied(); |
| 1296 | self.compare_flags_inst = inst; | 1333 | self.compare_flags_inst = inst; |
| 1297 | | 1334 | |
| 1298 | const partial = try self.genBinOp(.sub, inst, bin_op.lhs, bin_op.rhs); | 1335 | const lhs = try self.resolveInst(bin_op.lhs); |
| | 1336 | const rhs = try self.resolveInst(bin_op.rhs); |
| | 1337 | |
| | 1338 | const partial = try self.genBinOp(.sub, null, lhs, rhs, ty, ty); |
| 1299 | const result: MCValue = switch (int_info.signedness) { | 1339 | const result: MCValue = switch (int_info.signedness) { |
| 1300 | .signed => .{ .register_overflow_signed = partial.register }, | 1340 | .signed => .{ .register_overflow_signed = partial.register }, |
| 1301 | .unsigned => .{ .register_overflow_unsigned = partial.register }, | 1341 | .unsigned => .{ .register_overflow_unsigned = partial.register }, |
| ... | @@ -1330,9 +1370,12 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1330,9 +1370,12 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 1330 | | 1370 | |
| 1331 | try self.spillCompareFlagsIfOccupied(); | 1371 | try self.spillCompareFlagsIfOccupied(); |
| 1332 | | 1372 | |
| | 1373 | const lhs = try self.resolveInst(bin_op.lhs); |
| | 1374 | const rhs = try self.resolveInst(bin_op.rhs); |
| | 1375 | |
| 1333 | if (math.isPowerOfTwo(int_info.bits)) { | 1376 | if (math.isPowerOfTwo(int_info.bits)) { |
| 1334 | self.compare_flags_inst = inst; | 1377 | self.compare_flags_inst = inst; |
| 1335 | const partial = try self.genBinOp(.mul, inst, bin_op.lhs, bin_op.rhs); | 1378 | const partial = try self.genBinOp(.mul, null, lhs, rhs, ty, ty); |
| 1336 | break :result switch (int_info.signedness) { | 1379 | break :result switch (int_info.signedness) { |
| 1337 | .signed => MCValue{ .register_overflow_signed = partial.register }, | 1380 | .signed => MCValue{ .register_overflow_signed = partial.register }, |
| 1338 | .unsigned => MCValue{ .register_overflow_unsigned = partial.register }, | 1381 | .unsigned => MCValue{ .register_overflow_unsigned = partial.register }, |
| ... | @@ -1344,9 +1387,6 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1344,9 +1387,6 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 1344 | const dst_reg: Register = dst_reg: { | 1387 | const dst_reg: Register = dst_reg: { |
| 1345 | switch (int_info.signedness) { | 1388 | switch (int_info.signedness) { |
| 1346 | .signed => { | 1389 | .signed => { |
| 1347 | const lhs = try self.resolveInst(bin_op.lhs); | | |
| 1348 | const rhs = try self.resolveInst(bin_op.rhs); | | |
| 1349 | | | |
| 1350 | const rhs_lock: ?RegisterLock = switch (rhs) { | 1390 | const rhs_lock: ?RegisterLock = switch (rhs) { |
| 1351 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), | 1391 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 1352 | else => null, | 1392 | else => null, |
| ... | @@ -1375,7 +1415,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1375,7 +1415,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 1375 | break :dst_reg dst_reg; | 1415 | break :dst_reg dst_reg; |
| 1376 | }, | 1416 | }, |
| 1377 | .unsigned => { | 1417 | .unsigned => { |
| 1378 | const dst_mcv = try self.genBinOp(.mul, null, bin_op.lhs, bin_op.rhs); | 1418 | const dst_mcv = try self.genBinOp(.mul, null, lhs, rhs, ty, ty); |
| 1379 | break :dst_reg dst_mcv.register; | 1419 | break :dst_reg dst_mcv.register; |
| 1380 | }, | 1420 | }, |
| 1381 | } | 1421 | } |
| ... | @@ -3137,8 +3177,10 @@ fn genBinOp( | ... | @@ -3137,8 +3177,10 @@ fn genBinOp( |
| 3137 | self: *Self, | 3177 | self: *Self, |
| 3138 | tag: Air.Inst.Tag, | 3178 | tag: Air.Inst.Tag, |
| 3139 | maybe_inst: ?Air.Inst.Index, | 3179 | maybe_inst: ?Air.Inst.Index, |
| 3140 | op_lhs: Air.Inst.Ref, | 3180 | lhs: MCValue, |
| 3141 | op_rhs: Air.Inst.Ref, | 3181 | rhs: MCValue, |
| | 3182 | lhs_ty: Type, |
| | 3183 | rhs_ty: Type, |
| 3142 | ) !MCValue { | 3184 | ) !MCValue { |
| 3143 | const is_commutative: bool = switch (tag) { | 3185 | const is_commutative: bool = switch (tag) { |
| 3144 | .add, | 3186 | .add, |
| ... | @@ -3148,7 +3190,6 @@ fn genBinOp( | ... | @@ -3148,7 +3190,6 @@ fn genBinOp( |
| 3148 | .bool_and, | 3190 | .bool_and, |
| 3149 | .bit_and, | 3191 | .bit_and, |
| 3150 | .xor, | 3192 | .xor, |
| 3151 | .not, | | |
| 3152 | => true, | 3193 | => true, |
| 3153 | | 3194 | |
| 3154 | .sub, | 3195 | .sub, |
| ... | @@ -3169,14 +3210,12 @@ fn genBinOp( | ... | @@ -3169,14 +3210,12 @@ fn genBinOp( |
| 3169 | | 3210 | |
| 3170 | else => unreachable, | 3211 | else => unreachable, |
| 3171 | }; | 3212 | }; |
| 3172 | const dst_ty = self.air.typeOf(op_lhs); | | |
| 3173 | const src_ty = self.air.typeOf(op_rhs); | | |
| 3174 | | 3213 | |
| 3175 | if (dst_ty.zigTypeTag() == .Vector or dst_ty.zigTypeTag() == .Float) { | 3214 | if (lhs_ty.zigTypeTag() == .Vector or lhs_ty.zigTypeTag() == .Float) { |
| 3176 | return self.fail("TODO implement genBinOp for {}", .{dst_ty.fmtDebug()}); | 3215 | return self.fail("TODO implement genBinOp for {}", .{lhs_ty.fmtDebug()}); |
| 3177 | } | 3216 | } |
| 3178 | if (dst_ty.abiSize(self.target.*) > 8) { | 3217 | if (lhs_ty.abiSize(self.target.*) > 8) { |
| 3179 | return self.fail("TODO implement genBinOp for {}", .{dst_ty.fmtDebug()}); | 3218 | return self.fail("TODO implement genBinOp for {}", .{lhs_ty.fmtDebug()}); |
| 3180 | } | 3219 | } |
| 3181 | | 3220 | |
| 3182 | switch (tag) { | 3221 | switch (tag) { |
| ... | @@ -3191,24 +3230,21 @@ fn genBinOp( | ... | @@ -3191,24 +3230,21 @@ fn genBinOp( |
| 3191 | self.register_manager.unlockReg(reg); | 3230 | self.register_manager.unlockReg(reg); |
| 3192 | }; | 3231 | }; |
| 3193 | | 3232 | |
| 3194 | const lhs = try self.resolveInst(op_lhs); | 3233 | const int_info = lhs_ty.intInfo(self.target.*); |
| 3195 | const rhs = try self.resolveInst(op_rhs); | | |
| 3196 | | | |
| 3197 | const int_info = dst_ty.intInfo(self.target.*); | | |
| 3198 | try self.genIntMulDivOpMir(switch (int_info.signedness) { | 3234 | try self.genIntMulDivOpMir(switch (int_info.signedness) { |
| 3199 | .signed => .imul, | 3235 | .signed => .imul, |
| 3200 | .unsigned => .mul, | 3236 | .unsigned => .mul, |
| 3201 | }, dst_ty, int_info.signedness, lhs, rhs); | 3237 | }, lhs_ty, int_info.signedness, lhs, rhs); |
| 3202 | | 3238 | |
| 3203 | return switch (int_info.signedness) { | 3239 | return switch (int_info.signedness) { |
| 3204 | .signed => MCValue{ .register = .rax }, | 3240 | .signed => MCValue{ .register = .rax }, |
| 3205 | .unsigned => MCValue{ .register = registerAlias(.rax, @intCast(u32, dst_ty.abiSize(self.target.*))) }, | 3241 | .unsigned => MCValue{ .register = registerAlias(.rax, @intCast(u32, lhs_ty.abiSize(self.target.*))) }, |
| 3206 | }; | 3242 | }; |
| 3207 | }, | 3243 | }, |
| 3208 | .mod, | 3244 | .mod, |
| 3209 | .rem, | 3245 | .rem, |
| 3210 | => { | 3246 | => { |
| 3211 | const int_info = dst_ty.intInfo(self.target.*); | 3247 | const int_info = lhs_ty.intInfo(self.target.*); |
| 3212 | const track_inst_rdx: ?Air.Inst.Index = switch (tag) { | 3248 | const track_inst_rdx: ?Air.Inst.Index = switch (tag) { |
| 3213 | .mod => if (int_info.signedness == .unsigned) maybe_inst else null, | 3249 | .mod => if (int_info.signedness == .unsigned) maybe_inst else null, |
| 3214 | .rem => maybe_inst, | 3250 | .rem => maybe_inst, |
| ... | @@ -3223,27 +3259,24 @@ fn genBinOp( | ... | @@ -3223,27 +3259,24 @@ fn genBinOp( |
| 3223 | self.register_manager.unlockReg(reg); | 3259 | self.register_manager.unlockReg(reg); |
| 3224 | }; | 3260 | }; |
| 3225 | | 3261 | |
| 3226 | const lhs = try self.resolveInst(op_lhs); | | |
| 3227 | const rhs = try self.resolveInst(op_rhs); | | |
| 3228 | | | |
| 3229 | switch (int_info.signedness) { | 3262 | switch (int_info.signedness) { |
| 3230 | .signed => { | 3263 | .signed => { |
| 3231 | switch (tag) { | 3264 | switch (tag) { |
| 3232 | .rem => { | 3265 | .rem => { |
| 3233 | try self.genIntMulDivOpMir(.idiv, dst_ty, .signed, lhs, rhs); | 3266 | try self.genIntMulDivOpMir(.idiv, lhs_ty, .signed, lhs, rhs); |
| 3234 | return MCValue{ .register = .rdx }; | 3267 | return MCValue{ .register = .rdx }; |
| 3235 | }, | 3268 | }, |
| 3236 | .mod => { | 3269 | .mod => { |
| 3237 | const div_floor = try self.genInlineIntDivFloor(dst_ty, lhs, rhs); | 3270 | const div_floor = try self.genInlineIntDivFloor(lhs_ty, lhs, rhs); |
| 3238 | try self.genIntMulComplexOpMir(dst_ty, div_floor, rhs); | 3271 | try self.genIntMulComplexOpMir(lhs_ty, div_floor, rhs); |
| 3239 | const div_floor_lock = self.register_manager.lockReg(div_floor.register); | 3272 | const div_floor_lock = self.register_manager.lockReg(div_floor.register); |
| 3240 | defer if (div_floor_lock) |lock| self.register_manager.unlockReg(lock); | 3273 | defer if (div_floor_lock) |lock| self.register_manager.unlockReg(lock); |
| 3241 | | 3274 | |
| 3242 | const result: MCValue = if (maybe_inst) |inst| | 3275 | const result: MCValue = if (maybe_inst) |inst| |
| 3243 | try self.copyToRegisterWithInstTracking(inst, dst_ty, lhs) | 3276 | try self.copyToRegisterWithInstTracking(inst, lhs_ty, lhs) |
| 3244 | else | 3277 | else |
| 3245 | MCValue{ .register = try self.copyToTmpRegister(dst_ty, lhs) }; | 3278 | MCValue{ .register = try self.copyToTmpRegister(lhs_ty, lhs) }; |
| 3246 | try self.genBinOpMir(.sub, dst_ty, result, div_floor); | 3279 | try self.genBinOpMir(.sub, lhs_ty, result, div_floor); |
| 3247 | | 3280 | |
| 3248 | return result; | 3281 | return result; |
| 3249 | }, | 3282 | }, |
| ... | @@ -3251,7 +3284,7 @@ fn genBinOp( | ... | @@ -3251,7 +3284,7 @@ fn genBinOp( |
| 3251 | } | 3284 | } |
| 3252 | }, | 3285 | }, |
| 3253 | .unsigned => { | 3286 | .unsigned => { |
| 3254 | try self.genIntMulDivOpMir(.div, dst_ty, .unsigned, lhs, rhs); | 3287 | try self.genIntMulDivOpMir(.div, lhs_ty, .unsigned, lhs, rhs); |
| 3255 | return MCValue{ .register = .rdx }; | 3288 | return MCValue{ .register = .rdx }; |
| 3256 | }, | 3289 | }, |
| 3257 | } | 3290 | } |
| ... | @@ -3259,14 +3292,12 @@ fn genBinOp( | ... | @@ -3259,14 +3292,12 @@ fn genBinOp( |
| 3259 | else => {}, | 3292 | else => {}, |
| 3260 | } | 3293 | } |
| 3261 | | 3294 | |
| 3262 | const lhs = try self.resolveInst(op_lhs); | | |
| 3263 | const lhs_lock: ?RegisterLock = switch (lhs) { | 3295 | const lhs_lock: ?RegisterLock = switch (lhs) { |
| 3264 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), | 3296 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 3265 | else => null, | 3297 | else => null, |
| 3266 | }; | 3298 | }; |
| 3267 | defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock); | 3299 | defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock); |
| 3268 | | 3300 | |
| 3269 | const rhs = try self.resolveInst(op_rhs); | | |
| 3270 | const rhs_lock: ?RegisterLock = switch (rhs) { | 3301 | const rhs_lock: ?RegisterLock = switch (rhs) { |
| 3271 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), | 3302 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 3272 | else => null, | 3303 | else => null, |
| ... | @@ -3276,16 +3307,17 @@ fn genBinOp( | ... | @@ -3276,16 +3307,17 @@ fn genBinOp( |
| 3276 | var flipped: bool = false; | 3307 | var flipped: bool = false; |
| 3277 | const dst_mcv: MCValue = blk: { | 3308 | const dst_mcv: MCValue = blk: { |
| 3278 | if (maybe_inst) |inst| { | 3309 | if (maybe_inst) |inst| { |
| 3279 | if (self.reuseOperand(inst, op_lhs, 0, lhs) and lhs.isRegister()) { | 3310 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| | 3311 | if (self.reuseOperand(inst, bin_op.lhs, 0, lhs) and lhs.isRegister()) { |
| 3280 | break :blk lhs; | 3312 | break :blk lhs; |
| 3281 | } | 3313 | } |
| 3282 | if (is_commutative and self.reuseOperand(inst, op_rhs, 1, rhs) and rhs.isRegister()) { | 3314 | if (is_commutative and self.reuseOperand(inst, bin_op.rhs, 1, rhs) and rhs.isRegister()) { |
| 3283 | flipped = true; | 3315 | flipped = true; |
| 3284 | break :blk rhs; | 3316 | break :blk rhs; |
| 3285 | } | 3317 | } |
| 3286 | break :blk try self.copyToRegisterWithInstTracking(inst, dst_ty, lhs); | 3318 | break :blk try self.copyToRegisterWithInstTracking(inst, lhs_ty, lhs); |
| 3287 | } | 3319 | } |
| 3288 | break :blk MCValue{ .register = try self.copyToTmpRegister(dst_ty, lhs) }; | 3320 | break :blk MCValue{ .register = try self.copyToTmpRegister(lhs_ty, lhs) }; |
| 3289 | }; | 3321 | }; |
| 3290 | const dst_mcv_lock: ?RegisterLock = switch (dst_mcv) { | 3322 | const dst_mcv_lock: ?RegisterLock = switch (dst_mcv) { |
| 3291 | .register => |reg| self.register_manager.lockReg(reg), | 3323 | .register => |reg| self.register_manager.lockReg(reg), |
| ... | @@ -3296,7 +3328,7 @@ fn genBinOp( | ... | @@ -3296,7 +3328,7 @@ fn genBinOp( |
| 3296 | const src_mcv: MCValue = blk: { | 3328 | const src_mcv: MCValue = blk: { |
| 3297 | const mcv = if (flipped) lhs else rhs; | 3329 | const mcv = if (flipped) lhs else rhs; |
| 3298 | if (mcv.isRegister() or mcv.isMemory()) break :blk mcv; | 3330 | if (mcv.isRegister() or mcv.isMemory()) break :blk mcv; |
| 3299 | break :blk MCValue{ .register = try self.copyToTmpRegister(src_ty, mcv) }; | 3331 | break :blk MCValue{ .register = try self.copyToTmpRegister(rhs_ty, mcv) }; |
| 3300 | }; | 3332 | }; |
| 3301 | const src_mcv_lock: ?RegisterLock = switch (src_mcv) { | 3333 | const src_mcv_lock: ?RegisterLock = switch (src_mcv) { |
| 3302 | .register => |reg| self.register_manager.lockReg(reg), | 3334 | .register => |reg| self.register_manager.lockReg(reg), |
| ... | @@ -3307,11 +3339,11 @@ fn genBinOp( | ... | @@ -3307,11 +3339,11 @@ fn genBinOp( |
| 3307 | switch (tag) { | 3339 | switch (tag) { |
| 3308 | .add, | 3340 | .add, |
| 3309 | .addwrap, | 3341 | .addwrap, |
| 3310 | => try self.genBinOpMir(.add, dst_ty, dst_mcv, src_mcv), | 3342 | => try self.genBinOpMir(.add, lhs_ty, dst_mcv, src_mcv), |
| 3311 | | 3343 | |
| 3312 | .sub, | 3344 | .sub, |
| 3313 | .subwrap, | 3345 | .subwrap, |
| 3314 | => try self.genBinOpMir(.sub, dst_ty, dst_mcv, src_mcv), | 3346 | => try self.genBinOpMir(.sub, lhs_ty, dst_mcv, src_mcv), |
| 3315 | | 3347 | |
| 3316 | .ptr_add, | 3348 | .ptr_add, |
| 3317 | .ptr_sub, | 3349 | .ptr_sub, |
| ... | @@ -3321,22 +3353,20 @@ fn genBinOp( | ... | @@ -3321,22 +3353,20 @@ fn genBinOp( |
| 3321 | .ptr_sub => .sub, | 3353 | .ptr_sub => .sub, |
| 3322 | else => unreachable, | 3354 | else => unreachable, |
| 3323 | }; | 3355 | }; |
| 3324 | const elem_size = dst_ty.elemType2().abiSize(self.target.*); | 3356 | const elem_size = lhs_ty.elemType2().abiSize(self.target.*); |
| 3325 | try self.genIntMulComplexOpMir(src_ty, src_mcv, .{ .immediate = elem_size }); | 3357 | try self.genIntMulComplexOpMir(rhs_ty, src_mcv, .{ .immediate = elem_size }); |
| 3326 | try self.genBinOpMir(mir_tag, dst_ty, dst_mcv, src_mcv); | 3358 | try self.genBinOpMir(mir_tag, lhs_ty, dst_mcv, src_mcv); |
| 3327 | }, | 3359 | }, |
| 3328 | | 3360 | |
| 3329 | .bool_or, | 3361 | .bool_or, |
| 3330 | .bit_or, | 3362 | .bit_or, |
| 3331 | => try self.genBinOpMir(.@"or", dst_ty, dst_mcv, src_mcv), | 3363 | => try self.genBinOpMir(.@"or", lhs_ty, dst_mcv, src_mcv), |
| 3332 | | 3364 | |
| 3333 | .bool_and, | 3365 | .bool_and, |
| 3334 | .bit_and, | 3366 | .bit_and, |
| 3335 | => try self.genBinOpMir(.@"and", dst_ty, dst_mcv, src_mcv), | 3367 | => try self.genBinOpMir(.@"and", lhs_ty, dst_mcv, src_mcv), |
| 3336 | | 3368 | |
| 3337 | .xor, | 3369 | .xor => try self.genBinOpMir(.xor, lhs_ty, dst_mcv, src_mcv), |
| 3338 | .not, | | |
| 3339 | => try self.genBinOpMir(.xor, dst_ty, dst_mcv, src_mcv), | | |
| 3340 | | 3370 | |
| 3341 | else => unreachable, | 3371 | else => unreachable, |
| 3342 | } | 3372 | } |