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"); | ... | ... |