[llvm] bcc1aba - [SystemZ] Introducing assembler dialects for the Z backend

Kai Nacke via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 26 12:14:57 PST 2021


Author: Anirudh Prasad
Date: 2021-02-26T15:14:38-05:00
New Revision: bcc1aba6c4ee657840a306eadafa371cecd6a957

URL: https://github.com/llvm/llvm-project/commit/bcc1aba6c4ee657840a306eadafa371cecd6a957
DIFF: https://github.com/llvm/llvm-project/commit/bcc1aba6c4ee657840a306eadafa371cecd6a957.diff

LOG: [SystemZ] Introducing assembler dialects for the Z backend

- This patch introduces a different assembler dialect ("hlasm") for z/OS.
  The default dialect has now been given the "att" dialect name. For this
  appropriate changes have been added to SystemZ.td.
- This patch also makes a few changes to SystemZInstrFormats.td which
  restrict a few condition code mnemonics to just the "att" dialect
  variant (he, le, lh, nhe, nle, nlh). These extended condition code
  mnemonics are not available in HLASM.
- A new private function has been introduced in SystemZAsmParser.cpp to
  return the assembler dialect set in SystemZMCAsmInfo.cpp. The reason we
  couldn't/haven't explicitly queried the overriden getAssemblerDialect
  function from AsmParser is outlined in this thread here. This returned
  dialect is directly passed onto the relevant matcher functions which taken
  in a variantID, so that the matcher functions can appropriately choose an
  instruction based on the variant.

Reviewed By: uweigand

Differential Revision: https://reviews.llvm.org/D94250

Added: 
    

Modified: 
    llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
    llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.cpp
    llvm/lib/Target/SystemZ/SystemZ.td
    llvm/lib/Target/SystemZ/SystemZInstrFormats.td

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp b/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
index 2b815a366ccd..92a35e22007e 100644
--- 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 @@ class SystemZAsmParser : public MCTargetAsmParser {
 
   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 @@ bool SystemZAsmParser::ParseInstruction(ParseInstructionInfo &Info,
 
   // 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 @@ bool SystemZAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
   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 @@ bool SystemZAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
   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
index 76df8cf0f3b2..d0330b9cf40f 100644
--- 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
index ebbc6ffd2f1e..e18deede544a 100644
--- a/llvm/lib/Target/SystemZ/SystemZ.td
+++ b/llvm/lib/Target/SystemZ/SystemZ.td
@@ -67,6 +67,20 @@ def SystemZAsmParser : AsmParser {
   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 SystemZAsmParser : AsmParser {
 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
index 95e94c4c8e1c..a1b65b159eb1 100644
--- a/llvm/lib/Target/SystemZ/SystemZInstrFormats.td
+++ b/llvm/lib/Target/SystemZ/SystemZInstrFormats.td
@@ -1845,7 +1845,8 @@ class DirectiveInsnVSI<dag outs, dag ins, string asmstr, list<dag> pattern>
 //===----------------------------------------------------------------------===//
 
 // A class to describe a variant of an instruction with condition mask.
-class CondVariant<bits<4> ccmaskin, string suffixin, bit alternatein> {
+class CondVariant<bits<4> ccmaskin, string suffixin, bit alternatein,
+                  string asmvariantin = ""> {
   // The fixed condition mask to use.
   bits<4> ccmask = ccmaskin;
 
@@ -1854,6 +1855,11 @@ class CondVariant<bits<4> ccmaskin, string suffixin, bit alternatein> {
 
   // 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 CondAlways : CondVariant<15, "", 0>;
 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 @@ def CondVariantNO  : CondVariant<14, "no",  0>;
 class CV<string name>
   : CondVariant<!cast<CondVariant>("CondVariant"#name).ccmask,
                 !cast<CondVariant>("CondVariant"#name).suffix,
-                !cast<CondVariant>("CondVariant"#name).alternate>;
+                !cast<CondVariant>("CondVariant"#name).alternate,
+                !cast<CondVariant>("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<string name>
   : CondVariant<!cast<CondVariant>("IntCondVariant"#name).ccmask,
                 !cast<CondVariant>("IntCondVariant"#name).suffix,
-                !cast<CondVariant>("IntCondVariant"#name).alternate>;
+                !cast<CondVariant>("IntCondVariant"#name).alternate,
+                !cast<CondVariant>("IntCondVariant"#name).asmvariant>;
 
 // Defines a class that makes it easier to define
 // a MnemonicAlias when CondVariant's are involved.
 class MnemonicCondBranchAlias<CondVariant V, string from, string to>
-  : MnemonicAlias<!subst("#", V.suffix, from), !subst("#", V.suffix, to)>;
+  : MnemonicAlias<!subst("#", V.suffix, from), !subst("#", V.suffix, to),
+                  V.asmvariant>;
 
 //===----------------------------------------------------------------------===//
 // Instruction definitions with semantics
@@ -2125,6 +2134,7 @@ class FixedCondBranchRI<CondVariant V, string mnemonic, bits<12> opcode,
   : InstRIc<opcode, (outs), (ins brtarget16:$RI2),
             !subst("#", V.suffix, mnemonic)#"\t$RI2", [(operator bb:$RI2)]> {
   let isAsmParserOnly = V.alternate;
+  let AsmVariantName = V.asmvariant;
   let M1 = V.ccmask;
 }
 
@@ -2142,6 +2152,7 @@ class FixedCondBranchRIL<CondVariant V, string mnemonic, bits<12> opcode>
   : InstRILc<opcode, (outs), (ins brtarget32:$RI2),
              !subst("#", V.suffix, mnemonic)#"\t$RI2", []> {
   let isAsmParserOnly = V.alternate;
+  let AsmVariantName = V.asmvariant;
   let M1 = V.ccmask;
 }
 
@@ -2160,6 +2171,7 @@ class FixedCondBranchRR<CondVariant V, string mnemonic, bits<8> opcode,
   : InstRR<opcode, (outs), (ins ADDR64:$R2),
            !subst("#", V.suffix, mnemonic)#"\t$R2", [(operator ADDR64:$R2)]> {
   let isAsmParserOnly = V.alternate;
+  let AsmVariantName = V.asmvariant;
   let R1 = V.ccmask;
 }
 
@@ -2177,6 +2189,7 @@ class FixedCondBranchRX<CondVariant V, string mnemonic, bits<8> opcode>
   : InstRXb<opcode, (outs), (ins bdxaddr12only:$XBD2),
             !subst("#", V.suffix, mnemonic)#"\t$XBD2", []> {
   let isAsmParserOnly = V.alternate;
+  let AsmVariantName = V.asmvariant;
   let M1 = V.ccmask;
 }
 
@@ -2199,6 +2212,7 @@ class FixedCondBranchRXY<CondVariant V, string mnemonic, bits<16> opcode,
              !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 @@ class FixedCmpBranchRIEa<CondVariant V, string mnemonic, bits<16> opcode,
   : InstRIEa<opcode, (outs), (ins cls:$R1, imm:$I2),
              mnemonic#V.suffix#"\t$R1, $I2", []> {
   let isAsmParserOnly = V.alternate;
+  let AsmVariantName = V.asmvariant;
   let M3 = V.ccmask;
 }
 
@@ -2245,6 +2260,7 @@ class FixedCmpBranchRIEb<CondVariant V, string mnemonic, bits<16> opcode,
   : InstRIEb<opcode, (outs), (ins cls:$R1, cls:$R2, brtarget16:$RI4),
              mnemonic#V.suffix#"\t$R1, $R2, $RI4", []> {
   let isAsmParserOnly = V.alternate;
+  let AsmVariantName = V.asmvariant;
   let M3 = V.ccmask;
 }
 
@@ -2272,6 +2288,7 @@ class FixedCmpBranchRIEc<CondVariant V, string mnemonic, bits<16> opcode,
   : InstRIEc<opcode, (outs), (ins cls:$R1, imm:$I2, brtarget16:$RI4),
              mnemonic#V.suffix#"\t$R1, $I2, $RI4", []> {
   let isAsmParserOnly = V.alternate;
+  let AsmVariantName = V.asmvariant;
   let M3 = V.ccmask;
 }
 
@@ -2304,6 +2321,7 @@ class FixedCmpBranchRRFc<CondVariant V, string mnemonic, bits<16> opcode,
   : InstRRFc<opcode, (outs), (ins cls:$R1, cls:$R2),
              mnemonic#V.suffix#"\t$R1, $R2", []> {
   let isAsmParserOnly = V.alternate;
+  let AsmVariantName = V.asmvariant;
   let M3 = V.ccmask;
 }
 
@@ -2324,6 +2342,7 @@ class FixedCmpBranchRRS<CondVariant V, string mnemonic, bits<16> opcode,
   : InstRRS<opcode, (outs), (ins cls:$R1, cls:$R2, bdaddr12only:$BD4),
             mnemonic#V.suffix#"\t$R1, $R2, $BD4", []> {
   let isAsmParserOnly = V.alternate;
+  let AsmVariantName = V.asmvariant;
   let M3 = V.ccmask;
 }
 
@@ -2351,6 +2370,7 @@ class FixedCmpBranchRIS<CondVariant V, string mnemonic, bits<16> opcode,
   : InstRIS<opcode, (outs), (ins cls:$R1, imm:$I2, bdaddr12only:$BD4),
             mnemonic#V.suffix#"\t$R1, $I2, $BD4", []> {
   let isAsmParserOnly = V.alternate;
+  let AsmVariantName = V.asmvariant;
   let M3 = V.ccmask;
 }
 
@@ -2383,6 +2403,7 @@ class FixedCmpBranchRSYb<CondVariant V, string mnemonic, bits<16> opcode,
   : InstRSYb<opcode, (outs), (ins cls:$R1, bdaddr20only:$BD2),
              mnemonic#V.suffix#"\t$R1, $BD2", []> {
   let isAsmParserOnly = V.alternate;
+  let AsmVariantName = V.asmvariant;
   let M3 = V.ccmask;
 }
 
@@ -2717,6 +2738,7 @@ class FixedCondStoreRSY<CondVariant V, string mnemonic, bits<16> opcode,
   let mayStore = 1;
   let AccessBytes = bytes;
   let isAsmParserOnly = V.alternate;
+  let AsmVariantName = V.asmvariant;
   let M3 = V.ccmask;
 }
 
@@ -2891,6 +2913,7 @@ class FixedCondUnaryRSY<CondVariant V, string mnemonic, bits<16> opcode,
   let mayLoad = 1;
   let AccessBytes = bytes;
   let isAsmParserOnly = V.alternate;
+  let AsmVariantName = V.asmvariant;
   let M3 = V.ccmask;
 }
 
@@ -3294,6 +3317,7 @@ class FixedCondBinaryRRF<CondVariant V, string mnemonic, bits<16> opcode,
   let Constraints = "$R1 = $R1src";
   let DisableEncoding = "$R1src";
   let isAsmParserOnly = V.alternate;
+  let AsmVariantName = V.asmvariant;
   let M3 = V.ccmask;
 }
 
@@ -3332,6 +3356,7 @@ class FixedCondBinaryRRFa<CondVariant V, string mnemonic, bits<16> opcode,
   : InstRRFa<opcode, (outs cls1:$R1), (ins cls3:$R3, cls2:$R2),
              mnemonic#V.suffix#"\t$R1, $R2, $R3", []> {
   let isAsmParserOnly = V.alternate;
+  let AsmVariantName = V.asmvariant;
   let M4 = V.ccmask;
 }
 
@@ -3401,6 +3426,7 @@ class FixedCondBinaryRIE<CondVariant V, string mnemonic, bits<16> opcode,
   let Constraints = "$R1 = $R1src";
   let DisableEncoding = "$R1src";
   let isAsmParserOnly = V.alternate;
+  let AsmVariantName = V.asmvariant;
   let M3 = V.ccmask;
 }
 


        


More information about the llvm-commits mailing list