@@ -1487,28 +1487,52 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
1487
1487
break :result result ;
1488
1488
}
1489
1489
1490
- const lhs = try self .resolveInst (bin_op .lhs );
1491
- const rhs = try self .resolveInst (bin_op .rhs );
1490
+ const dst_reg : Register = dst_reg : {
1491
+ switch (int_info .signedness ) {
1492
+ .signed = > {
1493
+ const lhs = try self .resolveInst (bin_op .lhs );
1494
+ const rhs = try self .resolveInst (bin_op .rhs );
1495
+
1496
+ rhs .freezeIfRegister (& self .register_manager );
1497
+ defer rhs .unfreezeIfRegister (& self .register_manager );
1498
+
1499
+ // TODO check if we could reuse rhs instead, and swap the values out.
1500
+ const dst_reg : Register = blk : {
1501
+ if (self .reuseOperand (inst , bin_op .lhs , 0 , lhs )) {
1502
+ if (lhs .isRegister ()) break :blk lhs .register ;
1503
+ }
1504
+ break :blk try self .copyToTmpRegister (ty , lhs );
1505
+ };
1506
+ self .register_manager .freezeRegs (&.{dst_reg });
1507
+
1508
+ const rhs_mcv = blk : {
1509
+ if (rhs .isRegister () or rhs .isMemory ()) break :blk rhs ;
1510
+ break :blk MCValue { .register = try self .copyToTmpRegister (ty , rhs ) };
1511
+ };
1512
+ rhs_mcv .freezeIfRegister (& self .register_manager );
1513
+ defer rhs_mcv .unfreezeIfRegister (& self .register_manager );
1514
+
1515
+ try self .genIntMulComplexOpMir (Type .isize , .{ .register = dst_reg }, rhs_mcv );
1516
+
1517
+ break :dst_reg dst_reg ;
1518
+ },
1519
+ .unsigned = > {
1520
+ // Spill .rax and .rdx upfront to ensure we don't spill the operands too late.
1521
+ try self .register_manager .getReg (.rax , null );
1522
+ try self .register_manager .getReg (.rdx , null );
1523
+ self .register_manager .freezeRegs (&.{ .rax , .rdx });
1524
+ defer self .register_manager .unfreezeRegs (&.{.rdx });
1492
1525
1493
- rhs . freezeIfRegister ( & self . register_manager );
1494
- defer rhs . unfreezeIfRegister ( & self . register_manager );
1526
+ const lhs = try self . resolveInst ( bin_op . lhs );
1527
+ const rhs = try self . resolveInst ( bin_op . rhs );
1495
1528
1496
- // TODO check if we could reuse rhs instead, and swap the values out.
1497
- const dst_mcv = blk : {
1498
- if (self .reuseOperand (inst , bin_op .lhs , 0 , lhs )) {
1499
- if (lhs .isRegister ()) break :blk lhs ;
1500
- }
1501
- break :blk MCValue { .register = try self .copyToTmpRegister (ty , lhs ) };
1502
- };
1503
- dst_mcv .freezeIfRegister (& self .register_manager );
1504
- defer dst_mcv .unfreezeIfRegister (& self .register_manager );
1529
+ try self .genIntMulDivOpMir (.mul , ty , .unsigned , lhs , rhs );
1505
1530
1506
- const rhs_mcv = blk : {
1507
- if ( rhs . isRegister () or rhs . isMemory ()) break : blk rhs ;
1508
- break : blk MCValue { . register = try self . copyToTmpRegister ( ty , rhs ) };
1531
+ break : dst_reg registerAlias ( .rax , @intCast ( u32 , ty . abiSize ( self . target .* )));
1532
+ },
1533
+ }
1509
1534
};
1510
- rhs_mcv .freezeIfRegister (& self .register_manager );
1511
- defer rhs_mcv .unfreezeIfRegister (& self .register_manager );
1535
+ defer self .register_manager .unfreezeRegs (&.{dst_reg });
1512
1536
1513
1537
const tuple_ty = self .air .typeOfIndex (inst );
1514
1538
const tuple_size = @intCast (u32 , tuple_ty .abiSize (self .target .* ));
@@ -1521,8 +1545,6 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
1521
1545
.unsigned = > ty ,
1522
1546
};
1523
1547
1524
- try self .genIntMulComplexOpMir (extended_ty , dst_mcv , rhs_mcv );
1525
-
1526
1548
const temp_regs = try self .register_manager .allocRegs (3 , .{ null , null , null });
1527
1549
self .register_manager .freezeRegs (& temp_regs );
1528
1550
defer self .register_manager .unfreezeRegs (& temp_regs );
@@ -1542,9 +1564,14 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
1542
1564
});
1543
1565
1544
1566
const scratch_reg = temp_regs [1 ];
1545
- try self .genSetReg (extended_ty , scratch_reg , dst_mcv );
1567
+ try self .genSetReg (extended_ty , scratch_reg , .{ . register = dst_reg } );
1546
1568
try self .truncateRegister (ty , scratch_reg );
1547
- try self .genBinMathOpMir (.cmp , extended_ty , dst_mcv , .{ .register = scratch_reg });
1569
+ try self .genBinMathOpMir (
1570
+ .cmp ,
1571
+ extended_ty ,
1572
+ .{ .register = dst_reg },
1573
+ .{ .register = scratch_reg },
1574
+ );
1548
1575
1549
1576
const eq_reg = temp_regs [2 ];
1550
1577
_ = try self .addInst (.{
@@ -6626,7 +6653,12 @@ fn truncateRegister(self: *Self, ty: Type, reg: Register) !void {
6626
6653
.unsigned = > {
6627
6654
const shift = @intCast (u6 , max_reg_bit_width - int_info .bits );
6628
6655
const mask = (~ @as (u64 , 0 )) >> shift ;
6629
- try self .genBinMathOpMir (.@"and" , Type .usize , .{ .register = reg }, .{ .immediate = mask });
6656
+ if (int_info .bits <= 32 ) {
6657
+ try self .genBinMathOpMir (.@"and" , Type .usize , .{ .register = reg }, .{ .immediate = mask });
6658
+ } else {
6659
+ const tmp_reg = try self .copyToTmpRegister (Type .usize , .{ .immediate = mask });
6660
+ try self .genBinMathOpMir (.@"and" , Type .usize , .{ .register = reg }, .{ .register = tmp_reg });
6661
+ }
6630
6662
},
6631
6663
}
6632
6664
}
0 commit comments