authorgravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-07-06 21:10:28+02:00
committergravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-07-12 22:43:55+02:00
log47d1874218219d6eddbc96e9bafef81f24911033
tree6db1c7813edcbac0820b3c12540a7d5ab54b2f53
parent7090f0471c0169c60a9476b537b09eebe1bdf6af
signaturelock-open Commit is signed but in an unrecognized format.

stage2 ARM: implement division by constant int power-of-two divisors


1 files changed, 53 insertions(+), 8 deletions(-)

src/arch/arm/CodeGen.zig+53-8
...@@ -567,6 +567,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -567,6 +567,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
567 .xor => try self.airBinOp(inst, .xor),567 .xor => try self.airBinOp(inst, .xor),
568 .shr => try self.airBinOp(inst, .shr),568 .shr => try self.airBinOp(inst, .shr),
569 .shr_exact => try self.airBinOp(inst, .shr_exact),569 .shr_exact => try self.airBinOp(inst, .shr_exact),
570 .div_float => try self.airBinOp(inst, .div_float),
571 .div_trunc => try self.airBinOp(inst, .div_trunc),
572 .div_floor => try self.airBinOp(inst, .div_floor),
573 .div_exact => try self.airBinOp(inst, .div_exact),
570574
571 .ptr_add => try self.airPtrArithmetic(inst, .ptr_add),575 .ptr_add => try self.airPtrArithmetic(inst, .ptr_add),
572 .ptr_sub => try self.airPtrArithmetic(inst, .ptr_sub),576 .ptr_sub => try self.airPtrArithmetic(inst, .ptr_sub),
...@@ -604,8 +608,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -604,8 +608,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
604 .mul_with_overflow => try self.airMulWithOverflow(inst),608 .mul_with_overflow => try self.airMulWithOverflow(inst),
605 .shl_with_overflow => try self.airShlWithOverflow(inst),609 .shl_with_overflow => try self.airShlWithOverflow(inst),
606610
607 .div_float, .div_trunc, .div_floor, .div_exact => try self.airDiv(inst),
608
609 .cmp_lt => try self.airCmp(inst, .lt),611 .cmp_lt => try self.airCmp(inst, .lt),
610 .cmp_lte => try self.airCmp(inst, .lte),612 .cmp_lte => try self.airCmp(inst, .lte),
611 .cmp_eq => try self.airCmp(inst, .eq),613 .cmp_eq => try self.airCmp(inst, .eq),
...@@ -1729,12 +1731,6 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -1729,12 +1731,6 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
1729 return self.finishAir(inst, result, .{ extra.lhs, extra.rhs, .none });1731 return self.finishAir(inst, result, .{ extra.lhs, extra.rhs, .none });
1730}1732}
17311733
1732fn airDiv(self: *Self, inst: Air.Inst.Index) !void {
1733 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1734 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement div for {}", .{self.target.cpu.arch});
1735 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
1736}
1737
1738fn airRem(self: *Self, inst: Air.Inst.Index) !void {1734fn airRem(self: *Self, inst: Air.Inst.Index) !void {
1739 const bin_op = self.air.instructions.items(.data)[inst].bin_op;1735 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1740 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement rem for {}", .{self.target.cpu.arch});1736 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement rem for {}", .{self.target.cpu.arch});
...@@ -2878,6 +2874,55 @@ fn binOp(...@@ -2878,6 +2874,55 @@ fn binOp(
2878 else => unreachable,2874 else => unreachable,
2879 }2875 }
2880 },2876 },
2877 .div_float => {
2878 switch (lhs_ty.zigTypeTag()) {
2879 .Float => return self.fail("TODO ARM binary operations on floats", .{}),
2880 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
2881 else => unreachable,
2882 }
2883 },
2884 .div_trunc, .div_floor => {
2885 switch (lhs_ty.zigTypeTag()) {
2886 .Float => return self.fail("TODO ARM binary operations on floats", .{}),
2887 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
2888 .Int => {
2889 const mod = self.bin_file.options.module.?;
2890 assert(lhs_ty.eql(rhs_ty, mod));
2891 const int_info = lhs_ty.intInfo(self.target.*);
2892 if (int_info.bits <= 32) {
2893 switch (int_info.signedness) {
2894 .signed => {
2895 return self.fail("TODO ARM signed integer division", .{});
2896 },
2897 .unsigned => {
2898 switch (rhs) {
2899 .immediate => |imm| {
2900 if (std.math.isPowerOfTwo(imm)) {
2901 const shift = MCValue{ .immediate = std.math.log2_int(u32, imm) };
2902 return try self.binOp(.shr, lhs, shift, lhs_ty, rhs_ty, metadata);
2903 } else {
2904 return self.fail("TODO ARM integer division by constants", .{});
2905 }
2906 },
2907 else => return self.fail("TODO ARM integer division", .{}),
2908 }
2909 },
2910 }
2911 } else {
2912 return self.fail("TODO ARM integer division for integers > u32/i32", .{});
2913 }
2914 },
2915 else => unreachable,
2916 }
2917 },
2918 .div_exact => {
2919 switch (lhs_ty.zigTypeTag()) {
2920 .Float => return self.fail("TODO ARM binary operations on floats", .{}),
2921 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
2922 .Int => return self.fail("TODO ARM div_exact", .{}),
2923 else => unreachable,
2924 }
2925 },
2881 .addwrap,2926 .addwrap,
2882 .subwrap,2927 .subwrap,
2883 .mulwrap,2928 .mulwrap,