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

Reply via email to