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