Keep HVX lanes host-native while converting byte indexes at memory and helper boundaries.
Also place vector comparison predicate bytes according to host word order. Suggested-by: Anton Johansson <[email protected]> Reviewed-by: Anton Johansson <[email protected]> Signed-off-by: Brian Cain <[email protected]> --- target/hexagon/mmvec/macros.h | 23 +++++++++++++++-------- target/hexagon/mmvec/mmvec.h | 18 ++++++++++++++++++ target/hexagon/cpu.c | 17 +++++++++++------ target/hexagon/genptr.c | 3 ++- target/hexagon/mmvec/system_ext_mmvec.c | 2 +- target/hexagon/op_helper.c | 17 ++++++++++++----- 6 files changed, 59 insertions(+), 21 deletions(-) diff --git a/target/hexagon/mmvec/macros.h b/target/hexagon/mmvec/macros.h index b36f833b1de..e85beed3387 100644 --- a/target/hexagon/mmvec/macros.h +++ b/target/hexagon/mmvec/macros.h @@ -53,7 +53,7 @@ #define LOG_VTCM_BYTE(VA, MASK, VAL, IDX) \ do { \ - env->vtcm_log.data.ub[IDX] = (VAL); \ + hexagon_mmvec_set_byte(&env->vtcm_log.data, IDX, VAL); \ if (MASK) { \ set_bit((IDX), env->vtcm_log.mask); \ } else { \ @@ -133,7 +133,8 @@ target_ulong va_high = EA + LEN; \ for (int i0 = 0; i0 < 4; i0++) { \ log_byte = (va + i0) <= va_high; \ - LOG_VTCM_BYTE(va + i0, log_byte, INC. ub[4 * IDX + i0], \ + LOG_VTCM_BYTE(va + i0, log_byte, \ + hexagon_mmvec_get_byte(&(INC), 4 * IDX + i0), \ 4 * IDX + i0); \ } \ } while (0) @@ -144,7 +145,8 @@ target_ulong va_high = EA + LEN; \ for (int i0 = 0; i0 < 2; i0++) { \ log_byte = (va + i0) <= va_high; \ - LOG_VTCM_BYTE(va + i0, log_byte, INC.ub[2 * IDX + i0], \ + LOG_VTCM_BYTE(va + i0, log_byte, \ + hexagon_mmvec_get_byte(&(INC), 2 * IDX + i0), \ 2 * IDX + i0); \ } \ } while (0) @@ -157,7 +159,8 @@ target_ulong va_high = EA + LEN; \ for (int i0 = 0; i0 < 2; i0++) { \ log_byte = (va + i0) <= va_high; \ - LOG_VTCM_BYTE(va + i0, log_byte, INC.ub[2 * IDX + i0], \ + LOG_VTCM_BYTE(va + i0, log_byte, \ + hexagon_mmvec_get_byte(&(INC), 2 * IDX + i0), \ 2 * IDX + i0); \ } \ } while (0) @@ -174,7 +177,8 @@ log_byte = ((va + i0) <= va_high) && QVAL; \ uint8_t B; \ B = cpu_ldub_data_ra(env, EA + i0, ra); \ - env->tmp_VRegs[0].ub[ELEMENT_SIZE * IDX + i0] = B; \ + hexagon_mmvec_set_byte(&env->tmp_VRegs[0], \ + ELEMENT_SIZE * IDX + i0, B); \ LOG_VTCM_BYTE(va + i0, log_byte, B, ELEMENT_SIZE * IDX + i0); \ } \ } while (0) @@ -216,9 +220,10 @@ uint8_t val; \ val = cpu_ldub_data_ra(env, env->vtcm_log.va[i + j], ra); \ dst |= val << (8 * j); \ - inc |= env->vtcm_log.data.ub[j + i] << (8 * j); \ + inc |= hexagon_mmvec_get_byte(&env->vtcm_log.data, j + i) \ + << (8 * j); \ clear_bit(j + i, env->vtcm_log.mask); \ - env->vtcm_log.data.ub[j + i] = 0; \ + hexagon_mmvec_set_byte(&env->vtcm_log.data, j + i, 0); \ } \ dst += inc; \ for (int j = 0; j < sizeof(TYPE); j++) { \ @@ -249,7 +254,9 @@ int log_byte = 0; \ for (i0 = 0; i0 < ELEM_SIZE; i0++) { \ log_byte = ((va + i0) <= va_high) && QVAL; \ - LOG_VTCM_BYTE(va + i0, log_byte, IN.ub[ELEM_SIZE * IDX + i0], \ + LOG_VTCM_BYTE(va + i0, log_byte, \ + hexagon_mmvec_get_byte(&(IN), \ + ELEM_SIZE * IDX + i0), \ ELEM_SIZE * IDX + i0); \ } \ } while (0) diff --git a/target/hexagon/mmvec/mmvec.h b/target/hexagon/mmvec/mmvec.h index 8e72f2f6ae7..662f9d1597e 100644 --- a/target/hexagon/mmvec/mmvec.h +++ b/target/hexagon/mmvec/mmvec.h @@ -20,6 +20,7 @@ #include "exec/target_long.h" #include "qemu/bitmap.h" +#include "qemu/bitops.h" #define MAX_VEC_SIZE_LOGBYTES 7 #define MAX_VEC_SIZE_BYTES (1 << MAX_VEC_SIZE_LOGBYTES) @@ -69,6 +70,23 @@ typedef union { int8_t b[MAX_VEC_SIZE_BYTES / 1 / 8]; } MMQReg; +static inline uint8_t hexagon_mmvec_get_byte(const MMVector *v, size_t index) +{ + return extract64(v->ud[index / 8], (index % 8) * 8, 8); +} + +static inline void hexagon_mmvec_set_byte(MMVector *v, size_t index, + uint8_t value) +{ + v->ud[index / 8] = deposit64(v->ud[index / 8], (index % 8) * 8, 8, + value); +} + +static inline uint8_t hexagon_mmqreg_get_byte(const MMQReg *q, size_t index) +{ + return extract32(q->uw[index / 4], (index % 4) * 8, 8); +} + typedef struct { MMVector data; DECLARE_BITMAP(mask, MAX_VEC_SIZE_BYTES); diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c index 7067e5b70f7..544f101aa2d 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 (hexagon_mmvec_get_byte(&env->VRegs[regnum], i) != 0) { nonzero_found = true; break; } @@ -193,9 +193,12 @@ 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", + hexagon_mmvec_get_byte(&env->VRegs[regnum], + 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", + hexagon_mmvec_get_byte(&env->VRegs[regnum], i)); } qemu_fprintf(f, " )\n"); } @@ -211,7 +214,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 (hexagon_mmqreg_get_byte(&env->QRegs[regnum], i) != 0) { nonzero_found = true; break; } @@ -223,9 +226,11 @@ 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]); + hexagon_mmqreg_get_byte(&env->QRegs[regnum], + 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", + hexagon_mmqreg_get_byte(&env->QRegs[regnum], i)); } qemu_fprintf(f, " )\n"); } diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c index 2a98b13b714..5de8fe43f0b 100644 --- a/target/hexagon/genptr.c +++ b/target/hexagon/genptr.c @@ -1528,7 +1528,8 @@ 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, tcg_env, + dstoff + (i ^ (HOST_BIG_ENDIAN ? 3 : 0))); } } diff --git a/target/hexagon/mmvec/system_ext_mmvec.c b/target/hexagon/mmvec/system_ext_mmvec.c index 8351f2cc01b..081cadd814a 100644 --- a/target/hexagon/mmvec/system_ext_mmvec.c +++ b/target/hexagon/mmvec/system_ext_mmvec.c @@ -26,7 +26,7 @@ void mem_gather_store(CPUHexagonState *env, target_ulong vaddr, int slot) env->vstore_pending[slot] = 1; env->vstore[slot].va = vaddr; env->vstore[slot].size = size; - memcpy(&env->vstore[slot].data.ub[0], &env->tmp_VRegs[0], size); + memcpy(&env->vstore[slot].data, &env->tmp_VRegs[0], size); /* On a gather store, overwrite the store mask to emulate dropped gathers */ bitmap_copy(env->vstore[slot].mask, env->vtcm_log.mask, size); diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c index 23894ff3d28..cd677d3393e 100644 --- a/target/hexagon/op_helper.c +++ b/target/hexagon/op_helper.c @@ -146,7 +146,10 @@ void HELPER(commit_hvx_stores)(CPUHexagonState *env) int size = env->vstore[i].size; for (int j = 0; j < size; j++) { if (test_bit(j, env->vstore[i].mask)) { - cpu_stb_data_ra(env, va + j, env->vstore[i].data.ub[j], ra); + cpu_stb_data_ra(env, va + j, + hexagon_mmvec_get_byte(&env->vstore[i].data, + j), + ra); } } } @@ -169,9 +172,11 @@ void HELPER(commit_hvx_stores)(CPUHexagonState *env) for (int i = 0; i < sizeof(MMVector); i++) { if (test_bit(i, env->vtcm_log.mask)) { cpu_stb_data_ra(env, env->vtcm_log.va[i], - env->vtcm_log.data.ub[i], ra); + hexagon_mmvec_get_byte(&env->vtcm_log.data, + i), + ra); clear_bit(i, env->vtcm_log.mask); - env->vtcm_log.data.ub[i] = 0; + hexagon_mmvec_set_byte(&env->vtcm_log.data, i, 0); } } @@ -1370,7 +1375,8 @@ void HELPER(vhist)(CPUHexagonState *env) for (int lane = 0; lane < 8; lane++) { for (int i = 0; i < sizeof(MMVector) / 8; ++i) { - unsigned char value = input->ub[(sizeof(MMVector) / 8) * lane + i]; + unsigned char value = hexagon_mmvec_get_byte(input, + (sizeof(MMVector) / 8) * lane + i); unsigned char regno = value >> 3; unsigned char element = value & 7; @@ -1385,7 +1391,8 @@ void HELPER(vhistq)(CPUHexagonState *env) for (int lane = 0; lane < 8; lane++) { for (int i = 0; i < sizeof(MMVector) / 8; ++i) { - unsigned char value = input->ub[(sizeof(MMVector) / 8) * lane + i]; + unsigned char value = hexagon_mmvec_get_byte(input, + (sizeof(MMVector) / 8) * lane + i); unsigned char regno = value >> 3; unsigned char element = value & 7; -- 2.34.1
