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 7  
8 8 DEF_HELPER(uint32_t, helper_load_cr, (void))
9 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 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 40 #if !defined(CONFIG_USER_ONLY)
50 41 /* Segment registers load and store */
51 42 void OPPROTO op_load_sr (void)
... ... @@ -921,101 +912,7 @@ void OPPROTO op_subfzeo_64 (void)
921 912 }
922 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 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 916 /* or */
1020 917 void OPPROTO op_or (void)
1021 918 {
... ... @@ -1023,34 +920,6 @@ void OPPROTO op_or (void)
1023 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 923 /*** Integer rotate ***/
1055 924 void OPPROTO op_rotl32_T0_T1 (void)
1056 925 {
... ... @@ -1079,122 +948,13 @@ void OPPROTO op_rotli64_T0 (void)
1079 948 #endif
1080 949  
1081 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 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 952 void OPPROTO op_sli_T0 (void)
1179 953 {
1180 954 T0 = T0 << PARAM1;
1181 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 958 void OPPROTO op_srli_T0 (void)
1199 959 {
1200 960 T0 = (uint32_t)T0 >> PARAM1;
... ... @@ -1215,14 +975,6 @@ void OPPROTO op_srli_T1 (void)
1215 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 978 /*** Floating-Point arithmetic ***/
1227 979 /* fadd - fadd. */
1228 980 void OPPROTO op_fadd (void)
... ...
target-ppc/op_helper.c
... ... @@ -368,96 +368,98 @@ void do_subfzeo_64 (void)
368 368 }
369 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 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 381 #endif
382 382  
383 383 /* shift right arithmetic helper */
384   -void do_sraw (void)
  384 +target_ulong helper_sraw (target_ulong value, target_ulong shift)
385 385 {
386 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 393 env->xer &= ~(1 << XER_CA);
393 394 } else {
394 395 env->xer |= (1 << XER_CA);
395 396 }
396 397 } else {
397   - ret = T0;
  398 + ret = (int32_t)value;
398 399 env->xer &= ~(1 << XER_CA);
399 400 }
400 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 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 412 #if defined(TARGET_PPC64)
412   -void do_srad (void)
  413 +target_ulong helper_srad (target_ulong value, target_ulong shift)
413 414 {
414 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 422 env->xer &= ~(1 << XER_CA);
421 423 } else {
422 424 env->xer |= (1 << XER_CA);
423 425 }
424 426 } else {
425   - ret = T0;
  427 + ret = (int64_t)value;
426 428 env->xer &= ~(1 << XER_CA);
427 429 }
428 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 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 440 #endif
439 441  
440   -void do_popcntb (void)
  442 +target_ulong helper_popcntb (target_ulong val)
441 443 {
442 444 uint32_t ret;
443 445 int i;
444 446  
445 447 ret = 0;
446 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 453 #if defined(TARGET_PPC64)
452   -void do_popcntb_64 (void)
  454 +target_ulong helper_popcntb_64 (target_ulong val)
453 455 {
454 456 uint64_t ret;
455 457 int i;
456 458  
457 459 ret = 0;
458 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 464 #endif
463 465  
... ...
target-ppc/translate.c
... ... @@ -1277,63 +1277,56 @@ GEN_INT_ARITH2 (divdu, 0x1F, 0x09, 0x0E, PPC_64B);
1277 1277 #endif
1278 1278  
1279 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 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 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 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 1297 /* and & and. */
1304   -GEN_LOGICAL2(and, 0x00, PPC_INTEGER);
  1298 +GEN_LOGICAL2(and, tcg_gen_and_tl, 0x00, PPC_INTEGER);
1305 1299 /* andc & andc. */
1306   -GEN_LOGICAL2(andc, 0x01, PPC_INTEGER);
  1300 +GEN_LOGICAL2(andc, tcg_gen_andc_tl, 0x01, PPC_INTEGER);
1307 1301 /* andi. */
1308 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 1307 /* andis. */
1316 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 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 1320 /* eqv & eqv. */
1327   -GEN_LOGICAL2(eqv, 0x08, PPC_INTEGER);
  1321 +GEN_LOGICAL2(eqv, tcg_gen_eqv_tl, 0x08, PPC_INTEGER);
1328 1322 /* extsb & extsb. */
1329   -GEN_LOGICAL1(extsb, 0x1D, PPC_INTEGER);
  1323 +GEN_LOGICAL1(extsb, tcg_gen_ext8s_tl, 0x1D, PPC_INTEGER);
1330 1324 /* extsh & extsh. */
1331   -GEN_LOGICAL1(extsh, 0x1C, PPC_INTEGER);
  1325 +GEN_LOGICAL1(extsh, tcg_gen_ext16s_tl, 0x1C, PPC_INTEGER);
1332 1326 /* nand & nand. */
1333   -GEN_LOGICAL2(nand, 0x0E, PPC_INTEGER);
  1327 +GEN_LOGICAL2(nand, tcg_gen_nand_tl, 0x0E, PPC_INTEGER);
1334 1328 /* nor & nor. */
1335   -GEN_LOGICAL2(nor, 0x03, PPC_INTEGER);
1336   -
  1329 +GEN_LOGICAL2(nor, tcg_gen_nor_tl, 0x03, PPC_INTEGER);
1337 1330 /* or & or. */
1338 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 1337 rb = rB(ctx->opcode);
1345 1338 /* Optimisation for mr. ri case */
1346 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 1344 if (unlikely(Rc(ctx->opcode) != 0))
1354   - gen_set_Rc0(ctx, cpu_T[0]);
  1345 + gen_set_Rc0(ctx, cpu_gpr[ra]);
1355 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 1348 #if defined(TARGET_PPC64)
1359 1349 } else {
  1350 + int prio = 0;
  1351 +
1360 1352 switch (rs) {
1361 1353 case 1:
1362 1354 /* Set process priority to low */
1363   - gen_op_store_pri(2);
  1355 + prio = 2;
1364 1356 break;
1365 1357 case 6:
1366 1358 /* Set process priority to medium-low */
1367   - gen_op_store_pri(3);
  1359 + prio = 3;
1368 1360 break;
1369 1361 case 2:
1370 1362 /* Set process priority to normal */
1371   - gen_op_store_pri(4);
  1363 + prio = 4;
1372 1364 break;
1373 1365 #if !defined(CONFIG_USER_ONLY)
1374 1366 case 31:
1375 1367 if (ctx->supervisor > 0) {
1376 1368 /* Set process priority to very low */
1377   - gen_op_store_pri(1);
  1369 + prio = 1;
1378 1370 }
1379 1371 break;
1380 1372 case 5:
1381 1373 if (ctx->supervisor > 0) {
1382 1374 /* Set process priority to medium-hight */
1383   - gen_op_store_pri(5);
  1375 + prio = 5;
1384 1376 }
1385 1377 break;
1386 1378 case 3:
1387 1379 if (ctx->supervisor > 0) {
1388 1380 /* Set process priority to high */
1389   - gen_op_store_pri(6);
  1381 + prio = 6;
1390 1382 }
1391 1383 break;
1392 1384 case 7:
1393 1385 if (ctx->supervisor > 1) {
1394 1386 /* Set process priority to very high */
1395   - gen_op_store_pri(7);
  1387 + prio = 7;
1396 1388 }
1397 1389 break;
1398 1390 #endif
... ... @@ -1400,26 +1392,29 @@ GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER)
1400 1392 /* nop */
1401 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 1403 #endif
1404 1404 }
1405 1405 }
1406   -
1407 1406 /* orc & orc. */
1408   -GEN_LOGICAL2(orc, 0x0C, PPC_INTEGER);
  1407 +GEN_LOGICAL2(orc, tcg_gen_orc_tl, 0x0C, PPC_INTEGER);
1409 1408 /* xor & xor. */
1410 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 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 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 1419 /* ori */
1425 1420 GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
... ... @@ -1431,10 +1426,7 @@ GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1431 1426 /* XXX: should handle special NOPs for POWER series */
1432 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 1431 /* oris */
1440 1432 GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
... ... @@ -1445,10 +1437,7 @@ GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1445 1437 /* NOP */
1446 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 1442 /* xori */
1454 1443 GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
... ... @@ -1459,12 +1448,8 @@ GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1459 1448 /* NOP */
1460 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 1453 /* xoris */
1469 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 1459 /* NOP */
1475 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 1464 /* popcntb : PowerPC 2.03 specification */
1484 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 1467 #if defined(TARGET_PPC64)
1488 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 1470 else
1491 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 1475 #if defined(TARGET_PPC64)
1497 1476 /* extsw & extsw. */
1498   -GEN_LOGICAL1(extsw, 0x1E, PPC_64B);
  1477 +GEN_LOGICAL1(extsw, tcg_gen_ext32s_tl, 0x1E, PPC_64B);
1499 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 1485 #endif
1502 1486  
1503 1487 /*** Integer rotate ***/
... ... @@ -1759,54 +1743,141 @@ GEN_PPC64_R4(rldimi, 0x1E, 0x06);
1759 1743  
1760 1744 /*** Integer shift ***/
1761 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 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 1775 /* srawi & srawi. */
1766 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 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 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 1826 #if defined(TARGET_PPC64)
1788 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 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 1856 /* sradi & sradi. */
1793 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 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 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 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 1888 gen_sradi(ctx, 1);
1818 1889 }
1819 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 1911 #endif
1822 1912  
1823 1913 /*** Floating-Point arithmetic ***/
... ...