| ... | @@ -567,6 +567,12 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -567,6 +567,12 @@ 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), |
| | 574 | .rem => try self.airBinOp(inst, .rem), |
| | 575 | .mod => try self.airBinOp(inst, .mod), |
| 570 | | 576 | |
| 571 | .ptr_add => try self.airPtrArithmetic(inst, .ptr_add), | 577 | .ptr_add => try self.airPtrArithmetic(inst, .ptr_add), |
| 572 | .ptr_sub => try self.airPtrArithmetic(inst, .ptr_sub), | 578 | .ptr_sub => try self.airPtrArithmetic(inst, .ptr_sub), |
| ... | @@ -577,8 +583,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -577,8 +583,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 577 | .add_sat => try self.airAddSat(inst), | 583 | .add_sat => try self.airAddSat(inst), |
| 578 | .sub_sat => try self.airSubSat(inst), | 584 | .sub_sat => try self.airSubSat(inst), |
| 579 | .mul_sat => try self.airMulSat(inst), | 585 | .mul_sat => try self.airMulSat(inst), |
| 580 | .rem => try self.airRem(inst), | | |
| 581 | .mod => try self.airMod(inst), | | |
| 582 | .shl_sat => try self.airShlSat(inst), | 586 | .shl_sat => try self.airShlSat(inst), |
| 583 | .slice => try self.airSlice(inst), | 587 | .slice => try self.airSlice(inst), |
| 584 | | 588 | |
| ... | @@ -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), |
| 606 | | 610 | |
| 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,24 +1731,6 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1729,24 +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 | } |
| 1731 | | 1733 | |
| 1732 | fn 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 | | | |
| 1738 | fn airRem(self: *Self, inst: Air.Inst.Index) !void { | | |
| 1739 | 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}); | | |
| 1741 | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); | | |
| 1742 | } | | |
| 1743 | | | |
| 1744 | fn airMod(self: *Self, inst: Air.Inst.Index) !void { | | |
| 1745 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; | | |
| 1746 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement mod for {}", .{self.target.cpu.arch}); | | |
| 1747 | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); | | |
| 1748 | } | | |
| 1749 | | | |
| 1750 | fn airShlSat(self: *Self, inst: Air.Inst.Index) !void { | 1734 | fn airShlSat(self: *Self, inst: Air.Inst.Index) !void { |
| 1751 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; | 1735 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 1752 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement shl_sat for {}", .{self.target.cpu.arch}); | 1736 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement shl_sat for {}", .{self.target.cpu.arch}); |
| ... | @@ -2878,6 +2862,127 @@ fn binOp( | ... | @@ -2878,6 +2862,127 @@ fn binOp( |
| 2878 | else => unreachable, | 2862 | else => unreachable, |
| 2879 | } | 2863 | } |
| 2880 | }, | 2864 | }, |
| | 2865 | .div_float => { |
| | 2866 | switch (lhs_ty.zigTypeTag()) { |
| | 2867 | .Float => return self.fail("TODO ARM binary operations on floats", .{}), |
| | 2868 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), |
| | 2869 | else => unreachable, |
| | 2870 | } |
| | 2871 | }, |
| | 2872 | .div_trunc, .div_floor => { |
| | 2873 | switch (lhs_ty.zigTypeTag()) { |
| | 2874 | .Float => return self.fail("TODO ARM binary operations on floats", .{}), |
| | 2875 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), |
| | 2876 | .Int => { |
| | 2877 | const mod = self.bin_file.options.module.?; |
| | 2878 | assert(lhs_ty.eql(rhs_ty, mod)); |
| | 2879 | const int_info = lhs_ty.intInfo(self.target.*); |
| | 2880 | if (int_info.bits <= 32) { |
| | 2881 | switch (int_info.signedness) { |
| | 2882 | .signed => { |
| | 2883 | return self.fail("TODO ARM signed integer division", .{}); |
| | 2884 | }, |
| | 2885 | .unsigned => { |
| | 2886 | switch (rhs) { |
| | 2887 | .immediate => |imm| { |
| | 2888 | if (std.math.isPowerOfTwo(imm)) { |
| | 2889 | const shift = MCValue{ .immediate = std.math.log2_int(u32, imm) }; |
| | 2890 | return try self.binOp(.shr, lhs, shift, lhs_ty, rhs_ty, metadata); |
| | 2891 | } else { |
| | 2892 | return self.fail("TODO ARM integer division by constants", .{}); |
| | 2893 | } |
| | 2894 | }, |
| | 2895 | else => return self.fail("TODO ARM integer division", .{}), |
| | 2896 | } |
| | 2897 | }, |
| | 2898 | } |
| | 2899 | } else { |
| | 2900 | return self.fail("TODO ARM integer division for integers > u32/i32", .{}); |
| | 2901 | } |
| | 2902 | }, |
| | 2903 | else => unreachable, |
| | 2904 | } |
| | 2905 | }, |
| | 2906 | .div_exact => { |
| | 2907 | switch (lhs_ty.zigTypeTag()) { |
| | 2908 | .Float => return self.fail("TODO ARM binary operations on floats", .{}), |
| | 2909 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), |
| | 2910 | .Int => return self.fail("TODO ARM div_exact", .{}), |
| | 2911 | else => unreachable, |
| | 2912 | } |
| | 2913 | }, |
| | 2914 | .rem => { |
| | 2915 | switch (lhs_ty.zigTypeTag()) { |
| | 2916 | .Float => return self.fail("TODO ARM binary operations on floats", .{}), |
| | 2917 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), |
| | 2918 | .Int => { |
| | 2919 | const mod = self.bin_file.options.module.?; |
| | 2920 | assert(lhs_ty.eql(rhs_ty, mod)); |
| | 2921 | const int_info = lhs_ty.intInfo(self.target.*); |
| | 2922 | if (int_info.bits <= 32) { |
| | 2923 | switch (int_info.signedness) { |
| | 2924 | .signed => { |
| | 2925 | return self.fail("TODO ARM signed integer mod", .{}); |
| | 2926 | }, |
| | 2927 | .unsigned => { |
| | 2928 | switch (rhs) { |
| | 2929 | .immediate => |imm| { |
| | 2930 | if (std.math.isPowerOfTwo(imm)) { |
| | 2931 | const log2 = std.math.log2_int(u32, imm); |
| | 2932 | |
| | 2933 | const lhs_is_register = lhs == .register; |
| | 2934 | |
| | 2935 | const lhs_lock: ?RegisterLock = if (lhs_is_register) |
| | 2936 | self.register_manager.lockReg(lhs.register) |
| | 2937 | else |
| | 2938 | null; |
| | 2939 | defer if (lhs_lock) |reg| self.register_manager.unlockReg(reg); |
| | 2940 | |
| | 2941 | const lhs_reg = if (lhs_is_register) lhs.register else blk: { |
| | 2942 | const track_inst: ?Air.Inst.Index = if (metadata) |md| inst: { |
| | 2943 | break :inst Air.refToIndex(md.lhs).?; |
| | 2944 | } else null; |
| | 2945 | |
| | 2946 | break :blk try self.prepareNewRegForMoving(track_inst, gp, lhs); |
| | 2947 | }; |
| | 2948 | const new_lhs_lock = self.register_manager.lockReg(lhs_reg); |
| | 2949 | defer if (new_lhs_lock) |reg| self.register_manager.unlockReg(reg); |
| | 2950 | |
| | 2951 | const dest_reg = if (metadata) |md| blk: { |
| | 2952 | if (lhs_is_register and self.reuseOperand(md.inst, md.lhs, 0, lhs)) { |
| | 2953 | break :blk lhs_reg; |
| | 2954 | } else { |
| | 2955 | break :blk try self.register_manager.allocReg(md.inst, gp); |
| | 2956 | } |
| | 2957 | } else try self.register_manager.allocReg(null, gp); |
| | 2958 | |
| | 2959 | if (!lhs_is_register) try self.genSetReg(lhs_ty, lhs_reg, lhs); |
| | 2960 | |
| | 2961 | try self.truncRegister(lhs_reg, dest_reg, int_info.signedness, log2); |
| | 2962 | return MCValue{ .register = dest_reg }; |
| | 2963 | } else { |
| | 2964 | return self.fail("TODO ARM integer mod by constants", .{}); |
| | 2965 | } |
| | 2966 | }, |
| | 2967 | else => return self.fail("TODO ARM integer mod", .{}), |
| | 2968 | } |
| | 2969 | }, |
| | 2970 | } |
| | 2971 | } else { |
| | 2972 | return self.fail("TODO ARM integer division for integers > u32/i32", .{}); |
| | 2973 | } |
| | 2974 | }, |
| | 2975 | else => unreachable, |
| | 2976 | } |
| | 2977 | }, |
| | 2978 | .mod => { |
| | 2979 | switch (lhs_ty.zigTypeTag()) { |
| | 2980 | .Float => return self.fail("TODO ARM binary operations on floats", .{}), |
| | 2981 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), |
| | 2982 | .Int => return self.fail("TODO ARM mod", .{}), |
| | 2983 | else => unreachable, |
| | 2984 | } |
| | 2985 | }, |
| 2881 | .addwrap, | 2986 | .addwrap, |
| 2882 | .subwrap, | 2987 | .subwrap, |
| 2883 | .mulwrap, | 2988 | .mulwrap, |