Commit 30c7183b676076c940538b838c330c854a7995a9

Authored by aurel32
1 parent ae8ecd42

target-alpha: convert some arith3 instructions to TCG

Replace gen_arith3 generic macro and dyngen ops by instruction specific
optimized TCG code.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5236 c046a42c-6fe2-441c-8c8c-71466251a162
target-alpha/op.c
... ... @@ -198,72 +198,36 @@ void OPPROTO op_clear_irf (void)
198 198 }
199 199  
200 200 /* Arithmetic */
201   -void OPPROTO op_addq (void)
202   -{
203   - T0 += T1;
204   - RETURN();
205   -}
206   -
207 201 void OPPROTO op_addqv (void)
208 202 {
209 203 helper_addqv();
210 204 RETURN();
211 205 }
212 206  
213   -void OPPROTO op_addl (void)
214   -{
215   - T0 = (int64_t)((int32_t)(T0 + T1));
216   - RETURN();
217   -}
218   -
219 207 void OPPROTO op_addlv (void)
220 208 {
221 209 helper_addlv();
222 210 RETURN();
223 211 }
224 212  
225   -void OPPROTO op_subq (void)
226   -{
227   - T0 -= T1;
228   - RETURN();
229   -}
230   -
231 213 void OPPROTO op_subqv (void)
232 214 {
233 215 helper_subqv();
234 216 RETURN();
235 217 }
236 218  
237   -void OPPROTO op_subl (void)
238   -{
239   - T0 = (int64_t)((int32_t)(T0 - T1));
240   - RETURN();
241   -}
242   -
243 219 void OPPROTO op_sublv (void)
244 220 {
245 221 helper_sublv();
246 222 RETURN();
247 223 }
248 224  
249   -void OPPROTO op_mull (void)
250   -{
251   - T0 = (int64_t)((int32_t)T0 * (int32_t)T1);
252   - RETURN();
253   -}
254   -
255 225 void OPPROTO op_mullv (void)
256 226 {
257 227 helper_mullv();
258 228 RETURN();
259 229 }
260 230  
261   -void OPPROTO op_mulq (void)
262   -{
263   - T0 = (int64_t)T0 * (int64_t)T1;
264   - RETURN();
265   -}
266   -
267 231 void OPPROTO op_mulqv (void)
268 232 {
269 233 helper_mulqv();
... ... @@ -280,60 +244,6 @@ void OPPROTO op_umulh (void)
280 244 }
281 245  
282 246 /* Logical */
283   -void OPPROTO op_and (void)
284   -{
285   - T0 &= T1;
286   - RETURN();
287   -}
288   -
289   -void OPPROTO op_bic (void)
290   -{
291   - T0 &= ~T1;
292   - RETURN();
293   -}
294   -
295   -void OPPROTO op_bis (void)
296   -{
297   - T0 |= T1;
298   - RETURN();
299   -}
300   -
301   -void OPPROTO op_eqv (void)
302   -{
303   - T0 ^= ~T1;
304   - RETURN();
305   -}
306   -
307   -void OPPROTO op_ornot (void)
308   -{
309   - T0 |= ~T1;
310   - RETURN();
311   -}
312   -
313   -void OPPROTO op_xor (void)
314   -{
315   - T0 ^= T1;
316   - RETURN();
317   -}
318   -
319   -void OPPROTO op_sll (void)
320   -{
321   - T0 <<= T1;
322   - RETURN();
323   -}
324   -
325   -void OPPROTO op_srl (void)
326   -{
327   - T0 >>= T1;
328   - RETURN();
329   -}
330   -
331   -void OPPROTO op_sra (void)
332   -{
333   - T0 = (int64_t)T0 >> T1;
334   - RETURN();
335   -}
336   -
337 247 void OPPROTO op_mskbl (void)
338 248 {
339 249 helper_mskbl();
... ...
target-alpha/translate.c
... ... @@ -440,54 +440,6 @@ static always_inline void gen_itf (DisasContext *ctx,
440 440 gen_store_fir(ctx, rc, 0);
441 441 }
442 442  
443   -static always_inline void gen_s4addl (void)
444   -{
445   - tcg_gen_shli_i64(cpu_T[0], cpu_T[0], 2);
446   - gen_op_addl();
447   -}
448   -
449   -static always_inline void gen_s4subl (void)
450   -{
451   - tcg_gen_shli_i64(cpu_T[0], cpu_T[0], 2);
452   - gen_op_subl();
453   -}
454   -
455   -static always_inline void gen_s8addl (void)
456   -{
457   - tcg_gen_shli_i64(cpu_T[0], cpu_T[0], 3);
458   - gen_op_addl();
459   -}
460   -
461   -static always_inline void gen_s8subl (void)
462   -{
463   - tcg_gen_shli_i64(cpu_T[0], cpu_T[0], 3);
464   - gen_op_subl();
465   -}
466   -
467   -static always_inline void gen_s4addq (void)
468   -{
469   - tcg_gen_shli_i64(cpu_T[0], cpu_T[0], 2);
470   - tcg_gen_add_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
471   -}
472   -
473   -static always_inline void gen_s4subq (void)
474   -{
475   - tcg_gen_shli_i64(cpu_T[0], cpu_T[0], 2);
476   - tcg_gen_sub_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
477   -}
478   -
479   -static always_inline void gen_s8addq (void)
480   -{
481   - tcg_gen_shli_i64(cpu_T[0], cpu_T[0], 3);
482   - tcg_gen_add_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
483   -}
484   -
485   -static always_inline void gen_s8subq (void)
486   -{
487   - tcg_gen_shli_i64(cpu_T[0], cpu_T[0], 3);
488   - tcg_gen_sub_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
489   -}
490   -
491 443 static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
492 444 {
493 445 uint32_t palcode;
... ... @@ -616,19 +568,103 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
616 568 switch (fn7) {
617 569 case 0x00:
618 570 /* ADDL */
619   - gen_arith3(ctx, &gen_op_addl, ra, rb, rc, islit, lit);
  571 + if (likely(rc != 31)) {
  572 + if (ra != 31) {
  573 + if (islit) {
  574 + tcg_gen_addi_i64(cpu_ir[rc], cpu_ir[ra], lit);
  575 + tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
  576 + } else if (rb != 31) {
  577 + tcg_gen_add_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
  578 + tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
  579 + } else
  580 + tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[ra]);
  581 + } else {
  582 + if (islit)
  583 + tcg_gen_movi_i64(cpu_ir[rc], (int32_t)lit);
  584 + else if (rb != 31)
  585 + tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);
  586 + else
  587 + tcg_gen_movi_i64(cpu_ir[rc], 0);
  588 + }
  589 + }
620 590 break;
621 591 case 0x02:
622 592 /* S4ADDL */
623   - gen_arith3(ctx, &gen_s4addl, ra, rb, rc, islit, lit);
  593 + if (likely(rc != 31)) {
  594 + if (ra != 31) {
  595 + if (islit || rb != 31) {
  596 + TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
  597 + tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
  598 + if (islit)
  599 + tcg_gen_addi_i64(tmp, tmp, lit);
  600 + else
  601 + tcg_gen_add_i64(tmp, tmp, cpu_ir[rb]);
  602 + tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
  603 + tcg_temp_free(tmp);
  604 + } else {
  605 + tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], 2);
  606 + tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
  607 + }
  608 + } else {
  609 + if (islit)
  610 + tcg_gen_movi_i64(cpu_ir[rc], lit);
  611 + else if (rb != 31)
  612 + tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);
  613 + else
  614 + tcg_gen_movi_i64(cpu_ir[rc], 0);
  615 + }
  616 + }
624 617 break;
625 618 case 0x09:
626 619 /* SUBL */
627   - gen_arith3(ctx, &gen_op_subl, ra, rb, rc, islit, lit);
  620 + if (likely(rc != 31)) {
  621 + if (ra != 31) {
  622 + if (islit) {
  623 + tcg_gen_subi_i64(cpu_ir[rc], cpu_ir[ra], lit);
  624 + tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
  625 + } else if (rb != 31) {
  626 + tcg_gen_sub_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
  627 + tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
  628 + } else
  629 + tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[ra]);
  630 + } else {
  631 + if (islit)
  632 + tcg_gen_movi_i64(cpu_ir[rc], -lit);
  633 + else if (rb != 31) {
  634 + tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
  635 + tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
  636 + } else
  637 + tcg_gen_movi_i64(cpu_ir[rc], 0);
  638 + }
  639 + }
628 640 break;
629 641 case 0x0B:
630 642 /* S4SUBL */
631   - gen_arith3(ctx, &gen_s4subl, ra, rb, rc, islit, lit);
  643 + if (likely(rc != 31)) {
  644 + if (ra != 31) {
  645 + if (islit || rb != 31) {
  646 + TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
  647 + tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
  648 + if (islit)
  649 + tcg_gen_subi_i64(tmp, tmp, lit);
  650 + else
  651 + tcg_gen_sub_i64(tmp, tmp, cpu_ir[rb]);
  652 + tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
  653 + tcg_temp_free(tmp);
  654 + } else {
  655 + tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], 2);
  656 + tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
  657 + }
  658 + } else {
  659 + if (islit)
  660 + tcg_gen_movi_i64(cpu_ir[rc], -lit);
  661 + else if (rb != 31) {
  662 + tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
  663 + tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
  664 + } else
  665 + tcg_gen_movi_i64(cpu_ir[rc], 0);
  666 + }
  667 + }
632 668 break;
633 669 case 0x0F:
634 670 /* CMPBGE */
... ... @@ -636,11 +672,58 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
636 672 break;
637 673 case 0x12:
638 674 /* S8ADDL */
639   - gen_arith3(ctx, &gen_s8addl, ra, rb, rc, islit, lit);
  675 + if (likely(rc != 31)) {
  676 + if (ra != 31) {
  677 + if (islit || rb != 31) {
  678 + TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
  679 + tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
  680 + if (islit)
  681 + tcg_gen_addi_i64(tmp, tmp, lit);
  682 + else
  683 + tcg_gen_add_i64(tmp, tmp, cpu_ir[rb]);
  684 + tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
  685 + tcg_temp_free(tmp);
  686 + } else {
  687 + tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], 3);
  688 + tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
  689 + }
  690 + } else {
  691 + if (islit)
  692 + tcg_gen_movi_i64(cpu_ir[rc], lit);
  693 + else if (rb != 31)
  694 + tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);
  695 + else
  696 + tcg_gen_movi_i64(cpu_ir[rc], 0);
  697 + }
  698 + }
640 699 break;
641 700 case 0x1B:
642 701 /* S8SUBL */
643   - gen_arith3(ctx, &gen_s8subl, ra, rb, rc, islit, lit);
  702 + if (likely(rc != 31)) {
  703 + if (ra != 31) {
  704 + if (islit || rb != 31) {
  705 + TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
  706 + tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
  707 + if (islit)
  708 + tcg_gen_subi_i64(tmp, tmp, lit);
  709 + else
  710 + tcg_gen_sub_i64(tmp, tmp, cpu_ir[rb]);
  711 + tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
  712 + tcg_temp_free(tmp);
  713 + } else {
  714 + tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], 3);
  715 + tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
  716 + }
  717 + } else {
  718 + if (islit)
  719 + tcg_gen_movi_i64(cpu_ir[rc], -lit);
  720 + else if (rb != 31) {
  721 + tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
  722 + tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
  723 + } else
  724 + tcg_gen_movi_i64(cpu_ir[rc], 0);
  725 + }
  726 + }
644 727 break;
645 728 case 0x1D:
646 729 /* CMPULT */
... ... @@ -648,19 +731,91 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
648 731 break;
649 732 case 0x20:
650 733 /* ADDQ */
651   - gen_arith3(ctx, &gen_op_addq, ra, rb, rc, islit, lit);
  734 + if (likely(rc != 31)) {
  735 + if (ra != 31) {
  736 + if (islit)
  737 + tcg_gen_addi_i64(cpu_ir[rc], cpu_ir[ra], lit);
  738 + else if (rb != 31)
  739 + tcg_gen_add_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
  740 + else
  741 + tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[ra]);
  742 + } else {
  743 + if (islit)
  744 + tcg_gen_movi_i64(cpu_ir[rc], lit);
  745 + else if (rb != 31)
  746 + tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
  747 + else
  748 + tcg_gen_movi_i64(cpu_ir[rc], 0);
  749 + }
  750 + }
652 751 break;
653 752 case 0x22:
654 753 /* S4ADDQ */
655   - gen_arith3(ctx, &gen_s4addq, ra, rb, rc, islit, lit);
  754 + if (likely(rc != 31)) {
  755 + if (ra != 31) {
  756 + if (islit || rb != 31) {
  757 + TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
  758 + tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
  759 + if (islit)
  760 + tcg_gen_addi_i64(cpu_ir[rc], tmp, lit);
  761 + else
  762 + tcg_gen_add_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
  763 + tcg_temp_free(tmp);
  764 + } else
  765 + tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], 2);
  766 + } else {
  767 + if (islit)
  768 + tcg_gen_movi_i64(cpu_ir[rc], lit);
  769 + else if (rb != 31)
  770 + tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
  771 + else
  772 + tcg_gen_movi_i64(cpu_ir[rc], 0);
  773 + }
  774 + }
656 775 break;
657 776 case 0x29:
658 777 /* SUBQ */
659   - gen_arith3(ctx, &gen_op_subq, ra, rb, rc, islit, lit);
  778 + if (likely(rc != 31)) {
  779 + if (ra != 31) {
  780 + if (islit)
  781 + tcg_gen_subi_i64(cpu_ir[rc], cpu_ir[ra], lit);
  782 + else if (rb != 31)
  783 + tcg_gen_sub_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
  784 + else
  785 + tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[ra]);
  786 + } else {
  787 + if (islit)
  788 + tcg_gen_movi_i64(cpu_ir[rc], -lit);
  789 + else if (rb != 31)
  790 + tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
  791 + else
  792 + tcg_gen_movi_i64(cpu_ir[rc], 0);
  793 + }
  794 + }
660 795 break;
661 796 case 0x2B:
662 797 /* S4SUBQ */
663   - gen_arith3(ctx, &gen_s4subq, ra, rb, rc, islit, lit);
  798 + if (likely(rc != 31)) {
  799 + if (ra != 31) {
  800 + if (islit || rb != 31) {
  801 + TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
  802 + tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
  803 + if (islit)
  804 + tcg_gen_subi_i64(cpu_ir[rc], tmp, lit);
  805 + else
  806 + tcg_gen_sub_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
  807 + tcg_temp_free(tmp);
  808 + } else
  809 + tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], 2);
  810 + } else {
  811 + if (islit)
  812 + tcg_gen_movi_i64(cpu_ir[rc], -lit);
  813 + else if (rb != 31)
  814 + tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
  815 + else
  816 + tcg_gen_movi_i64(cpu_ir[rc], 0);
  817 + }
  818 + }
664 819 break;
665 820 case 0x2D:
666 821 /* CMPEQ */
... ... @@ -668,11 +823,51 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
668 823 break;
669 824 case 0x32:
670 825 /* S8ADDQ */
671   - gen_arith3(ctx, &gen_s8addq, ra, rb, rc, islit, lit);
  826 + if (likely(rc != 31)) {
  827 + if (ra != 31) {
  828 + if (islit || rb != 31) {
  829 + TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
  830 + tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
  831 + if (islit)
  832 + tcg_gen_addi_i64(cpu_ir[rc], tmp, lit);
  833 + else
  834 + tcg_gen_add_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
  835 + tcg_temp_free(tmp);
  836 + } else
  837 + tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], 3);
  838 + } else {
  839 + if (islit)
  840 + tcg_gen_movi_i64(cpu_ir[rc], lit);
  841 + else if (rb != 31)
  842 + tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
  843 + else
  844 + tcg_gen_movi_i64(cpu_ir[rc], 0);
  845 + }
  846 + }
672 847 break;
673 848 case 0x3B:
674 849 /* S8SUBQ */
675   - gen_arith3(ctx, &gen_s8subq, ra, rb, rc, islit, lit);
  850 + if (likely(rc != 31)) {
  851 + if (ra != 31) {
  852 + if (islit || rb != 31) {
  853 + TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
  854 + tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
  855 + if (islit)
  856 + tcg_gen_subi_i64(cpu_ir[rc], tmp, lit);
  857 + else
  858 + tcg_gen_sub_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
  859 + tcg_temp_free(tmp);
  860 + } else
  861 + tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], 3);
  862 + } else {
  863 + if (islit)
  864 + tcg_gen_movi_i64(cpu_ir[rc], -lit);
  865 + else if (rb != 31)
  866 + tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
  867 + else
  868 + tcg_gen_movi_i64(cpu_ir[rc], 0);
  869 + }
  870 + }
676 871 break;
677 872 case 0x3D:
678 873 /* CMPULE */
... ... @@ -710,11 +905,31 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
710 905 switch (fn7) {
711 906 case 0x00:
712 907 /* AND */
713   - gen_arith3(ctx, &gen_op_and, ra, rb, rc, islit, lit);
  908 + if (likely(rc != 31)) {
  909 + if (ra == 31 || (rb == 31 && !islit))
  910 + tcg_gen_movi_i64(cpu_ir[rc], 0);
  911 + else if (islit)
  912 + tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[ra], lit);
  913 + else
  914 + tcg_gen_and_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
  915 + }
714 916 break;
715 917 case 0x08:
716 918 /* BIC */
717   - gen_arith3(ctx, &gen_op_bic, ra, rb, rc, islit, lit);
  919 + if (likely(rc != 31)) {
  920 + if (ra != 31) {
  921 + if (islit)
  922 + tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
  923 + else if (rb != 31) {
  924 + TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
  925 + tcg_gen_not_i64(tmp, cpu_ir[rb]);
  926 + tcg_gen_and_i64(cpu_ir[rc], cpu_ir[ra], tmp);
  927 + tcg_temp_free(tmp);
  928 + } else
  929 + tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[ra]);
  930 + } else
  931 + tcg_gen_movi_i64(cpu_ir[rc], 0);
  932 + }
718 933 break;
719 934 case 0x14:
720 935 /* CMOVLBS */
... ... @@ -726,21 +941,22 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
726 941 break;
727 942 case 0x20:
728 943 /* BIS */
729   - if (ra == rb || ra == 31 || rb == 31) {
730   - if (ra == 31 && rc == 31) {
731   - /* NOP */
732   - gen_op_nop();
  944 + if (likely(rc != 31)) {
  945 + if (ra != 31) {
  946 + if (islit)
  947 + tcg_gen_ori_i64(cpu_ir[rc], cpu_ir[ra], lit);
  948 + else if (rb != 31)
  949 + tcg_gen_or_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
  950 + else
  951 + tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[ra]);
733 952 } else {
734   - /* MOV */
735   - if (rc != 31) {
736   - if (rb != 31)
737   - tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
738   - else
739   - tcg_gen_movi_i64(cpu_ir[rc], 0);
740   - }
  953 + if (islit)
  954 + tcg_gen_movi_i64(cpu_ir[rc], lit);
  955 + else if (rb != 31)
  956 + tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
  957 + else
  958 + tcg_gen_movi_i64(cpu_ir[rc], 0);
741 959 }
742   - } else {
743   - gen_arith3(ctx, &gen_op_bis, ra, rb, rc, islit, lit);
744 960 }
745 961 break;
746 962 case 0x24:
... ... @@ -753,11 +969,45 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
753 969 break;
754 970 case 0x28:
755 971 /* ORNOT */
756   - gen_arith3(ctx, &gen_op_ornot, ra, rb, rc, islit, lit);
  972 + if (likely(rc != 31)) {
  973 + if (rb == 31 && !islit)
  974 + tcg_gen_movi_i64(cpu_ir[rc], ~0);
  975 + else if (ra != 31) {
  976 + if (islit)
  977 + tcg_gen_ori_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
  978 + else {
  979 + TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
  980 + tcg_gen_not_i64(tmp, cpu_ir[rb]);
  981 + tcg_gen_or_i64(cpu_ir[rc], cpu_ir[ra], tmp);
  982 + tcg_temp_free(tmp);
  983 + }
  984 + } else {
  985 + if (islit)
  986 + tcg_gen_movi_i64(cpu_ir[rc], ~lit);
  987 + else
  988 + tcg_gen_not_i64(cpu_ir[rc], cpu_ir[rb]);
  989 + }
  990 + }
757 991 break;
758 992 case 0x40:
759 993 /* XOR */
760   - gen_arith3(ctx, &gen_op_xor, ra, rb, rc, islit, lit);
  994 + if (likely(rc != 31)) {
  995 + if (ra != 31) {
  996 + if (islit)
  997 + tcg_gen_xori_i64(cpu_ir[rc], cpu_ir[ra], lit);
  998 + else if (rb != 31)
  999 + tcg_gen_xor_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
  1000 + else
  1001 + tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[ra]);
  1002 + } else {
  1003 + if (islit)
  1004 + tcg_gen_movi_i64(cpu_ir[rc], lit);
  1005 + else if (rb != 31)
  1006 + tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
  1007 + else
  1008 + tcg_gen_movi_i64(cpu_ir[rc], 0);
  1009 + }
  1010 + }
761 1011 break;
762 1012 case 0x44:
763 1013 /* CMOVLT */
... ... @@ -769,7 +1019,26 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
769 1019 break;
770 1020 case 0x48:
771 1021 /* EQV */
772   - gen_arith3(ctx, &gen_op_eqv, ra, rb, rc, islit, lit);
  1022 + if (likely(rc != 31)) {
  1023 + if (ra != 31) {
  1024 + if (islit)
  1025 + tcg_gen_xori_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
  1026 + else if (rb != 31) {
  1027 + TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
  1028 + tcg_gen_not_i64(tmp, cpu_ir[rb]);
  1029 + tcg_gen_xor_i64(cpu_ir[rc], cpu_ir[ra], tmp);
  1030 + tcg_temp_free(tmp);
  1031 + } else
  1032 + tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[ra]);
  1033 + } else {
  1034 + if (islit)
  1035 + tcg_gen_movi_i64(cpu_ir[rc], ~lit);
  1036 + else if (rb != 31)
  1037 + tcg_gen_not_i64(cpu_ir[rc], cpu_ir[rb]);
  1038 + else
  1039 + tcg_gen_movi_i64(cpu_ir[rc], ~0);
  1040 + }
  1041 + }
773 1042 break;
774 1043 case 0x61:
775 1044 /* AMASK */
... ... @@ -852,7 +1121,20 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
852 1121 break;
853 1122 case 0x34:
854 1123 /* SRL */
855   - gen_arith3(ctx, &gen_op_srl, ra, rb, rc, islit, lit);
  1124 + if (likely(rc != 31)) {
  1125 + if (ra != 31) {
  1126 + if (islit)
  1127 + tcg_gen_shri_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);
  1128 + else if (rb != 31) {
  1129 + TCGv shift = tcg_temp_new(TCG_TYPE_I64);
  1130 + tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);
  1131 + tcg_gen_shr_i64(cpu_ir[rc], cpu_ir[ra], shift);
  1132 + tcg_temp_free(shift);
  1133 + } else
  1134 + tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[ra]);
  1135 + } else
  1136 + tcg_gen_movi_i64(cpu_ir[rc], 0);
  1137 + }
856 1138 break;
857 1139 case 0x36:
858 1140 /* EXTQL */
... ... @@ -860,7 +1142,20 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
860 1142 break;
861 1143 case 0x39:
862 1144 /* SLL */
863   - gen_arith3(ctx, &gen_op_sll, ra, rb, rc, islit, lit);
  1145 + if (likely(rc != 31)) {
  1146 + if (ra != 31) {
  1147 + if (islit)
  1148 + tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);
  1149 + else if (rb != 31) {
  1150 + TCGv shift = tcg_temp_new(TCG_TYPE_I64);
  1151 + tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);
  1152 + tcg_gen_shl_i64(cpu_ir[rc], cpu_ir[ra], shift);
  1153 + tcg_temp_free(shift);
  1154 + } else
  1155 + tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[ra]);
  1156 + } else
  1157 + tcg_gen_movi_i64(cpu_ir[rc], 0);
  1158 + }
864 1159 break;
865 1160 case 0x3B:
866 1161 /* INSQL */
... ... @@ -868,7 +1163,20 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
868 1163 break;
869 1164 case 0x3C:
870 1165 /* SRA */
871   - gen_arith3(ctx, &gen_op_sra, ra, rb, rc, islit, lit);
  1166 + if (likely(rc != 31)) {
  1167 + if (ra != 31) {
  1168 + if (islit)
  1169 + tcg_gen_sari_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);
  1170 + else if (rb != 31) {
  1171 + TCGv shift = tcg_temp_new(TCG_TYPE_I64);
  1172 + tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);
  1173 + tcg_gen_sar_i64(cpu_ir[rc], cpu_ir[ra], shift);
  1174 + tcg_temp_free(shift);
  1175 + } else
  1176 + tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[ra]);
  1177 + } else
  1178 + tcg_gen_movi_i64(cpu_ir[rc], 0);
  1179 + }
872 1180 break;
873 1181 case 0x52:
874 1182 /* MSKWH */
... ... @@ -914,11 +1222,28 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
914 1222 switch (fn7) {
915 1223 case 0x00:
916 1224 /* MULL */
917   - gen_arith3(ctx, &gen_op_mull, ra, rb, rc, islit, lit);
  1225 + if (likely(rc != 31)) {
  1226 + if (ra == 31 || (rb == 31 && !islit))
  1227 + tcg_gen_movi_i64(cpu_ir[rc], 0);
  1228 + else {
  1229 + if (islit)
  1230 + tcg_gen_muli_i64(cpu_ir[rc], cpu_ir[ra], lit);
  1231 + else
  1232 + tcg_gen_mul_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
  1233 + tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
  1234 + }
  1235 + }
918 1236 break;
919 1237 case 0x20:
920 1238 /* MULQ */
921   - gen_arith3(ctx, &gen_op_mulq, ra, rb, rc, islit, lit);
  1239 + if (likely(rc != 31)) {
  1240 + if (ra == 31 || (rb == 31 && !islit))
  1241 + tcg_gen_movi_i64(cpu_ir[rc], 0);
  1242 + else if (islit)
  1243 + tcg_gen_muli_i64(cpu_ir[rc], cpu_ir[ra], lit);
  1244 + else
  1245 + tcg_gen_mul_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
  1246 + }
922 1247 break;
923 1248 case 0x30:
924 1249 /* UMULH */
... ...