| ... | ... | @@ -2685,60 +2685,65 @@ fn genBinOp( |
| 2685 | 2685 | // a1, s0 was -1, flipping all the bits in a2 and effectively restoring a0. If a0 was greater than or equal to a1, |
| 2686 | 2686 | // s0 was 0, leaving a2 unchanged as a0. |
| 2687 | 2687 | .min, .max => { |
| 2688 | | const int_info = lhs_ty.intInfo(zcu); |
| 2688 | switch (lhs_ty.zigTypeTag(zcu)) { |
| 2689 | .Int => { |
| 2690 | const int_info = lhs_ty.intInfo(zcu); |
| 2689 | 2691 | |
| 2690 | | const mask_reg, const mask_lock = try func.allocReg(.int); |
| 2691 | | defer func.register_manager.unlockReg(mask_lock); |
| 2692 | const mask_reg, const mask_lock = try func.allocReg(.int); |
| 2693 | defer func.register_manager.unlockReg(mask_lock); |
| 2692 | 2694 | |
| 2693 | | _ = try func.addInst(.{ |
| 2694 | | .tag = if (int_info.signedness == .unsigned) .sltu else .slt, |
| 2695 | | .ops = .rrr, |
| 2696 | | .data = .{ .r_type = .{ |
| 2697 | | .rd = mask_reg, |
| 2698 | | .rs1 = lhs_reg, |
| 2699 | | .rs2 = rhs_reg, |
| 2700 | | } }, |
| 2701 | | }); |
| 2695 | _ = try func.addInst(.{ |
| 2696 | .tag = if (int_info.signedness == .unsigned) .sltu else .slt, |
| 2697 | .ops = .rrr, |
| 2698 | .data = .{ .r_type = .{ |
| 2699 | .rd = mask_reg, |
| 2700 | .rs1 = lhs_reg, |
| 2701 | .rs2 = rhs_reg, |
| 2702 | } }, |
| 2703 | }); |
| 2702 | 2704 | |
| 2703 | | _ = try func.addInst(.{ |
| 2704 | | .tag = .sub, |
| 2705 | | .ops = .rrr, |
| 2706 | | .data = .{ .r_type = .{ |
| 2707 | | .rd = mask_reg, |
| 2708 | | .rs1 = .zero, |
| 2709 | | .rs2 = mask_reg, |
| 2710 | | } }, |
| 2711 | | }); |
| 2705 | _ = try func.addInst(.{ |
| 2706 | .tag = .sub, |
| 2707 | .ops = .rrr, |
| 2708 | .data = .{ .r_type = .{ |
| 2709 | .rd = mask_reg, |
| 2710 | .rs1 = .zero, |
| 2711 | .rs2 = mask_reg, |
| 2712 | } }, |
| 2713 | }); |
| 2712 | 2714 | |
| 2713 | | _ = try func.addInst(.{ |
| 2714 | | .tag = .xor, |
| 2715 | | .ops = .rrr, |
| 2716 | | .data = .{ .r_type = .{ |
| 2717 | | .rd = dst_reg, |
| 2718 | | .rs1 = lhs_reg, |
| 2719 | | .rs2 = rhs_reg, |
| 2720 | | } }, |
| 2721 | | }); |
| 2715 | _ = try func.addInst(.{ |
| 2716 | .tag = .xor, |
| 2717 | .ops = .rrr, |
| 2718 | .data = .{ .r_type = .{ |
| 2719 | .rd = dst_reg, |
| 2720 | .rs1 = lhs_reg, |
| 2721 | .rs2 = rhs_reg, |
| 2722 | } }, |
| 2723 | }); |
| 2722 | 2724 | |
| 2723 | | _ = try func.addInst(.{ |
| 2724 | | .tag = .@"and", |
| 2725 | | .ops = .rrr, |
| 2726 | | .data = .{ .r_type = .{ |
| 2727 | | .rd = mask_reg, |
| 2728 | | .rs1 = dst_reg, |
| 2729 | | .rs2 = mask_reg, |
| 2730 | | } }, |
| 2731 | | }); |
| 2725 | _ = try func.addInst(.{ |
| 2726 | .tag = .@"and", |
| 2727 | .ops = .rrr, |
| 2728 | .data = .{ .r_type = .{ |
| 2729 | .rd = mask_reg, |
| 2730 | .rs1 = dst_reg, |
| 2731 | .rs2 = mask_reg, |
| 2732 | } }, |
| 2733 | }); |
| 2732 | 2734 | |
| 2733 | | _ = try func.addInst(.{ |
| 2734 | | .tag = .xor, |
| 2735 | | .ops = .rrr, |
| 2736 | | .data = .{ .r_type = .{ |
| 2737 | | .rd = dst_reg, |
| 2738 | | .rs1 = if (tag == .min) rhs_reg else lhs_reg, |
| 2739 | | .rs2 = mask_reg, |
| 2740 | | } }, |
| 2741 | | }); |
| 2735 | _ = try func.addInst(.{ |
| 2736 | .tag = .xor, |
| 2737 | .ops = .rrr, |
| 2738 | .data = .{ .r_type = .{ |
| 2739 | .rd = dst_reg, |
| 2740 | .rs1 = if (tag == .min) rhs_reg else lhs_reg, |
| 2741 | .rs2 = mask_reg, |
| 2742 | } }, |
| 2743 | }); |
| 2744 | }, |
| 2745 | else => |t| return func.fail("TODO: genBinOp min/max for {s}", .{@tagName(t)}), |
| 2746 | } |
| 2742 | 2747 | }, |
| 2743 | 2748 | else => return func.fail("TODO: genBinOp {}", .{tag}), |
| 2744 | 2749 | } |
| ... | ... | @@ -3852,6 +3857,13 @@ fn airAbs(func: *Func, inst: Air.Inst.Index) !void { |
| 3852 | 3857 | .Int => if (ty.zigTypeTag(zcu) == .Vector) { |
| 3853 | 3858 | return func.fail("TODO implement airAbs for {}", .{ty.fmt(pt)}); |
| 3854 | 3859 | } else { |
| 3860 | const int_info = scalar_ty.intInfo(zcu); |
| 3861 | const int_bits = int_info.bits; |
| 3862 | switch (int_bits) { |
| 3863 | 32, 64 => {}, |
| 3864 | else => return func.fail("TODO: airAbs Int size {d}", .{int_bits}), |
| 3865 | } |
| 3866 | |
| 3855 | 3867 | const return_mcv = try func.copyToNewRegister(inst, operand); |
| 3856 | 3868 | const operand_reg = return_mcv.register; |
| 3857 | 3869 | |
| ... | ... | @@ -3859,12 +3871,16 @@ fn airAbs(func: *Func, inst: Air.Inst.Index) !void { |
| 3859 | 3871 | defer func.register_manager.unlockReg(temp_lock); |
| 3860 | 3872 | |
| 3861 | 3873 | _ = try func.addInst(.{ |
| 3862 | | .tag = .srai, |
| 3874 | .tag = switch (int_bits) { |
| 3875 | 32 => .sraiw, |
| 3876 | 64 => .srai, |
| 3877 | else => unreachable, |
| 3878 | }, |
| 3863 | 3879 | .ops = .rri, |
| 3864 | 3880 | .data = .{ .i_type = .{ |
| 3865 | 3881 | .rd = temp_reg, |
| 3866 | 3882 | .rs1 = operand_reg, |
| 3867 | | .imm12 = Immediate.u(63), |
| 3883 | .imm12 = Immediate.u(int_bits - 1), |
| 3868 | 3884 | } }, |
| 3869 | 3885 | }); |
| 3870 | 3886 | |
| ... | ... | @@ -3879,7 +3895,11 @@ fn airAbs(func: *Func, inst: Air.Inst.Index) !void { |
| 3879 | 3895 | }); |
| 3880 | 3896 | |
| 3881 | 3897 | _ = try func.addInst(.{ |
| 3882 | | .tag = .sub, |
| 3898 | .tag = switch (int_bits) { |
| 3899 | 32 => .subw, |
| 3900 | 64 => .sub, |
| 3901 | else => unreachable, |
| 3902 | }, |
| 3883 | 3903 | .ops = .rrr, |
| 3884 | 3904 | .data = .{ .r_type = .{ |
| 3885 | 3905 | .rd = operand_reg, |