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,72 +198,36 @@ void OPPROTO op_clear_irf (void)
198 } 198 }
199 199
200 /* Arithmetic */ 200 /* Arithmetic */
201 -void OPPROTO op_addq (void)  
202 -{  
203 - T0 += T1;  
204 - RETURN();  
205 -}  
206 -  
207 void OPPROTO op_addqv (void) 201 void OPPROTO op_addqv (void)
208 { 202 {
209 helper_addqv(); 203 helper_addqv();
210 RETURN(); 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 void OPPROTO op_addlv (void) 207 void OPPROTO op_addlv (void)
220 { 208 {
221 helper_addlv(); 209 helper_addlv();
222 RETURN(); 210 RETURN();
223 } 211 }
224 212
225 -void OPPROTO op_subq (void)  
226 -{  
227 - T0 -= T1;  
228 - RETURN();  
229 -}  
230 -  
231 void OPPROTO op_subqv (void) 213 void OPPROTO op_subqv (void)
232 { 214 {
233 helper_subqv(); 215 helper_subqv();
234 RETURN(); 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 void OPPROTO op_sublv (void) 219 void OPPROTO op_sublv (void)
244 { 220 {
245 helper_sublv(); 221 helper_sublv();
246 RETURN(); 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 void OPPROTO op_mullv (void) 225 void OPPROTO op_mullv (void)
256 { 226 {
257 helper_mullv(); 227 helper_mullv();
258 RETURN(); 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 void OPPROTO op_mulqv (void) 231 void OPPROTO op_mulqv (void)
268 { 232 {
269 helper_mulqv(); 233 helper_mulqv();
@@ -280,60 +244,6 @@ void OPPROTO op_umulh (void) @@ -280,60 +244,6 @@ void OPPROTO op_umulh (void)
280 } 244 }
281 245
282 /* Logical */ 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 void OPPROTO op_mskbl (void) 247 void OPPROTO op_mskbl (void)
338 { 248 {
339 helper_mskbl(); 249 helper_mskbl();
target-alpha/translate.c
@@ -440,54 +440,6 @@ static always_inline void gen_itf (DisasContext *ctx, @@ -440,54 +440,6 @@ static always_inline void gen_itf (DisasContext *ctx,
440 gen_store_fir(ctx, rc, 0); 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 static always_inline int translate_one (DisasContext *ctx, uint32_t insn) 443 static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
492 { 444 {
493 uint32_t palcode; 445 uint32_t palcode;
@@ -616,19 +568,103 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn) @@ -616,19 +568,103 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
616 switch (fn7) { 568 switch (fn7) {
617 case 0x00: 569 case 0x00:
618 /* ADDL */ 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 break; 590 break;
621 case 0x02: 591 case 0x02:
622 /* S4ADDL */ 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 break; 617 break;
625 case 0x09: 618 case 0x09:
626 /* SUBL */ 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 break; 640 break;
629 case 0x0B: 641 case 0x0B:
630 /* S4SUBL */ 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 break; 668 break;
633 case 0x0F: 669 case 0x0F:
634 /* CMPBGE */ 670 /* CMPBGE */
@@ -636,11 +672,58 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn) @@ -636,11 +672,58 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
636 break; 672 break;
637 case 0x12: 673 case 0x12:
638 /* S8ADDL */ 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 break; 699 break;
641 case 0x1B: 700 case 0x1B:
642 /* S8SUBL */ 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 break; 727 break;
645 case 0x1D: 728 case 0x1D:
646 /* CMPULT */ 729 /* CMPULT */
@@ -648,19 +731,91 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn) @@ -648,19 +731,91 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
648 break; 731 break;
649 case 0x20: 732 case 0x20:
650 /* ADDQ */ 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 break; 751 break;
653 case 0x22: 752 case 0x22:
654 /* S4ADDQ */ 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 break; 775 break;
657 case 0x29: 776 case 0x29:
658 /* SUBQ */ 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 break; 795 break;
661 case 0x2B: 796 case 0x2B:
662 /* S4SUBQ */ 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 break; 819 break;
665 case 0x2D: 820 case 0x2D:
666 /* CMPEQ */ 821 /* CMPEQ */
@@ -668,11 +823,51 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn) @@ -668,11 +823,51 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
668 break; 823 break;
669 case 0x32: 824 case 0x32:
670 /* S8ADDQ */ 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 break; 847 break;
673 case 0x3B: 848 case 0x3B:
674 /* S8SUBQ */ 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 break; 871 break;
677 case 0x3D: 872 case 0x3D:
678 /* CMPULE */ 873 /* CMPULE */
@@ -710,11 +905,31 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn) @@ -710,11 +905,31 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
710 switch (fn7) { 905 switch (fn7) {
711 case 0x00: 906 case 0x00:
712 /* AND */ 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 break; 916 break;
715 case 0x08: 917 case 0x08:
716 /* BIC */ 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 break; 933 break;
719 case 0x14: 934 case 0x14:
720 /* CMOVLBS */ 935 /* CMOVLBS */
@@ -726,21 +941,22 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn) @@ -726,21 +941,22 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
726 break; 941 break;
727 case 0x20: 942 case 0x20:
728 /* BIS */ 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 } else { 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 break; 961 break;
746 case 0x24: 962 case 0x24:
@@ -753,11 +969,45 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn) @@ -753,11 +969,45 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
753 break; 969 break;
754 case 0x28: 970 case 0x28:
755 /* ORNOT */ 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 break; 991 break;
758 case 0x40: 992 case 0x40:
759 /* XOR */ 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 break; 1011 break;
762 case 0x44: 1012 case 0x44:
763 /* CMOVLT */ 1013 /* CMOVLT */
@@ -769,7 +1019,26 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn) @@ -769,7 +1019,26 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
769 break; 1019 break;
770 case 0x48: 1020 case 0x48:
771 /* EQV */ 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 break; 1042 break;
774 case 0x61: 1043 case 0x61:
775 /* AMASK */ 1044 /* AMASK */
@@ -852,7 +1121,20 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn) @@ -852,7 +1121,20 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
852 break; 1121 break;
853 case 0x34: 1122 case 0x34:
854 /* SRL */ 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 break; 1138 break;
857 case 0x36: 1139 case 0x36:
858 /* EXTQL */ 1140 /* EXTQL */
@@ -860,7 +1142,20 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn) @@ -860,7 +1142,20 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
860 break; 1142 break;
861 case 0x39: 1143 case 0x39:
862 /* SLL */ 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 break; 1159 break;
865 case 0x3B: 1160 case 0x3B:
866 /* INSQL */ 1161 /* INSQL */
@@ -868,7 +1163,20 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn) @@ -868,7 +1163,20 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
868 break; 1163 break;
869 case 0x3C: 1164 case 0x3C:
870 /* SRA */ 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 break; 1180 break;
873 case 0x52: 1181 case 0x52:
874 /* MSKWH */ 1182 /* MSKWH */
@@ -914,11 +1222,28 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn) @@ -914,11 +1222,28 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
914 switch (fn7) { 1222 switch (fn7) {
915 case 0x00: 1223 case 0x00:
916 /* MULL */ 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 break; 1236 break;
919 case 0x20: 1237 case 0x20:
920 /* MULQ */ 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 break; 1247 break;
923 case 0x30: 1248 case 0x30:
924 /* UMULH */ 1249 /* UMULH */