Commit 94bce0f2b9 for qemu.org

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

    target/hexagon: prepare for separate HVX contexts

    Prepare for system emulation modeling of HVX contexts, which are remapped
    at runtime.  No functional change is intended, this is just refactoring.

    Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
    Suggested-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
    Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
    Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>

diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
index 19486e0f74..7298cd27a0 100644
--- a/target/hexagon/cpu.c
+++ b/target/hexagon/cpu.c
@@ -191,7 +191,7 @@ static void print_vreg(FILE *f, CPUHexagonState *env, int regnum,
     if (skip_if_zero) {
         bool nonzero_found = false;
         for (int i = 0; i < MAX_VEC_SIZE_BYTES; i++) {
-            if (env->VRegs[regnum].ub[i] != 0) {
+            if (hex_hvx(env)->VRegs[regnum].ub[i] != 0) {
                 nonzero_found = true;
                 break;
             }
@@ -202,9 +202,10 @@ static void print_vreg(FILE *f, CPUHexagonState *env, int regnum,
     }

     qemu_fprintf(f, "  v%d = ( ", regnum);
-    qemu_fprintf(f, "0x%02x", env->VRegs[regnum].ub[MAX_VEC_SIZE_BYTES - 1]);
+    qemu_fprintf(f, "0x%02x",
+                 hex_hvx(env)->VRegs[regnum].ub[MAX_VEC_SIZE_BYTES - 1]);
     for (int i = MAX_VEC_SIZE_BYTES - 2; i >= 0; i--) {
-        qemu_fprintf(f, ", 0x%02x", env->VRegs[regnum].ub[i]);
+        qemu_fprintf(f, ", 0x%02x", hex_hvx(env)->VRegs[regnum].ub[i]);
     }
     qemu_fprintf(f, " )\n");
 }
@@ -220,7 +221,7 @@ static void print_qreg(FILE *f, CPUHexagonState *env, int regnum,
     if (skip_if_zero) {
         bool nonzero_found = false;
         for (int i = 0; i < MAX_VEC_SIZE_BYTES / 8; i++) {
-            if (env->QRegs[regnum].ub[i] != 0) {
+            if (hex_hvx(env)->QRegs[regnum].ub[i] != 0) {
                 nonzero_found = true;
                 break;
             }
@@ -232,9 +233,9 @@ static void print_qreg(FILE *f, CPUHexagonState *env, int regnum,

     qemu_fprintf(f, "  q%d = ( ", regnum);
     qemu_fprintf(f, "0x%02x",
-                 env->QRegs[regnum].ub[MAX_VEC_SIZE_BYTES / 8 - 1]);
+                 hex_hvx(env)->QRegs[regnum].ub[MAX_VEC_SIZE_BYTES / 8 - 1]);
     for (int i = MAX_VEC_SIZE_BYTES / 8 - 2; i >= 0; i--) {
-        qemu_fprintf(f, ", 0x%02x", env->QRegs[regnum].ub[i]);
+        qemu_fprintf(f, ", 0x%02x", hex_hvx(env)->QRegs[regnum].ub[i]);
     }
     qemu_fprintf(f, " )\n");
 }
diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h
index 97f689fda2..965abe4f6d 100644
--- a/target/hexagon/cpu.h
+++ b/target/hexagon/cpu.h
@@ -204,6 +204,11 @@ struct ArchCPU {
 #endif
 };

+static inline CPUHexagonState *hex_hvx(CPUHexagonState *env)
+{
+    return env;
+}
+
 FIELD(TB_FLAGS, IS_TIGHT_LOOP, 0, 1)
 FIELD(TB_FLAGS, MMU_INDEX, 1, 3)
 FIELD(TB_FLAGS, PCYCLE_ENABLED, 4, 1)
diff --git a/target/hexagon/gdbstub.c b/target/hexagon/gdbstub.c
index b9856cfc97..76ab5235f6 100644
--- a/target/hexagon/gdbstub.c
+++ b/target/hexagon/gdbstub.c
@@ -80,8 +80,8 @@ static int gdb_get_vreg(CPUHexagonState *env, GByteArray *mem_buf, int n)
 {
     int total = 0;
     int i;
-    for (i = 0; i < ARRAY_SIZE(env->VRegs[n].uw); i++) {
-        total += gdb_get_reg32(mem_buf, env->VRegs[n].uw[i]);
+    for (i = 0; i < ARRAY_SIZE(hex_hvx(env)->VRegs[n].uw); i++) {
+        total += gdb_get_reg32(mem_buf, hex_hvx(env)->VRegs[n].uw[i]);
     }
     return total;
 }
@@ -90,8 +90,8 @@ static int gdb_get_qreg(CPUHexagonState *env, GByteArray *mem_buf, int n)
 {
     int total = 0;
     int i;
-    for (i = 0; i < ARRAY_SIZE(env->QRegs[n].uw); i++) {
-        total += gdb_get_reg32(mem_buf, env->QRegs[n].uw[i]);
+    for (i = 0; i < ARRAY_SIZE(hex_hvx(env)->QRegs[n].uw); i++) {
+        total += gdb_get_reg32(mem_buf, hex_hvx(env)->QRegs[n].uw[i]);
     }
     return total;
 }
@@ -116,8 +116,8 @@ int hexagon_hvx_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
 static int gdb_put_vreg(CPUHexagonState *env, uint8_t *mem_buf, int n)
 {
     int i;
-    for (i = 0; i < ARRAY_SIZE(env->VRegs[n].uw); i++) {
-        env->VRegs[n].uw[i] = ldl_le_p(mem_buf);
+    for (i = 0; i < ARRAY_SIZE(hex_hvx(env)->VRegs[n].uw); i++) {
+        hex_hvx(env)->VRegs[n].uw[i] = ldl_le_p(mem_buf);
         mem_buf += 4;
     }
     return MAX_VEC_SIZE_BYTES;
@@ -126,8 +126,8 @@ static int gdb_put_vreg(CPUHexagonState *env, uint8_t *mem_buf, int n)
 static int gdb_put_qreg(CPUHexagonState *env, uint8_t *mem_buf, int n)
 {
     int i;
-    for (i = 0; i < ARRAY_SIZE(env->QRegs[n].uw); i++) {
-        env->QRegs[n].uw[i] = ldl_le_p(mem_buf);
+    for (i = 0; i < ARRAY_SIZE(hex_hvx(env)->QRegs[n].uw); i++) {
+        hex_hvx(env)->QRegs[n].uw[i] = ldl_le_p(mem_buf);
         mem_buf += 4;
     }
     return MAX_VEC_SIZE_BYTES / 8;
diff --git a/target/hexagon/gen_tcg_hvx.h b/target/hexagon/gen_tcg_hvx.h
index 2a342cdee6..f399291dc6 100644
--- a/target/hexagon/gen_tcg_hvx.h
+++ b/target/hexagon/gen_tcg_hvx.h
@@ -49,8 +49,8 @@ static inline void assert_vhist_tmp(DisasContext *ctx)
     do { \
         if (ctx->pre_commit) { \
             intptr_t dstoff = offsetof(CPUHexagonState, qtmp); \
-            tcg_gen_gvec_mov(MO_64, dstoff, QvV_off, \
-                             sizeof(MMVector), sizeof(MMVector)); \
+            tcg_gen_gvec_mov_var(MO_64, tcg_env, dstoff, QvV_base, QvV_off, \
+                                 sizeof(MMVector), sizeof(MMVector)); \
         } else { \
             assert_vhist_tmp(ctx); \
             gen_helper_vhistq(tcg_env); \
@@ -65,8 +65,8 @@ static inline void assert_vhist_tmp(DisasContext *ctx)
     do { \
         if (ctx->pre_commit) { \
             intptr_t dstoff = offsetof(CPUHexagonState, qtmp); \
-            tcg_gen_gvec_mov(MO_64, dstoff, QvV_off, \
-                             sizeof(MMVector), sizeof(MMVector)); \
+            tcg_gen_gvec_mov_var(MO_64, tcg_env, dstoff, QvV_base, QvV_off, \
+                                 sizeof(MMVector), sizeof(MMVector)); \
         } else { \
             assert_vhist_tmp(ctx); \
             gen_helper_vwhist256q(tcg_env); \
@@ -81,8 +81,8 @@ static inline void assert_vhist_tmp(DisasContext *ctx)
     do { \
         if (ctx->pre_commit) { \
             intptr_t dstoff = offsetof(CPUHexagonState, qtmp); \
-            tcg_gen_gvec_mov(MO_64, dstoff, QvV_off, \
-                             sizeof(MMVector), sizeof(MMVector)); \
+            tcg_gen_gvec_mov_var(MO_64, tcg_env, dstoff, QvV_base, QvV_off, \
+                                 sizeof(MMVector), sizeof(MMVector)); \
         } else { \
             assert_vhist_tmp(ctx); \
             gen_helper_vwhist256q_sat(tcg_env); \
@@ -97,8 +97,8 @@ static inline void assert_vhist_tmp(DisasContext *ctx)
     do { \
         if (ctx->pre_commit) { \
             intptr_t dstoff = offsetof(CPUHexagonState, qtmp); \
-            tcg_gen_gvec_mov(MO_64, dstoff, QvV_off, \
-                             sizeof(MMVector), sizeof(MMVector)); \
+            tcg_gen_gvec_mov_var(MO_64, tcg_env, dstoff, QvV_base, QvV_off, \
+                                 sizeof(MMVector), sizeof(MMVector)); \
         } else { \
             assert_vhist_tmp(ctx); \
             gen_helper_vwhist128q(tcg_env); \
@@ -114,8 +114,8 @@ static inline void assert_vhist_tmp(DisasContext *ctx)
     do { \
         if (ctx->pre_commit) { \
             intptr_t dstoff = offsetof(CPUHexagonState, qtmp); \
-            tcg_gen_gvec_mov(MO_64, dstoff, QvV_off, \
-                             sizeof(MMVector), sizeof(MMVector)); \
+            tcg_gen_gvec_mov_var(MO_64, tcg_env, dstoff, QvV_base, QvV_off, \
+                                 sizeof(MMVector), sizeof(MMVector)); \
         } else { \
             TCGv tcgv_uiV = tcg_constant_tl(uiV); \
             assert_vhist_tmp(ctx); \
@@ -125,19 +125,20 @@ static inline void assert_vhist_tmp(DisasContext *ctx)


 #define fGEN_TCG_V6_vassign(SHORTCODE) \
-    tcg_gen_gvec_mov(MO_64, VdV_off, VuV_off, \
-                     sizeof(MMVector), sizeof(MMVector))
+    tcg_gen_gvec_mov_var(MO_64, VdV_base, VdV_off, VuV_base, VuV_off, \
+                         sizeof(MMVector), sizeof(MMVector))

 #define fGEN_TCG_V6_vassign_tmp(SHORTCODE) \
-    tcg_gen_gvec_mov(MO_64, VdV_off, VuV_off, \
-                     sizeof(MMVector), sizeof(MMVector))
+    tcg_gen_gvec_mov_var(MO_64, VdV_base, VdV_off, VuV_base, VuV_off, \
+                         sizeof(MMVector), sizeof(MMVector))

 #define fGEN_TCG_V6_vcombine_tmp(SHORTCODE) \
     do { \
-        tcg_gen_gvec_mov(MO_64, VddV_off, VvV_off, \
-                         sizeof(MMVector), sizeof(MMVector)); \
-        tcg_gen_gvec_mov(MO_64, VddV_off + sizeof(MMVector), VuV_off, \
-                         sizeof(MMVector), sizeof(MMVector)); \
+        tcg_gen_gvec_mov_var(MO_64, VddV_base, VddV_off, VvV_base, VvV_off, \
+                             sizeof(MMVector), sizeof(MMVector)); \
+        tcg_gen_gvec_mov_var(MO_64, VddV_base, VddV_off + sizeof(MMVector), \
+                             VuV_base, VuV_off, sizeof(MMVector), \
+                             sizeof(MMVector)); \
     } while (0)

 /*
@@ -148,18 +149,20 @@ static inline void assert_vhist_tmp(DisasContext *ctx)
 #define fGEN_TCG_V6_vcombine(SHORTCODE) \
     do { \
         if (VddV_off != VuV_off) { \
-            tcg_gen_gvec_mov(MO_64, VddV_off, VvV_off, \
-                             sizeof(MMVector), sizeof(MMVector)); \
-            tcg_gen_gvec_mov(MO_64, VddV_off + sizeof(MMVector), VuV_off, \
-                             sizeof(MMVector), sizeof(MMVector)); \
+            tcg_gen_gvec_mov_var(MO_64, VddV_base, VddV_off, VvV_base, \
+                                 VvV_off, sizeof(MMVector), sizeof(MMVector)); \
+            tcg_gen_gvec_mov_var(MO_64, VddV_base, \
+                                 VddV_off + sizeof(MMVector), VuV_base, \
+                                 VuV_off, sizeof(MMVector), sizeof(MMVector)); \
         } else { \
             intptr_t tmpoff = offsetof(CPUHexagonState, vtmp); \
-            tcg_gen_gvec_mov(MO_64, tmpoff, VuV_off, \
-                             sizeof(MMVector), sizeof(MMVector)); \
-            tcg_gen_gvec_mov(MO_64, VddV_off, VvV_off, \
-                             sizeof(MMVector), sizeof(MMVector)); \
-            tcg_gen_gvec_mov(MO_64, VddV_off + sizeof(MMVector), tmpoff, \
-                             sizeof(MMVector), sizeof(MMVector)); \
+            tcg_gen_gvec_mov_var(MO_64, tcg_env, tmpoff, VuV_base, VuV_off, \
+                                 sizeof(MMVector), sizeof(MMVector)); \
+            tcg_gen_gvec_mov_var(MO_64, VddV_base, VddV_off, VvV_base, \
+                                 VvV_off, sizeof(MMVector), sizeof(MMVector)); \
+            tcg_gen_gvec_mov_var(MO_64, VddV_base, \
+                                 VddV_off + sizeof(MMVector), tcg_env, tmpoff, \
+                                 sizeof(MMVector), sizeof(MMVector)); \
         } \
     } while (0)

@@ -170,8 +173,8 @@ static inline void assert_vhist_tmp(DisasContext *ctx)
         TCGLabel *false_label = gen_new_label(); \
         tcg_gen_andi_tl(lsb, PsV, 1); \
         tcg_gen_brcondi_tl(TCG_COND_NE, lsb, PRED, false_label); \
-        tcg_gen_gvec_mov(MO_64, VdV_off, VuV_off, \
-                         sizeof(MMVector), sizeof(MMVector)); \
+        tcg_gen_gvec_mov_var(MO_64, VdV_base, VdV_off, VuV_base, VuV_off, \
+                             sizeof(MMVector), sizeof(MMVector)); \
         gen_set_label(false_label); \
     } while (0)

@@ -186,231 +189,276 @@ static inline void assert_vhist_tmp(DisasContext *ctx)

 /* Vector add - various forms */
 #define fGEN_TCG_V6_vaddb(SHORTCODE) \
-    tcg_gen_gvec_add(MO_8, VdV_off, VuV_off, VvV_off, \
-                     sizeof(MMVector), sizeof(MMVector))
+    tcg_gen_gvec_add_var(MO_8, VdV_base, VdV_off, VuV_base, VuV_off, VvV_base, \
+                         VvV_off, sizeof(MMVector), sizeof(MMVector))

 #define fGEN_TCG_V6_vaddh(SHORTCYDE) \
-    tcg_gen_gvec_add(MO_16, VdV_off, VuV_off, VvV_off, \
-                     sizeof(MMVector), sizeof(MMVector))
+    tcg_gen_gvec_add_var(MO_16, VdV_base, VdV_off, VuV_base, VuV_off, \
+                         VvV_base, VvV_off, sizeof(MMVector), \
+                         sizeof(MMVector))

 #define fGEN_TCG_V6_vaddw(SHORTCODE) \
-    tcg_gen_gvec_add(MO_32, VdV_off, VuV_off, VvV_off, \
-                     sizeof(MMVector), sizeof(MMVector))
+    tcg_gen_gvec_add_var(MO_32, VdV_base, VdV_off, VuV_base, VuV_off, \
+                         VvV_base, VvV_off, sizeof(MMVector), \
+                         sizeof(MMVector))

 #define fGEN_TCG_V6_vaddb_dv(SHORTCODE) \
-    tcg_gen_gvec_add(MO_8, VddV_off, VuuV_off, VvvV_off, \
-                     sizeof(MMVector) * 2, sizeof(MMVector) * 2)
+    tcg_gen_gvec_add_var(MO_8, VddV_base, VddV_off, VuuV_base, VuuV_off, \
+                         VvvV_base, VvvV_off, sizeof(MMVector) * 2, \
+                         sizeof(MMVector) * 2)

 #define fGEN_TCG_V6_vaddh_dv(SHORTCYDE) \
-    tcg_gen_gvec_add(MO_16, VddV_off, VuuV_off, VvvV_off, \
-                     sizeof(MMVector) * 2, sizeof(MMVector) * 2)
+    tcg_gen_gvec_add_var(MO_16, VddV_base, VddV_off, VuuV_base, VuuV_off, \
+                         VvvV_base, VvvV_off, sizeof(MMVector) * 2, \
+                         sizeof(MMVector) * 2)

 #define fGEN_TCG_V6_vaddw_dv(SHORTCODE) \
-    tcg_gen_gvec_add(MO_32, VddV_off, VuuV_off, VvvV_off, \
-                     sizeof(MMVector) * 2, sizeof(MMVector) * 2)
+    tcg_gen_gvec_add_var(MO_32, VddV_base, VddV_off, VuuV_base, VuuV_off, \
+                         VvvV_base, VvvV_off, sizeof(MMVector) * 2, \
+                         sizeof(MMVector) * 2)

 /* Vector sub - various forms */
 #define fGEN_TCG_V6_vsubb(SHORTCODE) \
-    tcg_gen_gvec_sub(MO_8, VdV_off, VuV_off, VvV_off, \
-                     sizeof(MMVector), sizeof(MMVector))
+    tcg_gen_gvec_sub_var(MO_8, VdV_base, VdV_off, VuV_base, VuV_off, VvV_base, \
+                         VvV_off, sizeof(MMVector), sizeof(MMVector))

 #define fGEN_TCG_V6_vsubh(SHORTCODE) \
-    tcg_gen_gvec_sub(MO_16, VdV_off, VuV_off, VvV_off, \
-                     sizeof(MMVector), sizeof(MMVector))
+    tcg_gen_gvec_sub_var(MO_16, VdV_base, VdV_off, VuV_base, VuV_off, \
+                         VvV_base, VvV_off, sizeof(MMVector), \
+                         sizeof(MMVector))

 #define fGEN_TCG_V6_vsubw(SHORTCODE) \
-    tcg_gen_gvec_sub(MO_32, VdV_off, VuV_off, VvV_off, \
-                     sizeof(MMVector), sizeof(MMVector))
+    tcg_gen_gvec_sub_var(MO_32, VdV_base, VdV_off, VuV_base, VuV_off, \
+                         VvV_base, VvV_off, sizeof(MMVector), \
+                         sizeof(MMVector))

 #define fGEN_TCG_V6_vsubb_dv(SHORTCODE) \
-    tcg_gen_gvec_sub(MO_8, VddV_off, VuuV_off, VvvV_off, \
-                     sizeof(MMVector) * 2, sizeof(MMVector) * 2)
+    tcg_gen_gvec_sub_var(MO_8, VddV_base, VddV_off, VuuV_base, VuuV_off, \
+                         VvvV_base, VvvV_off, sizeof(MMVector) * 2, \
+                         sizeof(MMVector) * 2)

 #define fGEN_TCG_V6_vsubh_dv(SHORTCODE) \
-    tcg_gen_gvec_sub(MO_16, VddV_off, VuuV_off, VvvV_off, \
-                     sizeof(MMVector) * 2, sizeof(MMVector) * 2)
+    tcg_gen_gvec_sub_var(MO_16, VddV_base, VddV_off, VuuV_base, VuuV_off, \
+                         VvvV_base, VvvV_off, sizeof(MMVector) * 2, \
+                         sizeof(MMVector) * 2)

 #define fGEN_TCG_V6_vsubw_dv(SHORTCODE) \
-    tcg_gen_gvec_sub(MO_32, VddV_off, VuuV_off, VvvV_off, \
-                     sizeof(MMVector) * 2, sizeof(MMVector) * 2)
+    tcg_gen_gvec_sub_var(MO_32, VddV_base, VddV_off, VuuV_base, VuuV_off, \
+                         VvvV_base, VvvV_off, sizeof(MMVector) * 2, \
+                         sizeof(MMVector) * 2)

 #define fGEN_TCG_V6_vaddbsat(SHORTCODE) \
-    tcg_gen_gvec_ssadd(MO_8, VdV_off, VuV_off, VvV_off, \
-                       VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE)
+    tcg_gen_gvec_ssadd_var(MO_8, VdV_base, VdV_off, VuV_base, VuV_off, \
+                          VvV_base, VvV_off, \
+                          VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE)

 #define fGEN_TCG_V6_vaddhsat(SHORTCODE) \
-    tcg_gen_gvec_ssadd(MO_16, VdV_off, VuV_off, VvV_off, \
-                       VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE)
+    tcg_gen_gvec_ssadd_var(MO_16, VdV_base, VdV_off, VuV_base, VuV_off, \
+                          VvV_base, VvV_off, \
+                          VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE)

 #define fGEN_TCG_V6_vaddwsat(SHORTCODE) \
-    tcg_gen_gvec_ssadd(MO_32, VdV_off, VuV_off, VvV_off, \
-                       VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE)
+    tcg_gen_gvec_ssadd_var(MO_32, VdV_base, VdV_off, VuV_base, VuV_off, \
+                          VvV_base, VvV_off, \
+                          VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE)

 #define fGEN_TCG_V6_vaddubsat(SHORTCODE) \
-    tcg_gen_gvec_usadd(MO_8, VdV_off, VuV_off, VvV_off, \
-                       VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE)
+    tcg_gen_gvec_usadd_var(MO_8, VdV_base, VdV_off, VuV_base, VuV_off, \
+                          VvV_base, VvV_off, \
+                          VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE)

 #define fGEN_TCG_V6_vadduhsat(SHORTCODE) \
-    tcg_gen_gvec_usadd(MO_16, VdV_off, VuV_off, VvV_off, \
-                       VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE)
+    tcg_gen_gvec_usadd_var(MO_16, VdV_base, VdV_off, VuV_base, VuV_off, \
+                          VvV_base, VvV_off, \
+                          VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE)

 #define fGEN_TCG_V6_vadduwsat(SHORTCODE) \
-    tcg_gen_gvec_usadd(MO_32, VdV_off, VuV_off, VvV_off, \
-                       VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE)
+    tcg_gen_gvec_usadd_var(MO_32, VdV_base, VdV_off, VuV_base, VuV_off, \
+                          VvV_base, VvV_off, \
+                          VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE)

-#define fGEN_TCG_PAIR_ADDSUB(OP, VECE, DST, SRC_A, SRC_B) \
-    tcg_gen_gvec_##OP(VECE, DST, SRC_A, SRC_B, \
-                     2 * VECTOR_SIZE_BYTE, 2 * VECTOR_SIZE_BYTE)
+#define fGEN_TCG_PAIR_ADDSUB(OP, VECE, DBASE, DST, ABASE, SRC_A, BBASE, SRC_B) \
+    tcg_gen_gvec_##OP##_var(VECE, DBASE, DST, ABASE, SRC_A, BBASE, SRC_B, \
+                           2 * VECTOR_SIZE_BYTE, 2 * VECTOR_SIZE_BYTE)

 #define fGEN_TCG_V6_vaddbsat_dv(SHORTCODE) \
-    fGEN_TCG_PAIR_ADDSUB(ssadd, MO_8, VddV_off, VuuV_off, VvvV_off)
+    fGEN_TCG_PAIR_ADDSUB(ssadd, MO_8, VddV_base, VddV_off, \
+                         VuuV_base, VuuV_off, VvvV_base, VvvV_off)

 #define fGEN_TCG_V6_vaddhsat_dv(SHORTCODE) \
-    fGEN_TCG_PAIR_ADDSUB(ssadd, MO_16, VddV_off, VuuV_off, VvvV_off)
+    fGEN_TCG_PAIR_ADDSUB(ssadd, MO_16, VddV_base, VddV_off, \
+                         VuuV_base, VuuV_off, VvvV_base, VvvV_off)

 #define fGEN_TCG_V6_vaddwsat_dv(SHORTCODE) \
-    fGEN_TCG_PAIR_ADDSUB(ssadd, MO_32, VddV_off, VuuV_off, VvvV_off)
+    fGEN_TCG_PAIR_ADDSUB(ssadd, MO_32, VddV_base, VddV_off, \
+                         VuuV_base, VuuV_off, VvvV_base, VvvV_off)

 #define fGEN_TCG_V6_vaddubsat_dv(SHORTCODE) \
-    fGEN_TCG_PAIR_ADDSUB(usadd, MO_8, VddV_off, VuuV_off, VvvV_off)
+    fGEN_TCG_PAIR_ADDSUB(usadd, MO_8, VddV_base, VddV_off, \
+                         VuuV_base, VuuV_off, VvvV_base, VvvV_off)

 #define fGEN_TCG_V6_vadduhsat_dv(SHORTCODE) \
-    fGEN_TCG_PAIR_ADDSUB(usadd, MO_16, VddV_off, VuuV_off, VvvV_off)
+    fGEN_TCG_PAIR_ADDSUB(usadd, MO_16, VddV_base, VddV_off, \
+                         VuuV_base, VuuV_off, VvvV_base, VvvV_off)

 #define fGEN_TCG_V6_vadduwsat_dv(SHORTCODE) \
-    fGEN_TCG_PAIR_ADDSUB(usadd, MO_32, VddV_off, VuuV_off, VvvV_off)
+    fGEN_TCG_PAIR_ADDSUB(usadd, MO_32, VddV_base, VddV_off, \
+                         VuuV_base, VuuV_off, VvvV_base, VvvV_off)

 #define fGEN_TCG_V6_vsubbsat(SHORTCODE) \
-    tcg_gen_gvec_sssub(MO_8, VdV_off, VuV_off, VvV_off, \
-                       VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE)
+    tcg_gen_gvec_sssub_var(MO_8, VdV_base, VdV_off, VuV_base, VuV_off, \
+                          VvV_base, VvV_off, \
+                          VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE)

 #define fGEN_TCG_V6_vsubhsat(SHORTCODE) \
-    tcg_gen_gvec_sssub(MO_16, VdV_off, VuV_off, VvV_off, \
-                       VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE)
+    tcg_gen_gvec_sssub_var(MO_16, VdV_base, VdV_off, VuV_base, VuV_off, \
+                          VvV_base, VvV_off, \
+                          VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE)

 #define fGEN_TCG_V6_vsubwsat(SHORTCODE) \
-    tcg_gen_gvec_sssub(MO_32, VdV_off, VuV_off, VvV_off, \
-                       VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE)
+    tcg_gen_gvec_sssub_var(MO_32, VdV_base, VdV_off, VuV_base, VuV_off, \
+                          VvV_base, VvV_off, \
+                          VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE)

 #define fGEN_TCG_V6_vsububsat(SHORTCODE) \
-    tcg_gen_gvec_ussub(MO_8, VdV_off, VuV_off, VvV_off, \
-                       VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE)
+    tcg_gen_gvec_ussub_var(MO_8, VdV_base, VdV_off, VuV_base, VuV_off, \
+                          VvV_base, VvV_off, \
+                          VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE)

 #define fGEN_TCG_V6_vsubuhsat(SHORTCODE) \
-    tcg_gen_gvec_ussub(MO_16, VdV_off, VuV_off, VvV_off, \
-                       VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE)
+    tcg_gen_gvec_ussub_var(MO_16, VdV_base, VdV_off, VuV_base, VuV_off, \
+                          VvV_base, VvV_off, \
+                          VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE)

 #define fGEN_TCG_V6_vsubuwsat(SHORTCODE) \
-    tcg_gen_gvec_ussub(MO_32, VdV_off, VuV_off, VvV_off, \
-                       VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE)
+    tcg_gen_gvec_ussub_var(MO_32, VdV_base, VdV_off, VuV_base, VuV_off, \
+                          VvV_base, VvV_off, \
+                          VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE)

 #define fGEN_TCG_V6_vsubbsat_dv(SHORTCODE) \
-    fGEN_TCG_PAIR_ADDSUB(sssub, MO_8, VddV_off, VuuV_off, VvvV_off)
+    fGEN_TCG_PAIR_ADDSUB(sssub, MO_8, VddV_base, VddV_off, \
+                         VuuV_base, VuuV_off, VvvV_base, VvvV_off)

 #define fGEN_TCG_V6_vsubhsat_dv(SHORTCODE) \
-    fGEN_TCG_PAIR_ADDSUB(sssub, MO_16, VddV_off, VuuV_off, VvvV_off)
+    fGEN_TCG_PAIR_ADDSUB(sssub, MO_16, VddV_base, VddV_off, \
+                         VuuV_base, VuuV_off, VvvV_base, VvvV_off)

 #define fGEN_TCG_V6_vsubwsat_dv(SHORTCODE) \
-    fGEN_TCG_PAIR_ADDSUB(sssub, MO_32, VddV_off, VuuV_off, VvvV_off)
+    fGEN_TCG_PAIR_ADDSUB(sssub, MO_32, VddV_base, VddV_off, \
+                         VuuV_base, VuuV_off, VvvV_base, VvvV_off)

 #define fGEN_TCG_V6_vsububsat_dv(SHORTCODE) \
-    fGEN_TCG_PAIR_ADDSUB(ussub, MO_8, VddV_off, VuuV_off, VvvV_off)
+    fGEN_TCG_PAIR_ADDSUB(ussub, MO_8, VddV_base, VddV_off, \
+                         VuuV_base, VuuV_off, VvvV_base, VvvV_off)

 #define fGEN_TCG_V6_vsubuhsat_dv(SHORTCODE) \
-    fGEN_TCG_PAIR_ADDSUB(ussub, MO_16, VddV_off, VuuV_off, VvvV_off)
+    fGEN_TCG_PAIR_ADDSUB(ussub, MO_16, VddV_base, VddV_off, \
+                         VuuV_base, VuuV_off, VvvV_base, VvvV_off)

 #define fGEN_TCG_V6_vsubuwsat_dv(SHORTCODE) \
-    fGEN_TCG_PAIR_ADDSUB(ussub, MO_32, VddV_off, VuuV_off, VvvV_off)
+    fGEN_TCG_PAIR_ADDSUB(ussub, MO_32, VddV_base, VddV_off, \
+                         VuuV_base, VuuV_off, VvvV_base, VvvV_off)

 #define fGEN_TCG_V6_vmpyih(SHORTCODE) \
-    tcg_gen_gvec_mul(MO_16, VdV_off, VuV_off, VvV_off, \
-                     VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE)
+    tcg_gen_gvec_mul_var(MO_16, VdV_base, VdV_off, VuV_base, VuV_off, \
+                        VvV_base, VvV_off, \
+                        VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE)

 #define fGEN_TCG_V6_vabsdiffub(SHORTCODE) \
-    gen_gvec_uabsdiff(MO_8, VdV_off, VuV_off, VvV_off, \
-                     VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE)
+    gen_gvec_uabsdiff_var(MO_8, VdV_base, VdV_off, VuV_base, VuV_off, \
+                        VvV_base, VvV_off, \
+                        VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE)

 #define fGEN_TCG_V6_vabsdiffuh(SHORTCODE) \
-    gen_gvec_uabsdiff(MO_16, VdV_off, VuV_off, VvV_off, \
-                     VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE)
+    gen_gvec_uabsdiff_var(MO_16, VdV_base, VdV_off, VuV_base, VuV_off, \
+                        VvV_base, VvV_off, \
+                        VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE)

 #define fGEN_TCG_V6_vabsdiffh(SHORTCODE) \
-    gen_gvec_sabsdiff(MO_16, VdV_off, VuV_off, VvV_off, \
-                     VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE)
+    gen_gvec_sabsdiff_var(MO_16, VdV_base, VdV_off, VuV_base, VuV_off, \
+                        VvV_base, VvV_off, \
+                        VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE)

 #define fGEN_TCG_V6_vabsdiffw(SHORTCODE) \
-    gen_gvec_sabsdiff(MO_32, VdV_off, VuV_off, VvV_off, \
-                     VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE)
+    gen_gvec_sabsdiff_var(MO_32, VdV_base, VdV_off, VuV_base, VuV_off, \
+                        VvV_base, VvV_off, \
+                        VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE)

 #define fGEN_TCG_VEC_AVG(VECE, SHIFT_FN) \
     do { \
         intptr_t tmpoff = offsetof(CPUHexagonState, vtmp); \
-        tcg_gen_gvec_and(MO_64, tmpoff, VuV_off, VvV_off, \
-                         VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE); \
-        tcg_gen_gvec_xor(MO_64, VdV_off, VuV_off, VvV_off, \
-                         VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE); \
-        SHIFT_FN(VECE, VdV_off, VdV_off, 1, \
+        tcg_gen_gvec_and_var(MO_64, tcg_env, tmpoff, VuV_base, VuV_off, \
+                            VvV_base, VvV_off, \
+                            VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE); \
+        tcg_gen_gvec_xor_var(MO_64, VdV_base, VdV_off, VuV_base, VuV_off, \
+                             VvV_base, VvV_off, \
+                             VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE); \
+        SHIFT_FN(VECE, VdV_base, VdV_off, VdV_base, VdV_off, 1, \
                  VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE); \
-        tcg_gen_gvec_add(VECE, VdV_off, tmpoff, VdV_off, \
-                         VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE); \
+        tcg_gen_gvec_add_var(VECE, VdV_base, VdV_off, tcg_env, tmpoff, \
+                             VdV_base, VdV_off, \
+                             VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE); \
     } while (0)

 #define fGEN_TCG_V6_vavgub(SHORTCODE) \
-    fGEN_TCG_VEC_AVG(MO_8, tcg_gen_gvec_shri)
+    fGEN_TCG_VEC_AVG(MO_8, tcg_gen_gvec_shri_var)

 #define fGEN_TCG_V6_vavguh(SHORTCODE) \
-    fGEN_TCG_VEC_AVG(MO_16, tcg_gen_gvec_shri)
+    fGEN_TCG_VEC_AVG(MO_16, tcg_gen_gvec_shri_var)

 #define fGEN_TCG_V6_vavguw(SHORTCODE) \
-    fGEN_TCG_VEC_AVG(MO_32, tcg_gen_gvec_shri)
+    fGEN_TCG_VEC_AVG(MO_32, tcg_gen_gvec_shri_var)

 #define fGEN_TCG_V6_vavgb(SHORTCODE) \
-    fGEN_TCG_VEC_AVG(MO_8, tcg_gen_gvec_sari)
+    fGEN_TCG_VEC_AVG(MO_8, tcg_gen_gvec_sari_var)

 #define fGEN_TCG_V6_vavgh(SHORTCODE) \
-    fGEN_TCG_VEC_AVG(MO_16, tcg_gen_gvec_sari)
+    fGEN_TCG_VEC_AVG(MO_16, tcg_gen_gvec_sari_var)

 #define fGEN_TCG_V6_vavgw(SHORTCODE) \
-    fGEN_TCG_VEC_AVG(MO_32, tcg_gen_gvec_sari)
+    fGEN_TCG_VEC_AVG(MO_32, tcg_gen_gvec_sari_var)

 #define fGEN_TCG_VEC_AVGRND(VECE, SHIFT_FN) \
     do { \
         intptr_t tmpoff = offsetof(CPUHexagonState, vtmp); \
-        tcg_gen_gvec_or(MO_64, tmpoff, VuV_off, VvV_off, \
-                        VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE); \
-        tcg_gen_gvec_xor(MO_64, VdV_off, VuV_off, VvV_off, \
-                         VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE); \
-        SHIFT_FN(VECE, VdV_off, VdV_off, 1, \
+        tcg_gen_gvec_or_var(MO_64, tcg_env, tmpoff, VuV_base, VuV_off, \
+                           VvV_base, VvV_off, \
+                           VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE); \
+        tcg_gen_gvec_xor_var(MO_64, VdV_base, VdV_off, VuV_base, VuV_off, \
+                             VvV_base, VvV_off, \
+                             VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE); \
+        SHIFT_FN(VECE, VdV_base, VdV_off, VdV_base, VdV_off, 1, \
                  VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE); \
-        tcg_gen_gvec_sub(VECE, VdV_off, tmpoff, VdV_off, \
-                         VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE); \
+        tcg_gen_gvec_sub_var(VECE, VdV_base, VdV_off, tcg_env, tmpoff, \
+                             VdV_base, VdV_off, \
+                             VECTOR_SIZE_BYTE, VECTOR_SIZE_BYTE); \
     } while (0)

 #define fGEN_TCG_V6_vavgubrnd(SHORTCODE) \
-    fGEN_TCG_VEC_AVGRND(MO_8, tcg_gen_gvec_shri)
+    fGEN_TCG_VEC_AVGRND(MO_8, tcg_gen_gvec_shri_var)

 #define fGEN_TCG_V6_vavguhrnd(SHORTCODE) \
-    fGEN_TCG_VEC_AVGRND(MO_16, tcg_gen_gvec_shri)
+    fGEN_TCG_VEC_AVGRND(MO_16, tcg_gen_gvec_shri_var)

 #define fGEN_TCG_V6_vavguwrnd(SHORTCODE) \
-    fGEN_TCG_VEC_AVGRND(MO_32, tcg_gen_gvec_shri)
+    fGEN_TCG_VEC_AVGRND(MO_32, tcg_gen_gvec_shri_var)

 #define fGEN_TCG_V6_vavgbrnd(SHORTCODE) \
-    fGEN_TCG_VEC_AVGRND(MO_8, tcg_gen_gvec_sari)
+    fGEN_TCG_VEC_AVGRND(MO_8, tcg_gen_gvec_sari_var)

 #define fGEN_TCG_V6_vavghrnd(SHORTCODE) \
-    fGEN_TCG_VEC_AVGRND(MO_16, tcg_gen_gvec_sari)
+    fGEN_TCG_VEC_AVGRND(MO_16, tcg_gen_gvec_sari_var)

 #define fGEN_TCG_V6_vavgwrnd(SHORTCODE) \
-    fGEN_TCG_VEC_AVGRND(MO_32, tcg_gen_gvec_sari)
+    fGEN_TCG_VEC_AVGRND(MO_32, tcg_gen_gvec_sari_var)

 /* Vector shift right - various forms */
 #define fGEN_TCG_V6_vasrh(SHORTCODE) \
     do { \
         TCGv shift = tcg_temp_new(); \
         tcg_gen_andi_tl(shift, RtV, 15); \
-        tcg_gen_gvec_sars(MO_16, VdV_off, VuV_off, shift, \
-                          sizeof(MMVector), sizeof(MMVector)); \
+        tcg_gen_gvec_sars_var(MO_16, VdV_base, VdV_off, VuV_base, VuV_off, \
+                              shift, sizeof(MMVector), sizeof(MMVector)); \
     } while (0)

 #define fGEN_TCG_V6_vasrh_acc(SHORTCODE) \
@@ -418,18 +466,19 @@ static inline void assert_vhist_tmp(DisasContext *ctx)
         intptr_t tmpoff = offsetof(CPUHexagonState, vtmp); \
         TCGv shift = tcg_temp_new(); \
         tcg_gen_andi_tl(shift, RtV, 15); \
-        tcg_gen_gvec_sars(MO_16, tmpoff, VuV_off, shift, \
-                          sizeof(MMVector), sizeof(MMVector)); \
-        tcg_gen_gvec_add(MO_16, VxV_off, VxV_off, tmpoff, \
-                         sizeof(MMVector), sizeof(MMVector)); \
+        tcg_gen_gvec_sars_var(MO_16, tcg_env, tmpoff, VuV_base, VuV_off, \
+                              shift, sizeof(MMVector), sizeof(MMVector)); \
+        tcg_gen_gvec_add_var(MO_16, VxV_base, VxV_off, VxV_base, VxV_off, \
+                             tcg_env, tmpoff, sizeof(MMVector), \
+                             sizeof(MMVector)); \
     } while (0)

 #define fGEN_TCG_V6_vasrw(SHORTCODE) \
     do { \
         TCGv shift = tcg_temp_new(); \
         tcg_gen_andi_tl(shift, RtV, 31); \
-        tcg_gen_gvec_sars(MO_32, VdV_off, VuV_off, shift, \
-                          sizeof(MMVector), sizeof(MMVector)); \
+        tcg_gen_gvec_sars_var(MO_32, VdV_base, VdV_off, VuV_base, VuV_off, \
+                              shift, sizeof(MMVector), sizeof(MMVector)); \
     } while (0)

 #define fGEN_TCG_V6_vasrw_acc(SHORTCODE) \
@@ -437,34 +486,35 @@ static inline void assert_vhist_tmp(DisasContext *ctx)
         intptr_t tmpoff = offsetof(CPUHexagonState, vtmp); \
         TCGv shift = tcg_temp_new(); \
         tcg_gen_andi_tl(shift, RtV, 31); \
-        tcg_gen_gvec_sars(MO_32, tmpoff, VuV_off, shift, \
-                          sizeof(MMVector), sizeof(MMVector)); \
-        tcg_gen_gvec_add(MO_32, VxV_off, VxV_off, tmpoff, \
-                          sizeof(MMVector), sizeof(MMVector)); \
+        tcg_gen_gvec_sars_var(MO_32, tcg_env, tmpoff, VuV_base, VuV_off, \
+                              shift, sizeof(MMVector), sizeof(MMVector)); \
+        tcg_gen_gvec_add_var(MO_32, VxV_base, VxV_off, VxV_base, VxV_off, \
+                             tcg_env, tmpoff, sizeof(MMVector), \
+                             sizeof(MMVector)); \
     } while (0)

 #define fGEN_TCG_V6_vlsrb(SHORTCODE) \
     do { \
         TCGv shift = tcg_temp_new(); \
         tcg_gen_andi_tl(shift, RtV, 7); \
-        tcg_gen_gvec_shrs(MO_8, VdV_off, VuV_off, shift, \
-                          sizeof(MMVector), sizeof(MMVector)); \
+        tcg_gen_gvec_shrs_var(MO_8, VdV_base, VdV_off, VuV_base, VuV_off, \
+                              shift, sizeof(MMVector), sizeof(MMVector)); \
     } while (0)

 #define fGEN_TCG_V6_vlsrh(SHORTCODE) \
     do { \
         TCGv shift = tcg_temp_new(); \
         tcg_gen_andi_tl(shift, RtV, 15); \
-        tcg_gen_gvec_shrs(MO_16, VdV_off, VuV_off, shift, \
-                          sizeof(MMVector), sizeof(MMVector)); \
+        tcg_gen_gvec_shrs_var(MO_16, VdV_base, VdV_off, VuV_base, VuV_off, \
+                              shift, sizeof(MMVector), sizeof(MMVector)); \
     } while (0)

 #define fGEN_TCG_V6_vlsrw(SHORTCODE) \
     do { \
         TCGv shift = tcg_temp_new(); \
         tcg_gen_andi_tl(shift, RtV, 31); \
-        tcg_gen_gvec_shrs(MO_32, VdV_off, VuV_off, shift, \
-                          sizeof(MMVector), sizeof(MMVector)); \
+        tcg_gen_gvec_shrs_var(MO_32, VdV_base, VdV_off, VuV_base, VuV_off, \
+                              shift, sizeof(MMVector), sizeof(MMVector)); \
     } while (0)

 /* Vector shift left - various forms */
@@ -472,16 +522,16 @@ static inline void assert_vhist_tmp(DisasContext *ctx)
     do { \
         TCGv shift = tcg_temp_new(); \
         tcg_gen_andi_tl(shift, RtV, 7); \
-        tcg_gen_gvec_shls(MO_8, VdV_off, VuV_off, shift, \
-                          sizeof(MMVector), sizeof(MMVector)); \
+        tcg_gen_gvec_shls_var(MO_8, VdV_base, VdV_off, VuV_base, VuV_off, \
+                              shift, sizeof(MMVector), sizeof(MMVector)); \
     } while (0)

 #define fGEN_TCG_V6_vaslh(SHORTCODE) \
     do { \
         TCGv shift = tcg_temp_new(); \
         tcg_gen_andi_tl(shift, RtV, 15); \
-        tcg_gen_gvec_shls(MO_16, VdV_off, VuV_off, shift, \
-                          sizeof(MMVector), sizeof(MMVector)); \
+        tcg_gen_gvec_shls_var(MO_16, VdV_base, VdV_off, VuV_base, VuV_off, \
+                              shift, sizeof(MMVector), sizeof(MMVector)); \
     } while (0)

 #define fGEN_TCG_V6_vaslh_acc(SHORTCODE) \
@@ -489,18 +539,19 @@ static inline void assert_vhist_tmp(DisasContext *ctx)
         intptr_t tmpoff = offsetof(CPUHexagonState, vtmp); \
         TCGv shift = tcg_temp_new(); \
         tcg_gen_andi_tl(shift, RtV, 15); \
-        tcg_gen_gvec_shls(MO_16, tmpoff, VuV_off, shift, \
-                          sizeof(MMVector), sizeof(MMVector)); \
-        tcg_gen_gvec_add(MO_16, VxV_off, VxV_off, tmpoff, \
-                         sizeof(MMVector), sizeof(MMVector)); \
+        tcg_gen_gvec_shls_var(MO_16, tcg_env, tmpoff, VuV_base, VuV_off, \
+                              shift, sizeof(MMVector), sizeof(MMVector)); \
+        tcg_gen_gvec_add_var(MO_16, VxV_base, VxV_off, VxV_base, VxV_off, \
+                             tcg_env, tmpoff, sizeof(MMVector), \
+                             sizeof(MMVector)); \
     } while (0)

 #define fGEN_TCG_V6_vaslw(SHORTCODE) \
     do { \
         TCGv shift = tcg_temp_new(); \
         tcg_gen_andi_tl(shift, RtV, 31); \
-        tcg_gen_gvec_shls(MO_32, VdV_off, VuV_off, shift, \
-                          sizeof(MMVector), sizeof(MMVector)); \
+        tcg_gen_gvec_shls_var(MO_32, VdV_base, VdV_off, VuV_base, VuV_off, \
+                              shift, sizeof(MMVector), sizeof(MMVector)); \
     } while (0)

 #define fGEN_TCG_V6_vaslw_acc(SHORTCODE) \
@@ -508,95 +559,109 @@ static inline void assert_vhist_tmp(DisasContext *ctx)
         intptr_t tmpoff = offsetof(CPUHexagonState, vtmp); \
         TCGv shift = tcg_temp_new(); \
         tcg_gen_andi_tl(shift, RtV, 31); \
-        tcg_gen_gvec_shls(MO_32, tmpoff, VuV_off, shift, \
-                          sizeof(MMVector), sizeof(MMVector)); \
-        tcg_gen_gvec_add(MO_32, VxV_off, VxV_off, tmpoff, \
-                         sizeof(MMVector), sizeof(MMVector)); \
+        tcg_gen_gvec_shls_var(MO_32, tcg_env, tmpoff, VuV_base, VuV_off, \
+                              shift, sizeof(MMVector), sizeof(MMVector)); \
+        tcg_gen_gvec_add_var(MO_32, VxV_base, VxV_off, VxV_base, VxV_off, \
+                             tcg_env, tmpoff, sizeof(MMVector), \
+                             sizeof(MMVector)); \
     } while (0)

 /* Vector max - various forms */
 #define fGEN_TCG_V6_vmaxw(SHORTCODE) \
-    tcg_gen_gvec_smax(MO_32, VdV_off, VuV_off, VvV_off, \
-                      sizeof(MMVector), sizeof(MMVector))
+    tcg_gen_gvec_smax_var(MO_32, VdV_base, VdV_off, VuV_base, VuV_off, \
+                          VvV_base, VvV_off, sizeof(MMVector), \
+                          sizeof(MMVector))
 #define fGEN_TCG_V6_vmaxh(SHORTCODE) \
-    tcg_gen_gvec_smax(MO_16, VdV_off, VuV_off, VvV_off, \
-                      sizeof(MMVector), sizeof(MMVector))
+    tcg_gen_gvec_smax_var(MO_16, VdV_base, VdV_off, VuV_base, VuV_off, \
+                          VvV_base, VvV_off, sizeof(MMVector), \
+                          sizeof(MMVector))
 #define fGEN_TCG_V6_vmaxuh(SHORTCODE) \
-    tcg_gen_gvec_umax(MO_16, VdV_off, VuV_off, VvV_off, \
-                      sizeof(MMVector), sizeof(MMVector))
+    tcg_gen_gvec_umax_var(MO_16, VdV_base, VdV_off, VuV_base, VuV_off, \
+                          VvV_base, VvV_off, sizeof(MMVector), \
+                          sizeof(MMVector))
 #define fGEN_TCG_V6_vmaxb(SHORTCODE) \
-    tcg_gen_gvec_smax(MO_8, VdV_off, VuV_off, VvV_off, \
-                      sizeof(MMVector), sizeof(MMVector))
+    tcg_gen_gvec_smax_var(MO_8, VdV_base, VdV_off, VuV_base, VuV_off, \
+                          VvV_base, VvV_off, sizeof(MMVector), \
+                          sizeof(MMVector))
 #define fGEN_TCG_V6_vmaxub(SHORTCODE) \
-    tcg_gen_gvec_umax(MO_8, VdV_off, VuV_off, VvV_off, \
-                      sizeof(MMVector), sizeof(MMVector))
+    tcg_gen_gvec_umax_var(MO_8, VdV_base, VdV_off, VuV_base, VuV_off, \
+                          VvV_base, VvV_off, sizeof(MMVector), \
+                          sizeof(MMVector))

 /* Vector min - various forms */
 #define fGEN_TCG_V6_vminw(SHORTCODE) \
-    tcg_gen_gvec_smin(MO_32, VdV_off, VuV_off, VvV_off, \
-                      sizeof(MMVector), sizeof(MMVector))
+    tcg_gen_gvec_smin_var(MO_32, VdV_base, VdV_off, VuV_base, VuV_off, \
+                          VvV_base, VvV_off, sizeof(MMVector), \
+                          sizeof(MMVector))
 #define fGEN_TCG_V6_vminh(SHORTCODE) \
-    tcg_gen_gvec_smin(MO_16, VdV_off, VuV_off, VvV_off, \
-                      sizeof(MMVector), sizeof(MMVector))
+    tcg_gen_gvec_smin_var(MO_16, VdV_base, VdV_off, VuV_base, VuV_off, \
+                          VvV_base, VvV_off, sizeof(MMVector), \
+                          sizeof(MMVector))
 #define fGEN_TCG_V6_vminuh(SHORTCODE) \
-    tcg_gen_gvec_umin(MO_16, VdV_off, VuV_off, VvV_off, \
-                      sizeof(MMVector), sizeof(MMVector))
+    tcg_gen_gvec_umin_var(MO_16, VdV_base, VdV_off, VuV_base, VuV_off, \
+                          VvV_base, VvV_off, sizeof(MMVector), \
+                          sizeof(MMVector))
 #define fGEN_TCG_V6_vminb(SHORTCODE) \
-    tcg_gen_gvec_smin(MO_8, VdV_off, VuV_off, VvV_off, \
-                      sizeof(MMVector), sizeof(MMVector))
+    tcg_gen_gvec_smin_var(MO_8, VdV_base, VdV_off, VuV_base, VuV_off, \
+                          VvV_base, VvV_off, sizeof(MMVector), \
+                          sizeof(MMVector))
 #define fGEN_TCG_V6_vminub(SHORTCODE) \
-    tcg_gen_gvec_umin(MO_8, VdV_off, VuV_off, VvV_off, \
-                      sizeof(MMVector), sizeof(MMVector))
+    tcg_gen_gvec_umin_var(MO_8, VdV_base, VdV_off, VuV_base, VuV_off, \
+                          VvV_base, VvV_off, sizeof(MMVector), \
+                          sizeof(MMVector))

 /* Vector logical ops */
 #define fGEN_TCG_V6_vxor(SHORTCODE) \
-    tcg_gen_gvec_xor(MO_64, VdV_off, VuV_off, VvV_off, \
-                     sizeof(MMVector), sizeof(MMVector))
+    tcg_gen_gvec_xor_var(MO_64, VdV_base, VdV_off, VuV_base, VuV_off, \
+                         VvV_base, VvV_off, sizeof(MMVector), \
+                         sizeof(MMVector))

 #define fGEN_TCG_V6_vand(SHORTCODE) \
-    tcg_gen_gvec_and(MO_64, VdV_off, VuV_off, VvV_off, \
-                     sizeof(MMVector), sizeof(MMVector))
+    tcg_gen_gvec_and_var(MO_64, VdV_base, VdV_off, VuV_base, VuV_off, \
+                         VvV_base, VvV_off, sizeof(MMVector), \
+                         sizeof(MMVector))

 #define fGEN_TCG_V6_vor(SHORTCODE) \
-    tcg_gen_gvec_or(MO_64, VdV_off, VuV_off, VvV_off, \
-                    sizeof(MMVector), sizeof(MMVector))
+    tcg_gen_gvec_or_var(MO_64, VdV_base, VdV_off, VuV_base, VuV_off, VvV_base, \
+                        VvV_off, sizeof(MMVector), sizeof(MMVector))

 #define fGEN_TCG_V6_vnot(SHORTCODE) \
-    tcg_gen_gvec_not(MO_64, VdV_off, VuV_off, \
-                     sizeof(MMVector), sizeof(MMVector))
+    tcg_gen_gvec_not_var(MO_64, VdV_base, VdV_off, VuV_base, VuV_off, \
+                         sizeof(MMVector), sizeof(MMVector))

 /* Q register logical ops */
 #define fGEN_TCG_V6_pred_or(SHORTCODE) \
-    tcg_gen_gvec_or(MO_64, QdV_off, QsV_off, QtV_off, \
-                    sizeof(MMQReg), sizeof(MMQReg))
+    tcg_gen_gvec_or_var(MO_64, QdV_base, QdV_off, QsV_base, QsV_off, QtV_base, \
+                        QtV_off, sizeof(MMQReg), sizeof(MMQReg))

 #define fGEN_TCG_V6_pred_and(SHORTCODE) \
-    tcg_gen_gvec_and(MO_64, QdV_off, QsV_off, QtV_off, \
-                     sizeof(MMQReg), sizeof(MMQReg))
+    tcg_gen_gvec_and_var(MO_64, QdV_base, QdV_off, QsV_base, QsV_off, \
+                         QtV_base, QtV_off, sizeof(MMQReg), sizeof(MMQReg))

 #define fGEN_TCG_V6_pred_xor(SHORTCODE) \
-    tcg_gen_gvec_xor(MO_64, QdV_off, QsV_off, QtV_off, \
-                     sizeof(MMQReg), sizeof(MMQReg))
+    tcg_gen_gvec_xor_var(MO_64, QdV_base, QdV_off, QsV_base, QsV_off, \
+                         QtV_base, QtV_off, sizeof(MMQReg), sizeof(MMQReg))

 #define fGEN_TCG_V6_pred_or_n(SHORTCODE) \
-    tcg_gen_gvec_orc(MO_64, QdV_off, QsV_off, QtV_off, \
-                     sizeof(MMQReg), sizeof(MMQReg))
+    tcg_gen_gvec_orc_var(MO_64, QdV_base, QdV_off, QsV_base, QsV_off, \
+                         QtV_base, QtV_off, sizeof(MMQReg), sizeof(MMQReg))

 #define fGEN_TCG_V6_pred_and_n(SHORTCODE) \
-    tcg_gen_gvec_andc(MO_64, QdV_off, QsV_off, QtV_off, \
-                      sizeof(MMQReg), sizeof(MMQReg))
+    tcg_gen_gvec_andc_var(MO_64, QdV_base, QdV_off, QsV_base, QsV_off, \
+                          QtV_base, QtV_off, sizeof(MMQReg), sizeof(MMQReg))

 #define fGEN_TCG_V6_pred_not(SHORTCODE) \
-    tcg_gen_gvec_not(MO_64, QdV_off, QsV_off, \
-                     sizeof(MMQReg), sizeof(MMQReg))
+    tcg_gen_gvec_not_var(MO_64, QdV_base, QdV_off, QsV_base, QsV_off, \
+                         sizeof(MMQReg), sizeof(MMQReg))

 /* Vector compares */
 #define fGEN_TCG_VEC_CMP(COND, TYPE, SIZE) \
     do { \
         intptr_t tmpoff = offsetof(CPUHexagonState, vtmp); \
-        tcg_gen_gvec_cmp(COND, TYPE, tmpoff, VuV_off, VvV_off, \
-                         sizeof(MMVector), sizeof(MMVector)); \
-        vec_to_qvec(SIZE, QdV_off, tmpoff); \
+        tcg_gen_gvec_cmp_var(COND, TYPE, tcg_env, tmpoff, VuV_base, VuV_off, \
+                             VvV_base, VvV_off, sizeof(MMVector), \
+                             sizeof(MMVector)); \
+        vec_to_qvec(SIZE, QdV_base, QdV_off, tcg_env, tmpoff); \
     } while (0)

 #define fGEN_TCG_V6_vgtw(SHORTCODE) \
@@ -624,100 +689,102 @@ static inline void assert_vhist_tmp(DisasContext *ctx)
     do { \
         intptr_t tmpoff = offsetof(CPUHexagonState, vtmp); \
         intptr_t qoff = offsetof(CPUHexagonState, qtmp); \
-        tcg_gen_gvec_cmp(COND, TYPE, tmpoff, VuV_off, VvV_off, \
-                         sizeof(MMVector), sizeof(MMVector)); \
-        vec_to_qvec(SIZE, qoff, tmpoff); \
-        OP(MO_64, QxV_off, QxV_off, qoff, sizeof(MMQReg), sizeof(MMQReg)); \
+        tcg_gen_gvec_cmp_var(COND, TYPE, tcg_env, tmpoff, VuV_base, VuV_off, \
+                             VvV_base, VvV_off, sizeof(MMVector), \
+                             sizeof(MMVector)); \
+        vec_to_qvec(SIZE, tcg_env, qoff, tcg_env, tmpoff); \
+        OP(MO_64, QxV_base, QxV_off, QxV_base, QxV_off, tcg_env, qoff, \
+           sizeof(MMQReg), sizeof(MMQReg)); \
     } while (0)

 #define fGEN_TCG_V6_vgtw_and(SHORTCODE) \
-    fGEN_TCG_VEC_CMP_OP(TCG_COND_GT, MO_32, 4, tcg_gen_gvec_and)
+    fGEN_TCG_VEC_CMP_OP(TCG_COND_GT, MO_32, 4, tcg_gen_gvec_and_var)
 #define fGEN_TCG_V6_vgtw_or(SHORTCODE) \
-    fGEN_TCG_VEC_CMP_OP(TCG_COND_GT, MO_32, 4, tcg_gen_gvec_or)
+    fGEN_TCG_VEC_CMP_OP(TCG_COND_GT, MO_32, 4, tcg_gen_gvec_or_var)
 #define fGEN_TCG_V6_vgtw_xor(SHORTCODE) \
-    fGEN_TCG_VEC_CMP_OP(TCG_COND_GT, MO_32, 4, tcg_gen_gvec_xor)
+    fGEN_TCG_VEC_CMP_OP(TCG_COND_GT, MO_32, 4, tcg_gen_gvec_xor_var)

 #define fGEN_TCG_V6_vgtuw_and(SHORTCODE) \
-    fGEN_TCG_VEC_CMP_OP(TCG_COND_GTU, MO_32, 4, tcg_gen_gvec_and)
+    fGEN_TCG_VEC_CMP_OP(TCG_COND_GTU, MO_32, 4, tcg_gen_gvec_and_var)
 #define fGEN_TCG_V6_vgtuw_or(SHORTCODE) \
-    fGEN_TCG_VEC_CMP_OP(TCG_COND_GTU, MO_32, 4, tcg_gen_gvec_or)
+    fGEN_TCG_VEC_CMP_OP(TCG_COND_GTU, MO_32, 4, tcg_gen_gvec_or_var)
 #define fGEN_TCG_V6_vgtuw_xor(SHORTCODE) \
-    fGEN_TCG_VEC_CMP_OP(TCG_COND_GTU, MO_32, 4, tcg_gen_gvec_xor)
+    fGEN_TCG_VEC_CMP_OP(TCG_COND_GTU, MO_32, 4, tcg_gen_gvec_xor_var)

 #define fGEN_TCG_V6_vgth_and(SHORTCODE) \
-    fGEN_TCG_VEC_CMP_OP(TCG_COND_GT, MO_16, 2, tcg_gen_gvec_and)
+    fGEN_TCG_VEC_CMP_OP(TCG_COND_GT, MO_16, 2, tcg_gen_gvec_and_var)
 #define fGEN_TCG_V6_vgth_or(SHORTCODE) \
-    fGEN_TCG_VEC_CMP_OP(TCG_COND_GT, MO_16, 2, tcg_gen_gvec_or)
+    fGEN_TCG_VEC_CMP_OP(TCG_COND_GT, MO_16, 2, tcg_gen_gvec_or_var)
 #define fGEN_TCG_V6_vgth_xor(SHORTCODE) \
-    fGEN_TCG_VEC_CMP_OP(TCG_COND_GT, MO_16, 2, tcg_gen_gvec_xor)
+    fGEN_TCG_VEC_CMP_OP(TCG_COND_GT, MO_16, 2, tcg_gen_gvec_xor_var)

 #define fGEN_TCG_V6_vgtuh_and(SHORTCODE) \
-    fGEN_TCG_VEC_CMP_OP(TCG_COND_GTU, MO_16, 2, tcg_gen_gvec_and)
+    fGEN_TCG_VEC_CMP_OP(TCG_COND_GTU, MO_16, 2, tcg_gen_gvec_and_var)
 #define fGEN_TCG_V6_vgtuh_or(SHORTCODE) \
-    fGEN_TCG_VEC_CMP_OP(TCG_COND_GTU, MO_16, 2, tcg_gen_gvec_or)
+    fGEN_TCG_VEC_CMP_OP(TCG_COND_GTU, MO_16, 2, tcg_gen_gvec_or_var)
 #define fGEN_TCG_V6_vgtuh_xor(SHORTCODE) \
-    fGEN_TCG_VEC_CMP_OP(TCG_COND_GTU, MO_16, 2, tcg_gen_gvec_xor)
+    fGEN_TCG_VEC_CMP_OP(TCG_COND_GTU, MO_16, 2, tcg_gen_gvec_xor_var)

 #define fGEN_TCG_V6_vgtb_and(SHORTCODE) \
-    fGEN_TCG_VEC_CMP_OP(TCG_COND_GT, MO_8, 1, tcg_gen_gvec_and)
+    fGEN_TCG_VEC_CMP_OP(TCG_COND_GT, MO_8, 1, tcg_gen_gvec_and_var)
 #define fGEN_TCG_V6_vgtb_or(SHORTCODE) \
-    fGEN_TCG_VEC_CMP_OP(TCG_COND_GT, MO_8, 1, tcg_gen_gvec_or)
+    fGEN_TCG_VEC_CMP_OP(TCG_COND_GT, MO_8, 1, tcg_gen_gvec_or_var)
 #define fGEN_TCG_V6_vgtb_xor(SHORTCODE) \
-    fGEN_TCG_VEC_CMP_OP(TCG_COND_GT, MO_8, 1, tcg_gen_gvec_xor)
+    fGEN_TCG_VEC_CMP_OP(TCG_COND_GT, MO_8, 1, tcg_gen_gvec_xor_var)

 #define fGEN_TCG_V6_vgtub_and(SHORTCODE) \
-    fGEN_TCG_VEC_CMP_OP(TCG_COND_GTU, MO_8, 1, tcg_gen_gvec_and)
+    fGEN_TCG_VEC_CMP_OP(TCG_COND_GTU, MO_8, 1, tcg_gen_gvec_and_var)
 #define fGEN_TCG_V6_vgtub_or(SHORTCODE) \
-    fGEN_TCG_VEC_CMP_OP(TCG_COND_GTU, MO_8, 1, tcg_gen_gvec_or)
+    fGEN_TCG_VEC_CMP_OP(TCG_COND_GTU, MO_8, 1, tcg_gen_gvec_or_var)
 #define fGEN_TCG_V6_vgtub_xor(SHORTCODE) \
-    fGEN_TCG_VEC_CMP_OP(TCG_COND_GTU, MO_8, 1, tcg_gen_gvec_xor)
+    fGEN_TCG_VEC_CMP_OP(TCG_COND_GTU, MO_8, 1, tcg_gen_gvec_xor_var)

 #define fGEN_TCG_V6_veqw_and(SHORTCODE) \
-    fGEN_TCG_VEC_CMP_OP(TCG_COND_EQ, MO_32, 4, tcg_gen_gvec_and)
+    fGEN_TCG_VEC_CMP_OP(TCG_COND_EQ, MO_32, 4, tcg_gen_gvec_and_var)
 #define fGEN_TCG_V6_veqw_or(SHORTCODE) \
-    fGEN_TCG_VEC_CMP_OP(TCG_COND_EQ, MO_32, 4, tcg_gen_gvec_or)
+    fGEN_TCG_VEC_CMP_OP(TCG_COND_EQ, MO_32, 4, tcg_gen_gvec_or_var)
 #define fGEN_TCG_V6_veqw_xor(SHORTCODE) \
-    fGEN_TCG_VEC_CMP_OP(TCG_COND_EQ, MO_32, 4, tcg_gen_gvec_xor)
+    fGEN_TCG_VEC_CMP_OP(TCG_COND_EQ, MO_32, 4, tcg_gen_gvec_xor_var)

 #define fGEN_TCG_V6_veqh_and(SHORTCODE) \
-    fGEN_TCG_VEC_CMP_OP(TCG_COND_EQ, MO_16, 2, tcg_gen_gvec_and)
+    fGEN_TCG_VEC_CMP_OP(TCG_COND_EQ, MO_16, 2, tcg_gen_gvec_and_var)
 #define fGEN_TCG_V6_veqh_or(SHORTCODE) \
-    fGEN_TCG_VEC_CMP_OP(TCG_COND_EQ, MO_16, 2, tcg_gen_gvec_or)
+    fGEN_TCG_VEC_CMP_OP(TCG_COND_EQ, MO_16, 2, tcg_gen_gvec_or_var)
 #define fGEN_TCG_V6_veqh_xor(SHORTCODE) \
-    fGEN_TCG_VEC_CMP_OP(TCG_COND_EQ, MO_16, 2, tcg_gen_gvec_xor)
+    fGEN_TCG_VEC_CMP_OP(TCG_COND_EQ, MO_16, 2, tcg_gen_gvec_xor_var)

 #define fGEN_TCG_V6_veqb_and(SHORTCODE) \
-    fGEN_TCG_VEC_CMP_OP(TCG_COND_EQ, MO_8, 1, tcg_gen_gvec_and)
+    fGEN_TCG_VEC_CMP_OP(TCG_COND_EQ, MO_8, 1, tcg_gen_gvec_and_var)
 #define fGEN_TCG_V6_veqb_or(SHORTCODE) \
-    fGEN_TCG_VEC_CMP_OP(TCG_COND_EQ, MO_8, 1, tcg_gen_gvec_or)
+    fGEN_TCG_VEC_CMP_OP(TCG_COND_EQ, MO_8, 1, tcg_gen_gvec_or_var)
 #define fGEN_TCG_V6_veqb_xor(SHORTCODE) \
-    fGEN_TCG_VEC_CMP_OP(TCG_COND_EQ, MO_8, 1, tcg_gen_gvec_xor)
+    fGEN_TCG_VEC_CMP_OP(TCG_COND_EQ, MO_8, 1, tcg_gen_gvec_xor_var)

 /* Vector splat - various forms */
 #define fGEN_TCG_V6_lvsplatw(SHORTCODE) \
-    tcg_gen_gvec_dup_i32(MO_32, VdV_off, \
-                         sizeof(MMVector), sizeof(MMVector), RtV)
+    tcg_gen_gvec_dup_i32_var(MO_32, VdV_base, VdV_off, sizeof(MMVector), \
+                             sizeof(MMVector), RtV)

 #define fGEN_TCG_V6_lvsplath(SHORTCODE) \
-    tcg_gen_gvec_dup_i32(MO_16, VdV_off, \
-                         sizeof(MMVector), sizeof(MMVector), RtV)
+    tcg_gen_gvec_dup_i32_var(MO_16, VdV_base, VdV_off, sizeof(MMVector), \
+                             sizeof(MMVector), RtV)

 #define fGEN_TCG_V6_lvsplatb(SHORTCODE) \
-    tcg_gen_gvec_dup_i32(MO_8, VdV_off, \
-                         sizeof(MMVector), sizeof(MMVector), RtV)
+    tcg_gen_gvec_dup_i32_var(MO_8, VdV_base, VdV_off, sizeof(MMVector), \
+                             sizeof(MMVector), RtV)

 /* Vector absolute value - various forms */
 #define fGEN_TCG_V6_vabsb(SHORTCODE) \
-    tcg_gen_gvec_abs(MO_8, VdV_off, VuV_off, \
-                     sizeof(MMVector), sizeof(MMVector))
+    tcg_gen_gvec_abs_var(MO_8, VdV_base, VdV_off, VuV_base, VuV_off, \
+                         sizeof(MMVector), sizeof(MMVector))

 #define fGEN_TCG_V6_vabsh(SHORTCODE) \
-    tcg_gen_gvec_abs(MO_16, VdV_off, VuV_off, \
-                     sizeof(MMVector), sizeof(MMVector))
+    tcg_gen_gvec_abs_var(MO_16, VdV_base, VdV_off, VuV_base, VuV_off, \
+                         sizeof(MMVector), sizeof(MMVector))

 #define fGEN_TCG_V6_vabsw(SHORTCODE) \
-    tcg_gen_gvec_abs(MO_32, VdV_off, VuV_off, \
-                     sizeof(MMVector), sizeof(MMVector))
+    tcg_gen_gvec_abs_var(MO_32, VdV_base, VdV_off, VuV_base, VuV_off, \
+                         sizeof(MMVector), sizeof(MMVector))

 /* Vector loads */
 #define fGEN_TCG_V6_vL32b_pi(SHORTCODE)                    SHORTCODE
@@ -743,14 +810,14 @@ static inline void assert_vhist_tmp(DisasContext *ctx)
 #define fGEN_TCG_V6_vL32b_nt_tmp_ppu(SHORTCODE)            SHORTCODE

 /* Predicated vector loads */
-#define fGEN_TCG_PRED_VEC_LOAD(GET_EA, PRED, DSTOFF, INC) \
+#define fGEN_TCG_PRED_VEC_LOAD(GET_EA, PRED, DST, INC) \
     do { \
         TCGv LSB = tcg_temp_new(); \
         TCGLabel *false_label = gen_new_label(); \
         GET_EA; \
         PRED; \
         tcg_gen_brcondi_tl(TCG_COND_EQ, LSB, 0, false_label); \
-        gen_vreg_load(ctx, DSTOFF, EA, true); \
+        gen_vreg_load(ctx, DST##_base, DST##_off, EA, true); \
         INC; \
         gen_set_label(false_label); \
     } while (0)
@@ -758,12 +825,12 @@ static inline void assert_vhist_tmp(DisasContext *ctx)
 #define fGEN_TCG_PRED_VEC_LOAD_pred_pi \
     fGEN_TCG_PRED_VEC_LOAD(fLSBOLD(PvV), \
                            fEA_REG(RxV), \
-                           VdV_off, \
+                           VdV, \
                            fPM_I(RxV, siV * sizeof(MMVector)))
 #define fGEN_TCG_PRED_VEC_LOAD_npred_pi \
     fGEN_TCG_PRED_VEC_LOAD(fLSBOLDNOT(PvV), \
                            fEA_REG(RxV), \
-                           VdV_off, \
+                           VdV, \
                            fPM_I(RxV, siV * sizeof(MMVector)))

 #define fGEN_TCG_V6_vL32b_pred_pi(SHORTCODE) \
@@ -794,12 +861,12 @@ static inline void assert_vhist_tmp(DisasContext *ctx)
 #define fGEN_TCG_PRED_VEC_LOAD_pred_ai \
     fGEN_TCG_PRED_VEC_LOAD(fLSBOLD(PvV), \
                            fEA_RI(RtV, siV * sizeof(MMVector)), \
-                           VdV_off, \
+                           VdV, \
                            do {} while (0))
 #define fGEN_TCG_PRED_VEC_LOAD_npred_ai \
     fGEN_TCG_PRED_VEC_LOAD(fLSBOLDNOT(PvV), \
                            fEA_RI(RtV, siV * sizeof(MMVector)), \
-                           VdV_off, \
+                           VdV, \
                            do {} while (0))

 #define fGEN_TCG_V6_vL32b_pred_ai(SHORTCODE) \
@@ -830,12 +897,12 @@ static inline void assert_vhist_tmp(DisasContext *ctx)
 #define fGEN_TCG_PRED_VEC_LOAD_pred_ppu \
     fGEN_TCG_PRED_VEC_LOAD(fLSBOLD(PvV), \
                            fEA_REG(RxV), \
-                           VdV_off, \
+                           VdV, \
                            fPM_M(RxV, MuV))
 #define fGEN_TCG_PRED_VEC_LOAD_npred_ppu \
     fGEN_TCG_PRED_VEC_LOAD(fLSBOLDNOT(PvV), \
                            fEA_REG(RxV), \
-                           VdV_off, \
+                           VdV, \
                            fPM_M(RxV, MuV))

 #define fGEN_TCG_V6_vL32b_pred_ppu(SHORTCODE) \
@@ -878,7 +945,7 @@ static inline void assert_vhist_tmp(DisasContext *ctx)
 #define fGEN_TCG_NEWVAL_VEC_STORE(GET_EA, INC) \
     do { \
         GET_EA; \
-        gen_vreg_store(ctx, EA, OsN_off, insn->slot, true); \
+        gen_vreg_store(ctx, EA, OsN_base, OsN_off, insn->slot, true); \
         INC; \
     } while (0)

@@ -908,14 +975,15 @@ static inline void assert_vhist_tmp(DisasContext *ctx)
     fGEN_TCG_NEWVAL_VEC_STORE_ppu

 /* Predicated vector stores */
-#define fGEN_TCG_PRED_VEC_STORE(GET_EA, PRED, SRCOFF, ALIGN, INC) \
+#define fGEN_TCG_PRED_VEC_STORE(GET_EA, PRED, SRC, ALIGN, INC) \
     do { \
         TCGv LSB = tcg_temp_new(); \
         TCGLabel *false_label = gen_new_label(); \
         GET_EA; \
         PRED; \
         tcg_gen_brcondi_tl(TCG_COND_EQ, LSB, 0, false_label); \
-        gen_vreg_store(ctx, EA, SRCOFF, insn->slot, ALIGN); \
+        gen_vreg_store(ctx, EA, SRC##_base, SRC##_off, insn->slot, \
+                       ALIGN); \
         INC; \
         gen_set_label(false_label); \
     } while (0)
@@ -923,22 +991,22 @@ static inline void assert_vhist_tmp(DisasContext *ctx)
 #define fGEN_TCG_PRED_VEC_STORE_pred_pi(ALIGN) \
     fGEN_TCG_PRED_VEC_STORE(fLSBOLD(PvV), \
                             fEA_REG(RxV), \
-                            VsV_off, ALIGN, \
+                            VsV, ALIGN, \
                             fPM_I(RxV, siV * sizeof(MMVector)))
 #define fGEN_TCG_PRED_VEC_STORE_npred_pi(ALIGN) \
     fGEN_TCG_PRED_VEC_STORE(fLSBOLDNOT(PvV), \
                             fEA_REG(RxV), \
-                            VsV_off, ALIGN, \
+                            VsV, ALIGN, \
                             fPM_I(RxV, siV * sizeof(MMVector)))
 #define fGEN_TCG_PRED_VEC_STORE_new_pred_pi \
     fGEN_TCG_PRED_VEC_STORE(fLSBOLD(PvV), \
                             fEA_REG(RxV), \
-                            OsN_off, true, \
+                            OsN, true, \
                             fPM_I(RxV, siV * sizeof(MMVector)))
 #define fGEN_TCG_PRED_VEC_STORE_new_npred_pi \
     fGEN_TCG_PRED_VEC_STORE(fLSBOLDNOT(PvV), \
                             fEA_REG(RxV), \
-                            OsN_off, true, \
+                            OsN, true, \
                             fPM_I(RxV, siV * sizeof(MMVector)))

 #define fGEN_TCG_V6_vS32b_pred_pi(SHORTCODE) \
@@ -965,22 +1033,22 @@ static inline void assert_vhist_tmp(DisasContext *ctx)
 #define fGEN_TCG_PRED_VEC_STORE_pred_ai(ALIGN) \
     fGEN_TCG_PRED_VEC_STORE(fLSBOLD(PvV), \
                             fEA_RI(RtV, siV * sizeof(MMVector)), \
-                            VsV_off, ALIGN, \
+                            VsV, ALIGN, \
                             do { } while (0))
 #define fGEN_TCG_PRED_VEC_STORE_npred_ai(ALIGN) \
     fGEN_TCG_PRED_VEC_STORE(fLSBOLDNOT(PvV), \
                             fEA_RI(RtV, siV * sizeof(MMVector)), \
-                            VsV_off, ALIGN, \
+                            VsV, ALIGN, \
                             do { } while (0))
 #define fGEN_TCG_PRED_VEC_STORE_new_pred_ai \
     fGEN_TCG_PRED_VEC_STORE(fLSBOLD(PvV), \
                             fEA_RI(RtV, siV * sizeof(MMVector)), \
-                            OsN_off, true, \
+                            OsN, true, \
                             do { } while (0))
 #define fGEN_TCG_PRED_VEC_STORE_new_npred_ai \
     fGEN_TCG_PRED_VEC_STORE(fLSBOLDNOT(PvV), \
                             fEA_RI(RtV, siV * sizeof(MMVector)), \
-                            OsN_off, true, \
+                            OsN, true, \
                             do { } while (0))

 #define fGEN_TCG_V6_vS32b_pred_ai(SHORTCODE) \
@@ -1007,22 +1075,22 @@ static inline void assert_vhist_tmp(DisasContext *ctx)
 #define fGEN_TCG_PRED_VEC_STORE_pred_ppu(ALIGN) \
     fGEN_TCG_PRED_VEC_STORE(fLSBOLD(PvV), \
                             fEA_REG(RxV), \
-                            VsV_off, ALIGN, \
+                            VsV, ALIGN, \
                             fPM_M(RxV, MuV))
 #define fGEN_TCG_PRED_VEC_STORE_npred_ppu(ALIGN) \
     fGEN_TCG_PRED_VEC_STORE(fLSBOLDNOT(PvV), \
                             fEA_REG(RxV), \
-                            VsV_off, ALIGN, \
+                            VsV, ALIGN, \
                             fPM_M(RxV, MuV))
 #define fGEN_TCG_PRED_VEC_STORE_new_pred_ppu \
     fGEN_TCG_PRED_VEC_STORE(fLSBOLD(PvV), \
                             fEA_REG(RxV), \
-                            OsN_off, true, \
+                            OsN, true, \
                             fPM_M(RxV, MuV))
 #define fGEN_TCG_PRED_VEC_STORE_new_npred_ppu \
     fGEN_TCG_PRED_VEC_STORE(fLSBOLDNOT(PvV), \
                             fEA_REG(RxV), \
-                            OsN_off, true, \
+                            OsN, true, \
                             fPM_M(RxV, MuV))

 #define fGEN_TCG_V6_vS32b_pred_ppu(SHORTCODE) \
diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index 4e9a9670d5..e1330d8e0b 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -56,8 +56,10 @@ static void gen_sabsdiff_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
     tcg_gen_sub_vec(vece, d, d, t);
 }

-void gen_gvec_sabsdiff(unsigned vece, uint32_t dofs, uint32_t aofs,
-                       uint32_t bofs, uint32_t oprsz, uint32_t maxsz)
+void gen_gvec_sabsdiff_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_sub_vec, INDEX_op_smin_vec, INDEX_op_smax_vec, 0
@@ -75,7 +77,15 @@ void gen_gvec_sabsdiff(unsigned vece, uint32_t dofs, uint32_t aofs,
     };

     tcg_debug_assert(vece == MO_16 || vece == MO_32);
-    tcg_gen_gvec_3(dofs, aofs, bofs, oprsz, maxsz, &ops[vece]);
+    tcg_gen_gvec_3_var(dbase, dofs, abase, aofs, bbase, bofs,
+                       oprsz, maxsz, &ops[vece]);
+}
+
+void gen_gvec_sabsdiff(unsigned vece, uint32_t dofs, uint32_t aofs,
+                       uint32_t bofs, uint32_t oprsz, uint32_t maxsz)
+{
+    gen_gvec_sabsdiff_var(vece, tcg_env, dofs, tcg_env, aofs, tcg_env, bofs,
+                         oprsz, maxsz);
 }

 static void gen_uabsdiff_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
@@ -87,8 +97,10 @@ static void gen_uabsdiff_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
     tcg_gen_sub_vec(vece, d, d, t);
 }

-void gen_gvec_uabsdiff(unsigned vece, uint32_t dofs, uint32_t aofs,
-                       uint32_t bofs, uint32_t oprsz, uint32_t maxsz)
+void gen_gvec_uabsdiff_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_sub_vec, INDEX_op_umin_vec, INDEX_op_umax_vec, 0
@@ -105,7 +117,15 @@ void gen_gvec_uabsdiff(unsigned vece, uint32_t dofs, uint32_t aofs,
     };

     tcg_debug_assert(vece == MO_8 || vece == MO_16);
-    tcg_gen_gvec_3(dofs, aofs, bofs, oprsz, maxsz, &ops[vece]);
+    tcg_gen_gvec_3_var(dbase, dofs, abase, aofs, bbase, bofs,
+                       oprsz, maxsz, &ops[vece]);
+}
+
+void gen_gvec_uabsdiff(unsigned vece, uint32_t dofs, uint32_t aofs,
+                       uint32_t bofs, uint32_t oprsz, uint32_t maxsz)
+{
+    gen_gvec_uabsdiff_var(vece, tcg_env, dofs, tcg_env, aofs, tcg_env, bofs,
+                         oprsz, maxsz);
 }

 TCGv gen_read_reg(TCGv result, int num)
@@ -1435,54 +1455,56 @@ static void gen_asr_r_svw_trun(DisasContext *ctx, TCGv RdV,
     gen_set_label(done);
 }

-static intptr_t vreg_src_off(DisasContext *ctx, int num)
+static intptr_t vreg_src_off(DisasContext *ctx, int num, TCGv_ptr *base)
 {
-    intptr_t offset = offsetof(CPUHexagonState, VRegs[num]);
+    intptr_t offset = HEX_HVX_OFFSET(VRegs[num]);

+    *base = hex_hvx_ptr;
     if (test_bit(num, ctx->vregs_select)) {
-        offset = ctx_future_vreg_off(ctx, num, 1, false);
+        offset = ctx_future_vreg_off(ctx, num, 1, false, base);
     }
     if (test_bit(num, ctx->vregs_updated_tmp)) {
-        offset = ctx_tmp_vreg_off(ctx, num, 1, false);
+        offset = ctx_tmp_vreg_off(ctx, num, 1, false, base);
     }
     return offset;
 }

-static void gen_vreg_write(DisasContext *ctx, intptr_t srcoff, int num,
-                               VRegWriteType type)
+static void gen_vreg_write(DisasContext *ctx, TCGv_ptr srcbase,
+                           intptr_t srcoff, int num, VRegWriteType type)
 {
+    TCGv_ptr dstbase;
     intptr_t dstoff;

     if (type != EXT_TMP) {
-        dstoff = ctx_future_vreg_off(ctx, num, 1, true);
-        tcg_gen_gvec_mov(MO_64, dstoff, srcoff,
-                         sizeof(MMVector), sizeof(MMVector));
+        dstoff = ctx_future_vreg_off(ctx, num, 1, true, &dstbase);
     } else {
-        dstoff = ctx_tmp_vreg_off(ctx, num, 1, false);
-        tcg_gen_gvec_mov(MO_64, dstoff, srcoff,
-                         sizeof(MMVector), sizeof(MMVector));
+        dstoff = ctx_tmp_vreg_off(ctx, num, 1, false, &dstbase);
     }
+    tcg_gen_gvec_mov_var(MO_64, dstbase, dstoff, srcbase, srcoff,
+                         sizeof(MMVector), sizeof(MMVector));
 }

-static void gen_vreg_write_pair(DisasContext *ctx, intptr_t srcoff, int num,
-                                    VRegWriteType type)
+static void gen_vreg_write_pair(DisasContext *ctx, TCGv_ptr srcbase,
+                                intptr_t srcoff, int num, VRegWriteType type)
 {
-    gen_vreg_write(ctx, srcoff, num ^ 0, type);
+    gen_vreg_write(ctx, srcbase, srcoff, num ^ 0, type);
     srcoff += sizeof(MMVector);
-    gen_vreg_write(ctx, srcoff, num ^ 1, type);
+    gen_vreg_write(ctx, srcbase, srcoff, num ^ 1, type);
 }

-static intptr_t get_result_qreg(DisasContext *ctx, int qnum)
+static intptr_t get_result_qreg(DisasContext *ctx, int qnum, TCGv_ptr *base)
 {
     if (ctx->need_commit) {
+        *base = tcg_env;
         return  offsetof(CPUHexagonState, future_QRegs[qnum]);
     } else {
-        return  offsetof(CPUHexagonState, QRegs[qnum]);
+        *base = hex_hvx_ptr;
+        return HEX_HVX_OFFSET(QRegs[qnum]);
     }
 }

-static void gen_vreg_load(DisasContext *ctx, intptr_t dstoff, TCGv src,
-                          bool aligned)
+static void gen_vreg_load(DisasContext *ctx, TCGv_ptr dstbase,
+                          intptr_t dstoff, TCGv src, bool aligned)
 {
     TCGv_i64 tmp = tcg_temp_new_i64();
     if (aligned) {
@@ -1491,12 +1513,12 @@ static void gen_vreg_load(DisasContext *ctx, intptr_t dstoff, TCGv src,
     for (int i = 0; i < sizeof(MMVector) / 8; i++) {
         tcg_gen_qemu_ld_i64(tmp, src, ctx->mem_idx, MO_LE | MO_UQ);
         tcg_gen_addi_tl(src, src, 8);
-        tcg_gen_st_i64(tmp, tcg_env, dstoff + i * 8);
+        tcg_gen_st_i64(tmp, dstbase, dstoff + i * 8);
     }
 }

-static void gen_vreg_store(DisasContext *ctx, TCGv EA, intptr_t srcoff,
-                           int slot, bool aligned)
+static void gen_vreg_store(DisasContext *ctx, TCGv EA, TCGv_ptr srcbase,
+                           intptr_t srcoff, int slot, bool aligned)
 {
     intptr_t dstoff = offsetof(CPUHexagonState, vstore[slot].data);
     intptr_t maskoff = offsetof(CPUHexagonState, vstore[slot].mask);
@@ -1517,13 +1539,16 @@ static void gen_vreg_store(DisasContext *ctx, TCGv EA, intptr_t srcoff,
     tcg_gen_movi_tl(hex_vstore_size[slot], sizeof(MMVector));

     /* Copy the data to the vstore buffer */
-    tcg_gen_gvec_mov(MO_64, dstoff, srcoff, sizeof(MMVector), sizeof(MMVector));
+    tcg_gen_gvec_mov_var(MO_64, tcg_env, dstoff, srcbase, srcoff,
+                         sizeof(MMVector), sizeof(MMVector));
     /* Set the mask to all 1's */
     tcg_gen_gvec_dup_imm(MO_64, maskoff, sizeof(MMQReg), sizeof(MMQReg), ~0LL);
 }

-static void gen_vreg_masked_store(DisasContext *ctx, TCGv EA, intptr_t srcoff,
-                                  intptr_t bitsoff, int slot, bool invert)
+static void gen_vreg_masked_store(DisasContext *ctx, TCGv EA,
+                                  TCGv_ptr srcbase, intptr_t srcoff,
+                                  TCGv_ptr bitsbase, intptr_t bitsoff,
+                                  int slot, bool invert)
 {
     intptr_t dstoff = offsetof(CPUHexagonState, vstore[slot].data);
     intptr_t maskoff = offsetof(CPUHexagonState, vstore[slot].mask);
@@ -1534,16 +1559,19 @@ static void gen_vreg_masked_store(DisasContext *ctx, TCGv EA, intptr_t srcoff,
     tcg_gen_movi_tl(hex_vstore_size[slot], sizeof(MMVector));

     /* Copy the data to the vstore buffer */
-    tcg_gen_gvec_mov(MO_64, dstoff, srcoff, sizeof(MMVector), sizeof(MMVector));
+    tcg_gen_gvec_mov_var(MO_64, tcg_env, dstoff, srcbase, srcoff,
+                         sizeof(MMVector), sizeof(MMVector));
     /* Copy the mask */
-    tcg_gen_gvec_mov(MO_64, maskoff, bitsoff, sizeof(MMQReg), sizeof(MMQReg));
+    tcg_gen_gvec_mov_var(MO_64, tcg_env, maskoff, bitsbase, bitsoff,
+                         sizeof(MMQReg), sizeof(MMQReg));
     if (invert) {
         tcg_gen_gvec_not(MO_64, maskoff, maskoff,
                          sizeof(MMQReg), sizeof(MMQReg));
     }
 }

-static void vec_to_qvec(size_t size, intptr_t dstoff, intptr_t srcoff)
+static void vec_to_qvec(size_t size, TCGv_ptr dstbase, intptr_t dstoff,
+                        TCGv_ptr srcbase, intptr_t srcoff)
 {
     TCGv_i64 tmp = tcg_temp_new_i64();
     TCGv_i64 word = tcg_temp_new_i64();
@@ -1553,7 +1581,7 @@ static void vec_to_qvec(size_t size, intptr_t dstoff, intptr_t srcoff)
     TCGv_i64 ones = tcg_constant_i64(~0);

     for (int i = 0; i < sizeof(MMVector) / 8; i++) {
-        tcg_gen_ld_i64(tmp, tcg_env, srcoff + i * 8);
+        tcg_gen_ld_i64(tmp, srcbase, srcoff + i * 8);
         tcg_gen_movi_i64(mask, 0);

         for (int j = 0; j < 8; j += size) {
@@ -1562,7 +1590,7 @@ static void vec_to_qvec(size_t size, intptr_t dstoff, intptr_t srcoff)
             tcg_gen_deposit_i64(mask, mask, bits, j, size);
         }

-        tcg_gen_st8_i64(mask, tcg_env, dstoff + i);
+        tcg_gen_st8_i64(mask, dstbase, dstoff + i);
     }
 }

diff --git a/target/hexagon/genptr.h b/target/hexagon/genptr.h
index f498398367..238ee089cb 100644
--- a/target/hexagon/genptr.h
+++ b/target/hexagon/genptr.h
@@ -59,6 +59,14 @@ TCGv gen_get_half(TCGv result, int N, TCGv src, bool sign);
 void gen_set_half(int N, TCGv result, TCGv src);
 void gen_set_half_i64(int N, TCGv_i64 result, TCGv src);
 void probe_noshuf_load(TCGv va, int s, int mi);
+void gen_gvec_sabsdiff_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 gen_gvec_uabsdiff_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 gen_gvec_sabsdiff(unsigned vece, uint32_t dofs, uint32_t aofs,
                        uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
 void gen_gvec_uabsdiff(unsigned vece, uint32_t dofs, uint32_t aofs,
diff --git a/target/hexagon/hex_common.py b/target/hexagon/hex_common.py
index c180c19b09..02c5450614 100755
--- a/target/hexagon/hex_common.py
+++ b/target/hexagon/hex_common.py
@@ -434,6 +434,14 @@ def is_hvx_reg(self):
         return True
     def hvx_off(self):
         return f"{self.reg_tcg()}_off"
+    def hvx_base(self):
+        return f"{self.reg_tcg()}_base"
+    def decl_tcg_ptr(self, f):
+        ptr = self.reg_tcg()
+        f.write(code_fmt(f"""\
+            TCGv_ptr {ptr} = tcg_temp_new_ptr();
+            tcg_gen_addi_ptr({ptr}, {self.hvx_base()}, {self.hvx_off()});
+        """))
     def helper_proto_type(self):
         return "ptr"
     def helper_arg_type(self):
@@ -778,18 +786,17 @@ class VRegDest(Register, Hvx, Dest):
     def decl_tcg(self, f, tag, regno):
         self.decl_reg_num(f, regno)
         f.write(code_fmt(f"""\
+            TCGv_ptr {self.hvx_base()};
             const intptr_t {self.hvx_off()} =
-                {vreg_offset_func(tag)}(ctx, {self.reg_num}, 1, true);
+                {vreg_offset_func(tag)}(ctx, {self.reg_num}, 1,
+                                        true, &{self.hvx_base()});
         """))
         if not skip_qemu_helper(tag):
-            f.write(code_fmt(f"""\
-                TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
-                tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
-            """))
+            self.decl_tcg_ptr(f)
     def gen_zero(self, f):
         f.write(code_fmt(f"""\
-                tcg_gen_gvec_dup_imm(MO_64, {self.hvx_off()},
-                    sizeof(MMVector), sizeof(MMVector), 0);
+                tcg_gen_gvec_dup_imm_var(MO_64, {self.hvx_base()},
+                    {self.hvx_off()}, sizeof(MMVector), sizeof(MMVector), 0);
             """))
     def gen_write(self, f, tag):
         pass
@@ -809,13 +816,12 @@ class VRegSource(Register, Hvx, OldSource):
     def decl_tcg(self, f, tag, regno):
         self.decl_reg_num(f, regno)
         f.write(code_fmt(f"""\
-            const intptr_t {self.hvx_off()} = vreg_src_off(ctx, {self.reg_num});
+            TCGv_ptr {self.hvx_base()};
+            const intptr_t {self.hvx_off()} =
+                vreg_src_off(ctx, {self.reg_num}, &{self.hvx_base()});
         """))
         if not skip_qemu_helper(tag):
-            f.write(code_fmt(f"""\
-                TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
-                tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
-            """))
+            self.decl_tcg_ptr(f)
     def helper_hvx_desc(self, f):
         f.write(code_fmt(f"""\
             /* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
@@ -830,8 +836,10 @@ def decl_tcg(self, f, tag, regno):
         self.decl_reg_num(f, regno)
         if skip_qemu_helper(tag):
             f.write(code_fmt(f"""\
+                TCGv_ptr {self.hvx_base()};
                 const intptr_t {self.hvx_off()} =
-                    ctx_future_vreg_off(ctx, {self.reg_num}, 1, true);
+                    ctx_future_vreg_off(ctx, {self.reg_num}, 1,
+                                        true, &{self.hvx_base()});
             """))
     def helper_hvx_desc(self, f):
         f.write(code_fmt(f"""\
@@ -846,21 +854,24 @@ class VRegReadWrite(Register, Hvx, ReadWrite):
     def decl_tcg(self, f, tag, regno):
         self.decl_reg_num(f, regno)
         f.write(code_fmt(f"""\
+            TCGv_ptr {self.hvx_base()};
+            TCGv_ptr {self.reg_tcg()}_srcbase;
             const intptr_t {self.hvx_off()} =
-                {vreg_offset_func(tag)}(ctx, {self.reg_num}, 1, true);
-            tcg_gen_gvec_mov(MO_64, {self.hvx_off()},
-                             vreg_src_off(ctx, {self.reg_num}),
-                             sizeof(MMVector), sizeof(MMVector));
+                {vreg_offset_func(tag)}(ctx, {self.reg_num}, 1,
+                                        true, &{self.hvx_base()});
+            const intptr_t {self.reg_tcg()}_srcoff =
+                vreg_src_off(ctx, {self.reg_num}, &{self.reg_tcg()}_srcbase);
+            tcg_gen_gvec_mov_var(MO_64, {self.hvx_base()}, {self.hvx_off()},
+                                 {self.reg_tcg()}_srcbase,
+                                 {self.reg_tcg()}_srcoff,
+                                 sizeof(MMVector), sizeof(MMVector));
         """))
         if not skip_qemu_helper(tag):
-            f.write(code_fmt(f"""\
-                TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
-                tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
-            """))
+            self.decl_tcg_ptr(f)
     def gen_zero(self, f):
         f.write(code_fmt(f"""\
-                tcg_gen_gvec_dup_imm(MO_64, {self.hvx_off()},
-                    sizeof(MMVector), sizeof(MMVector), 0);
+                tcg_gen_gvec_dup_imm_var(MO_64, {self.hvx_base()},
+                    {self.hvx_off()}, sizeof(MMVector), sizeof(MMVector), 0);
             """))
     def gen_write(self, f, tag):
         pass
@@ -884,15 +895,21 @@ class VRegTmp(Register, Hvx, ReadWrite):
     def decl_tcg(self, f, tag, regno):
         self.decl_reg_num(f, regno)
         f.write(code_fmt(f"""\
+            TCGv_ptr {self.hvx_base()} = tcg_env;
             const intptr_t {self.hvx_off()} = offsetof(CPUHexagonState, vtmp);
         """))
         if not skip_qemu_helper(tag):
+            self.decl_tcg_ptr(f)
             f.write(code_fmt(f"""\
-                TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
-                tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
-                tcg_gen_gvec_mov(MO_64, {self.hvx_off()},
-                                 vreg_src_off(ctx, {self.reg_num}),
-                                 sizeof(MMVector), sizeof(MMVector));
+                TCGv_ptr {self.reg_tcg()}_srcbase;
+                const intptr_t {self.reg_tcg()}_srcoff =
+                    vreg_src_off(ctx, {self.reg_num},
+                                 &{self.reg_tcg()}_srcbase);
+                tcg_gen_gvec_mov_var(MO_64, {self.hvx_base()},
+                                     {self.hvx_off()},
+                                     {self.reg_tcg()}_srcbase,
+                                     {self.reg_tcg()}_srcoff,
+                                     sizeof(MMVector), sizeof(MMVector));
             """))
     def gen_zero(self, f):
         f.write(code_fmt(f"""\
@@ -901,8 +918,8 @@ def gen_zero(self, f):
             """))
     def gen_write(self, f, tag):
         f.write(code_fmt(f"""\
-            gen_vreg_write(ctx, {self.hvx_off()}, {self.reg_num},
-                           {hvx_newv(tag)});
+            gen_vreg_write(ctx, {self.hvx_base()}, {self.hvx_off()},
+                           {self.reg_num}, {hvx_newv(tag)});
         """))
     def helper_hvx_desc(self, f):
         f.write(code_fmt(f"""\
@@ -924,17 +941,16 @@ class VRegPairDest(Register, Hvx, Dest):
     def decl_tcg(self, f, tag, regno):
         self.decl_reg_num(f, regno)
         f.write(code_fmt(f"""\
+            TCGv_ptr {self.hvx_base()};
             const intptr_t {self.hvx_off()} =
-                {vreg_offset_func(tag)}(ctx, {self.reg_num}, 2, true);
+                {vreg_offset_func(tag)}(ctx, {self.reg_num}, 2,
+                                        true, &{self.hvx_base()});
         """))
         if not skip_qemu_helper(tag):
-            f.write(code_fmt(f"""\
-                TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
-                tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
-            """))
+            self.decl_tcg_ptr(f)
     def gen_zero(self, f):
         f.write(code_fmt(f"""\
-            tcg_gen_gvec_dup_imm(MO_64, {self.hvx_off()},
+            tcg_gen_gvec_dup_imm_var(MO_64, {self.hvx_base()}, {self.hvx_off()},
                 sizeof(MMVectorPair), sizeof(MMVectorPair), 0);
         """))
     def gen_write(self, f, tag):
@@ -955,20 +971,27 @@ class VRegPairSource(Register, Hvx, OldSource):
     def decl_tcg(self, f, tag, regno):
         self.decl_reg_num(f, regno)
         f.write(code_fmt(f"""\
+            TCGv_ptr {self.hvx_base()} = tcg_env;
+            TCGv_ptr {self.reg_tcg()}_srcbase;
             const intptr_t {self.hvx_off()} =
                 offsetof(CPUHexagonState, {self.reg_tcg()});
-            tcg_gen_gvec_mov(MO_64, {self.hvx_off()},
-                             vreg_src_off(ctx, {self.reg_num}),
-                             sizeof(MMVector), sizeof(MMVector));
-            tcg_gen_gvec_mov(MO_64, {self.hvx_off()} + sizeof(MMVector),
-                             vreg_src_off(ctx, {self.reg_num} ^ 1),
-                             sizeof(MMVector), sizeof(MMVector));
+            intptr_t {self.reg_tcg()}_srcoff =
+                vreg_src_off(ctx, {self.reg_num}, &{self.reg_tcg()}_srcbase);
+            tcg_gen_gvec_mov_var(MO_64, {self.hvx_base()}, {self.hvx_off()},
+                                 {self.reg_tcg()}_srcbase,
+                                 {self.reg_tcg()}_srcoff,
+                                 sizeof(MMVector), sizeof(MMVector));
+            {self.reg_tcg()}_srcoff =
+                vreg_src_off(ctx, {self.reg_num} ^ 1,
+                             &{self.reg_tcg()}_srcbase);
+            tcg_gen_gvec_mov_var(MO_64, {self.hvx_base()},
+                                 {self.hvx_off()} + sizeof(MMVector),
+                                 {self.reg_tcg()}_srcbase,
+                                 {self.reg_tcg()}_srcoff,
+                                 sizeof(MMVector), sizeof(MMVector));
         """))
         if not skip_qemu_helper(tag):
-            f.write(code_fmt(f"""\
-                TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
-                tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
-            """))
+            self.decl_tcg_ptr(f)
     def helper_hvx_desc(self, f):
         f.write(code_fmt(f"""\
             /* {self.reg_tcg()} is *(MMVectorPair *)({self.helper_arg_name()}) */
@@ -982,29 +1005,36 @@ class VRegPairReadWrite(Register, Hvx, ReadWrite):
     def decl_tcg(self, f, tag, regno):
         self.decl_reg_num(f, regno)
         f.write(code_fmt(f"""\
+            TCGv_ptr {self.hvx_base()} = tcg_env;
+            TCGv_ptr {self.reg_tcg()}_srcbase;
             const intptr_t {self.hvx_off()} =
                 offsetof(CPUHexagonState, {self.reg_tcg()});
-            tcg_gen_gvec_mov(MO_64, {self.hvx_off()},
-                             vreg_src_off(ctx, {self.reg_num}),
-                             sizeof(MMVector), sizeof(MMVector));
-            tcg_gen_gvec_mov(MO_64, {self.hvx_off()} + sizeof(MMVector),
-                             vreg_src_off(ctx, {self.reg_num} ^ 1),
-                             sizeof(MMVector), sizeof(MMVector));
+            intptr_t {self.reg_tcg()}_srcoff =
+                vreg_src_off(ctx, {self.reg_num}, &{self.reg_tcg()}_srcbase);
+            tcg_gen_gvec_mov_var(MO_64, {self.hvx_base()}, {self.hvx_off()},
+                                 {self.reg_tcg()}_srcbase,
+                                 {self.reg_tcg()}_srcoff,
+                                 sizeof(MMVector), sizeof(MMVector));
+            {self.reg_tcg()}_srcoff =
+                vreg_src_off(ctx, {self.reg_num} ^ 1,
+                             &{self.reg_tcg()}_srcbase);
+            tcg_gen_gvec_mov_var(MO_64, {self.hvx_base()},
+                                 {self.hvx_off()} + sizeof(MMVector),
+                                 {self.reg_tcg()}_srcbase,
+                                 {self.reg_tcg()}_srcoff,
+                                 sizeof(MMVector), sizeof(MMVector));
         """))
         if not skip_qemu_helper(tag):
-            f.write(code_fmt(f"""\
-                TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
-                tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
-            """))
+            self.decl_tcg_ptr(f)
     def gen_zero(self, f):
         f.write(code_fmt(f"""\
-            tcg_gen_gvec_dup_imm(MO_64, {self.hvx_off()},
+            tcg_gen_gvec_dup_imm_var(MO_64, {self.hvx_base()}, {self.hvx_off()},
                 sizeof(MMVectorPair), sizeof(MMVectorPair), 0);
         """))
     def gen_write(self, f, tag):
         f.write(code_fmt(f"""\
-            gen_vreg_write_pair(ctx, {self.hvx_off()}, {self.reg_num},
-                                {hvx_newv(tag)});
+            gen_vreg_write_pair(ctx, {self.hvx_base()}, {self.hvx_off()},
+                                {self.reg_num}, {hvx_newv(tag)});
         """))
     def helper_hvx_desc(self, f):
         f.write(code_fmt(f"""\
@@ -1026,14 +1056,12 @@ class QRegDest(Register, Hvx, Dest):
     def decl_tcg(self, f, tag, regno):
         self.decl_reg_num(f, regno)
         f.write(code_fmt(f"""\
+            TCGv_ptr {self.hvx_base()};
             const intptr_t {self.hvx_off()} =
-                get_result_qreg(ctx, {self.reg_num});
+                get_result_qreg(ctx, {self.reg_num}, &{self.hvx_base()});
         """))
         if not skip_qemu_helper(tag):
-            f.write(code_fmt(f"""\
-                TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
-                tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
-            """))
+            self.decl_tcg_ptr(f)
     def gen_write(self, f, tag):
         pass
     def helper_hvx_desc(self, f):
@@ -1049,14 +1077,12 @@ class QRegSource(Register, Hvx, OldSource):
     def decl_tcg(self, f, tag, regno):
         self.decl_reg_num(f, regno)
         f.write(code_fmt(f"""\
+            TCGv_ptr {self.hvx_base()} = hex_hvx_ptr;
             const intptr_t {self.hvx_off()} =
-                offsetof(CPUHexagonState, QRegs[{self.reg_num}]);
+                HEX_HVX_OFFSET(QRegs[{self.reg_num}]);
         """))
         if not skip_qemu_helper(tag):
-            f.write(code_fmt(f"""\
-                TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
-                tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
-            """))
+            self.decl_tcg_ptr(f)
     def helper_hvx_desc(self, f):
         f.write(code_fmt(f"""\
             /* {self.reg_tcg()} is *(MMQReg *)({self.helper_arg_name()}) */
@@ -1070,17 +1096,16 @@ class QRegReadWrite(Register, Hvx, ReadWrite):
     def decl_tcg(self, f, tag, regno):
         self.decl_reg_num(f, regno)
         f.write(code_fmt(f"""\
+            TCGv_ptr {self.hvx_base()};
             const intptr_t {self.hvx_off()} =
-                get_result_qreg(ctx, {self.reg_num});
-            tcg_gen_gvec_mov(MO_64, {self.hvx_off()},
-                             offsetof(CPUHexagonState, QRegs[{self.reg_num}]),
-                             sizeof(MMQReg), sizeof(MMQReg));
+                get_result_qreg(ctx, {self.reg_num}, &{self.hvx_base()});
+            tcg_gen_gvec_mov_var(MO_64, {self.hvx_base()}, {self.hvx_off()},
+                                 hex_hvx_ptr,
+                                 HEX_HVX_OFFSET(QRegs[{self.reg_num}]),
+                                 sizeof(MMQReg), sizeof(MMQReg));
         """))
         if not skip_qemu_helper(tag):
-            f.write(code_fmt(f"""\
-                TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
-                tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
-            """))
+            self.decl_tcg_ptr(f)
     def gen_write(self, f, tag):
         pass
     def helper_hvx_desc(self, f):
diff --git a/target/hexagon/mmvec/macros.h b/target/hexagon/mmvec/macros.h
index b36f833b1d..df695d0731 100644
--- a/target/hexagon/mmvec/macros.h
+++ b/target/hexagon/mmvec/macros.h
@@ -286,26 +286,28 @@
         fV_AL_CHECK(EA, fVECSIZE() - 1); \
     } while (0)
 #ifdef QEMU_GENERATE
-#define fLOADMMV(EA, DST) gen_vreg_load(ctx, DST##_off, EA, true)
+#define fLOADMMV(EA, DST) gen_vreg_load(ctx, DST##_base, DST##_off, EA, true)
 #endif
 #ifdef QEMU_GENERATE
-#define fLOADMMVU(EA, DST) gen_vreg_load(ctx, DST##_off, EA, false)
+#define fLOADMMVU(EA, DST) gen_vreg_load(ctx, DST##_base, DST##_off, EA, false)
 #endif
 #ifdef QEMU_GENERATE
 #define fSTOREMMV(EA, SRC) \
-    gen_vreg_store(ctx, EA, SRC##_off, insn->slot, true)
+    gen_vreg_store(ctx, EA, SRC##_base, SRC##_off, insn->slot, true)
 #endif
 #ifdef QEMU_GENERATE
 #define fSTOREMMVQ(EA, SRC, MASK) \
-    gen_vreg_masked_store(ctx, EA, SRC##_off, MASK##_off, insn->slot, false)
+    gen_vreg_masked_store(ctx, EA, SRC##_base, SRC##_off, \
+                          MASK##_base, MASK##_off, insn->slot, false)
 #endif
 #ifdef QEMU_GENERATE
 #define fSTOREMMVNQ(EA, SRC, MASK) \
-    gen_vreg_masked_store(ctx, EA, SRC##_off, MASK##_off, insn->slot, true)
+    gen_vreg_masked_store(ctx, EA, SRC##_base, SRC##_off, \
+                          MASK##_base, MASK##_off, insn->slot, true)
 #endif
 #ifdef QEMU_GENERATE
 #define fSTOREMMVU(EA, SRC) \
-    gen_vreg_store(ctx, EA, SRC##_off, insn->slot, false)
+    gen_vreg_store(ctx, EA, SRC##_base, SRC##_off, insn->slot, false)
 #endif
 #define fVFOREACH(WIDTH, VAR) for (VAR = 0; VAR < fVELEM(WIDTH); VAR++)
 #define fVARRAY_ELEMENT_ACCESS(ARRAY, TYPE, INDEX) \
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
index 0d08ac7736..47c7953b92 100644
--- a/target/hexagon/op_helper.c
+++ b/target/hexagon/op_helper.c
@@ -1408,7 +1408,8 @@ void HELPER(vhist)(CPUHexagonState *env)
             unsigned char regno = value >> 3;
             unsigned char element = value & 7;

-            env->VRegs[regno].uh[(sizeof(MMVector) / 16) * lane + element]++;
+            hex_hvx(env)->VRegs[regno]
+                .uh[(sizeof(MMVector) / 16) * lane + element]++;
         }
     }
 }
@@ -1424,7 +1425,7 @@ void HELPER(vhistq)(CPUHexagonState *env)
             unsigned char element = value & 7;

             if (fGETQBIT(env->qtmp, sizeof(MMVector) / 8 * lane + i)) {
-                env->VRegs[regno].uh[
+                hex_hvx(env)->VRegs[regno].uh[
                     (sizeof(MMVector) / 16) * lane + element]++;
             }
         }
@@ -1441,8 +1442,8 @@ void HELPER(vwhist256)(CPUHexagonState *env)
         unsigned int vindex = (bucket >> 3) & 0x1F;
         unsigned int elindex = ((i >> 0) & (~7)) | ((bucket >> 0) & 7);

-        env->VRegs[vindex].uh[elindex] =
-            env->VRegs[vindex].uh[elindex] + weight;
+        hex_hvx(env)->VRegs[vindex].uh[elindex] =
+            hex_hvx(env)->VRegs[vindex].uh[elindex] + weight;
     }
 }

@@ -1457,8 +1458,8 @@ void HELPER(vwhist256q)(CPUHexagonState *env)
         unsigned int elindex = ((i >> 0) & (~7)) | ((bucket >> 0) & 7);

         if (fGETQBIT(env->qtmp, 2 * i)) {
-            env->VRegs[vindex].uh[elindex] =
-                env->VRegs[vindex].uh[elindex] + weight;
+            hex_hvx(env)->VRegs[vindex].uh[elindex] =
+                hex_hvx(env)->VRegs[vindex].uh[elindex] + weight;
         }
     }
 }
@@ -1473,8 +1474,8 @@ void HELPER(vwhist256_sat)(CPUHexagonState *env)
         unsigned int vindex = (bucket >> 3) & 0x1F;
         unsigned int elindex = ((i >> 0) & (~7)) | ((bucket >> 0) & 7);

-        env->VRegs[vindex].uh[elindex] =
-            fVSATUH(env->VRegs[vindex].uh[elindex] + weight);
+        hex_hvx(env)->VRegs[vindex].uh[elindex] =
+            fVSATUH(hex_hvx(env)->VRegs[vindex].uh[elindex] + weight);
     }
 }

@@ -1489,8 +1490,8 @@ void HELPER(vwhist256q_sat)(CPUHexagonState *env)
         unsigned int elindex = ((i >> 0) & (~7)) | ((bucket >> 0) & 7);

         if (fGETQBIT(env->qtmp, 2 * i)) {
-            env->VRegs[vindex].uh[elindex] =
-                fVSATUH(env->VRegs[vindex].uh[elindex] + weight);
+            hex_hvx(env)->VRegs[vindex].uh[elindex] =
+                fVSATUH(hex_hvx(env)->VRegs[vindex].uh[elindex] + weight);
         }
     }
 }
@@ -1505,8 +1506,8 @@ void HELPER(vwhist128)(CPUHexagonState *env)
         unsigned int vindex = (bucket >> 3) & 0x1F;
         unsigned int elindex = ((i >> 1) & (~3)) | ((bucket >> 1) & 3);

-        env->VRegs[vindex].uw[elindex] =
-            env->VRegs[vindex].uw[elindex] + weight;
+        hex_hvx(env)->VRegs[vindex].uw[elindex] =
+            hex_hvx(env)->VRegs[vindex].uw[elindex] + weight;
     }
 }

@@ -1521,8 +1522,8 @@ void HELPER(vwhist128q)(CPUHexagonState *env)
         unsigned int elindex = ((i >> 1) & (~3)) | ((bucket >> 1) & 3);

         if (fGETQBIT(env->qtmp, 2 * i)) {
-            env->VRegs[vindex].uw[elindex] =
-                env->VRegs[vindex].uw[elindex] + weight;
+            hex_hvx(env)->VRegs[vindex].uw[elindex] =
+                hex_hvx(env)->VRegs[vindex].uw[elindex] + weight;
         }
     }
 }
@@ -1538,8 +1539,8 @@ void HELPER(vwhist128m)(CPUHexagonState *env, int32_t uiV)
         unsigned int elindex = ((i >> 1) & (~3)) | ((bucket >> 1) & 3);

         if ((bucket & 1) == uiV) {
-            env->VRegs[vindex].uw[elindex] =
-                env->VRegs[vindex].uw[elindex] + weight;
+            hex_hvx(env)->VRegs[vindex].uw[elindex] =
+                hex_hvx(env)->VRegs[vindex].uw[elindex] + weight;
         }
     }
 }
@@ -1555,8 +1556,8 @@ void HELPER(vwhist128qm)(CPUHexagonState *env, int32_t uiV)
         unsigned int elindex = ((i >> 1) & (~3)) | ((bucket >> 1) & 3);

         if (((bucket & 1) == uiV) && fGETQBIT(env->qtmp, 2 * i)) {
-            env->VRegs[vindex].uw[elindex] =
-                env->VRegs[vindex].uw[elindex] + weight;
+            hex_hvx(env)->VRegs[vindex].uw[elindex] =
+                hex_hvx(env)->VRegs[vindex].uw[elindex] + weight;
         }
     }
 }
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
index bf92166e0f..bebfeb2dac 100644
--- a/target/hexagon/translate.c
+++ b/target/hexagon/translate.c
@@ -82,14 +82,18 @@ static const char * const hexagon_prednames[] = {
 };

 intptr_t ctx_future_vreg_off(DisasContext *ctx, int regnum,
-                          int num, bool alloc_ok)
+                          int num, bool alloc_ok, TCGv_ptr *base)
 {
     intptr_t offset;

     if (!ctx->need_commit) {
-        return offsetof(CPUHexagonState, VRegs[regnum]);
+        /* Short circuit: the write goes straight to the register file. */
+        *base = hex_hvx_ptr;
+        return HEX_HVX_OFFSET(VRegs[regnum]);
     }

+    *base = tcg_env;
+
     /* See if it is already allocated */
     for (int i = 0; i < ctx->future_vregs_idx; i++) {
         if (ctx->future_vregs_num[i] == regnum) {
@@ -108,10 +112,12 @@ intptr_t ctx_future_vreg_off(DisasContext *ctx, int regnum,
 }

 intptr_t ctx_tmp_vreg_off(DisasContext *ctx, int regnum,
-                          int num, bool alloc_ok)
+                          int num, bool alloc_ok, TCGv_ptr *base)
 {
     intptr_t offset;

+    *base = tcg_env;
+
     /* See if it is already allocated */
     for (int i = 0; i < ctx->tmp_vregs_idx; i++) {
         if (ctx->tmp_vregs_num[i] == regnum) {
@@ -743,26 +749,28 @@ static void gen_start_packet(DisasContext *ctx)
     if (!bitmap_empty(ctx->predicated_future_vregs, NUM_VREGS)) {
         i = find_first_bit(ctx->predicated_future_vregs, NUM_VREGS);
         while (i < NUM_VREGS) {
+            TCGv_ptr VdV_base;
             const intptr_t VdV_off =
-                ctx_future_vreg_off(ctx, i, 1, true);
-            intptr_t src_off = offsetof(CPUHexagonState, VRegs[i]);
-            tcg_gen_gvec_mov(MO_64, VdV_off,
-                             src_off,
-                             sizeof(MMVector),
-                             sizeof(MMVector));
+                ctx_future_vreg_off(ctx, i, 1, true, &VdV_base);
+            intptr_t src_off = HEX_HVX_OFFSET(VRegs[i]);
+            tcg_gen_gvec_mov_var(MO_64, VdV_base, VdV_off,
+                                 hex_hvx_ptr, src_off,
+                                 sizeof(MMVector),
+                                 sizeof(MMVector));
             i = find_next_bit(ctx->predicated_future_vregs, NUM_VREGS, i + 1);
         }
     }
     if (!bitmap_empty(ctx->predicated_tmp_vregs, NUM_VREGS)) {
         i = find_first_bit(ctx->predicated_tmp_vregs, NUM_VREGS);
         while (i < NUM_VREGS) {
+            TCGv_ptr VdV_base;
             const intptr_t VdV_off =
-                ctx_tmp_vreg_off(ctx, i, 1, true);
-            intptr_t src_off = offsetof(CPUHexagonState, VRegs[i]);
-            tcg_gen_gvec_mov(MO_64, VdV_off,
-                             src_off,
-                             sizeof(MMVector),
-                             sizeof(MMVector));
+                ctx_tmp_vreg_off(ctx, i, 1, true, &VdV_base);
+            intptr_t src_off = HEX_HVX_OFFSET(VRegs[i]);
+            tcg_gen_gvec_mov_var(MO_64, VdV_base, VdV_off,
+                                 hex_hvx_ptr, src_off,
+                                 sizeof(MMVector),
+                                 sizeof(MMVector));
             i = find_next_bit(ctx->predicated_tmp_vregs, NUM_VREGS, i + 1);
         }
     }
@@ -1062,31 +1070,34 @@ static void gen_commit_hvx(DisasContext *ctx)
     /*
      *    for (i = 0; i < ctx->vreg_log_idx; i++) {
      *        int rnum = ctx->vreg_log[i];
-     *        env->VRegs[rnum] = env->future_VRegs[rnum];
+     *        hex_hvx(env)->VRegs[rnum] = env->future_VRegs[rnum];
      *    }
      */
     for (i = 0; i < ctx->vreg_log_idx; i++) {
         int rnum = ctx->vreg_log[i];
-        intptr_t dstoff = offsetof(CPUHexagonState, VRegs[rnum]);
-        intptr_t srcoff = ctx_future_vreg_off(ctx, rnum, 1, false);
+        intptr_t dstoff = HEX_HVX_OFFSET(VRegs[rnum]);
+        TCGv_ptr srcbase;
+        intptr_t srcoff = ctx_future_vreg_off(ctx, rnum, 1, false, &srcbase);
         size_t size = sizeof(MMVector);

-        tcg_gen_gvec_mov(MO_64, dstoff, srcoff, size, size);
+        tcg_gen_gvec_mov_var(MO_64, hex_hvx_ptr, dstoff, srcbase, srcoff,
+                             size, size);
     }

     /*
      *    for (i = 0; i < ctx->qreg_log_idx; i++) {
      *        int rnum = ctx->qreg_log[i];
-     *        env->QRegs[rnum] = env->future_QRegs[rnum];
+     *        hex_hvx(env)->QRegs[rnum] = env->future_QRegs[rnum];
      *    }
      */
     for (i = 0; i < ctx->qreg_log_idx; i++) {
         int rnum = ctx->qreg_log[i];
-        intptr_t dstoff = offsetof(CPUHexagonState, QRegs[rnum]);
+        intptr_t dstoff = HEX_HVX_OFFSET(QRegs[rnum]);
         intptr_t srcoff = offsetof(CPUHexagonState, future_QRegs[rnum]);
         size_t size = sizeof(MMQReg);

-        tcg_gen_gvec_mov(MO_64, dstoff, srcoff, size, size);
+        tcg_gen_gvec_mov_var(MO_64, hex_hvx_ptr, dstoff, tcg_env, srcoff,
+                             size, size);
     }

     if (pkt_has_hvx_store(&ctx->pkt)) {
diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h
index b33d5dbdbe..d5940b9376 100644
--- a/target/hexagon/translate.h
+++ b/target/hexagon/translate.h
@@ -215,9 +215,9 @@ static inline void ctx_log_reg_read_pair(DisasContext *ctx, int rnum)
 }

 intptr_t ctx_future_vreg_off(DisasContext *ctx, int regnum,
-                             int num, bool alloc_ok);
+                             int num, bool alloc_ok, TCGv_ptr *base);
 intptr_t ctx_tmp_vreg_off(DisasContext *ctx, int regnum,
-                          int num, bool alloc_ok);
+                          int num, bool alloc_ok, TCGv_ptr *base);

 static inline void ctx_start_hvx_insn(DisasContext *ctx)
 {
@@ -363,6 +363,8 @@ extern TCGv_i64 hex_llsc_val_i64;
 extern TCGv hex_vstore_addr[VSTORES_MAX];
 extern TCGv hex_vstore_size[VSTORES_MAX];
 extern TCGv hex_vstore_pending[VSTORES_MAX];
+#define hex_hvx_ptr tcg_env
+#define HEX_HVX_OFFSET(member) offsetof(CPUHexagonState, member)
 #ifndef CONFIG_USER_ONLY
 extern TCGv_i32 hex_greg[NUM_GREGS];
 extern TCGv_i32 hex_t_sreg[NUM_SREGS];