Fix rotr immediate ops, mask shift/rotate arguments to their allowed
authorths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>
Thu, 5 Apr 2007 23:20:05 +0000 (23:20 +0000)
committerths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>
Thu, 5 Apr 2007 23:20:05 +0000 (23:20 +0000)
size.

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2614 c046a42c-6fe2-441c-8c8c-71466251a162

target-mips/op.c
target-mips/op_helper.c
target-mips/translate.c

index d09b8da..d440896 100644 (file)
@@ -493,19 +493,19 @@ void op_xor (void)
 
 void op_sll (void)
 {
-    T0 = (int32_t)((uint32_t)T0 << (uint32_t)T1);
+    T0 = (int32_t)((uint32_t)T0 << T1);
     RETURN();
 }
 
 void op_sra (void)
 {
-    T0 = (int32_t)((int32_t)T0 >> (uint32_t)T1);
+    T0 = (int32_t)((int32_t)T0 >> T1);
     RETURN();
 }
 
 void op_srl (void)
 {
-    T0 = (int32_t)((uint32_t)T0 >> (uint32_t)T1);
+    T0 = (int32_t)((uint32_t)T0 >> T1);
     RETURN();
 }
 
@@ -514,10 +514,9 @@ void op_rotr (void)
     target_ulong tmp;
 
     if (T1) {
-       tmp = (int32_t)((uint32_t)T0 << (0x20 - (uint32_t)T1));
-       T0 = (int32_t)((uint32_t)T0 >> (uint32_t)T1) | tmp;
-    } else
-       T0 = T1;
+       tmp = (int32_t)((uint32_t)T0 << (0x20 - T1));
+       T0 = (int32_t)((uint32_t)T0 >> T1) | tmp;
+    }
     RETURN();
 }
 
@@ -707,8 +706,7 @@ void op_drotr (void)
     if (T1) {
        tmp = T0 << (0x40 - T1);
        T0 = (T0 >> T1) | tmp;
-    } else
-       T0 = T1;
+    }
     RETURN();
 }
 
@@ -719,8 +717,7 @@ void op_drotr32 (void)
     if (T1) {
        tmp = T0 << (0x40 - (32 + T1));
        T0 = (T0 >> (32 + T1)) | tmp;
-    } else
-       T0 = T1;
+    }
     RETURN();
 }
 
index 7b6442e..ba02f0d 100644 (file)
@@ -120,8 +120,7 @@ void do_drotr (void)
     if (T1) {
        tmp = T0 << (0x40 - T1);
        T0 = (T0 >> T1) | tmp;
-    } else
-       T0 = T1;
+    }
 }
 
 void do_drotr32 (void)
@@ -131,8 +130,7 @@ void do_drotr32 (void)
     if (T1) {
        tmp = T0 << (0x40 - (32 + T1));
        T0 = (T0 >> (32 + T1)) | tmp;
-    } else
-       T0 = T1;
+    }
 }
 
 void do_dsllv (void)
index 816b91e..7b7c464 100644 (file)
@@ -849,18 +849,43 @@ static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
         MIPS_DEBUG("NOP");
         return;
     }
-    if (opc == OPC_ADDI || opc == OPC_ADDIU ||
-        opc == OPC_DADDI || opc == OPC_DADDIU ||
-        opc == OPC_SLTI || opc == OPC_SLTIU)
+    uimm = (uint16_t)imm;
+    switch (opc) {
+    case OPC_ADDI:
+    case OPC_ADDIU:
+#ifdef TARGET_MIPS64
+    case OPC_DADDI:
+    case OPC_DADDIU:
+#endif
+    case OPC_SLTI:
+    case OPC_SLTIU:
         uimm = (int32_t)imm; /* Sign extend to 32 bits */
-    else
-        uimm = (uint16_t)imm;
-    if (opc != OPC_LUI) {
+        /* Fall through. */
+    case OPC_ANDI:
+    case OPC_ORI:
+    case OPC_XORI:
         GEN_LOAD_REG_TN(T0, rs);
         GEN_LOAD_IMM_TN(T1, uimm);
-    } else {
-        uimm = uimm << 16;
+        break;
+    case OPC_LUI:
+        uimm <<= 16;
         GEN_LOAD_IMM_TN(T0, uimm);
+        break;
+    case OPC_SLL:
+    case OPC_SRA:
+    case OPC_SRL:
+#ifdef TARGET_MIPS64
+    case OPC_DSLL:
+    case OPC_DSRA:
+    case OPC_DSRL:
+    case OPC_DSLL32:
+    case OPC_DSRA32:
+    case OPC_DSRL32:
+#endif
+        uimm &= 0x1f;
+        GEN_LOAD_REG_TN(T0, rs);
+        GEN_LOAD_IMM_TN(T1, uimm);
+        break;
     }
     switch (opc) {
     case OPC_ADDI:
@@ -915,13 +940,20 @@ static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
         opn = "sra";
         break;
     case OPC_SRL:
-       if ((ctx->opcode >> 21) & 1) {
-            gen_op_rotr();
-            opn = "rotr";
-       } else {
+        switch ((ctx->opcode >> 21) & 0x1f) {
+        case 0:
             gen_op_srl();
             opn = "srl";
-       }
+            break;
+        case 1:
+            gen_op_rotr();
+            opn = "rotr";
+            break;
+        default:
+            MIPS_INVAL("invalid srl flag");
+            generate_exception(ctx, EXCP_RI);
+            break;
+        }
         break;
 #ifdef TARGET_MIPS64
     case OPC_DSLL:
@@ -933,13 +965,20 @@ static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
         opn = "dsra";
         break;
     case OPC_DSRL:
-       if ((ctx->opcode >> 21) & 1) {
-            gen_op_drotr();
-            opn = "drotr";
-       } else {
+        switch ((ctx->opcode >> 21) & 0x1f) {
+        case 0:
             gen_op_dsrl();
             opn = "dsrl";
-       }
+            break;
+        case 1:
+            gen_op_drotr();
+            opn = "drotr";
+            break;
+        default:
+            MIPS_INVAL("invalid dsrl flag");
+            generate_exception(ctx, EXCP_RI);
+            break;
+        }
         break;
     case OPC_DSLL32:
         gen_op_dsll32();
@@ -950,13 +989,20 @@ static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
         opn = "dsra32";
         break;
     case OPC_DSRL32:
-       if ((ctx->opcode >> 21) & 1) {
-            gen_op_drotr32();
-            opn = "drotr32";
-       } else {
+        switch ((ctx->opcode >> 21) & 0x1f) {
+        case 0:
             gen_op_dsrl32();
             opn = "dsrl32";
-       }
+            break;
+        case 1:
+            gen_op_drotr32();
+            opn = "drotr32";
+            break;
+        default:
+            MIPS_INVAL("invalid dsrl32 flag");
+            generate_exception(ctx, EXCP_RI);
+            break;
+        }
         break;
 #endif
     default:
@@ -1068,13 +1114,20 @@ static void gen_arith (DisasContext *ctx, uint32_t opc,
         opn = "srav";
         break;
     case OPC_SRLV:
-       if ((ctx->opcode >> 6) & 1) {
-            gen_op_rotrv();
-            opn = "rotrv";
-       } else {
+        switch ((ctx->opcode >> 6) & 0x1f) {
+        case 0:
             gen_op_srlv();
             opn = "srlv";
-       }
+            break;
+        case 1:
+            gen_op_rotrv();
+            opn = "rotrv";
+            break;
+        default:
+            MIPS_INVAL("invalid srlv flag");
+            generate_exception(ctx, EXCP_RI);
+            break;
+        }
         break;
 #ifdef TARGET_MIPS64
     case OPC_DSLLV:
@@ -1086,13 +1139,20 @@ static void gen_arith (DisasContext *ctx, uint32_t opc,
         opn = "dsrav";
         break;
     case OPC_DSRLV:
-       if ((ctx->opcode >> 6) & 1) {
-            gen_op_drotrv();
-            opn = "drotrv";
-       } else {
+        switch ((ctx->opcode >> 6) & 0x1f) {
+        case 0:
             gen_op_dsrlv();
             opn = "dsrlv";
-       }
+            break;
+        case 1:
+            gen_op_drotrv();
+            opn = "drotrv";
+            break;
+        default:
+            MIPS_INVAL("invalid dsrlv flag");
+            generate_exception(ctx, EXCP_RI);
+            break;
+        }
         break;
 #endif
     default: