All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/5] target/mips: Replace TARGET_WORDS_BIGENDIAN by cpu_is_bigendian()
@ 2021-08-18 16:43 Philippe Mathieu-Daudé
  2021-08-18 16:43 ` [PATCH 1/5] target/mips: Replace GET_OFFSET() macro by get_offset() function Philippe Mathieu-Daudé
                   ` (4 more replies)
  0 siblings, 5 replies; 13+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-08-18 16:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Thomas Huth, Richard Henderson, Aleksandar Rikalo,
	Philippe Mathieu-Daudé,
	Aurelien Jarno

MIPS CPU store its endianess in the CP0 Config0 register.
Use that runtime information instead of #ifdef'ry checking
TARGET_WORDS_BIGENDIAN by introducing the cpu_is_bigendian()
helper.

Philippe Mathieu-Daudé (5):
  target/mips: Replace GET_OFFSET() macro by get_offset() function
  target/mips: Replace GET_LMASK() macro by get_lmask(32) function
  target/mips: Replace GET_LMASK64() macro by get_lmask(64) function
  target/mips: Store CP0_Config0 in DisasContext
  target/mips: Replace TARGET_WORDS_BIGENDIAN by cpu_is_bigendian()

 target/mips/tcg/translate.h              |   6 ++
 target/mips/tcg/ldst_helper.c            | 120 +++++++++++++----------
 target/mips/tcg/translate.c              |  71 +++++++-------
 target/mips/tcg/nanomips_translate.c.inc |  20 ++--
 4 files changed, 120 insertions(+), 97 deletions(-)

-- 
2.31.1



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

* [PATCH 1/5] target/mips: Replace GET_OFFSET() macro by get_offset() function
  2021-08-18 16:43 [PATCH 0/5] target/mips: Replace TARGET_WORDS_BIGENDIAN by cpu_is_bigendian() Philippe Mathieu-Daudé
@ 2021-08-18 16:43 ` Philippe Mathieu-Daudé
  2021-08-18 16:56   ` Richard Henderson
  2021-08-18 16:43 ` [PATCH 2/5] target/mips: Replace GET_LMASK() macro by get_lmask(32) function Philippe Mathieu-Daudé
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 13+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-08-18 16:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Thomas Huth, Richard Henderson, Aleksandar Rikalo,
	Philippe Mathieu-Daudé,
	Aurelien Jarno

The target endianess information is stored in the BigEndian
bit of the Config0 register in CP0.

As a first step, replace the GET_OFFSET() macro by an inlined
get_offset() function, passing CPUMIPSState as argument.

Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 target/mips/tcg/ldst_helper.c | 57 +++++++++++++++++++++--------------
 1 file changed, 35 insertions(+), 22 deletions(-)

diff --git a/target/mips/tcg/ldst_helper.c b/target/mips/tcg/ldst_helper.c
index d42812b8a6a..97e7ad7d7a4 100644
--- a/target/mips/tcg/ldst_helper.c
+++ b/target/mips/tcg/ldst_helper.c
@@ -52,31 +52,44 @@ HELPER_LD_ATOMIC(lld, ldq, 0x7, (target_ulong))
 
 #endif /* !CONFIG_USER_ONLY */
 
+static inline bool cpu_is_bigendian(CPUMIPSState *env)
+{
+    return extract32(env->CP0_Config0, CP0C0_BE, 1);
+}
+
 #ifdef TARGET_WORDS_BIGENDIAN
 #define GET_LMASK(v) ((v) & 3)
-#define GET_OFFSET(addr, offset) (addr + (offset))
 #else
 #define GET_LMASK(v) (((v) & 3) ^ 3)
-#define GET_OFFSET(addr, offset) (addr - (offset))
 #endif
 
+static inline target_ulong get_offset(CPUMIPSState *env,
+                                      target_ulong addr, int offset)
+{
+    if (cpu_is_bigendian(env)) {
+        return addr + offset;
+    } else {
+        return addr - offset;
+    }
+}
+
 void helper_swl(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
                 int mem_idx)
 {
     cpu_stb_mmuidx_ra(env, arg2, (uint8_t)(arg1 >> 24), mem_idx, GETPC());
 
     if (GET_LMASK(arg2) <= 2) {
-        cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, 1), (uint8_t)(arg1 >> 16),
+        cpu_stb_mmuidx_ra(env, get_offset(env, arg2, 1), (uint8_t)(arg1 >> 16),
                           mem_idx, GETPC());
     }
 
     if (GET_LMASK(arg2) <= 1) {
-        cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, 2), (uint8_t)(arg1 >> 8),
+        cpu_stb_mmuidx_ra(env, get_offset(env, arg2, 2), (uint8_t)(arg1 >> 8),
                           mem_idx, GETPC());
     }
 
     if (GET_LMASK(arg2) == 0) {
-        cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, 3), (uint8_t)arg1,
+        cpu_stb_mmuidx_ra(env, get_offset(env, arg2, 3), (uint8_t)arg1,
                           mem_idx, GETPC());
     }
 }
@@ -87,17 +100,17 @@ void helper_swr(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
     cpu_stb_mmuidx_ra(env, arg2, (uint8_t)arg1, mem_idx, GETPC());
 
     if (GET_LMASK(arg2) >= 1) {
-        cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, -1), (uint8_t)(arg1 >> 8),
+        cpu_stb_mmuidx_ra(env, get_offset(env, arg2, -1), (uint8_t)(arg1 >> 8),
                           mem_idx, GETPC());
     }
 
     if (GET_LMASK(arg2) >= 2) {
-        cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, -2), (uint8_t)(arg1 >> 16),
+        cpu_stb_mmuidx_ra(env, get_offset(env, arg2, -2), (uint8_t)(arg1 >> 16),
                           mem_idx, GETPC());
     }
 
     if (GET_LMASK(arg2) == 3) {
-        cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, -3), (uint8_t)(arg1 >> 24),
+        cpu_stb_mmuidx_ra(env, get_offset(env, arg2, -3), (uint8_t)(arg1 >> 24),
                           mem_idx, GETPC());
     }
 }
@@ -119,37 +132,37 @@ void helper_sdl(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
     cpu_stb_mmuidx_ra(env, arg2, (uint8_t)(arg1 >> 56), mem_idx, GETPC());
 
     if (GET_LMASK64(arg2) <= 6) {
-        cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, 1), (uint8_t)(arg1 >> 48),
+        cpu_stb_mmuidx_ra(env, get_offset(env, arg2, 1), (uint8_t)(arg1 >> 48),
                           mem_idx, GETPC());
     }
 
     if (GET_LMASK64(arg2) <= 5) {
-        cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, 2), (uint8_t)(arg1 >> 40),
+        cpu_stb_mmuidx_ra(env, get_offset(env, arg2, 2), (uint8_t)(arg1 >> 40),
                           mem_idx, GETPC());
     }
 
     if (GET_LMASK64(arg2) <= 4) {
-        cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, 3), (uint8_t)(arg1 >> 32),
+        cpu_stb_mmuidx_ra(env, get_offset(env, arg2, 3), (uint8_t)(arg1 >> 32),
                           mem_idx, GETPC());
     }
 
     if (GET_LMASK64(arg2) <= 3) {
-        cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, 4), (uint8_t)(arg1 >> 24),
+        cpu_stb_mmuidx_ra(env, get_offset(env, arg2, 4), (uint8_t)(arg1 >> 24),
                           mem_idx, GETPC());
     }
 
     if (GET_LMASK64(arg2) <= 2) {
-        cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, 5), (uint8_t)(arg1 >> 16),
+        cpu_stb_mmuidx_ra(env, get_offset(env, arg2, 5), (uint8_t)(arg1 >> 16),
                           mem_idx, GETPC());
     }
 
     if (GET_LMASK64(arg2) <= 1) {
-        cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, 6), (uint8_t)(arg1 >> 8),
+        cpu_stb_mmuidx_ra(env, get_offset(env, arg2, 6), (uint8_t)(arg1 >> 8),
                           mem_idx, GETPC());
     }
 
     if (GET_LMASK64(arg2) <= 0) {
-        cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, 7), (uint8_t)arg1,
+        cpu_stb_mmuidx_ra(env, get_offset(env, arg2, 7), (uint8_t)arg1,
                           mem_idx, GETPC());
     }
 }
@@ -160,37 +173,37 @@ void helper_sdr(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
     cpu_stb_mmuidx_ra(env, arg2, (uint8_t)arg1, mem_idx, GETPC());
 
     if (GET_LMASK64(arg2) >= 1) {
-        cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, -1), (uint8_t)(arg1 >> 8),
+        cpu_stb_mmuidx_ra(env, get_offset(env, arg2, -1), (uint8_t)(arg1 >> 8),
                           mem_idx, GETPC());
     }
 
     if (GET_LMASK64(arg2) >= 2) {
-        cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, -2), (uint8_t)(arg1 >> 16),
+        cpu_stb_mmuidx_ra(env, get_offset(env, arg2, -2), (uint8_t)(arg1 >> 16),
                           mem_idx, GETPC());
     }
 
     if (GET_LMASK64(arg2) >= 3) {
-        cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, -3), (uint8_t)(arg1 >> 24),
+        cpu_stb_mmuidx_ra(env, get_offset(env, arg2, -3), (uint8_t)(arg1 >> 24),
                           mem_idx, GETPC());
     }
 
     if (GET_LMASK64(arg2) >= 4) {
-        cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, -4), (uint8_t)(arg1 >> 32),
+        cpu_stb_mmuidx_ra(env, get_offset(env, arg2, -4), (uint8_t)(arg1 >> 32),
                           mem_idx, GETPC());
     }
 
     if (GET_LMASK64(arg2) >= 5) {
-        cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, -5), (uint8_t)(arg1 >> 40),
+        cpu_stb_mmuidx_ra(env, get_offset(env, arg2, -5), (uint8_t)(arg1 >> 40),
                           mem_idx, GETPC());
     }
 
     if (GET_LMASK64(arg2) >= 6) {
-        cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, -6), (uint8_t)(arg1 >> 48),
+        cpu_stb_mmuidx_ra(env, get_offset(env, arg2, -6), (uint8_t)(arg1 >> 48),
                           mem_idx, GETPC());
     }
 
     if (GET_LMASK64(arg2) == 7) {
-        cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, -7), (uint8_t)(arg1 >> 56),
+        cpu_stb_mmuidx_ra(env, get_offset(env, arg2, -7), (uint8_t)(arg1 >> 56),
                           mem_idx, GETPC());
     }
 }
-- 
2.31.1



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

* [PATCH 2/5] target/mips: Replace GET_LMASK() macro by get_lmask(32) function
  2021-08-18 16:43 [PATCH 0/5] target/mips: Replace TARGET_WORDS_BIGENDIAN by cpu_is_bigendian() Philippe Mathieu-Daudé
  2021-08-18 16:43 ` [PATCH 1/5] target/mips: Replace GET_OFFSET() macro by get_offset() function Philippe Mathieu-Daudé
@ 2021-08-18 16:43 ` Philippe Mathieu-Daudé
  2021-08-18 17:09   ` Richard Henderson
  2021-08-18 16:43 ` [PATCH 3/5] target/mips: Replace GET_LMASK64() macro by get_lmask(64) function Philippe Mathieu-Daudé
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 13+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-08-18 16:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Thomas Huth, Richard Henderson, Aleksandar Rikalo,
	Philippe Mathieu-Daudé,
	Aurelien Jarno

The target endianess information is stored in the BigEndian
bit of the Config0 register in CP0.

Replace the GET_LMASK() macro by an inlined get_lmask() function,
passing CPUMIPSState and the word size as argument.

We can remove one use of the TARGET_WORDS_BIGENDIAN definition.

Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 target/mips/tcg/ldst_helper.c | 32 ++++++++++++++++++++------------
 1 file changed, 20 insertions(+), 12 deletions(-)

diff --git a/target/mips/tcg/ldst_helper.c b/target/mips/tcg/ldst_helper.c
index 97e7ad7d7a4..888578c0b9c 100644
--- a/target/mips/tcg/ldst_helper.c
+++ b/target/mips/tcg/ldst_helper.c
@@ -57,12 +57,6 @@ static inline bool cpu_is_bigendian(CPUMIPSState *env)
     return extract32(env->CP0_Config0, CP0C0_BE, 1);
 }
 
-#ifdef TARGET_WORDS_BIGENDIAN
-#define GET_LMASK(v) ((v) & 3)
-#else
-#define GET_LMASK(v) (((v) & 3) ^ 3)
-#endif
-
 static inline target_ulong get_offset(CPUMIPSState *env,
                                       target_ulong addr, int offset)
 {
@@ -73,22 +67,36 @@ static inline target_ulong get_offset(CPUMIPSState *env,
     }
 }
 
+static inline target_ulong get_lmask(CPUMIPSState *env,
+                                     target_ulong value, unsigned bits)
+{
+    unsigned mask = (bits / BITS_PER_BYTE) - 1;
+
+    value &= mask;
+
+    if (cpu_is_bigendian(env)) {
+        value ^= mask;
+    }
+
+    return value;
+}
+
 void helper_swl(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
                 int mem_idx)
 {
     cpu_stb_mmuidx_ra(env, arg2, (uint8_t)(arg1 >> 24), mem_idx, GETPC());
 
-    if (GET_LMASK(arg2) <= 2) {
+    if (get_lmask(env, arg2, 32) <= 2) {
         cpu_stb_mmuidx_ra(env, get_offset(env, arg2, 1), (uint8_t)(arg1 >> 16),
                           mem_idx, GETPC());
     }
 
-    if (GET_LMASK(arg2) <= 1) {
+    if (get_lmask(env, arg2, 32) <= 1) {
         cpu_stb_mmuidx_ra(env, get_offset(env, arg2, 2), (uint8_t)(arg1 >> 8),
                           mem_idx, GETPC());
     }
 
-    if (GET_LMASK(arg2) == 0) {
+    if (get_lmask(env, arg2, 32) == 0) {
         cpu_stb_mmuidx_ra(env, get_offset(env, arg2, 3), (uint8_t)arg1,
                           mem_idx, GETPC());
     }
@@ -99,17 +107,17 @@ void helper_swr(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
 {
     cpu_stb_mmuidx_ra(env, arg2, (uint8_t)arg1, mem_idx, GETPC());
 
-    if (GET_LMASK(arg2) >= 1) {
+    if (get_lmask(env, arg2, 32) >= 1) {
         cpu_stb_mmuidx_ra(env, get_offset(env, arg2, -1), (uint8_t)(arg1 >> 8),
                           mem_idx, GETPC());
     }
 
-    if (GET_LMASK(arg2) >= 2) {
+    if (get_lmask(env, arg2, 32) >= 2) {
         cpu_stb_mmuidx_ra(env, get_offset(env, arg2, -2), (uint8_t)(arg1 >> 16),
                           mem_idx, GETPC());
     }
 
-    if (GET_LMASK(arg2) == 3) {
+    if (get_lmask(env, arg2, 32) == 3) {
         cpu_stb_mmuidx_ra(env, get_offset(env, arg2, -3), (uint8_t)(arg1 >> 24),
                           mem_idx, GETPC());
     }
-- 
2.31.1



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

* [PATCH 3/5] target/mips: Replace GET_LMASK64() macro by get_lmask(64) function
  2021-08-18 16:43 [PATCH 0/5] target/mips: Replace TARGET_WORDS_BIGENDIAN by cpu_is_bigendian() Philippe Mathieu-Daudé
  2021-08-18 16:43 ` [PATCH 1/5] target/mips: Replace GET_OFFSET() macro by get_offset() function Philippe Mathieu-Daudé
  2021-08-18 16:43 ` [PATCH 2/5] target/mips: Replace GET_LMASK() macro by get_lmask(32) function Philippe Mathieu-Daudé
@ 2021-08-18 16:43 ` Philippe Mathieu-Daudé
  2021-08-18 16:43 ` [PATCH 4/5] target/mips: Store CP0_Config0 in DisasContext Philippe Mathieu-Daudé
  2021-08-18 16:43 ` [PATCH 5/5] target/mips: Replace TARGET_WORDS_BIGENDIAN by cpu_is_bigendian() Philippe Mathieu-Daudé
  4 siblings, 0 replies; 13+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-08-18 16:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Thomas Huth, Richard Henderson, Aleksandar Rikalo,
	Philippe Mathieu-Daudé,
	Aurelien Jarno

The target endianess information is stored in the BigEndian
bit of the Config0 register in CP0.

Replace the GET_LMASK() macro by an inlined get_lmask() function,
passing CPUMIPSState and the word size as argument.

We can remove another use of the TARGET_WORDS_BIGENDIAN definition.

Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 target/mips/tcg/ldst_helper.c | 33 ++++++++++++++-------------------
 1 file changed, 14 insertions(+), 19 deletions(-)

diff --git a/target/mips/tcg/ldst_helper.c b/target/mips/tcg/ldst_helper.c
index 888578c0b9c..01b3dc5bee0 100644
--- a/target/mips/tcg/ldst_helper.c
+++ b/target/mips/tcg/ldst_helper.c
@@ -128,48 +128,43 @@ void helper_swr(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
  * "half" load and stores.  We must do the memory access inline,
  * or fault handling won't work.
  */
-#ifdef TARGET_WORDS_BIGENDIAN
-#define GET_LMASK64(v) ((v) & 7)
-#else
-#define GET_LMASK64(v) (((v) & 7) ^ 7)
-#endif
 
 void helper_sdl(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
                 int mem_idx)
 {
     cpu_stb_mmuidx_ra(env, arg2, (uint8_t)(arg1 >> 56), mem_idx, GETPC());
 
-    if (GET_LMASK64(arg2) <= 6) {
+    if (get_lmask(env, arg2, 64) <= 6) {
         cpu_stb_mmuidx_ra(env, get_offset(env, arg2, 1), (uint8_t)(arg1 >> 48),
                           mem_idx, GETPC());
     }
 
-    if (GET_LMASK64(arg2) <= 5) {
+    if (get_lmask(env, arg2, 64) <= 5) {
         cpu_stb_mmuidx_ra(env, get_offset(env, arg2, 2), (uint8_t)(arg1 >> 40),
                           mem_idx, GETPC());
     }
 
-    if (GET_LMASK64(arg2) <= 4) {
+    if (get_lmask(env, arg2, 64) <= 4) {
         cpu_stb_mmuidx_ra(env, get_offset(env, arg2, 3), (uint8_t)(arg1 >> 32),
                           mem_idx, GETPC());
     }
 
-    if (GET_LMASK64(arg2) <= 3) {
+    if (get_lmask(env, arg2, 64) <= 3) {
         cpu_stb_mmuidx_ra(env, get_offset(env, arg2, 4), (uint8_t)(arg1 >> 24),
                           mem_idx, GETPC());
     }
 
-    if (GET_LMASK64(arg2) <= 2) {
+    if (get_lmask(env, arg2, 64) <= 2) {
         cpu_stb_mmuidx_ra(env, get_offset(env, arg2, 5), (uint8_t)(arg1 >> 16),
                           mem_idx, GETPC());
     }
 
-    if (GET_LMASK64(arg2) <= 1) {
+    if (get_lmask(env, arg2, 64) <= 1) {
         cpu_stb_mmuidx_ra(env, get_offset(env, arg2, 6), (uint8_t)(arg1 >> 8),
                           mem_idx, GETPC());
     }
 
-    if (GET_LMASK64(arg2) <= 0) {
+    if (get_lmask(env, arg2, 64) <= 0) {
         cpu_stb_mmuidx_ra(env, get_offset(env, arg2, 7), (uint8_t)arg1,
                           mem_idx, GETPC());
     }
@@ -180,37 +175,37 @@ void helper_sdr(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
 {
     cpu_stb_mmuidx_ra(env, arg2, (uint8_t)arg1, mem_idx, GETPC());
 
-    if (GET_LMASK64(arg2) >= 1) {
+    if (get_lmask(env, arg2, 64) >= 1) {
         cpu_stb_mmuidx_ra(env, get_offset(env, arg2, -1), (uint8_t)(arg1 >> 8),
                           mem_idx, GETPC());
     }
 
-    if (GET_LMASK64(arg2) >= 2) {
+    if (get_lmask(env, arg2, 64) >= 2) {
         cpu_stb_mmuidx_ra(env, get_offset(env, arg2, -2), (uint8_t)(arg1 >> 16),
                           mem_idx, GETPC());
     }
 
-    if (GET_LMASK64(arg2) >= 3) {
+    if (get_lmask(env, arg2, 64) >= 3) {
         cpu_stb_mmuidx_ra(env, get_offset(env, arg2, -3), (uint8_t)(arg1 >> 24),
                           mem_idx, GETPC());
     }
 
-    if (GET_LMASK64(arg2) >= 4) {
+    if (get_lmask(env, arg2, 64) >= 4) {
         cpu_stb_mmuidx_ra(env, get_offset(env, arg2, -4), (uint8_t)(arg1 >> 32),
                           mem_idx, GETPC());
     }
 
-    if (GET_LMASK64(arg2) >= 5) {
+    if (get_lmask(env, arg2, 64) >= 5) {
         cpu_stb_mmuidx_ra(env, get_offset(env, arg2, -5), (uint8_t)(arg1 >> 40),
                           mem_idx, GETPC());
     }
 
-    if (GET_LMASK64(arg2) >= 6) {
+    if (get_lmask(env, arg2, 64) >= 6) {
         cpu_stb_mmuidx_ra(env, get_offset(env, arg2, -6), (uint8_t)(arg1 >> 48),
                           mem_idx, GETPC());
     }
 
-    if (GET_LMASK64(arg2) == 7) {
+    if (get_lmask(env, arg2, 64) == 7) {
         cpu_stb_mmuidx_ra(env, get_offset(env, arg2, -7), (uint8_t)(arg1 >> 56),
                           mem_idx, GETPC());
     }
-- 
2.31.1



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

* [PATCH 4/5] target/mips: Store CP0_Config0 in DisasContext
  2021-08-18 16:43 [PATCH 0/5] target/mips: Replace TARGET_WORDS_BIGENDIAN by cpu_is_bigendian() Philippe Mathieu-Daudé
                   ` (2 preceding siblings ...)
  2021-08-18 16:43 ` [PATCH 3/5] target/mips: Replace GET_LMASK64() macro by get_lmask(64) function Philippe Mathieu-Daudé
@ 2021-08-18 16:43 ` Philippe Mathieu-Daudé
  2021-08-18 17:24   ` Richard Henderson
  2021-08-18 16:43 ` [PATCH 5/5] target/mips: Replace TARGET_WORDS_BIGENDIAN by cpu_is_bigendian() Philippe Mathieu-Daudé
  4 siblings, 1 reply; 13+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-08-18 16:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Thomas Huth, Richard Henderson, Aleksandar Rikalo,
	Philippe Mathieu-Daudé,
	Aurelien Jarno

Most TCG helpers only have access to a DisasContext pointer,
not CPUMIPSState. Store a copy of CPUMIPSState::CP0_Config0
in DisasContext so we can access it from TCG helpers.

Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 target/mips/tcg/translate.h | 1 +
 target/mips/tcg/translate.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/target/mips/tcg/translate.h b/target/mips/tcg/translate.h
index bb0a6b8d74f..9d325c836aa 100644
--- a/target/mips/tcg/translate.h
+++ b/target/mips/tcg/translate.h
@@ -18,6 +18,7 @@ typedef struct DisasContext {
     target_ulong page_start;
     uint32_t opcode;
     uint64_t insn_flags;
+    int32_t CP0_Config0;
     int32_t CP0_Config1;
     int32_t CP0_Config2;
     int32_t CP0_Config3;
diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
index a58d50e40e2..572104e2cc2 100644
--- a/target/mips/tcg/translate.c
+++ b/target/mips/tcg/translate.c
@@ -16034,6 +16034,7 @@ static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
     ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
     ctx->saved_pc = -1;
     ctx->insn_flags = env->insn_flags;
+    ctx->CP0_Config0 = env->CP0_Config0;
     ctx->CP0_Config1 = env->CP0_Config1;
     ctx->CP0_Config2 = env->CP0_Config2;
     ctx->CP0_Config3 = env->CP0_Config3;
-- 
2.31.1



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

* [PATCH 5/5] target/mips: Replace TARGET_WORDS_BIGENDIAN by cpu_is_bigendian()
  2021-08-18 16:43 [PATCH 0/5] target/mips: Replace TARGET_WORDS_BIGENDIAN by cpu_is_bigendian() Philippe Mathieu-Daudé
                   ` (3 preceding siblings ...)
  2021-08-18 16:43 ` [PATCH 4/5] target/mips: Store CP0_Config0 in DisasContext Philippe Mathieu-Daudé
@ 2021-08-18 16:43 ` Philippe Mathieu-Daudé
  2021-08-18 17:25   ` Richard Henderson
  4 siblings, 1 reply; 13+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-08-18 16:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Thomas Huth, Richard Henderson, Aleksandar Rikalo,
	Philippe Mathieu-Daudé,
	Aurelien Jarno

Add the inlined cpu_is_bigendian() function in "translate.h".

Replace the TARGET_WORDS_BIGENDIAN #ifdef'ry by calls to
cpu_is_bigendian().

Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 target/mips/tcg/translate.h              |  5 ++
 target/mips/tcg/translate.c              | 70 ++++++++++++------------
 target/mips/tcg/nanomips_translate.c.inc | 20 +++----
 3 files changed, 50 insertions(+), 45 deletions(-)

diff --git a/target/mips/tcg/translate.h b/target/mips/tcg/translate.h
index 9d325c836aa..dfb1552c2fc 100644
--- a/target/mips/tcg/translate.h
+++ b/target/mips/tcg/translate.h
@@ -212,4 +212,9 @@ bool decode_ext_vr54xx(DisasContext *ctx, uint32_t insn);
     static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a) \
     { return FUNC(ctx, a, __VA_ARGS__); }
 
+static inline bool cpu_is_bigendian(DisasContext *ctx)
+{
+    return extract32(ctx->CP0_Config0, CP0C0_BE, 1);
+}
+
 #endif
diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
index 572104e2cc2..f182e64643d 100644
--- a/target/mips/tcg/translate.c
+++ b/target/mips/tcg/translate.c
@@ -2093,9 +2093,9 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
          */
         tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
         tcg_gen_andi_tl(t1, t0, 7);
-#ifndef TARGET_WORDS_BIGENDIAN
-        tcg_gen_xori_tl(t1, t1, 7);
-#endif
+        if (!cpu_is_bigendian(ctx)) {
+            tcg_gen_xori_tl(t1, t1, 7);
+        }
         tcg_gen_shli_tl(t1, t1, 3);
         tcg_gen_andi_tl(t0, t0, ~7);
         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
@@ -2117,9 +2117,9 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
          */
         tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
         tcg_gen_andi_tl(t1, t0, 7);
-#ifdef TARGET_WORDS_BIGENDIAN
-        tcg_gen_xori_tl(t1, t1, 7);
-#endif
+        if (cpu_is_bigendian(ctx)) {
+            tcg_gen_xori_tl(t1, t1, 7);
+        }
         tcg_gen_shli_tl(t1, t1, 3);
         tcg_gen_andi_tl(t0, t0, ~7);
         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
@@ -2198,9 +2198,9 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
          */
         tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
         tcg_gen_andi_tl(t1, t0, 3);
-#ifndef TARGET_WORDS_BIGENDIAN
-        tcg_gen_xori_tl(t1, t1, 3);
-#endif
+        if (!cpu_is_bigendian(ctx)) {
+            tcg_gen_xori_tl(t1, t1, 3);
+        }
         tcg_gen_shli_tl(t1, t1, 3);
         tcg_gen_andi_tl(t0, t0, ~3);
         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
@@ -2226,9 +2226,9 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
          */
         tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
         tcg_gen_andi_tl(t1, t0, 3);
-#ifdef TARGET_WORDS_BIGENDIAN
-        tcg_gen_xori_tl(t1, t1, 3);
-#endif
+        if (cpu_is_bigendian(ctx)) {
+            tcg_gen_xori_tl(t1, t1, 3);
+        }
         tcg_gen_shli_tl(t1, t1, 3);
         tcg_gen_andi_tl(t0, t0, ~3);
         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
@@ -4445,9 +4445,9 @@ static void gen_loongson_lswc2(DisasContext *ctx, int rt,
             t1 = tcg_temp_new();
             tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
             tcg_gen_andi_tl(t1, t0, 3);
-#ifndef TARGET_WORDS_BIGENDIAN
-            tcg_gen_xori_tl(t1, t1, 3);
-#endif
+            if (!cpu_is_bigendian(ctx)) {
+                tcg_gen_xori_tl(t1, t1, 3);
+            }
             tcg_gen_shli_tl(t1, t1, 3);
             tcg_gen_andi_tl(t0, t0, ~3);
             tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
@@ -4475,9 +4475,9 @@ static void gen_loongson_lswc2(DisasContext *ctx, int rt,
             t1 = tcg_temp_new();
             tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
             tcg_gen_andi_tl(t1, t0, 3);
-#ifdef TARGET_WORDS_BIGENDIAN
-            tcg_gen_xori_tl(t1, t1, 3);
-#endif
+            if (cpu_is_bigendian(ctx)) {
+                tcg_gen_xori_tl(t1, t1, 3);
+            }
             tcg_gen_shli_tl(t1, t1, 3);
             tcg_gen_andi_tl(t0, t0, ~3);
             tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
@@ -4507,9 +4507,9 @@ static void gen_loongson_lswc2(DisasContext *ctx, int rt,
             t1 = tcg_temp_new();
             tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
             tcg_gen_andi_tl(t1, t0, 7);
-#ifndef TARGET_WORDS_BIGENDIAN
-            tcg_gen_xori_tl(t1, t1, 7);
-#endif
+            if (!cpu_is_bigendian(ctx)) {
+                tcg_gen_xori_tl(t1, t1, 7);
+            }
             tcg_gen_shli_tl(t1, t1, 3);
             tcg_gen_andi_tl(t0, t0, ~7);
             tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
@@ -4529,9 +4529,9 @@ static void gen_loongson_lswc2(DisasContext *ctx, int rt,
             t1 = tcg_temp_new();
             tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
             tcg_gen_andi_tl(t1, t0, 7);
-#ifdef TARGET_WORDS_BIGENDIAN
-            tcg_gen_xori_tl(t1, t1, 7);
-#endif
+            if (cpu_is_bigendian(ctx)) {
+                tcg_gen_xori_tl(t1, t1, 7);
+            }
             tcg_gen_shli_tl(t1, t1, 3);
             tcg_gen_andi_tl(t0, t0, ~7);
             tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
@@ -11464,17 +11464,17 @@ static void gen_flt3_arith(DisasContext *ctx, uint32_t opc,
             gen_set_label(l1);
             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
             tcg_temp_free(t0);
-#ifdef TARGET_WORDS_BIGENDIAN
-            gen_load_fpr32(ctx, fp, fs);
-            gen_load_fpr32h(ctx, fph, ft);
-            gen_store_fpr32h(ctx, fp, fd);
-            gen_store_fpr32(ctx, fph, fd);
-#else
-            gen_load_fpr32h(ctx, fph, fs);
-            gen_load_fpr32(ctx, fp, ft);
-            gen_store_fpr32(ctx, fph, fd);
-            gen_store_fpr32h(ctx, fp, fd);
-#endif
+            if (cpu_is_bigendian(ctx)) {
+                gen_load_fpr32(ctx, fp, fs);
+                gen_load_fpr32h(ctx, fph, ft);
+                gen_store_fpr32h(ctx, fp, fd);
+                gen_store_fpr32(ctx, fph, fd);
+            } else {
+                gen_load_fpr32h(ctx, fph, fs);
+                gen_load_fpr32(ctx, fp, ft);
+                gen_store_fpr32(ctx, fph, fd);
+                gen_store_fpr32h(ctx, fp, fd);
+            }
             gen_set_label(l2);
             tcg_temp_free_i32(fp);
             tcg_temp_free_i32(fph);
diff --git a/target/mips/tcg/nanomips_translate.c.inc b/target/mips/tcg/nanomips_translate.c.inc
index 09e64a69480..a66ae267963 100644
--- a/target/mips/tcg/nanomips_translate.c.inc
+++ b/target/mips/tcg/nanomips_translate.c.inc
@@ -999,11 +999,11 @@ static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset,
 
     gen_base_offset_addr(ctx, taddr, base, offset);
     tcg_gen_qemu_ld64(tval, taddr, ctx->mem_idx);
-#ifdef TARGET_WORDS_BIGENDIAN
-    tcg_gen_extr_i64_tl(tmp2, tmp1, tval);
-#else
-    tcg_gen_extr_i64_tl(tmp1, tmp2, tval);
-#endif
+    if (cpu_is_bigendian(ctx)) {
+        tcg_gen_extr_i64_tl(tmp2, tmp1, tval);
+    } else {
+        tcg_gen_extr_i64_tl(tmp1, tmp2, tval);
+    }
     gen_store_gpr(tmp1, reg1);
     tcg_temp_free(tmp1);
     gen_store_gpr(tmp2, reg2);
@@ -1035,11 +1035,11 @@ static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset,
     gen_load_gpr(tmp1, reg1);
     gen_load_gpr(tmp2, reg2);
 
-#ifdef TARGET_WORDS_BIGENDIAN
-    tcg_gen_concat_tl_i64(tval, tmp2, tmp1);
-#else
-    tcg_gen_concat_tl_i64(tval, tmp1, tmp2);
-#endif
+    if (cpu_is_bigendian(ctx)) {
+        tcg_gen_concat_tl_i64(tval, tmp2, tmp1);
+    } else {
+        tcg_gen_concat_tl_i64(tval, tmp1, tmp2);
+    }
 
     tcg_gen_ld_i64(llval, cpu_env, offsetof(CPUMIPSState, llval_wp));
     tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval,
-- 
2.31.1



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

* Re: [PATCH 1/5] target/mips: Replace GET_OFFSET() macro by get_offset() function
  2021-08-18 16:43 ` [PATCH 1/5] target/mips: Replace GET_OFFSET() macro by get_offset() function Philippe Mathieu-Daudé
@ 2021-08-18 16:56   ` Richard Henderson
  2021-08-18 21:31     ` Philippe Mathieu-Daudé
  0 siblings, 1 reply; 13+ messages in thread
From: Richard Henderson @ 2021-08-18 16:56 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel
  Cc: Thomas Huth, Aleksandar Rikalo, Aurelien Jarno

On 8/18/21 6:43 AM, Philippe Mathieu-Daudé wrote:
> The target endianess information is stored in the BigEndian
> bit of the Config0 register in CP0.
> 
> As a first step, replace the GET_OFFSET() macro by an inlined
> get_offset() function, passing CPUMIPSState as argument.
> 
> Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> ---
>   target/mips/tcg/ldst_helper.c | 57 +++++++++++++++++++++--------------
>   1 file changed, 35 insertions(+), 22 deletions(-)
> 
> diff --git a/target/mips/tcg/ldst_helper.c b/target/mips/tcg/ldst_helper.c
> index d42812b8a6a..97e7ad7d7a4 100644
> --- a/target/mips/tcg/ldst_helper.c
> +++ b/target/mips/tcg/ldst_helper.c
> @@ -52,31 +52,44 @@ HELPER_LD_ATOMIC(lld, ldq, 0x7, (target_ulong))
>   
>   #endif /* !CONFIG_USER_ONLY */
>   
> +static inline bool cpu_is_bigendian(CPUMIPSState *env)
> +{
> +    return extract32(env->CP0_Config0, CP0C0_BE, 1);
> +}
> +
>   #ifdef TARGET_WORDS_BIGENDIAN
>   #define GET_LMASK(v) ((v) & 3)
> -#define GET_OFFSET(addr, offset) (addr + (offset))
>   #else
>   #define GET_LMASK(v) (((v) & 3) ^ 3)
> -#define GET_OFFSET(addr, offset) (addr - (offset))
>   #endif
>   
> +static inline target_ulong get_offset(CPUMIPSState *env,
> +                                      target_ulong addr, int offset)
> +{
> +    if (cpu_is_bigendian(env)) {
> +        return addr + offset;
> +    } else {
> +        return addr - offset;
> +    }
> +}
> +
>   void helper_swl(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
>                   int mem_idx)
>   {
>       cpu_stb_mmuidx_ra(env, arg2, (uint8_t)(arg1 >> 24), mem_idx, GETPC());
>   
>       if (GET_LMASK(arg2) <= 2) {
> -        cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, 1), (uint8_t)(arg1 >> 16),
> +        cpu_stb_mmuidx_ra(env, get_offset(env, arg2, 1), (uint8_t)(arg1 >> 16),
>                             mem_idx, GETPC());
>       }
>   
>       if (GET_LMASK(arg2) <= 1) {
> -        cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, 2), (uint8_t)(arg1 >> 8),
> +        cpu_stb_mmuidx_ra(env, get_offset(env, arg2, 2), (uint8_t)(arg1 >> 8),
>                             mem_idx, GETPC());

So... yes, this is an improvement, but it's now substituting a constant for a runtime 
variable many times over.  I think you should drop get_offset() entirely and replace it with

     int dir = cpu_is_bigendian(env) ? 1 : -1;

     stb(env, arg2 + 1 * dir, data);

     stb(env, arg2 + 2 * dir, data);

Alternately, bite the bullet and split the function(s) into two, explicitly endian 
versions: helper_swl_be, helper_swl_le, etc.


r~


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

* Re: [PATCH 2/5] target/mips: Replace GET_LMASK() macro by get_lmask(32) function
  2021-08-18 16:43 ` [PATCH 2/5] target/mips: Replace GET_LMASK() macro by get_lmask(32) function Philippe Mathieu-Daudé
@ 2021-08-18 17:09   ` Richard Henderson
  2021-08-18 21:30     ` Philippe Mathieu-Daudé
  0 siblings, 1 reply; 13+ messages in thread
From: Richard Henderson @ 2021-08-18 17:09 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel
  Cc: Thomas Huth, Aleksandar Rikalo, Aurelien Jarno

On 8/18/21 6:43 AM, Philippe Mathieu-Daudé wrote:
> -    if (GET_LMASK(arg2) <= 2) {
> +    if (get_lmask(env, arg2, 32) <= 2) {

Whatever you decide to do with respect to the previous patch, the result of get_lmask is 
constant across the function and should be computed only once.


r~


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

* Re: [PATCH 4/5] target/mips: Store CP0_Config0 in DisasContext
  2021-08-18 16:43 ` [PATCH 4/5] target/mips: Store CP0_Config0 in DisasContext Philippe Mathieu-Daudé
@ 2021-08-18 17:24   ` Richard Henderson
  0 siblings, 0 replies; 13+ messages in thread
From: Richard Henderson @ 2021-08-18 17:24 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel
  Cc: Thomas Huth, Aleksandar Rikalo, Aurelien Jarno

On 8/18/21 6:43 AM, Philippe Mathieu-Daudé wrote:
> Most TCG helpers only have access to a DisasContext pointer,
> not CPUMIPSState. Store a copy of CPUMIPSState::CP0_Config0
> in DisasContext so we can access it from TCG helpers.
> 
> Signed-off-by: Philippe Mathieu-Daudé<f4bug@amsat.org>
> ---
>   target/mips/tcg/translate.h | 1 +
>   target/mips/tcg/translate.c | 1 +
>   2 files changed, 2 insertions(+)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

r~


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

* Re: [PATCH 5/5] target/mips: Replace TARGET_WORDS_BIGENDIAN by cpu_is_bigendian()
  2021-08-18 16:43 ` [PATCH 5/5] target/mips: Replace TARGET_WORDS_BIGENDIAN by cpu_is_bigendian() Philippe Mathieu-Daudé
@ 2021-08-18 17:25   ` Richard Henderson
  0 siblings, 0 replies; 13+ messages in thread
From: Richard Henderson @ 2021-08-18 17:25 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel
  Cc: Thomas Huth, Aleksandar Rikalo, Aurelien Jarno

On 8/18/21 6:43 AM, Philippe Mathieu-Daudé wrote:
> Add the inlined cpu_is_bigendian() function in "translate.h".
> 
> Replace the TARGET_WORDS_BIGENDIAN #ifdef'ry by calls to
> cpu_is_bigendian().
> 
> Signed-off-by: Philippe Mathieu-Daudé<f4bug@amsat.org>
> ---
>   target/mips/tcg/translate.h              |  5 ++
>   target/mips/tcg/translate.c              | 70 ++++++++++++------------
>   target/mips/tcg/nanomips_translate.c.inc | 20 +++----
>   3 files changed, 50 insertions(+), 45 deletions(-)
> 

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

r~


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

* Re: [PATCH 2/5] target/mips: Replace GET_LMASK() macro by get_lmask(32) function
  2021-08-18 17:09   ` Richard Henderson
@ 2021-08-18 21:30     ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 13+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-08-18 21:30 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel
  Cc: Thomas Huth, Aleksandar Rikalo, Aurelien Jarno

On 8/18/21 7:09 PM, Richard Henderson wrote:
> On 8/18/21 6:43 AM, Philippe Mathieu-Daudé wrote:
>> -    if (GET_LMASK(arg2) <= 2) {
>> +    if (get_lmask(env, arg2, 32) <= 2) {
> 
> Whatever you decide to do with respect to the previous patch, the result
> of get_lmask is constant across the function and should be computed only
> once.

Oops I missed that, thanks.


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

* Re: [PATCH 1/5] target/mips: Replace GET_OFFSET() macro by get_offset() function
  2021-08-18 16:56   ` Richard Henderson
@ 2021-08-18 21:31     ` Philippe Mathieu-Daudé
  2021-08-18 22:29       ` Richard Henderson
  0 siblings, 1 reply; 13+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-08-18 21:31 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel
  Cc: Thomas Huth, Aleksandar Rikalo, Aurelien Jarno

On 8/18/21 6:56 PM, Richard Henderson wrote:
> On 8/18/21 6:43 AM, Philippe Mathieu-Daudé wrote:
>> The target endianess information is stored in the BigEndian
>> bit of the Config0 register in CP0.
>>
>> As a first step, replace the GET_OFFSET() macro by an inlined
>> get_offset() function, passing CPUMIPSState as argument.
>>
>> Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
>> ---
>>   target/mips/tcg/ldst_helper.c | 57 +++++++++++++++++++++--------------
>>   1 file changed, 35 insertions(+), 22 deletions(-)
>>
>> diff --git a/target/mips/tcg/ldst_helper.c
>> b/target/mips/tcg/ldst_helper.c
>> index d42812b8a6a..97e7ad7d7a4 100644
>> --- a/target/mips/tcg/ldst_helper.c
>> +++ b/target/mips/tcg/ldst_helper.c
>> @@ -52,31 +52,44 @@ HELPER_LD_ATOMIC(lld, ldq, 0x7, (target_ulong))
>>     #endif /* !CONFIG_USER_ONLY */
>>   +static inline bool cpu_is_bigendian(CPUMIPSState *env)
>> +{
>> +    return extract32(env->CP0_Config0, CP0C0_BE, 1);
>> +}
>> +
>>   #ifdef TARGET_WORDS_BIGENDIAN
>>   #define GET_LMASK(v) ((v) & 3)
>> -#define GET_OFFSET(addr, offset) (addr + (offset))
>>   #else
>>   #define GET_LMASK(v) (((v) & 3) ^ 3)
>> -#define GET_OFFSET(addr, offset) (addr - (offset))
>>   #endif
>>   +static inline target_ulong get_offset(CPUMIPSState *env,
>> +                                      target_ulong addr, int offset)
>> +{
>> +    if (cpu_is_bigendian(env)) {
>> +        return addr + offset;
>> +    } else {
>> +        return addr - offset;
>> +    }
>> +}
>> +
>>   void helper_swl(CPUMIPSState *env, target_ulong arg1, target_ulong
>> arg2,
>>                   int mem_idx)
>>   {
>>       cpu_stb_mmuidx_ra(env, arg2, (uint8_t)(arg1 >> 24), mem_idx,
>> GETPC());
>>         if (GET_LMASK(arg2) <= 2) {
>> -        cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, 1), (uint8_t)(arg1 >>
>> 16),
>> +        cpu_stb_mmuidx_ra(env, get_offset(env, arg2, 1),
>> (uint8_t)(arg1 >> 16),
>>                             mem_idx, GETPC());
>>       }
>>         if (GET_LMASK(arg2) <= 1) {
>> -        cpu_stb_mmuidx_ra(env, GET_OFFSET(arg2, 2), (uint8_t)(arg1 >>
>> 8),
>> +        cpu_stb_mmuidx_ra(env, get_offset(env, arg2, 2),
>> (uint8_t)(arg1 >> 8),
>>                             mem_idx, GETPC());
> 
> So... yes, this is an improvement, but it's now substituting a constant
> for a runtime variable many times over.

Oops indeed.

>  I think you should drop
> get_offset() entirely and replace it with
> 
>     int dir = cpu_is_bigendian(env) ? 1 : -1;
> 
>     stb(env, arg2 + 1 * dir, data);
> 
>     stb(env, arg2 + 2 * dir, data);
> 
> Alternately, bite the bullet and split the function(s) into two,
> explicitly endian versions: helper_swl_be, helper_swl_le, etc.

I'll go for the easier path ;)


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

* Re: [PATCH 1/5] target/mips: Replace GET_OFFSET() macro by get_offset() function
  2021-08-18 21:31     ` Philippe Mathieu-Daudé
@ 2021-08-18 22:29       ` Richard Henderson
  0 siblings, 0 replies; 13+ messages in thread
From: Richard Henderson @ 2021-08-18 22:29 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel
  Cc: Thomas Huth, Aleksandar Rikalo, Aurelien Jarno

On 8/18/21 11:31 AM, Philippe Mathieu-Daudé wrote:
>>    I think you should drop
>> get_offset() entirely and replace it with
>>
>>      int dir = cpu_is_bigendian(env) ? 1 : -1;
>>
>>      stb(env, arg2 + 1 * dir, data);
>>
>>      stb(env, arg2 + 2 * dir, data);
>>
>> Alternately, bite the bullet and split the function(s) into two,
>> explicitly endian versions: helper_swl_be, helper_swl_le, etc.
> 
> I'll go for the easier path ;)

It's not really more difficult.

static inline void do_swl(env, uint32_t val, target_ulong addr, int midx,
                           int dir, unsigned lmask, uintptr_t ra)
{
     cpu_stb_mmuidx_ra(env, addr, val >> 24, midx, ra);

     if (lmask <= 2) {
         cpu_stb_mmuidx_ra(env, addr + 1 * dir, val >> 16, midx, ra);
     }
     if (lmask <= 1) {
         cpu_stb_mmuidx_ra(env, addr + 1 * dir, val >> 8, midx, ra);
     }
     if (lmask == 0) {
         cpu_stb_mmuidx_ra(env, addr + 1 * dir, val, midx, ra);
     }
}

void helper_swl_be(env, val, addr, midx)
{
     do_swl(env, val, addr, midx, 1, addr & 3, GETPC());
}

void helper_swl_le(env, val, addr, midx)
{
     do_swl(env, val, addr, midx, -1, ~addr & 3, GETPC());
}

Although I do wonder if this is strictly correct with respect to atomicity.  In my 
tcg/mips unaligned patch set, I assumed that lwl+lwr of an aligned address produces two 
atomic 32-bit loads, which result in a complete atomic load at the end.

Should we be doing something like

void helper_swl_be(env, val, addr, midx)
{
     uintptr_t ra = GETPC();

     switch (addr & 3) {
     case 0:
         cpu_stl_be_mmuidx_ra(env, val, addr, midx, ra);
         break;
     case 1:
         cpu_stb_mmuidx_ra(env, val >> 24, addr, midx, ra);
         cpu_stw_be_mmuidx_ra(env, val >> 16, addr + 1, midx, ra);
         break;
     case 2:
         cpu_stw_be_mmuidx_ra(env, val >> 16, addr, midx, ra);
         break;
     case 3:
         cpu_stb_mmuidx_ra(env, val >> 24, addr, midx, ra);
         break;
     }
}

void helper_swl_le(env, val, addr, midx)
{
     uintptr_t ra = GETPC();

     /*
      * We want to use stw and stl for atomicity, but want any
      * fault to report ADDR, not the aligned address.
      */
     probe_write(env, addr, 0, midx, ra);

     switch (addr & 3) {
     case 3:
         cpu_stl_le_mmuidx_ra(env, val, addr - 3, midx, ra);
         break;
     case 1:
         cpu_stw_le_mmuidx_ra(env, val >> 16, addr - 1, midx, ra);
         break;
     case 2:
         cpu_stw_le_mmuidx_ra(env, val >> 8, addr - 2, midx, ra);
         /* fall through */
     case 0:
         cpu_stb_mmuidx_ra(env, val >> 24, addr, midx, ra);
         break;
     }
}

etc.


r~


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

end of thread, other threads:[~2021-08-18 22:30 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-18 16:43 [PATCH 0/5] target/mips: Replace TARGET_WORDS_BIGENDIAN by cpu_is_bigendian() Philippe Mathieu-Daudé
2021-08-18 16:43 ` [PATCH 1/5] target/mips: Replace GET_OFFSET() macro by get_offset() function Philippe Mathieu-Daudé
2021-08-18 16:56   ` Richard Henderson
2021-08-18 21:31     ` Philippe Mathieu-Daudé
2021-08-18 22:29       ` Richard Henderson
2021-08-18 16:43 ` [PATCH 2/5] target/mips: Replace GET_LMASK() macro by get_lmask(32) function Philippe Mathieu-Daudé
2021-08-18 17:09   ` Richard Henderson
2021-08-18 21:30     ` Philippe Mathieu-Daudé
2021-08-18 16:43 ` [PATCH 3/5] target/mips: Replace GET_LMASK64() macro by get_lmask(64) function Philippe Mathieu-Daudé
2021-08-18 16:43 ` [PATCH 4/5] target/mips: Store CP0_Config0 in DisasContext Philippe Mathieu-Daudé
2021-08-18 17:24   ` Richard Henderson
2021-08-18 16:43 ` [PATCH 5/5] target/mips: Replace TARGET_WORDS_BIGENDIAN by cpu_is_bigendian() Philippe Mathieu-Daudé
2021-08-18 17:25   ` Richard Henderson

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.