@@ -1416,8 +1416,9 @@ fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
1416
1416
1417
1417
.div_float = > try self .divFloat (lhs_bind , rhs_bind , lhs_ty , rhs_ty , inst ),
1418
1418
1419
- .div_trunc = > try self .div (tag , lhs_bind , rhs_bind , lhs_ty , rhs_ty , inst ),
1420
- .div_floor = > try self .div (tag , lhs_bind , rhs_bind , lhs_ty , rhs_ty , inst ),
1419
+ .div_trunc = > try self .divTrunc (lhs_bind , rhs_bind , lhs_ty , rhs_ty , inst ),
1420
+
1421
+ .div_floor = > try self .divFloor (lhs_bind , rhs_bind , lhs_ty , rhs_ty , inst ),
1421
1422
1422
1423
.div_exact = > try self .divExact (lhs_bind , rhs_bind , lhs_ty , rhs_ty , inst ),
1423
1424
@@ -1567,12 +1568,12 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {
1567
1568
1568
1569
const dest = blk : {
1569
1570
if (rhs_immediate_ok ) {
1570
- break :blk try self .binOpImmediateNew (mir_tag , lhs_bind , rhs_immediate .? , lhs_ty , false , null );
1571
+ break :blk try self .binOpImmediate (mir_tag , lhs_bind , rhs_immediate .? , lhs_ty , false , null );
1571
1572
} else if (lhs_immediate_ok ) {
1572
1573
// swap lhs and rhs
1573
- break :blk try self .binOpImmediateNew (mir_tag , rhs_bind , lhs_immediate .? , rhs_ty , true , null );
1574
+ break :blk try self .binOpImmediate (mir_tag , rhs_bind , lhs_immediate .? , rhs_ty , true , null );
1574
1575
} else {
1575
- break :blk try self .binOpRegisterNew (mir_tag , lhs_bind , rhs_bind , lhs_ty , rhs_ty , null );
1576
+ break :blk try self .binOpRegister (mir_tag , lhs_bind , rhs_bind , lhs_ty , rhs_ty , null );
1576
1577
}
1577
1578
};
1578
1579
@@ -1625,7 +1626,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
1625
1626
.unsigned = > .mul ,
1626
1627
};
1627
1628
1628
- const dest = try self .binOpRegisterNew (base_tag , lhs_bind , rhs_bind , lhs_ty , rhs_ty , null );
1629
+ const dest = try self .binOpRegister (base_tag , lhs_bind , rhs_bind , lhs_ty , rhs_ty , null );
1629
1630
const dest_reg = dest .register ;
1630
1631
const dest_reg_lock = self .register_manager .lockRegAssumeUnused (dest_reg );
1631
1632
defer self .register_manager .unlockReg (dest_reg_lock );
@@ -3123,7 +3124,7 @@ fn allocRegs(
3123
3124
/// instructions which are binary operations acting on two registers
3124
3125
///
3125
3126
/// Returns the destination register
3126
- fn binOpRegisterNew (
3127
+ fn binOpRegister (
3127
3128
self : * Self ,
3128
3129
mir_tag : Mir.Inst.Tag ,
3129
3130
lhs_bind : ReadArg.Bind ,
@@ -3196,7 +3197,7 @@ fn binOpRegisterNew(
3196
3197
/// an immediate
3197
3198
///
3198
3199
/// Returns the destination register
3199
- fn binOpImmediateNew (
3200
+ fn binOpImmediate (
3200
3201
self : * Self ,
3201
3202
mir_tag : Mir.Inst.Tag ,
3202
3203
lhs_bind : ReadArg.Bind ,
@@ -3265,11 +3266,11 @@ fn addSub(
3265
3266
rhs_ty : Type ,
3266
3267
maybe_inst : ? Air.Inst.Index ,
3267
3268
) InnerError ! MCValue {
3269
+ const mod = self .bin_file .options .module .? ;
3268
3270
switch (lhs_ty .zigTypeTag ()) {
3269
3271
.Float = > return self .fail ("TODO ARM binary operations on floats" , .{}),
3270
3272
.Vector = > return self .fail ("TODO ARM binary operations on vectors" , .{}),
3271
3273
.Int = > {
3272
- const mod = self .bin_file .options .module .? ;
3273
3274
assert (lhs_ty .eql (rhs_ty , mod ));
3274
3275
const int_info = lhs_ty .intInfo (self .target .* );
3275
3276
if (int_info .bits <= 32 ) {
@@ -3298,12 +3299,12 @@ fn addSub(
3298
3299
};
3299
3300
3300
3301
if (rhs_immediate_ok ) {
3301
- return try self .binOpImmediateNew (mir_tag , lhs_bind , rhs_immediate .? , lhs_ty , false , maybe_inst );
3302
+ return try self .binOpImmediate (mir_tag , lhs_bind , rhs_immediate .? , lhs_ty , false , maybe_inst );
3302
3303
} else if (lhs_immediate_ok ) {
3303
3304
// swap lhs and rhs
3304
- return try self .binOpImmediateNew (mir_tag , rhs_bind , lhs_immediate .? , rhs_ty , true , maybe_inst );
3305
+ return try self .binOpImmediate (mir_tag , rhs_bind , lhs_immediate .? , rhs_ty , true , maybe_inst );
3305
3306
} else {
3306
- return try self .binOpRegisterNew (mir_tag , lhs_bind , rhs_bind , lhs_ty , rhs_ty , maybe_inst );
3307
+ return try self .binOpRegister (mir_tag , lhs_bind , rhs_bind , lhs_ty , rhs_ty , maybe_inst );
3307
3308
}
3308
3309
} else {
3309
3310
return self .fail ("TODO ARM binary operations on integers > u32/i32" , .{});
@@ -3321,18 +3322,18 @@ fn mul(
3321
3322
rhs_ty : Type ,
3322
3323
maybe_inst : ? Air.Inst.Index ,
3323
3324
) InnerError ! MCValue {
3325
+ const mod = self .bin_file .options .module .? ;
3324
3326
switch (lhs_ty .zigTypeTag ()) {
3325
3327
.Float = > return self .fail ("TODO ARM binary operations on floats" , .{}),
3326
3328
.Vector = > return self .fail ("TODO ARM binary operations on vectors" , .{}),
3327
3329
.Int = > {
3328
- const mod = self .bin_file .options .module .? ;
3329
3330
assert (lhs_ty .eql (rhs_ty , mod ));
3330
3331
const int_info = lhs_ty .intInfo (self .target .* );
3331
3332
if (int_info .bits <= 32 ) {
3332
3333
// TODO add optimisations for multiplication
3333
3334
// with immediates, for example a * 2 can be
3334
3335
// lowered to a << 1
3335
- return try self .binOpRegisterNew (.mul , lhs_bind , rhs_bind , lhs_ty , rhs_ty , maybe_inst );
3336
+ return try self .binOpRegister (.mul , lhs_bind , rhs_bind , lhs_ty , rhs_ty , maybe_inst );
3336
3337
} else {
3337
3338
return self .fail ("TODO ARM binary operations on integers > u32/i32" , .{});
3338
3339
}
@@ -3361,22 +3362,62 @@ fn divFloat(
3361
3362
}
3362
3363
}
3363
3364
3364
- fn div (
3365
+ fn divTrunc (
3365
3366
self : * Self ,
3366
- tag : Air.Inst.Tag ,
3367
3367
lhs_bind : ReadArg.Bind ,
3368
3368
rhs_bind : ReadArg.Bind ,
3369
3369
lhs_ty : Type ,
3370
3370
rhs_ty : Type ,
3371
3371
maybe_inst : ? Air.Inst.Index ,
3372
3372
) InnerError ! MCValue {
3373
- _ = tag ;
3373
+ const mod = self .bin_file .options .module .? ;
3374
+ switch (lhs_ty .zigTypeTag ()) {
3375
+ .Float = > return self .fail ("TODO ARM binary operations on floats" , .{}),
3376
+ .Vector = > return self .fail ("TODO ARM binary operations on vectors" , .{}),
3377
+ .Int = > {
3378
+ assert (lhs_ty .eql (rhs_ty , mod ));
3379
+ const int_info = lhs_ty .intInfo (self .target .* );
3380
+ if (int_info .bits <= 32 ) {
3381
+ switch (int_info .signedness ) {
3382
+ .signed = > {
3383
+ return self .fail ("TODO ARM signed integer division" , .{});
3384
+ },
3385
+ .unsigned = > {
3386
+ const rhs_immediate = try rhs_bind .resolveToImmediate (self );
3387
+
3388
+ if (rhs_immediate ) | imm | {
3389
+ if (std .math .isPowerOfTwo (imm )) {
3390
+ const shift = std .math .log2_int (u32 , imm );
3391
+ return try self .binOpImmediate (.lsr , lhs_bind , shift , lhs_ty , false , maybe_inst );
3392
+ } else {
3393
+ return self .fail ("TODO ARM integer division by constants" , .{});
3394
+ }
3395
+ } else {
3396
+ return self .fail ("TODO ARM integer division" , .{});
3397
+ }
3398
+ },
3399
+ }
3400
+ } else {
3401
+ return self .fail ("TODO ARM integer division for integers > u32/i32" , .{});
3402
+ }
3403
+ },
3404
+ else = > unreachable ,
3405
+ }
3406
+ }
3374
3407
3408
+ fn divFloor (
3409
+ self : * Self ,
3410
+ lhs_bind : ReadArg.Bind ,
3411
+ rhs_bind : ReadArg.Bind ,
3412
+ lhs_ty : Type ,
3413
+ rhs_ty : Type ,
3414
+ maybe_inst : ? Air.Inst.Index ,
3415
+ ) InnerError ! MCValue {
3416
+ const mod = self .bin_file .options .module .? ;
3375
3417
switch (lhs_ty .zigTypeTag ()) {
3376
3418
.Float = > return self .fail ("TODO ARM binary operations on floats" , .{}),
3377
3419
.Vector = > return self .fail ("TODO ARM binary operations on vectors" , .{}),
3378
3420
.Int = > {
3379
- const mod = self .bin_file .options .module .? ;
3380
3421
assert (lhs_ty .eql (rhs_ty , mod ));
3381
3422
const int_info = lhs_ty .intInfo (self .target .* );
3382
3423
if (int_info .bits <= 32 ) {
@@ -3390,7 +3431,7 @@ fn div(
3390
3431
if (rhs_immediate ) | imm | {
3391
3432
if (std .math .isPowerOfTwo (imm )) {
3392
3433
const shift = std .math .log2_int (u32 , imm );
3393
- return try self .binOpImmediateNew (.lsr , lhs_bind , shift , lhs_ty , false , maybe_inst );
3434
+ return try self .binOpImmediate (.lsr , lhs_bind , shift , lhs_ty , false , maybe_inst );
3394
3435
} else {
3395
3436
return self .fail ("TODO ARM integer division by constants" , .{});
3396
3437
}
@@ -3436,11 +3477,11 @@ fn rem(
3436
3477
rhs_ty : Type ,
3437
3478
maybe_inst : ? Air.Inst.Index ,
3438
3479
) InnerError ! MCValue {
3480
+ const mod = self .bin_file .options .module .? ;
3439
3481
switch (lhs_ty .zigTypeTag ()) {
3440
3482
.Float = > return self .fail ("TODO ARM binary operations on floats" , .{}),
3441
3483
.Vector = > return self .fail ("TODO ARM binary operations on vectors" , .{}),
3442
3484
.Int = > {
3443
- const mod = self .bin_file .options .module .? ;
3444
3485
assert (lhs_ty .eql (rhs_ty , mod ));
3445
3486
const int_info = lhs_ty .intInfo (self .target .* );
3446
3487
if (int_info .bits <= 32 ) {
@@ -3522,28 +3563,26 @@ fn wrappingArithmetic(
3522
3563
rhs_ty : Type ,
3523
3564
maybe_inst : ? Air.Inst.Index ,
3524
3565
) InnerError ! MCValue {
3525
- const base_tag : Air.Inst.Tag = switch (tag ) {
3526
- .addwrap = > .add ,
3527
- .subwrap = > .sub ,
3528
- .mulwrap = > .mul ,
3529
- else = > unreachable ,
3530
- };
3531
-
3532
- // Generate an add/sub/mul
3533
- const result = try self .addSub (base_tag , lhs_bind , rhs_bind , lhs_ty , rhs_ty , maybe_inst );
3534
-
3535
- // Truncate if necessary
3536
3566
switch (lhs_ty .zigTypeTag ()) {
3537
3567
.Vector = > return self .fail ("TODO ARM binary operations on vectors" , .{}),
3538
3568
.Int = > {
3539
3569
const int_info = lhs_ty .intInfo (self .target .* );
3540
3570
if (int_info .bits <= 32 ) {
3541
- const result_reg = result .register ;
3571
+ // Generate an add/sub/mul
3572
+ const result : MCValue = switch (tag ) {
3573
+ .addwrap = > try self .addSub (.add , lhs_bind , rhs_bind , lhs_ty , rhs_ty , maybe_inst ),
3574
+ .subwrap = > try self .addSub (.sub , lhs_bind , rhs_bind , lhs_ty , rhs_ty , maybe_inst ),
3575
+ .mulwrap = > try self .mul (lhs_bind , rhs_bind , lhs_ty , rhs_ty , maybe_inst ),
3576
+ else = > unreachable ,
3577
+ };
3542
3578
3579
+ // Truncate if necessary
3580
+ const result_reg = result .register ;
3543
3581
if (int_info .bits < 32 ) {
3544
3582
try self .truncRegister (result_reg , result_reg , int_info .signedness , int_info .bits );
3545
- return result ;
3546
- } else return result ;
3583
+ }
3584
+
3585
+ return result ;
3547
3586
} else {
3548
3587
return self .fail ("TODO ARM binary operations on integers > u32/i32" , .{});
3549
3588
}
@@ -3582,12 +3621,12 @@ fn bitwise(
3582
3621
};
3583
3622
3584
3623
if (rhs_immediate_ok ) {
3585
- return try self .binOpImmediateNew (mir_tag , lhs_bind , rhs_immediate .? , lhs_ty , false , maybe_inst );
3624
+ return try self .binOpImmediate (mir_tag , lhs_bind , rhs_immediate .? , lhs_ty , false , maybe_inst );
3586
3625
} else if (lhs_immediate_ok ) {
3587
3626
// swap lhs and rhs
3588
- return try self .binOpImmediateNew (mir_tag , rhs_bind , lhs_immediate .? , rhs_ty , true , maybe_inst );
3627
+ return try self .binOpImmediate (mir_tag , rhs_bind , lhs_immediate .? , rhs_ty , true , maybe_inst );
3589
3628
} else {
3590
- return try self .binOpRegisterNew (mir_tag , lhs_bind , rhs_bind , lhs_ty , rhs_ty , maybe_inst );
3629
+ return try self .binOpRegister (mir_tag , lhs_bind , rhs_bind , lhs_ty , rhs_ty , maybe_inst );
3591
3630
}
3592
3631
} else {
3593
3632
return self .fail ("TODO ARM binary operations on integers > u32/i32" , .{});
@@ -3623,9 +3662,9 @@ fn shiftExact(
3623
3662
};
3624
3663
3625
3664
if (rhs_immediate ) | imm | {
3626
- return try self .binOpImmediateNew (mir_tag , lhs_bind , imm , lhs_ty , false , maybe_inst );
3665
+ return try self .binOpImmediate (mir_tag , lhs_bind , imm , lhs_ty , false , maybe_inst );
3627
3666
} else {
3628
- return try self .binOpRegisterNew (mir_tag , lhs_bind , rhs_bind , lhs_ty , rhs_ty , maybe_inst );
3667
+ return try self .binOpRegister (mir_tag , lhs_bind , rhs_bind , lhs_ty , rhs_ty , maybe_inst );
3629
3668
}
3630
3669
} else {
3631
3670
return self .fail ("TODO ARM binary operations on integers > u32/i32" , .{});
@@ -3644,34 +3683,34 @@ fn shiftNormal(
3644
3683
rhs_ty : Type ,
3645
3684
maybe_inst : ? Air.Inst.Index ,
3646
3685
) InnerError ! MCValue {
3647
- const base_tag : Air.Inst.Tag = switch (tag ) {
3648
- .shl = > .shl_exact ,
3649
- .shr = > .shr_exact ,
3650
- else = > unreachable ,
3651
- };
3652
-
3653
- // Generate a shl_exact/shr_exact
3654
- const result = try self .shiftExact (base_tag , lhs_bind , rhs_bind , lhs_ty , rhs_ty , maybe_inst );
3686
+ switch (lhs_ty .zigTypeTag ()) {
3687
+ .Vector = > return self .fail ("TODO ARM binary operations on vectors" , .{}),
3688
+ .Int = > {
3689
+ const int_info = lhs_ty .intInfo (self .target .* );
3690
+ if (int_info .bits <= 32 ) {
3691
+ // Generate a shl_exact/shr_exact
3692
+ const result : MCValue = switch (tag ) {
3693
+ .shl = > try self .shiftExact (.shl_exact , lhs_bind , rhs_bind , lhs_ty , rhs_ty , maybe_inst ),
3694
+ .shr = > try self .shiftExact (.shr_exact , lhs_bind , rhs_bind , lhs_ty , rhs_ty , maybe_inst ),
3695
+ else = > unreachable ,
3696
+ };
3655
3697
3656
- // Truncate if necessary
3657
- switch (tag ) {
3658
- .shr = > return result ,
3659
- .shl = > switch (lhs_ty .zigTypeTag ()) {
3660
- .Vector = > return self .fail ("TODO ARM binary operations on vectors" , .{}),
3661
- .Int = > {
3662
- const int_info = lhs_ty .intInfo (self .target .* );
3663
- if (int_info .bits <= 32 ) {
3664
- const result_reg = result .register ;
3698
+ // Truncate if necessary
3699
+ switch (tag ) {
3700
+ .shr = > return result ,
3701
+ .shl = > {
3702
+ const result_reg = result .register ;
3703
+ if (int_info .bits < 32 ) {
3704
+ try self .truncRegister (result_reg , result_reg , int_info .signedness , int_info .bits );
3705
+ }
3665
3706
3666
- if (int_info .bits < 32 ) {
3667
- try self .truncRegister (result_reg , result_reg , int_info .signedness , int_info .bits );
3668
3707
return result ;
3669
- } else return result ;
3670
- } else {
3671
- return self .fail ("TODO ARM binary operations on integers > u32/i32" , .{});
3708
+ },
3709
+ else = > unreachable ,
3672
3710
}
3673
- },
3674
- else = > unreachable ,
3711
+ } else {
3712
+ return self .fail ("TODO ARM binary operations on integers > u32/i32" , .{});
3713
+ }
3675
3714
},
3676
3715
else = > unreachable ,
3677
3716
}
@@ -3698,12 +3737,12 @@ fn booleanOp(
3698
3737
};
3699
3738
3700
3739
if (rhs_immediate ) | imm | {
3701
- return try self .binOpImmediateNew (mir_tag , lhs_bind , imm , lhs_ty , false , maybe_inst );
3740
+ return try self .binOpImmediate (mir_tag , lhs_bind , imm , lhs_ty , false , maybe_inst );
3702
3741
} else if (lhs_immediate ) | imm | {
3703
3742
// swap lhs and rhs
3704
- return try self .binOpImmediateNew (mir_tag , rhs_bind , imm , rhs_ty , true , maybe_inst );
3743
+ return try self .binOpImmediate (mir_tag , rhs_bind , imm , rhs_ty , true , maybe_inst );
3705
3744
} else {
3706
- return try self .binOpRegisterNew (mir_tag , lhs_bind , rhs_bind , lhs_ty , rhs_ty , maybe_inst );
3745
+ return try self .binOpRegister (mir_tag , lhs_bind , rhs_bind , lhs_ty , rhs_ty , maybe_inst );
3707
3746
}
3708
3747
},
3709
3748
else = > unreachable ,
0 commit comments