From: Brian Cain <brian.cain@oss.qualcomm.com>
To: qemu-devel@nongnu.org
Cc: "Philippe Mathieu-Daudé" <philmd@oss.qualcomm.com>,
"Pierrick Bouvier" <pierrick.bouvier@oss.qualcomm.com>,
"Brian Cain" <brian.cain@oss.qualcomm.com>,
marco.liebel@oss.qualcomm.com, "Helge Deller" <deller@gmx.de>,
"Paolo Bonzini" <pbonzini@redhat.com>,
richard.henderson@linaro.org,
"Laurent Vivier" <laurent@vivier.eu>
Subject: [PATCH v3 3/6] tcg: split out _var forms of gvec saturating/mul/shift-immediate ops
Date: Sun, 13 Sep 2026 08:59:25 -0700 [thread overview]
Message-ID: <20260913155928.365928-4-brian.cain@oss.qualcomm.com> (raw)
In-Reply-To: <20260913155928.365928-1-brian.cain@oss.qualcomm.com>
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. Split the other
gvec op families it needs like tcg_gen_gvec_{add,sub,mov,and,etc}.
Add tcg_gen_gvec_{ssadd,sssub,usadd,ussub,mul}_var and
tcg_gen_gvec_{shri,sari}_var, plus the tcg_gen_gvec_2i_var plumbing the
immediate-shift forms are built on.
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>
---
include/tcg/tcg-op-gvec-common.h | 31 ++++++
tcg/tcg-op-gvec.c | 177 ++++++++++++++++++++++---------
2 files changed, 160 insertions(+), 48 deletions(-)
diff --git a/include/tcg/tcg-op-gvec-common.h b/include/tcg/tcg-op-gvec-common.h
index fa28ebdde0f..6d3c2bae57a 100644
--- a/include/tcg/tcg-op-gvec-common.h
+++ b/include/tcg/tcg-op-gvec-common.h
@@ -234,6 +234,10 @@ void tcg_gen_gvec_2_var(TCGv_ptr dbase, uint32_t dofs,
/* Similarly, expand (env+dofs) = op(env+aofs). */
void tcg_gen_gvec_2(uint32_t dofs, uint32_t aofs,
uint32_t oprsz, uint32_t maxsz, const GVecGen2 *op);
+/* Expand (dbase+dofs) = op(abase+aofs, c), clearing @oprsz..@maxsz. */
+void tcg_gen_gvec_2i_var(TCGv_ptr dbase, uint32_t dofs,
+ TCGv_ptr abase, uint32_t aofs, uint32_t oprsz,
+ uint32_t maxsz, int64_t c, const GVecGen2i *op);
/* Similarly, expand (env+dofs) = op(env+aofs, c). */
void tcg_gen_gvec_2i(uint32_t dofs, uint32_t aofs, uint32_t oprsz,
uint32_t maxsz, int64_t c, const GVecGen2i *op);
@@ -315,6 +319,10 @@ void tcg_gen_gvec_sub_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_mul_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_add(unsigned vece, uint32_t dofs, uint32_t aofs,
uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
@@ -336,6 +344,23 @@ void tcg_gen_gvec_muls(unsigned vece, uint32_t dofs, uint32_t aofs,
TCGv_i64 c, uint32_t oprsz, uint32_t maxsz);
/* Saturated arithmetic. */
+void tcg_gen_gvec_ssadd_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_sssub_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_usadd_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_ussub_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_ssadd(unsigned vece, uint32_t dofs, uint32_t aofs,
uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
void tcg_gen_gvec_sssub(unsigned vece, uint32_t dofs, uint32_t aofs,
@@ -442,8 +467,14 @@ void tcg_gen_gvec_dup_i32_var(unsigned vece, TCGv_ptr dbase, uint32_t dofs,
void tcg_gen_gvec_shli(unsigned vece, uint32_t dofs, uint32_t aofs,
int64_t shift, uint32_t oprsz, uint32_t maxsz);
+void tcg_gen_gvec_shri_var(unsigned vece, TCGv_ptr dbase, uint32_t dofs,
+ TCGv_ptr abase, uint32_t aofs,
+ int64_t shift, uint32_t oprsz, uint32_t maxsz);
void tcg_gen_gvec_shri(unsigned vece, uint32_t dofs, uint32_t aofs,
int64_t shift, uint32_t oprsz, uint32_t maxsz);
+void tcg_gen_gvec_sari_var(unsigned vece, TCGv_ptr dbase, uint32_t dofs,
+ TCGv_ptr abase, uint32_t aofs,
+ int64_t shift, uint32_t oprsz, uint32_t maxsz);
void tcg_gen_gvec_sari(unsigned vece, uint32_t dofs, uint32_t aofs,
int64_t shift, uint32_t oprsz, uint32_t maxsz);
void tcg_gen_gvec_rotli(unsigned vece, uint32_t dofs, uint32_t aofs,
diff --git a/tcg/tcg-op-gvec.c b/tcg/tcg-op-gvec.c
index fc1a70434c5..0d649cc13b2 100644
--- a/tcg/tcg-op-gvec.c
+++ b/tcg/tcg-op-gvec.c
@@ -771,7 +771,8 @@ static void expand_2_i32(TCGv_ptr dbase, uint32_t dofs, TCGv_ptr abase,
tcg_temp_free_i32(t1);
}
-static void expand_2i_i32(uint32_t dofs, uint32_t aofs, uint32_t oprsz,
+static void expand_2i_i32(TCGv_ptr dbase, uint32_t dofs,
+ TCGv_ptr abase, uint32_t aofs, uint32_t oprsz,
int32_t c, bool load_dest,
void (*fni)(TCGv_i32, TCGv_i32, int32_t))
{
@@ -780,12 +781,12 @@ static void expand_2i_i32(uint32_t dofs, uint32_t aofs, uint32_t oprsz,
uint32_t i;
for (i = 0; i < oprsz; i += 4) {
- tcg_gen_ld_i32(t0, tcg_env, aofs + i);
+ tcg_gen_ld_i32(t0, abase, aofs + i);
if (load_dest) {
- tcg_gen_ld_i32(t1, tcg_env, dofs + i);
+ tcg_gen_ld_i32(t1, dbase, dofs + i);
}
fni(t1, t0, c);
- tcg_gen_st_i32(t1, tcg_env, dofs + i);
+ tcg_gen_st_i32(t1, dbase, dofs + i);
}
tcg_temp_free_i32(t0);
tcg_temp_free_i32(t1);
@@ -938,7 +939,8 @@ static void expand_2_i64(TCGv_ptr dbase, uint32_t dofs, TCGv_ptr abase,
tcg_temp_free_i64(t1);
}
-static void expand_2i_i64(uint32_t dofs, uint32_t aofs, uint32_t oprsz,
+static void expand_2i_i64(TCGv_ptr dbase, uint32_t dofs,
+ TCGv_ptr abase, uint32_t aofs, uint32_t oprsz,
int64_t c, bool load_dest,
void (*fni)(TCGv_i64, TCGv_i64, int64_t))
{
@@ -947,12 +949,12 @@ static void expand_2i_i64(uint32_t dofs, uint32_t aofs, uint32_t oprsz,
uint32_t i;
for (i = 0; i < oprsz; i += 8) {
- tcg_gen_ld_i64(t0, tcg_env, aofs + i);
+ tcg_gen_ld_i64(t0, abase, aofs + i);
if (load_dest) {
- tcg_gen_ld_i64(t1, tcg_env, dofs + i);
+ tcg_gen_ld_i64(t1, dbase, dofs + i);
}
fni(t1, t0, c);
- tcg_gen_st_i64(t1, tcg_env, dofs + i);
+ tcg_gen_st_i64(t1, dbase, dofs + i);
}
tcg_temp_free_i64(t0);
tcg_temp_free_i64(t1);
@@ -1106,7 +1108,8 @@ static void expand_2_vec(unsigned vece, TCGv_ptr dbase, uint32_t dofs,
/* Expand OPSZ bytes worth of two-vector operands and an immediate operand
using host vectors. */
-static void expand_2i_vec(unsigned vece, uint32_t dofs, uint32_t aofs,
+static void expand_2i_vec(unsigned vece, TCGv_ptr dbase, uint32_t dofs,
+ TCGv_ptr abase, uint32_t aofs,
uint32_t oprsz, uint32_t tysz, TCGType type,
int64_t c, bool load_dest,
void (*fni)(unsigned, TCGv_vec, TCGv_vec, int64_t))
@@ -1115,12 +1118,12 @@ static void expand_2i_vec(unsigned vece, uint32_t dofs, uint32_t aofs,
TCGv_vec t0 = tcg_temp_new_vec(type);
TCGv_vec t1 = tcg_temp_new_vec(type);
- tcg_gen_ld_vec(t0, tcg_env, aofs + i);
+ tcg_gen_ld_vec(t0, abase, aofs + i);
if (load_dest) {
- tcg_gen_ld_vec(t1, tcg_env, dofs + i);
+ tcg_gen_ld_vec(t1, dbase, dofs + i);
}
fni(vece, t1, t0, c);
- tcg_gen_st_vec(t1, tcg_env, dofs + i);
+ tcg_gen_st_vec(t1, dbase, dofs + i);
}
}
@@ -1318,8 +1321,9 @@ void tcg_gen_gvec_2(uint32_t dofs, uint32_t aofs,
}
/* Expand a vector operation with two vectors and an immediate. */
-void tcg_gen_gvec_2i(uint32_t dofs, uint32_t aofs, uint32_t oprsz,
- uint32_t maxsz, int64_t c, const GVecGen2i *g)
+void tcg_gen_gvec_2i_var(TCGv_ptr dbase, uint32_t dofs,
+ TCGv_ptr abase, uint32_t aofs, uint32_t oprsz,
+ uint32_t maxsz, int64_t c, const GVecGen2i *g)
{
const TCGOpcode *this_list = g->opt_opc ? : vecop_list_empty;
const TCGOpcode *hold_list = tcg_swap_vecop_list(this_list);
@@ -1327,7 +1331,7 @@ void tcg_gen_gvec_2i(uint32_t dofs, uint32_t aofs, uint32_t oprsz,
uint32_t some;
check_size_align(oprsz, maxsz, dofs | aofs);
- check_overlap_2(tcg_env, dofs, tcg_env, aofs, maxsz);
+ check_overlap_2(dbase, dofs, abase, aofs, maxsz);
type = 0;
if (g->fniv) {
@@ -1340,8 +1344,8 @@ void tcg_gen_gvec_2i(uint32_t dofs, uint32_t aofs, uint32_t oprsz,
* that e.g. size == 80 would be expanded with 2x32 + 1x16.
*/
some = QEMU_ALIGN_DOWN(oprsz, 32);
- expand_2i_vec(g->vece, dofs, aofs, some, 32, TCG_TYPE_V256,
- c, g->load_dest, g->fniv);
+ expand_2i_vec(g->vece, dbase, dofs, abase, aofs, some, 32,
+ TCG_TYPE_V256, c, g->load_dest, g->fniv);
if (some == oprsz) {
break;
}
@@ -1351,26 +1355,29 @@ void tcg_gen_gvec_2i(uint32_t dofs, uint32_t aofs, uint32_t oprsz,
maxsz -= some;
/* fallthru */
case TCG_TYPE_V128:
- expand_2i_vec(g->vece, dofs, aofs, oprsz, 16, TCG_TYPE_V128,
- c, g->load_dest, g->fniv);
+ expand_2i_vec(g->vece, dbase, dofs, abase, aofs, oprsz, 16,
+ TCG_TYPE_V128, c, g->load_dest, g->fniv);
break;
case TCG_TYPE_V64:
- expand_2i_vec(g->vece, dofs, aofs, oprsz, 8, TCG_TYPE_V64,
- c, g->load_dest, g->fniv);
+ expand_2i_vec(g->vece, dbase, dofs, abase, aofs, oprsz, 8,
+ TCG_TYPE_V64, c, g->load_dest, g->fniv);
break;
case 0:
if (g->fni8 && check_size_impl(oprsz, 8)) {
- expand_2i_i64(dofs, aofs, oprsz, c, g->load_dest, g->fni8);
+ expand_2i_i64(dbase, dofs, abase, aofs, oprsz, c,
+ g->load_dest, g->fni8);
} else if (g->fni4 && check_size_impl(oprsz, 4)) {
- expand_2i_i32(dofs, aofs, oprsz, c, g->load_dest, g->fni4);
+ expand_2i_i32(dbase, dofs, abase, aofs, oprsz, c,
+ g->load_dest, g->fni4);
} else {
if (g->fno) {
- tcg_gen_gvec_2_ool(dofs, aofs, oprsz, maxsz, c, g->fno);
+ expand_2_ool(dbase, dofs, abase, aofs, oprsz, maxsz,
+ c, g->fno);
} else {
TCGv_i64 tcg_c = tcg_constant_i64(c);
- tcg_gen_gvec_2i_ool(dofs, aofs, tcg_c, oprsz,
- maxsz, c, g->fnoi);
+ expand_2i_ool(dbase, dofs, abase, aofs, tcg_c, oprsz,
+ maxsz, c, g->fnoi);
}
oprsz = maxsz;
}
@@ -1382,10 +1389,16 @@ void tcg_gen_gvec_2i(uint32_t dofs, uint32_t aofs, uint32_t oprsz,
tcg_swap_vecop_list(hold_list);
if (oprsz < maxsz) {
- expand_clr(tcg_env, dofs + oprsz, maxsz - oprsz);
+ expand_clr(dbase, dofs + oprsz, maxsz - oprsz);
}
}
+void tcg_gen_gvec_2i(uint32_t dofs, uint32_t aofs, uint32_t oprsz,
+ uint32_t maxsz, int64_t c, const GVecGen2i *g)
+{
+ tcg_gen_gvec_2i_var(tcg_env, dofs, tcg_env, aofs, oprsz, maxsz, c, g);
+}
+
/*
* Expand a vector operation with two vectors and a scalar,
* (dbase+dofs) = op(abase+aofs, c).
@@ -2279,8 +2292,10 @@ void tcg_gen_gvec_sub(unsigned vece, uint32_t dofs, uint32_t aofs,
static const TCGOpcode vecop_list_mul[] = { INDEX_op_mul_vec, 0 };
-void tcg_gen_gvec_mul(unsigned vece, uint32_t dofs, uint32_t aofs,
- uint32_t bofs, uint32_t oprsz, uint32_t maxsz)
+void tcg_gen_gvec_mul_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[4] = {
{ .fniv = tcg_gen_mul_vec,
@@ -2305,7 +2320,15 @@ void tcg_gen_gvec_mul(unsigned vece, uint32_t dofs, uint32_t aofs,
};
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_mul(unsigned vece, uint32_t dofs, uint32_t aofs,
+ uint32_t bofs, uint32_t oprsz, uint32_t maxsz)
+{
+ tcg_gen_gvec_mul_var(vece, tcg_env, dofs, tcg_env, aofs, tcg_env, bofs,
+ oprsz, maxsz);
}
void tcg_gen_gvec_muls(unsigned vece, uint32_t dofs, uint32_t aofs,
@@ -2344,8 +2367,10 @@ void tcg_gen_gvec_muli(unsigned vece, uint32_t dofs, uint32_t aofs,
tcg_gen_gvec_muls(vece, dofs, aofs, tmp, oprsz, maxsz);
}
-void tcg_gen_gvec_ssadd(unsigned vece, uint32_t dofs, uint32_t aofs,
- uint32_t bofs, uint32_t oprsz, uint32_t maxsz)
+void tcg_gen_gvec_ssadd_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_ssadd_vec, 0 };
static const GVecGen3 g[4] = {
@@ -2367,11 +2392,21 @@ void tcg_gen_gvec_ssadd(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_sssub(unsigned vece, uint32_t dofs, uint32_t aofs,
+void tcg_gen_gvec_ssadd(unsigned vece, uint32_t dofs, uint32_t aofs,
uint32_t bofs, uint32_t oprsz, uint32_t maxsz)
+{
+ tcg_gen_gvec_ssadd_var(vece, tcg_env, dofs, tcg_env, aofs,
+ tcg_env, bofs, oprsz, maxsz);
+}
+
+void tcg_gen_gvec_sssub_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_sssub_vec, 0 };
static const GVecGen3 g[4] = {
@@ -2393,7 +2428,15 @@ void tcg_gen_gvec_sssub(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_sssub(unsigned vece, uint32_t dofs, uint32_t aofs,
+ uint32_t bofs, uint32_t oprsz, uint32_t maxsz)
+{
+ tcg_gen_gvec_sssub_var(vece, tcg_env, dofs, tcg_env, aofs,
+ tcg_env, bofs, oprsz, maxsz);
}
static void tcg_gen_usadd_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
@@ -2410,8 +2453,10 @@ static void tcg_gen_usadd_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
tcg_gen_movcond_i64(TCG_COND_LTU, d, d, a, max, d);
}
-void tcg_gen_gvec_usadd(unsigned vece, uint32_t dofs, uint32_t aofs,
- uint32_t bofs, uint32_t oprsz, uint32_t maxsz)
+void tcg_gen_gvec_usadd_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_usadd_vec, 0 };
static const GVecGen3 g[4] = {
@@ -2435,11 +2480,21 @@ void tcg_gen_gvec_usadd(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_ussub(unsigned vece, uint32_t dofs, uint32_t aofs,
+void tcg_gen_gvec_usadd(unsigned vece, uint32_t dofs, uint32_t aofs,
uint32_t bofs, uint32_t oprsz, uint32_t maxsz)
+{
+ tcg_gen_gvec_usadd_var(vece, tcg_env, dofs, tcg_env, aofs,
+ tcg_env, bofs, oprsz, maxsz);
+}
+
+void tcg_gen_gvec_ussub_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_ussub_vec, 0 };
static const GVecGen3 g[4] = {
@@ -2463,7 +2518,15 @@ void tcg_gen_gvec_ussub(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_ussub(unsigned vece, uint32_t dofs, uint32_t aofs,
+ uint32_t bofs, uint32_t oprsz, uint32_t maxsz)
+{
+ tcg_gen_gvec_ussub_var(vece, tcg_env, dofs, tcg_env, aofs,
+ tcg_env, bofs, oprsz, maxsz);
}
void tcg_gen_gvec_smin_var(unsigned vece, TCGv_ptr dbase, uint32_t dofs,
@@ -3131,8 +3194,9 @@ void tcg_gen_vec_shr16i_i32(TCGv_i32 d, TCGv_i32 a, int32_t c)
tcg_gen_andi_i32(d, d, mask);
}
-void tcg_gen_gvec_shri(unsigned vece, uint32_t dofs, uint32_t aofs,
- int64_t shift, uint32_t oprsz, uint32_t maxsz)
+void tcg_gen_gvec_shri_var(unsigned vece, TCGv_ptr dbase, uint32_t dofs,
+ TCGv_ptr abase, uint32_t aofs,
+ int64_t shift, uint32_t oprsz, uint32_t maxsz)
{
static const TCGOpcode vecop_list[] = { INDEX_op_shri_vec, 0 };
static const GVecGen2i g[4] = {
@@ -3162,12 +3226,20 @@ void tcg_gen_gvec_shri(unsigned vece, uint32_t dofs, uint32_t aofs,
tcg_debug_assert(vece <= MO_64);
tcg_debug_assert(shift >= 0 && shift < (8 << vece));
if (shift == 0) {
- tcg_gen_gvec_mov(vece, dofs, aofs, oprsz, maxsz);
+ tcg_gen_gvec_mov_var(vece, dbase, dofs, abase, aofs, oprsz, maxsz);
} else {
- tcg_gen_gvec_2i(dofs, aofs, oprsz, maxsz, shift, &g[vece]);
+ tcg_gen_gvec_2i_var(dbase, dofs, abase, aofs, oprsz, maxsz,
+ shift, &g[vece]);
}
}
+void tcg_gen_gvec_shri(unsigned vece, uint32_t dofs, uint32_t aofs,
+ int64_t shift, uint32_t oprsz, uint32_t maxsz)
+{
+ tcg_gen_gvec_shri_var(vece, tcg_env, dofs, tcg_env, aofs,
+ shift, oprsz, maxsz);
+}
+
void tcg_gen_vec_sar8i_i64(TCGv_i64 d, TCGv_i64 a, int64_t c)
{
uint64_t s_mask = dup_const(MO_8, 0x80 >> c);
@@ -3224,8 +3296,9 @@ void tcg_gen_vec_sar16i_i32(TCGv_i32 d, TCGv_i32 a, int32_t c)
tcg_temp_free_i32(s);
}
-void tcg_gen_gvec_sari(unsigned vece, uint32_t dofs, uint32_t aofs,
- int64_t shift, uint32_t oprsz, uint32_t maxsz)
+void tcg_gen_gvec_sari_var(unsigned vece, TCGv_ptr dbase, uint32_t dofs,
+ TCGv_ptr abase, uint32_t aofs,
+ int64_t shift, uint32_t oprsz, uint32_t maxsz)
{
static const TCGOpcode vecop_list[] = { INDEX_op_sari_vec, 0 };
static const GVecGen2i g[4] = {
@@ -3255,12 +3328,20 @@ void tcg_gen_gvec_sari(unsigned vece, uint32_t dofs, uint32_t aofs,
tcg_debug_assert(vece <= MO_64);
tcg_debug_assert(shift >= 0 && shift < (8 << vece));
if (shift == 0) {
- tcg_gen_gvec_mov(vece, dofs, aofs, oprsz, maxsz);
+ tcg_gen_gvec_mov_var(vece, dbase, dofs, abase, aofs, oprsz, maxsz);
} else {
- tcg_gen_gvec_2i(dofs, aofs, oprsz, maxsz, shift, &g[vece]);
+ tcg_gen_gvec_2i_var(dbase, dofs, abase, aofs, oprsz, maxsz,
+ shift, &g[vece]);
}
}
+void tcg_gen_gvec_sari(unsigned vece, uint32_t dofs, uint32_t aofs,
+ int64_t shift, uint32_t oprsz, uint32_t maxsz)
+{
+ tcg_gen_gvec_sari_var(vece, tcg_env, dofs, tcg_env, aofs,
+ shift, oprsz, maxsz);
+}
+
void tcg_gen_vec_rotl8i_i64(TCGv_i64 d, TCGv_i64 a, int64_t c)
{
uint64_t mask = dup_const(MO_8, 0xff << c);
--
2.34.1
next prev parent reply other threads:[~2026-09-13 16:00 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-13 15:59 [PATCH v3 0/6] hexagon: Add HVX context Brian Cain
2026-09-13 15:59 ` [PATCH v3 1/6] tcg: split out _var forms of gvec logical, abs and min/max ops Brian Cain
2026-09-13 15:59 ` [PATCH v3 2/6] tcg: add base arguments to the gvec 2s, dup_i32 and cmp expanders Brian Cain
2026-09-13 15:59 ` Brian Cain [this message]
2026-09-13 15:59 ` [PATCH v3 4/6] target/hexagon: raise an exception for HVX with SSR:XE clear Brian Cain
2026-09-13 15:59 ` [PATCH v3 5/6] target/hexagon: share HVX contexts among CPUs Brian Cain
2026-09-13 22:02 ` Richard Henderson
2026-09-13 15:59 ` [PATCH v3 6/6] tests/functional/hexagon: add HVX tests Brian Cain
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260913155928.365928-4-brian.cain@oss.qualcomm.com \
--to=brian.cain@oss.qualcomm.com \
--cc=deller@gmx.de \
--cc=laurent@vivier.eu \
--cc=marco.liebel@oss.qualcomm.com \
--cc=pbonzini@redhat.com \
--cc=philmd@oss.qualcomm.com \
--cc=pierrick.bouvier@oss.qualcomm.com \
--cc=qemu-devel@nongnu.org \
--cc=richard.henderson@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.