Commit 40d0591e2c4922f545ebf1c9a3bd89e73e8428b4
1 parent
92a343da
Fixes for PowerPC 64 rotate and mask instructions.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3247 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
38 additions
and
7 deletions
target-ppc/op.c
| @@ -1353,6 +1353,21 @@ void OPPROTO op_andi_T1 (void) | @@ -1353,6 +1353,21 @@ void OPPROTO op_andi_T1 (void) | ||
| 1353 | RETURN(); | 1353 | RETURN(); |
| 1354 | } | 1354 | } |
| 1355 | 1355 | ||
| 1356 | +#if defined(TARGET_PPC64) | ||
| 1357 | +void OPPROTO op_andi_T0_64 (void) | ||
| 1358 | +{ | ||
| 1359 | + T0 &= ((uint64_t)PARAM1 << 32) | PARAM2; | ||
| 1360 | + RETURN(); | ||
| 1361 | +} | ||
| 1362 | + | ||
| 1363 | +void OPPROTO op_andi_T1_64 (void) | ||
| 1364 | +{ | ||
| 1365 | + T1 &= ((uint64_t)PARAM1 << 32) | PARAM2; | ||
| 1366 | + RETURN(); | ||
| 1367 | +} | ||
| 1368 | +#endif | ||
| 1369 | + | ||
| 1370 | + | ||
| 1356 | /* count leading zero */ | 1371 | /* count leading zero */ |
| 1357 | void OPPROTO op_cntlzw (void) | 1372 | void OPPROTO op_cntlzw (void) |
| 1358 | { | 1373 | { |
target-ppc/translate.c
| @@ -1339,6 +1339,22 @@ GEN_HANDLER(name##3, opc1, opc2 | 0x11, 0xFF, 0x00000000, PPC_64B) \ | @@ -1339,6 +1339,22 @@ GEN_HANDLER(name##3, opc1, opc2 | 0x11, 0xFF, 0x00000000, PPC_64B) \ | ||
| 1339 | gen_##name(ctx, 1, 1); \ | 1339 | gen_##name(ctx, 1, 1); \ |
| 1340 | } | 1340 | } |
| 1341 | 1341 | ||
| 1342 | +static inline void gen_andi_T0_64 (DisasContext *ctx, uint64_t mask) | ||
| 1343 | +{ | ||
| 1344 | + if (mask >> 32) | ||
| 1345 | + gen_op_andi_T0_64(mask >> 32, mask & 0xFFFFFFFF); | ||
| 1346 | + else | ||
| 1347 | + gen_op_andi_T0(mask); | ||
| 1348 | +} | ||
| 1349 | + | ||
| 1350 | +static inline void gen_andi_T1_64 (DisasContext *ctx, uint64_t mask) | ||
| 1351 | +{ | ||
| 1352 | + if (mask >> 32) | ||
| 1353 | + gen_op_andi_T1_64(mask >> 32, mask & 0xFFFFFFFF); | ||
| 1354 | + else | ||
| 1355 | + gen_op_andi_T1(mask); | ||
| 1356 | +} | ||
| 1357 | + | ||
| 1342 | static inline void gen_rldinm (DisasContext *ctx, uint32_t mb, uint32_t me, | 1358 | static inline void gen_rldinm (DisasContext *ctx, uint32_t mb, uint32_t me, |
| 1343 | uint32_t sh) | 1359 | uint32_t sh) |
| 1344 | { | 1360 | { |
| @@ -1348,7 +1364,7 @@ static inline void gen_rldinm (DisasContext *ctx, uint32_t mb, uint32_t me, | @@ -1348,7 +1364,7 @@ static inline void gen_rldinm (DisasContext *ctx, uint32_t mb, uint32_t me, | ||
| 1348 | } | 1364 | } |
| 1349 | if (likely(mb == 0)) { | 1365 | if (likely(mb == 0)) { |
| 1350 | if (likely(me == 63)) { | 1366 | if (likely(me == 63)) { |
| 1351 | - gen_op_rotli32_T0(sh); | 1367 | + gen_op_rotli64_T0(sh); |
| 1352 | goto do_store; | 1368 | goto do_store; |
| 1353 | } else if (likely(me == (63 - sh))) { | 1369 | } else if (likely(me == (63 - sh))) { |
| 1354 | gen_op_sli_T0(sh); | 1370 | gen_op_sli_T0(sh); |
| @@ -1356,13 +1372,13 @@ static inline void gen_rldinm (DisasContext *ctx, uint32_t mb, uint32_t me, | @@ -1356,13 +1372,13 @@ static inline void gen_rldinm (DisasContext *ctx, uint32_t mb, uint32_t me, | ||
| 1356 | } | 1372 | } |
| 1357 | } else if (likely(me == 63)) { | 1373 | } else if (likely(me == 63)) { |
| 1358 | if (likely(sh == (64 - mb))) { | 1374 | if (likely(sh == (64 - mb))) { |
| 1359 | - gen_op_srli_T0(mb); | 1375 | + gen_op_srli_T0_64(mb); |
| 1360 | goto do_store; | 1376 | goto do_store; |
| 1361 | } | 1377 | } |
| 1362 | } | 1378 | } |
| 1363 | gen_op_rotli64_T0(sh); | 1379 | gen_op_rotli64_T0(sh); |
| 1364 | do_mask: | 1380 | do_mask: |
| 1365 | - gen_op_andi_T0(MASK(mb, me)); | 1381 | + gen_andi_T0_64(ctx, MASK(mb, me)); |
| 1366 | do_store: | 1382 | do_store: |
| 1367 | gen_op_store_T0_gpr(rA(ctx->opcode)); | 1383 | gen_op_store_T0_gpr(rA(ctx->opcode)); |
| 1368 | if (unlikely(Rc(ctx->opcode) != 0)) | 1384 | if (unlikely(Rc(ctx->opcode) != 0)) |
| @@ -1405,7 +1421,7 @@ static inline void gen_rldnm (DisasContext *ctx, uint32_t mb, uint32_t me) | @@ -1405,7 +1421,7 @@ static inline void gen_rldnm (DisasContext *ctx, uint32_t mb, uint32_t me) | ||
| 1405 | gen_op_load_gpr_T1(rB(ctx->opcode)); | 1421 | gen_op_load_gpr_T1(rB(ctx->opcode)); |
| 1406 | gen_op_rotl64_T0_T1(); | 1422 | gen_op_rotl64_T0_T1(); |
| 1407 | if (unlikely(mb != 0 || me != 63)) { | 1423 | if (unlikely(mb != 0 || me != 63)) { |
| 1408 | - gen_op_andi_T0(MASK(mb, me)); | 1424 | + gen_andi_T0_64(ctx, MASK(mb, me)); |
| 1409 | } | 1425 | } |
| 1410 | gen_op_store_T0_gpr(rA(ctx->opcode)); | 1426 | gen_op_store_T0_gpr(rA(ctx->opcode)); |
| 1411 | if (unlikely(Rc(ctx->opcode) != 0)) | 1427 | if (unlikely(Rc(ctx->opcode) != 0)) |
| @@ -1452,11 +1468,11 @@ static inline void gen_rldimi (DisasContext *ctx, int mbn, int shn) | @@ -1452,11 +1468,11 @@ static inline void gen_rldimi (DisasContext *ctx, int mbn, int shn) | ||
| 1452 | } | 1468 | } |
| 1453 | gen_op_load_gpr_T0(rS(ctx->opcode)); | 1469 | gen_op_load_gpr_T0(rS(ctx->opcode)); |
| 1454 | gen_op_load_gpr_T1(rA(ctx->opcode)); | 1470 | gen_op_load_gpr_T1(rA(ctx->opcode)); |
| 1455 | - gen_op_rotli64_T0(SH(ctx->opcode)); | 1471 | + gen_op_rotli64_T0(sh); |
| 1456 | do_mask: | 1472 | do_mask: |
| 1457 | mask = MASK(mb, 63 - sh); | 1473 | mask = MASK(mb, 63 - sh); |
| 1458 | - gen_op_andi_T0(mask); | ||
| 1459 | - gen_op_andi_T1(~mask); | 1474 | + gen_andi_T0_64(ctx, mask); |
| 1475 | + gen_andi_T1_64(ctx, ~mask); | ||
| 1460 | gen_op_or(); | 1476 | gen_op_or(); |
| 1461 | do_store: | 1477 | do_store: |
| 1462 | gen_op_store_T0_gpr(rA(ctx->opcode)); | 1478 | gen_op_store_T0_gpr(rA(ctx->opcode)); |