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
