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 */ | ... | ... |