Commit 51789c410beb34423b1188a6b6e069fe8b68aebe

Authored by j_mayer
1 parent e864cabd

PowerPC improvments:

- add missing 64 bits rotate instructions
- safely define TARGET_PPCSPE when 64 bits registers are used
  a separate target will be needed to use it in 32 bits mode on 32 bits hosts.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2527 c046a42c-6fe2-441c-8c8c-71466251a162
target-ppc/cpu.h
... ... @@ -23,13 +23,18 @@
23 23 #include "config.h"
24 24 #include <stdint.h>
25 25  
  26 +#if defined(TARGET_PPC64) || (HOST_LONG_BITS >= 64)
  27 +/* When using 64 bits temporary registers,
  28 + * we can use 64 bits GPR with no extra cost
  29 + */
  30 +#define TARGET_PPCSPE
  31 +#endif
  32 +
26 33 #if defined (TARGET_PPC64)
27 34 typedef uint64_t ppc_gpr_t;
28 35 #define TARGET_LONG_BITS 64
29 36 #define TARGET_GPR_BITS 64
30 37 #define REGX "%016" PRIx64
31   -/* We can safely use PowerPC SPE extension when compiling PowerPC 64 */
32   -#define TARGET_PPCSPE
33 38 #elif defined(TARGET_PPCSPE)
34 39 /* GPR are 64 bits: used by vector extension */
35 40 typedef uint64_t ppc_gpr_t;
... ...
target-ppc/op.c
... ... @@ -1444,6 +1444,20 @@ void OPPROTO op_rotli32_T0 (void)
1444 1444 RETURN();
1445 1445 }
1446 1446  
  1447 +#if defined(TARGET_PPC64)
  1448 +void OPPROTO op_rotl64_T0_T1 (void)
  1449 +{
  1450 + T0 = rotl64(T0, T1 & 0x3F);
  1451 + RETURN();
  1452 +}
  1453 +
  1454 +void OPPROTO op_rotli64_T0 (void)
  1455 +{
  1456 + T0 = rotl64(T0, PARAM1);
  1457 + RETURN();
  1458 +}
  1459 +#endif
  1460 +
1447 1461 /*** Integer shift ***/
1448 1462 /* shift left word */
1449 1463 void OPPROTO op_slw (void)
... ...
target-ppc/translate.c
... ... @@ -1109,12 +1109,10 @@ GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1109 1109 {
1110 1110 target_ulong mask;
1111 1111 uint32_t mb, me, sh;
1112   - int n;
1113 1112  
1114 1113 mb = MB(ctx->opcode);
1115 1114 me = ME(ctx->opcode);
1116 1115 sh = SH(ctx->opcode);
1117   - n = me + 1 - mb;
1118 1116 if (likely(sh == 0)) {
1119 1117 if (likely(mb == 0 && me == 31)) {
1120 1118 gen_op_load_gpr_T0(rS(ctx->opcode));
... ... @@ -1231,68 +1229,130 @@ GEN_HANDLER(name##3, opc1, opc2 | 0x11, 0xFF, 0x00000000, PPC_64B) \
1231 1229 { \
1232 1230 gen_##name(ctx, 1, 1); \
1233 1231 }
  1232 +
  1233 +static inline void gen_rldinm (DisasContext *ctx, uint32_t mb, uint32_t me,
  1234 + uint32_t sh)
  1235 +{
  1236 + gen_op_load_gpr_T0(rS(ctx->opcode));
  1237 + if (likely(sh == 0)) {
  1238 + goto do_mask;
  1239 + }
  1240 + if (likely(mb == 0)) {
  1241 + if (likely(me == 63)) {
  1242 + gen_op_rotli32_T0(sh);
  1243 + goto do_store;
  1244 + } else if (likely(me == (63 - sh))) {
  1245 + gen_op_sli_T0(sh);
  1246 + goto do_store;
  1247 + }
  1248 + } else if (likely(me == 63)) {
  1249 + if (likely(sh == (64 - mb))) {
  1250 + gen_op_srli_T0(mb);
  1251 + goto do_store;
  1252 + }
  1253 + }
  1254 + gen_op_rotli64_T0(sh);
  1255 + do_mask:
  1256 + gen_op_andi_T0(MASK(mb, me));
  1257 + do_store:
  1258 + gen_op_store_T0_gpr(rA(ctx->opcode));
  1259 + if (unlikely(Rc(ctx->opcode) != 0))
  1260 + gen_set_Rc0(ctx);
  1261 +}
1234 1262 /* rldicl - rldicl. */
1235 1263 static inline void gen_rldicl (DisasContext *ctx, int mbn, int shn)
1236 1264 {
1237   - int sh, mb;
  1265 + uint32_t sh, mb;
1238 1266  
1239 1267 sh = SH(ctx->opcode) | (1 << shn);
1240 1268 mb = (MB(ctx->opcode) << 1) | mbn;
1241   - /* XXX: TODO */
1242   - RET_INVAL(ctx);
  1269 + gen_rldinm(ctx, mb, 63, sh);
1243 1270 }
1244   -GEN_PPC64_R4(rldicl, 0x1E, 0x00)
  1271 +GEN_PPC64_R4(rldicl, 0x1E, 0x00);
1245 1272 /* rldicr - rldicr. */
1246 1273 static inline void gen_rldicr (DisasContext *ctx, int men, int shn)
1247 1274 {
1248   - int sh, me;
  1275 + uint32_t sh, me;
1249 1276  
1250 1277 sh = SH(ctx->opcode) | (1 << shn);
1251 1278 me = (MB(ctx->opcode) << 1) | men;
1252   - /* XXX: TODO */
1253   - RET_INVAL(ctx);
  1279 + gen_rldinm(ctx, 0, me, sh);
1254 1280 }
1255   -GEN_PPC64_R4(rldicr, 0x1E, 0x02)
  1281 +GEN_PPC64_R4(rldicr, 0x1E, 0x02);
1256 1282 /* rldic - rldic. */
1257 1283 static inline void gen_rldic (DisasContext *ctx, int mbn, int shn)
1258 1284 {
1259   - int sh, mb;
  1285 + uint32_t sh, mb;
1260 1286  
1261 1287 sh = SH(ctx->opcode) | (1 << shn);
1262 1288 mb = (MB(ctx->opcode) << 1) | mbn;
1263   - /* XXX: TODO */
1264   - RET_INVAL(ctx);
  1289 + gen_rldinm(ctx, mb, 63 - sh, sh);
1265 1290 }
1266   -GEN_PPC64_R4(rldic, 0x1E, 0x04)
  1291 +GEN_PPC64_R4(rldic, 0x1E, 0x04);
  1292 +
  1293 +static inline void gen_rldnm (DisasContext *ctx, uint32_t mb, uint32_t me)
  1294 +{
  1295 + gen_op_load_gpr_T0(rS(ctx->opcode));
  1296 + gen_op_load_gpr_T1(rB(ctx->opcode));
  1297 + gen_op_rotl64_T0_T1();
  1298 + if (unlikely(mb != 0 || me != 63)) {
  1299 + gen_op_andi_T0(MASK(mb, me));
  1300 + }
  1301 + gen_op_store_T0_gpr(rA(ctx->opcode));
  1302 + if (unlikely(Rc(ctx->opcode) != 0))
  1303 + gen_set_Rc0(ctx);
  1304 +}
  1305 +
1267 1306 /* rldcl - rldcl. */
1268 1307 static inline void gen_rldcl (DisasContext *ctx, int mbn)
1269 1308 {
1270   - int mb;
  1309 + uint32_t mb;
1271 1310  
1272 1311 mb = (MB(ctx->opcode) << 1) | mbn;
1273   - /* XXX: TODO */
1274   - RET_INVAL(ctx);
  1312 + gen_rldnm(ctx, mb, 63);
1275 1313 }
1276 1314 GEN_PPC64_R2(rldcl, 0x1E, 0x08)
1277 1315 /* rldcr - rldcr. */
1278 1316 static inline void gen_rldcr (DisasContext *ctx, int men)
1279 1317 {
1280   - int me;
  1318 + uint32_t me;
1281 1319  
1282 1320 me = (MB(ctx->opcode) << 1) | men;
1283   - /* XXX: TODO */
1284   - RET_INVAL(ctx);
  1321 + gen_rldnm(ctx, 0, me);
1285 1322 }
1286 1323 GEN_PPC64_R2(rldcr, 0x1E, 0x09)
1287 1324 /* rldimi - rldimi. */
1288 1325 static inline void gen_rldimi (DisasContext *ctx, int mbn, int shn)
1289 1326 {
1290   - int sh, mb;
  1327 + uint64_t mask;
  1328 + uint32_t sh, mb;
1291 1329  
1292 1330 sh = SH(ctx->opcode) | (1 << shn);
1293 1331 mb = (MB(ctx->opcode) << 1) | mbn;
1294   - /* XXX: TODO */
1295   - RET_INVAL(ctx);
  1332 + if (likely(sh == 0)) {
  1333 + if (likely(mb == 0)) {
  1334 + gen_op_load_gpr_T0(rS(ctx->opcode));
  1335 + goto do_store;
  1336 + } else if (likely(mb == 63)) {
  1337 + gen_op_load_gpr_T0(rA(ctx->opcode));
  1338 + goto do_store;
  1339 + }
  1340 + gen_op_load_gpr_T0(rS(ctx->opcode));
  1341 + gen_op_load_gpr_T1(rA(ctx->opcode));
  1342 + goto do_mask;
  1343 + }
  1344 + gen_op_load_gpr_T0(rS(ctx->opcode));
  1345 + gen_op_load_gpr_T1(rA(ctx->opcode));
  1346 + gen_op_rotli64_T0(SH(ctx->opcode));
  1347 + do_mask:
  1348 + mask = MASK(mb, 63 - sh);
  1349 + gen_op_andi_T0(mask);
  1350 + gen_op_andi_T1(~mask);
  1351 + gen_op_or();
  1352 + do_store:
  1353 + gen_op_store_T0_gpr(rA(ctx->opcode));
  1354 + if (unlikely(Rc(ctx->opcode) != 0))
  1355 + gen_set_Rc0(ctx);
1296 1356 }
1297 1357 GEN_PPC64_R4(rldimi, 0x1E, 0x06)
1298 1358 #endif
... ...