Commit c6d6dd7c74aaf8ca156d4589adff060078ec20ef
1 parent
8c89395e
Fix MIPS64 R2 instructions.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3686 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
34 additions
and
30 deletions
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"); | ... | ... |