linux-mips
[Top] [All Lists]

Re: [PATCH 06/15] mips: clear upper bits of FP registers on emulator wri

To: Paul Burton <paul.burton@imgtec.com>, linux-mips@linux-mips.org
Subject: Re: [PATCH 06/15] mips: clear upper bits of FP registers on emulator writes
From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Date: Mon, 27 Jan 2014 21:06:52 +0300
In-reply-to: <1390836194-26286-7-git-send-email-paul.burton@imgtec.com>
List-archive: <http://www.linux-mips.org/archives/linux-mips/>
List-help: <mailto:ecartis@linux-mips.org?Subject=help>
List-id: linux-mips <linux-mips.eddie.linux-mips.org>
List-owner: <mailto:ralf@linux-mips.org>
List-post: <mailto:linux-mips@linux-mips.org>
List-software: Ecartis version 1.0.0
List-subscribe: <mailto:ecartis@linux-mips.org?subject=subscribe%20linux-mips>
List-unsubscribe: <mailto:ecartis@linux-mips.org?subject=unsubscribe%20linux-mips>
Organization: Cogent Embedded
Original-recipient: rfc822;linux-mips@linux-mips.org
References: <1390836194-26286-1-git-send-email-paul.burton@imgtec.com> <1390836194-26286-7-git-send-email-paul.burton@imgtec.com>
Sender: linux-mips-bounce@linux-mips.org
User-agent: Mozilla/5.0 (X11; Linux i686; rv:24.0) Gecko/20100101 Thunderbird/24.2.0
Hello.

On 01/27/2014 06:23 PM, Paul Burton wrote:

The upper bits of an FP register are architecturally defined as
unpredictable following an instructions which only writes the lower
bits. The prior behaviour of the kernel is to leave them unmodified.
This patch modifies that to clear the upper bits to zero. This is what
the MSA architecture reference manual specifies should happen for its
wider registers and is still permissible for scalar FP instructions
given the bits unpredictability there.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
---
  arch/mips/math-emu/cp1emu.c | 25 ++++++++++++++++++++-----
  1 file changed, 20 insertions(+), 5 deletions(-)

diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c
index 9144842..c484f5f 100644
--- a/arch/mips/math-emu/cp1emu.c
+++ b/arch/mips/math-emu/cp1emu.c
@@ -884,20 +884,35 @@ static inline int cop1_64bit(struct pt_regs *xcp)
  } while (0)

  #define SITOREG(si, x) do {                                           \
-       if (cop1_64bit(xcp))                                            \
+       if (cop1_64bit(xcp)) {                                          \
+               unsigned i;                                             \
                set_fpr32(&ctx->fpr[x], 0, si);                          \
-       else                                                            \
+               for (i = 1; i < ARRAY_SIZE(ctx->fpr[x].val32); i++)       \
+                       set_fpr32(&ctx->fpr[x], i, 0);                   \
+       } else {                                                        \
                set_fpr32(&ctx->fpr[(x) & ~1], (x) & 1, si);             \
+       }                                                               \
  } while (0)

  #define SIFROMHREG(si, x)     ((si) = get_fpr32(&ctx->fpr[x], 1))
-#define SITOHREG(si, x)                set_fpr32(&ctx->fpr[x], 1, si)
+
+#define SITOHREG(si, x) do {                                           \
+       unsigned i;                                                     \
+       set_fpr32(&ctx->fpr[x], 1, si);                                  \
+       for (i = 2; i < ARRAY_SIZE(ctx->fpr[x].val32); i++)               \
+                       set_fpr32(&ctx->fpr[x], i, 0);                   \

   This line is over-indented, no? Compare the loop below...

+} while (0)

  #define DIFROMREG(di, x) \
        ((di) = get_fpr64(&ctx->fpr[(x) & ~(cop1_64bit(xcp) == 0)], 0))

-#define DITOREG(di, x) \
-       set_fpr64(&ctx->fpr[(x) & ~(cop1_64bit(xcp) == 0)], 0, di)
+#define DITOREG(di, x) do {                                            \
+       unsigned fpr, i;                                                \
+       fpr = (x) & ~(cop1_64bit(xcp) == 0);                                \
+       set_fpr64(&ctx->fpr[fpr], 0, di);                                \
+       for (i = 1; i < ARRAY_SIZE(ctx->fpr[x].val64); i++)               \
+               set_fpr64(&ctx->fpr[fpr], i, 0);                 \
+} while (0)

WBR, Sergei


<Prev in Thread] Current Thread [Next in Thread>