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 <[email protected]>
Reviewed-by: Richard Henderson <[email protected]>
Signed-off-by: Brian Cain <[email protected]>
---
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