Commit 7487953d704369c7acc7486f09eaf87faa5d3693

Authored by aurel32
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
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 */