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,6 +191,12 @@ void OPPROTO op_move_T2_T0 (void)
191 RETURN(); 191 RETURN();
192 } 192 }
193 193
  194 +void OPPROTO op_moven_T2_T0 (void)
  195 +{
  196 + T2 = ~T0;
  197 + RETURN();
  198 +}
  199 +
194 /* Generate exceptions */ 200 /* Generate exceptions */
195 void OPPROTO op_raise_exception_err (void) 201 void OPPROTO op_raise_exception_err (void)
196 { 202 {
@@ -847,26 +853,18 @@ void OPPROTO op_add (void) @@ -847,26 +853,18 @@ void OPPROTO op_add (void)
847 853
848 void OPPROTO op_check_addo (void) 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 RETURN(); 859 RETURN();
858 } 860 }
859 861
860 #if defined(TARGET_PPC64) 862 #if defined(TARGET_PPC64)
861 void OPPROTO op_check_addo_64 (void) 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 RETURN(); 868 RETURN();
871 } 869 }
872 #endif 870 #endif
@@ -922,6 +920,8 @@ void OPPROTO op_add_me (void) @@ -922,6 +920,8 @@ void OPPROTO op_add_me (void)
922 T0 += xer_ca + (-1); 920 T0 += xer_ca + (-1);
923 if (likely((uint32_t)T1 != 0)) 921 if (likely((uint32_t)T1 != 0))
924 xer_ca = 1; 922 xer_ca = 1;
  923 + else
  924 + xer_ca = 0;
925 RETURN(); 925 RETURN();
926 } 926 }
927 927
@@ -931,6 +931,8 @@ void OPPROTO op_add_me_64 (void) @@ -931,6 +931,8 @@ void OPPROTO op_add_me_64 (void)
931 T0 += xer_ca + (-1); 931 T0 += xer_ca + (-1);
932 if (likely((uint64_t)T1 != 0)) 932 if (likely((uint64_t)T1 != 0))
933 xer_ca = 1; 933 xer_ca = 1;
  934 + else
  935 + xer_ca = 0;
934 RETURN(); 936 RETURN();
935 } 937 }
936 #endif 938 #endif
@@ -1142,32 +1144,6 @@ void OPPROTO op_subf (void) @@ -1142,32 +1144,6 @@ void OPPROTO op_subf (void)
1142 RETURN(); 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 /* subtract from carrying */ 1147 /* subtract from carrying */
1172 void OPPROTO op_check_subfc (void) 1148 void OPPROTO op_check_subfc (void)
1173 { 1149 {
@@ -1235,8 +1211,10 @@ void OPPROTO op_subfic_64 (void) @@ -1235,8 +1211,10 @@ void OPPROTO op_subfic_64 (void)
1235 void OPPROTO op_subfme (void) 1211 void OPPROTO op_subfme (void)
1236 { 1212 {
1237 T0 = ~T0 + xer_ca - 1; 1213 T0 = ~T0 + xer_ca - 1;
1238 - if (likely((uint32_t)T0 != (uint32_t)-1)) 1214 + if (likely((uint32_t)T0 != UINT32_MAX))
1239 xer_ca = 1; 1215 xer_ca = 1;
  1216 + else
  1217 + xer_ca = 0;
1240 RETURN(); 1218 RETURN();
1241 } 1219 }
1242 1220
@@ -1244,8 +1222,10 @@ void OPPROTO op_subfme (void) @@ -1244,8 +1222,10 @@ void OPPROTO op_subfme (void)
1244 void OPPROTO op_subfme_64 (void) 1222 void OPPROTO op_subfme_64 (void)
1245 { 1223 {
1246 T0 = ~T0 + xer_ca - 1; 1224 T0 = ~T0 + xer_ca - 1;
1247 - if (likely((uint64_t)T0 != (uint64_t)-1)) 1225 + if (likely((uint64_t)T0 != UINT64_MAX))
1248 xer_ca = 1; 1226 xer_ca = 1;
  1227 + else
  1228 + xer_ca = 0;
1249 RETURN(); 1229 RETURN();
1250 } 1230 }
1251 #endif 1231 #endif
@@ -2528,12 +2508,6 @@ void OPPROTO op_405_mullhwu (void) @@ -2528,12 +2508,6 @@ void OPPROTO op_405_mullhwu (void)
2528 RETURN(); 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 void OPPROTO op_405_check_sat (void) 2511 void OPPROTO op_405_check_sat (void)
2538 { 2512 {
2539 do_405_check_sat(); 2513 do_405_check_sat();
target-ppc/op_helper.c
@@ -151,15 +151,12 @@ void do_addmeo (void) @@ -151,15 +151,12 @@ void do_addmeo (void)
151 { 151 {
152 T1 = T0; 152 T1 = T0;
153 T0 += xer_ca + (-1); 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 if (likely(T1 != 0)) 156 if (likely(T1 != 0))
162 xer_ca = 1; 157 xer_ca = 1;
  158 + else
  159 + xer_ca = 0;
163 } 160 }
164 161
165 #if defined(TARGET_PPC64) 162 #if defined(TARGET_PPC64)
@@ -167,15 +164,12 @@ void do_addmeo_64 (void) @@ -167,15 +164,12 @@ void do_addmeo_64 (void)
167 { 164 {
168 T1 = T0; 165 T1 = T0;
169 T0 += xer_ca + (-1); 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 if (likely(T1 != 0)) 169 if (likely(T1 != 0))
178 xer_ca = 1; 170 xer_ca = 1;
  171 + else
  172 + xer_ca = 0;
179 } 173 }
180 #endif 174 #endif
181 175
@@ -316,15 +310,12 @@ void do_subfmeo (void) @@ -316,15 +310,12 @@ void do_subfmeo (void)
316 { 310 {
317 T1 = T0; 311 T1 = T0;
318 T0 = ~T0 + xer_ca - 1; 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 if (likely((uint32_t)T1 != UINT32_MAX)) 315 if (likely((uint32_t)T1 != UINT32_MAX))
327 xer_ca = 1; 316 xer_ca = 1;
  317 + else
  318 + xer_ca = 0;
328 } 319 }
329 320
330 #if defined(TARGET_PPC64) 321 #if defined(TARGET_PPC64)
@@ -332,15 +323,12 @@ void do_subfmeo_64 (void) @@ -332,15 +323,12 @@ void do_subfmeo_64 (void)
332 { 323 {
333 T1 = T0; 324 T1 = T0;
334 T0 = ~T0 + xer_ca - 1; 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 if (likely((uint64_t)T1 != UINT64_MAX)) 328 if (likely((uint64_t)T1 != UINT64_MAX))
343 xer_ca = 1; 329 xer_ca = 1;
  330 + else
  331 + xer_ca = 0;
344 } 332 }
345 #endif 333 #endif
346 334
@@ -348,13 +336,9 @@ void do_subfzeo (void) @@ -348,13 +336,9 @@ void do_subfzeo (void)
348 { 336 {
349 T1 = T0; 337 T1 = T0;
350 T0 = ~T0 + xer_ca; 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 if (likely((uint32_t)T0 >= (uint32_t)~T1)) { 342 if (likely((uint32_t)T0 >= (uint32_t)~T1)) {
359 xer_ca = 0; 343 xer_ca = 0;
360 } else { 344 } else {
@@ -367,13 +351,9 @@ void do_subfzeo_64 (void) @@ -367,13 +351,9 @@ void do_subfzeo_64 (void)
367 { 351 {
368 T1 = T0; 352 T1 = T0;
369 T0 = ~T0 + xer_ca; 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 if (likely((uint64_t)T0 >= (uint64_t)~T1)) { 357 if (likely((uint64_t)T0 >= (uint64_t)~T1)) {
378 xer_ca = 0; 358 xer_ca = 0;
379 } else { 359 } else {
@@ -1755,17 +1735,6 @@ void do_op_602_mfrom (void) @@ -1755,17 +1735,6 @@ void do_op_602_mfrom (void)
1755 1735
1756 /*****************************************************************************/ 1736 /*****************************************************************************/
1757 /* Embedded PowerPC specific helpers */ 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 void do_405_check_sat (void) 1738 void do_405_check_sat (void)
1770 { 1739 {
1771 if (!likely((((uint32_t)T1 ^ (uint32_t)T2) >> 31) || 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,7 +182,6 @@ void do_440_tlbwe (int word);
182 #endif 182 #endif
183 183
184 /* PowerPC 4xx specific helpers */ 184 /* PowerPC 4xx specific helpers */
185 -void do_405_check_ov (void);  
186 void do_405_check_sat (void); 185 void do_405_check_sat (void);
187 void do_load_dcr (void); 186 void do_load_dcr (void);
188 void do_store_dcr (void); 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,17 +888,17 @@ GEN_INT_ARITH1_64 (neg, 0x1F, 0x08, 0x03, PPC_INTEGER);
888 /* subf subf. subfo subfo. */ 888 /* subf subf. subfo subfo. */
889 static always_inline void gen_op_subfo (void) 889 static always_inline void gen_op_subfo (void)
890 { 890 {
891 - gen_op_move_T2_T0(); 891 + gen_op_moven_T2_T0();
892 gen_op_subf(); 892 gen_op_subf();
893 - gen_op_check_subfo(); 893 + gen_op_check_addo();
894 } 894 }
895 #if defined(TARGET_PPC64) 895 #if defined(TARGET_PPC64)
896 #define gen_op_subf_64 gen_op_subf 896 #define gen_op_subf_64 gen_op_subf
897 static always_inline void gen_op_subfo_64 (void) 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 gen_op_subf(); 900 gen_op_subf();
901 - gen_op_check_subfo_64(); 901 + gen_op_check_addo_64();
902 } 902 }
903 #endif 903 #endif
904 GEN_INT_ARITH2_64 (subf, 0x1F, 0x08, 0x01, PPC_INTEGER); 904 GEN_INT_ARITH2_64 (subf, 0x1F, 0x08, 0x01, PPC_INTEGER);
@@ -910,10 +910,10 @@ static always_inline void gen_op_subfc (void) @@ -910,10 +910,10 @@ static always_inline void gen_op_subfc (void)
910 } 910 }
911 static always_inline void gen_op_subfco (void) 911 static always_inline void gen_op_subfco (void)
912 { 912 {
913 - gen_op_move_T2_T0(); 913 + gen_op_moven_T2_T0();
914 gen_op_subf(); 914 gen_op_subf();
915 gen_op_check_subfc(); 915 gen_op_check_subfc();
916 - gen_op_check_subfo(); 916 + gen_op_check_addo();
917 } 917 }
918 #if defined(TARGET_PPC64) 918 #if defined(TARGET_PPC64)
919 static always_inline void gen_op_subfc_64 (void) 919 static always_inline void gen_op_subfc_64 (void)
@@ -923,27 +923,27 @@ 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 static always_inline void gen_op_subfco_64 (void) 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 gen_op_subf(); 927 gen_op_subf();
928 gen_op_check_subfc_64(); 928 gen_op_check_subfc_64();
929 - gen_op_check_subfo_64(); 929 + gen_op_check_addo_64();
930 } 930 }
931 #endif 931 #endif
932 GEN_INT_ARITH2_64 (subfc, 0x1F, 0x08, 0x00, PPC_INTEGER); 932 GEN_INT_ARITH2_64 (subfc, 0x1F, 0x08, 0x00, PPC_INTEGER);
933 /* subfe subfe. subfeo subfeo. */ 933 /* subfe subfe. subfeo subfeo. */
934 static always_inline void gen_op_subfeo (void) 934 static always_inline void gen_op_subfeo (void)
935 { 935 {
936 - gen_op_move_T2_T0(); 936 + gen_op_moven_T2_T0();
937 gen_op_subfe(); 937 gen_op_subfe();
938 - gen_op_check_subfo(); 938 + gen_op_check_addo();
939 } 939 }
940 #if defined(TARGET_PPC64) 940 #if defined(TARGET_PPC64)
941 #define gen_op_subfe_64 gen_op_subfe 941 #define gen_op_subfe_64 gen_op_subfe
942 static always_inline void gen_op_subfeo_64 (void) 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 gen_op_subfe_64(); 945 gen_op_subfe_64();
946 - gen_op_check_subfo_64(); 946 + gen_op_check_addo_64();
947 } 947 }
948 #endif 948 #endif
949 GEN_INT_ARITH2_64 (subfe, 0x1F, 0x08, 0x04, PPC_INTEGER); 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,7 +5116,7 @@ static always_inline void gen_405_mulladd_insn (DisasContext *ctx,
5116 if (opc3 & 0x10) { 5116 if (opc3 & 0x10) {
5117 /* Check overflow */ 5117 /* Check overflow */
5118 if (opc3 & 0x01) 5118 if (opc3 & 0x01)
5119 - gen_op_405_check_ov(); 5119 + gen_op_check_addo();
5120 else 5120 else
5121 gen_op_405_check_ovu(); 5121 gen_op_405_check_ovu();
5122 } 5122 }