@@ -6885,6 +6885,65 @@ static int FixupQMux(int arg, IRList *irl, IR *ir)
6885
6885
return 1 ;
6886
6886
}
6887
6887
6888
+ /*
6889
+ * sign extend followed by AND is sometimes redundant
6890
+ */
6891
+ static PeepholePattern pat_shl_shr_and [] = {
6892
+ { COND_ANY , OPC_SHL , PEEP_OP_SET |0 , PEEP_OP_SET_IMM |1 , PEEP_FLAGS_NONE },
6893
+ { COND_ANY , OPC_SAR , PEEP_OP_MATCH |0 , PEEP_OP_MATCH |1 , PEEP_FLAGS_NONE },
6894
+ { COND_ANY , OPC_AND , PEEP_OP_MATCH |0 , PEEP_OP_SET_IMM |2 , PEEP_FLAGS_NONE },
6895
+
6896
+ { 0 , 0 , 0 , 0 , PEEP_FLAGS_DONE }
6897
+ };
6898
+ static PeepholePattern pat_signx_and [] = {
6899
+ { COND_ANY , OPC_SIGNX , PEEP_OP_SET |0 , PEEP_OP_SET_IMM |1 , PEEP_FLAGS_P2 },
6900
+ { COND_ANY , OPC_AND , PEEP_OP_MATCH |0 , PEEP_OP_SET_IMM |2 , PEEP_FLAGS_P2 },
6901
+
6902
+ { 0 , 0 , 0 , 0 , PEEP_FLAGS_DONE }
6903
+ };
6904
+
6905
+ static int FixupShlShrAndImm (int arg , IRList * irl , IR * ir0 )
6906
+ {
6907
+ IR * ir1 , * ir2 ;
6908
+ int signx_width ;
6909
+ unsigned and_pat , signx_pat ;
6910
+
6911
+ ir1 = NextIR (ir0 ); // this is the SHR
6912
+ ir2 = NextIR (ir1 ); // and this is the AND
6913
+ signx_width = ir0 -> src -> val & 0x1f ;
6914
+ and_pat = (unsigned )ir2 -> src -> val ;
6915
+ signx_pat = (1U <<(signx_width )) - 1 ;
6916
+ if ( (and_pat & signx_pat ) == and_pat ) {
6917
+ // we can delete the shl and shr
6918
+ DeleteIR (irl , ir1 );
6919
+ DeleteIR (irl , ir0 );
6920
+ return 1 ;
6921
+ }
6922
+ return 0 ;
6923
+ }
6924
+
6925
+ static int FixupSignxAndImm (int arg , IRList * irl , IR * ir0 )
6926
+ {
6927
+ IR * ir1 ;
6928
+ int signx_width ;
6929
+ unsigned and_pat , signx_pat ;
6930
+
6931
+ ir1 = NextIR (ir0 ); // this is the AND
6932
+ signx_width = ir0 -> src -> val & 0x1f ;
6933
+ and_pat = (unsigned )ir1 -> src -> val ;
6934
+ signx_pat = (1U <<(signx_width + 1 )) - 1 ;
6935
+ if ( (and_pat & signx_pat ) == and_pat ) {
6936
+ // we can delete the signx
6937
+ DeleteIR (irl , ir0 );
6938
+ return 1 ;
6939
+ }
6940
+ return 0 ;
6941
+ }
6942
+
6943
+ /*
6944
+ * the actual list of peepholes
6945
+ */
6946
+
6888
6947
struct Peepholes {
6889
6948
PeepholePattern * check ;
6890
6949
int arg ;
@@ -6900,6 +6959,9 @@ struct Peepholes {
6900
6959
{ pat_zeroex , OPC_ZEROX , ReplaceExtend },
6901
6960
{ pat_signex , OPC_SIGNX , ReplaceExtend },
6902
6961
6962
+ { pat_signx_and , 0 , FixupSignxAndImm },
6963
+ { pat_shl_shr_and , 0 , FixupShlShrAndImm },
6964
+
6903
6965
{ pat_drvc1 , OPC_DRVC , ReplaceDrvc },
6904
6966
{ pat_drvc2 , OPC_DRVC , ReplaceDrvc },
6905
6967
{ pat_drvnc1 , OPC_DRVNC , ReplaceDrvc },
0 commit comments