authorgravatar for david@vortan.devDavid Rubin <david@vortan.dev> 2024-07-16 01:48:55-07:00
committergravatar for david@vortan.devDavid Rubin <david@vortan.dev> 2024-07-26 04:05:42-07:00
log6ac1b2d82ae5ea1067117031d52799bf86a5b2b8
treebe4316332f924b16a9144b528ebc985040c08d93
parent1820f4410450a0dfa35eafefa217465f762e26fd
signaturelock-open Commit is signed but in an unrecognized format.

riscv: add 32-bit support to integer `@abs`


1 files changed, 71 insertions(+), 51 deletions(-)

src/arch/riscv64/CodeGen.zig+71-51
...@@ -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);
26892691
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);
26922694
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 });
27022704
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 });
27122714
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 });
27222724
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 });
27322734
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;
38573869
...@@ -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);
38603872
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 });
38703886
...@@ -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 });
38803896
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,