All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v4 0/5] target/mips: Fix support for MSA instructions on a big endian host
@ 2019-04-02 13:43 Mateja Marjanovic
  2019-04-02 13:43 ` [Qemu-devel] [PATCH v4 1/5] target/mips: Fix MSA instructions LD.<B|H|W|D> on " Mateja Marjanovic
                   ` (4 more replies)
  0 siblings, 5 replies; 17+ messages in thread
From: Mateja Marjanovic @ 2019-04-02 13:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: aurelien, amarkovic, arikalo

From: Mateja Marjanovic <Mateja.Marjanovic@rt-rk.com>

Fix support for MSA instructions while executing QEMU on a
machine that uses big endian MIPS CPU. This is achieved by
changing the implementation of helpers for MSA instructions
ST.<B|H|W|D>, LD.<B|H|W|D>, INSERT.<B|H|W> (and D on MIPS64),
COPY_S.<B|H|W> (and D on MIPS64) and COPY_U.<B|H> (and W
on MIPS64). Instead of using a switch in a helper, which is
called many times, put a switch in translate.c file, which
is called only a few times and change the value of the
index if a host is a big endian machine.

v4:
 - Change the alignment, so it looks cleaner.
 - Change the commit messages and cover letter, so they
   are more understandable.

v3:
 - Unroll loops in ST.<B|H|W|D> and LD.<B|H|W|D>
   instructions.
 - Eliminate macro that generates the helpers for
   the ST.<B|H|W|D> and LD.<B|H|W|D> instructions,
   and add four helpers for each (for byte,
   halfword, word and doubleword).
 - Eliminate the helpers for INSERT.<B|H|W|D>,
   COPY_S.<B|H|W|D> and COPY_U.<B|H|W> and add
   four (three in case of COPY_U) helpers for
   each one.

v2:
 - Eliminate unreachable code in COPY_U.<B|H|W>
 - Add preprocessing conditionals (if host is MIPS64, check that case)
   in COPY_U.<B|H|W>, INSERT.<B|H|W|D>.

Mateja Marjanovic (5):
  target/mips: Fix MSA instructions LD.<B|H|W|D> on big endian host
  target/mips: Fix MSA instructions ST.<B|H|W|D> on big endian host
  target/mips: Refactor and fix COPY_S.<B|H|W|D> instructions
  target/mips: Refactor and fix COPY_U.<B|H|W> instructions
  target/mips: Refactor and fix INSERT.<B|H|W|D> instructions

 target/mips/helper.h     |  16 +-
 target/mips/msa_helper.c | 182 ++++++++++++++++-------
 target/mips/op_helper.c  | 376 ++++++++++++++++++++++++++++++++++++++++++-----
 target/mips/translate.c  |  59 +++++++-
 4 files changed, 533 insertions(+), 100 deletions(-)

-- 
2.7.4

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH v4 1/5] target/mips: Fix MSA instructions LD.<B|H|W|D> on big endian host
  2019-04-02 13:43 [Qemu-devel] [PATCH v4 0/5] target/mips: Fix support for MSA instructions on a big endian host Mateja Marjanovic
@ 2019-04-02 13:43 ` Mateja Marjanovic
  2019-04-02 20:38   ` Aleksandar Markovic
  2019-04-02 13:43 ` [Qemu-devel] [PATCH v4 2/5] target/mips: Fix MSA instructions ST.<B|H|W|D> " Mateja Marjanovic
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 17+ messages in thread
From: Mateja Marjanovic @ 2019-04-02 13:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: aurelien, amarkovic, arikalo

From: Mateja Marjanovic <Mateja.Marjanovic@rt-rk.com>

Fix the case when the host is a big endian machine, and change
the approach toward LD.<B|H|W|D> instruction helpers.

Signed-off-by: Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
---
 target/mips/op_helper.c | 188 ++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 168 insertions(+), 20 deletions(-)

diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c
index 0f272a5..45be406 100644
--- a/target/mips/op_helper.c
+++ b/target/mips/op_helper.c
@@ -4371,31 +4371,179 @@ FOP_CONDN_S(sne,  (float32_lt(fst1, fst0, &env->active_fpu.fp_status)
 #define MEMOP_IDX(DF)
 #endif
 
-#define MSA_LD_DF(DF, TYPE, LD_INSN, ...)                               \
-void helper_msa_ld_ ## TYPE(CPUMIPSState *env, uint32_t wd,             \
-                            target_ulong addr)                          \
-{                                                                       \
-    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);                          \
-    wr_t wx;                                                            \
-    int i;                                                              \
-    MEMOP_IDX(DF)                                                       \
-    for (i = 0; i < DF_ELEMENTS(DF); i++) {                             \
-        wx.TYPE[i] = LD_INSN(env, addr + (i << DF), ##__VA_ARGS__);     \
-    }                                                                   \
-    memcpy(pwd, &wx, sizeof(wr_t));                                     \
+void helper_msa_ld_b(CPUMIPSState *env, uint32_t wd,
+                     target_ulong addr)
+{
+    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
+    MEMOP_IDX(DF_BYTE)
+#if !defined(CONFIG_USER_ONLY)
+#if !defined(HOST_WORDS_BIGENDIAN)
+    pwd->b[0]  = helper_ret_ldub_mmu(env, addr + (0  << DF_BYTE), oi, GETPC());
+    pwd->b[1]  = helper_ret_ldub_mmu(env, addr + (1  << DF_BYTE), oi, GETPC());
+    pwd->b[2]  = helper_ret_ldub_mmu(env, addr + (2  << DF_BYTE), oi, GETPC());
+    pwd->b[3]  = helper_ret_ldub_mmu(env, addr + (3  << DF_BYTE), oi, GETPC());
+    pwd->b[4]  = helper_ret_ldub_mmu(env, addr + (4  << DF_BYTE), oi, GETPC());
+    pwd->b[5]  = helper_ret_ldub_mmu(env, addr + (5  << DF_BYTE), oi, GETPC());
+    pwd->b[6]  = helper_ret_ldub_mmu(env, addr + (6  << DF_BYTE), oi, GETPC());
+    pwd->b[7]  = helper_ret_ldub_mmu(env, addr + (7  << DF_BYTE), oi, GETPC());
+    pwd->b[8]  = helper_ret_ldub_mmu(env, addr + (8  << DF_BYTE), oi, GETPC());
+    pwd->b[9]  = helper_ret_ldub_mmu(env, addr + (9  << DF_BYTE), oi, GETPC());
+    pwd->b[10] = helper_ret_ldub_mmu(env, addr + (10 << DF_BYTE), oi, GETPC());
+    pwd->b[11] = helper_ret_ldub_mmu(env, addr + (11 << DF_BYTE), oi, GETPC());
+    pwd->b[12] = helper_ret_ldub_mmu(env, addr + (12 << DF_BYTE), oi, GETPC());
+    pwd->b[13] = helper_ret_ldub_mmu(env, addr + (13 << DF_BYTE), oi, GETPC());
+    pwd->b[14] = helper_ret_ldub_mmu(env, addr + (14 << DF_BYTE), oi, GETPC());
+    pwd->b[15] = helper_ret_ldub_mmu(env, addr + (15 << DF_BYTE), oi, GETPC());
+#else
+    pwd->b[0]  = helper_ret_ldub_mmu(env, addr + (7  << DF_BYTE), oi, GETPC());
+    pwd->b[1]  = helper_ret_ldub_mmu(env, addr + (6  << DF_BYTE), oi, GETPC());
+    pwd->b[2]  = helper_ret_ldub_mmu(env, addr + (5  << DF_BYTE), oi, GETPC());
+    pwd->b[3]  = helper_ret_ldub_mmu(env, addr + (4  << DF_BYTE), oi, GETPC());
+    pwd->b[4]  = helper_ret_ldub_mmu(env, addr + (3  << DF_BYTE), oi, GETPC());
+    pwd->b[5]  = helper_ret_ldub_mmu(env, addr + (2  << DF_BYTE), oi, GETPC());
+    pwd->b[6]  = helper_ret_ldub_mmu(env, addr + (1  << DF_BYTE), oi, GETPC());
+    pwd->b[7]  = helper_ret_ldub_mmu(env, addr + (0  << DF_BYTE), oi, GETPC());
+    pwd->b[8]  = helper_ret_ldub_mmu(env, addr + (15 << DF_BYTE), oi, GETPC());
+    pwd->b[9]  = helper_ret_ldub_mmu(env, addr + (14 << DF_BYTE), oi, GETPC());
+    pwd->b[10] = helper_ret_ldub_mmu(env, addr + (13 << DF_BYTE), oi, GETPC());
+    pwd->b[11] = helper_ret_ldub_mmu(env, addr + (12 << DF_BYTE), oi, GETPC());
+    pwd->b[12] = helper_ret_ldub_mmu(env, addr + (11 << DF_BYTE), oi, GETPC());
+    pwd->b[13] = helper_ret_ldub_mmu(env, addr + (10 << DF_BYTE), oi, GETPC());
+    pwd->b[14] = helper_ret_ldub_mmu(env, addr + (9  << DF_BYTE), oi, GETPC());
+    pwd->b[15] = helper_ret_ldub_mmu(env, addr + (8  << DF_BYTE), oi, GETPC());
+#endif
+#else
+#if !defined(HOST_WORDS_BIGENDIAN)
+    pwd->b[0]  = cpu_ldub_data(env, addr + (0  << DF_BYTE));
+    pwd->b[1]  = cpu_ldub_data(env, addr + (1  << DF_BYTE));
+    pwd->b[2]  = cpu_ldub_data(env, addr + (2  << DF_BYTE));
+    pwd->b[3]  = cpu_ldub_data(env, addr + (3  << DF_BYTE));
+    pwd->b[4]  = cpu_ldub_data(env, addr + (4  << DF_BYTE));
+    pwd->b[5]  = cpu_ldub_data(env, addr + (5  << DF_BYTE));
+    pwd->b[6]  = cpu_ldub_data(env, addr + (6  << DF_BYTE));
+    pwd->b[7]  = cpu_ldub_data(env, addr + (7  << DF_BYTE));
+    pwd->b[8]  = cpu_ldub_data(env, addr + (8  << DF_BYTE));
+    pwd->b[9]  = cpu_ldub_data(env, addr + (9  << DF_BYTE));
+    pwd->b[10] = cpu_ldub_data(env, addr + (10 << DF_BYTE));
+    pwd->b[11] = cpu_ldub_data(env, addr + (11 << DF_BYTE));
+    pwd->b[12] = cpu_ldub_data(env, addr + (12 << DF_BYTE));
+    pwd->b[13] = cpu_ldub_data(env, addr + (13 << DF_BYTE));
+    pwd->b[14] = cpu_ldub_data(env, addr + (14 << DF_BYTE));
+    pwd->b[15] = cpu_ldub_data(env, addr + (15 << DF_BYTE));
+#else
+    pwd->b[0]  = cpu_ldub_data(env, addr + (7  << DF_BYTE));
+    pwd->b[1]  = cpu_ldub_data(env, addr + (6  << DF_BYTE));
+    pwd->b[2]  = cpu_ldub_data(env, addr + (5  << DF_BYTE));
+    pwd->b[3]  = cpu_ldub_data(env, addr + (4  << DF_BYTE));
+    pwd->b[4]  = cpu_ldub_data(env, addr + (3  << DF_BYTE));
+    pwd->b[5]  = cpu_ldub_data(env, addr + (2  << DF_BYTE));
+    pwd->b[6]  = cpu_ldub_data(env, addr + (1  << DF_BYTE));
+    pwd->b[7]  = cpu_ldub_data(env, addr + (0  << DF_BYTE));
+    pwd->b[8]  = cpu_ldub_data(env, addr + (15 << DF_BYTE));
+    pwd->b[9]  = cpu_ldub_data(env, addr + (14 << DF_BYTE));
+    pwd->b[10] = cpu_ldub_data(env, addr + (13 << DF_BYTE));
+    pwd->b[11] = cpu_ldub_data(env, addr + (12 << DF_BYTE));
+    pwd->b[12] = cpu_ldub_data(env, addr + (11 << DF_BYTE));
+    pwd->b[13] = cpu_ldub_data(env, addr + (10 << DF_BYTE));
+    pwd->b[14] = cpu_ldub_data(env, addr + (9 << DF_BYTE));
+    pwd->b[15] = cpu_ldub_data(env, addr + (8 << DF_BYTE));
+#endif
+#endif
 }
 
+void helper_msa_ld_h(CPUMIPSState *env, uint32_t wd,
+                     target_ulong addr)
+{
+    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
+    MEMOP_IDX(DF_HALF)
 #if !defined(CONFIG_USER_ONLY)
-MSA_LD_DF(DF_BYTE,   b, helper_ret_ldub_mmu, oi, GETPC())
-MSA_LD_DF(DF_HALF,   h, helper_ret_lduw_mmu, oi, GETPC())
-MSA_LD_DF(DF_WORD,   w, helper_ret_ldul_mmu, oi, GETPC())
-MSA_LD_DF(DF_DOUBLE, d, helper_ret_ldq_mmu,  oi, GETPC())
+#if !defined(HOST_WORDS_BIGENDIAN)
+    pwd->h[0] = helper_ret_lduw_mmu(env, addr + (0 << DF_HALF), oi, GETPC());
+    pwd->h[1] = helper_ret_lduw_mmu(env, addr + (1 << DF_HALF), oi, GETPC());
+    pwd->h[2] = helper_ret_lduw_mmu(env, addr + (2 << DF_HALF), oi, GETPC());
+    pwd->h[3] = helper_ret_lduw_mmu(env, addr + (3 << DF_HALF), oi, GETPC());
+    pwd->h[4] = helper_ret_lduw_mmu(env, addr + (4 << DF_HALF), oi, GETPC());
+    pwd->h[5] = helper_ret_lduw_mmu(env, addr + (5 << DF_HALF), oi, GETPC());
+    pwd->h[6] = helper_ret_lduw_mmu(env, addr + (6 << DF_HALF), oi, GETPC());
+    pwd->h[7] = helper_ret_lduw_mmu(env, addr + (7 << DF_HALF), oi, GETPC());
+#else
+    pwd->h[0] = helper_ret_lduw_mmu(env, addr + (3 << DF_HALF), oi, GETPC());
+    pwd->h[1] = helper_ret_lduw_mmu(env, addr + (2 << DF_HALF), oi, GETPC());
+    pwd->h[2] = helper_ret_lduw_mmu(env, addr + (1 << DF_HALF), oi, GETPC());
+    pwd->h[3] = helper_ret_lduw_mmu(env, addr + (0 << DF_HALF), oi, GETPC());
+    pwd->h[4] = helper_ret_lduw_mmu(env, addr + (7 << DF_HALF), oi, GETPC());
+    pwd->h[5] = helper_ret_lduw_mmu(env, addr + (6 << DF_HALF), oi, GETPC());
+    pwd->h[6] = helper_ret_lduw_mmu(env, addr + (5 << DF_HALF), oi, GETPC());
+    pwd->h[7] = helper_ret_lduw_mmu(env, addr + (4 << DF_HALF), oi, GETPC());
+#endif
+#else
+#if !defined(HOST_WORDS_BIGENDIAN)
+    pwd->h[0] = cpu_lduw_data(env, addr + (0 << DF_HALF));
+    pwd->h[1] = cpu_lduw_data(env, addr + (1 << DF_HALF));
+    pwd->h[2] = cpu_lduw_data(env, addr + (2 << DF_HALF));
+    pwd->h[3] = cpu_lduw_data(env, addr + (3 << DF_HALF));
+    pwd->h[4] = cpu_lduw_data(env, addr + (4 << DF_HALF));
+    pwd->h[5] = cpu_lduw_data(env, addr + (5 << DF_HALF));
+    pwd->h[6] = cpu_lduw_data(env, addr + (6 << DF_HALF));
+    pwd->h[7] = cpu_lduw_data(env, addr + (7 << DF_HALF));
 #else
-MSA_LD_DF(DF_BYTE,   b, cpu_ldub_data)
-MSA_LD_DF(DF_HALF,   h, cpu_lduw_data)
-MSA_LD_DF(DF_WORD,   w, cpu_ldl_data)
-MSA_LD_DF(DF_DOUBLE, d, cpu_ldq_data)
+    pwd->h[0] = cpu_lduw_data(env, addr + (3 << DF_HALF));
+    pwd->h[1] = cpu_lduw_data(env, addr + (2 << DF_HALF));
+    pwd->h[2] = cpu_lduw_data(env, addr + (1 << DF_HALF));
+    pwd->h[3] = cpu_lduw_data(env, addr + (0 << DF_HALF));
+    pwd->h[4] = cpu_lduw_data(env, addr + (7 << DF_HALF));
+    pwd->h[5] = cpu_lduw_data(env, addr + (6 << DF_HALF));
+    pwd->h[6] = cpu_lduw_data(env, addr + (5 << DF_HALF));
+    pwd->h[7] = cpu_lduw_data(env, addr + (4 << DF_HALF));
 #endif
+#endif
+}
+
+void helper_msa_ld_w(CPUMIPSState *env, uint32_t wd,
+                     target_ulong addr)
+{
+    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
+    MEMOP_IDX(DF_WORD)
+#if !defined(CONFIG_USER_ONLY)
+#if !defined(HOST_WORDS_BIGENDIAN)
+    pwd->w[0] = helper_ret_ldul_mmu(env, addr + (0 << DF_WORD), oi, GETPC());
+    pwd->w[1] = helper_ret_ldul_mmu(env, addr + (1 << DF_WORD), oi, GETPC());
+    pwd->w[2] = helper_ret_ldul_mmu(env, addr + (2 << DF_WORD), oi, GETPC());
+    pwd->w[3] = helper_ret_ldul_mmu(env, addr + (3 << DF_WORD), oi, GETPC());
+#else
+    pwd->w[0] = helper_ret_ldul_mmu(env, addr + (1 << DF_WORD), oi, GETPC());
+    pwd->w[1] = helper_ret_ldul_mmu(env, addr + (0 << DF_WORD), oi, GETPC());
+    pwd->w[2] = helper_ret_ldul_mmu(env, addr + (3 << DF_WORD), oi, GETPC());
+    pwd->w[3] = helper_ret_ldul_mmu(env, addr + (2 << DF_WORD), oi, GETPC());
+#endif
+#else
+#if !defined(HOST_WORDS_BIGENDIAN)
+    pwd->w[0] = cpu_ldl_data(env, addr + (0 << DF_WORD));
+    pwd->w[1] = cpu_ldl_data(env, addr + (1 << DF_WORD));
+    pwd->w[2] = cpu_ldl_data(env, addr + (2 << DF_WORD));
+    pwd->w[3] = cpu_ldl_data(env, addr + (3 << DF_WORD));
+#else
+    pwd->w[0] = cpu_ldl_data(env, addr + (1 << DF_WORD));
+    pwd->w[1] = cpu_ldl_data(env, addr + (0 << DF_WORD));
+    pwd->w[2] = cpu_ldl_data(env, addr + (3 << DF_WORD));
+    pwd->w[3] = cpu_ldl_data(env, addr + (2 << DF_WORD));
+#endif
+#endif
+}
+
+void helper_msa_ld_d(CPUMIPSState *env, uint32_t wd,
+                     target_ulong addr)
+{
+    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
+    MEMOP_IDX(DF_DOUBLE)
+#if !defined(CONFIG_USER_ONLY)
+    pwd->d[0] = helper_ret_ldq_mmu(env, addr + (0 << DF_DOUBLE), oi, GETPC());
+    pwd->d[1] = helper_ret_ldq_mmu(env, addr + (1 << DF_DOUBLE), oi, GETPC());
+#else
+    pwd->d[0] = cpu_ldq_data(env, addr + (0 << DF_DOUBLE));
+    pwd->d[1] = cpu_ldq_data(env, addr + (1 << DF_DOUBLE));
+#endif
+}
 
 #define MSA_PAGESPAN(x) \
         ((((x) & ~TARGET_PAGE_MASK) + MSA_WRLEN/8 - 1) >= TARGET_PAGE_SIZE)
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH v4 2/5] target/mips: Fix MSA instructions ST.<B|H|W|D> on big endian host
  2019-04-02 13:43 [Qemu-devel] [PATCH v4 0/5] target/mips: Fix support for MSA instructions on a big endian host Mateja Marjanovic
  2019-04-02 13:43 ` [Qemu-devel] [PATCH v4 1/5] target/mips: Fix MSA instructions LD.<B|H|W|D> on " Mateja Marjanovic
@ 2019-04-02 13:43 ` Mateja Marjanovic
  2019-04-02 20:39   ` Aleksandar Markovic
  2019-05-20 12:59   ` Aleksandar Markovic
  2019-04-02 13:43 ` [Qemu-devel] [PATCH v4 3/5] target/mips: Refactor and fix COPY_S.<B|H|W|D> instructions Mateja Marjanovic
                   ` (2 subsequent siblings)
  4 siblings, 2 replies; 17+ messages in thread
From: Mateja Marjanovic @ 2019-04-02 13:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: aurelien, amarkovic, arikalo

From: Mateja Marjanovic <Mateja.Marjanovic@rt-rk.com>

Fix the case when the host is a big endian machine, and change
the approach toward ST.<B|H|W|D> instruction helpers.

Signed-off-by: Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
---
 target/mips/op_helper.c | 188 ++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 168 insertions(+), 20 deletions(-)

diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c
index 45be406..d94909a 100644
--- a/target/mips/op_helper.c
+++ b/target/mips/op_helper.c
@@ -4565,31 +4565,179 @@ static inline void ensure_writable_pages(CPUMIPSState *env,
 #endif
 }
 
-#define MSA_ST_DF(DF, TYPE, ST_INSN, ...)                               \
-void helper_msa_st_ ## TYPE(CPUMIPSState *env, uint32_t wd,             \
-                            target_ulong addr)                          \
-{                                                                       \
-    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);                          \
-    int mmu_idx = cpu_mmu_index(env, false);				\
-    int i;                                                              \
-    MEMOP_IDX(DF)                                                       \
-    ensure_writable_pages(env, addr, mmu_idx, GETPC());                 \
-    for (i = 0; i < DF_ELEMENTS(DF); i++) {                             \
-        ST_INSN(env, addr + (i << DF), pwd->TYPE[i], ##__VA_ARGS__);    \
-    }                                                                   \
+void helper_msa_st_b(CPUMIPSState *env, uint32_t wd,
+                     target_ulong addr)
+{
+    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
+    MEMOP_IDX(DF_BYTE)
+#if !defined(CONFIG_USER_ONLY)
+#if !defined(HOST_WORDS_BIGENDIAN)
+    helper_ret_stb_mmu(env, addr + (0  << DF_BYTE), pwd->b[0],  oi, GETPC());
+    helper_ret_stb_mmu(env, addr + (1  << DF_BYTE), pwd->b[1],  oi, GETPC());
+    helper_ret_stb_mmu(env, addr + (2  << DF_BYTE), pwd->b[2],  oi, GETPC());
+    helper_ret_stb_mmu(env, addr + (3  << DF_BYTE), pwd->b[3],  oi, GETPC());
+    helper_ret_stb_mmu(env, addr + (4  << DF_BYTE), pwd->b[4],  oi, GETPC());
+    helper_ret_stb_mmu(env, addr + (5  << DF_BYTE), pwd->b[5],  oi, GETPC());
+    helper_ret_stb_mmu(env, addr + (6  << DF_BYTE), pwd->b[6],  oi, GETPC());
+    helper_ret_stb_mmu(env, addr + (7  << DF_BYTE), pwd->b[7],  oi, GETPC());
+    helper_ret_stb_mmu(env, addr + (8  << DF_BYTE), pwd->b[8],  oi, GETPC());
+    helper_ret_stb_mmu(env, addr + (9  << DF_BYTE), pwd->b[9],  oi, GETPC());
+    helper_ret_stb_mmu(env, addr + (10 << DF_BYTE), pwd->b[10], oi, GETPC());
+    helper_ret_stb_mmu(env, addr + (11 << DF_BYTE), pwd->b[11], oi, GETPC());
+    helper_ret_stb_mmu(env, addr + (12 << DF_BYTE), pwd->b[12], oi, GETPC());
+    helper_ret_stb_mmu(env, addr + (13 << DF_BYTE), pwd->b[13], oi, GETPC());
+    helper_ret_stb_mmu(env, addr + (14 << DF_BYTE), pwd->b[14], oi, GETPC());
+    helper_ret_stb_mmu(env, addr + (15 << DF_BYTE), pwd->b[15], oi, GETPC());
+#else
+    helper_ret_stb_mmu(env, addr + (7  << DF_BYTE), pwd->b[0],  oi, GETPC());
+    helper_ret_stb_mmu(env, addr + (6  << DF_BYTE), pwd->b[1],  oi, GETPC());
+    helper_ret_stb_mmu(env, addr + (5  << DF_BYTE), pwd->b[2],  oi, GETPC());
+    helper_ret_stb_mmu(env, addr + (4  << DF_BYTE), pwd->b[3],  oi, GETPC());
+    helper_ret_stb_mmu(env, addr + (3  << DF_BYTE), pwd->b[4],  oi, GETPC());
+    helper_ret_stb_mmu(env, addr + (2  << DF_BYTE), pwd->b[5],  oi, GETPC());
+    helper_ret_stb_mmu(env, addr + (1  << DF_BYTE), pwd->b[6],  oi, GETPC());
+    helper_ret_stb_mmu(env, addr + (0  << DF_BYTE), pwd->b[7],  oi, GETPC());
+    helper_ret_stb_mmu(env, addr + (15 << DF_BYTE), pwd->b[8],  oi, GETPC());
+    helper_ret_stb_mmu(env, addr + (14 << DF_BYTE), pwd->b[9],  oi, GETPC());
+    helper_ret_stb_mmu(env, addr + (13 << DF_BYTE), pwd->b[10], oi, GETPC());
+    helper_ret_stb_mmu(env, addr + (12 << DF_BYTE), pwd->b[11], oi, GETPC());
+    helper_ret_stb_mmu(env, addr + (11 << DF_BYTE), pwd->b[12], oi, GETPC());
+    helper_ret_stb_mmu(env, addr + (10 << DF_BYTE), pwd->b[13], oi, GETPC());
+    helper_ret_stb_mmu(env, addr + (9  << DF_BYTE), pwd->b[14], oi, GETPC());
+    helper_ret_stb_mmu(env, addr + (8  << DF_BYTE), pwd->b[15], oi, GETPC());
+#endif
+#else
+#if !defined(HOST_WORDS_BIGENDIAN)
+    cpu_stb_data(env, addr + (0  << DF_BYTE), pwd->b[0]);
+    cpu_stb_data(env, addr + (1  << DF_BYTE), pwd->b[1]);
+    cpu_stb_data(env, addr + (2  << DF_BYTE), pwd->b[2]);
+    cpu_stb_data(env, addr + (3  << DF_BYTE), pwd->b[3]);
+    cpu_stb_data(env, addr + (4  << DF_BYTE), pwd->b[4]);
+    cpu_stb_data(env, addr + (5  << DF_BYTE), pwd->b[5]);
+    cpu_stb_data(env, addr + (6  << DF_BYTE), pwd->b[6]);
+    cpu_stb_data(env, addr + (7  << DF_BYTE), pwd->b[7]);
+    cpu_stb_data(env, addr + (8  << DF_BYTE), pwd->b[8]);
+    cpu_stb_data(env, addr + (9  << DF_BYTE), pwd->b[9]);
+    cpu_stb_data(env, addr + (10 << DF_BYTE), pwd->b[10]);
+    cpu_stb_data(env, addr + (11 << DF_BYTE), pwd->b[11]);
+    cpu_stb_data(env, addr + (12 << DF_BYTE), pwd->b[12]);
+    cpu_stb_data(env, addr + (13 << DF_BYTE), pwd->b[13]);
+    cpu_stb_data(env, addr + (14 << DF_BYTE), pwd->b[14]);
+    cpu_stb_data(env, addr + (15 << DF_BYTE), pwd->b[15]);
+#else
+    cpu_stb_data(env, addr + (7  << DF_BYTE), pwd->b[0]);
+    cpu_stb_data(env, addr + (6  << DF_BYTE), pwd->b[1]);
+    cpu_stb_data(env, addr + (5  << DF_BYTE), pwd->b[2]);
+    cpu_stb_data(env, addr + (4  << DF_BYTE), pwd->b[3]);
+    cpu_stb_data(env, addr + (3  << DF_BYTE), pwd->b[4]);
+    cpu_stb_data(env, addr + (2  << DF_BYTE), pwd->b[5]);
+    cpu_stb_data(env, addr + (1  << DF_BYTE), pwd->b[6]);
+    cpu_stb_data(env, addr + (0  << DF_BYTE), pwd->b[7]);
+    cpu_stb_data(env, addr + (15 << DF_BYTE), pwd->b[8]);
+    cpu_stb_data(env, addr + (14 << DF_BYTE), pwd->b[9]);
+    cpu_stb_data(env, addr + (13 << DF_BYTE), pwd->b[10]);
+    cpu_stb_data(env, addr + (12 << DF_BYTE), pwd->b[11]);
+    cpu_stb_data(env, addr + (11 << DF_BYTE), pwd->b[12]);
+    cpu_stb_data(env, addr + (10 << DF_BYTE), pwd->b[13]);
+    cpu_stb_data(env, addr + (9  << DF_BYTE), pwd->b[14]);
+    cpu_stb_data(env, addr + (8  << DF_BYTE), pwd->b[15]);
+#endif
+#endif
+}
+
+void helper_msa_st_h(CPUMIPSState *env, uint32_t wd,
+                     target_ulong addr)
+{
+    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
+    MEMOP_IDX(DF_HALF)
+#if !defined(CONFIG_USER_ONLY)
+#if !defined(HOST_WORDS_BIGENDIAN)
+    helper_ret_stw_mmu(env, addr + (0 << DF_HALF), pwd->h[0], oi, GETPC());
+    helper_ret_stw_mmu(env, addr + (1 << DF_HALF), pwd->h[1], oi, GETPC());
+    helper_ret_stw_mmu(env, addr + (2 << DF_HALF), pwd->h[2], oi, GETPC());
+    helper_ret_stw_mmu(env, addr + (3 << DF_HALF), pwd->h[3], oi, GETPC());
+    helper_ret_stw_mmu(env, addr + (4 << DF_HALF), pwd->h[4], oi, GETPC());
+    helper_ret_stw_mmu(env, addr + (5 << DF_HALF), pwd->h[5], oi, GETPC());
+    helper_ret_stw_mmu(env, addr + (6 << DF_HALF), pwd->h[6], oi, GETPC());
+    helper_ret_stw_mmu(env, addr + (7 << DF_HALF), pwd->h[7], oi, GETPC());
+#else
+    helper_ret_stw_mmu(env, addr + (3 << DF_HALF), pwd->h[0], oi, GETPC());
+    helper_ret_stw_mmu(env, addr + (2 << DF_HALF), pwd->h[1], oi, GETPC());
+    helper_ret_stw_mmu(env, addr + (1 << DF_HALF), pwd->h[2], oi, GETPC());
+    helper_ret_stw_mmu(env, addr + (0 << DF_HALF), pwd->h[3], oi, GETPC());
+    helper_ret_stw_mmu(env, addr + (7 << DF_HALF), pwd->h[4], oi, GETPC());
+    helper_ret_stw_mmu(env, addr + (6 << DF_HALF), pwd->h[5], oi, GETPC());
+    helper_ret_stw_mmu(env, addr + (5 << DF_HALF), pwd->h[6], oi, GETPC());
+    helper_ret_stw_mmu(env, addr + (4 << DF_HALF), pwd->h[7], oi, GETPC());
+#endif
+#else
+#if !defined(HOST_WORDS_BIGENDIAN)
+    cpu_stw_data(env, addr + (0 << DF_HALF), pwd->h[0]);
+    cpu_stw_data(env, addr + (1 << DF_HALF), pwd->h[1]);
+    cpu_stw_data(env, addr + (2 << DF_HALF), pwd->h[2]);
+    cpu_stw_data(env, addr + (3 << DF_HALF), pwd->h[3]);
+    cpu_stw_data(env, addr + (4 << DF_HALF), pwd->h[4]);
+    cpu_stw_data(env, addr + (5 << DF_HALF), pwd->h[5]);
+    cpu_stw_data(env, addr + (6 << DF_HALF), pwd->h[6]);
+    cpu_stw_data(env, addr + (7 << DF_HALF), pwd->h[7]);
+#else
+    cpu_stw_data(env, addr + (3 << DF_HALF), pwd->h[0]);
+    cpu_stw_data(env, addr + (2 << DF_HALF), pwd->h[1]);
+    cpu_stw_data(env, addr + (1 << DF_HALF), pwd->h[2]);
+    cpu_stw_data(env, addr + (0 << DF_HALF), pwd->h[3]);
+    cpu_stw_data(env, addr + (7 << DF_HALF), pwd->h[4]);
+    cpu_stw_data(env, addr + (6 << DF_HALF), pwd->h[5]);
+    cpu_stw_data(env, addr + (5 << DF_HALF), pwd->h[6]);
+    cpu_stw_data(env, addr + (4 << DF_HALF), pwd->h[7]);
+#endif
+#endif
 }
 
+void helper_msa_st_w(CPUMIPSState *env, uint32_t wd,
+                     target_ulong addr)
+{
+    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
+    MEMOP_IDX(DF_WORD)
 #if !defined(CONFIG_USER_ONLY)
-MSA_ST_DF(DF_BYTE,   b, helper_ret_stb_mmu, oi, GETPC())
-MSA_ST_DF(DF_HALF,   h, helper_ret_stw_mmu, oi, GETPC())
-MSA_ST_DF(DF_WORD,   w, helper_ret_stl_mmu, oi, GETPC())
-MSA_ST_DF(DF_DOUBLE, d, helper_ret_stq_mmu, oi, GETPC())
+#if !defined(HOST_WORDS_BIGENDIAN)
+    helper_ret_stl_mmu(env, addr + (0 << DF_WORD), oi, GETPC(), pwd->w[0]);
+    helper_ret_stl_mmu(env, addr + (1 << DF_WORD), oi, GETPC(), pwd->w[1]);
+    helper_ret_stl_mmu(env, addr + (2 << DF_WORD), oi, GETPC(), pwd->w[2]);
+    helper_ret_stl_mmu(env, addr + (3 << DF_WORD), oi, GETPC(), pwd->w[3]);
 #else
-MSA_ST_DF(DF_BYTE,   b, cpu_stb_data)
-MSA_ST_DF(DF_HALF,   h, cpu_stw_data)
-MSA_ST_DF(DF_WORD,   w, cpu_stl_data)
-MSA_ST_DF(DF_DOUBLE, d, cpu_stq_data)
+    helper_ret_stl_mmu(env, addr + (1 << DF_WORD), oi, GETPC(), pwd->w[0]);
+    helper_ret_stl_mmu(env, addr + (0 << DF_WORD), oi, GETPC(), pwd->w[1]);
+    helper_ret_stl_mmu(env, addr + (3 << DF_WORD), oi, GETPC(), pwd->w[2]);
+    helper_ret_stl_mmu(env, addr + (2 << DF_WORD), oi, GETPC(), pwd->w[3]);
 #endif
+#else
+#if !defined(HOST_WORDS_BIGENDIAN)
+    cpu_stl_data(env, addr + (0 << DF_WORD), pwd->w[0]);
+    cpu_stl_data(env, addr + (1 << DF_WORD), pwd->w[1]);
+    cpu_stl_data(env, addr + (2 << DF_WORD), pwd->w[2]);
+    cpu_stl_data(env, addr + (3 << DF_WORD), pwd->w[3]);
+#else
+    cpu_stl_data(env, addr + (1 << DF_WORD), pwd->w[0]);
+    cpu_stl_data(env, addr + (0 << DF_WORD), pwd->w[1]);
+    cpu_stl_data(env, addr + (3 << DF_WORD), pwd->w[2]);
+    cpu_stl_data(env, addr + (2 << DF_WORD), pwd->w[3]);
+#endif
+#endif
+}
+
+void helper_msa_st_d(CPUMIPSState *env, uint32_t wd,
+                     target_ulong addr)
+{
+    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
+    MEMOP_IDX(DF_DOUBLE)
+#if !defined(CONFIG_USER_ONLY)
+    helper_ret_stq_mmu(env, addr + (0 << DF_DOUBLE), pwd->d[0], oi, GETPC());
+    helper_ret_stq_mmu(env, addr + (1 << DF_DOUBLE), pwd->d[1], oi, GETPC());
+#else
+    cpu_stq_data(env, addr + (0 << DF_DOUBLE), pwd->d[0]);
+    cpu_stq_data(env, addr + (1 << DF_DOUBLE), pwd->d[1]);
+#endif
+}
 
 void helper_cache(CPUMIPSState *env, target_ulong addr, uint32_t op)
 {
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH v4 3/5] target/mips: Refactor and fix COPY_S.<B|H|W|D> instructions
  2019-04-02 13:43 [Qemu-devel] [PATCH v4 0/5] target/mips: Fix support for MSA instructions on a big endian host Mateja Marjanovic
  2019-04-02 13:43 ` [Qemu-devel] [PATCH v4 1/5] target/mips: Fix MSA instructions LD.<B|H|W|D> on " Mateja Marjanovic
  2019-04-02 13:43 ` [Qemu-devel] [PATCH v4 2/5] target/mips: Fix MSA instructions ST.<B|H|W|D> " Mateja Marjanovic
@ 2019-04-02 13:43 ` Mateja Marjanovic
  2019-05-18 15:47   ` Aleksandar Markovic
  2019-04-02 13:43 ` [Qemu-devel] [PATCH v4 4/5] target/mips: Refactor and fix COPY_U.<B|H|W> instructions Mateja Marjanovic
  2019-04-02 13:43 ` [Qemu-devel] [PATCH v4 5/5] target/mips: Refactor and fix INSERT.<B|H|W|D> instructions Mateja Marjanovic
  4 siblings, 1 reply; 17+ messages in thread
From: Mateja Marjanovic @ 2019-04-02 13:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: aurelien, amarkovic, arikalo

From: Mateja Marjanovic <Mateja.Marjanovic@rt-rk.com>

The old version of the helper for the COPY_S.<B|H|W|D> MSA instructions
has been replaced with four helpers that don't use switch, and change
the endianness of the given index, when executed on a big endian host.

Signed-off-by: Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
---
 target/mips/helper.h     |  7 +++++-
 target/mips/msa_helper.c | 62 +++++++++++++++++++++++++++++++++---------------
 target/mips/translate.c  | 19 ++++++++++++++-
 3 files changed, 67 insertions(+), 21 deletions(-)

diff --git a/target/mips/helper.h b/target/mips/helper.h
index 2f23b0d..4e49618 100644
--- a/target/mips/helper.h
+++ b/target/mips/helper.h
@@ -874,7 +874,7 @@ DEF_HELPER_5(msa_hsub_u_df, void, env, i32, i32, i32, i32)
 
 DEF_HELPER_5(msa_sldi_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_splati_df, void, env, i32, i32, i32, i32)
-DEF_HELPER_5(msa_copy_s_df, void, env, i32, i32, i32, i32)
+
 DEF_HELPER_5(msa_copy_u_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_insert_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_insve_df, void, env, i32, i32, i32, i32)
@@ -936,6 +936,11 @@ DEF_HELPER_4(msa_pcnt_df, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_nloc_df, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_nlzc_df, void, env, i32, i32, i32)
 
+DEF_HELPER_4(msa_copy_s_b, void, env, i32, i32, i32)
+DEF_HELPER_4(msa_copy_s_h, void, env, i32, i32, i32)
+DEF_HELPER_4(msa_copy_s_w, void, env, i32, i32, i32)
+DEF_HELPER_4(msa_copy_s_d, void, env, i32, i32, i32)
+
 DEF_HELPER_4(msa_fclass_df, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_ftrunc_s_df, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_ftrunc_u_df, void, env, i32, i32, i32)
diff --git a/target/mips/msa_helper.c b/target/mips/msa_helper.c
index a500c59..5a06579 100644
--- a/target/mips/msa_helper.c
+++ b/target/mips/msa_helper.c
@@ -1232,29 +1232,53 @@ void helper_msa_splati_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
     msa_splat_df(df, pwd, pws, n);
 }
 
-void helper_msa_copy_s_df(CPUMIPSState *env, uint32_t df, uint32_t rd,
-                          uint32_t ws, uint32_t n)
+void helper_msa_copy_s_b(CPUMIPSState *env, uint32_t rd,
+                         uint32_t ws, uint32_t n)
 {
-    n %= DF_ELEMENTS(df);
+    n %= 16;
+#if defined(HOST_WORDS_BIGENDIAN)
+    if (n < 8) {
+        n = 8 - n - 1;
+    } else {
+        n = 24 - n - 1;
+    }
+#endif
+    env->active_tc.gpr[rd] = (int8_t)env->active_fpu.fpr[ws].wr.b[n];
+}
 
-    switch (df) {
-    case DF_BYTE:
-        env->active_tc.gpr[rd] = (int8_t)env->active_fpu.fpr[ws].wr.b[n];
-        break;
-    case DF_HALF:
-        env->active_tc.gpr[rd] = (int16_t)env->active_fpu.fpr[ws].wr.h[n];
-        break;
-    case DF_WORD:
-        env->active_tc.gpr[rd] = (int32_t)env->active_fpu.fpr[ws].wr.w[n];
-        break;
-#ifdef TARGET_MIPS64
-    case DF_DOUBLE:
-        env->active_tc.gpr[rd] = (int64_t)env->active_fpu.fpr[ws].wr.d[n];
-        break;
+void helper_msa_copy_s_h(CPUMIPSState *env, uint32_t rd,
+                         uint32_t ws, uint32_t n)
+{
+    n %= 8;
+#if defined(HOST_WORDS_BIGENDIAN)
+    if (n < 4) {
+        n = 4 - n - 1;
+    } else {
+        n = 12 - n - 1;
+    }
 #endif
-    default:
-        assert(0);
+    env->active_tc.gpr[rd] = (int16_t)env->active_fpu.fpr[ws].wr.h[n];
+}
+
+void helper_msa_copy_s_w(CPUMIPSState *env, uint32_t rd,
+                         uint32_t ws, uint32_t n)
+{
+    n %= 4;
+#if defined(HOST_WORDS_BIGENDIAN)
+    if (n < 2) {
+        n = 2 - n - 1;
+    } else {
+        n = 6 - n - 1;
     }
+#endif
+    env->active_tc.gpr[rd] = (int32_t)env->active_fpu.fpr[ws].wr.w[n];
+}
+
+void helper_msa_copy_s_d(CPUMIPSState *env, uint32_t rd,
+                         uint32_t ws, uint32_t n)
+{
+    n %= 2;
+    env->active_tc.gpr[rd] = (int64_t)env->active_fpu.fpr[ws].wr.d[n];
 }
 
 void helper_msa_copy_u_df(CPUMIPSState *env, uint32_t df, uint32_t rd,
diff --git a/target/mips/translate.c b/target/mips/translate.c
index 189bbc4..f2ea378 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -29401,7 +29401,24 @@ static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
         switch (MASK_MSA_ELM(ctx->opcode)) {
         case OPC_COPY_S_df:
             if (likely(wd != 0)) {
-                gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
+                switch (df) {
+                case DF_BYTE:
+                    gen_helper_msa_copy_s_b(cpu_env, twd, tws, tn);
+                    break;
+                case DF_HALF:
+                    gen_helper_msa_copy_s_h(cpu_env, twd, tws, tn);
+                    break;
+                case DF_WORD:
+                    gen_helper_msa_copy_s_w(cpu_env, twd, tws, tn);
+                    break;
+#if defined(TARGET_MIPS64)
+                case DF_DOUBLE:
+                    gen_helper_msa_copy_s_d(cpu_env, twd, tws, tn);
+                    break;
+#endif
+                default:
+                    assert(0);
+                }
             }
             break;
         case OPC_COPY_U_df:
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH v4 4/5] target/mips: Refactor and fix COPY_U.<B|H|W> instructions
  2019-04-02 13:43 [Qemu-devel] [PATCH v4 0/5] target/mips: Fix support for MSA instructions on a big endian host Mateja Marjanovic
                   ` (2 preceding siblings ...)
  2019-04-02 13:43 ` [Qemu-devel] [PATCH v4 3/5] target/mips: Refactor and fix COPY_S.<B|H|W|D> instructions Mateja Marjanovic
@ 2019-04-02 13:43 ` Mateja Marjanovic
  2019-05-18 15:47   ` Aleksandar Markovic
  2019-04-02 13:43 ` [Qemu-devel] [PATCH v4 5/5] target/mips: Refactor and fix INSERT.<B|H|W|D> instructions Mateja Marjanovic
  4 siblings, 1 reply; 17+ messages in thread
From: Mateja Marjanovic @ 2019-04-02 13:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: aurelien, amarkovic, arikalo

From: Mateja Marjanovic <Mateja.Marjanovic@rt-rk.com>

The old version of the helper for the COPY_U.<B|H|W> MSA instructions
has been replaced with four helpers that don't use switch, and change
the endianness of the given index, when executed on a big endian host.

Signed-off-by: Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
---
 target/mips/helper.h     |  4 +++-
 target/mips/msa_helper.c | 55 +++++++++++++++++++++++++++++++-----------------
 target/mips/translate.c  | 21 +++++++++++++++++-
 3 files changed, 59 insertions(+), 21 deletions(-)

diff --git a/target/mips/helper.h b/target/mips/helper.h
index 4e49618..8b6703c 100644
--- a/target/mips/helper.h
+++ b/target/mips/helper.h
@@ -875,7 +875,6 @@ DEF_HELPER_5(msa_hsub_u_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_sldi_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_splati_df, void, env, i32, i32, i32, i32)
 
-DEF_HELPER_5(msa_copy_u_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_insert_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_insve_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_3(msa_ctcmsa, void, env, tl, i32)
@@ -940,6 +939,9 @@ DEF_HELPER_4(msa_copy_s_b, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_copy_s_h, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_copy_s_w, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_copy_s_d, void, env, i32, i32, i32)
+DEF_HELPER_4(msa_copy_u_b, void, env, i32, i32, i32)
+DEF_HELPER_4(msa_copy_u_h, void, env, i32, i32, i32)
+DEF_HELPER_4(msa_copy_u_w, void, env, i32, i32, i32)
 
 DEF_HELPER_4(msa_fclass_df, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_ftrunc_s_df, void, env, i32, i32, i32)
diff --git a/target/mips/msa_helper.c b/target/mips/msa_helper.c
index 5a06579..d5bf4dc 100644
--- a/target/mips/msa_helper.c
+++ b/target/mips/msa_helper.c
@@ -1281,29 +1281,46 @@ void helper_msa_copy_s_d(CPUMIPSState *env, uint32_t rd,
     env->active_tc.gpr[rd] = (int64_t)env->active_fpu.fpr[ws].wr.d[n];
 }
 
-void helper_msa_copy_u_df(CPUMIPSState *env, uint32_t df, uint32_t rd,
-                          uint32_t ws, uint32_t n)
+void helper_msa_copy_u_b(CPUMIPSState *env, uint32_t rd,
+                         uint32_t ws, uint32_t n)
 {
-    n %= DF_ELEMENTS(df);
+    n %= 16;
+#if defined(HOST_WORDS_BIGENDIAN)
+    if (n < 8) {
+        n = 8 - n - 1;
+    } else {
+        n = 24 - n - 1;
+    }
+#endif
+    env->active_tc.gpr[rd] = (uint8_t)env->active_fpu.fpr[ws].wr.b[n];
+}
 
-    switch (df) {
-    case DF_BYTE:
-        env->active_tc.gpr[rd] = (uint8_t)env->active_fpu.fpr[ws].wr.b[n];
-        break;
-    case DF_HALF:
-        env->active_tc.gpr[rd] = (uint16_t)env->active_fpu.fpr[ws].wr.h[n];
-        break;
-    case DF_WORD:
-        env->active_tc.gpr[rd] = (uint32_t)env->active_fpu.fpr[ws].wr.w[n];
-        break;
-#ifdef TARGET_MIPS64
-    case DF_DOUBLE:
-        env->active_tc.gpr[rd] = (uint64_t)env->active_fpu.fpr[ws].wr.d[n];
-        break;
+void helper_msa_copy_u_h(CPUMIPSState *env, uint32_t rd,
+                         uint32_t ws, uint32_t n)
+{
+    n %= 8;
+#if defined(HOST_WORDS_BIGENDIAN)
+    if (n < 4) {
+        n = 4 - n - 1;
+    } else {
+        n = 12 - n - 1;
+    }
 #endif
-    default:
-        assert(0);
+    env->active_tc.gpr[rd] = (uint16_t)env->active_fpu.fpr[ws].wr.h[n];
+}
+
+void helper_msa_copy_u_w(CPUMIPSState *env, uint32_t rd,
+                         uint32_t ws, uint32_t n)
+{
+    n %= 4;
+#if defined(HOST_WORDS_BIGENDIAN)
+    if (n < 2) {
+        n = 2 - n - 1;
+    } else {
+        n = 6 - n - 1;
     }
+#endif
+    env->active_tc.gpr[rd] = (uint32_t)env->active_fpu.fpr[ws].wr.w[n];
 }
 
 void helper_msa_insert_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
diff --git a/target/mips/translate.c b/target/mips/translate.c
index f2ea378..72ed0a8 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -29397,6 +29397,11 @@ static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
             generate_exception_end(ctx, EXCP_RI);
             break;
         }
+        if ((MASK_MSA_ELM(ctx->opcode) == OPC_COPY_U_df) &&
+              (df == DF_WORD)) {
+            generate_exception_end(ctx, EXCP_RI);
+            break;
+        }
 #endif
         switch (MASK_MSA_ELM(ctx->opcode)) {
         case OPC_COPY_S_df:
@@ -29423,7 +29428,21 @@ static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
             break;
         case OPC_COPY_U_df:
             if (likely(wd != 0)) {
-                gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
+                switch (df) {
+                case DF_BYTE:
+                    gen_helper_msa_copy_u_b(cpu_env, twd, tws, tn);
+                    break;
+                case DF_HALF:
+                    gen_helper_msa_copy_u_h(cpu_env, twd, tws, tn);
+                    break;
+#if defined(TARGET_MIPS64)
+                case DF_WORD:
+                    gen_helper_msa_copy_u_w(cpu_env, twd, tws, tn);
+                    break;
+#endif
+                default:
+                    assert(0);
+                }
             }
             break;
         case OPC_INSERT_df:
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH v4 5/5] target/mips: Refactor and fix INSERT.<B|H|W|D> instructions
  2019-04-02 13:43 [Qemu-devel] [PATCH v4 0/5] target/mips: Fix support for MSA instructions on a big endian host Mateja Marjanovic
                   ` (3 preceding siblings ...)
  2019-04-02 13:43 ` [Qemu-devel] [PATCH v4 4/5] target/mips: Refactor and fix COPY_U.<B|H|W> instructions Mateja Marjanovic
@ 2019-04-02 13:43 ` Mateja Marjanovic
  2019-04-02 20:50   ` Aleksandar Markovic
  2019-05-19  5:25   ` Aleksandar Markovic
  4 siblings, 2 replies; 17+ messages in thread
From: Mateja Marjanovic @ 2019-04-02 13:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: aurelien, amarkovic, arikalo

From: Mateja Marjanovic <Mateja.Marjanovic@rt-rk.com>

The old version of the helper for the INSERT.<B|H|W|D> MSA instructions
has been replaced with four helpers that don't use switch, and change
the endianness of the given index, when executed on a big endian host.

Signed-off-by: Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
---
 target/mips/helper.h     |  5 +++-
 target/mips/msa_helper.c | 65 ++++++++++++++++++++++++++++++++++++------------
 target/mips/translate.c  | 19 +++++++++++++-
 3 files changed, 71 insertions(+), 18 deletions(-)

diff --git a/target/mips/helper.h b/target/mips/helper.h
index 8b6703c..82f6a40 100644
--- a/target/mips/helper.h
+++ b/target/mips/helper.h
@@ -875,7 +875,6 @@ DEF_HELPER_5(msa_hsub_u_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_sldi_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_splati_df, void, env, i32, i32, i32, i32)
 
-DEF_HELPER_5(msa_insert_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(msa_insve_df, void, env, i32, i32, i32, i32)
 DEF_HELPER_3(msa_ctcmsa, void, env, tl, i32)
 DEF_HELPER_2(msa_cfcmsa, tl, env, i32)
@@ -942,6 +941,10 @@ DEF_HELPER_4(msa_copy_s_d, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_copy_u_b, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_copy_u_h, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_copy_u_w, void, env, i32, i32, i32)
+DEF_HELPER_4(msa_insert_b, void, env, i32, i32, i32)
+DEF_HELPER_4(msa_insert_h, void, env, i32, i32, i32)
+DEF_HELPER_4(msa_insert_w, void, env, i32, i32, i32)
+DEF_HELPER_4(msa_insert_d, void, env, i32, i32, i32)
 
 DEF_HELPER_4(msa_fclass_df, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_ftrunc_s_df, void, env, i32, i32, i32)
diff --git a/target/mips/msa_helper.c b/target/mips/msa_helper.c
index d5bf4dc..d5c3842 100644
--- a/target/mips/msa_helper.c
+++ b/target/mips/msa_helper.c
@@ -1323,28 +1323,61 @@ void helper_msa_copy_u_w(CPUMIPSState *env, uint32_t rd,
     env->active_tc.gpr[rd] = (uint32_t)env->active_fpu.fpr[ws].wr.w[n];
 }
 
-void helper_msa_insert_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
+void helper_msa_insert_b(CPUMIPSState *env, uint32_t wd,
                           uint32_t rs_num, uint32_t n)
 {
     wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
     target_ulong rs = env->active_tc.gpr[rs_num];
+    n %= 16;
+#if defined(HOST_WORDS_BIGENDIAN)
+    if (n < 8) {
+        n = 8 - n - 1;
+    } else {
+        n = 24 - n - 1;
+    }
+#endif
+    pwd->b[n] = (int8_t)rs;
+}
 
-    switch (df) {
-    case DF_BYTE:
-        pwd->b[n] = (int8_t)rs;
-        break;
-    case DF_HALF:
-        pwd->h[n] = (int16_t)rs;
-        break;
-    case DF_WORD:
-        pwd->w[n] = (int32_t)rs;
-        break;
-    case DF_DOUBLE:
-        pwd->d[n] = (int64_t)rs;
-        break;
-    default:
-        assert(0);
+void helper_msa_insert_h(CPUMIPSState *env, uint32_t wd,
+                          uint32_t rs_num, uint32_t n)
+{
+    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
+    target_ulong rs = env->active_tc.gpr[rs_num];
+    n %= 8;
+#if defined(HOST_WORDS_BIGENDIAN)
+    if (n < 4) {
+        n = 4 - n - 1;
+    } else {
+        n = 12 - n - 1;
+    }
+#endif
+    pwd->h[n] = (int16_t)rs;
+}
+
+void helper_msa_insert_w(CPUMIPSState *env, uint32_t wd,
+                          uint32_t rs_num, uint32_t n)
+{
+    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
+    target_ulong rs = env->active_tc.gpr[rs_num];
+    n %= 4;
+#if defined(HOST_WORDS_BIGENDIAN)
+    if (n < 2) {
+        n = 2 - n - 1;
+    } else {
+        n = 6 - n - 1;
     }
+#endif
+    pwd->w[n] = (int32_t)rs;
+}
+
+void helper_msa_insert_d(CPUMIPSState *env, uint32_t wd,
+                          uint32_t rs_num, uint32_t n)
+{
+    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
+    target_ulong rs = env->active_tc.gpr[rs_num];
+    n %= 2;
+    pwd->d[n] = (int64_t)rs;
 }
 
 void helper_msa_insve_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
diff --git a/target/mips/translate.c b/target/mips/translate.c
index 72ed0a8..64587c4 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -29446,7 +29446,24 @@ static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
             }
             break;
         case OPC_INSERT_df:
-            gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
+            switch (df) {
+            case DF_BYTE:
+                gen_helper_msa_insert_b(cpu_env, twd, tws, tn);
+                break;
+            case DF_HALF:
+                gen_helper_msa_insert_h(cpu_env, twd, tws, tn);
+                break;
+            case DF_WORD:
+                gen_helper_msa_insert_w(cpu_env, twd, tws, tn);
+                break;
+#if defined(TARGET_MIPS64)
+            case DF_DOUBLE:
+                gen_helper_msa_insert_d(cpu_env, twd, tws, tn);
+                break;
+#endif
+            default:
+                assert(0);
+            }
             break;
         }
         break;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH v4 1/5] target/mips: Fix MSA instructions LD.<B|H|W|D> on big endian host
  2019-04-02 13:43 ` [Qemu-devel] [PATCH v4 1/5] target/mips: Fix MSA instructions LD.<B|H|W|D> on " Mateja Marjanovic
@ 2019-04-02 20:38   ` Aleksandar Markovic
  0 siblings, 0 replies; 17+ messages in thread
From: Aleksandar Markovic @ 2019-04-02 20:38 UTC (permalink / raw)
  To: Mateja Marjanovic, qemu-devel; +Cc: aurelien, Aleksandar Rikalo

> From: Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
> Subject: [PATCH v4 1/5] target/mips: Fix MSA instructions LD.<B|H|W|D> on big endian host
>
> From: Mateja Marjanovic <Mateja.Marjanovic@rt-rk.com>
>
> Fix the case when the host is a big endian machine, and change
> the approach toward LD.<B|H|W|D> instruction helpers.
>
> Signed-off-by: Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
> ---

Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH v4 2/5] target/mips: Fix MSA instructions ST.<B|H|W|D> on big endian host
  2019-04-02 13:43 ` [Qemu-devel] [PATCH v4 2/5] target/mips: Fix MSA instructions ST.<B|H|W|D> " Mateja Marjanovic
@ 2019-04-02 20:39   ` Aleksandar Markovic
  2019-05-20 12:59   ` Aleksandar Markovic
  1 sibling, 0 replies; 17+ messages in thread
From: Aleksandar Markovic @ 2019-04-02 20:39 UTC (permalink / raw)
  To: Mateja Marjanovic, qemu-devel; +Cc: aurelien, Aleksandar Rikalo

> From: Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
> Subject: [PATCH v4 2/5] target/mips: Fix MSA instructions ST.<B|H|W|D> on big endian host
>
> From: Mateja Marjanovic <Mateja.Marjanovic@rt-rk.com>
>
> Fix the case when the host is a big endian machine, and change
> the approach toward ST.<B|H|W|D> instruction helpers.
>
> Signed-off-by: Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
> ---

Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH v4 5/5] target/mips: Refactor and fix INSERT.<B|H|W|D> instructions
  2019-04-02 13:43 ` [Qemu-devel] [PATCH v4 5/5] target/mips: Refactor and fix INSERT.<B|H|W|D> instructions Mateja Marjanovic
@ 2019-04-02 20:50   ` Aleksandar Markovic
  2019-04-03  8:37     ` Mateja Marjanovic
  2019-05-19  5:25   ` Aleksandar Markovic
  1 sibling, 1 reply; 17+ messages in thread
From: Aleksandar Markovic @ 2019-04-02 20:50 UTC (permalink / raw)
  To: Mateja Marjanovic, qemu-devel; +Cc: aurelien, Aleksandar Rikalo

> From: Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
> Subject: [PATCH v4 5/5] target/mips: Refactor and fix INSERT.<B|H|W|D> instructions
> 
> From: Mateja Marjanovic <Mateja.Marjanovic@rt-rk.com>
> 
> The old version of the helper for the INSERT.<B|H|W|D> MSA instructions
> has been replaced with four helpers that don't use switch, and change
> the endianness of the given index, when executed on a big endian host.
> 
> Signed-off-by: Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
> ---

...


> +    n %= 16;

Mateja, could you just clarify what is the purpose of this line (and
similar three lines involving "%=")? It looks to me that n is already
limited here to be between 0 and 15, isn't it? (that follows from the
source code of gen_msa_elm().) What made you insert this line,
as it stands?

Thanks,
Aleksandar

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH v4 5/5] target/mips: Refactor and fix INSERT.<B|H|W|D> instructions
  2019-04-02 20:50   ` Aleksandar Markovic
@ 2019-04-03  8:37     ` Mateja Marjanovic
  2019-04-03 12:12       ` Aleksandar Markovic
  0 siblings, 1 reply; 17+ messages in thread
From: Mateja Marjanovic @ 2019-04-03  8:37 UTC (permalink / raw)
  To: Aleksandar Markovic, qemu-devel; +Cc: aurelien, Aleksandar Rikalo


On 2.4.19. 22:50, Aleksandar Markovic wrote:
>> From: Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
>> Subject: [PATCH v4 5/5] target/mips: Refactor and fix INSERT.<B|H|W|D> instructions
>>
>> From: Mateja Marjanovic <Mateja.Marjanovic@rt-rk.com>
>>
>> The old version of the helper for the INSERT.<B|H|W|D> MSA instructions
>> has been replaced with four helpers that don't use switch, and change
>> the endianness of the given index, when executed on a big endian host.
>>
>> Signed-off-by: Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
>> ---
> ...
>
>
>> +    n %= 16;
> Mateja, could you just clarify what is the purpose of this line (and
> similar three lines involving "%=")? It looks to me that n is already
> limited here to be between 0 and 15, isn't it? (that follows from the
> source code of gen_msa_elm().) What made you insert this line,
> as it stands?

It was

n %= DF_ELEMENTS(df);

but when I deleted the df argument, so it had to be done like
this. I think it's a matter of precaution (in case a number
greater than 15, or 8... is passed as an argument).

> Thanks,
> Aleksandar

Thanks,
Mateja

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH v4 5/5] target/mips: Refactor and fix INSERT.<B|H|W|D> instructions
  2019-04-03  8:37     ` Mateja Marjanovic
@ 2019-04-03 12:12       ` Aleksandar Markovic
  0 siblings, 0 replies; 17+ messages in thread
From: Aleksandar Markovic @ 2019-04-03 12:12 UTC (permalink / raw)
  To: Mateja Marjanovic, qemu-devel; +Cc: aurelien, Aleksandar Rikalo

> From: Mateja Marjanovic <Mateja.Marjanovic@rt-rk.com>
> Subject: Re: [PATCH v4 5/5] target/mips: Refactor and fix INSERT.<B|H|W|D> instructions
> 
> On 2.4.19. 22:50, Aleksandar Markovic wrote:
> >> From: Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
> >> Subject: [PATCH v4 5/5] target/mips: Refactor and fix INSERT.<B|H|W|D> instructions
> >>
> >> From: Mateja Marjanovic <Mateja.Marjanovic@rt-rk.com>
> >>
> >> The old version of the helper for the INSERT.<B|H|W|D> MSA instructions
> >> has been replaced with four helpers that don't use switch, and change
> >> the endianness of the given index, when executed on a big endian host.
> >>
> >> Signed-off-by: Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
> >> ---
> > ...
> >
> >
> >> +    n %= 16;
> > Mateja, could you just clarify what is the purpose of this line (and
> > similar three lines involving "%=")? It looks to me that n is already
> > limited here to be between 0 and 15, isn't it? (that follows from the
> > source code of gen_msa_elm().) What made you insert this line,
> > as it stands?
> 
> It was
> 
> n %= DF_ELEMENTS(df);
> 
> but when I deleted the df argument, so it had to be done like
> this. I think it's a matter of precaution (in case a number
> greater than 15, or 8... is passed as an argument).

Oh, I see.
 
At this moment, I think a more appropriate code would be:

assert(n < 16)

The whole set of functions decoding this group of instructions is
too complicated (several layers, repeated calculations), and could
be further simplified. But let's say that would be outside of the
scope of this patch and series. Your series, in fact, begins that
simplification by removing redundant decoding of "df" in helpers,
so it is a good step towards better code organization, and we'll
leave more detailed cleanup for some future endeavors.

Yours,
Aleksandar

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH v4 3/5] target/mips: Refactor and fix COPY_S.<B|H|W|D> instructions
  2019-04-02 13:43 ` [Qemu-devel] [PATCH v4 3/5] target/mips: Refactor and fix COPY_S.<B|H|W|D> instructions Mateja Marjanovic
@ 2019-05-18 15:47   ` Aleksandar Markovic
  0 siblings, 0 replies; 17+ messages in thread
From: Aleksandar Markovic @ 2019-05-18 15:47 UTC (permalink / raw)
  To: Mateja Marjanovic; +Cc: arikalo, amarkovic, aurelien, qemu-devel

On Apr 2, 2019 3:44 PM, "Mateja Marjanovic" <mateja.marjanovic@rt-rk.com>
wrote:
>
> From: Mateja Marjanovic <Mateja.Marjanovic@rt-rk.com>
>
> The old version of the helper for the COPY_S.<B|H|W|D> MSA instructions
> has been replaced with four helpers that don't use switch, and change
> the endianness of the given index, when executed on a big endian host.
>
> Signed-off-by: Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
> ---

Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>

>  target/mips/helper.h     |  7 +++++-
>  target/mips/msa_helper.c | 62
+++++++++++++++++++++++++++++++++---------------
>  target/mips/translate.c  | 19 ++++++++++++++-
>  3 files changed, 67 insertions(+), 21 deletions(-)
>
> diff --git a/target/mips/helper.h b/target/mips/helper.h
> index 2f23b0d..4e49618 100644
> --- a/target/mips/helper.h
> +++ b/target/mips/helper.h
> @@ -874,7 +874,7 @@ DEF_HELPER_5(msa_hsub_u_df, void, env, i32, i32, i32,
i32)
>
>  DEF_HELPER_5(msa_sldi_df, void, env, i32, i32, i32, i32)
>  DEF_HELPER_5(msa_splati_df, void, env, i32, i32, i32, i32)
> -DEF_HELPER_5(msa_copy_s_df, void, env, i32, i32, i32, i32)
> +
>  DEF_HELPER_5(msa_copy_u_df, void, env, i32, i32, i32, i32)
>  DEF_HELPER_5(msa_insert_df, void, env, i32, i32, i32, i32)
>  DEF_HELPER_5(msa_insve_df, void, env, i32, i32, i32, i32)
> @@ -936,6 +936,11 @@ DEF_HELPER_4(msa_pcnt_df, void, env, i32, i32, i32)
>  DEF_HELPER_4(msa_nloc_df, void, env, i32, i32, i32)
>  DEF_HELPER_4(msa_nlzc_df, void, env, i32, i32, i32)
>
> +DEF_HELPER_4(msa_copy_s_b, void, env, i32, i32, i32)
> +DEF_HELPER_4(msa_copy_s_h, void, env, i32, i32, i32)
> +DEF_HELPER_4(msa_copy_s_w, void, env, i32, i32, i32)
> +DEF_HELPER_4(msa_copy_s_d, void, env, i32, i32, i32)
> +
>  DEF_HELPER_4(msa_fclass_df, void, env, i32, i32, i32)
>  DEF_HELPER_4(msa_ftrunc_s_df, void, env, i32, i32, i32)
>  DEF_HELPER_4(msa_ftrunc_u_df, void, env, i32, i32, i32)
> diff --git a/target/mips/msa_helper.c b/target/mips/msa_helper.c
> index a500c59..5a06579 100644
> --- a/target/mips/msa_helper.c
> +++ b/target/mips/msa_helper.c
> @@ -1232,29 +1232,53 @@ void helper_msa_splati_df(CPUMIPSState *env,
uint32_t df, uint32_t wd,
>      msa_splat_df(df, pwd, pws, n);
>  }
>
> -void helper_msa_copy_s_df(CPUMIPSState *env, uint32_t df, uint32_t rd,
> -                          uint32_t ws, uint32_t n)
> +void helper_msa_copy_s_b(CPUMIPSState *env, uint32_t rd,
> +                         uint32_t ws, uint32_t n)
>  {
> -    n %= DF_ELEMENTS(df);
> +    n %= 16;
> +#if defined(HOST_WORDS_BIGENDIAN)
> +    if (n < 8) {
> +        n = 8 - n - 1;
> +    } else {
> +        n = 24 - n - 1;
> +    }
> +#endif
> +    env->active_tc.gpr[rd] = (int8_t)env->active_fpu.fpr[ws].wr.b[n];
> +}
>
> -    switch (df) {
> -    case DF_BYTE:
> -        env->active_tc.gpr[rd] = (int8_t)env->active_fpu.fpr[ws].wr.b[n];
> -        break;
> -    case DF_HALF:
> -        env->active_tc.gpr[rd] =
(int16_t)env->active_fpu.fpr[ws].wr.h[n];
> -        break;
> -    case DF_WORD:
> -        env->active_tc.gpr[rd] =
(int32_t)env->active_fpu.fpr[ws].wr.w[n];
> -        break;
> -#ifdef TARGET_MIPS64
> -    case DF_DOUBLE:
> -        env->active_tc.gpr[rd] =
(int64_t)env->active_fpu.fpr[ws].wr.d[n];
> -        break;
> +void helper_msa_copy_s_h(CPUMIPSState *env, uint32_t rd,
> +                         uint32_t ws, uint32_t n)
> +{
> +    n %= 8;
> +#if defined(HOST_WORDS_BIGENDIAN)
> +    if (n < 4) {
> +        n = 4 - n - 1;
> +    } else {
> +        n = 12 - n - 1;
> +    }
>  #endif
> -    default:
> -        assert(0);
> +    env->active_tc.gpr[rd] = (int16_t)env->active_fpu.fpr[ws].wr.h[n];
> +}
> +
> +void helper_msa_copy_s_w(CPUMIPSState *env, uint32_t rd,
> +                         uint32_t ws, uint32_t n)
> +{
> +    n %= 4;
> +#if defined(HOST_WORDS_BIGENDIAN)
> +    if (n < 2) {
> +        n = 2 - n - 1;
> +    } else {
> +        n = 6 - n - 1;
>      }
> +#endif
> +    env->active_tc.gpr[rd] = (int32_t)env->active_fpu.fpr[ws].wr.w[n];
> +}
> +
> +void helper_msa_copy_s_d(CPUMIPSState *env, uint32_t rd,
> +                         uint32_t ws, uint32_t n)
> +{
> +    n %= 2;
> +    env->active_tc.gpr[rd] = (int64_t)env->active_fpu.fpr[ws].wr.d[n];
>  }
>
>  void helper_msa_copy_u_df(CPUMIPSState *env, uint32_t df, uint32_t rd,
> diff --git a/target/mips/translate.c b/target/mips/translate.c
> index 189bbc4..f2ea378 100644
> --- a/target/mips/translate.c
> +++ b/target/mips/translate.c
> @@ -29401,7 +29401,24 @@ static void gen_msa_elm_df(CPUMIPSState *env,
DisasContext *ctx, uint32_t df,
>          switch (MASK_MSA_ELM(ctx->opcode)) {
>          case OPC_COPY_S_df:
>              if (likely(wd != 0)) {
> -                gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
> +                switch (df) {
> +                case DF_BYTE:
> +                    gen_helper_msa_copy_s_b(cpu_env, twd, tws, tn);
> +                    break;
> +                case DF_HALF:
> +                    gen_helper_msa_copy_s_h(cpu_env, twd, tws, tn);
> +                    break;
> +                case DF_WORD:
> +                    gen_helper_msa_copy_s_w(cpu_env, twd, tws, tn);
> +                    break;
> +#if defined(TARGET_MIPS64)
> +                case DF_DOUBLE:
> +                    gen_helper_msa_copy_s_d(cpu_env, twd, tws, tn);
> +                    break;
> +#endif
> +                default:
> +                    assert(0);
> +                }
>              }
>              break;
>          case OPC_COPY_U_df:
> --
> 2.7.4
>
>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH v4 4/5] target/mips: Refactor and fix COPY_U.<B|H|W> instructions
  2019-04-02 13:43 ` [Qemu-devel] [PATCH v4 4/5] target/mips: Refactor and fix COPY_U.<B|H|W> instructions Mateja Marjanovic
@ 2019-05-18 15:47   ` Aleksandar Markovic
  0 siblings, 0 replies; 17+ messages in thread
From: Aleksandar Markovic @ 2019-05-18 15:47 UTC (permalink / raw)
  To: Mateja Marjanovic; +Cc: arikalo, amarkovic, aurelien, qemu-devel

On Apr 2, 2019 3:44 PM, "Mateja Marjanovic" <mateja.marjanovic@rt-rk.com>
wrote:
>
> From: Mateja Marjanovic <Mateja.Marjanovic@rt-rk.com>
>
> The old version of the helper for the COPY_U.<B|H|W> MSA instructions
> has been replaced with four helpers that don't use switch, and change
> the endianness of the given index, when executed on a big endian host.
>
> Signed-off-by: Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
> ---

Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>

>  target/mips/helper.h     |  4 +++-
>  target/mips/msa_helper.c | 55
+++++++++++++++++++++++++++++++-----------------
>  target/mips/translate.c  | 21 +++++++++++++++++-
>  3 files changed, 59 insertions(+), 21 deletions(-)
>
> diff --git a/target/mips/helper.h b/target/mips/helper.h
> index 4e49618..8b6703c 100644
> --- a/target/mips/helper.h
> +++ b/target/mips/helper.h
> @@ -875,7 +875,6 @@ DEF_HELPER_5(msa_hsub_u_df, void, env, i32, i32, i32,
i32)
>  DEF_HELPER_5(msa_sldi_df, void, env, i32, i32, i32, i32)
>  DEF_HELPER_5(msa_splati_df, void, env, i32, i32, i32, i32)
>
> -DEF_HELPER_5(msa_copy_u_df, void, env, i32, i32, i32, i32)
>  DEF_HELPER_5(msa_insert_df, void, env, i32, i32, i32, i32)
>  DEF_HELPER_5(msa_insve_df, void, env, i32, i32, i32, i32)
>  DEF_HELPER_3(msa_ctcmsa, void, env, tl, i32)
> @@ -940,6 +939,9 @@ DEF_HELPER_4(msa_copy_s_b, void, env, i32, i32, i32)
>  DEF_HELPER_4(msa_copy_s_h, void, env, i32, i32, i32)
>  DEF_HELPER_4(msa_copy_s_w, void, env, i32, i32, i32)
>  DEF_HELPER_4(msa_copy_s_d, void, env, i32, i32, i32)
> +DEF_HELPER_4(msa_copy_u_b, void, env, i32, i32, i32)
> +DEF_HELPER_4(msa_copy_u_h, void, env, i32, i32, i32)
> +DEF_HELPER_4(msa_copy_u_w, void, env, i32, i32, i32)
>
>  DEF_HELPER_4(msa_fclass_df, void, env, i32, i32, i32)
>  DEF_HELPER_4(msa_ftrunc_s_df, void, env, i32, i32, i32)
> diff --git a/target/mips/msa_helper.c b/target/mips/msa_helper.c
> index 5a06579..d5bf4dc 100644
> --- a/target/mips/msa_helper.c
> +++ b/target/mips/msa_helper.c
> @@ -1281,29 +1281,46 @@ void helper_msa_copy_s_d(CPUMIPSState *env,
uint32_t rd,
>      env->active_tc.gpr[rd] = (int64_t)env->active_fpu.fpr[ws].wr.d[n];
>  }
>
> -void helper_msa_copy_u_df(CPUMIPSState *env, uint32_t df, uint32_t rd,
> -                          uint32_t ws, uint32_t n)
> +void helper_msa_copy_u_b(CPUMIPSState *env, uint32_t rd,
> +                         uint32_t ws, uint32_t n)
>  {
> -    n %= DF_ELEMENTS(df);
> +    n %= 16;
> +#if defined(HOST_WORDS_BIGENDIAN)
> +    if (n < 8) {
> +        n = 8 - n - 1;
> +    } else {
> +        n = 24 - n - 1;
> +    }
> +#endif
> +    env->active_tc.gpr[rd] = (uint8_t)env->active_fpu.fpr[ws].wr.b[n];
> +}
>
> -    switch (df) {
> -    case DF_BYTE:
> -        env->active_tc.gpr[rd] =
(uint8_t)env->active_fpu.fpr[ws].wr.b[n];
> -        break;
> -    case DF_HALF:
> -        env->active_tc.gpr[rd] =
(uint16_t)env->active_fpu.fpr[ws].wr.h[n];
> -        break;
> -    case DF_WORD:
> -        env->active_tc.gpr[rd] =
(uint32_t)env->active_fpu.fpr[ws].wr.w[n];
> -        break;
> -#ifdef TARGET_MIPS64
> -    case DF_DOUBLE:
> -        env->active_tc.gpr[rd] =
(uint64_t)env->active_fpu.fpr[ws].wr.d[n];
> -        break;
> +void helper_msa_copy_u_h(CPUMIPSState *env, uint32_t rd,
> +                         uint32_t ws, uint32_t n)
> +{
> +    n %= 8;
> +#if defined(HOST_WORDS_BIGENDIAN)
> +    if (n < 4) {
> +        n = 4 - n - 1;
> +    } else {
> +        n = 12 - n - 1;
> +    }
>  #endif
> -    default:
> -        assert(0);
> +    env->active_tc.gpr[rd] = (uint16_t)env->active_fpu.fpr[ws].wr.h[n];
> +}
> +
> +void helper_msa_copy_u_w(CPUMIPSState *env, uint32_t rd,
> +                         uint32_t ws, uint32_t n)
> +{
> +    n %= 4;
> +#if defined(HOST_WORDS_BIGENDIAN)
> +    if (n < 2) {
> +        n = 2 - n - 1;
> +    } else {
> +        n = 6 - n - 1;
>      }
> +#endif
> +    env->active_tc.gpr[rd] = (uint32_t)env->active_fpu.fpr[ws].wr.w[n];
>  }
>
>  void helper_msa_insert_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
> diff --git a/target/mips/translate.c b/target/mips/translate.c
> index f2ea378..72ed0a8 100644
> --- a/target/mips/translate.c
> +++ b/target/mips/translate.c
> @@ -29397,6 +29397,11 @@ static void gen_msa_elm_df(CPUMIPSState *env,
DisasContext *ctx, uint32_t df,
>              generate_exception_end(ctx, EXCP_RI);
>              break;
>          }
> +        if ((MASK_MSA_ELM(ctx->opcode) == OPC_COPY_U_df) &&
> +              (df == DF_WORD)) {
> +            generate_exception_end(ctx, EXCP_RI);
> +            break;
> +        }
>  #endif
>          switch (MASK_MSA_ELM(ctx->opcode)) {
>          case OPC_COPY_S_df:
> @@ -29423,7 +29428,21 @@ static void gen_msa_elm_df(CPUMIPSState *env,
DisasContext *ctx, uint32_t df,
>              break;
>          case OPC_COPY_U_df:
>              if (likely(wd != 0)) {
> -                gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
> +                switch (df) {
> +                case DF_BYTE:
> +                    gen_helper_msa_copy_u_b(cpu_env, twd, tws, tn);
> +                    break;
> +                case DF_HALF:
> +                    gen_helper_msa_copy_u_h(cpu_env, twd, tws, tn);
> +                    break;
> +#if defined(TARGET_MIPS64)
> +                case DF_WORD:
> +                    gen_helper_msa_copy_u_w(cpu_env, twd, tws, tn);
> +                    break;
> +#endif
> +                default:
> +                    assert(0);
> +                }
>              }
>              break;
>          case OPC_INSERT_df:
> --
> 2.7.4
>
>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH v4 5/5] target/mips: Refactor and fix INSERT.<B|H|W|D> instructions
  2019-04-02 13:43 ` [Qemu-devel] [PATCH v4 5/5] target/mips: Refactor and fix INSERT.<B|H|W|D> instructions Mateja Marjanovic
  2019-04-02 20:50   ` Aleksandar Markovic
@ 2019-05-19  5:25   ` Aleksandar Markovic
  2019-05-20 10:24     ` Mateja Marjanovic
  1 sibling, 1 reply; 17+ messages in thread
From: Aleksandar Markovic @ 2019-05-19  5:25 UTC (permalink / raw)
  To: Mateja Marjanovic; +Cc: arikalo, amarkovic, aurelien, qemu-devel

On Apr 2, 2019 3:49 PM, "Mateja Marjanovic" <mateja.marjanovic@rt-rk.com>
wrote:
>
> From: Mateja Marjanovic <Mateja.Marjanovic@rt-rk.com>
>
> The old version of the helper for the INSERT.<B|H|W|D> MSA instructions
> has been replaced with four helpers that don't use switch, and change
> the endianness of the given index, when executed on a big endian host.
>
> Signed-off-by: Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
> ---

Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>

I'll do minor corrections (resulting from this mail thread discussion)
while applying to my pull request.

>  target/mips/helper.h     |  5 +++-
>  target/mips/msa_helper.c | 65
++++++++++++++++++++++++++++++++++++------------
>  target/mips/translate.c  | 19 +++++++++++++-
>  3 files changed, 71 insertions(+), 18 deletions(-)
>
> diff --git a/target/mips/helper.h b/target/mips/helper.h
> index 8b6703c..82f6a40 100644
> --- a/target/mips/helper.h
> +++ b/target/mips/helper.h
> @@ -875,7 +875,6 @@ DEF_HELPER_5(msa_hsub_u_df, void, env, i32, i32, i32,
i32)
>  DEF_HELPER_5(msa_sldi_df, void, env, i32, i32, i32, i32)
>  DEF_HELPER_5(msa_splati_df, void, env, i32, i32, i32, i32)
>
> -DEF_HELPER_5(msa_insert_df, void, env, i32, i32, i32, i32)
>  DEF_HELPER_5(msa_insve_df, void, env, i32, i32, i32, i32)
>  DEF_HELPER_3(msa_ctcmsa, void, env, tl, i32)
>  DEF_HELPER_2(msa_cfcmsa, tl, env, i32)
> @@ -942,6 +941,10 @@ DEF_HELPER_4(msa_copy_s_d, void, env, i32, i32, i32)
>  DEF_HELPER_4(msa_copy_u_b, void, env, i32, i32, i32)
>  DEF_HELPER_4(msa_copy_u_h, void, env, i32, i32, i32)
>  DEF_HELPER_4(msa_copy_u_w, void, env, i32, i32, i32)
> +DEF_HELPER_4(msa_insert_b, void, env, i32, i32, i32)
> +DEF_HELPER_4(msa_insert_h, void, env, i32, i32, i32)
> +DEF_HELPER_4(msa_insert_w, void, env, i32, i32, i32)
> +DEF_HELPER_4(msa_insert_d, void, env, i32, i32, i32)
>
>  DEF_HELPER_4(msa_fclass_df, void, env, i32, i32, i32)
>  DEF_HELPER_4(msa_ftrunc_s_df, void, env, i32, i32, i32)
> diff --git a/target/mips/msa_helper.c b/target/mips/msa_helper.c
> index d5bf4dc..d5c3842 100644
> --- a/target/mips/msa_helper.c
> +++ b/target/mips/msa_helper.c
> @@ -1323,28 +1323,61 @@ void helper_msa_copy_u_w(CPUMIPSState *env,
uint32_t rd,
>      env->active_tc.gpr[rd] = (uint32_t)env->active_fpu.fpr[ws].wr.w[n];
>  }
>
> -void helper_msa_insert_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
> +void helper_msa_insert_b(CPUMIPSState *env, uint32_t wd,
>                            uint32_t rs_num, uint32_t n)
>  {
>      wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
>      target_ulong rs = env->active_tc.gpr[rs_num];
> +    n %= 16;
> +#if defined(HOST_WORDS_BIGENDIAN)
> +    if (n < 8) {
> +        n = 8 - n - 1;
> +    } else {
> +        n = 24 - n - 1;
> +    }
> +#endif
> +    pwd->b[n] = (int8_t)rs;
> +}
>
> -    switch (df) {
> -    case DF_BYTE:
> -        pwd->b[n] = (int8_t)rs;
> -        break;
> -    case DF_HALF:
> -        pwd->h[n] = (int16_t)rs;
> -        break;
> -    case DF_WORD:
> -        pwd->w[n] = (int32_t)rs;
> -        break;
> -    case DF_DOUBLE:
> -        pwd->d[n] = (int64_t)rs;
> -        break;
> -    default:
> -        assert(0);
> +void helper_msa_insert_h(CPUMIPSState *env, uint32_t wd,
> +                          uint32_t rs_num, uint32_t n)
> +{
> +    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
> +    target_ulong rs = env->active_tc.gpr[rs_num];
> +    n %= 8;
> +#if defined(HOST_WORDS_BIGENDIAN)
> +    if (n < 4) {
> +        n = 4 - n - 1;
> +    } else {
> +        n = 12 - n - 1;
> +    }
> +#endif
> +    pwd->h[n] = (int16_t)rs;
> +}
> +
> +void helper_msa_insert_w(CPUMIPSState *env, uint32_t wd,
> +                          uint32_t rs_num, uint32_t n)
> +{
> +    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
> +    target_ulong rs = env->active_tc.gpr[rs_num];
> +    n %= 4;
> +#if defined(HOST_WORDS_BIGENDIAN)
> +    if (n < 2) {
> +        n = 2 - n - 1;
> +    } else {
> +        n = 6 - n - 1;
>      }
> +#endif
> +    pwd->w[n] = (int32_t)rs;
> +}
> +
> +void helper_msa_insert_d(CPUMIPSState *env, uint32_t wd,
> +                          uint32_t rs_num, uint32_t n)
> +{
> +    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
> +    target_ulong rs = env->active_tc.gpr[rs_num];
> +    n %= 2;
> +    pwd->d[n] = (int64_t)rs;
>  }
>
>  void helper_msa_insve_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
> diff --git a/target/mips/translate.c b/target/mips/translate.c
> index 72ed0a8..64587c4 100644
> --- a/target/mips/translate.c
> +++ b/target/mips/translate.c
> @@ -29446,7 +29446,24 @@ static void gen_msa_elm_df(CPUMIPSState *env,
DisasContext *ctx, uint32_t df,
>              }
>              break;
>          case OPC_INSERT_df:
> -            gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
> +            switch (df) {
> +            case DF_BYTE:
> +                gen_helper_msa_insert_b(cpu_env, twd, tws, tn);
> +                break;
> +            case DF_HALF:
> +                gen_helper_msa_insert_h(cpu_env, twd, tws, tn);
> +                break;
> +            case DF_WORD:
> +                gen_helper_msa_insert_w(cpu_env, twd, tws, tn);
> +                break;
> +#if defined(TARGET_MIPS64)
> +            case DF_DOUBLE:
> +                gen_helper_msa_insert_d(cpu_env, twd, tws, tn);
> +                break;
> +#endif
> +            default:
> +                assert(0);
> +            }
>              break;
>          }
>          break;
> --
> 2.7.4
>
>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH v4 5/5] target/mips: Refactor and fix INSERT.<B|H|W|D> instructions
  2019-05-19  5:25   ` Aleksandar Markovic
@ 2019-05-20 10:24     ` Mateja Marjanovic
  0 siblings, 0 replies; 17+ messages in thread
From: Mateja Marjanovic @ 2019-05-20 10:24 UTC (permalink / raw)
  To: Aleksandar Markovic; +Cc: arikalo, amarkovic, aurelien, qemu-devel


On 19.5.19. 07:25, Aleksandar Markovic wrote:
>
>
> On Apr 2, 2019 3:49 PM, "Mateja Marjanovic" 
> <mateja.marjanovic@rt-rk.com <mailto:mateja.marjanovic@rt-rk.com>> wrote:
> >
> > From: Mateja Marjanovic <Mateja.Marjanovic@rt-rk.com 
> <mailto:Mateja.Marjanovic@rt-rk.com>>
> >
> > The old version of the helper for the INSERT.<B|H|W|D> MSA instructions
> > has been replaced with four helpers that don't use switch, and change
> > the endianness of the given index, when executed on a big endian host.
> >
> > Signed-off-by: Mateja Marjanovic <mateja.marjanovic@rt-rk.com 
> <mailto:mateja.marjanovic@rt-rk.com>>
> > ---
>
> Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com 
> <mailto:amarkovic@wavecomp.com>>
>
> I'll do minor corrections (resulting from this mail thread discussion) 
> while applying to my pull request.
>
Great, thanks.

Regards,
Mateja

> >  target/mips/helper.h     |  5 +++-
> >  target/mips/msa_helper.c | 65 
> ++++++++++++++++++++++++++++++++++++------------
> >  target/mips/translate.c  | 19 +++++++++++++-
> >  3 files changed, 71 insertions(+), 18 deletions(-)
> >
> > diff --git a/target/mips/helper.h b/target/mips/helper.h
> > index 8b6703c..82f6a40 100644
> > --- a/target/mips/helper.h
> > +++ b/target/mips/helper.h
> > @@ -875,7 +875,6 @@ DEF_HELPER_5(msa_hsub_u_df, void, env, i32, i32, 
> i32, i32)
> >  DEF_HELPER_5(msa_sldi_df, void, env, i32, i32, i32, i32)
> >  DEF_HELPER_5(msa_splati_df, void, env, i32, i32, i32, i32)
> >
> > -DEF_HELPER_5(msa_insert_df, void, env, i32, i32, i32, i32)
> >  DEF_HELPER_5(msa_insve_df, void, env, i32, i32, i32, i32)
> >  DEF_HELPER_3(msa_ctcmsa, void, env, tl, i32)
> >  DEF_HELPER_2(msa_cfcmsa, tl, env, i32)
> > @@ -942,6 +941,10 @@ DEF_HELPER_4(msa_copy_s_d, void, env, i32, i32, 
> i32)
> >  DEF_HELPER_4(msa_copy_u_b, void, env, i32, i32, i32)
> >  DEF_HELPER_4(msa_copy_u_h, void, env, i32, i32, i32)
> >  DEF_HELPER_4(msa_copy_u_w, void, env, i32, i32, i32)
> > +DEF_HELPER_4(msa_insert_b, void, env, i32, i32, i32)
> > +DEF_HELPER_4(msa_insert_h, void, env, i32, i32, i32)
> > +DEF_HELPER_4(msa_insert_w, void, env, i32, i32, i32)
> > +DEF_HELPER_4(msa_insert_d, void, env, i32, i32, i32)
> >
> >  DEF_HELPER_4(msa_fclass_df, void, env, i32, i32, i32)
> >  DEF_HELPER_4(msa_ftrunc_s_df, void, env, i32, i32, i32)
> > diff --git a/target/mips/msa_helper.c b/target/mips/msa_helper.c
> > index d5bf4dc..d5c3842 100644
> > --- a/target/mips/msa_helper.c
> > +++ b/target/mips/msa_helper.c
> > @@ -1323,28 +1323,61 @@ void helper_msa_copy_u_w(CPUMIPSState *env, 
> uint32_t rd,
> >      env->active_tc.gpr[rd] = (uint32_t)env->active_fpu.fpr[ws].wr.w[n];
> >  }
> >
> > -void helper_msa_insert_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
> > +void helper_msa_insert_b(CPUMIPSState *env, uint32_t wd,
> >                            uint32_t rs_num, uint32_t n)
> >  {
> >      wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
> >      target_ulong rs = env->active_tc.gpr[rs_num];
> > +    n %= 16;
> > +#if defined(HOST_WORDS_BIGENDIAN)
> > +    if (n < 8) {
> > +        n = 8 - n - 1;
> > +    } else {
> > +        n = 24 - n - 1;
> > +    }
> > +#endif
> > +    pwd->b[n] = (int8_t)rs;
> > +}
> >
> > -    switch (df) {
> > -    case DF_BYTE:
> > -        pwd->b[n] = (int8_t)rs;
> > -        break;
> > -    case DF_HALF:
> > -        pwd->h[n] = (int16_t)rs;
> > -        break;
> > -    case DF_WORD:
> > -        pwd->w[n] = (int32_t)rs;
> > -        break;
> > -    case DF_DOUBLE:
> > -        pwd->d[n] = (int64_t)rs;
> > -        break;
> > -    default:
> > -        assert(0);
> > +void helper_msa_insert_h(CPUMIPSState *env, uint32_t wd,
> > +                          uint32_t rs_num, uint32_t n)
> > +{
> > +    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
> > +    target_ulong rs = env->active_tc.gpr[rs_num];
> > +    n %= 8;
> > +#if defined(HOST_WORDS_BIGENDIAN)
> > +    if (n < 4) {
> > +        n = 4 - n - 1;
> > +    } else {
> > +        n = 12 - n - 1;
> > +    }
> > +#endif
> > +    pwd->h[n] = (int16_t)rs;
> > +}
> > +
> > +void helper_msa_insert_w(CPUMIPSState *env, uint32_t wd,
> > +                          uint32_t rs_num, uint32_t n)
> > +{
> > +    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
> > +    target_ulong rs = env->active_tc.gpr[rs_num];
> > +    n %= 4;
> > +#if defined(HOST_WORDS_BIGENDIAN)
> > +    if (n < 2) {
> > +        n = 2 - n - 1;
> > +    } else {
> > +        n = 6 - n - 1;
> >      }
> > +#endif
> > +    pwd->w[n] = (int32_t)rs;
> > +}
> > +
> > +void helper_msa_insert_d(CPUMIPSState *env, uint32_t wd,
> > +                          uint32_t rs_num, uint32_t n)
> > +{
> > +    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
> > +    target_ulong rs = env->active_tc.gpr[rs_num];
> > +    n %= 2;
> > +    pwd->d[n] = (int64_t)rs;
> >  }
> >
> >  void helper_msa_insve_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
> > diff --git a/target/mips/translate.c b/target/mips/translate.c
> > index 72ed0a8..64587c4 100644
> > --- a/target/mips/translate.c
> > +++ b/target/mips/translate.c
> > @@ -29446,7 +29446,24 @@ static void gen_msa_elm_df(CPUMIPSState 
> *env, DisasContext *ctx, uint32_t df,
> >              }
> >              break;
> >          case OPC_INSERT_df:
> > -            gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
> > +            switch (df) {
> > +            case DF_BYTE:
> > +                gen_helper_msa_insert_b(cpu_env, twd, tws, tn);
> > +                break;
> > +            case DF_HALF:
> > +                gen_helper_msa_insert_h(cpu_env, twd, tws, tn);
> > +                break;
> > +            case DF_WORD:
> > +                gen_helper_msa_insert_w(cpu_env, twd, tws, tn);
> > +                break;
> > +#if defined(TARGET_MIPS64)
> > +            case DF_DOUBLE:
> > +                gen_helper_msa_insert_d(cpu_env, twd, tws, tn);
> > +                break;
> > +#endif
> > +            default:
> > +                assert(0);
> > +            }
> >              break;
> >          }
> >          break;
> > --
> > 2.7.4
> >
> >
>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH v4 2/5] target/mips: Fix MSA instructions ST.<B|H|W|D> on big endian host
  2019-04-02 13:43 ` [Qemu-devel] [PATCH v4 2/5] target/mips: Fix MSA instructions ST.<B|H|W|D> " Mateja Marjanovic
  2019-04-02 20:39   ` Aleksandar Markovic
@ 2019-05-20 12:59   ` Aleksandar Markovic
  2019-05-20 13:07     ` Mateja Marjanovic
  1 sibling, 1 reply; 17+ messages in thread
From: Aleksandar Markovic @ 2019-05-20 12:59 UTC (permalink / raw)
  To: Mateja Marjanovic; +Cc: arikalo, amarkovic, aurelien, qemu-devel

On Apr 2, 2019 3:47 PM, "Mateja Marjanovic" <mateja.marjanovic@rt-rk.com>
wrote:
>
> From: Mateja Marjanovic <Mateja.Marjanovic@rt-rk.com>
>
> Fix the case when the host is a big endian machine, and change
> the approach toward ST.<B|H|W|D> instruction helpers.
>
> Signed-off-by: Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
> ---

Hello, Mateja.

There is unfortunatelly still a slight problem with the new implementation:
it looks like the invocations to ensure_writable_pages() in new helpers are
missing. Or, perhaps, there is a reason you removed them. Please reanalyse
and reexplain. But thanks for previous efforts.

Yours,
Aleksandar

>  target/mips/op_helper.c | 188
++++++++++++++++++++++++++++++++++++++++++------
>  1 file changed, 168 insertions(+), 20 deletions(-)
>
> diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c
> index 45be406..d94909a 100644
> --- a/target/mips/op_helper.c
> +++ b/target/mips/op_helper.c
> @@ -4565,31 +4565,179 @@ static inline void
ensure_writable_pages(CPUMIPSState *env,
>  #endif
>  }
>
> -#define MSA_ST_DF(DF, TYPE, ST_INSN, ...)                               \
> -void helper_msa_st_ ## TYPE(CPUMIPSState *env, uint32_t wd,             \
> -                            target_ulong addr)                          \
> -{                                                                       \
> -    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);                          \
> -    int mmu_idx = cpu_mmu_index(env, false);                           \
> -    int i;                                                              \
> -    MEMOP_IDX(DF)                                                       \
> -    ensure_writable_pages(env, addr, mmu_idx, GETPC());                 \
> -    for (i = 0; i < DF_ELEMENTS(DF); i++) {                             \
> -        ST_INSN(env, addr + (i << DF), pwd->TYPE[i], ##__VA_ARGS__);    \
> -    }                                                                   \
> +void helper_msa_st_b(CPUMIPSState *env, uint32_t wd,
> +                     target_ulong addr)
> +{
> +    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
> +    MEMOP_IDX(DF_BYTE)
> +#if !defined(CONFIG_USER_ONLY)
> +#if !defined(HOST_WORDS_BIGENDIAN)
> +    helper_ret_stb_mmu(env, addr + (0  << DF_BYTE), pwd->b[0],  oi,
GETPC());
> +    helper_ret_stb_mmu(env, addr + (1  << DF_BYTE), pwd->b[1],  oi,
GETPC());
> +    helper_ret_stb_mmu(env, addr + (2  << DF_BYTE), pwd->b[2],  oi,
GETPC());
> +    helper_ret_stb_mmu(env, addr + (3  << DF_BYTE), pwd->b[3],  oi,
GETPC());
> +    helper_ret_stb_mmu(env, addr + (4  << DF_BYTE), pwd->b[4],  oi,
GETPC());
> +    helper_ret_stb_mmu(env, addr + (5  << DF_BYTE), pwd->b[5],  oi,
GETPC());
> +    helper_ret_stb_mmu(env, addr + (6  << DF_BYTE), pwd->b[6],  oi,
GETPC());
> +    helper_ret_stb_mmu(env, addr + (7  << DF_BYTE), pwd->b[7],  oi,
GETPC());
> +    helper_ret_stb_mmu(env, addr + (8  << DF_BYTE), pwd->b[8],  oi,
GETPC());
> +    helper_ret_stb_mmu(env, addr + (9  << DF_BYTE), pwd->b[9],  oi,
GETPC());
> +    helper_ret_stb_mmu(env, addr + (10 << DF_BYTE), pwd->b[10], oi,
GETPC());
> +    helper_ret_stb_mmu(env, addr + (11 << DF_BYTE), pwd->b[11], oi,
GETPC());
> +    helper_ret_stb_mmu(env, addr + (12 << DF_BYTE), pwd->b[12], oi,
GETPC());
> +    helper_ret_stb_mmu(env, addr + (13 << DF_BYTE), pwd->b[13], oi,
GETPC());
> +    helper_ret_stb_mmu(env, addr + (14 << DF_BYTE), pwd->b[14], oi,
GETPC());
> +    helper_ret_stb_mmu(env, addr + (15 << DF_BYTE), pwd->b[15], oi,
GETPC());
> +#else
> +    helper_ret_stb_mmu(env, addr + (7  << DF_BYTE), pwd->b[0],  oi,
GETPC());
> +    helper_ret_stb_mmu(env, addr + (6  << DF_BYTE), pwd->b[1],  oi,
GETPC());
> +    helper_ret_stb_mmu(env, addr + (5  << DF_BYTE), pwd->b[2],  oi,
GETPC());
> +    helper_ret_stb_mmu(env, addr + (4  << DF_BYTE), pwd->b[3],  oi,
GETPC());
> +    helper_ret_stb_mmu(env, addr + (3  << DF_BYTE), pwd->b[4],  oi,
GETPC());
> +    helper_ret_stb_mmu(env, addr + (2  << DF_BYTE), pwd->b[5],  oi,
GETPC());
> +    helper_ret_stb_mmu(env, addr + (1  << DF_BYTE), pwd->b[6],  oi,
GETPC());
> +    helper_ret_stb_mmu(env, addr + (0  << DF_BYTE), pwd->b[7],  oi,
GETPC());
> +    helper_ret_stb_mmu(env, addr + (15 << DF_BYTE), pwd->b[8],  oi,
GETPC());
> +    helper_ret_stb_mmu(env, addr + (14 << DF_BYTE), pwd->b[9],  oi,
GETPC());
> +    helper_ret_stb_mmu(env, addr + (13 << DF_BYTE), pwd->b[10], oi,
GETPC());
> +    helper_ret_stb_mmu(env, addr + (12 << DF_BYTE), pwd->b[11], oi,
GETPC());
> +    helper_ret_stb_mmu(env, addr + (11 << DF_BYTE), pwd->b[12], oi,
GETPC());
> +    helper_ret_stb_mmu(env, addr + (10 << DF_BYTE), pwd->b[13], oi,
GETPC());
> +    helper_ret_stb_mmu(env, addr + (9  << DF_BYTE), pwd->b[14], oi,
GETPC());
> +    helper_ret_stb_mmu(env, addr + (8  << DF_BYTE), pwd->b[15], oi,
GETPC());
> +#endif
> +#else
> +#if !defined(HOST_WORDS_BIGENDIAN)
> +    cpu_stb_data(env, addr + (0  << DF_BYTE), pwd->b[0]);
> +    cpu_stb_data(env, addr + (1  << DF_BYTE), pwd->b[1]);
> +    cpu_stb_data(env, addr + (2  << DF_BYTE), pwd->b[2]);
> +    cpu_stb_data(env, addr + (3  << DF_BYTE), pwd->b[3]);
> +    cpu_stb_data(env, addr + (4  << DF_BYTE), pwd->b[4]);
> +    cpu_stb_data(env, addr + (5  << DF_BYTE), pwd->b[5]);
> +    cpu_stb_data(env, addr + (6  << DF_BYTE), pwd->b[6]);
> +    cpu_stb_data(env, addr + (7  << DF_BYTE), pwd->b[7]);
> +    cpu_stb_data(env, addr + (8  << DF_BYTE), pwd->b[8]);
> +    cpu_stb_data(env, addr + (9  << DF_BYTE), pwd->b[9]);
> +    cpu_stb_data(env, addr + (10 << DF_BYTE), pwd->b[10]);
> +    cpu_stb_data(env, addr + (11 << DF_BYTE), pwd->b[11]);
> +    cpu_stb_data(env, addr + (12 << DF_BYTE), pwd->b[12]);
> +    cpu_stb_data(env, addr + (13 << DF_BYTE), pwd->b[13]);
> +    cpu_stb_data(env, addr + (14 << DF_BYTE), pwd->b[14]);
> +    cpu_stb_data(env, addr + (15 << DF_BYTE), pwd->b[15]);
> +#else
> +    cpu_stb_data(env, addr + (7  << DF_BYTE), pwd->b[0]);
> +    cpu_stb_data(env, addr + (6  << DF_BYTE), pwd->b[1]);
> +    cpu_stb_data(env, addr + (5  << DF_BYTE), pwd->b[2]);
> +    cpu_stb_data(env, addr + (4  << DF_BYTE), pwd->b[3]);
> +    cpu_stb_data(env, addr + (3  << DF_BYTE), pwd->b[4]);
> +    cpu_stb_data(env, addr + (2  << DF_BYTE), pwd->b[5]);
> +    cpu_stb_data(env, addr + (1  << DF_BYTE), pwd->b[6]);
> +    cpu_stb_data(env, addr + (0  << DF_BYTE), pwd->b[7]);
> +    cpu_stb_data(env, addr + (15 << DF_BYTE), pwd->b[8]);
> +    cpu_stb_data(env, addr + (14 << DF_BYTE), pwd->b[9]);
> +    cpu_stb_data(env, addr + (13 << DF_BYTE), pwd->b[10]);
> +    cpu_stb_data(env, addr + (12 << DF_BYTE), pwd->b[11]);
> +    cpu_stb_data(env, addr + (11 << DF_BYTE), pwd->b[12]);
> +    cpu_stb_data(env, addr + (10 << DF_BYTE), pwd->b[13]);
> +    cpu_stb_data(env, addr + (9  << DF_BYTE), pwd->b[14]);
> +    cpu_stb_data(env, addr + (8  << DF_BYTE), pwd->b[15]);
> +#endif
> +#endif
> +}
> +
> +void helper_msa_st_h(CPUMIPSState *env, uint32_t wd,
> +                     target_ulong addr)
> +{
> +    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
> +    MEMOP_IDX(DF_HALF)
> +#if !defined(CONFIG_USER_ONLY)
> +#if !defined(HOST_WORDS_BIGENDIAN)
> +    helper_ret_stw_mmu(env, addr + (0 << DF_HALF), pwd->h[0], oi,
GETPC());
> +    helper_ret_stw_mmu(env, addr + (1 << DF_HALF), pwd->h[1], oi,
GETPC());
> +    helper_ret_stw_mmu(env, addr + (2 << DF_HALF), pwd->h[2], oi,
GETPC());
> +    helper_ret_stw_mmu(env, addr + (3 << DF_HALF), pwd->h[3], oi,
GETPC());
> +    helper_ret_stw_mmu(env, addr + (4 << DF_HALF), pwd->h[4], oi,
GETPC());
> +    helper_ret_stw_mmu(env, addr + (5 << DF_HALF), pwd->h[5], oi,
GETPC());
> +    helper_ret_stw_mmu(env, addr + (6 << DF_HALF), pwd->h[6], oi,
GETPC());
> +    helper_ret_stw_mmu(env, addr + (7 << DF_HALF), pwd->h[7], oi,
GETPC());
> +#else
> +    helper_ret_stw_mmu(env, addr + (3 << DF_HALF), pwd->h[0], oi,
GETPC());
> +    helper_ret_stw_mmu(env, addr + (2 << DF_HALF), pwd->h[1], oi,
GETPC());
> +    helper_ret_stw_mmu(env, addr + (1 << DF_HALF), pwd->h[2], oi,
GETPC());
> +    helper_ret_stw_mmu(env, addr + (0 << DF_HALF), pwd->h[3], oi,
GETPC());
> +    helper_ret_stw_mmu(env, addr + (7 << DF_HALF), pwd->h[4], oi,
GETPC());
> +    helper_ret_stw_mmu(env, addr + (6 << DF_HALF), pwd->h[5], oi,
GETPC());
> +    helper_ret_stw_mmu(env, addr + (5 << DF_HALF), pwd->h[6], oi,
GETPC());
> +    helper_ret_stw_mmu(env, addr + (4 << DF_HALF), pwd->h[7], oi,
GETPC());
> +#endif
> +#else
> +#if !defined(HOST_WORDS_BIGENDIAN)
> +    cpu_stw_data(env, addr + (0 << DF_HALF), pwd->h[0]);
> +    cpu_stw_data(env, addr + (1 << DF_HALF), pwd->h[1]);
> +    cpu_stw_data(env, addr + (2 << DF_HALF), pwd->h[2]);
> +    cpu_stw_data(env, addr + (3 << DF_HALF), pwd->h[3]);
> +    cpu_stw_data(env, addr + (4 << DF_HALF), pwd->h[4]);
> +    cpu_stw_data(env, addr + (5 << DF_HALF), pwd->h[5]);
> +    cpu_stw_data(env, addr + (6 << DF_HALF), pwd->h[6]);
> +    cpu_stw_data(env, addr + (7 << DF_HALF), pwd->h[7]);
> +#else
> +    cpu_stw_data(env, addr + (3 << DF_HALF), pwd->h[0]);
> +    cpu_stw_data(env, addr + (2 << DF_HALF), pwd->h[1]);
> +    cpu_stw_data(env, addr + (1 << DF_HALF), pwd->h[2]);
> +    cpu_stw_data(env, addr + (0 << DF_HALF), pwd->h[3]);
> +    cpu_stw_data(env, addr + (7 << DF_HALF), pwd->h[4]);
> +    cpu_stw_data(env, addr + (6 << DF_HALF), pwd->h[5]);
> +    cpu_stw_data(env, addr + (5 << DF_HALF), pwd->h[6]);
> +    cpu_stw_data(env, addr + (4 << DF_HALF), pwd->h[7]);
> +#endif
> +#endif
>  }
>
> +void helper_msa_st_w(CPUMIPSState *env, uint32_t wd,
> +                     target_ulong addr)
> +{
> +    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
> +    MEMOP_IDX(DF_WORD)
>  #if !defined(CONFIG_USER_ONLY)
> -MSA_ST_DF(DF_BYTE,   b, helper_ret_stb_mmu, oi, GETPC())
> -MSA_ST_DF(DF_HALF,   h, helper_ret_stw_mmu, oi, GETPC())
> -MSA_ST_DF(DF_WORD,   w, helper_ret_stl_mmu, oi, GETPC())
> -MSA_ST_DF(DF_DOUBLE, d, helper_ret_stq_mmu, oi, GETPC())
> +#if !defined(HOST_WORDS_BIGENDIAN)
> +    helper_ret_stl_mmu(env, addr + (0 << DF_WORD), oi, GETPC(),
pwd->w[0]);
> +    helper_ret_stl_mmu(env, addr + (1 << DF_WORD), oi, GETPC(),
pwd->w[1]);
> +    helper_ret_stl_mmu(env, addr + (2 << DF_WORD), oi, GETPC(),
pwd->w[2]);
> +    helper_ret_stl_mmu(env, addr + (3 << DF_WORD), oi, GETPC(),
pwd->w[3]);
>  #else
> -MSA_ST_DF(DF_BYTE,   b, cpu_stb_data)
> -MSA_ST_DF(DF_HALF,   h, cpu_stw_data)
> -MSA_ST_DF(DF_WORD,   w, cpu_stl_data)
> -MSA_ST_DF(DF_DOUBLE, d, cpu_stq_data)
> +    helper_ret_stl_mmu(env, addr + (1 << DF_WORD), oi, GETPC(),
pwd->w[0]);
> +    helper_ret_stl_mmu(env, addr + (0 << DF_WORD), oi, GETPC(),
pwd->w[1]);
> +    helper_ret_stl_mmu(env, addr + (3 << DF_WORD), oi, GETPC(),
pwd->w[2]);
> +    helper_ret_stl_mmu(env, addr + (2 << DF_WORD), oi, GETPC(),
pwd->w[3]);
>  #endif
> +#else
> +#if !defined(HOST_WORDS_BIGENDIAN)
> +    cpu_stl_data(env, addr + (0 << DF_WORD), pwd->w[0]);
> +    cpu_stl_data(env, addr + (1 << DF_WORD), pwd->w[1]);
> +    cpu_stl_data(env, addr + (2 << DF_WORD), pwd->w[2]);
> +    cpu_stl_data(env, addr + (3 << DF_WORD), pwd->w[3]);
> +#else
> +    cpu_stl_data(env, addr + (1 << DF_WORD), pwd->w[0]);
> +    cpu_stl_data(env, addr + (0 << DF_WORD), pwd->w[1]);
> +    cpu_stl_data(env, addr + (3 << DF_WORD), pwd->w[2]);
> +    cpu_stl_data(env, addr + (2 << DF_WORD), pwd->w[3]);
> +#endif
> +#endif
> +}
> +
> +void helper_msa_st_d(CPUMIPSState *env, uint32_t wd,
> +                     target_ulong addr)
> +{
> +    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
> +    MEMOP_IDX(DF_DOUBLE)
> +#if !defined(CONFIG_USER_ONLY)
> +    helper_ret_stq_mmu(env, addr + (0 << DF_DOUBLE), pwd->d[0], oi,
GETPC());
> +    helper_ret_stq_mmu(env, addr + (1 << DF_DOUBLE), pwd->d[1], oi,
GETPC());
> +#else
> +    cpu_stq_data(env, addr + (0 << DF_DOUBLE), pwd->d[0]);
> +    cpu_stq_data(env, addr + (1 << DF_DOUBLE), pwd->d[1]);
> +#endif
> +}
>
>  void helper_cache(CPUMIPSState *env, target_ulong addr, uint32_t op)
>  {
> --
> 2.7.4
>
>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH v4 2/5] target/mips: Fix MSA instructions ST.<B|H|W|D> on big endian host
  2019-05-20 12:59   ` Aleksandar Markovic
@ 2019-05-20 13:07     ` Mateja Marjanovic
  0 siblings, 0 replies; 17+ messages in thread
From: Mateja Marjanovic @ 2019-05-20 13:07 UTC (permalink / raw)
  To: Aleksandar Markovic; +Cc: arikalo, amarkovic, aurelien, qemu-devel


On 20.5.19. 14:59, Aleksandar Markovic wrote:
>
>
> On Apr 2, 2019 3:47 PM, "Mateja Marjanovic" 
> <mateja.marjanovic@rt-rk.com <mailto:mateja.marjanovic@rt-rk.com>> wrote:
> >
> > From: Mateja Marjanovic <Mateja.Marjanovic@rt-rk.com 
> <mailto:Mateja.Marjanovic@rt-rk.com>>
> >
> > Fix the case when the host is a big endian machine, and change
> > the approach toward ST.<B|H|W|D> instruction helpers.
> >
> > Signed-off-by: Mateja Marjanovic <mateja.marjanovic@rt-rk.com 
> <mailto:mateja.marjanovic@rt-rk.com>>
> > ---
>
> Hello, Mateja.
>
> There is unfortunatelly still a slight problem with the new 
> implementation: it looks like the invocations to 
> ensure_writable_pages() in new helpers are missing. Or, perhaps, there 
> is a reason you removed them. Please reanalyse and reexplain. But 
> thanks for previous efforts.
>
I see, I deleted it by accident.

Thanks,
Mateja

> Yours,
> Aleksandar
>
> >  target/mips/op_helper.c | 188 
> ++++++++++++++++++++++++++++++++++++++++++------
> >  1 file changed, 168 insertions(+), 20 deletions(-)
> >
> > diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c
> > index 45be406..d94909a 100644
> > --- a/target/mips/op_helper.c
> > +++ b/target/mips/op_helper.c
> > @@ -4565,31 +4565,179 @@ static inline void 
> ensure_writable_pages(CPUMIPSState *env,
> >  #endif
> >  }
> >
> > -#define MSA_ST_DF(DF, TYPE, ST_INSN, ...)              \
> > -void helper_msa_st_ ## TYPE(CPUMIPSState *env, uint32_t wd,        
>      \
> > -                            target_ulong addr)               \
> > -{              \
> > -    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);                     \
> > -    int mmu_idx = cpu_mmu_index(env, false);              \
> > -    int i;               \
> > -    MEMOP_IDX(DF)              \
> > -    ensure_writable_pages(env, addr, mmu_idx, GETPC());              \
> > -    for (i = 0; i < DF_ELEMENTS(DF); i++) {                  \
> > -        ST_INSN(env, addr + (i << DF), pwd->TYPE[i], 
> ##__VA_ARGS__);    \
> > -    }              \
> > +void helper_msa_st_b(CPUMIPSState *env, uint32_t wd,
> > +                     target_ulong addr)
> > +{
> > +    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
> > +    MEMOP_IDX(DF_BYTE)
> > +#if !defined(CONFIG_USER_ONLY)
> > +#if !defined(HOST_WORDS_BIGENDIAN)
> > +    helper_ret_stb_mmu(env, addr + (0  << DF_BYTE), pwd->b[0],  oi, 
> GETPC());
> > +    helper_ret_stb_mmu(env, addr + (1  << DF_BYTE), pwd->b[1],  oi, 
> GETPC());
> > +    helper_ret_stb_mmu(env, addr + (2  << DF_BYTE), pwd->b[2],  oi, 
> GETPC());
> > +    helper_ret_stb_mmu(env, addr + (3  << DF_BYTE), pwd->b[3],  oi, 
> GETPC());
> > +    helper_ret_stb_mmu(env, addr + (4  << DF_BYTE), pwd->b[4],  oi, 
> GETPC());
> > +    helper_ret_stb_mmu(env, addr + (5  << DF_BYTE), pwd->b[5],  oi, 
> GETPC());
> > +    helper_ret_stb_mmu(env, addr + (6  << DF_BYTE), pwd->b[6],  oi, 
> GETPC());
> > +    helper_ret_stb_mmu(env, addr + (7  << DF_BYTE), pwd->b[7],  oi, 
> GETPC());
> > +    helper_ret_stb_mmu(env, addr + (8  << DF_BYTE), pwd->b[8],  oi, 
> GETPC());
> > +    helper_ret_stb_mmu(env, addr + (9  << DF_BYTE), pwd->b[9],  oi, 
> GETPC());
> > +    helper_ret_stb_mmu(env, addr + (10 << DF_BYTE), pwd->b[10], oi, 
> GETPC());
> > +    helper_ret_stb_mmu(env, addr + (11 << DF_BYTE), pwd->b[11], oi, 
> GETPC());
> > +    helper_ret_stb_mmu(env, addr + (12 << DF_BYTE), pwd->b[12], oi, 
> GETPC());
> > +    helper_ret_stb_mmu(env, addr + (13 << DF_BYTE), pwd->b[13], oi, 
> GETPC());
> > +    helper_ret_stb_mmu(env, addr + (14 << DF_BYTE), pwd->b[14], oi, 
> GETPC());
> > +    helper_ret_stb_mmu(env, addr + (15 << DF_BYTE), pwd->b[15], oi, 
> GETPC());
> > +#else
> > +    helper_ret_stb_mmu(env, addr + (7  << DF_BYTE), pwd->b[0],  oi, 
> GETPC());
> > +    helper_ret_stb_mmu(env, addr + (6  << DF_BYTE), pwd->b[1],  oi, 
> GETPC());
> > +    helper_ret_stb_mmu(env, addr + (5  << DF_BYTE), pwd->b[2],  oi, 
> GETPC());
> > +    helper_ret_stb_mmu(env, addr + (4  << DF_BYTE), pwd->b[3],  oi, 
> GETPC());
> > +    helper_ret_stb_mmu(env, addr + (3  << DF_BYTE), pwd->b[4],  oi, 
> GETPC());
> > +    helper_ret_stb_mmu(env, addr + (2  << DF_BYTE), pwd->b[5],  oi, 
> GETPC());
> > +    helper_ret_stb_mmu(env, addr + (1  << DF_BYTE), pwd->b[6],  oi, 
> GETPC());
> > +    helper_ret_stb_mmu(env, addr + (0  << DF_BYTE), pwd->b[7],  oi, 
> GETPC());
> > +    helper_ret_stb_mmu(env, addr + (15 << DF_BYTE), pwd->b[8],  oi, 
> GETPC());
> > +    helper_ret_stb_mmu(env, addr + (14 << DF_BYTE), pwd->b[9],  oi, 
> GETPC());
> > +    helper_ret_stb_mmu(env, addr + (13 << DF_BYTE), pwd->b[10], oi, 
> GETPC());
> > +    helper_ret_stb_mmu(env, addr + (12 << DF_BYTE), pwd->b[11], oi, 
> GETPC());
> > +    helper_ret_stb_mmu(env, addr + (11 << DF_BYTE), pwd->b[12], oi, 
> GETPC());
> > +    helper_ret_stb_mmu(env, addr + (10 << DF_BYTE), pwd->b[13], oi, 
> GETPC());
> > +    helper_ret_stb_mmu(env, addr + (9  << DF_BYTE), pwd->b[14], oi, 
> GETPC());
> > +    helper_ret_stb_mmu(env, addr + (8  << DF_BYTE), pwd->b[15], oi, 
> GETPC());
> > +#endif
> > +#else
> > +#if !defined(HOST_WORDS_BIGENDIAN)
> > +    cpu_stb_data(env, addr + (0  << DF_BYTE), pwd->b[0]);
> > +    cpu_stb_data(env, addr + (1  << DF_BYTE), pwd->b[1]);
> > +    cpu_stb_data(env, addr + (2  << DF_BYTE), pwd->b[2]);
> > +    cpu_stb_data(env, addr + (3  << DF_BYTE), pwd->b[3]);
> > +    cpu_stb_data(env, addr + (4  << DF_BYTE), pwd->b[4]);
> > +    cpu_stb_data(env, addr + (5  << DF_BYTE), pwd->b[5]);
> > +    cpu_stb_data(env, addr + (6  << DF_BYTE), pwd->b[6]);
> > +    cpu_stb_data(env, addr + (7  << DF_BYTE), pwd->b[7]);
> > +    cpu_stb_data(env, addr + (8  << DF_BYTE), pwd->b[8]);
> > +    cpu_stb_data(env, addr + (9  << DF_BYTE), pwd->b[9]);
> > +    cpu_stb_data(env, addr + (10 << DF_BYTE), pwd->b[10]);
> > +    cpu_stb_data(env, addr + (11 << DF_BYTE), pwd->b[11]);
> > +    cpu_stb_data(env, addr + (12 << DF_BYTE), pwd->b[12]);
> > +    cpu_stb_data(env, addr + (13 << DF_BYTE), pwd->b[13]);
> > +    cpu_stb_data(env, addr + (14 << DF_BYTE), pwd->b[14]);
> > +    cpu_stb_data(env, addr + (15 << DF_BYTE), pwd->b[15]);
> > +#else
> > +    cpu_stb_data(env, addr + (7  << DF_BYTE), pwd->b[0]);
> > +    cpu_stb_data(env, addr + (6  << DF_BYTE), pwd->b[1]);
> > +    cpu_stb_data(env, addr + (5  << DF_BYTE), pwd->b[2]);
> > +    cpu_stb_data(env, addr + (4  << DF_BYTE), pwd->b[3]);
> > +    cpu_stb_data(env, addr + (3  << DF_BYTE), pwd->b[4]);
> > +    cpu_stb_data(env, addr + (2  << DF_BYTE), pwd->b[5]);
> > +    cpu_stb_data(env, addr + (1  << DF_BYTE), pwd->b[6]);
> > +    cpu_stb_data(env, addr + (0  << DF_BYTE), pwd->b[7]);
> > +    cpu_stb_data(env, addr + (15 << DF_BYTE), pwd->b[8]);
> > +    cpu_stb_data(env, addr + (14 << DF_BYTE), pwd->b[9]);
> > +    cpu_stb_data(env, addr + (13 << DF_BYTE), pwd->b[10]);
> > +    cpu_stb_data(env, addr + (12 << DF_BYTE), pwd->b[11]);
> > +    cpu_stb_data(env, addr + (11 << DF_BYTE), pwd->b[12]);
> > +    cpu_stb_data(env, addr + (10 << DF_BYTE), pwd->b[13]);
> > +    cpu_stb_data(env, addr + (9  << DF_BYTE), pwd->b[14]);
> > +    cpu_stb_data(env, addr + (8  << DF_BYTE), pwd->b[15]);
> > +#endif
> > +#endif
> > +}
> > +
> > +void helper_msa_st_h(CPUMIPSState *env, uint32_t wd,
> > +                     target_ulong addr)
> > +{
> > +    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
> > +    MEMOP_IDX(DF_HALF)
> > +#if !defined(CONFIG_USER_ONLY)
> > +#if !defined(HOST_WORDS_BIGENDIAN)
> > +    helper_ret_stw_mmu(env, addr + (0 << DF_HALF), pwd->h[0], oi, 
> GETPC());
> > +    helper_ret_stw_mmu(env, addr + (1 << DF_HALF), pwd->h[1], oi, 
> GETPC());
> > +    helper_ret_stw_mmu(env, addr + (2 << DF_HALF), pwd->h[2], oi, 
> GETPC());
> > +    helper_ret_stw_mmu(env, addr + (3 << DF_HALF), pwd->h[3], oi, 
> GETPC());
> > +    helper_ret_stw_mmu(env, addr + (4 << DF_HALF), pwd->h[4], oi, 
> GETPC());
> > +    helper_ret_stw_mmu(env, addr + (5 << DF_HALF), pwd->h[5], oi, 
> GETPC());
> > +    helper_ret_stw_mmu(env, addr + (6 << DF_HALF), pwd->h[6], oi, 
> GETPC());
> > +    helper_ret_stw_mmu(env, addr + (7 << DF_HALF), pwd->h[7], oi, 
> GETPC());
> > +#else
> > +    helper_ret_stw_mmu(env, addr + (3 << DF_HALF), pwd->h[0], oi, 
> GETPC());
> > +    helper_ret_stw_mmu(env, addr + (2 << DF_HALF), pwd->h[1], oi, 
> GETPC());
> > +    helper_ret_stw_mmu(env, addr + (1 << DF_HALF), pwd->h[2], oi, 
> GETPC());
> > +    helper_ret_stw_mmu(env, addr + (0 << DF_HALF), pwd->h[3], oi, 
> GETPC());
> > +    helper_ret_stw_mmu(env, addr + (7 << DF_HALF), pwd->h[4], oi, 
> GETPC());
> > +    helper_ret_stw_mmu(env, addr + (6 << DF_HALF), pwd->h[5], oi, 
> GETPC());
> > +    helper_ret_stw_mmu(env, addr + (5 << DF_HALF), pwd->h[6], oi, 
> GETPC());
> > +    helper_ret_stw_mmu(env, addr + (4 << DF_HALF), pwd->h[7], oi, 
> GETPC());
> > +#endif
> > +#else
> > +#if !defined(HOST_WORDS_BIGENDIAN)
> > +    cpu_stw_data(env, addr + (0 << DF_HALF), pwd->h[0]);
> > +    cpu_stw_data(env, addr + (1 << DF_HALF), pwd->h[1]);
> > +    cpu_stw_data(env, addr + (2 << DF_HALF), pwd->h[2]);
> > +    cpu_stw_data(env, addr + (3 << DF_HALF), pwd->h[3]);
> > +    cpu_stw_data(env, addr + (4 << DF_HALF), pwd->h[4]);
> > +    cpu_stw_data(env, addr + (5 << DF_HALF), pwd->h[5]);
> > +    cpu_stw_data(env, addr + (6 << DF_HALF), pwd->h[6]);
> > +    cpu_stw_data(env, addr + (7 << DF_HALF), pwd->h[7]);
> > +#else
> > +    cpu_stw_data(env, addr + (3 << DF_HALF), pwd->h[0]);
> > +    cpu_stw_data(env, addr + (2 << DF_HALF), pwd->h[1]);
> > +    cpu_stw_data(env, addr + (1 << DF_HALF), pwd->h[2]);
> > +    cpu_stw_data(env, addr + (0 << DF_HALF), pwd->h[3]);
> > +    cpu_stw_data(env, addr + (7 << DF_HALF), pwd->h[4]);
> > +    cpu_stw_data(env, addr + (6 << DF_HALF), pwd->h[5]);
> > +    cpu_stw_data(env, addr + (5 << DF_HALF), pwd->h[6]);
> > +    cpu_stw_data(env, addr + (4 << DF_HALF), pwd->h[7]);
> > +#endif
> > +#endif
> >  }
> >
> > +void helper_msa_st_w(CPUMIPSState *env, uint32_t wd,
> > +                     target_ulong addr)
> > +{
> > +    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
> > +    MEMOP_IDX(DF_WORD)
> >  #if !defined(CONFIG_USER_ONLY)
> > -MSA_ST_DF(DF_BYTE,   b, helper_ret_stb_mmu, oi, GETPC())
> > -MSA_ST_DF(DF_HALF,   h, helper_ret_stw_mmu, oi, GETPC())
> > -MSA_ST_DF(DF_WORD,   w, helper_ret_stl_mmu, oi, GETPC())
> > -MSA_ST_DF(DF_DOUBLE, d, helper_ret_stq_mmu, oi, GETPC())
> > +#if !defined(HOST_WORDS_BIGENDIAN)
> > +    helper_ret_stl_mmu(env, addr + (0 << DF_WORD), oi, GETPC(), 
> pwd->w[0]);
> > +    helper_ret_stl_mmu(env, addr + (1 << DF_WORD), oi, GETPC(), 
> pwd->w[1]);
> > +    helper_ret_stl_mmu(env, addr + (2 << DF_WORD), oi, GETPC(), 
> pwd->w[2]);
> > +    helper_ret_stl_mmu(env, addr + (3 << DF_WORD), oi, GETPC(), 
> pwd->w[3]);
> >  #else
> > -MSA_ST_DF(DF_BYTE,   b, cpu_stb_data)
> > -MSA_ST_DF(DF_HALF,   h, cpu_stw_data)
> > -MSA_ST_DF(DF_WORD,   w, cpu_stl_data)
> > -MSA_ST_DF(DF_DOUBLE, d, cpu_stq_data)
> > +    helper_ret_stl_mmu(env, addr + (1 << DF_WORD), oi, GETPC(), 
> pwd->w[0]);
> > +    helper_ret_stl_mmu(env, addr + (0 << DF_WORD), oi, GETPC(), 
> pwd->w[1]);
> > +    helper_ret_stl_mmu(env, addr + (3 << DF_WORD), oi, GETPC(), 
> pwd->w[2]);
> > +    helper_ret_stl_mmu(env, addr + (2 << DF_WORD), oi, GETPC(), 
> pwd->w[3]);
> >  #endif
> > +#else
> > +#if !defined(HOST_WORDS_BIGENDIAN)
> > +    cpu_stl_data(env, addr + (0 << DF_WORD), pwd->w[0]);
> > +    cpu_stl_data(env, addr + (1 << DF_WORD), pwd->w[1]);
> > +    cpu_stl_data(env, addr + (2 << DF_WORD), pwd->w[2]);
> > +    cpu_stl_data(env, addr + (3 << DF_WORD), pwd->w[3]);
> > +#else
> > +    cpu_stl_data(env, addr + (1 << DF_WORD), pwd->w[0]);
> > +    cpu_stl_data(env, addr + (0 << DF_WORD), pwd->w[1]);
> > +    cpu_stl_data(env, addr + (3 << DF_WORD), pwd->w[2]);
> > +    cpu_stl_data(env, addr + (2 << DF_WORD), pwd->w[3]);
> > +#endif
> > +#endif
> > +}
> > +
> > +void helper_msa_st_d(CPUMIPSState *env, uint32_t wd,
> > +                     target_ulong addr)
> > +{
> > +    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
> > +    MEMOP_IDX(DF_DOUBLE)
> > +#if !defined(CONFIG_USER_ONLY)
> > +    helper_ret_stq_mmu(env, addr + (0 << DF_DOUBLE), pwd->d[0], oi, 
> GETPC());
> > +    helper_ret_stq_mmu(env, addr + (1 << DF_DOUBLE), pwd->d[1], oi, 
> GETPC());
> > +#else
> > +    cpu_stq_data(env, addr + (0 << DF_DOUBLE), pwd->d[0]);
> > +    cpu_stq_data(env, addr + (1 << DF_DOUBLE), pwd->d[1]);
> > +#endif
> > +}
> >
> >  void helper_cache(CPUMIPSState *env, target_ulong addr, uint32_t op)
> >  {
> > --
> > 2.7.4
> >
> >
>

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2019-05-20 13:09 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-04-02 13:43 [Qemu-devel] [PATCH v4 0/5] target/mips: Fix support for MSA instructions on a big endian host Mateja Marjanovic
2019-04-02 13:43 ` [Qemu-devel] [PATCH v4 1/5] target/mips: Fix MSA instructions LD.<B|H|W|D> on " Mateja Marjanovic
2019-04-02 20:38   ` Aleksandar Markovic
2019-04-02 13:43 ` [Qemu-devel] [PATCH v4 2/5] target/mips: Fix MSA instructions ST.<B|H|W|D> " Mateja Marjanovic
2019-04-02 20:39   ` Aleksandar Markovic
2019-05-20 12:59   ` Aleksandar Markovic
2019-05-20 13:07     ` Mateja Marjanovic
2019-04-02 13:43 ` [Qemu-devel] [PATCH v4 3/5] target/mips: Refactor and fix COPY_S.<B|H|W|D> instructions Mateja Marjanovic
2019-05-18 15:47   ` Aleksandar Markovic
2019-04-02 13:43 ` [Qemu-devel] [PATCH v4 4/5] target/mips: Refactor and fix COPY_U.<B|H|W> instructions Mateja Marjanovic
2019-05-18 15:47   ` Aleksandar Markovic
2019-04-02 13:43 ` [Qemu-devel] [PATCH v4 5/5] target/mips: Refactor and fix INSERT.<B|H|W|D> instructions Mateja Marjanovic
2019-04-02 20:50   ` Aleksandar Markovic
2019-04-03  8:37     ` Mateja Marjanovic
2019-04-03 12:12       ` Aleksandar Markovic
2019-05-19  5:25   ` Aleksandar Markovic
2019-05-20 10:24     ` Mateja Marjanovic

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.