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