@@ -2662,13 +2662,59 @@ std::string getArchSupplInfoPPC(StringRef const &TargetName,
2662
2662
return " {{ 0 }}" ;
2663
2663
}
2664
2664
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
+
2665
2709
std::string getArchSupplInfo (StringRef const &TargetName,
2666
2710
CodeGenInstruction const *CGI,
2667
- raw_string_ostream &PPCFormatEnum ) {
2711
+ raw_string_ostream &FormatEnum ) {
2668
2712
if (TargetName == " PPC" )
2669
- return getArchSupplInfoPPC (TargetName, CGI, PPCFormatEnum );
2713
+ return getArchSupplInfoPPC (TargetName, CGI, FormatEnum );
2670
2714
else if (TargetName == " AArch64" ) {
2671
2715
return getArchSupplInfoAArch64 (CGI);
2716
+ } else if (TargetName == " LoongArch" ) {
2717
+ return getArchSupplInfoLoongArch (TargetName, CGI, FormatEnum);
2672
2718
}
2673
2719
return " {{ 0 }}" ;
2674
2720
}
@@ -2929,7 +2975,7 @@ void printInsnMapEntry(StringRef const &TargetName, AsmMatcherInfo &AMI,
2929
2975
std::unique_ptr<MatchableInfo> const &MI, bool UseMI,
2930
2976
CodeGenInstruction const *CGI,
2931
2977
raw_string_ostream &InsnMap, unsigned InsnNum,
2932
- raw_string_ostream &PPCFormatEnum ) {
2978
+ raw_string_ostream &FormatEnum ) {
2933
2979
InsnMap << " {\n " ;
2934
2980
InsnMap.indent (2 ) << " /* "
2935
2981
<< (CGI->AsmString != " " ? CGI->AsmString
@@ -2948,7 +2994,7 @@ void printInsnMapEntry(StringRef const &TargetName, AsmMatcherInfo &AMI,
2948
2994
InsnMap << getReqFeatures (TargetName, AMI, MI, UseMI, CGI) << " , " ;
2949
2995
InsnMap << ((CGI->isBranch || CGI->isReturn ) ? " 1" : " 0" ) << " , " ;
2950
2996
InsnMap << (CGI->isIndirectBranch ? " 1" : " 0" ) << " , " ;
2951
- InsnMap << getArchSupplInfo (TargetName, CGI, PPCFormatEnum ) << " \n " ;
2997
+ InsnMap << getArchSupplInfo (TargetName, CGI, FormatEnum ) << " \n " ;
2952
2998
} else {
2953
2999
InsnMap.indent (4 ) << " { 0 }, { 0 }, { 0 }, 0, 0, {{ 0 }}" ;
2954
3000
}
@@ -3383,7 +3429,7 @@ void PrinterCapstone::asmMatcherEmitMatchTable(CodeGenTarget const &Target,
3383
3429
std::string FeatureEnumStr;
3384
3430
std::string FeatureNameArrayStr;
3385
3431
std::string OpGroupStr;
3386
- std::string PPCFormatEnumStr ;
3432
+ std::string FormatEnumStr ;
3387
3433
std::string AliasEnumStr;
3388
3434
std::string AliasMnemMapStr;
3389
3435
raw_string_ostream InsnMap (InsnMapStr);
@@ -3393,7 +3439,7 @@ void PrinterCapstone::asmMatcherEmitMatchTable(CodeGenTarget const &Target,
3393
3439
raw_string_ostream FeatureEnum (FeatureEnumStr);
3394
3440
raw_string_ostream FeatureNameArray (FeatureNameArrayStr);
3395
3441
raw_string_ostream OpGroups (OpGroupStr);
3396
- raw_string_ostream PPCFormatEnum (PPCFormatEnumStr );
3442
+ raw_string_ostream FormatEnum (FormatEnumStr );
3397
3443
raw_string_ostream AliasEnum (AliasEnumStr);
3398
3444
raw_string_ostream AliasMnemMap (AliasMnemMapStr);
3399
3445
emitDefaultSourceFileHeader (InsnMap);
@@ -3403,7 +3449,7 @@ void PrinterCapstone::asmMatcherEmitMatchTable(CodeGenTarget const &Target,
3403
3449
emitDefaultSourceFileHeader (FeatureEnum);
3404
3450
emitDefaultSourceFileHeader (FeatureNameArray);
3405
3451
emitDefaultSourceFileHeader (OpGroups);
3406
- emitDefaultSourceFileHeader (PPCFormatEnum );
3452
+ emitDefaultSourceFileHeader (FormatEnum );
3407
3453
emitDefaultSourceFileHeader (AliasEnum);
3408
3454
emitDefaultSourceFileHeader (AliasMnemMap);
3409
3455
@@ -3453,7 +3499,7 @@ void PrinterCapstone::asmMatcherEmitMatchTable(CodeGenTarget const &Target,
3453
3499
printInsnOpMapEntry (Target, MI, UseMI, CGI, InsnOpMap, InsnNum,
3454
3500
InsnPatternMap);
3455
3501
printInsnMapEntry (Target.getName (), Info, MI, UseMI, CGI, InsnMap, InsnNum,
3456
- PPCFormatEnum );
3502
+ FormatEnum );
3457
3503
3458
3504
++InsnNum;
3459
3505
}
@@ -3478,9 +3524,9 @@ void PrinterCapstone::asmMatcherEmitMatchTable(CodeGenTarget const &Target,
3478
3524
writeFile (InsnMapFilename, AliasEnumStr);
3479
3525
InsnMapFilename = TName + " GenCSAliasMnemMap.inc" ;
3480
3526
writeFile (InsnMapFilename, AliasMnemMapStr);
3481
- if (TName == " PPC" ) {
3482
- InsnMapFilename = " PPCGenCSInsnFormatsEnum .inc" ;
3483
- writeFile (InsnMapFilename, PPCFormatEnumStr );
3527
+ if (TName == " PPC" || TName == " LoongArch " ) {
3528
+ InsnMapFilename = TName + " GenCSInsnFormatsEnum .inc" ;
3529
+ writeFile (InsnMapFilename, FormatEnumStr );
3484
3530
}
3485
3531
}
3486
3532
0 commit comments