@@ -1414,23 +1414,27 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void {
1414
1414
fn airAddWithOverflow (self : * Self , inst : Air.Inst.Index ) ! void {
1415
1415
const ty_pl = self .air .instructions .items (.data )[inst ].ty_pl ;
1416
1416
const bin_op = self .air .extraData (Air .Bin , ty_pl .payload ).data ;
1417
+ const result = if (self .liveness .isUnused (inst )) .dead else result : {
1418
+ const ty = self .air .typeOf (bin_op .lhs );
1417
1419
1418
- if (self .liveness .isUnused (inst )) {
1419
- return self .finishAir (inst , .dead , .{ bin_op .lhs , bin_op .rhs , .none });
1420
- }
1420
+ switch (ty .zigTypeTag ()) {
1421
+ .Vector = > return self .fail ("TODO implement add_with_overflow for Vector type" , .{}),
1422
+ .Int = > {
1423
+ const int_info = ty .intInfo (self .target .* );
1421
1424
1422
- const ty = self .air .typeOf (bin_op .lhs );
1423
- const signedness : std.builtin.Signedness = blk : {
1424
- if (ty .zigTypeTag () != .Int ) {
1425
- return self .fail ("TODO implement airAddWithOverflow for type {}" , .{ty .fmtDebug ()});
1426
- }
1427
- break :blk ty .intInfo (self .target .* ).signedness ;
1428
- };
1425
+ if (int_info .bits > 64 ) {
1426
+ return self .fail ("TODO implement add_with_overflow for Ints larger than 64bits" , .{});
1427
+ }
1429
1428
1430
- const partial = try self .genBinMathOp (inst , bin_op .lhs , bin_op .rhs );
1431
- const result : MCValue = switch (signedness ) {
1432
- .signed = > .{ .register_overflow_signed = partial .register },
1433
- .unsigned = > .{ .register_overflow_unsigned = partial .register },
1429
+ const partial = try self .genBinMathOp (inst , bin_op .lhs , bin_op .rhs );
1430
+ const result : MCValue = switch (int_info .signedness ) {
1431
+ .signed = > .{ .register_overflow_signed = partial .register },
1432
+ .unsigned = > .{ .register_overflow_unsigned = partial .register },
1433
+ };
1434
+ break :result result ;
1435
+ },
1436
+ else = > unreachable ,
1437
+ }
1434
1438
};
1435
1439
1436
1440
return self .finishAir (inst , result , .{ bin_op .lhs , bin_op .rhs , .none });
@@ -1439,23 +1443,27 @@ fn airAddWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
1439
1443
fn airSubWithOverflow (self : * Self , inst : Air.Inst.Index ) ! void {
1440
1444
const ty_pl = self .air .instructions .items (.data )[inst ].ty_pl ;
1441
1445
const bin_op = self .air .extraData (Air .Bin , ty_pl .payload ).data ;
1446
+ const result = if (self .liveness .isUnused (inst )) .dead else result : {
1447
+ const ty = self .air .typeOf (bin_op .lhs );
1442
1448
1443
- if (self .liveness .isUnused (inst )) {
1444
- return self .finishAir (inst , .dead , .{ bin_op .lhs , bin_op .rhs , .none });
1445
- }
1449
+ switch (ty .zigTypeTag ()) {
1450
+ .Vector = > return self .fail ("TODO implement sub_with_overflow for Vector type" , .{}),
1451
+ .Int = > {
1452
+ const int_info = ty .intInfo (self .target .* );
1446
1453
1447
- const ty = self .air .typeOf (bin_op .lhs );
1448
- const signedness : std.builtin.Signedness = blk : {
1449
- if (ty .zigTypeTag () != .Int ) {
1450
- return self .fail ("TODO implement airSubWithOverflow for type {}" , .{ty .fmtDebug ()});
1451
- }
1452
- break :blk ty .intInfo (self .target .* ).signedness ;
1453
- };
1454
+ if (int_info .bits > 64 ) {
1455
+ return self .fail ("TODO implement sub_with_overflow for Ints larger than 64bits" , .{});
1456
+ }
1454
1457
1455
- const partial = try self .genSubOp (inst , bin_op .lhs , bin_op .rhs );
1456
- const result : MCValue = switch (signedness ) {
1457
- .signed = > .{ .register_overflow_signed = partial .register },
1458
- .unsigned = > .{ .register_overflow_unsigned = partial .register },
1458
+ const partial = try self .genSubOp (inst , bin_op .lhs , bin_op .rhs );
1459
+ const result : MCValue = switch (int_info .signedness ) {
1460
+ .signed = > .{ .register_overflow_signed = partial .register },
1461
+ .unsigned = > .{ .register_overflow_unsigned = partial .register },
1462
+ };
1463
+ break :result result ;
1464
+ },
1465
+ else = > unreachable ,
1466
+ }
1459
1467
};
1460
1468
1461
1469
return self .finishAir (inst , result , .{ bin_op .lhs , bin_op .rhs , .none });
@@ -1466,30 +1474,37 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
1466
1474
const bin_op = self .air .extraData (Air .Bin , ty_pl .payload ).data ;
1467
1475
const result = if (self .liveness .isUnused (inst )) .dead else result : {
1468
1476
const ty = self .air .typeOf (bin_op .lhs );
1469
- const signedness : std.builtin.Signedness = blk : {
1470
- if (ty .zigTypeTag () != .Int ) {
1471
- return self .fail ("TODO implement airMulWithOverflow for type {}" , .{ty .fmtDebug ()});
1472
- }
1473
- break :blk ty .intInfo (self .target .* ).signedness ;
1474
- };
1475
1477
1476
- // Spill .rax and .rdx upfront to ensure we don't spill the operands too late.
1477
- try self .register_manager .getReg (.rax , inst );
1478
- try self .register_manager .getReg (.rdx , null );
1479
- self .register_manager .freezeRegs (&.{ .rax , .rdx });
1480
- defer self .register_manager .unfreezeRegs (&.{ .rax , .rdx });
1478
+ switch (ty .zigTypeTag ()) {
1479
+ .Vector = > return self .fail ("TODO implement mul_with_overflow for Vector type" , .{}),
1480
+ .Int = > {
1481
+ const int_info = ty .intInfo (self .target .* );
1481
1482
1482
- const lhs = try self .resolveInst (bin_op .lhs );
1483
- const rhs = try self .resolveInst (bin_op .rhs );
1483
+ if (int_info .bits > 64 ) {
1484
+ return self .fail ("TODO implement mul_with_overflow for Ints larger than 64bits" , .{});
1485
+ }
1484
1486
1485
- try self .genIntMulDivOpMir (switch (signedness ) {
1486
- .signed = > .imul ,
1487
- .unsigned = > .mul ,
1488
- }, ty , signedness , lhs , rhs );
1487
+ // Spill .rax and .rdx upfront to ensure we don't spill the operands too late.
1488
+ try self .register_manager .getReg (.rax , inst );
1489
+ try self .register_manager .getReg (.rdx , null );
1490
+ self .register_manager .freezeRegs (&.{ .rax , .rdx });
1491
+ defer self .register_manager .unfreezeRegs (&.{ .rax , .rdx });
1489
1492
1490
- switch (signedness ) {
1491
- .signed = > break :result MCValue { .register_overflow_signed = .rax },
1492
- .unsigned = > break :result MCValue { .register_overflow_unsigned = .rax },
1493
+ const lhs = try self .resolveInst (bin_op .lhs );
1494
+ const rhs = try self .resolveInst (bin_op .rhs );
1495
+
1496
+ try self .genIntMulDivOpMir (switch (int_info .signedness ) {
1497
+ .signed = > .imul ,
1498
+ .unsigned = > .mul ,
1499
+ }, ty , int_info .signedness , lhs , rhs );
1500
+
1501
+ const result : MCValue = switch (int_info .signedness ) {
1502
+ .signed = > .{ .register_overflow_signed = .rax },
1503
+ .unsigned = > .{ .register_overflow_unsigned = .rax },
1504
+ };
1505
+ break :result result ;
1506
+ },
1507
+ else = > unreachable ,
1493
1508
}
1494
1509
};
1495
1510
0 commit comments