Commit c6d6dd7c74aaf8ca156d4589adff060078ec20ef

Authored by ths
1 parent 8c89395e

Fix MIPS64 R2 instructions.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3686 c046a42c-6fe2-441c-8c8c-71466251a162
target-mips/op.c
... ... @@ -683,8 +683,8 @@ void op_drotr (void)
683 683 target_ulong tmp;
684 684  
685 685 if (T1) {
686   - tmp = T0 << (0x40 - T1);
687   - T0 = (T0 >> T1) | tmp;
  686 + tmp = T0 << (0x40 - T1);
  687 + T0 = (T0 >> T1) | tmp;
688 688 }
689 689 FORCE_RET();
690 690 }
... ... @@ -693,10 +693,8 @@ void op_drotr32 (void)
693 693 {
694 694 target_ulong tmp;
695 695  
696   - if (T1) {
697   - tmp = T0 << (0x40 - (32 + T1));
698   - T0 = (T0 >> (32 + T1)) | tmp;
699   - }
  696 + tmp = T0 << (0x40 - (32 + T1));
  697 + T0 = (T0 >> (32 + T1)) | tmp;
700 698 FORCE_RET();
701 699 }
702 700  
... ... @@ -724,10 +722,10 @@ void op_drotrv (void)
724 722  
725 723 T0 &= 0x3F;
726 724 if (T0) {
727   - tmp = T1 << (0x40 - T0);
728   - T0 = (T1 >> T0) | tmp;
  725 + tmp = T1 << (0x40 - T0);
  726 + T0 = (T1 >> T0) | tmp;
729 727 } else
730   - T0 = T1;
  728 + T0 = T1;
731 729 FORCE_RET();
732 730 }
733 731  
... ... @@ -3091,7 +3089,7 @@ void op_ext(void)
3091 3089 unsigned int pos = PARAM1;
3092 3090 unsigned int size = PARAM2;
3093 3091  
3094   - T0 = ((uint32_t)T1 >> pos) & ((size < 32) ? ((1 << size) - 1) : ~0);
  3092 + T0 = (int32_t)((T1 >> pos) & ((size < 32) ? ((1 << size) - 1) : ~0));
3095 3093 FORCE_RET();
3096 3094 }
3097 3095  
... ... @@ -3101,13 +3099,13 @@ void op_ins(void)
3101 3099 unsigned int size = PARAM2;
3102 3100 target_ulong mask = ((size < 32) ? ((1 << size) - 1) : ~0) << pos;
3103 3101  
3104   - T0 = (T0 & ~mask) | (((uint32_t)T1 << pos) & mask);
  3102 + T0 = (int32_t)((T0 & ~mask) | ((T1 << pos) & mask));
3105 3103 FORCE_RET();
3106 3104 }
3107 3105  
3108 3106 void op_wsbh(void)
3109 3107 {
3110   - T0 = ((T1 << 8) & ~0x00FF00FF) | ((T1 >> 8) & 0x00FF00FF);
  3108 + T0 = (int32_t)(((T1 << 8) & ~0x00FF00FF) | ((T1 >> 8) & 0x00FF00FF));
3111 3109 FORCE_RET();
3112 3110 }
3113 3111  
... ... @@ -3117,7 +3115,7 @@ void op_dext(void)
3117 3115 unsigned int pos = PARAM1;
3118 3116 unsigned int size = PARAM2;
3119 3117  
3120   - T0 = (T1 >> pos) & ((size < 32) ? ((1 << size) - 1) : ~0);
  3118 + T0 = (T1 >> pos) & ((size < 64) ? ((1ULL << size) - 1) : ~0ULL);
3121 3119 FORCE_RET();
3122 3120 }
3123 3121  
... ... @@ -3125,7 +3123,7 @@ void op_dins(void)
3125 3123 {
3126 3124 unsigned int pos = PARAM1;
3127 3125 unsigned int size = PARAM2;
3128   - target_ulong mask = ((size < 32) ? ((1 << size) - 1) : ~0) << pos;
  3126 + target_ulong mask = ((size < 64) ? ((1ULL << size) - 1) : ~0ULL) << pos;
3129 3127  
3130 3128 T0 = (T0 & ~mask) | ((T1 << pos) & mask);
3131 3129 FORCE_RET();
... ... @@ -3139,7 +3137,8 @@ void op_dsbh(void)
3139 3137  
3140 3138 void op_dshd(void)
3141 3139 {
3142   - T0 = ((T1 << 16) & ~0x0000FFFF0000FFFFULL) | ((T1 >> 16) & 0x0000FFFF0000FFFFULL);
  3140 + T1 = ((T1 << 16) & ~0x0000FFFF0000FFFFULL) | ((T1 >> 16) & 0x0000FFFF0000FFFFULL);
  3141 + T0 = (T1 << 32) | (T1 >> 32);
3143 3142 FORCE_RET();
3144 3143 }
3145 3144 #endif
... ...
target-mips/op_helper.c
... ... @@ -106,8 +106,8 @@ void do_drotr (void)
106 106 target_ulong tmp;
107 107  
108 108 if (T1) {
109   - tmp = T0 << (0x40 - T1);
110   - T0 = (T0 >> T1) | tmp;
  109 + tmp = T0 << (0x40 - T1);
  110 + T0 = (T0 >> T1) | tmp;
111 111 }
112 112 }
113 113  
... ... @@ -115,10 +115,8 @@ void do_drotr32 (void)
115 115 {
116 116 target_ulong tmp;
117 117  
118   - if (T1) {
119   - tmp = T0 << (0x40 - (32 + T1));
120   - T0 = (T0 >> (32 + T1)) | tmp;
121   - }
  118 + tmp = T0 << (0x40 - (32 + T1));
  119 + T0 = (T0 >> (32 + T1)) | tmp;
122 120 }
123 121  
124 122 void do_dsllv (void)
... ... @@ -142,10 +140,10 @@ void do_drotrv (void)
142 140  
143 141 T0 &= 0x3F;
144 142 if (T0) {
145   - tmp = T1 << (0x40 - T0);
146   - T0 = (T1 >> T0) | tmp;
  143 + tmp = T1 << (0x40 - T0);
  144 + T0 = (T1 >> T0) | tmp;
147 145 } else
148   - T0 = T1;
  146 + T0 = T1;
149 147 }
150 148  
151 149 void do_dclo (void)
... ...
target-mips/translate.c
... ... @@ -1897,43 +1897,49 @@ static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
1897 1897 goto fail;
1898 1898 gen_op_ext(lsb, msb + 1);
1899 1899 break;
  1900 +#if defined(TARGET_MIPS64)
1900 1901 case OPC_DEXTM:
1901 1902 if (lsb + msb > 63)
1902 1903 goto fail;
1903   - gen_op_ext(lsb, msb + 1 + 32);
  1904 + gen_op_dext(lsb, msb + 1 + 32);
1904 1905 break;
1905 1906 case OPC_DEXTU:
1906 1907 if (lsb + msb > 63)
1907 1908 goto fail;
1908   - gen_op_ext(lsb + 32, msb + 1);
  1909 + gen_op_dext(lsb + 32, msb + 1);
1909 1910 break;
1910 1911 case OPC_DEXT:
1911   - gen_op_ext(lsb, msb + 1);
  1912 + if (lsb + msb > 63)
  1913 + goto fail;
  1914 + gen_op_dext(lsb, msb + 1);
1912 1915 break;
  1916 +#endif
1913 1917 case OPC_INS:
1914 1918 if (lsb > msb)
1915 1919 goto fail;
1916 1920 GEN_LOAD_REG_TN(T0, rt);
1917 1921 gen_op_ins(lsb, msb - lsb + 1);
1918 1922 break;
  1923 +#if defined(TARGET_MIPS64)
1919 1924 case OPC_DINSM:
1920 1925 if (lsb > msb)
1921 1926 goto fail;
1922 1927 GEN_LOAD_REG_TN(T0, rt);
1923   - gen_op_ins(lsb, msb - lsb + 1 + 32);
  1928 + gen_op_dins(lsb, msb - lsb + 1 + 32);
1924 1929 break;
1925 1930 case OPC_DINSU:
1926 1931 if (lsb > msb)
1927 1932 goto fail;
1928 1933 GEN_LOAD_REG_TN(T0, rt);
1929   - gen_op_ins(lsb + 32, msb - lsb + 1);
  1934 + gen_op_dins(lsb + 32, msb - lsb + 1);
1930 1935 break;
1931 1936 case OPC_DINS:
1932 1937 if (lsb > msb)
1933 1938 goto fail;
1934 1939 GEN_LOAD_REG_TN(T0, rt);
1935   - gen_op_ins(lsb, msb - lsb + 1);
  1940 + gen_op_dins(lsb, msb - lsb + 1);
1936 1941 break;
  1942 +#endif
1937 1943 default:
1938 1944 fail:
1939 1945 MIPS_INVAL("bitops");
... ... @@ -6156,6 +6162,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
6156 6162 break;
6157 6163 }
6158 6164 GEN_STORE_TN_REG(rd, T0);
  6165 + break;
6159 6166 #endif
6160 6167 default: /* Invalid */
6161 6168 MIPS_INVAL("special3");
... ...