Commit 26d6736245f313da32487688c9a171462ac7c6de

Authored by aurel32
1 parent e1571908

target-ppc: convert logical instructions to TCG

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5506 c046a42c-6fe2-441c-8c8c-71466251a162
target-ppc/helper.h
@@ -7,3 +7,13 @@ DEF_HELPER(uint32_t, helper_fcmpu, (void)) @@ -7,3 +7,13 @@ DEF_HELPER(uint32_t, helper_fcmpu, (void))
7 7
8 DEF_HELPER(uint32_t, helper_load_cr, (void)) 8 DEF_HELPER(uint32_t, helper_load_cr, (void))
9 DEF_HELPER(void, helper_store_cr, (target_ulong, uint32_t)) 9 DEF_HELPER(void, helper_store_cr, (target_ulong, uint32_t))
  10 +
  11 +DEF_HELPER(target_ulong, helper_cntlzw, (target_ulong t))
  12 +DEF_HELPER(target_ulong, helper_popcntb, (target_ulong val))
  13 +DEF_HELPER(target_ulong, helper_sraw, (target_ulong, target_ulong))
  14 +#if defined(TARGET_PPC64)
  15 +DEF_HELPER(target_ulong, helper_cntlzd, (target_ulong t))
  16 +DEF_HELPER(target_ulong, helper_popcntb_64, (target_ulong val))
  17 +DEF_HELPER(target_ulong, helper_srad, (target_ulong, target_ulong))
  18 +#endif
  19 +
target-ppc/op.c
@@ -37,15 +37,6 @@ void OPPROTO op_debug (void) @@ -37,15 +37,6 @@ void OPPROTO op_debug (void)
37 do_raise_exception(EXCP_DEBUG); 37 do_raise_exception(EXCP_DEBUG);
38 } 38 }
39 39
40 -/* Load/store special registers */  
41 -#if defined(TARGET_PPC64)  
42 -void OPPROTO op_store_pri (void)  
43 -{  
44 - do_store_pri(PARAM1);  
45 - RETURN();  
46 -}  
47 -#endif  
48 -  
49 #if !defined(CONFIG_USER_ONLY) 40 #if !defined(CONFIG_USER_ONLY)
50 /* Segment registers load and store */ 41 /* Segment registers load and store */
51 void OPPROTO op_load_sr (void) 42 void OPPROTO op_load_sr (void)
@@ -921,101 +912,7 @@ void OPPROTO op_subfzeo_64 (void) @@ -921,101 +912,7 @@ void OPPROTO op_subfzeo_64 (void)
921 } 912 }
922 #endif 913 #endif
923 914
924 -void OPPROTO op_popcntb (void)  
925 -{  
926 - do_popcntb();  
927 - RETURN();  
928 -}  
929 -  
930 -#if defined(TARGET_PPC64)  
931 -void OPPROTO op_popcntb_64 (void)  
932 -{  
933 - do_popcntb_64();  
934 - RETURN();  
935 -}  
936 -#endif  
937 -  
938 /*** Integer logical ***/ 915 /*** Integer logical ***/
939 -/* and */  
940 -void OPPROTO op_and (void)  
941 -{  
942 - T0 &= T1;  
943 - RETURN();  
944 -}  
945 -  
946 -/* andc */  
947 -void OPPROTO op_andc (void)  
948 -{  
949 - T0 &= ~T1;  
950 - RETURN();  
951 -}  
952 -  
953 -/* count leading zero */  
954 -void OPPROTO op_cntlzw (void)  
955 -{  
956 - do_cntlzw();  
957 - RETURN();  
958 -}  
959 -  
960 -#if defined(TARGET_PPC64)  
961 -void OPPROTO op_cntlzd (void)  
962 -{  
963 - do_cntlzd();  
964 - RETURN();  
965 -}  
966 -#endif  
967 -  
968 -/* eqv */  
969 -void OPPROTO op_eqv (void)  
970 -{  
971 - T0 = ~(T0 ^ T1);  
972 - RETURN();  
973 -}  
974 -  
975 -/* extend sign byte */  
976 -void OPPROTO op_extsb (void)  
977 -{  
978 -#if defined (TARGET_PPC64)  
979 - T0 = (int64_t)((int8_t)T0);  
980 -#else  
981 - T0 = (int32_t)((int8_t)T0);  
982 -#endif  
983 - RETURN();  
984 -}  
985 -  
986 -/* extend sign half word */  
987 -void OPPROTO op_extsh (void)  
988 -{  
989 -#if defined (TARGET_PPC64)  
990 - T0 = (int64_t)((int16_t)T0);  
991 -#else  
992 - T0 = (int32_t)((int16_t)T0);  
993 -#endif  
994 - RETURN();  
995 -}  
996 -  
997 -#if defined (TARGET_PPC64)  
998 -void OPPROTO op_extsw (void)  
999 -{  
1000 - T0 = (int64_t)((int32_t)T0);  
1001 - RETURN();  
1002 -}  
1003 -#endif  
1004 -  
1005 -/* nand */  
1006 -void OPPROTO op_nand (void)  
1007 -{  
1008 - T0 = ~(T0 & T1);  
1009 - RETURN();  
1010 -}  
1011 -  
1012 -/* nor */  
1013 -void OPPROTO op_nor (void)  
1014 -{  
1015 - T0 = ~(T0 | T1);  
1016 - RETURN();  
1017 -}  
1018 -  
1019 /* or */ 916 /* or */
1020 void OPPROTO op_or (void) 917 void OPPROTO op_or (void)
1021 { 918 {
@@ -1023,34 +920,6 @@ void OPPROTO op_or (void) @@ -1023,34 +920,6 @@ void OPPROTO op_or (void)
1023 RETURN(); 920 RETURN();
1024 } 921 }
1025 922
1026 -/* orc */  
1027 -void OPPROTO op_orc (void)  
1028 -{  
1029 - T0 |= ~T1;  
1030 - RETURN();  
1031 -}  
1032 -  
1033 -/* ori */  
1034 -void OPPROTO op_ori (void)  
1035 -{  
1036 - T0 |= (uint32_t)PARAM1;  
1037 - RETURN();  
1038 -}  
1039 -  
1040 -/* xor */  
1041 -void OPPROTO op_xor (void)  
1042 -{  
1043 - T0 ^= T1;  
1044 - RETURN();  
1045 -}  
1046 -  
1047 -/* xori */  
1048 -void OPPROTO op_xori (void)  
1049 -{  
1050 - T0 ^= (uint32_t)PARAM1;  
1051 - RETURN();  
1052 -}  
1053 -  
1054 /*** Integer rotate ***/ 923 /*** Integer rotate ***/
1055 void OPPROTO op_rotl32_T0_T1 (void) 924 void OPPROTO op_rotl32_T0_T1 (void)
1056 { 925 {
@@ -1079,122 +948,13 @@ void OPPROTO op_rotli64_T0 (void) @@ -1079,122 +948,13 @@ void OPPROTO op_rotli64_T0 (void)
1079 #endif 948 #endif
1080 949
1081 /*** Integer shift ***/ 950 /*** Integer shift ***/
1082 -/* shift left word */  
1083 -void OPPROTO op_slw (void)  
1084 -{  
1085 - if (T1 & 0x20) {  
1086 - T0 = 0;  
1087 - } else {  
1088 - T0 = (uint32_t)(T0 << T1);  
1089 - }  
1090 - RETURN();  
1091 -}  
1092 -  
1093 -#if defined(TARGET_PPC64)  
1094 -void OPPROTO op_sld (void)  
1095 -{  
1096 - if (T1 & 0x40) {  
1097 - T0 = 0;  
1098 - } else {  
1099 - T0 = T0 << T1;  
1100 - }  
1101 - RETURN();  
1102 -}  
1103 -#endif  
1104 -  
1105 -/* shift right algebraic word */  
1106 -void OPPROTO op_sraw (void)  
1107 -{  
1108 - do_sraw();  
1109 - RETURN();  
1110 -}  
1111 -  
1112 -#if defined(TARGET_PPC64)  
1113 -void OPPROTO op_srad (void)  
1114 -{  
1115 - do_srad();  
1116 - RETURN();  
1117 -}  
1118 -#endif  
1119 -  
1120 -/* shift right algebraic word immediate */  
1121 -void OPPROTO op_srawi (void)  
1122 -{  
1123 - uint32_t mask = (uint32_t)PARAM2;  
1124 -  
1125 - T0 = (int32_t)T0 >> PARAM1;  
1126 - if ((int32_t)T1 < 0 && (T1 & mask) != 0) {  
1127 - env->xer |= (1 << XER_CA);  
1128 - } else {  
1129 - env->xer &= ~(1 << XER_CA);  
1130 - }  
1131 - RETURN();  
1132 -}  
1133 -  
1134 -#if defined(TARGET_PPC64)  
1135 -void OPPROTO op_sradi (void)  
1136 -{  
1137 - uint64_t mask = ((uint64_t)PARAM2 << 32) | (uint64_t)PARAM3;  
1138 -  
1139 - T0 = (int64_t)T0 >> PARAM1;  
1140 - if ((int64_t)T1 < 0 && ((uint64_t)T1 & mask) != 0) {  
1141 - env->xer |= (1 << XER_CA);  
1142 - } else {  
1143 - env->xer &= ~(1 << XER_CA);  
1144 - }  
1145 - RETURN();  
1146 -}  
1147 -#endif  
1148 -  
1149 /* shift right word */ 951 /* shift right word */
1150 -void OPPROTO op_srw (void)  
1151 -{  
1152 - if (T1 & 0x20) {  
1153 - T0 = 0;  
1154 - } else {  
1155 - T0 = (uint32_t)T0 >> T1;  
1156 - }  
1157 - RETURN();  
1158 -}  
1159 -  
1160 -#if defined(TARGET_PPC64)  
1161 -void OPPROTO op_srd (void)  
1162 -{  
1163 - if (T1 & 0x40) {  
1164 - T0 = 0;  
1165 - } else {  
1166 - T0 = (uint64_t)T0 >> T1;  
1167 - }  
1168 - RETURN();  
1169 -}  
1170 -#endif  
1171 -  
1172 -void OPPROTO op_sl_T0_T1 (void)  
1173 -{  
1174 - T0 = T0 << T1;  
1175 - RETURN();  
1176 -}  
1177 -  
1178 void OPPROTO op_sli_T0 (void) 952 void OPPROTO op_sli_T0 (void)
1179 { 953 {
1180 T0 = T0 << PARAM1; 954 T0 = T0 << PARAM1;
1181 RETURN(); 955 RETURN();
1182 } 956 }
1183 957
1184 -void OPPROTO op_srl_T0_T1 (void)  
1185 -{  
1186 - T0 = (uint32_t)T0 >> T1;  
1187 - RETURN();  
1188 -}  
1189 -  
1190 -#if defined(TARGET_PPC64)  
1191 -void OPPROTO op_srl_T0_T1_64 (void)  
1192 -{  
1193 - T0 = (uint32_t)T0 >> T1;  
1194 - RETURN();  
1195 -}  
1196 -#endif  
1197 -  
1198 void OPPROTO op_srli_T0 (void) 958 void OPPROTO op_srli_T0 (void)
1199 { 959 {
1200 T0 = (uint32_t)T0 >> PARAM1; 960 T0 = (uint32_t)T0 >> PARAM1;
@@ -1215,14 +975,6 @@ void OPPROTO op_srli_T1 (void) @@ -1215,14 +975,6 @@ void OPPROTO op_srli_T1 (void)
1215 RETURN(); 975 RETURN();
1216 } 976 }
1217 977
1218 -#if defined(TARGET_PPC64)  
1219 -void OPPROTO op_srli_T1_64 (void)  
1220 -{  
1221 - T1 = (uint64_t)T1 >> PARAM1;  
1222 - RETURN();  
1223 -}  
1224 -#endif  
1225 -  
1226 /*** Floating-Point arithmetic ***/ 978 /*** Floating-Point arithmetic ***/
1227 /* fadd - fadd. */ 979 /* fadd - fadd. */
1228 void OPPROTO op_fadd (void) 980 void OPPROTO op_fadd (void)
target-ppc/op_helper.c
@@ -368,96 +368,98 @@ void do_subfzeo_64 (void) @@ -368,96 +368,98 @@ void do_subfzeo_64 (void)
368 } 368 }
369 #endif 369 #endif
370 370
371 -void do_cntlzw (void) 371 +target_ulong helper_cntlzw (target_ulong t)
372 { 372 {
373 - T0 = clz32(T0); 373 + return clz32(t);
374 } 374 }
375 375
376 #if defined(TARGET_PPC64) 376 #if defined(TARGET_PPC64)
377 -void do_cntlzd (void) 377 +target_ulong helper_cntlzd (target_ulong t)
378 { 378 {
379 - T0 = clz64(T0); 379 + return clz64(t);
380 } 380 }
381 #endif 381 #endif
382 382
383 /* shift right arithmetic helper */ 383 /* shift right arithmetic helper */
384 -void do_sraw (void) 384 +target_ulong helper_sraw (target_ulong value, target_ulong shift)
385 { 385 {
386 int32_t ret; 386 int32_t ret;
387 387
388 - if (likely(!(T1 & 0x20UL))) {  
389 - if (likely((uint32_t)T1 != 0)) {  
390 - ret = (int32_t)T0 >> (T1 & 0x1fUL);  
391 - if (likely(ret >= 0 || ((int32_t)T0 & ((1 << T1) - 1)) == 0)) { 388 + if (likely(!(shift & 0x20))) {
  389 + if (likely((uint32_t)shift != 0)) {
  390 + shift &= 0x1f;
  391 + ret = (int32_t)value >> shift;
  392 + if (likely(ret >= 0 || (value & ((1 << shift) - 1)) == 0)) {
392 env->xer &= ~(1 << XER_CA); 393 env->xer &= ~(1 << XER_CA);
393 } else { 394 } else {
394 env->xer |= (1 << XER_CA); 395 env->xer |= (1 << XER_CA);
395 } 396 }
396 } else { 397 } else {
397 - ret = T0; 398 + ret = (int32_t)value;
398 env->xer &= ~(1 << XER_CA); 399 env->xer &= ~(1 << XER_CA);
399 } 400 }
400 } else { 401 } else {
401 - ret = UINT32_MAX * ((uint32_t)T0 >> 31);  
402 - if (likely(ret >= 0 || ((uint32_t)T0 & ~0x80000000UL) == 0)) {  
403 - env->xer &= ~(1 << XER_CA);  
404 - } else { 402 + ret = (int32_t)value >> 31;
  403 + if (ret) {
405 env->xer |= (1 << XER_CA); 404 env->xer |= (1 << XER_CA);
  405 + } else {
  406 + env->xer &= ~(1 << XER_CA);
406 } 407 }
407 } 408 }
408 - T0 = ret; 409 + return (target_long)ret;
409 } 410 }
410 411
411 #if defined(TARGET_PPC64) 412 #if defined(TARGET_PPC64)
412 -void do_srad (void) 413 +target_ulong helper_srad (target_ulong value, target_ulong shift)
413 { 414 {
414 int64_t ret; 415 int64_t ret;
415 416
416 - if (likely(!(T1 & 0x40UL))) {  
417 - if (likely((uint64_t)T1 != 0)) {  
418 - ret = (int64_t)T0 >> (T1 & 0x3FUL);  
419 - if (likely(ret >= 0 || ((int64_t)T0 & ((1 << T1) - 1)) == 0)) { 417 + if (likely(!(shift & 0x40))) {
  418 + if (likely((uint64_t)shift != 0)) {
  419 + shift &= 0x3f;
  420 + ret = (int64_t)value >> shift;
  421 + if (likely(ret >= 0 || (value & ((1 << shift) - 1)) == 0)) {
420 env->xer &= ~(1 << XER_CA); 422 env->xer &= ~(1 << XER_CA);
421 } else { 423 } else {
422 env->xer |= (1 << XER_CA); 424 env->xer |= (1 << XER_CA);
423 } 425 }
424 } else { 426 } else {
425 - ret = T0; 427 + ret = (int64_t)value;
426 env->xer &= ~(1 << XER_CA); 428 env->xer &= ~(1 << XER_CA);
427 } 429 }
428 } else { 430 } else {
429 - ret = UINT64_MAX * ((uint64_t)T0 >> 63);  
430 - if (likely(ret >= 0 || ((uint64_t)T0 & ~0x8000000000000000ULL) == 0)) {  
431 - env->xer &= ~(1 << XER_CA);  
432 - } else { 431 + ret = (int64_t)value >> 63;
  432 + if (ret) {
433 env->xer |= (1 << XER_CA); 433 env->xer |= (1 << XER_CA);
  434 + } else {
  435 + env->xer &= ~(1 << XER_CA);
434 } 436 }
435 } 437 }
436 - T0 = ret; 438 + return ret;
437 } 439 }
438 #endif 440 #endif
439 441
440 -void do_popcntb (void) 442 +target_ulong helper_popcntb (target_ulong val)
441 { 443 {
442 uint32_t ret; 444 uint32_t ret;
443 int i; 445 int i;
444 446
445 ret = 0; 447 ret = 0;
446 for (i = 0; i < 32; i += 8) 448 for (i = 0; i < 32; i += 8)
447 - ret |= ctpop8((T0 >> i) & 0xFF) << i;  
448 - T0 = ret; 449 + ret |= ctpop8((val >> i) & 0xFF) << i;
  450 + return ret;
449 } 451 }
450 452
451 #if defined(TARGET_PPC64) 453 #if defined(TARGET_PPC64)
452 -void do_popcntb_64 (void) 454 +target_ulong helper_popcntb_64 (target_ulong val)
453 { 455 {
454 uint64_t ret; 456 uint64_t ret;
455 int i; 457 int i;
456 458
457 ret = 0; 459 ret = 0;
458 for (i = 0; i < 64; i += 8) 460 for (i = 0; i < 64; i += 8)
459 - ret |= ctpop8((T0 >> i) & 0xFF) << i;  
460 - T0 = ret; 461 + ret |= ctpop8((val >> i) & 0xFF) << i;
  462 + return ret;
461 } 463 }
462 #endif 464 #endif
463 465
target-ppc/translate.c
@@ -1277,63 +1277,56 @@ GEN_INT_ARITH2 (divdu, 0x1F, 0x09, 0x0E, PPC_64B); @@ -1277,63 +1277,56 @@ GEN_INT_ARITH2 (divdu, 0x1F, 0x09, 0x0E, PPC_64B);
1277 #endif 1277 #endif
1278 1278
1279 /*** Integer logical ***/ 1279 /*** Integer logical ***/
1280 -#define __GEN_LOGICAL2(name, opc2, opc3, type) \  
1281 -GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000000, type) \ 1280 +#define GEN_LOGICAL2(name, tcg_op, opc, type) \
  1281 +GEN_HANDLER(name, 0x1F, 0x1C, opc, 0x00000000, type) \
1282 { \ 1282 { \
1283 - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]); \  
1284 - tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]); \  
1285 - gen_op_##name(); \  
1286 - tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]); \ 1283 + tcg_op(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], \
  1284 + cpu_gpr[rB(ctx->opcode)]); \
1287 if (unlikely(Rc(ctx->opcode) != 0)) \ 1285 if (unlikely(Rc(ctx->opcode) != 0)) \
1288 - gen_set_Rc0(ctx, cpu_T[0]); \ 1286 + gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); \
1289 } 1287 }
1290 -#define GEN_LOGICAL2(name, opc, type) \  
1291 -__GEN_LOGICAL2(name, 0x1C, opc, type)  
1292 1288
1293 -#define GEN_LOGICAL1(name, opc, type) \ 1289 +#define GEN_LOGICAL1(name, tcg_op, opc, type) \
1294 GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, type) \ 1290 GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, type) \
1295 { \ 1291 { \
1296 - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]); \  
1297 - gen_op_##name(); \  
1298 - tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]); \ 1292 + tcg_op(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]); \
1299 if (unlikely(Rc(ctx->opcode) != 0)) \ 1293 if (unlikely(Rc(ctx->opcode) != 0)) \
1300 - gen_set_Rc0(ctx, cpu_T[0]); \ 1294 + gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); \
1301 } 1295 }
1302 1296
1303 /* and & and. */ 1297 /* and & and. */
1304 -GEN_LOGICAL2(and, 0x00, PPC_INTEGER); 1298 +GEN_LOGICAL2(and, tcg_gen_and_tl, 0x00, PPC_INTEGER);
1305 /* andc & andc. */ 1299 /* andc & andc. */
1306 -GEN_LOGICAL2(andc, 0x01, PPC_INTEGER); 1300 +GEN_LOGICAL2(andc, tcg_gen_andc_tl, 0x01, PPC_INTEGER);
1307 /* andi. */ 1301 /* andi. */
1308 GEN_HANDLER2(andi_, "andi.", 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) 1302 GEN_HANDLER2(andi_, "andi.", 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1309 { 1303 {
1310 - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);  
1311 - tcg_gen_andi_tl(cpu_T[0], cpu_T[0], UIMM(ctx->opcode));  
1312 - tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);  
1313 - gen_set_Rc0(ctx, cpu_T[0]); 1304 + tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], UIMM(ctx->opcode));
  1305 + gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1314 } 1306 }
1315 /* andis. */ 1307 /* andis. */
1316 GEN_HANDLER2(andis_, "andis.", 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) 1308 GEN_HANDLER2(andis_, "andis.", 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1317 { 1309 {
1318 - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);  
1319 - tcg_gen_andi_tl(cpu_T[0], cpu_T[0], UIMM(ctx->opcode) << 16);  
1320 - tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);  
1321 - gen_set_Rc0(ctx, cpu_T[0]); 1310 + tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], UIMM(ctx->opcode) << 16);
  1311 + gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1322 } 1312 }
1323 -  
1324 /* cntlzw */ 1313 /* cntlzw */
1325 -GEN_LOGICAL1(cntlzw, 0x00, PPC_INTEGER); 1314 +GEN_HANDLER(cntlzw, 0x1F, 0x1A, 0x00, 0x00000000, PPC_INTEGER)
  1315 +{
  1316 + tcg_gen_helper_1_1(helper_cntlzw, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
  1317 + if (unlikely(Rc(ctx->opcode) != 0))
  1318 + gen_set_Rc0(ctx, cpu_gpr[rS(ctx->opcode)]);
  1319 +}
1326 /* eqv & eqv. */ 1320 /* eqv & eqv. */
1327 -GEN_LOGICAL2(eqv, 0x08, PPC_INTEGER); 1321 +GEN_LOGICAL2(eqv, tcg_gen_eqv_tl, 0x08, PPC_INTEGER);
1328 /* extsb & extsb. */ 1322 /* extsb & extsb. */
1329 -GEN_LOGICAL1(extsb, 0x1D, PPC_INTEGER); 1323 +GEN_LOGICAL1(extsb, tcg_gen_ext8s_tl, 0x1D, PPC_INTEGER);
1330 /* extsh & extsh. */ 1324 /* extsh & extsh. */
1331 -GEN_LOGICAL1(extsh, 0x1C, PPC_INTEGER); 1325 +GEN_LOGICAL1(extsh, tcg_gen_ext16s_tl, 0x1C, PPC_INTEGER);
1332 /* nand & nand. */ 1326 /* nand & nand. */
1333 -GEN_LOGICAL2(nand, 0x0E, PPC_INTEGER); 1327 +GEN_LOGICAL2(nand, tcg_gen_nand_tl, 0x0E, PPC_INTEGER);
1334 /* nor & nor. */ 1328 /* nor & nor. */
1335 -GEN_LOGICAL2(nor, 0x03, PPC_INTEGER);  
1336 - 1329 +GEN_LOGICAL2(nor, tcg_gen_nor_tl, 0x03, PPC_INTEGER);
1337 /* or & or. */ 1330 /* or & or. */
1338 GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER) 1331 GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER)
1339 { 1332 {
@@ -1344,55 +1337,54 @@ GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER) @@ -1344,55 +1337,54 @@ GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER)
1344 rb = rB(ctx->opcode); 1337 rb = rB(ctx->opcode);
1345 /* Optimisation for mr. ri case */ 1338 /* Optimisation for mr. ri case */
1346 if (rs != ra || rs != rb) { 1339 if (rs != ra || rs != rb) {
1347 - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rs]);  
1348 - if (rs != rb) {  
1349 - tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rb]);  
1350 - gen_op_or();  
1351 - }  
1352 - tcg_gen_mov_tl(cpu_gpr[ra], cpu_T[0]); 1340 + if (rs != rb)
  1341 + tcg_gen_or_tl(cpu_gpr[ra], cpu_gpr[rs], cpu_gpr[rb]);
  1342 + else
  1343 + tcg_gen_mov_tl(cpu_gpr[ra], cpu_gpr[rs]);
1353 if (unlikely(Rc(ctx->opcode) != 0)) 1344 if (unlikely(Rc(ctx->opcode) != 0))
1354 - gen_set_Rc0(ctx, cpu_T[0]); 1345 + gen_set_Rc0(ctx, cpu_gpr[ra]);
1355 } else if (unlikely(Rc(ctx->opcode) != 0)) { 1346 } else if (unlikely(Rc(ctx->opcode) != 0)) {
1356 - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rs]);  
1357 - gen_set_Rc0(ctx, cpu_T[0]); 1347 + gen_set_Rc0(ctx, cpu_gpr[rs]);
1358 #if defined(TARGET_PPC64) 1348 #if defined(TARGET_PPC64)
1359 } else { 1349 } else {
  1350 + int prio = 0;
  1351 +
1360 switch (rs) { 1352 switch (rs) {
1361 case 1: 1353 case 1:
1362 /* Set process priority to low */ 1354 /* Set process priority to low */
1363 - gen_op_store_pri(2); 1355 + prio = 2;
1364 break; 1356 break;
1365 case 6: 1357 case 6:
1366 /* Set process priority to medium-low */ 1358 /* Set process priority to medium-low */
1367 - gen_op_store_pri(3); 1359 + prio = 3;
1368 break; 1360 break;
1369 case 2: 1361 case 2:
1370 /* Set process priority to normal */ 1362 /* Set process priority to normal */
1371 - gen_op_store_pri(4); 1363 + prio = 4;
1372 break; 1364 break;
1373 #if !defined(CONFIG_USER_ONLY) 1365 #if !defined(CONFIG_USER_ONLY)
1374 case 31: 1366 case 31:
1375 if (ctx->supervisor > 0) { 1367 if (ctx->supervisor > 0) {
1376 /* Set process priority to very low */ 1368 /* Set process priority to very low */
1377 - gen_op_store_pri(1); 1369 + prio = 1;
1378 } 1370 }
1379 break; 1371 break;
1380 case 5: 1372 case 5:
1381 if (ctx->supervisor > 0) { 1373 if (ctx->supervisor > 0) {
1382 /* Set process priority to medium-hight */ 1374 /* Set process priority to medium-hight */
1383 - gen_op_store_pri(5); 1375 + prio = 5;
1384 } 1376 }
1385 break; 1377 break;
1386 case 3: 1378 case 3:
1387 if (ctx->supervisor > 0) { 1379 if (ctx->supervisor > 0) {
1388 /* Set process priority to high */ 1380 /* Set process priority to high */
1389 - gen_op_store_pri(6); 1381 + prio = 6;
1390 } 1382 }
1391 break; 1383 break;
1392 case 7: 1384 case 7:
1393 if (ctx->supervisor > 1) { 1385 if (ctx->supervisor > 1) {
1394 /* Set process priority to very high */ 1386 /* Set process priority to very high */
1395 - gen_op_store_pri(7); 1387 + prio = 7;
1396 } 1388 }
1397 break; 1389 break;
1398 #endif 1390 #endif
@@ -1400,26 +1392,29 @@ GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER) @@ -1400,26 +1392,29 @@ GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER)
1400 /* nop */ 1392 /* nop */
1401 break; 1393 break;
1402 } 1394 }
  1395 + if (prio) {
  1396 + TCGv temp = tcg_temp_new(TCG_TYPE_TL);
  1397 + tcg_gen_ld_tl(temp, cpu_env, offsetof(CPUState, spr[SPR_PPR]));
  1398 + tcg_gen_andi_tl(temp, temp, ~0x001C000000000000ULL);
  1399 + tcg_gen_ori_tl(temp, temp, ((uint64_t)prio) << 50);
  1400 + tcg_gen_st_tl(temp, cpu_env, offsetof(CPUState, spr[SPR_PPR]));
  1401 + tcg_temp_free(temp);
  1402 + }
1403 #endif 1403 #endif
1404 } 1404 }
1405 } 1405 }
1406 -  
1407 /* orc & orc. */ 1406 /* orc & orc. */
1408 -GEN_LOGICAL2(orc, 0x0C, PPC_INTEGER); 1407 +GEN_LOGICAL2(orc, tcg_gen_orc_tl, 0x0C, PPC_INTEGER);
1409 /* xor & xor. */ 1408 /* xor & xor. */
1410 GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER) 1409 GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER)
1411 { 1410 {
1412 - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);  
1413 /* Optimisation for "set to zero" case */ 1411 /* Optimisation for "set to zero" case */
1414 - if (rS(ctx->opcode) != rB(ctx->opcode)) {  
1415 - tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);  
1416 - gen_op_xor();  
1417 - } else {  
1418 - tcg_gen_movi_tl(cpu_T[0], 0);  
1419 - }  
1420 - tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]); 1412 + if (rS(ctx->opcode) != rB(ctx->opcode))
  1413 + tcg_gen_xor_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
  1414 + else
  1415 + tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
1421 if (unlikely(Rc(ctx->opcode) != 0)) 1416 if (unlikely(Rc(ctx->opcode) != 0))
1422 - gen_set_Rc0(ctx, cpu_T[0]); 1417 + gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1423 } 1418 }
1424 /* ori */ 1419 /* ori */
1425 GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) 1420 GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
@@ -1431,10 +1426,7 @@ GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) @@ -1431,10 +1426,7 @@ GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1431 /* XXX: should handle special NOPs for POWER series */ 1426 /* XXX: should handle special NOPs for POWER series */
1432 return; 1427 return;
1433 } 1428 }
1434 - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);  
1435 - if (likely(uimm != 0))  
1436 - gen_op_ori(uimm);  
1437 - tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]); 1429 + tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm);
1438 } 1430 }
1439 /* oris */ 1431 /* oris */
1440 GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) 1432 GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
@@ -1445,10 +1437,7 @@ GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) @@ -1445,10 +1437,7 @@ GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1445 /* NOP */ 1437 /* NOP */
1446 return; 1438 return;
1447 } 1439 }
1448 - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);  
1449 - if (likely(uimm != 0))  
1450 - gen_op_ori(uimm << 16);  
1451 - tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]); 1440 + tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm << 16);
1452 } 1441 }
1453 /* xori */ 1442 /* xori */
1454 GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) 1443 GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
@@ -1459,12 +1448,8 @@ GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) @@ -1459,12 +1448,8 @@ GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1459 /* NOP */ 1448 /* NOP */
1460 return; 1449 return;
1461 } 1450 }
1462 - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);  
1463 - if (likely(uimm != 0))  
1464 - gen_op_xori(uimm);  
1465 - tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]); 1451 + tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm);
1466 } 1452 }
1467 -  
1468 /* xoris */ 1453 /* xoris */
1469 GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) 1454 GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1470 { 1455 {
@@ -1474,30 +1459,29 @@ GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) @@ -1474,30 +1459,29 @@ GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1474 /* NOP */ 1459 /* NOP */
1475 return; 1460 return;
1476 } 1461 }
1477 - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);  
1478 - if (likely(uimm != 0))  
1479 - gen_op_xori(uimm << 16);  
1480 - tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]); 1462 + tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm << 16);
1481 } 1463 }
1482 -  
1483 /* popcntb : PowerPC 2.03 specification */ 1464 /* popcntb : PowerPC 2.03 specification */
1484 GEN_HANDLER(popcntb, 0x1F, 0x03, 0x03, 0x0000F801, PPC_POPCNTB) 1465 GEN_HANDLER(popcntb, 0x1F, 0x03, 0x03, 0x0000F801, PPC_POPCNTB)
1485 { 1466 {
1486 - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);  
1487 #if defined(TARGET_PPC64) 1467 #if defined(TARGET_PPC64)
1488 if (ctx->sf_mode) 1468 if (ctx->sf_mode)
1489 - gen_op_popcntb_64(); 1469 + tcg_gen_helper_1_1(helper_popcntb_64, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1490 else 1470 else
1491 #endif 1471 #endif
1492 - gen_op_popcntb();  
1493 - tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]); 1472 + tcg_gen_helper_1_1(helper_popcntb, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1494 } 1473 }
1495 1474
1496 #if defined(TARGET_PPC64) 1475 #if defined(TARGET_PPC64)
1497 /* extsw & extsw. */ 1476 /* extsw & extsw. */
1498 -GEN_LOGICAL1(extsw, 0x1E, PPC_64B); 1477 +GEN_LOGICAL1(extsw, tcg_gen_ext32s_tl, 0x1E, PPC_64B);
1499 /* cntlzd */ 1478 /* cntlzd */
1500 -GEN_LOGICAL1(cntlzd, 0x01, PPC_64B); 1479 +GEN_HANDLER(cntlzd, 0x1F, 0x1A, 0x01, 0x00000000, PPC_64B)
  1480 +{
  1481 + tcg_gen_helper_1_1(helper_cntlzd, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
  1482 + if (unlikely(Rc(ctx->opcode) != 0))
  1483 + gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
  1484 +}
1501 #endif 1485 #endif
1502 1486
1503 /*** Integer rotate ***/ 1487 /*** Integer rotate ***/
@@ -1759,54 +1743,141 @@ GEN_PPC64_R4(rldimi, 0x1E, 0x06); @@ -1759,54 +1743,141 @@ GEN_PPC64_R4(rldimi, 0x1E, 0x06);
1759 1743
1760 /*** Integer shift ***/ 1744 /*** Integer shift ***/
1761 /* slw & slw. */ 1745 /* slw & slw. */
1762 -__GEN_LOGICAL2(slw, 0x18, 0x00, PPC_INTEGER); 1746 +GEN_HANDLER(slw, 0x1F, 0x18, 0x00, 0x00000000, PPC_INTEGER)
  1747 +{
  1748 + TCGv temp;
  1749 + int l1, l2;
  1750 + l1 = gen_new_label();
  1751 + l2 = gen_new_label();
  1752 +
  1753 + temp = tcg_temp_local_new(TCG_TYPE_TL);
  1754 + tcg_gen_andi_tl(temp, cpu_gpr[rB(ctx->opcode)], 0x20);
  1755 + tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1);
  1756 + tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
  1757 + tcg_gen_br(l2);
  1758 + gen_set_label(l1);
  1759 + tcg_gen_andi_tl(temp, cpu_gpr[rB(ctx->opcode)], 0x3f);
  1760 + tcg_gen_shl_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], temp);
  1761 + tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
  1762 + gen_set_label(l2);
  1763 + tcg_temp_free(temp);
  1764 + if (unlikely(Rc(ctx->opcode) != 0))
  1765 + gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
  1766 +}
1763 /* sraw & sraw. */ 1767 /* sraw & sraw. */
1764 -__GEN_LOGICAL2(sraw, 0x18, 0x18, PPC_INTEGER); 1768 +GEN_HANDLER(sraw, 0x1F, 0x18, 0x18, 0x00000000, PPC_INTEGER)
  1769 +{
  1770 + tcg_gen_helper_1_2(helper_sraw, cpu_gpr[rA(ctx->opcode)],
  1771 + cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
  1772 + if (unlikely(Rc(ctx->opcode) != 0))
  1773 + gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
  1774 +}
1765 /* srawi & srawi. */ 1775 /* srawi & srawi. */
1766 GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER) 1776 GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER)
1767 { 1777 {
1768 - int mb, me;  
1769 - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);  
1770 - if (SH(ctx->opcode) != 0) {  
1771 - tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);  
1772 - mb = 32 - SH(ctx->opcode);  
1773 - me = 31;  
1774 -#if defined(TARGET_PPC64)  
1775 - mb += 32;  
1776 - me += 32;  
1777 -#endif  
1778 - gen_op_srawi(SH(ctx->opcode), MASK(mb, me)); 1778 + int sh = SH(ctx->opcode);
  1779 + if (sh != 0) {
  1780 + int l1, l2;
  1781 + TCGv temp;
  1782 + l1 = gen_new_label();
  1783 + l2 = gen_new_label();
  1784 + temp = tcg_temp_local_new(TCG_TYPE_TL);
  1785 + tcg_gen_ext32s_tl(temp, cpu_gpr[rS(ctx->opcode)]);
  1786 + tcg_gen_brcondi_tl(TCG_COND_GE, temp, 0, l1);
  1787 + tcg_gen_andi_tl(temp, cpu_gpr[rS(ctx->opcode)], (1ULL << sh) - 1);
  1788 + tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1);
  1789 + tcg_gen_ori_i32(cpu_xer, cpu_xer, 1 << XER_CA);
  1790 + tcg_gen_br(l2);
  1791 + gen_set_label(l1);
  1792 + tcg_gen_andi_i32(cpu_xer, cpu_xer, ~(1 << XER_CA));
  1793 + gen_set_label(l2);
  1794 + tcg_gen_ext32s_tl(temp, cpu_gpr[rS(ctx->opcode)]);
  1795 + tcg_gen_sari_tl(cpu_gpr[rA(ctx->opcode)], temp, sh);
  1796 + tcg_temp_free(temp);
  1797 + } else {
  1798 + tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
  1799 + tcg_gen_andi_i32(cpu_xer, cpu_xer, ~(1 << XER_CA));
1779 } 1800 }
1780 - tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);  
1781 if (unlikely(Rc(ctx->opcode) != 0)) 1801 if (unlikely(Rc(ctx->opcode) != 0))
1782 - gen_set_Rc0(ctx, cpu_T[0]); 1802 + gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1783 } 1803 }
1784 /* srw & srw. */ 1804 /* srw & srw. */
1785 -__GEN_LOGICAL2(srw, 0x18, 0x10, PPC_INTEGER); 1805 +GEN_HANDLER(srw, 0x1F, 0x18, 0x10, 0x00000000, PPC_INTEGER)
  1806 +{
  1807 + TCGv temp;
  1808 + int l1, l2;
  1809 + l1 = gen_new_label();
  1810 + l2 = gen_new_label();
1786 1811
  1812 + temp = tcg_temp_local_new(TCG_TYPE_TL);
  1813 + tcg_gen_andi_tl(temp, cpu_gpr[rB(ctx->opcode)], 0x20);
  1814 + tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1);
  1815 + tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
  1816 + tcg_gen_br(l2);
  1817 + gen_set_label(l1);
  1818 + tcg_gen_andi_tl(temp, cpu_gpr[rB(ctx->opcode)], 0x3f);
  1819 + tcg_gen_shr_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], temp);
  1820 + tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
  1821 + gen_set_label(l2);
  1822 + tcg_temp_free(temp);
  1823 + if (unlikely(Rc(ctx->opcode) != 0))
  1824 + gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
  1825 +}
1787 #if defined(TARGET_PPC64) 1826 #if defined(TARGET_PPC64)
1788 /* sld & sld. */ 1827 /* sld & sld. */
1789 -__GEN_LOGICAL2(sld, 0x1B, 0x00, PPC_64B); 1828 +GEN_HANDLER(sld, 0x1F, 0x1B, 0x00, 0x00000000, PPC_64B)
  1829 +{
  1830 + TCGv temp;
  1831 + int l1, l2;
  1832 + l1 = gen_new_label();
  1833 + l2 = gen_new_label();
  1834 +
  1835 + temp = tcg_temp_local_new(TCG_TYPE_TL);
  1836 + tcg_gen_andi_tl(temp, cpu_gpr[rB(ctx->opcode)], 0x40);
  1837 + tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1);
  1838 + tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
  1839 + tcg_gen_br(l2);
  1840 + gen_set_label(l1);
  1841 + tcg_gen_andi_tl(temp, cpu_gpr[rB(ctx->opcode)], 0x7f);
  1842 + tcg_gen_shl_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], temp);
  1843 + gen_set_label(l2);
  1844 + tcg_temp_free(temp);
  1845 + if (unlikely(Rc(ctx->opcode) != 0))
  1846 + gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
  1847 +}
1790 /* srad & srad. */ 1848 /* srad & srad. */
1791 -__GEN_LOGICAL2(srad, 0x1A, 0x18, PPC_64B); 1849 +GEN_HANDLER(srad, 0x1F, 0x1A, 0x18, 0x00000000, PPC_64B)
  1850 +{
  1851 + tcg_gen_helper_1_2(helper_srad, cpu_gpr[rA(ctx->opcode)],
  1852 + cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
  1853 + if (unlikely(Rc(ctx->opcode) != 0))
  1854 + gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
  1855 +}
1792 /* sradi & sradi. */ 1856 /* sradi & sradi. */
1793 static always_inline void gen_sradi (DisasContext *ctx, int n) 1857 static always_inline void gen_sradi (DisasContext *ctx, int n)
1794 { 1858 {
1795 - uint64_t mask;  
1796 - int sh, mb, me;  
1797 -  
1798 - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);  
1799 - sh = SH(ctx->opcode) + (n << 5); 1859 + int sh = SH(ctx->opcode) + (n << 5);
1800 if (sh != 0) { 1860 if (sh != 0) {
1801 - tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);  
1802 - mb = 64 - SH(ctx->opcode);  
1803 - me = 63;  
1804 - mask = MASK(mb, me);  
1805 - gen_op_sradi(sh, mask >> 32, mask); 1861 + int l1, l2;
  1862 + TCGv temp;
  1863 + l1 = gen_new_label();
  1864 + l2 = gen_new_label();
  1865 + tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rS(ctx->opcode)], 0, l1);
  1866 + temp = tcg_temp_new(TCG_TYPE_TL);
  1867 + tcg_gen_andi_tl(temp, cpu_gpr[rS(ctx->opcode)], (1ULL << sh) - 1);
  1868 + tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1);
  1869 + tcg_gen_ori_i32(cpu_xer, cpu_xer, 1 << XER_CA);
  1870 + tcg_gen_br(l2);
  1871 + gen_set_label(l1);
  1872 + tcg_gen_andi_i32(cpu_xer, cpu_xer, ~(1 << XER_CA));
  1873 + gen_set_label(l2);
  1874 + tcg_gen_sari_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], sh);
  1875 + } else {
  1876 + tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
  1877 + tcg_gen_andi_i32(cpu_xer, cpu_xer, ~(1 << XER_CA));
1806 } 1878 }
1807 - tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);  
1808 if (unlikely(Rc(ctx->opcode) != 0)) 1879 if (unlikely(Rc(ctx->opcode) != 0))
1809 - gen_set_Rc0(ctx, cpu_T[0]); 1880 + gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1810 } 1881 }
1811 GEN_HANDLER2(sradi0, "sradi", 0x1F, 0x1A, 0x19, 0x00000000, PPC_64B) 1882 GEN_HANDLER2(sradi0, "sradi", 0x1F, 0x1A, 0x19, 0x00000000, PPC_64B)
1812 { 1883 {
@@ -1817,7 +1888,26 @@ GEN_HANDLER2(sradi1, &quot;sradi&quot;, 0x1F, 0x1B, 0x19, 0x00000000, PPC_64B) @@ -1817,7 +1888,26 @@ GEN_HANDLER2(sradi1, &quot;sradi&quot;, 0x1F, 0x1B, 0x19, 0x00000000, PPC_64B)
1817 gen_sradi(ctx, 1); 1888 gen_sradi(ctx, 1);
1818 } 1889 }
1819 /* srd & srd. */ 1890 /* srd & srd. */
1820 -__GEN_LOGICAL2(srd, 0x1B, 0x10, PPC_64B); 1891 +GEN_HANDLER(srd, 0x1F, 0x1B, 0x10, 0x00000000, PPC_64B)
  1892 +{
  1893 + TCGv temp;
  1894 + int l1, l2;
  1895 + l1 = gen_new_label();
  1896 + l2 = gen_new_label();
  1897 +
  1898 + temp = tcg_temp_local_new(TCG_TYPE_TL);
  1899 + tcg_gen_andi_tl(temp, cpu_gpr[rB(ctx->opcode)], 0x40);
  1900 + tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1);
  1901 + tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
  1902 + tcg_gen_br(l2);
  1903 + gen_set_label(l1);
  1904 + tcg_gen_andi_tl(temp, cpu_gpr[rB(ctx->opcode)], 0x7f);
  1905 + tcg_gen_shr_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], temp);
  1906 + gen_set_label(l2);
  1907 + tcg_temp_free(temp);
  1908 + if (unlikely(Rc(ctx->opcode) != 0))
  1909 + gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
  1910 +}
1821 #endif 1911 #endif
1822 1912
1823 /*** Floating-Point arithmetic ***/ 1913 /*** Floating-Point arithmetic ***/