[PATCH 10/11] target/hexagon: fix iassign{r,w} to cover all threads
Brian Cain <[email protected]>
| Newsgroups | gmane.comp.emulators.qemu |
|---|---|
| Message-ID | <[email protected]> |
iassignw/iassignr were filtering CPU_FOREACH by MODECTL_E, the thread-enabled mask. That mask reflects whether a thread has been started, not whether it exists, so IMASK writes/reads never reached threads that hadn't been started yet, leaving their IMASK stale or unreadable. Drop the MODECTL_E filtering and operate on every thread. Signed-off-by: Brian Cain <[email protected]> --- target/hexagon/op_helper.c | 42 +++++++++----------------------------- 1 file changed, 10 insertions(+), 32 deletions(-) diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c index df31ed2488a..e19c3c91085 100644 --- a/target/hexagon/op_helper.c +++ b/target/hexagon/op_helper.c @@ -1637,61 +1637,39 @@ void HELPER(cswi)(CPUHexagonState *env, uint32_t mask) void HELPER(iassignw)(CPUHexagonState *env, uint32_t src) { - uint32_t modectl; - uint32_t thread_enabled_mask; CPUState *cpu; - HexagonCPU *hex_cpu; BQL_LOCK_GUARD(); - hex_cpu = env_archcpu(env); - modectl = hex_cpu->globalregs ? - hexagon_globalreg_read(hex_cpu->globalregs, HEX_SREG_MODECTL, - env->threadId) : 0; - thread_enabled_mask = GET_FIELD(MODECTL_E, modectl); CPU_FOREACH(cpu) { CPUHexagonState *thread_env = &(HEXAGON_CPU(cpu)->env); - uint32_t thread_id_mask = 0x1 << thread_env->threadId; - if (thread_enabled_mask & thread_id_mask) { - uint32_t imask = thread_env->t_sreg[HEX_SREG_IMASK]; - uint32_t intbitpos = (src >> 16) & 0xF; - uint32_t val = (src >> thread_env->threadId) & 0x1; - imask = deposit32(imask, intbitpos, 1, val); - thread_env->t_sreg[HEX_SREG_IMASK] = imask; + uint32_t imask = thread_env->t_sreg[HEX_SREG_IMASK]; + uint32_t intbitpos = (src >> 16) & 0xF; + uint32_t val = (src >> thread_env->threadId) & 0x1; + imask = deposit32(imask, intbitpos, 1, val); + thread_env->t_sreg[HEX_SREG_IMASK] = imask; - qemu_log_mask(CPU_LOG_INT, "%s: thread " TARGET_FMT_ld - ", new imask 0x%" PRIx32 "\n", __func__, - thread_env->threadId, imask); - } + qemu_log_mask(CPU_LOG_INT, "%s: thread " TARGET_FMT_ld + ", new imask 0x%" PRIx32 "\n", __func__, + thread_env->threadId, imask); } hex_interrupt_update(env); } uint32_t HELPER(iassignr)(CPUHexagonState *env, uint32_t src) { - uint32_t modectl; - uint32_t thread_enabled_mask; uint32_t intbitpos; uint32_t dest_reg; CPUState *cpu; - HexagonCPU *hex_cpu; BQL_LOCK_GUARD(); - hex_cpu = env_archcpu(env); - modectl = hex_cpu->globalregs ? - hexagon_globalreg_read(hex_cpu->globalregs, HEX_SREG_MODECTL, - env->threadId) : 0; - thread_enabled_mask = GET_FIELD(MODECTL_E, modectl); /* src fields are in same position as modectl, but mean different things */ intbitpos = GET_FIELD(MODECTL_W, src); dest_reg = 0; CPU_FOREACH(cpu) { CPUHexagonState *thread_env = &(HEXAGON_CPU(cpu)->env); - uint32_t thread_id_mask = 0x1 << thread_env->threadId; - if (thread_enabled_mask & thread_id_mask) { - uint32_t imask = thread_env->t_sreg[HEX_SREG_IMASK]; - dest_reg |= ((imask >> intbitpos) & 0x1) << thread_env->threadId; - } + uint32_t imask = thread_env->t_sreg[HEX_SREG_IMASK]; + dest_reg |= ((imask >> intbitpos) & 0x1) << thread_env->threadId; } return dest_reg; -- 2.34.1