@@ -2662,13 +2662,59 @@ std::string getArchSupplInfoPPC(StringRef const &TargetName,
26622662 return " {{ 0 }}" ;
26632663}
26642664
2665+ std::string getArchSupplInfoLoongArch (StringRef const &TargetName,
2666+ CodeGenInstruction const *CGI,
2667+ raw_string_ostream &LoongArchFormatEnum) {
2668+ static std::set<std::string> Formats;
2669+ // Get instruction format
2670+ ArrayRef<std::pair<Record *, SMRange>> SCs = CGI->TheDef ->getSuperClasses ();
2671+ if (SCs.empty ()) {
2672+ llvm_unreachable (" A CGI without superclass should not exist." );
2673+ }
2674+
2675+ // Compute memory access type
2676+ std::string MemoryAccess;
2677+ if (CGI->mayLoad && CGI->mayStore ) {
2678+ MemoryAccess = " CS_AC_READ_WRTE" ;
2679+ } else if (CGI->mayLoad && !CGI->mayStore ) {
2680+ MemoryAccess = " CS_AC_READ" ;
2681+ } else if (!CGI->mayLoad && CGI->mayStore ) {
2682+ MemoryAccess = " CS_AC_WRITE" ;
2683+ } else {
2684+ MemoryAccess = " CS_AC_INVALID" ;
2685+ }
2686+
2687+ // Get base instruction format class "LAInst"
2688+ const Record *PrevSC = nullptr ;
2689+ // Superclasses are in post-order. So we go through them backwards.
2690+ // The class before the "LAInst" class is the format class.
2691+ for (int I = SCs.size () - 1 ; I >= 0 ; --I) {
2692+ const Record *SC = SCs[I].first ;
2693+ if (SC->getName () == " LAInst" ) {
2694+ if (!PrevSC)
2695+ llvm_unreachable (" I class has no predecessor." );
2696+ std::string Format = " LoongArch_INSN_FORM_" + PrevSC->getName ().upper ();
2697+ if (Formats.find (Format) == Formats.end ()) {
2698+ LoongArchFormatEnum << Format + " ,\n " ;
2699+ }
2700+ Formats.emplace (Format);
2701+ return " { .loongarch = { " + Format + " , " + MemoryAccess + " }}" ;
2702+ }
2703+ PrevSC = SC;
2704+ }
2705+ // Pseudo instructions
2706+ return " { .loongarch = { 0, " + MemoryAccess + " }}" ;
2707+ }
2708+
26652709std::string getArchSupplInfo (StringRef const &TargetName,
26662710 CodeGenInstruction const *CGI,
2667- raw_string_ostream &PPCFormatEnum ) {
2711+ raw_string_ostream &FormatEnum ) {
26682712 if (TargetName == " PPC" )
2669- return getArchSupplInfoPPC (TargetName, CGI, PPCFormatEnum );
2713+ return getArchSupplInfoPPC (TargetName, CGI, FormatEnum );
26702714 else if (TargetName == " AArch64" ) {
26712715 return getArchSupplInfoAArch64 (CGI);
2716+ } else if (TargetName == " LoongArch" ) {
2717+ return getArchSupplInfoLoongArch (TargetName, CGI, FormatEnum);
26722718 }
26732719 return " {{ 0 }}" ;
26742720}
@@ -2936,7 +2982,7 @@ void printInsnMapEntry(StringRef const &TargetName, AsmMatcherInfo &AMI,
29362982 std::unique_ptr<MatchableInfo> const &MI, bool UseMI,
29372983 CodeGenInstruction const *CGI,
29382984 raw_string_ostream &InsnMap, unsigned InsnNum,
2939- raw_string_ostream &PPCFormatEnum ) {
2985+ raw_string_ostream &FormatEnum ) {
29402986 InsnMap << " {\n " ;
29412987 InsnMap.indent (2 ) << " /* "
29422988 << (CGI->AsmString != " " ? CGI->AsmString
@@ -2955,7 +3001,7 @@ void printInsnMapEntry(StringRef const &TargetName, AsmMatcherInfo &AMI,
29553001 InsnMap << getReqFeatures (TargetName, AMI, MI, UseMI, CGI) << " , " ;
29563002 InsnMap << ((CGI->isBranch || CGI->isReturn ) ? " 1" : " 0" ) << " , " ;
29573003 InsnMap << (CGI->isIndirectBranch ? " 1" : " 0" ) << " , " ;
2958- InsnMap << getArchSupplInfo (TargetName, CGI, PPCFormatEnum ) << " \n " ;
3004+ InsnMap << getArchSupplInfo (TargetName, CGI, FormatEnum ) << " \n " ;
29593005 } else {
29603006 InsnMap.indent (4 ) << " { 0 }, { 0 }, { 0 }, 0, 0, {{ 0 }}" ;
29613007 }
@@ -3390,7 +3436,7 @@ void PrinterCapstone::asmMatcherEmitMatchTable(CodeGenTarget const &Target,
33903436 std::string FeatureEnumStr;
33913437 std::string FeatureNameArrayStr;
33923438 std::string OpGroupStr;
3393- std::string PPCFormatEnumStr ;
3439+ std::string FormatEnumStr ;
33943440 std::string AliasEnumStr;
33953441 std::string AliasMnemMapStr;
33963442 raw_string_ostream InsnMap (InsnMapStr);
@@ -3400,7 +3446,7 @@ void PrinterCapstone::asmMatcherEmitMatchTable(CodeGenTarget const &Target,
34003446 raw_string_ostream FeatureEnum (FeatureEnumStr);
34013447 raw_string_ostream FeatureNameArray (FeatureNameArrayStr);
34023448 raw_string_ostream OpGroups (OpGroupStr);
3403- raw_string_ostream PPCFormatEnum (PPCFormatEnumStr );
3449+ raw_string_ostream FormatEnum (FormatEnumStr );
34043450 raw_string_ostream AliasEnum (AliasEnumStr);
34053451 raw_string_ostream AliasMnemMap (AliasMnemMapStr);
34063452 emitDefaultSourceFileHeader (InsnMap);
@@ -3410,7 +3456,7 @@ void PrinterCapstone::asmMatcherEmitMatchTable(CodeGenTarget const &Target,
34103456 emitDefaultSourceFileHeader (FeatureEnum);
34113457 emitDefaultSourceFileHeader (FeatureNameArray);
34123458 emitDefaultSourceFileHeader (OpGroups);
3413- emitDefaultSourceFileHeader (PPCFormatEnum );
3459+ emitDefaultSourceFileHeader (FormatEnum );
34143460 emitDefaultSourceFileHeader (AliasEnum);
34153461 emitDefaultSourceFileHeader (AliasMnemMap);
34163462
@@ -3460,7 +3506,7 @@ void PrinterCapstone::asmMatcherEmitMatchTable(CodeGenTarget const &Target,
34603506 printInsnOpMapEntry (Target, MI, UseMI, CGI, InsnOpMap, InsnNum,
34613507 InsnPatternMap);
34623508 printInsnMapEntry (Target.getName (), Info, MI, UseMI, CGI, InsnMap, InsnNum,
3463- PPCFormatEnum );
3509+ FormatEnum );
34643510
34653511 ++InsnNum;
34663512 }
@@ -3485,9 +3531,9 @@ void PrinterCapstone::asmMatcherEmitMatchTable(CodeGenTarget const &Target,
34853531 writeFile (InsnMapFilename, AliasEnumStr);
34863532 InsnMapFilename = TName + " GenCSAliasMnemMap.inc" ;
34873533 writeFile (InsnMapFilename, AliasMnemMapStr);
3488- if (TName == " PPC" ) {
3489- InsnMapFilename = " PPCGenCSInsnFormatsEnum .inc" ;
3490- writeFile (InsnMapFilename, PPCFormatEnumStr );
3534+ if (TName == " PPC" || TName == " LoongArch " ) {
3535+ InsnMapFilename = TName + " GenCSInsnFormatsEnum .inc" ;
3536+ writeFile (InsnMapFilename, FormatEnumStr );
34913537 }
34923538}
34933539
0 commit comments