Commit 7487953d704369c7acc7486f09eaf87faa5d3693
1 parent
54cdcae6
target-ppc: convert POWER shift instructions to TCG
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5882 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
258 additions
and
241 deletions
target-ppc/exec.h
| ... | ... | @@ -51,28 +51,6 @@ register target_ulong T2 asm(AREG3); |
| 51 | 51 | # define RETURN() __asm__ __volatile__("" : : : "memory"); |
| 52 | 52 | #endif |
| 53 | 53 | |
| 54 | -static always_inline target_ulong rotl8 (target_ulong i, int n) | |
| 55 | -{ | |
| 56 | - return (((uint8_t)i << n) | ((uint8_t)i >> (8 - n))); | |
| 57 | -} | |
| 58 | - | |
| 59 | -static always_inline target_ulong rotl16 (target_ulong i, int n) | |
| 60 | -{ | |
| 61 | - return (((uint16_t)i << n) | ((uint16_t)i >> (16 - n))); | |
| 62 | -} | |
| 63 | - | |
| 64 | -static always_inline target_ulong rotl32 (target_ulong i, int n) | |
| 65 | -{ | |
| 66 | - return (((uint32_t)i << n) | ((uint32_t)i >> (32 - n))); | |
| 67 | -} | |
| 68 | - | |
| 69 | -#if defined(TARGET_PPC64) | |
| 70 | -static always_inline target_ulong rotl64 (target_ulong i, int n) | |
| 71 | -{ | |
| 72 | - return (((uint64_t)i << n) | ((uint64_t)i >> (64 - n))); | |
| 73 | -} | |
| 74 | -#endif | |
| 75 | - | |
| 76 | 54 | #if !defined(CONFIG_USER_ONLY) |
| 77 | 55 | #include "softmmu_exec.h" |
| 78 | 56 | #endif /* !defined(CONFIG_USER_ONLY) */ | ... | ... |
target-ppc/op.c
| ... | ... | @@ -476,133 +476,6 @@ void OPPROTO op_POWER_nabso (void) |
| 476 | 476 | RETURN(); |
| 477 | 477 | } |
| 478 | 478 | |
| 479 | -/* XXX: factorise POWER rotates... */ | |
| 480 | -void OPPROTO op_POWER_rlmi (void) | |
| 481 | -{ | |
| 482 | - T0 = rotl32(T0, T2) & PARAM1; | |
| 483 | - T0 |= T1 & (uint32_t)PARAM2; | |
| 484 | - RETURN(); | |
| 485 | -} | |
| 486 | - | |
| 487 | -void OPPROTO op_POWER_rrib (void) | |
| 488 | -{ | |
| 489 | - T2 &= 0x1FUL; | |
| 490 | - T0 = rotl32(T0 & INT32_MIN, T2); | |
| 491 | - T0 |= T1 & ~rotl32(INT32_MIN, T2); | |
| 492 | - RETURN(); | |
| 493 | -} | |
| 494 | - | |
| 495 | -void OPPROTO op_POWER_sle (void) | |
| 496 | -{ | |
| 497 | - T1 &= 0x1FUL; | |
| 498 | - env->spr[SPR_MQ] = rotl32(T0, T1); | |
| 499 | - T0 = T0 << T1; | |
| 500 | - RETURN(); | |
| 501 | -} | |
| 502 | - | |
| 503 | -void OPPROTO op_POWER_sleq (void) | |
| 504 | -{ | |
| 505 | - uint32_t tmp = env->spr[SPR_MQ]; | |
| 506 | - | |
| 507 | - T1 &= 0x1FUL; | |
| 508 | - env->spr[SPR_MQ] = rotl32(T0, T1); | |
| 509 | - T0 = T0 << T1; | |
| 510 | - T0 |= tmp >> (32 - T1); | |
| 511 | - RETURN(); | |
| 512 | -} | |
| 513 | - | |
| 514 | -void OPPROTO op_POWER_sllq (void) | |
| 515 | -{ | |
| 516 | - uint32_t msk = UINT32_MAX; | |
| 517 | - | |
| 518 | - msk = msk << (T1 & 0x1FUL); | |
| 519 | - if (T1 & 0x20UL) | |
| 520 | - msk = ~msk; | |
| 521 | - T1 &= 0x1FUL; | |
| 522 | - T0 = (T0 << T1) & msk; | |
| 523 | - T0 |= env->spr[SPR_MQ] & ~msk; | |
| 524 | - RETURN(); | |
| 525 | -} | |
| 526 | - | |
| 527 | -void OPPROTO op_POWER_slq (void) | |
| 528 | -{ | |
| 529 | - uint32_t msk = UINT32_MAX, tmp; | |
| 530 | - | |
| 531 | - msk = msk << (T1 & 0x1FUL); | |
| 532 | - if (T1 & 0x20UL) | |
| 533 | - msk = ~msk; | |
| 534 | - T1 &= 0x1FUL; | |
| 535 | - tmp = rotl32(T0, T1); | |
| 536 | - T0 = tmp & msk; | |
| 537 | - env->spr[SPR_MQ] = tmp; | |
| 538 | - RETURN(); | |
| 539 | -} | |
| 540 | - | |
| 541 | -void OPPROTO op_POWER_sraq (void) | |
| 542 | -{ | |
| 543 | - env->spr[SPR_MQ] = rotl32(T0, 32 - (T1 & 0x1FUL)); | |
| 544 | - if (T1 & 0x20UL) | |
| 545 | - T0 = UINT32_MAX; | |
| 546 | - else | |
| 547 | - T0 = (int32_t)T0 >> T1; | |
| 548 | - RETURN(); | |
| 549 | -} | |
| 550 | - | |
| 551 | -void OPPROTO op_POWER_sre (void) | |
| 552 | -{ | |
| 553 | - T1 &= 0x1FUL; | |
| 554 | - env->spr[SPR_MQ] = rotl32(T0, 32 - T1); | |
| 555 | - T0 = (int32_t)T0 >> T1; | |
| 556 | - RETURN(); | |
| 557 | -} | |
| 558 | - | |
| 559 | -void OPPROTO op_POWER_srea (void) | |
| 560 | -{ | |
| 561 | - T1 &= 0x1FUL; | |
| 562 | - env->spr[SPR_MQ] = T0 >> T1; | |
| 563 | - T0 = (int32_t)T0 >> T1; | |
| 564 | - RETURN(); | |
| 565 | -} | |
| 566 | - | |
| 567 | -void OPPROTO op_POWER_sreq (void) | |
| 568 | -{ | |
| 569 | - uint32_t tmp; | |
| 570 | - int32_t msk; | |
| 571 | - | |
| 572 | - T1 &= 0x1FUL; | |
| 573 | - msk = INT32_MIN >> T1; | |
| 574 | - tmp = env->spr[SPR_MQ]; | |
| 575 | - env->spr[SPR_MQ] = rotl32(T0, 32 - T1); | |
| 576 | - T0 = T0 >> T1; | |
| 577 | - T0 |= tmp & msk; | |
| 578 | - RETURN(); | |
| 579 | -} | |
| 580 | - | |
| 581 | -void OPPROTO op_POWER_srlq (void) | |
| 582 | -{ | |
| 583 | - uint32_t tmp; | |
| 584 | - int32_t msk; | |
| 585 | - | |
| 586 | - msk = INT32_MIN >> (T1 & 0x1FUL); | |
| 587 | - if (T1 & 0x20UL) | |
| 588 | - msk = ~msk; | |
| 589 | - T1 &= 0x1FUL; | |
| 590 | - tmp = env->spr[SPR_MQ]; | |
| 591 | - env->spr[SPR_MQ] = rotl32(T0, 32 - T1); | |
| 592 | - T0 = T0 >> T1; | |
| 593 | - T0 &= msk; | |
| 594 | - T0 |= tmp & ~msk; | |
| 595 | - RETURN(); | |
| 596 | -} | |
| 597 | - | |
| 598 | -void OPPROTO op_POWER_srq (void) | |
| 599 | -{ | |
| 600 | - T1 &= 0x1FUL; | |
| 601 | - env->spr[SPR_MQ] = rotl32(T0, 32 - T1); | |
| 602 | - T0 = T0 >> T1; | |
| 603 | - RETURN(); | |
| 604 | -} | |
| 605 | - | |
| 606 | 479 | /* POWER instructions not implemented in PowerPC 601 */ |
| 607 | 480 | #if !defined(CONFIG_USER_ONLY) |
| 608 | 481 | void OPPROTO op_POWER_mfsri (void) | ... | ... |
target-ppc/translate.c
| ... | ... | @@ -4626,195 +4626,361 @@ GEN_HANDLER(nabso, 0x1F, 0x08, 0x1F, 0x00000000, PPC_POWER_BR) |
| 4626 | 4626 | /* rlmi - rlmi. */ |
| 4627 | 4627 | GEN_HANDLER(rlmi, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR) |
| 4628 | 4628 | { |
| 4629 | - uint32_t mb, me; | |
| 4630 | - | |
| 4631 | - mb = MB(ctx->opcode); | |
| 4632 | - me = ME(ctx->opcode); | |
| 4633 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]); | |
| 4634 | - tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rA(ctx->opcode)]); | |
| 4635 | - tcg_gen_mov_tl(cpu_T[2], cpu_gpr[rB(ctx->opcode)]); | |
| 4636 | - gen_op_POWER_rlmi(MASK(mb, me), ~MASK(mb, me)); | |
| 4637 | - tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]); | |
| 4629 | + uint32_t mb = MB(ctx->opcode); | |
| 4630 | + uint32_t me = ME(ctx->opcode); | |
| 4631 | + TCGv t0 = tcg_temp_new(); | |
| 4632 | + tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F); | |
| 4633 | + tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0); | |
| 4634 | + tcg_gen_andi_tl(t0, t0, MASK(mb, me)); | |
| 4635 | + tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~MASK(mb, me)); | |
| 4636 | + tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], t0); | |
| 4637 | + tcg_temp_free(t0); | |
| 4638 | 4638 | if (unlikely(Rc(ctx->opcode) != 0)) |
| 4639 | - gen_set_Rc0(ctx, cpu_T[0]); | |
| 4639 | + gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); | |
| 4640 | 4640 | } |
| 4641 | 4641 | |
| 4642 | 4642 | /* rrib - rrib. */ |
| 4643 | 4643 | GEN_HANDLER(rrib, 0x1F, 0x19, 0x10, 0x00000000, PPC_POWER_BR) |
| 4644 | 4644 | { |
| 4645 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]); | |
| 4646 | - tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rA(ctx->opcode)]); | |
| 4647 | - tcg_gen_mov_tl(cpu_T[2], cpu_gpr[rB(ctx->opcode)]); | |
| 4648 | - gen_op_POWER_rrib(); | |
| 4649 | - tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]); | |
| 4645 | + TCGv t0 = tcg_temp_new(); | |
| 4646 | + TCGv t1 = tcg_temp_new(); | |
| 4647 | + tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F); | |
| 4648 | + tcg_gen_movi_tl(t1, 0x80000000); | |
| 4649 | + tcg_gen_shr_tl(t1, t1, t0); | |
| 4650 | + tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t0); | |
| 4651 | + tcg_gen_and_tl(t0, t0, t1); | |
| 4652 | + tcg_gen_andc_tl(t1, cpu_gpr[rA(ctx->opcode)], t1); | |
| 4653 | + tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1); | |
| 4654 | + tcg_temp_free(t0); | |
| 4655 | + tcg_temp_free(t1); | |
| 4650 | 4656 | if (unlikely(Rc(ctx->opcode) != 0)) |
| 4651 | - gen_set_Rc0(ctx, cpu_T[0]); | |
| 4657 | + gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); | |
| 4652 | 4658 | } |
| 4653 | 4659 | |
| 4654 | 4660 | /* sle - sle. */ |
| 4655 | 4661 | GEN_HANDLER(sle, 0x1F, 0x19, 0x04, 0x00000000, PPC_POWER_BR) |
| 4656 | 4662 | { |
| 4657 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]); | |
| 4658 | - tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]); | |
| 4659 | - gen_op_POWER_sle(); | |
| 4660 | - tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]); | |
| 4663 | + TCGv t0 = tcg_temp_new(); | |
| 4664 | + TCGv t1 = tcg_temp_new(); | |
| 4665 | + tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F); | |
| 4666 | + tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t1); | |
| 4667 | + tcg_gen_subfi_tl(t1, 32, t1); | |
| 4668 | + tcg_gen_shr_tl(t1, cpu_gpr[rS(ctx->opcode)], t1); | |
| 4669 | + tcg_gen_or_tl(t1, t0, t1); | |
| 4670 | + tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0); | |
| 4671 | + gen_store_spr(SPR_MQ, t1); | |
| 4672 | + tcg_temp_free(t0); | |
| 4673 | + tcg_temp_free(t1); | |
| 4661 | 4674 | if (unlikely(Rc(ctx->opcode) != 0)) |
| 4662 | - gen_set_Rc0(ctx, cpu_T[0]); | |
| 4675 | + gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); | |
| 4663 | 4676 | } |
| 4664 | 4677 | |
| 4665 | 4678 | /* sleq - sleq. */ |
| 4666 | 4679 | GEN_HANDLER(sleq, 0x1F, 0x19, 0x06, 0x00000000, PPC_POWER_BR) |
| 4667 | 4680 | { |
| 4668 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]); | |
| 4669 | - tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]); | |
| 4670 | - gen_op_POWER_sleq(); | |
| 4671 | - tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]); | |
| 4681 | + TCGv t0 = tcg_temp_new(); | |
| 4682 | + TCGv t1 = tcg_temp_new(); | |
| 4683 | + TCGv t2 = tcg_temp_new(); | |
| 4684 | + tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F); | |
| 4685 | + tcg_gen_movi_tl(t2, 0xFFFFFFFF); | |
| 4686 | + tcg_gen_shl_tl(t2, t2, t0); | |
| 4687 | + tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0); | |
| 4688 | + gen_load_spr(t1, SPR_MQ); | |
| 4689 | + gen_store_spr(SPR_MQ, t0); | |
| 4690 | + tcg_gen_and_tl(t0, t0, t2); | |
| 4691 | + tcg_gen_andc_tl(t1, t1, t2); | |
| 4692 | + tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1); | |
| 4693 | + tcg_temp_free(t0); | |
| 4694 | + tcg_temp_free(t1); | |
| 4695 | + tcg_temp_free(t2); | |
| 4672 | 4696 | if (unlikely(Rc(ctx->opcode) != 0)) |
| 4673 | - gen_set_Rc0(ctx, cpu_T[0]); | |
| 4697 | + gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); | |
| 4674 | 4698 | } |
| 4675 | 4699 | |
| 4676 | 4700 | /* sliq - sliq. */ |
| 4677 | 4701 | GEN_HANDLER(sliq, 0x1F, 0x18, 0x05, 0x00000000, PPC_POWER_BR) |
| 4678 | 4702 | { |
| 4679 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]); | |
| 4680 | - tcg_gen_movi_tl(cpu_T[1], SH(ctx->opcode)); | |
| 4681 | - gen_op_POWER_sle(); | |
| 4682 | - tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]); | |
| 4703 | + int sh = SH(ctx->opcode); | |
| 4704 | + TCGv t0 = tcg_temp_new(); | |
| 4705 | + TCGv t1 = tcg_temp_new(); | |
| 4706 | + tcg_gen_shli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh); | |
| 4707 | + tcg_gen_shri_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh); | |
| 4708 | + tcg_gen_or_tl(t1, t0, t1); | |
| 4709 | + tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0); | |
| 4710 | + gen_store_spr(SPR_MQ, t1); | |
| 4711 | + tcg_temp_free(t0); | |
| 4712 | + tcg_temp_free(t1); | |
| 4683 | 4713 | if (unlikely(Rc(ctx->opcode) != 0)) |
| 4684 | - gen_set_Rc0(ctx, cpu_T[0]); | |
| 4714 | + gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); | |
| 4685 | 4715 | } |
| 4686 | 4716 | |
| 4687 | 4717 | /* slliq - slliq. */ |
| 4688 | 4718 | GEN_HANDLER(slliq, 0x1F, 0x18, 0x07, 0x00000000, PPC_POWER_BR) |
| 4689 | 4719 | { |
| 4690 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]); | |
| 4691 | - tcg_gen_movi_tl(cpu_T[1], SH(ctx->opcode)); | |
| 4692 | - gen_op_POWER_sleq(); | |
| 4693 | - tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]); | |
| 4720 | + int sh = SH(ctx->opcode); | |
| 4721 | + TCGv t0 = tcg_temp_new(); | |
| 4722 | + TCGv t1 = tcg_temp_new(); | |
| 4723 | + tcg_gen_rotli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh); | |
| 4724 | + gen_load_spr(t1, SPR_MQ); | |
| 4725 | + gen_store_spr(SPR_MQ, t0); | |
| 4726 | + tcg_gen_andi_tl(t0, t0, (0xFFFFFFFFU << sh)); | |
| 4727 | + tcg_gen_andi_tl(t1, t1, ~(0xFFFFFFFFU << sh)); | |
| 4728 | + tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1); | |
| 4729 | + tcg_temp_free(t0); | |
| 4730 | + tcg_temp_free(t1); | |
| 4694 | 4731 | if (unlikely(Rc(ctx->opcode) != 0)) |
| 4695 | - gen_set_Rc0(ctx, cpu_T[0]); | |
| 4732 | + gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); | |
| 4696 | 4733 | } |
| 4697 | 4734 | |
| 4698 | 4735 | /* sllq - sllq. */ |
| 4699 | 4736 | GEN_HANDLER(sllq, 0x1F, 0x18, 0x06, 0x00000000, PPC_POWER_BR) |
| 4700 | 4737 | { |
| 4701 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]); | |
| 4702 | - tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]); | |
| 4703 | - gen_op_POWER_sllq(); | |
| 4704 | - tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]); | |
| 4738 | + int l1 = gen_new_label(); | |
| 4739 | + int l2 = gen_new_label(); | |
| 4740 | + TCGv t0 = tcg_temp_local_new(); | |
| 4741 | + TCGv t1 = tcg_temp_local_new(); | |
| 4742 | + TCGv t2 = tcg_temp_local_new(); | |
| 4743 | + tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F); | |
| 4744 | + tcg_gen_movi_tl(t1, 0xFFFFFFFF); | |
| 4745 | + tcg_gen_shl_tl(t1, t1, t2); | |
| 4746 | + tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20); | |
| 4747 | + tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); | |
| 4748 | + gen_load_spr(t0, SPR_MQ); | |
| 4749 | + tcg_gen_and_tl(cpu_gpr[rA(ctx->opcode)], t0, t1); | |
| 4750 | + tcg_gen_br(l2); | |
| 4751 | + gen_set_label(l1); | |
| 4752 | + tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t2); | |
| 4753 | + gen_load_spr(t2, SPR_MQ); | |
| 4754 | + tcg_gen_andc_tl(t1, t2, t1); | |
| 4755 | + tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1); | |
| 4756 | + gen_set_label(l2); | |
| 4757 | + tcg_temp_free(t0); | |
| 4758 | + tcg_temp_free(t1); | |
| 4759 | + tcg_temp_free(t2); | |
| 4705 | 4760 | if (unlikely(Rc(ctx->opcode) != 0)) |
| 4706 | - gen_set_Rc0(ctx, cpu_T[0]); | |
| 4761 | + gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); | |
| 4707 | 4762 | } |
| 4708 | 4763 | |
| 4709 | 4764 | /* slq - slq. */ |
| 4710 | 4765 | GEN_HANDLER(slq, 0x1F, 0x18, 0x04, 0x00000000, PPC_POWER_BR) |
| 4711 | 4766 | { |
| 4712 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]); | |
| 4713 | - tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]); | |
| 4714 | - gen_op_POWER_slq(); | |
| 4715 | - tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]); | |
| 4767 | + int l1 = gen_new_label(); | |
| 4768 | + TCGv t0 = tcg_temp_new(); | |
| 4769 | + TCGv t1 = tcg_temp_new(); | |
| 4770 | + tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F); | |
| 4771 | + tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t1); | |
| 4772 | + tcg_gen_subfi_tl(t1, 32, t1); | |
| 4773 | + tcg_gen_shr_tl(t1, cpu_gpr[rS(ctx->opcode)], t1); | |
| 4774 | + tcg_gen_or_tl(t1, t0, t1); | |
| 4775 | + gen_store_spr(SPR_MQ, t1); | |
| 4776 | + tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x20); | |
| 4777 | + tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0); | |
| 4778 | + tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1); | |
| 4779 | + tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0); | |
| 4780 | + gen_set_label(l1); | |
| 4781 | + tcg_temp_free(t0); | |
| 4782 | + tcg_temp_free(t1); | |
| 4716 | 4783 | if (unlikely(Rc(ctx->opcode) != 0)) |
| 4717 | - gen_set_Rc0(ctx, cpu_T[0]); | |
| 4784 | + gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); | |
| 4718 | 4785 | } |
| 4719 | 4786 | |
| 4720 | 4787 | /* sraiq - sraiq. */ |
| 4721 | 4788 | GEN_HANDLER(sraiq, 0x1F, 0x18, 0x1D, 0x00000000, PPC_POWER_BR) |
| 4722 | 4789 | { |
| 4723 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]); | |
| 4724 | - tcg_gen_movi_tl(cpu_T[1], SH(ctx->opcode)); | |
| 4725 | - gen_op_POWER_sraq(); | |
| 4726 | - tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]); | |
| 4790 | + int sh = SH(ctx->opcode); | |
| 4791 | + int l1 = gen_new_label(); | |
| 4792 | + TCGv t0 = tcg_temp_new(); | |
| 4793 | + TCGv t1 = tcg_temp_new(); | |
| 4794 | + tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh); | |
| 4795 | + tcg_gen_shli_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh); | |
| 4796 | + tcg_gen_or_tl(t0, t0, t1); | |
| 4797 | + gen_store_spr(SPR_MQ, t0); | |
| 4798 | + tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA)); | |
| 4799 | + tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1); | |
| 4800 | + tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rS(ctx->opcode)], 0, l1); | |
| 4801 | + tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_CA)); | |
| 4802 | + gen_set_label(l1); | |
| 4803 | + tcg_gen_sari_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], sh); | |
| 4804 | + tcg_temp_free(t0); | |
| 4805 | + tcg_temp_free(t1); | |
| 4727 | 4806 | if (unlikely(Rc(ctx->opcode) != 0)) |
| 4728 | - gen_set_Rc0(ctx, cpu_T[0]); | |
| 4807 | + gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); | |
| 4729 | 4808 | } |
| 4730 | 4809 | |
| 4731 | 4810 | /* sraq - sraq. */ |
| 4732 | 4811 | GEN_HANDLER(sraq, 0x1F, 0x18, 0x1C, 0x00000000, PPC_POWER_BR) |
| 4733 | 4812 | { |
| 4734 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]); | |
| 4735 | - tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]); | |
| 4736 | - gen_op_POWER_sraq(); | |
| 4737 | - tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]); | |
| 4813 | + int l1 = gen_new_label(); | |
| 4814 | + int l2 = gen_new_label(); | |
| 4815 | + TCGv t0 = tcg_temp_new(); | |
| 4816 | + TCGv t1 = tcg_temp_local_new(); | |
| 4817 | + TCGv t2 = tcg_temp_local_new(); | |
| 4818 | + tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F); | |
| 4819 | + tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t2); | |
| 4820 | + tcg_gen_sar_tl(t1, cpu_gpr[rS(ctx->opcode)], t2); | |
| 4821 | + tcg_gen_subfi_tl(t2, 32, t2); | |
| 4822 | + tcg_gen_shl_tl(t2, cpu_gpr[rS(ctx->opcode)], t2); | |
| 4823 | + tcg_gen_or_tl(t0, t0, t2); | |
| 4824 | + gen_store_spr(SPR_MQ, t0); | |
| 4825 | + tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20); | |
| 4826 | + tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, l1); | |
| 4827 | + tcg_gen_mov_tl(t2, cpu_gpr[rS(ctx->opcode)]); | |
| 4828 | + tcg_gen_sari_tl(t1, cpu_gpr[rS(ctx->opcode)], 31); | |
| 4829 | + gen_set_label(l1); | |
| 4830 | + tcg_temp_free(t0); | |
| 4831 | + tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t1); | |
| 4832 | + tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA)); | |
| 4833 | + tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l2); | |
| 4834 | + tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, l2); | |
| 4835 | + tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_CA)); | |
| 4836 | + gen_set_label(l2); | |
| 4837 | + tcg_temp_free(t1); | |
| 4838 | + tcg_temp_free(t2); | |
| 4738 | 4839 | if (unlikely(Rc(ctx->opcode) != 0)) |
| 4739 | - gen_set_Rc0(ctx, cpu_T[0]); | |
| 4840 | + gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); | |
| 4740 | 4841 | } |
| 4741 | 4842 | |
| 4742 | 4843 | /* sre - sre. */ |
| 4743 | 4844 | GEN_HANDLER(sre, 0x1F, 0x19, 0x14, 0x00000000, PPC_POWER_BR) |
| 4744 | 4845 | { |
| 4745 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]); | |
| 4746 | - tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]); | |
| 4747 | - gen_op_POWER_sre(); | |
| 4748 | - tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]); | |
| 4846 | + TCGv t0 = tcg_temp_new(); | |
| 4847 | + TCGv t1 = tcg_temp_new(); | |
| 4848 | + tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F); | |
| 4849 | + tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1); | |
| 4850 | + tcg_gen_subfi_tl(t1, 32, t1); | |
| 4851 | + tcg_gen_shl_tl(t1, cpu_gpr[rS(ctx->opcode)], t1); | |
| 4852 | + tcg_gen_or_tl(t1, t0, t1); | |
| 4853 | + tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0); | |
| 4854 | + gen_store_spr(SPR_MQ, t1); | |
| 4855 | + tcg_temp_free(t0); | |
| 4856 | + tcg_temp_free(t1); | |
| 4749 | 4857 | if (unlikely(Rc(ctx->opcode) != 0)) |
| 4750 | - gen_set_Rc0(ctx, cpu_T[0]); | |
| 4858 | + gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); | |
| 4751 | 4859 | } |
| 4752 | 4860 | |
| 4753 | 4861 | /* srea - srea. */ |
| 4754 | 4862 | GEN_HANDLER(srea, 0x1F, 0x19, 0x1C, 0x00000000, PPC_POWER_BR) |
| 4755 | 4863 | { |
| 4756 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]); | |
| 4757 | - tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]); | |
| 4758 | - gen_op_POWER_srea(); | |
| 4759 | - tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]); | |
| 4864 | + TCGv t0 = tcg_temp_new(); | |
| 4865 | + TCGv t1 = tcg_temp_new(); | |
| 4866 | + tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F); | |
| 4867 | + tcg_gen_rotr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1); | |
| 4868 | + gen_store_spr(SPR_MQ, t0); | |
| 4869 | + tcg_gen_sar_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], t1); | |
| 4870 | + tcg_temp_free(t0); | |
| 4871 | + tcg_temp_free(t1); | |
| 4760 | 4872 | if (unlikely(Rc(ctx->opcode) != 0)) |
| 4761 | - gen_set_Rc0(ctx, cpu_T[0]); | |
| 4873 | + gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); | |
| 4762 | 4874 | } |
| 4763 | 4875 | |
| 4764 | 4876 | /* sreq */ |
| 4765 | 4877 | GEN_HANDLER(sreq, 0x1F, 0x19, 0x16, 0x00000000, PPC_POWER_BR) |
| 4766 | 4878 | { |
| 4767 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]); | |
| 4768 | - tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]); | |
| 4769 | - gen_op_POWER_sreq(); | |
| 4770 | - tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]); | |
| 4879 | + TCGv t0 = tcg_temp_new(); | |
| 4880 | + TCGv t1 = tcg_temp_new(); | |
| 4881 | + TCGv t2 = tcg_temp_new(); | |
| 4882 | + tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F); | |
| 4883 | + tcg_gen_movi_tl(t1, 0xFFFFFFFF); | |
| 4884 | + tcg_gen_shr_tl(t1, t1, t0); | |
| 4885 | + tcg_gen_rotr_tl(t0, cpu_gpr[rS(ctx->opcode)], t0); | |
| 4886 | + gen_load_spr(t2, SPR_MQ); | |
| 4887 | + gen_store_spr(SPR_MQ, t0); | |
| 4888 | + tcg_gen_and_tl(t0, t0, t1); | |
| 4889 | + tcg_gen_andc_tl(t2, t2, t1); | |
| 4890 | + tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t2); | |
| 4891 | + tcg_temp_free(t0); | |
| 4892 | + tcg_temp_free(t1); | |
| 4893 | + tcg_temp_free(t2); | |
| 4771 | 4894 | if (unlikely(Rc(ctx->opcode) != 0)) |
| 4772 | - gen_set_Rc0(ctx, cpu_T[0]); | |
| 4895 | + gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); | |
| 4773 | 4896 | } |
| 4774 | 4897 | |
| 4775 | 4898 | /* sriq */ |
| 4776 | 4899 | GEN_HANDLER(sriq, 0x1F, 0x18, 0x15, 0x00000000, PPC_POWER_BR) |
| 4777 | 4900 | { |
| 4778 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]); | |
| 4779 | - tcg_gen_movi_tl(cpu_T[1], SH(ctx->opcode)); | |
| 4780 | - gen_op_POWER_srq(); | |
| 4781 | - tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]); | |
| 4901 | + int sh = SH(ctx->opcode); | |
| 4902 | + TCGv t0 = tcg_temp_new(); | |
| 4903 | + TCGv t1 = tcg_temp_new(); | |
| 4904 | + tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh); | |
| 4905 | + tcg_gen_shli_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh); | |
| 4906 | + tcg_gen_or_tl(t1, t0, t1); | |
| 4907 | + tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0); | |
| 4908 | + gen_store_spr(SPR_MQ, t1); | |
| 4909 | + tcg_temp_free(t0); | |
| 4910 | + tcg_temp_free(t1); | |
| 4782 | 4911 | if (unlikely(Rc(ctx->opcode) != 0)) |
| 4783 | - gen_set_Rc0(ctx, cpu_T[0]); | |
| 4912 | + gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); | |
| 4784 | 4913 | } |
| 4785 | 4914 | |
| 4786 | 4915 | /* srliq */ |
| 4787 | 4916 | GEN_HANDLER(srliq, 0x1F, 0x18, 0x17, 0x00000000, PPC_POWER_BR) |
| 4788 | 4917 | { |
| 4789 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]); | |
| 4790 | - tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]); | |
| 4791 | - tcg_gen_movi_tl(cpu_T[1], SH(ctx->opcode)); | |
| 4792 | - gen_op_POWER_srlq(); | |
| 4793 | - tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]); | |
| 4918 | + int sh = SH(ctx->opcode); | |
| 4919 | + TCGv t0 = tcg_temp_new(); | |
| 4920 | + TCGv t1 = tcg_temp_new(); | |
| 4921 | + tcg_gen_rotri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh); | |
| 4922 | + gen_load_spr(t1, SPR_MQ); | |
| 4923 | + gen_store_spr(SPR_MQ, t0); | |
| 4924 | + tcg_gen_andi_tl(t0, t0, (0xFFFFFFFFU >> sh)); | |
| 4925 | + tcg_gen_andi_tl(t1, t1, ~(0xFFFFFFFFU >> sh)); | |
| 4926 | + tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1); | |
| 4927 | + tcg_temp_free(t0); | |
| 4928 | + tcg_temp_free(t1); | |
| 4794 | 4929 | if (unlikely(Rc(ctx->opcode) != 0)) |
| 4795 | - gen_set_Rc0(ctx, cpu_T[0]); | |
| 4930 | + gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); | |
| 4796 | 4931 | } |
| 4797 | 4932 | |
| 4798 | 4933 | /* srlq */ |
| 4799 | 4934 | GEN_HANDLER(srlq, 0x1F, 0x18, 0x16, 0x00000000, PPC_POWER_BR) |
| 4800 | 4935 | { |
| 4801 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]); | |
| 4802 | - tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]); | |
| 4803 | - gen_op_POWER_srlq(); | |
| 4804 | - tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]); | |
| 4936 | + int l1 = gen_new_label(); | |
| 4937 | + int l2 = gen_new_label(); | |
| 4938 | + TCGv t0 = tcg_temp_local_new(); | |
| 4939 | + TCGv t1 = tcg_temp_local_new(); | |
| 4940 | + TCGv t2 = tcg_temp_local_new(); | |
| 4941 | + tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F); | |
| 4942 | + tcg_gen_movi_tl(t1, 0xFFFFFFFF); | |
| 4943 | + tcg_gen_shr_tl(t2, t1, t2); | |
| 4944 | + tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20); | |
| 4945 | + tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); | |
| 4946 | + gen_load_spr(t0, SPR_MQ); | |
| 4947 | + tcg_gen_and_tl(cpu_gpr[rA(ctx->opcode)], t0, t2); | |
| 4948 | + tcg_gen_br(l2); | |
| 4949 | + gen_set_label(l1); | |
| 4950 | + tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t2); | |
| 4951 | + tcg_gen_and_tl(t0, t0, t2); | |
| 4952 | + gen_load_spr(t1, SPR_MQ); | |
| 4953 | + tcg_gen_andc_tl(t1, t1, t2); | |
| 4954 | + tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1); | |
| 4955 | + gen_set_label(l2); | |
| 4956 | + tcg_temp_free(t0); | |
| 4957 | + tcg_temp_free(t1); | |
| 4958 | + tcg_temp_free(t2); | |
| 4805 | 4959 | if (unlikely(Rc(ctx->opcode) != 0)) |
| 4806 | - gen_set_Rc0(ctx, cpu_T[0]); | |
| 4960 | + gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); | |
| 4807 | 4961 | } |
| 4808 | 4962 | |
| 4809 | 4963 | /* srq */ |
| 4810 | 4964 | GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR) |
| 4811 | 4965 | { |
| 4812 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]); | |
| 4813 | - tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]); | |
| 4814 | - gen_op_POWER_srq(); | |
| 4815 | - tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]); | |
| 4966 | + int l1 = gen_new_label(); | |
| 4967 | + TCGv t0 = tcg_temp_new(); | |
| 4968 | + TCGv t1 = tcg_temp_new(); | |
| 4969 | + tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F); | |
| 4970 | + tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1); | |
| 4971 | + tcg_gen_subfi_tl(t1, 32, t1); | |
| 4972 | + tcg_gen_shl_tl(t1, cpu_gpr[rS(ctx->opcode)], t1); | |
| 4973 | + tcg_gen_or_tl(t1, t0, t1); | |
| 4974 | + gen_store_spr(SPR_MQ, t1); | |
| 4975 | + tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x20); | |
| 4976 | + tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0); | |
| 4977 | + tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); | |
| 4978 | + tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0); | |
| 4979 | + gen_set_label(l1); | |
| 4980 | + tcg_temp_free(t0); | |
| 4981 | + tcg_temp_free(t1); | |
| 4816 | 4982 | if (unlikely(Rc(ctx->opcode) != 0)) |
| 4817 | - gen_set_Rc0(ctx, cpu_T[0]); | |
| 4983 | + gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); | |
| 4818 | 4984 | } |
| 4819 | 4985 | |
| 4820 | 4986 | /* PowerPC 602 specific instructions */ | ... | ... |