Commit c3e10c7b4377c1cbc0a4fbc12312c2cf41c0cda7

Authored by j_mayer
1 parent a76dc35a

Optimize PowerPC overflow flag computation in most useful cases.

Use the same routines to check overflow for addo, subfo and PowerPC 405
  multiply and add cases.
Fix carry reset in addme(o) and subfme(o) cases.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3574 c046a42c-6fe2-441c-8c8c-71466251a162
target-ppc/op.c
... ... @@ -191,6 +191,12 @@ void OPPROTO op_move_T2_T0 (void)
191 191 RETURN();
192 192 }
193 193  
  194 +void OPPROTO op_moven_T2_T0 (void)
  195 +{
  196 + T2 = ~T0;
  197 + RETURN();
  198 +}
  199 +
194 200 /* Generate exceptions */
195 201 void OPPROTO op_raise_exception_err (void)
196 202 {
... ... @@ -847,26 +853,18 @@ void OPPROTO op_add (void)
847 853  
848 854 void OPPROTO op_check_addo (void)
849 855 {
850   - if (likely(!(((uint32_t)T2 ^ (uint32_t)T1 ^ UINT32_MAX) &
851   - ((uint32_t)T2 ^ (uint32_t)T0) & (1UL << 31)))) {
852   - xer_ov = 0;
853   - } else {
854   - xer_ov = 1;
855   - xer_so = 1;
856   - }
  856 + xer_ov = (((uint32_t)T2 ^ (uint32_t)T1 ^ UINT32_MAX) &
  857 + ((uint32_t)T2 ^ (uint32_t)T0)) >> 31;
  858 + xer_so |= xer_ov;
857 859 RETURN();
858 860 }
859 861  
860 862 #if defined(TARGET_PPC64)
861 863 void OPPROTO op_check_addo_64 (void)
862 864 {
863   - if (likely(!(((uint64_t)T2 ^ (uint64_t)T1 ^ UINT64_MAX) &
864   - ((uint64_t)T2 ^ (uint64_t)T0) & (1ULL << 63)))) {
865   - xer_ov = 0;
866   - } else {
867   - xer_ov = 1;
868   - xer_so = 1;
869   - }
  865 + xer_ov = (((uint64_t)T2 ^ (uint64_t)T1 ^ UINT64_MAX) &
  866 + ((uint64_t)T2 ^ (uint64_t)T0)) >> 63;
  867 + xer_so |= xer_ov;
870 868 RETURN();
871 869 }
872 870 #endif
... ... @@ -922,6 +920,8 @@ void OPPROTO op_add_me (void)
922 920 T0 += xer_ca + (-1);
923 921 if (likely((uint32_t)T1 != 0))
924 922 xer_ca = 1;
  923 + else
  924 + xer_ca = 0;
925 925 RETURN();
926 926 }
927 927  
... ... @@ -931,6 +931,8 @@ void OPPROTO op_add_me_64 (void)
931 931 T0 += xer_ca + (-1);
932 932 if (likely((uint64_t)T1 != 0))
933 933 xer_ca = 1;
  934 + else
  935 + xer_ca = 0;
934 936 RETURN();
935 937 }
936 938 #endif
... ... @@ -1142,32 +1144,6 @@ void OPPROTO op_subf (void)
1142 1144 RETURN();
1143 1145 }
1144 1146  
1145   -void OPPROTO op_check_subfo (void)
1146   -{
1147   - if (likely(!(((uint32_t)(~T2) ^ (uint32_t)T1 ^ UINT32_MAX) &
1148   - ((uint32_t)(~T2) ^ (uint32_t)T0) & (1UL << 31)))) {
1149   - xer_ov = 0;
1150   - } else {
1151   - xer_ov = 1;
1152   - xer_so = 1;
1153   - }
1154   - RETURN();
1155   -}
1156   -
1157   -#if defined(TARGET_PPC64)
1158   -void OPPROTO op_check_subfo_64 (void)
1159   -{
1160   - if (likely(!(((uint64_t)(~T2) ^ (uint64_t)T1 ^ UINT64_MAX) &
1161   - ((uint64_t)(~T2) ^ (uint64_t)T0) & (1ULL << 63)))) {
1162   - xer_ov = 0;
1163   - } else {
1164   - xer_ov = 1;
1165   - xer_so = 1;
1166   - }
1167   - RETURN();
1168   -}
1169   -#endif
1170   -
1171 1147 /* subtract from carrying */
1172 1148 void OPPROTO op_check_subfc (void)
1173 1149 {
... ... @@ -1235,8 +1211,10 @@ void OPPROTO op_subfic_64 (void)
1235 1211 void OPPROTO op_subfme (void)
1236 1212 {
1237 1213 T0 = ~T0 + xer_ca - 1;
1238   - if (likely((uint32_t)T0 != (uint32_t)-1))
  1214 + if (likely((uint32_t)T0 != UINT32_MAX))
1239 1215 xer_ca = 1;
  1216 + else
  1217 + xer_ca = 0;
1240 1218 RETURN();
1241 1219 }
1242 1220  
... ... @@ -1244,8 +1222,10 @@ void OPPROTO op_subfme (void)
1244 1222 void OPPROTO op_subfme_64 (void)
1245 1223 {
1246 1224 T0 = ~T0 + xer_ca - 1;
1247   - if (likely((uint64_t)T0 != (uint64_t)-1))
  1225 + if (likely((uint64_t)T0 != UINT64_MAX))
1248 1226 xer_ca = 1;
  1227 + else
  1228 + xer_ca = 0;
1249 1229 RETURN();
1250 1230 }
1251 1231 #endif
... ... @@ -2528,12 +2508,6 @@ void OPPROTO op_405_mullhwu (void)
2528 2508 RETURN();
2529 2509 }
2530 2510  
2531   -void OPPROTO op_405_check_ov (void)
2532   -{
2533   - do_405_check_ov();
2534   - RETURN();
2535   -}
2536   -
2537 2511 void OPPROTO op_405_check_sat (void)
2538 2512 {
2539 2513 do_405_check_sat();
... ...
target-ppc/op_helper.c
... ... @@ -151,15 +151,12 @@ void do_addmeo (void)
151 151 {
152 152 T1 = T0;
153 153 T0 += xer_ca + (-1);
154   - if (likely(!((uint32_t)T1 &
155   - ((uint32_t)T1 ^ (uint32_t)T0) & (1UL << 31)))) {
156   - xer_ov = 0;
157   - } else {
158   - xer_ov = 1;
159   - xer_so = 1;
160   - }
  154 + xer_ov = ((uint32_t)T1 & ((uint32_t)T1 ^ (uint32_t)T0)) >> 31;
  155 + xer_so |= xer_ov;
161 156 if (likely(T1 != 0))
162 157 xer_ca = 1;
  158 + else
  159 + xer_ca = 0;
163 160 }
164 161  
165 162 #if defined(TARGET_PPC64)
... ... @@ -167,15 +164,12 @@ void do_addmeo_64 (void)
167 164 {
168 165 T1 = T0;
169 166 T0 += xer_ca + (-1);
170   - if (likely(!((uint64_t)T1 &
171   - ((uint64_t)T1 ^ (uint64_t)T0) & (1ULL << 63)))) {
172   - xer_ov = 0;
173   - } else {
174   - xer_ov = 1;
175   - xer_so = 1;
176   - }
  167 + xer_ov = ((uint64_t)T1 & ((uint64_t)T1 ^ (uint64_t)T0)) >> 63;
  168 + xer_so |= xer_ov;
177 169 if (likely(T1 != 0))
178 170 xer_ca = 1;
  171 + else
  172 + xer_ca = 0;
179 173 }
180 174 #endif
181 175  
... ... @@ -316,15 +310,12 @@ void do_subfmeo (void)
316 310 {
317 311 T1 = T0;
318 312 T0 = ~T0 + xer_ca - 1;
319   - if (likely(!((uint32_t)~T1 & ((uint32_t)~T1 ^ (uint32_t)T0) &
320   - (1UL << 31)))) {
321   - xer_ov = 0;
322   - } else {
323   - xer_ov = 1;
324   - xer_so = 1;
325   - }
  313 + xer_ov = ((uint32_t)~T1 & ((uint32_t)~T1 ^ (uint32_t)T0)) >> 31;
  314 + xer_so |= xer_ov;
326 315 if (likely((uint32_t)T1 != UINT32_MAX))
327 316 xer_ca = 1;
  317 + else
  318 + xer_ca = 0;
328 319 }
329 320  
330 321 #if defined(TARGET_PPC64)
... ... @@ -332,15 +323,12 @@ void do_subfmeo_64 (void)
332 323 {
333 324 T1 = T0;
334 325 T0 = ~T0 + xer_ca - 1;
335   - if (likely(!((uint64_t)~T1 & ((uint64_t)~T1 ^ (uint64_t)T0) &
336   - (1ULL << 63)))) {
337   - xer_ov = 0;
338   - } else {
339   - xer_ov = 1;
340   - xer_so = 1;
341   - }
  326 + xer_ov = ((uint64_t)~T1 & ((uint64_t)~T1 ^ (uint64_t)T0)) >> 63;
  327 + xer_so |= xer_ov;
342 328 if (likely((uint64_t)T1 != UINT64_MAX))
343 329 xer_ca = 1;
  330 + else
  331 + xer_ca = 0;
344 332 }
345 333 #endif
346 334  
... ... @@ -348,13 +336,9 @@ void do_subfzeo (void)
348 336 {
349 337 T1 = T0;
350 338 T0 = ~T0 + xer_ca;
351   - if (likely(!(((uint32_t)~T1 ^ UINT32_MAX) &
352   - ((uint32_t)(~T1) ^ (uint32_t)T0) & (1UL << 31)))) {
353   - xer_ov = 0;
354   - } else {
355   - xer_ov = 1;
356   - xer_so = 1;
357   - }
  339 + xer_ov = (((uint32_t)~T1 ^ UINT32_MAX) &
  340 + ((uint32_t)(~T1) ^ (uint32_t)T0)) >> 31;
  341 + xer_so |= xer_ov;
358 342 if (likely((uint32_t)T0 >= (uint32_t)~T1)) {
359 343 xer_ca = 0;
360 344 } else {
... ... @@ -367,13 +351,9 @@ void do_subfzeo_64 (void)
367 351 {
368 352 T1 = T0;
369 353 T0 = ~T0 + xer_ca;
370   - if (likely(!(((uint64_t)~T1 ^ UINT64_MAX) &
371   - ((uint64_t)(~T1) ^ (uint64_t)T0) & (1ULL << 63)))) {
372   - xer_ov = 0;
373   - } else {
374   - xer_ov = 1;
375   - xer_so = 1;
376   - }
  354 + xer_ov = (((uint64_t)~T1 ^ UINT64_MAX) &
  355 + ((uint64_t)(~T1) ^ (uint64_t)T0)) >> 63;
  356 + xer_so |= xer_ov;
377 357 if (likely((uint64_t)T0 >= (uint64_t)~T1)) {
378 358 xer_ca = 0;
379 359 } else {
... ... @@ -1755,17 +1735,6 @@ void do_op_602_mfrom (void)
1755 1735  
1756 1736 /*****************************************************************************/
1757 1737 /* Embedded PowerPC specific helpers */
1758   -void do_405_check_ov (void)
1759   -{
1760   - if (likely((((uint32_t)T1 ^ (uint32_t)T2) >> 31) ||
1761   - !(((uint32_t)T0 ^ (uint32_t)T2) >> 31))) {
1762   - xer_ov = 0;
1763   - } else {
1764   - xer_ov = 1;
1765   - xer_so = 1;
1766   - }
1767   -}
1768   -
1769 1738 void do_405_check_sat (void)
1770 1739 {
1771 1740 if (!likely((((uint32_t)T1 ^ (uint32_t)T2) >> 31) ||
... ...
target-ppc/op_helper.h
... ... @@ -182,7 +182,6 @@ void do_440_tlbwe (int word);
182 182 #endif
183 183  
184 184 /* PowerPC 4xx specific helpers */
185   -void do_405_check_ov (void);
186 185 void do_405_check_sat (void);
187 186 void do_load_dcr (void);
188 187 void do_store_dcr (void);
... ...
target-ppc/translate.c
... ... @@ -888,17 +888,17 @@ GEN_INT_ARITH1_64 (neg, 0x1F, 0x08, 0x03, PPC_INTEGER);
888 888 /* subf subf. subfo subfo. */
889 889 static always_inline void gen_op_subfo (void)
890 890 {
891   - gen_op_move_T2_T0();
  891 + gen_op_moven_T2_T0();
892 892 gen_op_subf();
893   - gen_op_check_subfo();
  893 + gen_op_check_addo();
894 894 }
895 895 #if defined(TARGET_PPC64)
896 896 #define gen_op_subf_64 gen_op_subf
897 897 static always_inline void gen_op_subfo_64 (void)
898 898 {
899   - gen_op_move_T2_T0();
  899 + gen_op_moven_T2_T0();
900 900 gen_op_subf();
901   - gen_op_check_subfo_64();
  901 + gen_op_check_addo_64();
902 902 }
903 903 #endif
904 904 GEN_INT_ARITH2_64 (subf, 0x1F, 0x08, 0x01, PPC_INTEGER);
... ... @@ -910,10 +910,10 @@ static always_inline void gen_op_subfc (void)
910 910 }
911 911 static always_inline void gen_op_subfco (void)
912 912 {
913   - gen_op_move_T2_T0();
  913 + gen_op_moven_T2_T0();
914 914 gen_op_subf();
915 915 gen_op_check_subfc();
916   - gen_op_check_subfo();
  916 + gen_op_check_addo();
917 917 }
918 918 #if defined(TARGET_PPC64)
919 919 static always_inline void gen_op_subfc_64 (void)
... ... @@ -923,27 +923,27 @@ static always_inline void gen_op_subfc_64 (void)
923 923 }
924 924 static always_inline void gen_op_subfco_64 (void)
925 925 {
926   - gen_op_move_T2_T0();
  926 + gen_op_moven_T2_T0();
927 927 gen_op_subf();
928 928 gen_op_check_subfc_64();
929   - gen_op_check_subfo_64();
  929 + gen_op_check_addo_64();
930 930 }
931 931 #endif
932 932 GEN_INT_ARITH2_64 (subfc, 0x1F, 0x08, 0x00, PPC_INTEGER);
933 933 /* subfe subfe. subfeo subfeo. */
934 934 static always_inline void gen_op_subfeo (void)
935 935 {
936   - gen_op_move_T2_T0();
  936 + gen_op_moven_T2_T0();
937 937 gen_op_subfe();
938   - gen_op_check_subfo();
  938 + gen_op_check_addo();
939 939 }
940 940 #if defined(TARGET_PPC64)
941 941 #define gen_op_subfe_64 gen_op_subfe
942 942 static always_inline void gen_op_subfeo_64 (void)
943 943 {
944   - gen_op_move_T2_T0();
  944 + gen_op_moven_T2_T0();
945 945 gen_op_subfe_64();
946   - gen_op_check_subfo_64();
  946 + gen_op_check_addo_64();
947 947 }
948 948 #endif
949 949 GEN_INT_ARITH2_64 (subfe, 0x1F, 0x08, 0x04, PPC_INTEGER);
... ... @@ -5116,7 +5116,7 @@ static always_inline void gen_405_mulladd_insn (DisasContext *ctx,
5116 5116 if (opc3 & 0x10) {
5117 5117 /* Check overflow */
5118 5118 if (opc3 & 0x01)
5119   - gen_op_405_check_ov();
  5119 + gen_op_check_addo();
5120 5120 else
5121 5121 gen_op_405_check_ovu();
5122 5122 }
... ...