@@ -294,6 +294,13 @@ struct ClassInfo {
294
294
}
295
295
};
296
296
297
+ class AsmVariantInfo {
298
+ public:
299
+ std::string TokenizingCharacters;
300
+ std::string SeparatorCharacters;
301
+ std::string BreakCharacters;
302
+ };
303
+
297
304
// / MatchableInfo - Helper class for storing the necessary information for an
298
305
// / instruction or alias which is capable of being matched.
299
306
struct MatchableInfo {
@@ -484,7 +491,8 @@ struct MatchableInfo {
484
491
485
492
void initialize (const AsmMatcherInfo &Info,
486
493
SmallPtrSetImpl<Record*> &SingletonRegisters,
487
- int AsmVariantNo, StringRef RegisterPrefix);
494
+ int AsmVariantNo, StringRef RegisterPrefix,
495
+ AsmVariantInfo const &Variant);
488
496
489
497
// / validate - Return true if this matchable is a valid thing to match against
490
498
// / and perform a bunch of validity checking.
@@ -584,8 +592,10 @@ struct MatchableInfo {
584
592
void dump () const ;
585
593
586
594
private:
587
- void tokenizeAsmString (const AsmMatcherInfo &Info);
588
- void addAsmOperand (size_t Start, size_t End);
595
+ void tokenizeAsmString (AsmMatcherInfo const &Info,
596
+ AsmVariantInfo const &Variant);
597
+ void addAsmOperand (size_t Start, size_t End,
598
+ std::string const &SeparatorCharacters);
589
599
};
590
600
591
601
// / SubtargetFeatureInfo - Helper class for storing information on a subtarget
@@ -828,12 +838,13 @@ extractSingletonRegisterForAsmOperand(MatchableInfo::AsmOperand &Op,
828
838
829
839
void MatchableInfo::initialize (const AsmMatcherInfo &Info,
830
840
SmallPtrSetImpl<Record*> &SingletonRegisters,
831
- int AsmVariantNo, StringRef RegisterPrefix) {
841
+ int AsmVariantNo, StringRef RegisterPrefix,
842
+ AsmVariantInfo const &Variant) {
832
843
AsmVariantID = AsmVariantNo;
833
844
AsmString =
834
845
CodeGenInstruction::FlattenAsmStringVariants (AsmString, AsmVariantNo);
835
846
836
- tokenizeAsmString (Info);
847
+ tokenizeAsmString (Info, Variant );
837
848
838
849
// Compute the require features.
839
850
for (Record *Predicate : TheDef->getValueAsListOfDefs (" Predicates" ))
@@ -857,9 +868,9 @@ void MatchableInfo::initialize(const AsmMatcherInfo &Info,
857
868
}
858
869
859
870
// / Append an AsmOperand for the given substring of AsmString.
860
- void MatchableInfo::addAsmOperand (size_t Start, size_t End) {
871
+ void MatchableInfo::addAsmOperand (size_t Start, size_t End,
872
+ std::string const &Separators) {
861
873
StringRef String = AsmString;
862
- StringRef Separators = " []*! \t ," ;
863
874
// Look for separators before and after to figure out is this token is
864
875
// isolated. Accept '$$' as that's how we escape '$'.
865
876
bool IsIsolatedToken =
@@ -870,42 +881,54 @@ void MatchableInfo::addAsmOperand(size_t Start, size_t End) {
870
881
}
871
882
872
883
// / tokenizeAsmString - Tokenize a simplified assembly string.
873
- void MatchableInfo::tokenizeAsmString (const AsmMatcherInfo &Info) {
884
+ void MatchableInfo::tokenizeAsmString (const AsmMatcherInfo &Info,
885
+ AsmVariantInfo const &Variant) {
874
886
StringRef String = AsmString;
875
- size_t Prev = 0 ;
876
- bool InTok = true ;
877
- for (size_t i = 0 , e = String.size (); i != e; ++i) {
878
- switch (String[i]) {
879
- case ' [' :
880
- case ' ]' :
881
- case ' *' :
882
- case ' !' :
883
- case ' ' :
884
- case ' \t ' :
885
- case ' ,' :
886
- if (InTok) {
887
- addAsmOperand (Prev, i);
887
+ unsigned Prev = 0 ;
888
+ bool InTok = false ;
889
+ std::string Separators = Variant.TokenizingCharacters +
890
+ Variant.SeparatorCharacters ;
891
+ for (unsigned i = 0 , e = String.size (); i != e; ++i) {
892
+ if (Variant.BreakCharacters .find (String[i]) != std::string::npos) {
893
+ if (InTok) {
894
+ addAsmOperand (Prev, i, Separators);
895
+ Prev = i;
896
+ }
897
+ InTok = true ;
898
+ continue ;
899
+ }
900
+ if (Variant.TokenizingCharacters .find (String[i]) != std::string::npos) {
901
+ if (InTok) {
902
+ addAsmOperand (Prev, i, Separators);
888
903
InTok = false ;
889
904
}
890
- if (!isspace (String[i]) && String[i] != ' ,' )
891
- addAsmOperand (i, i + 1 );
905
+ addAsmOperand (i, i + 1 , Separators);
892
906
Prev = i + 1 ;
893
- break ;
894
-
907
+ continue ;
908
+ }
909
+ if (Variant.SeparatorCharacters .find (String[i]) != std::string::npos) {
910
+ if (InTok) {
911
+ addAsmOperand (Prev, i, Separators);
912
+ InTok = false ;
913
+ }
914
+ Prev = i + 1 ;
915
+ continue ;
916
+ }
917
+ switch (String[i]) {
895
918
case ' \\ ' :
896
919
if (InTok) {
897
- addAsmOperand (Prev, i);
920
+ addAsmOperand (Prev, i, Separators );
898
921
InTok = false ;
899
922
}
900
923
++i;
901
924
assert (i != String.size () && " Invalid quoted character" );
902
- addAsmOperand (i, i + 1 );
925
+ addAsmOperand (i, i + 1 , Separators );
903
926
Prev = i + 1 ;
904
927
break ;
905
928
906
929
case ' $' : {
907
- if (InTok) {
908
- addAsmOperand (Prev, i);
930
+ if (InTok && Prev != i ) {
931
+ addAsmOperand (Prev, i, Separators );
909
932
InTok = false ;
910
933
}
911
934
@@ -915,31 +938,20 @@ void MatchableInfo::tokenizeAsmString(const AsmMatcherInfo &Info) {
915
938
break ;
916
939
}
917
940
918
- // If this is "${" find the next "}" and make an identifier like "${xxx}"
919
- size_t EndPos = String.find (' }' , i);
920
- assert (EndPos != StringRef::npos &&
921
- " Missing brace in operand reference!" );
922
- addAsmOperand (i, EndPos+1 );
941
+ StringRef::iterator End = std::find (String.begin () + i, String.end (),' }' );
942
+ assert (End != String.end () && " Missing brace in operand reference!" );
943
+ size_t EndPos = End - String.begin ();
944
+ addAsmOperand (i, EndPos+1 , Separators);
923
945
Prev = EndPos + 1 ;
924
946
i = EndPos;
925
947
break ;
926
948
}
927
-
928
- case ' .' :
929
- if (!Info.AsmParser ->getValueAsBit (" MnemonicContainsDot" )) {
930
- if (InTok)
931
- addAsmOperand (Prev, i);
932
- Prev = i;
933
- }
934
- InTok = true ;
935
- break ;
936
-
937
949
default :
938
950
InTok = true ;
939
951
}
940
952
}
941
953
if (InTok && Prev != String.size ())
942
- addAsmOperand (Prev, StringRef::npos);
954
+ addAsmOperand (Prev, StringRef::npos, Separators );
943
955
944
956
// The first token of the instruction is the mnemonic, which must be a
945
957
// simple string, not a $foo variable or a singleton register.
@@ -1373,6 +1385,13 @@ void AsmMatcherInfo::buildInfo() {
1373
1385
std::string CommentDelimiter =
1374
1386
AsmVariant->getValueAsString (" CommentDelimiter" );
1375
1387
std::string RegisterPrefix = AsmVariant->getValueAsString (" RegisterPrefix" );
1388
+ AsmVariantInfo Variant;
1389
+ Variant.TokenizingCharacters =
1390
+ AsmVariant->getValueAsString (" TokenizingCharacters" );
1391
+ Variant.SeparatorCharacters =
1392
+ AsmVariant->getValueAsString (" SeparatorCharacters" );
1393
+ Variant.BreakCharacters =
1394
+ AsmVariant->getValueAsString (" BreakCharacters" );
1376
1395
int AsmVariantNo = AsmVariant->getValueAsInt (" Variant" );
1377
1396
1378
1397
for (const CodeGenInstruction *CGI : Target.instructions ()) {
@@ -1388,7 +1407,8 @@ void AsmMatcherInfo::buildInfo() {
1388
1407
1389
1408
auto II = llvm::make_unique<MatchableInfo>(*CGI);
1390
1409
1391
- II->initialize (*this , SingletonRegisters, AsmVariantNo, RegisterPrefix);
1410
+ II->initialize (*this , SingletonRegisters, AsmVariantNo, RegisterPrefix,
1411
+ Variant);
1392
1412
1393
1413
// Ignore instructions which shouldn't be matched and diagnose invalid
1394
1414
// instruction definitions with an error.
@@ -1415,7 +1435,8 @@ void AsmMatcherInfo::buildInfo() {
1415
1435
1416
1436
auto II = llvm::make_unique<MatchableInfo>(std::move (Alias));
1417
1437
1418
- II->initialize (*this , SingletonRegisters, AsmVariantNo, RegisterPrefix);
1438
+ II->initialize (*this , SingletonRegisters, AsmVariantNo, RegisterPrefix,
1439
+ Variant);
1419
1440
1420
1441
// Validate the alias definitions.
1421
1442
II->validate (CommentDelimiter, false );
0 commit comments