| ... | ... | @@ -621,8 +621,8 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 621 | 621 | .trunc_float, |
| 622 | 622 | => try self.airUnaryMath(inst), |
| 623 | 623 | |
| 624 | | .add_with_overflow => try self.airAddWithOverflow(inst), |
| 625 | | .sub_with_overflow => try self.airSubWithOverflow(inst), |
| 624 | .add_with_overflow => try self.airAddSubWithOverflow(inst), |
| 625 | .sub_with_overflow => try self.airAddSubWithOverflow(inst), |
| 626 | 626 | .mul_with_overflow => try self.airMulWithOverflow(inst), |
| 627 | 627 | .shl_with_overflow => try self.airShlWithOverflow(inst), |
| 628 | 628 | |
| ... | ... | @@ -1279,8 +1279,9 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void { |
| 1279 | 1279 | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 1280 | 1280 | } |
| 1281 | 1281 | |
| 1282 | | fn airAddWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 1282 | fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 1283 | 1283 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 1284 | const tag = self.air.instructions.items(.tag)[inst]; |
| 1284 | 1285 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 1285 | 1286 | const result = if (self.liveness.isUnused(inst)) .dead else result: { |
| 1286 | 1287 | const ty = self.air.typeOf(bin_op.lhs); |
| ... | ... | @@ -1300,42 +1301,12 @@ fn airAddWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 1300 | 1301 | const lhs = try self.resolveInst(bin_op.lhs); |
| 1301 | 1302 | const rhs = try self.resolveInst(bin_op.rhs); |
| 1302 | 1303 | |
| 1303 | | const partial = try self.genBinOp(.add, null, lhs, rhs, ty, ty); |
| 1304 | | const result: MCValue = switch (int_info.signedness) { |
| 1305 | | .signed => .{ .register_overflow_signed = partial.register }, |
| 1306 | | .unsigned => .{ .register_overflow_unsigned = partial.register }, |
| 1304 | const base_tag: Air.Inst.Tag = switch (tag) { |
| 1305 | .add_with_overflow => .add, |
| 1306 | .sub_with_overflow => .sub, |
| 1307 | else => unreachable, |
| 1307 | 1308 | }; |
| 1308 | | break :result result; |
| 1309 | | }, |
| 1310 | | else => unreachable, |
| 1311 | | } |
| 1312 | | }; |
| 1313 | | |
| 1314 | | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 1315 | | } |
| 1316 | | |
| 1317 | | fn airSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 1318 | | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 1319 | | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 1320 | | const result = if (self.liveness.isUnused(inst)) .dead else result: { |
| 1321 | | const ty = self.air.typeOf(bin_op.lhs); |
| 1322 | | |
| 1323 | | switch (ty.zigTypeTag()) { |
| 1324 | | .Vector => return self.fail("TODO implement sub_with_overflow for Vector type", .{}), |
| 1325 | | .Int => { |
| 1326 | | const int_info = ty.intInfo(self.target.*); |
| 1327 | | |
| 1328 | | if (int_info.bits > 64) { |
| 1329 | | return self.fail("TODO implement sub_with_overflow for Ints larger than 64bits", .{}); |
| 1330 | | } |
| 1331 | | |
| 1332 | | try self.spillCompareFlagsIfOccupied(); |
| 1333 | | self.compare_flags_inst = inst; |
| 1334 | | |
| 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); |
| 1309 | const partial = try self.genBinOp(base_tag, null, lhs, rhs, ty, ty); |
| 1339 | 1310 | const result: MCValue = switch (int_info.signedness) { |
| 1340 | 1311 | .signed => .{ .register_overflow_signed = partial.register }, |
| 1341 | 1312 | .unsigned => .{ .register_overflow_unsigned = partial.register }, |