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,28 +51,6 @@ register target_ulong T2 asm(AREG3); | ||
| 51 | # define RETURN() __asm__ __volatile__("" : : : "memory"); | 51 | # define RETURN() __asm__ __volatile__("" : : : "memory"); |
| 52 | #endif | 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 | #if !defined(CONFIG_USER_ONLY) | 54 | #if !defined(CONFIG_USER_ONLY) |
| 77 | #include "softmmu_exec.h" | 55 | #include "softmmu_exec.h" |
| 78 | #endif /* !defined(CONFIG_USER_ONLY) */ | 56 | #endif /* !defined(CONFIG_USER_ONLY) */ |
target-ppc/op.c
| @@ -476,133 +476,6 @@ void OPPROTO op_POWER_nabso (void) | @@ -476,133 +476,6 @@ void OPPROTO op_POWER_nabso (void) | ||
| 476 | RETURN(); | 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 | /* POWER instructions not implemented in PowerPC 601 */ | 479 | /* POWER instructions not implemented in PowerPC 601 */ |
| 607 | #if !defined(CONFIG_USER_ONLY) | 480 | #if !defined(CONFIG_USER_ONLY) |
| 608 | void OPPROTO op_POWER_mfsri (void) | 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,195 +4626,361 @@ GEN_HANDLER(nabso, 0x1F, 0x08, 0x1F, 0x00000000, PPC_POWER_BR) | ||
| 4626 | /* rlmi - rlmi. */ | 4626 | /* rlmi - rlmi. */ |
| 4627 | GEN_HANDLER(rlmi, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR) | 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 | if (unlikely(Rc(ctx->opcode) != 0)) | 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 | /* rrib - rrib. */ | 4642 | /* rrib - rrib. */ |
| 4643 | GEN_HANDLER(rrib, 0x1F, 0x19, 0x10, 0x00000000, PPC_POWER_BR) | 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 | if (unlikely(Rc(ctx->opcode) != 0)) | 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 | /* sle - sle. */ | 4660 | /* sle - sle. */ |
| 4655 | GEN_HANDLER(sle, 0x1F, 0x19, 0x04, 0x00000000, PPC_POWER_BR) | 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 | if (unlikely(Rc(ctx->opcode) != 0)) | 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 | /* sleq - sleq. */ | 4678 | /* sleq - sleq. */ |
| 4666 | GEN_HANDLER(sleq, 0x1F, 0x19, 0x06, 0x00000000, PPC_POWER_BR) | 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 | if (unlikely(Rc(ctx->opcode) != 0)) | 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 | /* sliq - sliq. */ | 4700 | /* sliq - sliq. */ |
| 4677 | GEN_HANDLER(sliq, 0x1F, 0x18, 0x05, 0x00000000, PPC_POWER_BR) | 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 | if (unlikely(Rc(ctx->opcode) != 0)) | 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 | /* slliq - slliq. */ | 4717 | /* slliq - slliq. */ |
| 4688 | GEN_HANDLER(slliq, 0x1F, 0x18, 0x07, 0x00000000, PPC_POWER_BR) | 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 | if (unlikely(Rc(ctx->opcode) != 0)) | 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 | /* sllq - sllq. */ | 4735 | /* sllq - sllq. */ |
| 4699 | GEN_HANDLER(sllq, 0x1F, 0x18, 0x06, 0x00000000, PPC_POWER_BR) | 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 | if (unlikely(Rc(ctx->opcode) != 0)) | 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 | /* slq - slq. */ | 4764 | /* slq - slq. */ |
| 4710 | GEN_HANDLER(slq, 0x1F, 0x18, 0x04, 0x00000000, PPC_POWER_BR) | 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 | if (unlikely(Rc(ctx->opcode) != 0)) | 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 | /* sraiq - sraiq. */ | 4787 | /* sraiq - sraiq. */ |
| 4721 | GEN_HANDLER(sraiq, 0x1F, 0x18, 0x1D, 0x00000000, PPC_POWER_BR) | 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 | if (unlikely(Rc(ctx->opcode) != 0)) | 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 | /* sraq - sraq. */ | 4810 | /* sraq - sraq. */ |
| 4732 | GEN_HANDLER(sraq, 0x1F, 0x18, 0x1C, 0x00000000, PPC_POWER_BR) | 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 | if (unlikely(Rc(ctx->opcode) != 0)) | 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 | /* sre - sre. */ | 4843 | /* sre - sre. */ |
| 4743 | GEN_HANDLER(sre, 0x1F, 0x19, 0x14, 0x00000000, PPC_POWER_BR) | 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 | if (unlikely(Rc(ctx->opcode) != 0)) | 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 | /* srea - srea. */ | 4861 | /* srea - srea. */ |
| 4754 | GEN_HANDLER(srea, 0x1F, 0x19, 0x1C, 0x00000000, PPC_POWER_BR) | 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 | if (unlikely(Rc(ctx->opcode) != 0)) | 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 | /* sreq */ | 4876 | /* sreq */ |
| 4765 | GEN_HANDLER(sreq, 0x1F, 0x19, 0x16, 0x00000000, PPC_POWER_BR) | 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 | if (unlikely(Rc(ctx->opcode) != 0)) | 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 | /* sriq */ | 4898 | /* sriq */ |
| 4776 | GEN_HANDLER(sriq, 0x1F, 0x18, 0x15, 0x00000000, PPC_POWER_BR) | 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 | if (unlikely(Rc(ctx->opcode) != 0)) | 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 | /* srliq */ | 4915 | /* srliq */ |
| 4787 | GEN_HANDLER(srliq, 0x1F, 0x18, 0x17, 0x00000000, PPC_POWER_BR) | 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 | if (unlikely(Rc(ctx->opcode) != 0)) | 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 | /* srlq */ | 4933 | /* srlq */ |
| 4799 | GEN_HANDLER(srlq, 0x1F, 0x18, 0x16, 0x00000000, PPC_POWER_BR) | 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 | if (unlikely(Rc(ctx->opcode) != 0)) | 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 | /* srq */ | 4963 | /* srq */ |
| 4810 | GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR) | 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 | if (unlikely(Rc(ctx->opcode) != 0)) | 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 | /* PowerPC 602 specific instructions */ | 4986 | /* PowerPC 602 specific instructions */ |