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 493  
494 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 497 RETURN();
498 498 }
499 499  
500 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 503 RETURN();
504 504 }
505 505  
506 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 509 RETURN();
510 510 }
511 511  
... ... @@ -514,10 +514,9 @@ void op_rotr (void)
514 514 target_ulong tmp;
515 515  
516 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 520 RETURN();
522 521 }
523 522  
... ... @@ -707,8 +706,7 @@ void op_drotr (void)
707 706 if (T1) {
708 707 tmp = T0 << (0x40 - T1);
709 708 T0 = (T0 >> T1) | tmp;
710   - } else
711   - T0 = T1;
  709 + }
712 710 RETURN();
713 711 }
714 712  
... ... @@ -719,8 +717,7 @@ void op_drotr32 (void)
719 717 if (T1) {
720 718 tmp = T0 << (0x40 - (32 + T1));
721 719 T0 = (T0 >> (32 + T1)) | tmp;
722   - } else
723   - T0 = T1;
  720 + }
724 721 RETURN();
725 722 }
726 723  
... ...
target-mips/op_helper.c
... ... @@ -120,8 +120,7 @@ void do_drotr (void)
120 120 if (T1) {
121 121 tmp = T0 << (0x40 - T1);
122 122 T0 = (T0 >> T1) | tmp;
123   - } else
124   - T0 = T1;
  123 + }
125 124 }
126 125  
127 126 void do_drotr32 (void)
... ... @@ -131,8 +130,7 @@ void do_drotr32 (void)
131 130 if (T1) {
132 131 tmp = T0 << (0x40 - (32 + T1));
133 132 T0 = (T0 >> (32 + T1)) | tmp;
134   - } else
135   - T0 = T1;
  133 + }
136 134 }
137 135  
138 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 849 MIPS_DEBUG("NOP");
850 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 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 867 GEN_LOAD_REG_TN(T0, rs);
860 868 GEN_LOAD_IMM_TN(T1, uimm);
861   - } else {
862   - uimm = uimm << 16;
  869 + break;
  870 + case OPC_LUI:
  871 + uimm <<= 16;
863 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 890 switch (opc) {
866 891 case OPC_ADDI:
... ... @@ -915,13 +940,20 @@ static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
915 940 opn = "sra";
916 941 break;
917 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 945 gen_op_srl();
923 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 957 break;
926 958 #ifdef TARGET_MIPS64
927 959 case OPC_DSLL:
... ... @@ -933,13 +965,20 @@ static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
933 965 opn = "dsra";
934 966 break;
935 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 970 gen_op_dsrl();
941 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 982 break;
944 983 case OPC_DSLL32:
945 984 gen_op_dsll32();
... ... @@ -950,13 +989,20 @@ static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
950 989 opn = "dsra32";
951 990 break;
952 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 994 gen_op_dsrl32();
958 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 1006 break;
961 1007 #endif
962 1008 default:
... ... @@ -1068,13 +1114,20 @@ static void gen_arith (DisasContext *ctx, uint32_t opc,
1068 1114 opn = "srav";
1069 1115 break;
1070 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 1119 gen_op_srlv();
1076 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 1131 break;
1079 1132 #ifdef TARGET_MIPS64
1080 1133 case OPC_DSLLV:
... ... @@ -1086,13 +1139,20 @@ static void gen_arith (DisasContext *ctx, uint32_t opc,
1086 1139 opn = "dsrav";
1087 1140 break;
1088 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 1144 gen_op_dsrlv();
1094 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 1156 break;
1097 1157 #endif
1098 1158 default:
... ...