Commit 5a63bcb2d27675a3fc2c5bc8a8c323e5c756e749

Authored by ths
1 parent acd858d9

Fix rotr immediate ops, mask shift/rotate arguments to their allowed

size.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2614 c046a42c-6fe2-441c-8c8c-71466251a162
target-mips/op.c
@@ -493,19 +493,19 @@ void op_xor (void) @@ -493,19 +493,19 @@ void op_xor (void)
493 493
494 void op_sll (void) 494 void op_sll (void)
495 { 495 {
496 - T0 = (int32_t)((uint32_t)T0 << (uint32_t)T1); 496 + T0 = (int32_t)((uint32_t)T0 << T1);
497 RETURN(); 497 RETURN();
498 } 498 }
499 499
500 void op_sra (void) 500 void op_sra (void)
501 { 501 {
502 - T0 = (int32_t)((int32_t)T0 >> (uint32_t)T1); 502 + T0 = (int32_t)((int32_t)T0 >> T1);
503 RETURN(); 503 RETURN();
504 } 504 }
505 505
506 void op_srl (void) 506 void op_srl (void)
507 { 507 {
508 - T0 = (int32_t)((uint32_t)T0 >> (uint32_t)T1); 508 + T0 = (int32_t)((uint32_t)T0 >> T1);
509 RETURN(); 509 RETURN();
510 } 510 }
511 511
@@ -514,10 +514,9 @@ void op_rotr (void) @@ -514,10 +514,9 @@ void op_rotr (void)
514 target_ulong tmp; 514 target_ulong tmp;
515 515
516 if (T1) { 516 if (T1) {
517 - tmp = (int32_t)((uint32_t)T0 << (0x20 - (uint32_t)T1));  
518 - T0 = (int32_t)((uint32_t)T0 >> (uint32_t)T1) | tmp;  
519 - } else  
520 - T0 = T1; 517 + tmp = (int32_t)((uint32_t)T0 << (0x20 - T1));
  518 + T0 = (int32_t)((uint32_t)T0 >> T1) | tmp;
  519 + }
521 RETURN(); 520 RETURN();
522 } 521 }
523 522
@@ -707,8 +706,7 @@ void op_drotr (void) @@ -707,8 +706,7 @@ void op_drotr (void)
707 if (T1) { 706 if (T1) {
708 tmp = T0 << (0x40 - T1); 707 tmp = T0 << (0x40 - T1);
709 T0 = (T0 >> T1) | tmp; 708 T0 = (T0 >> T1) | tmp;
710 - } else  
711 - T0 = T1; 709 + }
712 RETURN(); 710 RETURN();
713 } 711 }
714 712
@@ -719,8 +717,7 @@ void op_drotr32 (void) @@ -719,8 +717,7 @@ void op_drotr32 (void)
719 if (T1) { 717 if (T1) {
720 tmp = T0 << (0x40 - (32 + T1)); 718 tmp = T0 << (0x40 - (32 + T1));
721 T0 = (T0 >> (32 + T1)) | tmp; 719 T0 = (T0 >> (32 + T1)) | tmp;
722 - } else  
723 - T0 = T1; 720 + }
724 RETURN(); 721 RETURN();
725 } 722 }
726 723
target-mips/op_helper.c
@@ -120,8 +120,7 @@ void do_drotr (void) @@ -120,8 +120,7 @@ void do_drotr (void)
120 if (T1) { 120 if (T1) {
121 tmp = T0 << (0x40 - T1); 121 tmp = T0 << (0x40 - T1);
122 T0 = (T0 >> T1) | tmp; 122 T0 = (T0 >> T1) | tmp;
123 - } else  
124 - T0 = T1; 123 + }
125 } 124 }
126 125
127 void do_drotr32 (void) 126 void do_drotr32 (void)
@@ -131,8 +130,7 @@ void do_drotr32 (void) @@ -131,8 +130,7 @@ void do_drotr32 (void)
131 if (T1) { 130 if (T1) {
132 tmp = T0 << (0x40 - (32 + T1)); 131 tmp = T0 << (0x40 - (32 + T1));
133 T0 = (T0 >> (32 + T1)) | tmp; 132 T0 = (T0 >> (32 + T1)) | tmp;
134 - } else  
135 - T0 = T1; 133 + }
136 } 134 }
137 135
138 void do_dsllv (void) 136 void do_dsllv (void)
target-mips/translate.c
@@ -849,18 +849,43 @@ static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt, @@ -849,18 +849,43 @@ static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
849 MIPS_DEBUG("NOP"); 849 MIPS_DEBUG("NOP");
850 return; 850 return;
851 } 851 }
852 - if (opc == OPC_ADDI || opc == OPC_ADDIU ||  
853 - opc == OPC_DADDI || opc == OPC_DADDIU ||  
854 - opc == OPC_SLTI || opc == OPC_SLTIU) 852 + uimm = (uint16_t)imm;
  853 + switch (opc) {
  854 + case OPC_ADDI:
  855 + case OPC_ADDIU:
  856 +#ifdef TARGET_MIPS64
  857 + case OPC_DADDI:
  858 + case OPC_DADDIU:
  859 +#endif
  860 + case OPC_SLTI:
  861 + case OPC_SLTIU:
855 uimm = (int32_t)imm; /* Sign extend to 32 bits */ 862 uimm = (int32_t)imm; /* Sign extend to 32 bits */
856 - else  
857 - uimm = (uint16_t)imm;  
858 - if (opc != OPC_LUI) { 863 + /* Fall through. */
  864 + case OPC_ANDI:
  865 + case OPC_ORI:
  866 + case OPC_XORI:
859 GEN_LOAD_REG_TN(T0, rs); 867 GEN_LOAD_REG_TN(T0, rs);
860 GEN_LOAD_IMM_TN(T1, uimm); 868 GEN_LOAD_IMM_TN(T1, uimm);
861 - } else {  
862 - uimm = uimm << 16; 869 + break;
  870 + case OPC_LUI:
  871 + uimm <<= 16;
863 GEN_LOAD_IMM_TN(T0, uimm); 872 GEN_LOAD_IMM_TN(T0, uimm);
  873 + break;
  874 + case OPC_SLL:
  875 + case OPC_SRA:
  876 + case OPC_SRL:
  877 +#ifdef TARGET_MIPS64
  878 + case OPC_DSLL:
  879 + case OPC_DSRA:
  880 + case OPC_DSRL:
  881 + case OPC_DSLL32:
  882 + case OPC_DSRA32:
  883 + case OPC_DSRL32:
  884 +#endif
  885 + uimm &= 0x1f;
  886 + GEN_LOAD_REG_TN(T0, rs);
  887 + GEN_LOAD_IMM_TN(T1, uimm);
  888 + break;
864 } 889 }
865 switch (opc) { 890 switch (opc) {
866 case OPC_ADDI: 891 case OPC_ADDI:
@@ -915,13 +940,20 @@ static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt, @@ -915,13 +940,20 @@ static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
915 opn = "sra"; 940 opn = "sra";
916 break; 941 break;
917 case OPC_SRL: 942 case OPC_SRL:
918 - if ((ctx->opcode >> 21) & 1) {  
919 - gen_op_rotr();  
920 - opn = "rotr";  
921 - } else { 943 + switch ((ctx->opcode >> 21) & 0x1f) {
  944 + case 0:
922 gen_op_srl(); 945 gen_op_srl();
923 opn = "srl"; 946 opn = "srl";
924 - } 947 + break;
  948 + case 1:
  949 + gen_op_rotr();
  950 + opn = "rotr";
  951 + break;
  952 + default:
  953 + MIPS_INVAL("invalid srl flag");
  954 + generate_exception(ctx, EXCP_RI);
  955 + break;
  956 + }
925 break; 957 break;
926 #ifdef TARGET_MIPS64 958 #ifdef TARGET_MIPS64
927 case OPC_DSLL: 959 case OPC_DSLL:
@@ -933,13 +965,20 @@ static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt, @@ -933,13 +965,20 @@ static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
933 opn = "dsra"; 965 opn = "dsra";
934 break; 966 break;
935 case OPC_DSRL: 967 case OPC_DSRL:
936 - if ((ctx->opcode >> 21) & 1) {  
937 - gen_op_drotr();  
938 - opn = "drotr";  
939 - } else { 968 + switch ((ctx->opcode >> 21) & 0x1f) {
  969 + case 0:
940 gen_op_dsrl(); 970 gen_op_dsrl();
941 opn = "dsrl"; 971 opn = "dsrl";
942 - } 972 + break;
  973 + case 1:
  974 + gen_op_drotr();
  975 + opn = "drotr";
  976 + break;
  977 + default:
  978 + MIPS_INVAL("invalid dsrl flag");
  979 + generate_exception(ctx, EXCP_RI);
  980 + break;
  981 + }
943 break; 982 break;
944 case OPC_DSLL32: 983 case OPC_DSLL32:
945 gen_op_dsll32(); 984 gen_op_dsll32();
@@ -950,13 +989,20 @@ static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt, @@ -950,13 +989,20 @@ static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
950 opn = "dsra32"; 989 opn = "dsra32";
951 break; 990 break;
952 case OPC_DSRL32: 991 case OPC_DSRL32:
953 - if ((ctx->opcode >> 21) & 1) {  
954 - gen_op_drotr32();  
955 - opn = "drotr32";  
956 - } else { 992 + switch ((ctx->opcode >> 21) & 0x1f) {
  993 + case 0:
957 gen_op_dsrl32(); 994 gen_op_dsrl32();
958 opn = "dsrl32"; 995 opn = "dsrl32";
959 - } 996 + break;
  997 + case 1:
  998 + gen_op_drotr32();
  999 + opn = "drotr32";
  1000 + break;
  1001 + default:
  1002 + MIPS_INVAL("invalid dsrl32 flag");
  1003 + generate_exception(ctx, EXCP_RI);
  1004 + break;
  1005 + }
960 break; 1006 break;
961 #endif 1007 #endif
962 default: 1008 default:
@@ -1068,13 +1114,20 @@ static void gen_arith (DisasContext *ctx, uint32_t opc, @@ -1068,13 +1114,20 @@ static void gen_arith (DisasContext *ctx, uint32_t opc,
1068 opn = "srav"; 1114 opn = "srav";
1069 break; 1115 break;
1070 case OPC_SRLV: 1116 case OPC_SRLV:
1071 - if ((ctx->opcode >> 6) & 1) {  
1072 - gen_op_rotrv();  
1073 - opn = "rotrv";  
1074 - } else { 1117 + switch ((ctx->opcode >> 6) & 0x1f) {
  1118 + case 0:
1075 gen_op_srlv(); 1119 gen_op_srlv();
1076 opn = "srlv"; 1120 opn = "srlv";
1077 - } 1121 + break;
  1122 + case 1:
  1123 + gen_op_rotrv();
  1124 + opn = "rotrv";
  1125 + break;
  1126 + default:
  1127 + MIPS_INVAL("invalid srlv flag");
  1128 + generate_exception(ctx, EXCP_RI);
  1129 + break;
  1130 + }
1078 break; 1131 break;
1079 #ifdef TARGET_MIPS64 1132 #ifdef TARGET_MIPS64
1080 case OPC_DSLLV: 1133 case OPC_DSLLV:
@@ -1086,13 +1139,20 @@ static void gen_arith (DisasContext *ctx, uint32_t opc, @@ -1086,13 +1139,20 @@ static void gen_arith (DisasContext *ctx, uint32_t opc,
1086 opn = "dsrav"; 1139 opn = "dsrav";
1087 break; 1140 break;
1088 case OPC_DSRLV: 1141 case OPC_DSRLV:
1089 - if ((ctx->opcode >> 6) & 1) {  
1090 - gen_op_drotrv();  
1091 - opn = "drotrv";  
1092 - } else { 1142 + switch ((ctx->opcode >> 6) & 0x1f) {
  1143 + case 0:
1093 gen_op_dsrlv(); 1144 gen_op_dsrlv();
1094 opn = "dsrlv"; 1145 opn = "dsrlv";
1095 - } 1146 + break;
  1147 + case 1:
  1148 + gen_op_drotrv();
  1149 + opn = "drotrv";
  1150 + break;
  1151 + default:
  1152 + MIPS_INVAL("invalid dsrlv flag");
  1153 + generate_exception(ctx, EXCP_RI);
  1154 + break;
  1155 + }
1096 break; 1156 break;
1097 #endif 1157 #endif
1098 default: 1158 default: