Commit 4f1b8a5842 for qemu.org

commit 4f1b8a5842a390ee990df19ed060ade34bfb4875
Author: Brian Cain <brian.cain@oss.qualcomm.com>
Date:   Wed Sep 23 10:15:10 2026 -0700

    tcg: split out _var forms of gvec logical, abs and min/max ops

    target/hexagon is about to address its HVX register file through a
    runtime base pointer rather than a constant offset from env, in order to
    share one register file between several vCPUs.  The gvec ops it needs
    have no base-parameterized form yet.

    Split tcg_gen_gvec_{and,or,xor,andc,orc,not,abs,smin,umin,smax,umax}
    the same way tcg_gen_gvec_{add,sub,mov,dup_imm} already are: the work
    moves to a _var function taking a TCGv_ptr base per operand, and the
    existing entry point becomes a wrapper passing tcg_env.

    The aofs == bofs shortcuts also have to compare the bases, since equal
    offsets into different objects are not the same operand.

    Reviewed-by: Marco Liebel <marco.liebel@oss.qualcomm.com>
    Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
    Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>

diff --git a/include/tcg/tcg-op-gvec-common.h b/include/tcg/tcg-op-gvec-common.h
index ea0c87f4db..99a6685e8a 100644
--- a/include/tcg/tcg-op-gvec-common.h
+++ b/include/tcg/tcg-op-gvec-common.h
@@ -287,6 +287,13 @@ void tcg_gen_gvec_mov_var(unsigned vece, TCGv_ptr dbase, uint32_t dofs,
                           TCGv_ptr abase, uint32_t aofs,
                           uint32_t oprsz, uint32_t maxsz);

+void tcg_gen_gvec_not_var(unsigned vece, TCGv_ptr dbase, uint32_t dofs,
+                          TCGv_ptr abase, uint32_t aofs,
+                          uint32_t oprsz, uint32_t maxsz);
+void tcg_gen_gvec_abs_var(unsigned vece, TCGv_ptr dbase, uint32_t dofs,
+                          TCGv_ptr abase, uint32_t aofs,
+                          uint32_t oprsz, uint32_t maxsz);
+
 void tcg_gen_gvec_mov(unsigned vece, uint32_t dofs, uint32_t aofs,
                       uint32_t oprsz, uint32_t maxsz);
 void tcg_gen_gvec_not(unsigned vece, uint32_t dofs, uint32_t aofs,
@@ -335,6 +342,23 @@ void tcg_gen_gvec_ussub(unsigned vece, uint32_t dofs, uint32_t aofs,
                         uint32_t bofs, uint32_t oprsz, uint32_t maxsz);

 /* Min/max.  */
+void tcg_gen_gvec_smin_var(unsigned vece, TCGv_ptr dbase, uint32_t dofs,
+                           TCGv_ptr abase, uint32_t aofs,
+                           TCGv_ptr bbase, uint32_t bofs,
+                           uint32_t oprsz, uint32_t maxsz);
+void tcg_gen_gvec_umin_var(unsigned vece, TCGv_ptr dbase, uint32_t dofs,
+                           TCGv_ptr abase, uint32_t aofs,
+                           TCGv_ptr bbase, uint32_t bofs,
+                           uint32_t oprsz, uint32_t maxsz);
+void tcg_gen_gvec_smax_var(unsigned vece, TCGv_ptr dbase, uint32_t dofs,
+                           TCGv_ptr abase, uint32_t aofs,
+                           TCGv_ptr bbase, uint32_t bofs,
+                           uint32_t oprsz, uint32_t maxsz);
+void tcg_gen_gvec_umax_var(unsigned vece, TCGv_ptr dbase, uint32_t dofs,
+                           TCGv_ptr abase, uint32_t aofs,
+                           TCGv_ptr bbase, uint32_t bofs,
+                           uint32_t oprsz, uint32_t maxsz);
+
 void tcg_gen_gvec_smin(unsigned vece, uint32_t dofs, uint32_t aofs,
                        uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
 void tcg_gen_gvec_umin(unsigned vece, uint32_t dofs, uint32_t aofs,
@@ -344,6 +368,27 @@ void tcg_gen_gvec_smax(unsigned vece, uint32_t dofs, uint32_t aofs,
 void tcg_gen_gvec_umax(unsigned vece, uint32_t dofs, uint32_t aofs,
                        uint32_t bofs, uint32_t oprsz, uint32_t maxsz);

+void tcg_gen_gvec_and_var(unsigned vece, TCGv_ptr dbase, uint32_t dofs,
+                          TCGv_ptr abase, uint32_t aofs,
+                          TCGv_ptr bbase, uint32_t bofs,
+                          uint32_t oprsz, uint32_t maxsz);
+void tcg_gen_gvec_or_var(unsigned vece, TCGv_ptr dbase, uint32_t dofs,
+                         TCGv_ptr abase, uint32_t aofs,
+                         TCGv_ptr bbase, uint32_t bofs,
+                         uint32_t oprsz, uint32_t maxsz);
+void tcg_gen_gvec_xor_var(unsigned vece, TCGv_ptr dbase, uint32_t dofs,
+                          TCGv_ptr abase, uint32_t aofs,
+                          TCGv_ptr bbase, uint32_t bofs,
+                          uint32_t oprsz, uint32_t maxsz);
+void tcg_gen_gvec_andc_var(unsigned vece, TCGv_ptr dbase, uint32_t dofs,
+                           TCGv_ptr abase, uint32_t aofs,
+                           TCGv_ptr bbase, uint32_t bofs,
+                           uint32_t oprsz, uint32_t maxsz);
+void tcg_gen_gvec_orc_var(unsigned vece, TCGv_ptr dbase, uint32_t dofs,
+                          TCGv_ptr abase, uint32_t aofs,
+                          TCGv_ptr bbase, uint32_t bofs,
+                          uint32_t oprsz, uint32_t maxsz);
+
 void tcg_gen_gvec_and(unsigned vece, uint32_t dofs, uint32_t aofs,
                       uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
 void tcg_gen_gvec_or(unsigned vece, uint32_t dofs, uint32_t aofs,
diff --git a/tcg/tcg-op-gvec.c b/tcg/tcg-op-gvec.c
index 27f3807b00..191ac0fa86 100644
--- a/tcg/tcg-op-gvec.c
+++ b/tcg/tcg-op-gvec.c
@@ -1911,8 +1911,9 @@ void tcg_gen_gvec_dup_imm(unsigned vece, uint32_t dofs, uint32_t oprsz,
     tcg_gen_gvec_dup_imm_var(vece, tcg_env, dofs, oprsz, maxsz, x);
 }

-void tcg_gen_gvec_not(unsigned vece, uint32_t dofs, uint32_t aofs,
-                      uint32_t oprsz, uint32_t maxsz)
+void tcg_gen_gvec_not_var(unsigned vece, TCGv_ptr dbase, uint32_t dofs,
+                          TCGv_ptr abase, uint32_t aofs,
+                          uint32_t oprsz, uint32_t maxsz)
 {
     static const GVecGen2 g = {
         .fni8 = tcg_gen_not_i64,
@@ -1920,7 +1921,13 @@ void tcg_gen_gvec_not(unsigned vece, uint32_t dofs, uint32_t aofs,
         .fno = gen_helper_gvec_not,
         .prefer_i64 = true,
     };
-    tcg_gen_gvec_2(dofs, aofs, oprsz, maxsz, &g);
+    tcg_gen_gvec_2_var(dbase, dofs, abase, aofs, oprsz, maxsz, &g);
+}
+
+void tcg_gen_gvec_not(unsigned vece, uint32_t dofs, uint32_t aofs,
+                      uint32_t oprsz, uint32_t maxsz)
+{
+    tcg_gen_gvec_not_var(vece, tcg_env, dofs, tcg_env, aofs, oprsz, maxsz);
 }

 /* Perform a vector addition using normal addition and a mask.  The mask
@@ -2427,8 +2434,10 @@ void tcg_gen_gvec_ussub(unsigned vece, uint32_t dofs, uint32_t aofs,
     tcg_gen_gvec_3(dofs, aofs, bofs, oprsz, maxsz, &g[vece]);
 }

-void tcg_gen_gvec_smin(unsigned vece, uint32_t dofs, uint32_t aofs,
-                       uint32_t bofs, uint32_t oprsz, uint32_t maxsz)
+void tcg_gen_gvec_smin_var(unsigned vece, TCGv_ptr dbase, uint32_t dofs,
+                           TCGv_ptr abase, uint32_t aofs,
+                           TCGv_ptr bbase, uint32_t bofs,
+                           uint32_t oprsz, uint32_t maxsz)
 {
     static const TCGOpcode vecop_list[] = { INDEX_op_smin_vec, 0 };
     static const GVecGen3 g[4] = {
@@ -2452,11 +2461,21 @@ void tcg_gen_gvec_smin(unsigned vece, uint32_t dofs, uint32_t aofs,
           .vece = MO_64 }
     };
     tcg_debug_assert(vece <= MO_64);
-    tcg_gen_gvec_3(dofs, aofs, bofs, oprsz, maxsz, &g[vece]);
+    tcg_gen_gvec_3_var(dbase, dofs, abase, aofs, bbase, bofs,
+                       oprsz, maxsz, &g[vece]);
 }

-void tcg_gen_gvec_umin(unsigned vece, uint32_t dofs, uint32_t aofs,
+void tcg_gen_gvec_smin(unsigned vece, uint32_t dofs, uint32_t aofs,
                        uint32_t bofs, uint32_t oprsz, uint32_t maxsz)
+{
+    tcg_gen_gvec_smin_var(vece, tcg_env, dofs, tcg_env, aofs,
+                          tcg_env, bofs, oprsz, maxsz);
+}
+
+void tcg_gen_gvec_umin_var(unsigned vece, TCGv_ptr dbase, uint32_t dofs,
+                           TCGv_ptr abase, uint32_t aofs,
+                           TCGv_ptr bbase, uint32_t bofs,
+                           uint32_t oprsz, uint32_t maxsz)
 {
     static const TCGOpcode vecop_list[] = { INDEX_op_umin_vec, 0 };
     static const GVecGen3 g[4] = {
@@ -2480,11 +2499,21 @@ void tcg_gen_gvec_umin(unsigned vece, uint32_t dofs, uint32_t aofs,
           .vece = MO_64 }
     };
     tcg_debug_assert(vece <= MO_64);
-    tcg_gen_gvec_3(dofs, aofs, bofs, oprsz, maxsz, &g[vece]);
+    tcg_gen_gvec_3_var(dbase, dofs, abase, aofs, bbase, bofs,
+                       oprsz, maxsz, &g[vece]);
 }

-void tcg_gen_gvec_smax(unsigned vece, uint32_t dofs, uint32_t aofs,
+void tcg_gen_gvec_umin(unsigned vece, uint32_t dofs, uint32_t aofs,
                        uint32_t bofs, uint32_t oprsz, uint32_t maxsz)
+{
+    tcg_gen_gvec_umin_var(vece, tcg_env, dofs, tcg_env, aofs,
+                          tcg_env, bofs, oprsz, maxsz);
+}
+
+void tcg_gen_gvec_smax_var(unsigned vece, TCGv_ptr dbase, uint32_t dofs,
+                           TCGv_ptr abase, uint32_t aofs,
+                           TCGv_ptr bbase, uint32_t bofs,
+                           uint32_t oprsz, uint32_t maxsz)
 {
     static const TCGOpcode vecop_list[] = { INDEX_op_smax_vec, 0 };
     static const GVecGen3 g[4] = {
@@ -2508,11 +2537,21 @@ void tcg_gen_gvec_smax(unsigned vece, uint32_t dofs, uint32_t aofs,
           .vece = MO_64 }
     };
     tcg_debug_assert(vece <= MO_64);
-    tcg_gen_gvec_3(dofs, aofs, bofs, oprsz, maxsz, &g[vece]);
+    tcg_gen_gvec_3_var(dbase, dofs, abase, aofs, bbase, bofs,
+                       oprsz, maxsz, &g[vece]);
 }

-void tcg_gen_gvec_umax(unsigned vece, uint32_t dofs, uint32_t aofs,
+void tcg_gen_gvec_smax(unsigned vece, uint32_t dofs, uint32_t aofs,
                        uint32_t bofs, uint32_t oprsz, uint32_t maxsz)
+{
+    tcg_gen_gvec_smax_var(vece, tcg_env, dofs, tcg_env, aofs,
+                          tcg_env, bofs, oprsz, maxsz);
+}
+
+void tcg_gen_gvec_umax_var(unsigned vece, TCGv_ptr dbase, uint32_t dofs,
+                           TCGv_ptr abase, uint32_t aofs,
+                           TCGv_ptr bbase, uint32_t bofs,
+                           uint32_t oprsz, uint32_t maxsz)
 {
     static const TCGOpcode vecop_list[] = { INDEX_op_umax_vec, 0 };
     static const GVecGen3 g[4] = {
@@ -2536,7 +2575,15 @@ void tcg_gen_gvec_umax(unsigned vece, uint32_t dofs, uint32_t aofs,
           .vece = MO_64 }
     };
     tcg_debug_assert(vece <= MO_64);
-    tcg_gen_gvec_3(dofs, aofs, bofs, oprsz, maxsz, &g[vece]);
+    tcg_gen_gvec_3_var(dbase, dofs, abase, aofs, bbase, bofs,
+                       oprsz, maxsz, &g[vece]);
+}
+
+void tcg_gen_gvec_umax(unsigned vece, uint32_t dofs, uint32_t aofs,
+                       uint32_t bofs, uint32_t oprsz, uint32_t maxsz)
+{
+    tcg_gen_gvec_umax_var(vece, tcg_env, dofs, tcg_env, aofs,
+                          tcg_env, bofs, oprsz, maxsz);
 }

 /* Perform a vector negation using normal negation and a mask.
@@ -2645,8 +2692,9 @@ static void tcg_gen_vec_abs16_i64(TCGv_i64 d, TCGv_i64 b)
     gen_absv_mask(d, b, MO_16);
 }

-void tcg_gen_gvec_abs(unsigned vece, uint32_t dofs, uint32_t aofs,
-                      uint32_t oprsz, uint32_t maxsz)
+void tcg_gen_gvec_abs_var(unsigned vece, TCGv_ptr dbase, uint32_t dofs,
+                          TCGv_ptr abase, uint32_t aofs,
+                          uint32_t oprsz, uint32_t maxsz)
 {
     static const TCGOpcode vecop_list[] = { INDEX_op_abs_vec, 0 };
     static const GVecGen2 g[4] = {
@@ -2674,11 +2722,19 @@ void tcg_gen_gvec_abs(unsigned vece, uint32_t dofs, uint32_t aofs,
     };

     tcg_debug_assert(vece <= MO_64);
-    tcg_gen_gvec_2(dofs, aofs, oprsz, maxsz, &g[vece]);
+    tcg_gen_gvec_2_var(dbase, dofs, abase, aofs, oprsz, maxsz, &g[vece]);
 }

-void tcg_gen_gvec_and(unsigned vece, uint32_t dofs, uint32_t aofs,
-                      uint32_t bofs, uint32_t oprsz, uint32_t maxsz)
+void tcg_gen_gvec_abs(unsigned vece, uint32_t dofs, uint32_t aofs,
+                      uint32_t oprsz, uint32_t maxsz)
+{
+    tcg_gen_gvec_abs_var(vece, tcg_env, dofs, tcg_env, aofs, oprsz, maxsz);
+}
+
+void tcg_gen_gvec_and_var(unsigned vece, TCGv_ptr dbase, uint32_t dofs,
+                          TCGv_ptr abase, uint32_t aofs,
+                          TCGv_ptr bbase, uint32_t bofs,
+                          uint32_t oprsz, uint32_t maxsz)
 {
     static const GVecGen3 g = {
         .fni8 = tcg_gen_and_i64,
@@ -2687,15 +2743,25 @@ void tcg_gen_gvec_and(unsigned vece, uint32_t dofs, uint32_t aofs,
         .prefer_i64 = true,
     };

-    if (aofs == bofs) {
-        tcg_gen_gvec_mov(vece, dofs, aofs, oprsz, maxsz);
+    if (abase == bbase && aofs == bofs) {
+        tcg_gen_gvec_mov_var(vece, dbase, dofs, abase, aofs, oprsz, maxsz);
     } else {
-        tcg_gen_gvec_3(dofs, aofs, bofs, oprsz, maxsz, &g);
+        tcg_gen_gvec_3_var(dbase, dofs, abase, aofs, bbase, bofs,
+                           oprsz, maxsz, &g);
     }
 }

-void tcg_gen_gvec_or(unsigned vece, uint32_t dofs, uint32_t aofs,
-                     uint32_t bofs, uint32_t oprsz, uint32_t maxsz)
+void tcg_gen_gvec_and(unsigned vece, uint32_t dofs, uint32_t aofs,
+                      uint32_t bofs, uint32_t oprsz, uint32_t maxsz)
+{
+    tcg_gen_gvec_and_var(vece, tcg_env, dofs, tcg_env, aofs, tcg_env, bofs,
+                         oprsz, maxsz);
+}
+
+void tcg_gen_gvec_or_var(unsigned vece, TCGv_ptr dbase, uint32_t dofs,
+                         TCGv_ptr abase, uint32_t aofs,
+                         TCGv_ptr bbase, uint32_t bofs,
+                         uint32_t oprsz, uint32_t maxsz)
 {
     static const GVecGen3 g = {
         .fni8 = tcg_gen_or_i64,
@@ -2704,15 +2770,25 @@ void tcg_gen_gvec_or(unsigned vece, uint32_t dofs, uint32_t aofs,
         .prefer_i64 = true,
     };

-    if (aofs == bofs) {
-        tcg_gen_gvec_mov(vece, dofs, aofs, oprsz, maxsz);
+    if (abase == bbase && aofs == bofs) {
+        tcg_gen_gvec_mov_var(vece, dbase, dofs, abase, aofs, oprsz, maxsz);
     } else {
-        tcg_gen_gvec_3(dofs, aofs, bofs, oprsz, maxsz, &g);
+        tcg_gen_gvec_3_var(dbase, dofs, abase, aofs, bbase, bofs,
+                           oprsz, maxsz, &g);
     }
 }

-void tcg_gen_gvec_xor(unsigned vece, uint32_t dofs, uint32_t aofs,
-                      uint32_t bofs, uint32_t oprsz, uint32_t maxsz)
+void tcg_gen_gvec_or(unsigned vece, uint32_t dofs, uint32_t aofs,
+                     uint32_t bofs, uint32_t oprsz, uint32_t maxsz)
+{
+    tcg_gen_gvec_or_var(vece, tcg_env, dofs, tcg_env, aofs, tcg_env, bofs,
+                        oprsz, maxsz);
+}
+
+void tcg_gen_gvec_xor_var(unsigned vece, TCGv_ptr dbase, uint32_t dofs,
+                          TCGv_ptr abase, uint32_t aofs,
+                          TCGv_ptr bbase, uint32_t bofs,
+                          uint32_t oprsz, uint32_t maxsz)
 {
     static const GVecGen3 g = {
         .fni8 = tcg_gen_xor_i64,
@@ -2721,15 +2797,25 @@ void tcg_gen_gvec_xor(unsigned vece, uint32_t dofs, uint32_t aofs,
         .prefer_i64 = true,
     };

-    if (aofs == bofs) {
-        tcg_gen_gvec_dup_imm(MO_64, dofs, oprsz, maxsz, 0);
+    if (abase == bbase && aofs == bofs) {
+        tcg_gen_gvec_dup_imm_var(MO_64, dbase, dofs, oprsz, maxsz, 0);
     } else {
-        tcg_gen_gvec_3(dofs, aofs, bofs, oprsz, maxsz, &g);
+        tcg_gen_gvec_3_var(dbase, dofs, abase, aofs, bbase, bofs,
+                           oprsz, maxsz, &g);
     }
 }

-void tcg_gen_gvec_andc(unsigned vece, uint32_t dofs, uint32_t aofs,
-                       uint32_t bofs, uint32_t oprsz, uint32_t maxsz)
+void tcg_gen_gvec_xor(unsigned vece, uint32_t dofs, uint32_t aofs,
+                      uint32_t bofs, uint32_t oprsz, uint32_t maxsz)
+{
+    tcg_gen_gvec_xor_var(vece, tcg_env, dofs, tcg_env, aofs, tcg_env, bofs,
+                         oprsz, maxsz);
+}
+
+void tcg_gen_gvec_andc_var(unsigned vece, TCGv_ptr dbase, uint32_t dofs,
+                           TCGv_ptr abase, uint32_t aofs,
+                           TCGv_ptr bbase, uint32_t bofs,
+                           uint32_t oprsz, uint32_t maxsz)
 {
     static const GVecGen3 g = {
         .fni8 = tcg_gen_andc_i64,
@@ -2738,15 +2824,25 @@ void tcg_gen_gvec_andc(unsigned vece, uint32_t dofs, uint32_t aofs,
         .prefer_i64 = true,
     };

-    if (aofs == bofs) {
-        tcg_gen_gvec_dup_imm(MO_64, dofs, oprsz, maxsz, 0);
+    if (abase == bbase && aofs == bofs) {
+        tcg_gen_gvec_dup_imm_var(MO_64, dbase, dofs, oprsz, maxsz, 0);
     } else {
-        tcg_gen_gvec_3(dofs, aofs, bofs, oprsz, maxsz, &g);
+        tcg_gen_gvec_3_var(dbase, dofs, abase, aofs, bbase, bofs,
+                           oprsz, maxsz, &g);
     }
 }

-void tcg_gen_gvec_orc(unsigned vece, uint32_t dofs, uint32_t aofs,
-                      uint32_t bofs, uint32_t oprsz, uint32_t maxsz)
+void tcg_gen_gvec_andc(unsigned vece, uint32_t dofs, uint32_t aofs,
+                       uint32_t bofs, uint32_t oprsz, uint32_t maxsz)
+{
+    tcg_gen_gvec_andc_var(vece, tcg_env, dofs, tcg_env, aofs, tcg_env, bofs,
+                          oprsz, maxsz);
+}
+
+void tcg_gen_gvec_orc_var(unsigned vece, TCGv_ptr dbase, uint32_t dofs,
+                          TCGv_ptr abase, uint32_t aofs,
+                          TCGv_ptr bbase, uint32_t bofs,
+                          uint32_t oprsz, uint32_t maxsz)
 {
     static const GVecGen3 g = {
         .fni8 = tcg_gen_orc_i64,
@@ -2755,13 +2851,21 @@ void tcg_gen_gvec_orc(unsigned vece, uint32_t dofs, uint32_t aofs,
         .prefer_i64 = true,
     };

-    if (aofs == bofs) {
-        tcg_gen_gvec_dup_imm(MO_64, dofs, oprsz, maxsz, -1);
+    if (abase == bbase && aofs == bofs) {
+        tcg_gen_gvec_dup_imm_var(MO_64, dbase, dofs, oprsz, maxsz, -1);
     } else {
-        tcg_gen_gvec_3(dofs, aofs, bofs, oprsz, maxsz, &g);
+        tcg_gen_gvec_3_var(dbase, dofs, abase, aofs, bbase, bofs,
+                           oprsz, maxsz, &g);
     }
 }

+void tcg_gen_gvec_orc(unsigned vece, uint32_t dofs, uint32_t aofs,
+                      uint32_t bofs, uint32_t oprsz, uint32_t maxsz)
+{
+    tcg_gen_gvec_orc_var(vece, tcg_env, dofs, tcg_env, aofs, tcg_env, bofs,
+                         oprsz, maxsz);
+}
+
 void tcg_gen_gvec_nand(unsigned vece, uint32_t dofs, uint32_t aofs,
                        uint32_t bofs, uint32_t oprsz, uint32_t maxsz)
 {