diff --git a/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp b/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp --- a/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp +++ b/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp @@ -12,6 +12,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" +#include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" @@ -428,6 +429,27 @@ bool parseOperand(OperandVector &Operands, StringRef Mnemonic); + // Both the hlasm and att variants still rely on the basic gnu asm + // format with respect to inputs, clobbers, outputs etc. + // + // However, calling the overriden getAssemblerDialect() method in + // AsmParser is problematic. It either returns the AssemblerDialect field + // in the MCAsmInfo instance if the AssemblerDialect field in AsmParser is + // unset, otherwise it returns the private AssemblerDialect field in + // AsmParser. + // + // The problematic part is because, we forcibly set the inline asm dialect + // in the AsmParser instance in AsmPrinterInlineAsm.cpp. Soo any query + // to the overriden getAssemblerDialect function in AsmParser.cpp, will + // not return the assembler dialect set in the respective MCAsmInfo instance. + // + // For this purpose, we explicitly query the SystemZMCAsmInfo instance + // here, to get the "correct" assembler dialect, and use it in various + // functions. + unsigned getMAIAssemblerDialect() { + return Parser.getContext().getAsmInfo()->getAssemblerDialect(); + } + public: SystemZAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser, const MCInstrInfo &MII, @@ -1325,7 +1347,7 @@ // Apply mnemonic aliases first, before doing anything else, in // case the target uses it. - applyMnemonicAliases(Name, getAvailableFeatures(), 0 /*VariantID*/); + applyMnemonicAliases(Name, getAvailableFeatures(), getMAIAssemblerDialect()); Operands.push_back(SystemZOperand::createToken(Name, NameLoc)); @@ -1428,9 +1450,11 @@ MCInst Inst; unsigned MatchResult; + unsigned Dialect = getMAIAssemblerDialect(); + FeatureBitset MissingFeatures; - MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo, - MissingFeatures, MatchingInlineAsm); + MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures, + MatchingInlineAsm, Dialect); switch (MatchResult) { case Match_Success: Inst.setLoc(IDLoc); @@ -1467,7 +1491,7 @@ case Match_MnemonicFail: { FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits()); std::string Suggestion = SystemZMnemonicSpellCheck( - ((SystemZOperand &)*Operands[0]).getToken(), FBS); + ((SystemZOperand &)*Operands[0]).getToken(), FBS, Dialect); return Error(IDLoc, "invalid instruction" + Suggestion, ((SystemZOperand &)*Operands[0]).getLocRange()); } diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.cpp --- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.cpp +++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.cpp @@ -12,11 +12,15 @@ using namespace llvm; +enum AsmDialect { AD_ATT = 0, AD_HLASM = 1 }; + SystemZMCAsmInfo::SystemZMCAsmInfo(const Triple &TT) { CodePointerSize = 8; CalleeSaveStackSlotSize = 8; IsLittleEndian = false; + AssemblerDialect = TT.isOSzOS() ? AD_HLASM : AD_ATT; + MaxInstLength = 6; CommentString = "#"; diff --git a/llvm/lib/Target/SystemZ/SystemZ.td b/llvm/lib/Target/SystemZ/SystemZ.td --- a/llvm/lib/Target/SystemZ/SystemZ.td +++ b/llvm/lib/Target/SystemZ/SystemZ.td @@ -67,6 +67,20 @@ let ShouldEmitMatchRegisterName = 0; } +def ATTAsmParserVariant : AsmParserVariant { + int Variant = 0; + + // Variant name. + string Name = "att"; +} + +def HLASMAsmParserVariant : AsmParserVariant { + int Variant = 1; + + // Variant name. + string Name = "hlasm"; +} + //===----------------------------------------------------------------------===// // Top-level target declaration //===----------------------------------------------------------------------===// @@ -74,5 +88,6 @@ def SystemZ : Target { let InstructionSet = SystemZInstrInfo; let AssemblyParsers = [SystemZAsmParser]; + let AssemblyParserVariants = [ATTAsmParserVariant, HLASMAsmParserVariant]; let AllowRegisterRenaming = 1; } diff --git a/llvm/lib/Target/SystemZ/SystemZInstrFormats.td b/llvm/lib/Target/SystemZ/SystemZInstrFormats.td --- a/llvm/lib/Target/SystemZ/SystemZInstrFormats.td +++ b/llvm/lib/Target/SystemZ/SystemZInstrFormats.td @@ -1845,7 +1845,8 @@ //===----------------------------------------------------------------------===// // A class to describe a variant of an instruction with condition mask. -class CondVariant ccmaskin, string suffixin, bit alternatein> { +class CondVariant ccmaskin, string suffixin, bit alternatein, + string asmvariantin = ""> { // The fixed condition mask to use. bits<4> ccmask = ccmaskin; @@ -1854,6 +1855,11 @@ // Whether this is an alternate that needs to be marked isAsmParserOnly. bit alternate = alternatein; + + // Whether this needs be to restricted to a specific dialect. + // Valid values are "att" and "hlasm", which when passed in + // will set AsmVariantName. + string asmvariant = asmvariantin; } // Condition mask 15 means "always true", which is used to define @@ -1864,20 +1870,20 @@ def CondVariantO : CondVariant<1, "o", 0>; def CondVariantH : CondVariant<2, "h", 0>; def CondVariantP : CondVariant<2, "p", 1>; -def CondVariantNLE : CondVariant<3, "nle", 0>; +def CondVariantNLE : CondVariant<3, "nle", 0, "att">; def CondVariantL : CondVariant<4, "l", 0>; def CondVariantM : CondVariant<4, "m", 1>; -def CondVariantNHE : CondVariant<5, "nhe", 0>; -def CondVariantLH : CondVariant<6, "lh", 0>; +def CondVariantNHE : CondVariant<5, "nhe", 0, "att">; +def CondVariantLH : CondVariant<6, "lh", 0, "att">; def CondVariantNE : CondVariant<7, "ne", 0>; def CondVariantNZ : CondVariant<7, "nz", 1>; def CondVariantE : CondVariant<8, "e", 0>; def CondVariantZ : CondVariant<8, "z", 1>; -def CondVariantNLH : CondVariant<9, "nlh", 0>; -def CondVariantHE : CondVariant<10, "he", 0>; +def CondVariantNLH : CondVariant<9, "nlh", 0, "att">; +def CondVariantHE : CondVariant<10, "he", 0, "att">; def CondVariantNL : CondVariant<11, "nl", 0>; def CondVariantNM : CondVariant<11, "nm", 1>; -def CondVariantLE : CondVariant<12, "le", 0>; +def CondVariantLE : CondVariant<12, "le", 0, "att">; def CondVariantNH : CondVariant<13, "nh", 0>; def CondVariantNP : CondVariant<13, "np", 1>; def CondVariantNO : CondVariant<14, "no", 0>; @@ -1886,35 +1892,38 @@ class CV : CondVariant("CondVariant"#name).ccmask, !cast("CondVariant"#name).suffix, - !cast("CondVariant"#name).alternate>; + !cast("CondVariant"#name).alternate, + !cast("CondVariant"#name).asmvariant>; // Condition masks for integer instructions (e.g. compare-and-branch). // This is like the list above, except that condition 3 is not possible // and that the low bit of the mask is therefore always 0. This means // that each condition has two names. Conditions "o" and "no" are not used. def IntCondVariantH : CondVariant<2, "h", 0>; -def IntCondVariantNLE : CondVariant<2, "nle", 1>; +def IntCondVariantNLE : CondVariant<2, "nle", 1, "att">; def IntCondVariantL : CondVariant<4, "l", 0>; -def IntCondVariantNHE : CondVariant<4, "nhe", 1>; -def IntCondVariantLH : CondVariant<6, "lh", 0>; +def IntCondVariantNHE : CondVariant<4, "nhe", 1, "att">; +def IntCondVariantLH : CondVariant<6, "lh", 0, "att">; def IntCondVariantNE : CondVariant<6, "ne", 1>; def IntCondVariantE : CondVariant<8, "e", 0>; -def IntCondVariantNLH : CondVariant<8, "nlh", 1>; -def IntCondVariantHE : CondVariant<10, "he", 0>; +def IntCondVariantNLH : CondVariant<8, "nlh", 1, "att">; +def IntCondVariantHE : CondVariant<10, "he", 0, "att">; def IntCondVariantNL : CondVariant<10, "nl", 1>; -def IntCondVariantLE : CondVariant<12, "le", 0>; +def IntCondVariantLE : CondVariant<12, "le", 0, "att">; def IntCondVariantNH : CondVariant<12, "nh", 1>; // A helper class to look up one of the above by name. class ICV : CondVariant("IntCondVariant"#name).ccmask, !cast("IntCondVariant"#name).suffix, - !cast("IntCondVariant"#name).alternate>; + !cast("IntCondVariant"#name).alternate, + !cast("IntCondVariant"#name).asmvariant>; // Defines a class that makes it easier to define // a MnemonicAlias when CondVariant's are involved. class MnemonicCondBranchAlias - : MnemonicAlias; + : MnemonicAlias; //===----------------------------------------------------------------------===// // Instruction definitions with semantics @@ -2125,6 +2134,7 @@ : InstRIc { let isAsmParserOnly = V.alternate; + let AsmVariantName = V.asmvariant; let M1 = V.ccmask; } @@ -2142,6 +2152,7 @@ : InstRILc { let isAsmParserOnly = V.alternate; + let AsmVariantName = V.asmvariant; let M1 = V.ccmask; } @@ -2160,6 +2171,7 @@ : InstRR { let isAsmParserOnly = V.alternate; + let AsmVariantName = V.asmvariant; let R1 = V.ccmask; } @@ -2177,6 +2189,7 @@ : InstRXb { let isAsmParserOnly = V.alternate; + let AsmVariantName = V.asmvariant; let M1 = V.ccmask; } @@ -2199,6 +2212,7 @@ !subst("#", V.suffix, mnemonic)#"\t$XBD2", [(operator (load bdxaddr20only:$XBD2))]> { let isAsmParserOnly = V.alternate; + let AsmVariantName = V.asmvariant; let M1 = V.ccmask; let mayLoad = 1; } @@ -2218,6 +2232,7 @@ : InstRIEa { let isAsmParserOnly = V.alternate; + let AsmVariantName = V.asmvariant; let M3 = V.ccmask; } @@ -2245,6 +2260,7 @@ : InstRIEb { let isAsmParserOnly = V.alternate; + let AsmVariantName = V.asmvariant; let M3 = V.ccmask; } @@ -2272,6 +2288,7 @@ : InstRIEc { let isAsmParserOnly = V.alternate; + let AsmVariantName = V.asmvariant; let M3 = V.ccmask; } @@ -2304,6 +2321,7 @@ : InstRRFc { let isAsmParserOnly = V.alternate; + let AsmVariantName = V.asmvariant; let M3 = V.ccmask; } @@ -2324,6 +2342,7 @@ : InstRRS { let isAsmParserOnly = V.alternate; + let AsmVariantName = V.asmvariant; let M3 = V.ccmask; } @@ -2351,6 +2370,7 @@ : InstRIS { let isAsmParserOnly = V.alternate; + let AsmVariantName = V.asmvariant; let M3 = V.ccmask; } @@ -2383,6 +2403,7 @@ : InstRSYb { let isAsmParserOnly = V.alternate; + let AsmVariantName = V.asmvariant; let M3 = V.ccmask; } @@ -2717,6 +2738,7 @@ let mayStore = 1; let AccessBytes = bytes; let isAsmParserOnly = V.alternate; + let AsmVariantName = V.asmvariant; let M3 = V.ccmask; } @@ -2891,6 +2913,7 @@ let mayLoad = 1; let AccessBytes = bytes; let isAsmParserOnly = V.alternate; + let AsmVariantName = V.asmvariant; let M3 = V.ccmask; } @@ -3294,6 +3317,7 @@ let Constraints = "$R1 = $R1src"; let DisableEncoding = "$R1src"; let isAsmParserOnly = V.alternate; + let AsmVariantName = V.asmvariant; let M3 = V.ccmask; } @@ -3332,6 +3356,7 @@ : InstRRFa { let isAsmParserOnly = V.alternate; + let AsmVariantName = V.asmvariant; let M4 = V.ccmask; } @@ -3401,6 +3426,7 @@ let Constraints = "$R1 = $R1src"; let DisableEncoding = "$R1src"; let isAsmParserOnly = V.alternate; + let AsmVariantName = V.asmvariant; let M3 = V.ccmask; }