The HVX register file belongs to an extension context, not a hw thread.
A core has a number of contexts, and each thread's SSR:XA selects the one
bound to it.

Group the regs into HexagonHVXContext and reach them through
CPUHexagonState::hvx.  Later patches move the storage into an object that
can be shared by vCPUs.

Signed-off-by: Brian Cain <[email protected]>
---
 target/hexagon/cpu.h          | 10 ++++++++--
 linux-user/hexagon/cpu_loop.c |  2 ++
 target/hexagon/cpu.c          | 15 ++++++++------
 target/hexagon/gdbstub.c      | 16 +++++++--------
 target/hexagon/genptr.c       |  4 ++--
 target/hexagon/op_helper.c    | 37 ++++++++++++++++++-----------------
 target/hexagon/translate.c    | 14 ++++++-------
 target/hexagon/hex_common.py  |  5 +++--
 8 files changed, 58 insertions(+), 45 deletions(-)

diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h
index 32cdcfe8529..c983a9791e1 100644
--- a/target/hexagon/cpu.h
+++ b/target/hexagon/cpu.h
@@ -120,6 +120,11 @@ typedef struct {
 /* Maximum number of vector temps in a packet */
 #define VECTOR_TEMPS_MAX            4
 
+typedef struct HexagonHVXContext {
+    MMVector VRegs[NUM_VREGS] QEMU_ALIGNED(16);
+    MMQReg QRegs[NUM_QREGS] QEMU_ALIGNED(16);
+} HexagonHVXContext;
+
 typedef struct CPUArchState {
     target_ulong gpr[TOTAL_PER_THREAD_REGS];
     target_ulong pred[NUM_PREGS];
@@ -159,11 +164,12 @@ typedef struct CPUArchState {
     target_ulong llsc_val;
     uint64_t     llsc_val_i64;
 
-    MMVector VRegs[NUM_VREGS] QEMU_ALIGNED(16);
+    HexagonHVXContext *hvx;
+    HexagonHVXContext hvx_ctx QEMU_ALIGNED(16);
+
     MMVector future_VRegs[VECTOR_TEMPS_MAX] QEMU_ALIGNED(16);
     MMVector tmp_VRegs[VECTOR_TEMPS_MAX] QEMU_ALIGNED(16);
 
-    MMQReg QRegs[NUM_QREGS] QEMU_ALIGNED(16);
     MMQReg future_QRegs[NUM_QREGS] QEMU_ALIGNED(16);
 
     /* Temporaries used within instructions */
diff --git a/linux-user/hexagon/cpu_loop.c b/linux-user/hexagon/cpu_loop.c
index e4ef97a1184..ccfb1da86f5 100644
--- a/linux-user/hexagon/cpu_loop.c
+++ b/linux-user/hexagon/cpu_loop.c
@@ -33,6 +33,8 @@ void cpu_loop(CPUHexagonState *env)
     target_ulong syscallnum;
     target_ulong ret;
 
+    env->hvx = &env->hvx_ctx;
+
     for (;;) {
         cpu_exec_start(cs);
         trapnr = cpu_exec(cs);
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
index 1109a8d914c..68c50cbcb45 100644
--- a/target/hexagon/cpu.c
+++ b/target/hexagon/cpu.c
@@ -182,7 +182,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 (env->hvx->VRegs[regnum].ub[i] != 0) {
                 nonzero_found = true;
                 break;
             }
@@ -193,9 +193,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",
+                 env->hvx->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", env->hvx->VRegs[regnum].ub[i]);
     }
     qemu_fprintf(f, " )\n");
 }
@@ -211,7 +212,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 (env->hvx->QRegs[regnum].ub[i] != 0) {
                 nonzero_found = true;
                 break;
             }
@@ -223,9 +224,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]);
+                 env->hvx->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", env->hvx->QRegs[regnum].ub[i]);
     }
     qemu_fprintf(f, " )\n");
 }
@@ -419,6 +420,8 @@ static void hexagon_cpu_reset_hold(Object *obj, ResetType 
type)
         mcc->parent_phases.hold(obj, type);
     }
 
+    env->hvx = &env->hvx_ctx;
+
     set_default_nan_mode(1, &env->fp_status);
     set_float_detect_tininess(float_tininess_before_rounding, &env->fp_status);
     /* Default NaN value: sign bit set, all frac bits set */
diff --git a/target/hexagon/gdbstub.c b/target/hexagon/gdbstub.c
index b9856cfc978..5e480726b03 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(env->hvx->VRegs[n].uw); i++) {
+        total += gdb_get_reg32(mem_buf, env->hvx->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(env->hvx->QRegs[n].uw); i++) {
+        total += gdb_get_reg32(mem_buf, env->hvx->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(env->hvx->VRegs[n].uw); i++) {
+        env->hvx->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(env->hvx->QRegs[n].uw); i++) {
+        env->hvx->QRegs[n].uw[i] = ldl_le_p(mem_buf);
         mem_buf += 4;
     }
     return MAX_VEC_SIZE_BYTES / 8;
diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index 9f53fcb6b95..257836be227 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -1433,7 +1433,7 @@ static void gen_asr_r_svw_trun(DisasContext *ctx, TCGv 
RdV,
 
 static intptr_t vreg_src_off(DisasContext *ctx, int num)
 {
-    intptr_t offset = offsetof(CPUHexagonState, VRegs[num]);
+    intptr_t offset = offsetof(CPUHexagonState, hvx_ctx.VRegs[num]);
 
     if (test_bit(num, ctx->vregs_select)) {
         offset = ctx_future_vreg_off(ctx, num, 1, false);
@@ -1473,7 +1473,7 @@ static intptr_t get_result_qreg(DisasContext *ctx, int 
qnum)
     if (ctx->need_commit) {
         return  offsetof(CPUHexagonState, future_QRegs[qnum]);
     } else {
-        return  offsetof(CPUHexagonState, QRegs[qnum]);
+        return  offsetof(CPUHexagonState, hvx_ctx.QRegs[qnum]);
     }
 }
 
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
index 7ad99ced7ab..cb9bc7e4317 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]++;
+            env->hvx->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[
+                env->hvx->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;
+        env->hvx->VRegs[vindex].uh[elindex] =
+            env->hvx->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;
+            env->hvx->VRegs[vindex].uh[elindex] =
+                env->hvx->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);
+        env->hvx->VRegs[vindex].uh[elindex] =
+            fVSATUH(env->hvx->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);
+            env->hvx->VRegs[vindex].uh[elindex] =
+                fVSATUH(env->hvx->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;
+        env->hvx->VRegs[vindex].uw[elindex] =
+            env->hvx->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;
+            env->hvx->VRegs[vindex].uw[elindex] =
+                env->hvx->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;
+            env->hvx->VRegs[vindex].uw[elindex] =
+                env->hvx->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;
+            env->hvx->VRegs[vindex].uw[elindex] =
+                env->hvx->VRegs[vindex].uw[elindex] + weight;
         }
     }
 }
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
index b44cf48d757..b05ac91846a 100644
--- a/target/hexagon/translate.c
+++ b/target/hexagon/translate.c
@@ -87,7 +87,7 @@ intptr_t ctx_future_vreg_off(DisasContext *ctx, int regnum,
     intptr_t offset;
 
     if (!ctx->need_commit) {
-        return offsetof(CPUHexagonState, VRegs[regnum]);
+        return offsetof(CPUHexagonState, hvx_ctx.VRegs[regnum]);
     }
 
     /* See if it is already allocated */
@@ -697,7 +697,7 @@ static void gen_start_packet(DisasContext *ctx)
         while (i < NUM_VREGS) {
             const intptr_t VdV_off =
                 ctx_future_vreg_off(ctx, i, 1, true);
-            intptr_t src_off = offsetof(CPUHexagonState, VRegs[i]);
+            intptr_t src_off = offsetof(CPUHexagonState, hvx_ctx.VRegs[i]);
             tcg_gen_gvec_mov(MO_64, VdV_off,
                              src_off,
                              sizeof(MMVector),
@@ -710,7 +710,7 @@ static void gen_start_packet(DisasContext *ctx)
         while (i < NUM_VREGS) {
             const intptr_t VdV_off =
                 ctx_tmp_vreg_off(ctx, i, 1, true);
-            intptr_t src_off = offsetof(CPUHexagonState, VRegs[i]);
+            intptr_t src_off = offsetof(CPUHexagonState, hvx_ctx.VRegs[i]);
             tcg_gen_gvec_mov(MO_64, VdV_off,
                              src_off,
                              sizeof(MMVector),
@@ -1012,12 +1012,12 @@ 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];
+     *        env->hvx->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 dstoff = offsetof(CPUHexagonState, hvx_ctx.VRegs[rnum]);
         intptr_t srcoff = ctx_future_vreg_off(ctx, rnum, 1, false);
         size_t size = sizeof(MMVector);
 
@@ -1027,12 +1027,12 @@ static void gen_commit_hvx(DisasContext *ctx)
     /*
      *    for (i = 0; i < ctx->qreg_log_idx; i++) {
      *        int rnum = ctx->qreg_log[i];
-     *        env->QRegs[rnum] = env->future_QRegs[rnum];
+     *        env->hvx->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 = offsetof(CPUHexagonState, hvx_ctx.QRegs[rnum]);
         intptr_t srcoff = offsetof(CPUHexagonState, future_QRegs[rnum]);
         size_t size = sizeof(MMQReg);
 
diff --git a/target/hexagon/hex_common.py b/target/hexagon/hex_common.py
index c180c19b092..ea3163132d9 100755
--- a/target/hexagon/hex_common.py
+++ b/target/hexagon/hex_common.py
@@ -1050,7 +1050,7 @@ def decl_tcg(self, f, tag, regno):
         self.decl_reg_num(f, regno)
         f.write(code_fmt(f"""\
             const intptr_t {self.hvx_off()} =
-                offsetof(CPUHexagonState, QRegs[{self.reg_num}]);
+                offsetof(CPUHexagonState, hvx_ctx.QRegs[{self.reg_num}]);
         """))
         if not skip_qemu_helper(tag):
             f.write(code_fmt(f"""\
@@ -1073,7 +1073,8 @@ def decl_tcg(self, f, tag, regno):
             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}]),
+                             offsetof(CPUHexagonState,
+                                      hvx_ctx.QRegs[{self.reg_num}]),
                              sizeof(MMQReg), sizeof(MMQReg));
         """))
         if not skip_qemu_helper(tag):
-- 
2.34.1

Reply via email to