@@ -728,98 +728,89 @@ static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv a, TCGv b) {
728728static void gen_test_cc (int cc , TCGLabel * label ) {
729729 TCGv tmp ;
730730 TCGv tmp2 ;
731- TCGLabel * inv ;
731+
732+ TCGv_i32 value ;
733+ TCGCond cond ;
732734
733735 switch (cc ) {
734736 case 0 : /* eq: Z */
735- tmp = load_cpu_field (ZF );
736- tcg_gen_brcondi_i32 (TCG_COND_EQ , tmp , 0 , label );
737- break ;
738737 case 1 : /* ne: !Z */
739- tmp = load_cpu_field ( ZF ) ;
740- tcg_gen_brcondi_i32 ( TCG_COND_NE , tmp , 0 , label );
738+ cond = TCG_COND_EQ ;
739+ value = load_cpu_field ( ZF );
741740 break ;
742741 case 2 : /* cs: C */
743- tmp = load_cpu_field (CF );
744- tcg_gen_brcondi_i32 (TCG_COND_NE , tmp , 0 , label );
745- break ;
746742 case 3 : /* cc: !C */
747- tmp = load_cpu_field ( CF ) ;
748- tcg_gen_brcondi_i32 ( TCG_COND_EQ , tmp , 0 , label );
743+ cond = TCG_COND_NE ;
744+ value = load_cpu_field ( CF );
749745 break ;
750746 case 4 : /* mi: N */
751- tmp = load_cpu_field (NF );
752- tcg_gen_brcondi_i32 (TCG_COND_LT , tmp , 0 , label );
753- break ;
754747 case 5 : /* pl: !N */
755- tmp = load_cpu_field ( NF ) ;
756- tcg_gen_brcondi_i32 ( TCG_COND_GE , tmp , 0 , label );
748+ cond = TCG_COND_LT ;
749+ value = load_cpu_field ( NF );
757750 break ;
758751 case 6 : /* vs: V */
759- tmp = load_cpu_field (VF );
760- tcg_gen_brcondi_i32 (TCG_COND_LT , tmp , 0 , label );
761- break ;
762752 case 7 : /* vc: !V */
763- tmp = load_cpu_field ( VF ) ;
764- tcg_gen_brcondi_i32 ( TCG_COND_GE , tmp , 0 , label );
753+ cond = TCG_COND_LT ;
754+ value = load_cpu_field ( VF );
765755 break ;
766756 case 8 : /* hi: C && !Z */
767- inv = gen_new_label ();
768- tmp = load_cpu_field (CF );
769- tcg_gen_brcondi_i32 (TCG_COND_EQ , tmp , 0 , inv );
770- tcg_temp_free_i32 (tmp );
771- tmp = load_cpu_field (ZF );
772- tcg_gen_brcondi_i32 (TCG_COND_NE , tmp , 0 , label );
773- gen_set_label (inv );
774- break ;
775757 case 9 : /* ls: !C || Z */
758+ cond = TCG_COND_NE ;
759+ value = tcg_temp_new_i32 ();
776760 tmp = load_cpu_field (CF );
777- tcg_gen_brcondi_i32 (TCG_COND_EQ , tmp , 0 , label );
761+ tmp2 = load_cpu_field (ZF );
762+ /* CF is 1 for C, so -CF is an all-bits-set mask for C;
763+ ZF is non-zero for !Z; so AND the two subexpressions. */
764+ tcg_gen_neg_i32 (value , tmp );
765+ tcg_gen_and_i32 (value , value , tmp2 );
778766 tcg_temp_free_i32 (tmp );
779- tmp = load_cpu_field (ZF );
780- tcg_gen_brcondi_i32 (TCG_COND_EQ , tmp , 0 , label );
781- break ;
782- case 10 : /* ge: N == V -> N ^ V == 0 */
783- tmp = load_cpu_field (VF );
784- tmp2 = load_cpu_field (NF );
785- tcg_gen_xor_i32 (tmp , tmp , tmp2 );
786767 tcg_temp_free_i32 (tmp2 );
787- tcg_gen_brcondi_i32 (TCG_COND_GE , tmp , 0 , label );
788768 break ;
769+ case 10 : /* ge: N == V -> N ^ V == 0 */
789770 case 11 : /* lt: N != V -> N ^ V != 0 */
771+ cond = TCG_COND_GE ;
772+ value = tcg_temp_new_i32 ();
790773 tmp = load_cpu_field (VF );
791774 tmp2 = load_cpu_field (NF );
792- tcg_gen_xor_i32 (tmp , tmp , tmp2 );
775+ tcg_gen_xor_i32 (value , tmp , tmp2 );
776+ tcg_temp_free_i32 (tmp );
793777 tcg_temp_free_i32 (tmp2 );
794- tcg_gen_brcondi_i32 (TCG_COND_LT , tmp , 0 , label );
795778 break ;
796779 case 12 : /* gt: !Z && N == V */
797- inv = gen_new_label ();
798- tmp = load_cpu_field (ZF );
799- tcg_gen_brcondi_i32 (TCG_COND_EQ , tmp , 0 , inv );
800- tcg_temp_free_i32 (tmp );
780+ case 13 : /* le: Z || N != V */
781+ cond = TCG_COND_NE ;
782+ value = tcg_temp_new_i32 ();
801783 tmp = load_cpu_field (VF );
802784 tmp2 = load_cpu_field (NF );
803- tcg_gen_xor_i32 (tmp , tmp , tmp2 );
785+ /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
786+ * the sign bit then AND with ZF to yield the result. */
787+ tcg_gen_xor_i32 (value , tmp , tmp2 );
788+ tcg_gen_sari_i32 (value , value , 31 );
789+ tcg_temp_free_i32 (tmp );
804790 tcg_temp_free_i32 (tmp2 );
805- tcg_gen_brcondi_i32 (TCG_COND_GE , tmp , 0 , label );
806- gen_set_label (inv );
807- break ;
808- case 13 : /* le: Z || N != V */
809791 tmp = load_cpu_field (ZF );
810- tcg_gen_brcondi_i32 ( TCG_COND_EQ , tmp , 0 , label );
792+ tcg_gen_andc_i32 ( value , tmp , value );
811793 tcg_temp_free_i32 (tmp );
812- tmp = load_cpu_field (VF );
813- tmp2 = load_cpu_field (NF );
814- tcg_gen_xor_i32 (tmp , tmp , tmp2 );
815- tcg_temp_free_i32 (tmp2 );
816- tcg_gen_brcondi_i32 (TCG_COND_LT , tmp , 0 , label );
817794 break ;
795+ case 14 : /* always */
796+ case 15 : /* always */
797+ /* Use the ALWAYS condition, which will fold early.
798+ * It doesn't matter what we use for the value. */
799+ cond = TCG_COND_ALWAYS ;
800+ value = load_cpu_field (ZF );
801+ goto no_invert ;
818802 default :
819803 fprintf (stderr , "Bad condition code 0x%x\n" , cc );
820804 abort ();
821805 }
822- tcg_temp_free_i32 (tmp );
806+
807+ if (cc & 1 ) {
808+ cond = tcg_invert_cond (cond );
809+ }
810+
811+ no_invert :
812+ tcg_gen_brcondi_i32 (cond , value , 0 , label );
813+ tcg_temp_free_i32 (value );
823814}
824815
825816static const uint8_t table_logic_cc [16 ] = {
0 commit comments