qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 1/5] target/mips: Replace GET_OFFSET() macro by get_offset()


From: Richard Henderson
Subject: Re: [PATCH 1/5] target/mips: Replace GET_OFFSET() macro by get_offset() function
Date: Wed, 18 Aug 2021 06:56:04 -1000
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.11.0

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~



reply via email to

[Prev in Thread] Current Thread [Next in Thread]