Commit 30c7183b676076c940538b838c330c854a7995a9
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
Showing
2 changed files
with
408 additions
and
173 deletions
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 */ |