authorgravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-11-20 21:02:20+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-01-09 14:35:32-07:00
log10a660ebea6b616644b1010b3766bf9899eeaa75
tree05785dd3b39ce238085c368175af0619f61a07de
parent9498c95fafad5b1561f37461a7588e8b2a922044

stage2 ARM: misc fixes

- remove redundant `new` from `binOpRegisterNew` name - fix mul_with_overflow

1 files changed, 105 insertions(+), 66 deletions(-)

src/arch/arm/CodeGen.zig+105-66
......@@ -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
3126fn binOpRegisterNew(
3127fn 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
3199fn binOpImmediateNew(
3200fn 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
3364fn div(
3365fn 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
3408fn 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,