Browse Source

target-mips: allow microMIPS SWP and SDP to have RD equal to BASE

The microMIPS SWP and SDP instructions do not modify GPRs.  So their
behavior is well defined when RD equals BASE.  The MIPS Architecture
Verification Programs (AVPs) check that they work as expected.  This
is required for AVPs to pass.

Signed-off-by: Eric Johnson <ericj@mips.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
(cherry picked from commit 36c6711bbe79642b0102416a9dd4243505e874a6)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Eric Johnson 14 years ago
parent
commit
849c865155
1 changed files with 9 additions and 1 deletions
  1. 9 1
      target-mips/translate.c

+ 9 - 1
target-mips/translate.c

@@ -10031,7 +10031,7 @@ static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
     const char *opn = "ldst_pair";
     const char *opn = "ldst_pair";
     TCGv t0, t1;
     TCGv t0, t1;
 
 
-    if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31 || rd == base) {
+    if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
         generate_exception(ctx, EXCP_RI);
         generate_exception(ctx, EXCP_RI);
         return;
         return;
     }
     }
@@ -10043,6 +10043,10 @@ static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
 
 
     switch (opc) {
     switch (opc) {
     case LWP:
     case LWP:
+        if (rd == base) {
+            generate_exception(ctx, EXCP_RI);
+            return;
+        }
         save_cpu_state(ctx, 0);
         save_cpu_state(ctx, 0);
         op_ld_lw(t1, t0, ctx);
         op_ld_lw(t1, t0, ctx);
         gen_store_gpr(t1, rd);
         gen_store_gpr(t1, rd);
@@ -10064,6 +10068,10 @@ static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
         break;
         break;
 #ifdef TARGET_MIPS64
 #ifdef TARGET_MIPS64
     case LDP:
     case LDP:
+        if (rd == base) {
+            generate_exception(ctx, EXCP_RI);
+            return;
+        }
         save_cpu_state(ctx, 0);
         save_cpu_state(ctx, 0);
         op_ld_ld(t1, t0, ctx);
         op_ld_ld(t1, t0, ctx);
         gen_store_gpr(t1, rd);
         gen_store_gpr(t1, rd);