Skip to content

Commit 10a660e

Browse files
joachimschmidt557andrewrk
authored andcommitted
stage2 ARM: misc fixes
- remove redundant `new` from `binOpRegisterNew` name - fix mul_with_overflow
1 parent 9498c95 commit 10a660e

File tree

1 file changed

+105
-66
lines changed

1 file changed

+105
-66
lines changed

src/arch/arm/CodeGen.zig

Lines changed: 105 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1416,8 +1416,9 @@ fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
14161416

14171417
.div_float => try self.divFloat(lhs_bind, rhs_bind, lhs_ty, rhs_ty, inst),
14181418

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),
14211422

14221423
.div_exact => try self.divExact(lhs_bind, rhs_bind, lhs_ty, rhs_ty, inst),
14231424

@@ -1567,12 +1568,12 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {
15671568

15681569
const dest = blk: {
15691570
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);
15711572
} else if (lhs_immediate_ok) {
15721573
// 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);
15741575
} 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);
15761577
}
15771578
};
15781579

@@ -1625,7 +1626,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
16251626
.unsigned => .mul,
16261627
};
16271628

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);
16291630
const dest_reg = dest.register;
16301631
const dest_reg_lock = self.register_manager.lockRegAssumeUnused(dest_reg);
16311632
defer self.register_manager.unlockReg(dest_reg_lock);
@@ -3123,7 +3124,7 @@ fn allocRegs(
31233124
/// instructions which are binary operations acting on two registers
31243125
///
31253126
/// Returns the destination register
3126-
fn binOpRegisterNew(
3127+
fn binOpRegister(
31273128
self: *Self,
31283129
mir_tag: Mir.Inst.Tag,
31293130
lhs_bind: ReadArg.Bind,
@@ -3196,7 +3197,7 @@ fn binOpRegisterNew(
31963197
/// an immediate
31973198
///
31983199
/// Returns the destination register
3199-
fn binOpImmediateNew(
3200+
fn binOpImmediate(
32003201
self: *Self,
32013202
mir_tag: Mir.Inst.Tag,
32023203
lhs_bind: ReadArg.Bind,
@@ -3265,11 +3266,11 @@ fn addSub(
32653266
rhs_ty: Type,
32663267
maybe_inst: ?Air.Inst.Index,
32673268
) InnerError!MCValue {
3269+
const mod = self.bin_file.options.module.?;
32683270
switch (lhs_ty.zigTypeTag()) {
32693271
.Float => return self.fail("TODO ARM binary operations on floats", .{}),
32703272
.Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
32713273
.Int => {
3272-
const mod = self.bin_file.options.module.?;
32733274
assert(lhs_ty.eql(rhs_ty, mod));
32743275
const int_info = lhs_ty.intInfo(self.target.*);
32753276
if (int_info.bits <= 32) {
@@ -3298,12 +3299,12 @@ fn addSub(
32983299
};
32993300

33003301
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);
33023303
} else if (lhs_immediate_ok) {
33033304
// 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);
33053306
} 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);
33073308
}
33083309
} else {
33093310
return self.fail("TODO ARM binary operations on integers > u32/i32", .{});
@@ -3321,18 +3322,18 @@ fn mul(
33213322
rhs_ty: Type,
33223323
maybe_inst: ?Air.Inst.Index,
33233324
) InnerError!MCValue {
3325+
const mod = self.bin_file.options.module.?;
33243326
switch (lhs_ty.zigTypeTag()) {
33253327
.Float => return self.fail("TODO ARM binary operations on floats", .{}),
33263328
.Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
33273329
.Int => {
3328-
const mod = self.bin_file.options.module.?;
33293330
assert(lhs_ty.eql(rhs_ty, mod));
33303331
const int_info = lhs_ty.intInfo(self.target.*);
33313332
if (int_info.bits <= 32) {
33323333
// TODO add optimisations for multiplication
33333334
// with immediates, for example a * 2 can be
33343335
// 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);
33363337
} else {
33373338
return self.fail("TODO ARM binary operations on integers > u32/i32", .{});
33383339
}
@@ -3361,22 +3362,62 @@ fn divFloat(
33613362
}
33623363
}
33633364

3364-
fn div(
3365+
fn divTrunc(
33653366
self: *Self,
3366-
tag: Air.Inst.Tag,
33673367
lhs_bind: ReadArg.Bind,
33683368
rhs_bind: ReadArg.Bind,
33693369
lhs_ty: Type,
33703370
rhs_ty: Type,
33713371
maybe_inst: ?Air.Inst.Index,
33723372
) 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+
}
33743407

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.?;
33753417
switch (lhs_ty.zigTypeTag()) {
33763418
.Float => return self.fail("TODO ARM binary operations on floats", .{}),
33773419
.Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
33783420
.Int => {
3379-
const mod = self.bin_file.options.module.?;
33803421
assert(lhs_ty.eql(rhs_ty, mod));
33813422
const int_info = lhs_ty.intInfo(self.target.*);
33823423
if (int_info.bits <= 32) {
@@ -3390,7 +3431,7 @@ fn div(
33903431
if (rhs_immediate) |imm| {
33913432
if (std.math.isPowerOfTwo(imm)) {
33923433
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);
33943435
} else {
33953436
return self.fail("TODO ARM integer division by constants", .{});
33963437
}
@@ -3436,11 +3477,11 @@ fn rem(
34363477
rhs_ty: Type,
34373478
maybe_inst: ?Air.Inst.Index,
34383479
) InnerError!MCValue {
3480+
const mod = self.bin_file.options.module.?;
34393481
switch (lhs_ty.zigTypeTag()) {
34403482
.Float => return self.fail("TODO ARM binary operations on floats", .{}),
34413483
.Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
34423484
.Int => {
3443-
const mod = self.bin_file.options.module.?;
34443485
assert(lhs_ty.eql(rhs_ty, mod));
34453486
const int_info = lhs_ty.intInfo(self.target.*);
34463487
if (int_info.bits <= 32) {
@@ -3522,28 +3563,26 @@ fn wrappingArithmetic(
35223563
rhs_ty: Type,
35233564
maybe_inst: ?Air.Inst.Index,
35243565
) 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
35363566
switch (lhs_ty.zigTypeTag()) {
35373567
.Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
35383568
.Int => {
35393569
const int_info = lhs_ty.intInfo(self.target.*);
35403570
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+
};
35423578

3579+
// Truncate if necessary
3580+
const result_reg = result.register;
35433581
if (int_info.bits < 32) {
35443582
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;
35473586
} else {
35483587
return self.fail("TODO ARM binary operations on integers > u32/i32", .{});
35493588
}
@@ -3582,12 +3621,12 @@ fn bitwise(
35823621
};
35833622

35843623
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);
35863625
} else if (lhs_immediate_ok) {
35873626
// 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);
35893628
} 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);
35913630
}
35923631
} else {
35933632
return self.fail("TODO ARM binary operations on integers > u32/i32", .{});
@@ -3623,9 +3662,9 @@ fn shiftExact(
36233662
};
36243663

36253664
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);
36273666
} 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);
36293668
}
36303669
} else {
36313670
return self.fail("TODO ARM binary operations on integers > u32/i32", .{});
@@ -3644,34 +3683,34 @@ fn shiftNormal(
36443683
rhs_ty: Type,
36453684
maybe_inst: ?Air.Inst.Index,
36463685
) 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+
};
36553697

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+
}
36653706

3666-
if (int_info.bits < 32) {
3667-
try self.truncRegister(result_reg, result_reg, int_info.signedness, int_info.bits);
36683707
return result;
3669-
} else return result;
3670-
} else {
3671-
return self.fail("TODO ARM binary operations on integers > u32/i32", .{});
3708+
},
3709+
else => unreachable,
36723710
}
3673-
},
3674-
else => unreachable,
3711+
} else {
3712+
return self.fail("TODO ARM binary operations on integers > u32/i32", .{});
3713+
}
36753714
},
36763715
else => unreachable,
36773716
}
@@ -3698,12 +3737,12 @@ fn booleanOp(
36983737
};
36993738

37003739
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);
37023741
} else if (lhs_immediate) |imm| {
37033742
// 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);
37053744
} 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);
37073746
}
37083747
},
37093748
else => unreachable,

0 commit comments

Comments
 (0)