brintos

brintos / llvm-project-archived public Read only

0
0
Text · 60.9 KiB · 4efb305 Raw
1779 lines · cpp
1//===-- SystemZAsmParser.cpp - Parse SystemZ assembly instructions --------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "MCTargetDesc/SystemZGNUInstPrinter.h"10#include "MCTargetDesc/SystemZMCAsmInfo.h"11#include "MCTargetDesc/SystemZMCTargetDesc.h"12#include "MCTargetDesc/SystemZTargetStreamer.h"13#include "TargetInfo/SystemZTargetInfo.h"14#include "llvm/ADT/STLExtras.h"15#include "llvm/ADT/SmallVector.h"16#include "llvm/ADT/StringExtras.h"17#include "llvm/ADT/StringRef.h"18#include "llvm/MC/MCAsmInfo.h"19#include "llvm/MC/MCContext.h"20#include "llvm/MC/MCExpr.h"21#include "llvm/MC/MCInst.h"22#include "llvm/MC/MCInstBuilder.h"23#include "llvm/MC/MCInstrInfo.h"24#include "llvm/MC/MCParser/AsmLexer.h"25#include "llvm/MC/MCParser/MCAsmParser.h"26#include "llvm/MC/MCParser/MCAsmParserExtension.h"27#include "llvm/MC/MCParser/MCParsedAsmOperand.h"28#include "llvm/MC/MCParser/MCTargetAsmParser.h"29#include "llvm/MC/MCStreamer.h"30#include "llvm/MC/MCSubtargetInfo.h"31#include "llvm/MC/TargetRegistry.h"32#include "llvm/Support/Casting.h"33#include "llvm/Support/Compiler.h"34#include "llvm/Support/ErrorHandling.h"35#include "llvm/Support/SMLoc.h"36#include "llvm/TargetParser/SubtargetFeature.h"37#include <algorithm>38#include <cassert>39#include <cstddef>40#include <cstdint>41#include <iterator>42#include <memory>43#include <string>44 45using namespace llvm;46 47// Return true if Expr is in the range [MinValue, MaxValue]. If AllowSymbol48// is true any MCExpr is accepted (address displacement).49static bool inRange(const MCExpr *Expr, int64_t MinValue, int64_t MaxValue,50                    bool AllowSymbol = false) {51  if (auto *CE = dyn_cast<MCConstantExpr>(Expr)) {52    int64_t Value = CE->getValue();53    return Value >= MinValue && Value <= MaxValue;54  }55  return AllowSymbol;56}57 58namespace {59 60enum RegisterKind {61  GR32Reg,62  GRH32Reg,63  GR64Reg,64  GR128Reg,65  FP16Reg,66  FP32Reg,67  FP64Reg,68  FP128Reg,69  VR16Reg,70  VR32Reg,71  VR64Reg,72  VR128Reg,73  AR32Reg,74  CR64Reg,75};76 77enum MemoryKind {78  BDMem,79  BDXMem,80  BDLMem,81  BDRMem,82  BDVMem,83  LXAMem84};85 86class SystemZOperand : public MCParsedAsmOperand {87private:88  enum OperandKind {89    KindInvalid,90    KindToken,91    KindReg,92    KindImm,93    KindImmTLS,94    KindMem95  };96 97  OperandKind Kind;98  SMLoc StartLoc, EndLoc;99 100  // A string of length Length, starting at Data.101  struct TokenOp {102    const char *Data;103    unsigned Length;104  };105 106  // LLVM register Num, which has kind Kind.  In some ways it might be107  // easier for this class to have a register bank (general, floating-point108  // or access) and a raw register number (0-15).  This would postpone the109  // interpretation of the operand to the add*() methods and avoid the need110  // for context-dependent parsing.  However, we do things the current way111  // because of the virtual getReg() method, which needs to distinguish112  // between (say) %r0 used as a single register and %r0 used as a pair.113  // Context-dependent parsing can also give us slightly better error114  // messages when invalid pairs like %r1 are used.115  struct RegOp {116    RegisterKind Kind;117    unsigned Num;118  };119 120  // Base + Disp + Index, where Base and Index are LLVM registers or 0.121  // MemKind says what type of memory this is and RegKind says what type122  // the base register has (GR32Reg or GR64Reg).  Length is the operand123  // length for D(L,B)-style operands, otherwise it is null.124  struct MemOp {125    unsigned Base : 12;126    unsigned Index : 12;127    unsigned MemKind : 4;128    unsigned RegKind : 4;129    const MCExpr *Disp;130    union {131      const MCExpr *Imm;132      unsigned Reg;133    } Length;134  };135 136  // Imm is an immediate operand, and Sym is an optional TLS symbol137  // for use with a __tls_get_offset marker relocation.138  struct ImmTLSOp {139    const MCExpr *Imm;140    const MCExpr *Sym;141  };142 143  union {144    TokenOp Token;145    RegOp Reg;146    const MCExpr *Imm;147    ImmTLSOp ImmTLS;148    MemOp Mem;149  };150 151  void addExpr(MCInst &Inst, const MCExpr *Expr) const {152    // Add as immediates when possible.  Null MCExpr = 0.153    if (!Expr)154      Inst.addOperand(MCOperand::createImm(0));155    else if (auto *CE = dyn_cast<MCConstantExpr>(Expr))156      Inst.addOperand(MCOperand::createImm(CE->getValue()));157    else158      Inst.addOperand(MCOperand::createExpr(Expr));159  }160 161public:162  SystemZOperand(OperandKind Kind, SMLoc StartLoc, SMLoc EndLoc)163      : Kind(Kind), StartLoc(StartLoc), EndLoc(EndLoc) {}164 165  // Create particular kinds of operand.166  static std::unique_ptr<SystemZOperand> createInvalid(SMLoc StartLoc,167                                                       SMLoc EndLoc) {168    return std::make_unique<SystemZOperand>(KindInvalid, StartLoc, EndLoc);169  }170 171  static std::unique_ptr<SystemZOperand> createToken(StringRef Str, SMLoc Loc) {172    auto Op = std::make_unique<SystemZOperand>(KindToken, Loc, Loc);173    Op->Token.Data = Str.data();174    Op->Token.Length = Str.size();175    return Op;176  }177 178  static std::unique_ptr<SystemZOperand>179  createReg(RegisterKind Kind, unsigned Num, SMLoc StartLoc, SMLoc EndLoc) {180    auto Op = std::make_unique<SystemZOperand>(KindReg, StartLoc, EndLoc);181    Op->Reg.Kind = Kind;182    Op->Reg.Num = Num;183    return Op;184  }185 186  static std::unique_ptr<SystemZOperand>187  createImm(const MCExpr *Expr, SMLoc StartLoc, SMLoc EndLoc) {188    auto Op = std::make_unique<SystemZOperand>(KindImm, StartLoc, EndLoc);189    Op->Imm = Expr;190    return Op;191  }192 193  static std::unique_ptr<SystemZOperand>194  createMem(MemoryKind MemKind, RegisterKind RegKind, unsigned Base,195            const MCExpr *Disp, unsigned Index, const MCExpr *LengthImm,196            unsigned LengthReg, SMLoc StartLoc, SMLoc EndLoc) {197    auto Op = std::make_unique<SystemZOperand>(KindMem, StartLoc, EndLoc);198    Op->Mem.MemKind = MemKind;199    Op->Mem.RegKind = RegKind;200    Op->Mem.Base = Base;201    Op->Mem.Index = Index;202    Op->Mem.Disp = Disp;203    if (MemKind == BDLMem)204      Op->Mem.Length.Imm = LengthImm;205    if (MemKind == BDRMem)206      Op->Mem.Length.Reg = LengthReg;207    return Op;208  }209 210  static std::unique_ptr<SystemZOperand>211  createImmTLS(const MCExpr *Imm, const MCExpr *Sym,212               SMLoc StartLoc, SMLoc EndLoc) {213    auto Op = std::make_unique<SystemZOperand>(KindImmTLS, StartLoc, EndLoc);214    Op->ImmTLS.Imm = Imm;215    Op->ImmTLS.Sym = Sym;216    return Op;217  }218 219  // Token operands220  bool isToken() const override {221    return Kind == KindToken;222  }223  StringRef getToken() const {224    assert(Kind == KindToken && "Not a token");225    return StringRef(Token.Data, Token.Length);226  }227 228  // Register operands.229  bool isReg() const override {230    return Kind == KindReg;231  }232  bool isReg(RegisterKind RegKind) const {233    return Kind == KindReg && Reg.Kind == RegKind;234  }235  MCRegister getReg() const override {236    assert(Kind == KindReg && "Not a register");237    return Reg.Num;238  }239 240  // Immediate operands.241  bool isImm() const override {242    return Kind == KindImm;243  }244  bool isImm(int64_t MinValue, int64_t MaxValue) const {245    return Kind == KindImm && inRange(Imm, MinValue, MaxValue, true);246  }247  const MCExpr *getImm() const {248    assert(Kind == KindImm && "Not an immediate");249    return Imm;250  }251 252  // Immediate operands with optional TLS symbol.253  bool isImmTLS() const {254    return Kind == KindImmTLS;255  }256 257  const ImmTLSOp getImmTLS() const {258    assert(Kind == KindImmTLS && "Not a TLS immediate");259    return ImmTLS;260  }261 262  // Memory operands.263  bool isMem() const override {264    return Kind == KindMem;265  }266  bool isMem(MemoryKind MemKind) const {267    return (Kind == KindMem &&268            (Mem.MemKind == MemKind ||269             // A BDMem can be treated as a BDXMem in which the index270             // register field is 0.271             (Mem.MemKind == BDMem && MemKind == BDXMem)));272  }273  bool isMem(MemoryKind MemKind, RegisterKind RegKind) const {274    return isMem(MemKind) && Mem.RegKind == RegKind;275  }276  bool isMemDisp12(MemoryKind MemKind, RegisterKind RegKind) const {277    return isMem(MemKind, RegKind) && inRange(Mem.Disp, 0, 0xfff, true);278  }279  bool isMemDisp20(MemoryKind MemKind, RegisterKind RegKind) const {280    return isMem(MemKind, RegKind) && inRange(Mem.Disp, -524288, 524287, true);281  }282  bool isMemDisp12Len4(RegisterKind RegKind) const {283    return isMemDisp12(BDLMem, RegKind) && inRange(Mem.Length.Imm, 1, 0x10);284  }285  bool isMemDisp12Len8(RegisterKind RegKind) const {286    return isMemDisp12(BDLMem, RegKind) && inRange(Mem.Length.Imm, 1, 0x100);287  }288 289  const MemOp& getMem() const {290    assert(Kind == KindMem && "Not a Mem operand");291    return Mem;292  }293 294  // Override MCParsedAsmOperand.295  SMLoc getStartLoc() const override { return StartLoc; }296  SMLoc getEndLoc() const override { return EndLoc; }297  void print(raw_ostream &OS, const MCAsmInfo &MAI) const override;298 299  /// getLocRange - Get the range between the first and last token of this300  /// operand.301  SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }302 303  // Used by the TableGen code to add particular types of operand304  // to an instruction.305  void addRegOperands(MCInst &Inst, unsigned N) const {306    assert(N == 1 && "Invalid number of operands");307    Inst.addOperand(MCOperand::createReg(getReg()));308  }309  void addImmOperands(MCInst &Inst, unsigned N) const {310    assert(N == 1 && "Invalid number of operands");311    addExpr(Inst, getImm());312  }313  void addBDAddrOperands(MCInst &Inst, unsigned N) const {314    assert(N == 2 && "Invalid number of operands");315    assert(isMem(BDMem) && "Invalid operand type");316    Inst.addOperand(MCOperand::createReg(Mem.Base));317    addExpr(Inst, Mem.Disp);318  }319  void addBDXAddrOperands(MCInst &Inst, unsigned N) const {320    assert(N == 3 && "Invalid number of operands");321    assert(isMem(BDXMem) && "Invalid operand type");322    Inst.addOperand(MCOperand::createReg(Mem.Base));323    addExpr(Inst, Mem.Disp);324    Inst.addOperand(MCOperand::createReg(Mem.Index));325  }326  void addBDLAddrOperands(MCInst &Inst, unsigned N) const {327    assert(N == 3 && "Invalid number of operands");328    assert(isMem(BDLMem) && "Invalid operand type");329    Inst.addOperand(MCOperand::createReg(Mem.Base));330    addExpr(Inst, Mem.Disp);331    addExpr(Inst, Mem.Length.Imm);332  }333  void addBDRAddrOperands(MCInst &Inst, unsigned N) const {334    assert(N == 3 && "Invalid number of operands");335    assert(isMem(BDRMem) && "Invalid operand type");336    Inst.addOperand(MCOperand::createReg(Mem.Base));337    addExpr(Inst, Mem.Disp);338    Inst.addOperand(MCOperand::createReg(Mem.Length.Reg));339  }340  void addBDVAddrOperands(MCInst &Inst, unsigned N) const {341    assert(N == 3 && "Invalid number of operands");342    assert(isMem(BDVMem) && "Invalid operand type");343    Inst.addOperand(MCOperand::createReg(Mem.Base));344    addExpr(Inst, Mem.Disp);345    Inst.addOperand(MCOperand::createReg(Mem.Index));346  }347  void addLXAAddrOperands(MCInst &Inst, unsigned N) const {348    assert(N == 3 && "Invalid number of operands");349    assert(isMem(LXAMem) && "Invalid operand type");350    Inst.addOperand(MCOperand::createReg(Mem.Base));351    addExpr(Inst, Mem.Disp);352    Inst.addOperand(MCOperand::createReg(Mem.Index));353  }354  void addImmTLSOperands(MCInst &Inst, unsigned N) const {355    assert(N == 2 && "Invalid number of operands");356    assert(Kind == KindImmTLS && "Invalid operand type");357    addExpr(Inst, ImmTLS.Imm);358    if (ImmTLS.Sym)359      addExpr(Inst, ImmTLS.Sym);360  }361 362  // Used by the TableGen code to check for particular operand types.363  bool isGR32() const { return isReg(GR32Reg); }364  bool isGRH32() const { return isReg(GRH32Reg); }365  bool isGRX32() const { return false; }366  bool isGR64() const { return isReg(GR64Reg); }367  bool isGR128() const { return isReg(GR128Reg); }368  bool isADDR32() const { return isReg(GR32Reg); }369  bool isADDR64() const { return isReg(GR64Reg); }370  bool isADDR128() const { return false; }371  bool isFP16() const { return isReg(FP16Reg); }372  bool isFP32() const { return isReg(FP32Reg); }373  bool isFP64() const { return isReg(FP64Reg); }374  bool isFP128() const { return isReg(FP128Reg); }375  bool isVR16() const { return isReg(VR16Reg); }376  bool isVR32() const { return isReg(VR32Reg); }377  bool isVR64() const { return isReg(VR64Reg); }378  bool isVF128() const { return false; }379  bool isVR128() const { return isReg(VR128Reg); }380  bool isAR32() const { return isReg(AR32Reg); }381  bool isCR64() const { return isReg(CR64Reg); }382  bool isAnyReg() const { return (isReg() || isImm(0, 15)); }383  bool isBDAddr32Disp12() const { return isMemDisp12(BDMem, GR32Reg); }384  bool isBDAddr32Disp20() const { return isMemDisp20(BDMem, GR32Reg); }385  bool isBDAddr64Disp12() const { return isMemDisp12(BDMem, GR64Reg); }386  bool isBDAddr64Disp20() const { return isMemDisp20(BDMem, GR64Reg); }387  bool isBDXAddr64Disp12() const { return isMemDisp12(BDXMem, GR64Reg); }388  bool isBDXAddr64Disp20() const { return isMemDisp20(BDXMem, GR64Reg); }389  bool isBDLAddr64Disp12Len4() const { return isMemDisp12Len4(GR64Reg); }390  bool isBDLAddr64Disp12Len8() const { return isMemDisp12Len8(GR64Reg); }391  bool isBDRAddr64Disp12() const { return isMemDisp12(BDRMem, GR64Reg); }392  bool isBDVAddr64Disp12() const { return isMemDisp12(BDVMem, GR64Reg); }393  bool isLXAAddr64Disp20() const { return isMemDisp20(LXAMem, GR64Reg); }394  bool isU1Imm() const { return isImm(0, 1); }395  bool isU2Imm() const { return isImm(0, 3); }396  bool isU3Imm() const { return isImm(0, 7); }397  bool isU4Imm() const { return isImm(0, 15); }398  bool isU8Imm() const { return isImm(0, 255); }399  bool isS8Imm() const { return isImm(-128, 127); }400  bool isU12Imm() const { return isImm(0, 4095); }401  bool isU16Imm() const { return isImm(0, 65535); }402  bool isS16Imm() const { return isImm(-32768, 32767); }403  bool isU32Imm() const { return isImm(0, (1LL << 32) - 1); }404  bool isS32Imm() const { return isImm(-(1LL << 31), (1LL << 31) - 1); }405  bool isU48Imm() const { return isImm(0, (1LL << 48) - 1); }406};407 408class SystemZAsmParser : public MCTargetAsmParser {409#define GET_ASSEMBLER_HEADER410#include "SystemZGenAsmMatcher.inc"411 412private:413  MCAsmParser &Parser;414 415  // A vector to contain the stack of FeatureBitsets created by `.machine push`.416  // `.machine pop` pops the top of the stack and uses `setAvailableFeatures` to417  // apply the result.418  SmallVector<FeatureBitset> MachineStack;419 420  enum RegisterGroup {421    RegGR,422    RegFP,423    RegV,424    RegAR,425    RegCR426  };427  struct Register {428    RegisterGroup Group;429    unsigned Num;430    SMLoc StartLoc, EndLoc;431  };432 433  SystemZTargetStreamer &getTargetStreamer() {434    assert(getParser().getStreamer().getTargetStreamer() &&435           "do not have a target streamer");436    MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();437    return static_cast<SystemZTargetStreamer &>(TS);438  }439 440  bool parseRegister(Register &Reg, bool RequirePercent,441                     bool RestoreOnFailure = false);442 443  bool parseIntegerRegister(Register &Reg, RegisterGroup Group);444 445  ParseStatus parseRegister(OperandVector &Operands, RegisterKind Kind);446 447  ParseStatus parseAnyRegister(OperandVector &Operands);448 449  bool parseAddress(bool &HaveReg1, Register &Reg1, bool &HaveReg2,450                    Register &Reg2, const MCExpr *&Disp, const MCExpr *&Length,451                    bool HasLength = false, bool HasVectorIndex = false);452  bool parseAddressRegister(Register &Reg);453 454  bool parseDirectiveInsn(SMLoc L);455  bool parseDirectiveMachine(SMLoc L);456  bool parseGNUAttribute(SMLoc L);457 458  ParseStatus parseAddress(OperandVector &Operands, MemoryKind MemKind,459                           RegisterKind RegKind);460 461  ParseStatus parsePCRel(OperandVector &Operands, int64_t MinVal,462                         int64_t MaxVal, bool AllowTLS);463 464  bool parseOperand(OperandVector &Operands, StringRef Mnemonic);465 466  // Both the hlasm and gnu variants still rely on the basic gnu asm467  // format with respect to inputs, clobbers, outputs etc.468  //469  // However, calling the overriden getAssemblerDialect() method in470  // AsmParser is problematic. It either returns the AssemblerDialect field471  // in the MCAsmInfo instance if the AssemblerDialect field in AsmParser is472  // unset, otherwise it returns the private AssemblerDialect field in473  // AsmParser.474  //475  // The problematic part is because, we forcibly set the inline asm dialect476  // in the AsmParser instance in AsmPrinterInlineAsm.cpp. Soo any query477  // to the overriden getAssemblerDialect function in AsmParser.cpp, will478  // not return the assembler dialect set in the respective MCAsmInfo instance.479  //480  // For this purpose, we explicitly query the SystemZMCAsmInfo instance481  // here, to get the "correct" assembler dialect, and use it in various482  // functions.483  unsigned getMAIAssemblerDialect() {484    return Parser.getContext().getAsmInfo()->getAssemblerDialect();485  }486 487  // An alphabetic character in HLASM is a letter from 'A' through 'Z',488  // or from 'a' through 'z', or '$', '_','#', or '@'.489  inline bool isHLASMAlpha(char C) {490    return isAlpha(C) || llvm::is_contained("_@#$", C);491  }492 493  // A digit in HLASM is a number from 0 to 9.494  inline bool isHLASMAlnum(char C) { return isHLASMAlpha(C) || isDigit(C); }495 496  // Are we parsing using the AD_HLASM dialect?497  inline bool isParsingHLASM() { return getMAIAssemblerDialect() == AD_HLASM; }498 499  // Are we parsing using the AD_GNU dialect?500  inline bool isParsingGNU() { return getMAIAssemblerDialect() == AD_GNU; }501 502public:503  SystemZAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,504                   const MCInstrInfo &MII, const MCTargetOptions &Options)505      : MCTargetAsmParser(Options, sti, MII), Parser(parser) {506    MCAsmParserExtension::Initialize(Parser);507 508    // Alias the .word directive to .short.509    parser.addAliasForDirective(".word", ".short");510 511    // Initialize the set of available features.512    setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));513  }514 515  // Override MCTargetAsmParser.516  ParseStatus parseDirective(AsmToken DirectiveID) override;517  bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override;518  bool ParseRegister(MCRegister &RegNo, SMLoc &StartLoc, SMLoc &EndLoc,519                     bool RequirePercent, bool RestoreOnFailure);520  ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,521                               SMLoc &EndLoc) override;522  bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,523                        SMLoc NameLoc, OperandVector &Operands) override;524  bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,525                               OperandVector &Operands, MCStreamer &Out,526                               uint64_t &ErrorInfo,527                               bool MatchingInlineAsm) override;528  bool isLabel(AsmToken &Token) override;529 530  // Used by the TableGen code to parse particular operand types.531  ParseStatus parseGR32(OperandVector &Operands) {532    return parseRegister(Operands, GR32Reg);533  }534  ParseStatus parseGRH32(OperandVector &Operands) {535    return parseRegister(Operands, GRH32Reg);536  }537  ParseStatus parseGRX32(OperandVector &Operands) {538    llvm_unreachable("GRX32 should only be used for pseudo instructions");539  }540  ParseStatus parseGR64(OperandVector &Operands) {541    return parseRegister(Operands, GR64Reg);542  }543  ParseStatus parseGR128(OperandVector &Operands) {544    return parseRegister(Operands, GR128Reg);545  }546  ParseStatus parseADDR32(OperandVector &Operands) {547    // For the AsmParser, we will accept %r0 for ADDR32 as well.548    return parseRegister(Operands, GR32Reg);549  }550  ParseStatus parseADDR64(OperandVector &Operands) {551    // For the AsmParser, we will accept %r0 for ADDR64 as well.552    return parseRegister(Operands, GR64Reg);553  }554  ParseStatus parseADDR128(OperandVector &Operands) {555    llvm_unreachable("Shouldn't be used as an operand");556  }557  ParseStatus parseFP16(OperandVector &Operands) {558    return parseRegister(Operands, FP16Reg);559  }560  ParseStatus parseFP32(OperandVector &Operands) {561    return parseRegister(Operands, FP32Reg);562  }563  ParseStatus parseFP64(OperandVector &Operands) {564    return parseRegister(Operands, FP64Reg);565  }566  ParseStatus parseFP128(OperandVector &Operands) {567    return parseRegister(Operands, FP128Reg);568  }569  ParseStatus parseVR16(OperandVector &Operands) {570    return parseRegister(Operands, VR16Reg);571  }572  ParseStatus parseVR32(OperandVector &Operands) {573    return parseRegister(Operands, VR32Reg);574  }575  ParseStatus parseVR64(OperandVector &Operands) {576    return parseRegister(Operands, VR64Reg);577  }578  ParseStatus parseVF128(OperandVector &Operands) {579    llvm_unreachable("Shouldn't be used as an operand");580  }581  ParseStatus parseVR128(OperandVector &Operands) {582    return parseRegister(Operands, VR128Reg);583  }584  ParseStatus parseAR32(OperandVector &Operands) {585    return parseRegister(Operands, AR32Reg);586  }587  ParseStatus parseCR64(OperandVector &Operands) {588    return parseRegister(Operands, CR64Reg);589  }590  ParseStatus parseAnyReg(OperandVector &Operands) {591    return parseAnyRegister(Operands);592  }593  ParseStatus parseBDAddr32(OperandVector &Operands) {594    return parseAddress(Operands, BDMem, GR32Reg);595  }596  ParseStatus parseBDAddr64(OperandVector &Operands) {597    return parseAddress(Operands, BDMem, GR64Reg);598  }599  ParseStatus parseBDXAddr64(OperandVector &Operands) {600    return parseAddress(Operands, BDXMem, GR64Reg);601  }602  ParseStatus parseBDLAddr64(OperandVector &Operands) {603    return parseAddress(Operands, BDLMem, GR64Reg);604  }605  ParseStatus parseBDRAddr64(OperandVector &Operands) {606    return parseAddress(Operands, BDRMem, GR64Reg);607  }608  ParseStatus parseBDVAddr64(OperandVector &Operands) {609    return parseAddress(Operands, BDVMem, GR64Reg);610  }611  ParseStatus parseLXAAddr64(OperandVector &Operands) {612    return parseAddress(Operands, LXAMem, GR64Reg);613  }614  ParseStatus parsePCRel12(OperandVector &Operands) {615    return parsePCRel(Operands, -(1LL << 12), (1LL << 12) - 1, false);616  }617  ParseStatus parsePCRel16(OperandVector &Operands) {618    return parsePCRel(Operands, -(1LL << 16), (1LL << 16) - 1, false);619  }620  ParseStatus parsePCRel24(OperandVector &Operands) {621    return parsePCRel(Operands, -(1LL << 24), (1LL << 24) - 1, false);622  }623  ParseStatus parsePCRel32(OperandVector &Operands) {624    return parsePCRel(Operands, -(1LL << 32), (1LL << 32) - 1, false);625  }626  ParseStatus parsePCRelTLS16(OperandVector &Operands) {627    return parsePCRel(Operands, -(1LL << 16), (1LL << 16) - 1, true);628  }629  ParseStatus parsePCRelTLS32(OperandVector &Operands) {630    return parsePCRel(Operands, -(1LL << 32), (1LL << 32) - 1, true);631  }632};633 634} // end anonymous namespace635 636#define GET_REGISTER_MATCHER637#define GET_SUBTARGET_FEATURE_NAME638#define GET_MATCHER_IMPLEMENTATION639#define GET_MNEMONIC_SPELL_CHECKER640#include "SystemZGenAsmMatcher.inc"641 642// Used for the .insn directives; contains information needed to parse the643// operands in the directive.644struct InsnMatchEntry {645  StringRef Format;646  uint64_t Opcode;647  int32_t NumOperands;648  MatchClassKind OperandKinds[7];649};650 651// For equal_range comparison.652struct CompareInsn {653  bool operator() (const InsnMatchEntry &LHS, StringRef RHS) {654    return LHS.Format < RHS;655  }656  bool operator() (StringRef LHS, const InsnMatchEntry &RHS) {657    return LHS < RHS.Format;658  }659  bool operator() (const InsnMatchEntry &LHS, const InsnMatchEntry &RHS) {660    return LHS.Format < RHS.Format;661  }662};663 664// Table initializing information for parsing the .insn directive.665static struct InsnMatchEntry InsnMatchTable[] = {666  /* Format, Opcode, NumOperands, OperandKinds */667  { "e", SystemZ::InsnE, 1,668    { MCK_U16Imm } },669  { "ri", SystemZ::InsnRI, 3,670    { MCK_U32Imm, MCK_AnyReg, MCK_S16Imm } },671  { "rie", SystemZ::InsnRIE, 4,672    { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_PCRel16 } },673  { "ril", SystemZ::InsnRIL, 3,674    { MCK_U48Imm, MCK_AnyReg, MCK_PCRel32 } },675  { "rilu", SystemZ::InsnRILU, 3,676    { MCK_U48Imm, MCK_AnyReg, MCK_U32Imm } },677  { "ris", SystemZ::InsnRIS, 5,678    { MCK_U48Imm, MCK_AnyReg, MCK_S8Imm, MCK_U4Imm, MCK_BDAddr64Disp12 } },679  { "rr", SystemZ::InsnRR, 3,680    { MCK_U16Imm, MCK_AnyReg, MCK_AnyReg } },681  { "rre", SystemZ::InsnRRE, 3,682    { MCK_U32Imm, MCK_AnyReg, MCK_AnyReg } },683  { "rrf", SystemZ::InsnRRF, 5,684    { MCK_U32Imm, MCK_AnyReg, MCK_AnyReg, MCK_AnyReg, MCK_U4Imm } },685  { "rrs", SystemZ::InsnRRS, 5,686    { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_U4Imm, MCK_BDAddr64Disp12 } },687  { "rs", SystemZ::InsnRS, 4,688    { MCK_U32Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddr64Disp12 } },689  { "rse", SystemZ::InsnRSE, 4,690    { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddr64Disp12 } },691  { "rsi", SystemZ::InsnRSI, 4,692    { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_PCRel16 } },693  { "rsy", SystemZ::InsnRSY, 4,694    { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddr64Disp20 } },695  { "rx", SystemZ::InsnRX, 3,696    { MCK_U32Imm, MCK_AnyReg, MCK_BDXAddr64Disp12 } },697  { "rxe", SystemZ::InsnRXE, 3,698    { MCK_U48Imm, MCK_AnyReg, MCK_BDXAddr64Disp12 } },699  { "rxf", SystemZ::InsnRXF, 4,700    { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDXAddr64Disp12 } },701  { "rxy", SystemZ::InsnRXY, 3,702    { MCK_U48Imm, MCK_AnyReg, MCK_BDXAddr64Disp20 } },703  { "s", SystemZ::InsnS, 2,704    { MCK_U32Imm, MCK_BDAddr64Disp12 } },705  { "si", SystemZ::InsnSI, 3,706    { MCK_U32Imm, MCK_BDAddr64Disp12, MCK_S8Imm } },707  { "sil", SystemZ::InsnSIL, 3,708    { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_U16Imm } },709  { "siy", SystemZ::InsnSIY, 3,710    { MCK_U48Imm, MCK_BDAddr64Disp20, MCK_U8Imm } },711  { "ss", SystemZ::InsnSS, 4,712    { MCK_U48Imm, MCK_BDXAddr64Disp12, MCK_BDAddr64Disp12, MCK_AnyReg } },713  { "sse", SystemZ::InsnSSE, 3,714    { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_BDAddr64Disp12 } },715  { "ssf", SystemZ::InsnSSF, 4,716    { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_BDAddr64Disp12, MCK_AnyReg } },717  { "vri", SystemZ::InsnVRI, 6,718    { MCK_U48Imm, MCK_VR128, MCK_VR128, MCK_U12Imm, MCK_U4Imm, MCK_U4Imm } },719  { "vrr", SystemZ::InsnVRR, 7,720    { MCK_U48Imm, MCK_VR128, MCK_VR128, MCK_VR128, MCK_U4Imm, MCK_U4Imm,721      MCK_U4Imm } },722  { "vrs", SystemZ::InsnVRS, 5,723    { MCK_U48Imm, MCK_AnyReg, MCK_VR128, MCK_BDAddr64Disp12, MCK_U4Imm } },724  { "vrv", SystemZ::InsnVRV, 4,725    { MCK_U48Imm, MCK_VR128, MCK_BDVAddr64Disp12, MCK_U4Imm } },726  { "vrx", SystemZ::InsnVRX, 4,727    { MCK_U48Imm, MCK_VR128, MCK_BDXAddr64Disp12, MCK_U4Imm } },728  { "vsi", SystemZ::InsnVSI, 4,729    { MCK_U48Imm, MCK_VR128, MCK_BDAddr64Disp12, MCK_U8Imm } }730};731 732void SystemZOperand::print(raw_ostream &OS, const MCAsmInfo &MAI) const {733  switch (Kind) {734  case KindToken:735    OS << "Token:" << getToken();736    break;737  case KindReg:738    OS << "Reg:" << SystemZGNUInstPrinter::getRegisterName(getReg());739    break;740  case KindImm:741    OS << "Imm:";742    MAI.printExpr(OS, *getImm());743    break;744  case KindImmTLS:745    OS << "ImmTLS:";746    MAI.printExpr(OS, *getImmTLS().Imm);747    if (getImmTLS().Sym) {748      OS << ", ";749      MAI.printExpr(OS, *getImmTLS().Sym);750    }751    break;752  case KindMem: {753    const MemOp &Op = getMem();754    OS << "Mem:";755    MAI.printExpr(OS, *cast<MCConstantExpr>(Op.Disp));756    if (Op.Base) {757      OS << "(";758      if (Op.MemKind == BDLMem) {759        MAI.printExpr(OS, *cast<MCConstantExpr>(Op.Length.Imm));760        OS << ',';761      } else if (Op.MemKind == BDRMem)762        OS << SystemZGNUInstPrinter::getRegisterName(Op.Length.Reg) << ",";763      if (Op.Index)764        OS << SystemZGNUInstPrinter::getRegisterName(Op.Index) << ",";765      OS << SystemZGNUInstPrinter::getRegisterName(Op.Base);766      OS << ")";767    }768    break;769  }770  case KindInvalid:771    break;772  }773}774 775// Parse one register of the form %<prefix><number>.776bool SystemZAsmParser::parseRegister(Register &Reg, bool RequirePercent,777                                     bool RestoreOnFailure) {778  const AsmToken &PercentTok = Parser.getTok();779  bool HasPercent = PercentTok.is(AsmToken::Percent);780 781  Reg.StartLoc = PercentTok.getLoc();782 783  if (RequirePercent && PercentTok.isNot(AsmToken::Percent))784    return Error(PercentTok.getLoc(), "register expected");785 786  if (HasPercent) {787    Parser.Lex(); // Eat percent token.788  }789 790  // Expect a register name.791  if (Parser.getTok().isNot(AsmToken::Identifier)) {792    if (RestoreOnFailure && HasPercent)793      getLexer().UnLex(PercentTok);794    return Error(Reg.StartLoc,795                 HasPercent ? "invalid register" : "register expected");796  }797 798  // Check that there's a prefix.799  StringRef Name = Parser.getTok().getString();800  if (Name.size() < 2) {801    if (RestoreOnFailure && HasPercent)802      getLexer().UnLex(PercentTok);803    return Error(Reg.StartLoc, "invalid register");804  }805  char Prefix = Name[0];806 807  // Treat the rest of the register name as a register number.808  if (Name.substr(1).getAsInteger(10, Reg.Num)) {809    if (RestoreOnFailure && HasPercent)810      getLexer().UnLex(PercentTok);811    return Error(Reg.StartLoc, "invalid register");812  }813 814  // Look for valid combinations of prefix and number.815  if (Prefix == 'r' && Reg.Num < 16)816    Reg.Group = RegGR;817  else if (Prefix == 'f' && Reg.Num < 16)818    Reg.Group = RegFP;819  else if (Prefix == 'v' && Reg.Num < 32)820    Reg.Group = RegV;821  else if (Prefix == 'a' && Reg.Num < 16)822    Reg.Group = RegAR;823  else if (Prefix == 'c' && Reg.Num < 16)824    Reg.Group = RegCR;825  else {826    if (RestoreOnFailure && HasPercent)827      getLexer().UnLex(PercentTok);828    return Error(Reg.StartLoc, "invalid register");829  }830 831  Reg.EndLoc = Parser.getTok().getLoc();832  Parser.Lex();833  return false;834}835 836// Parse a register of kind Kind and add it to Operands.837ParseStatus SystemZAsmParser::parseRegister(OperandVector &Operands,838                                            RegisterKind Kind) {839  Register Reg;840  RegisterGroup Group;841  switch (Kind) {842  case GR32Reg:843  case GRH32Reg:844  case GR64Reg:845  case GR128Reg:846    Group = RegGR;847    break;848  case FP16Reg:849  case FP32Reg:850  case FP64Reg:851  case FP128Reg:852    Group = RegFP;853    break;854  case VR16Reg:855  case VR32Reg:856  case VR64Reg:857  case VR128Reg:858    Group = RegV;859    break;860  case AR32Reg:861    Group = RegAR;862    break;863  case CR64Reg:864    Group = RegCR;865    break;866  }867 868  // Handle register names of the form %<prefix><number>869  if (isParsingGNU() && Parser.getTok().is(AsmToken::Percent)) {870    if (parseRegister(Reg, /*RequirePercent=*/true))871      return ParseStatus::Failure;872 873    // Check the parsed register group "Reg.Group" with the expected "Group"874    // Have to error out if user specified wrong prefix.875    switch (Group) {876    case RegGR:877    case RegFP:878    case RegAR:879    case RegCR:880      if (Group != Reg.Group)881        return Error(Reg.StartLoc, "invalid operand for instruction");882      break;883    case RegV:884      if (Reg.Group != RegV && Reg.Group != RegFP)885        return Error(Reg.StartLoc, "invalid operand for instruction");886      break;887    }888  } else if (Parser.getTok().is(AsmToken::Integer)) {889    if (parseIntegerRegister(Reg, Group))890      return ParseStatus::Failure;891  }892  // Otherwise we didn't match a register operand.893  else894    return ParseStatus::NoMatch;895 896  // Determine the LLVM register number according to Kind.897  // clang-format off898  const unsigned *Regs;899  switch (Kind) {900  case GR32Reg:  Regs = SystemZMC::GR32Regs;  break;901  case GRH32Reg: Regs = SystemZMC::GRH32Regs; break;902  case GR64Reg:  Regs = SystemZMC::GR64Regs;  break;903  case GR128Reg: Regs = SystemZMC::GR128Regs; break;904  case FP16Reg:  Regs = SystemZMC::FP16Regs;  break;905  case FP32Reg:  Regs = SystemZMC::FP32Regs;  break;906  case FP64Reg:  Regs = SystemZMC::FP64Regs;  break;907  case FP128Reg: Regs = SystemZMC::FP128Regs; break;908  case VR16Reg:  Regs = SystemZMC::VR16Regs;  break;909  case VR32Reg:  Regs = SystemZMC::VR32Regs;  break;910  case VR64Reg:  Regs = SystemZMC::VR64Regs;  break;911  case VR128Reg: Regs = SystemZMC::VR128Regs; break;912  case AR32Reg:  Regs = SystemZMC::AR32Regs;  break;913  case CR64Reg:  Regs = SystemZMC::CR64Regs;  break;914  }915  // clang-format on916  if (Regs[Reg.Num] == 0)917    return Error(Reg.StartLoc, "invalid register pair");918 919  Operands.push_back(920      SystemZOperand::createReg(Kind, Regs[Reg.Num], Reg.StartLoc, Reg.EndLoc));921  return ParseStatus::Success;922}923 924// Parse any type of register (including integers) and add it to Operands.925ParseStatus SystemZAsmParser::parseAnyRegister(OperandVector &Operands) {926  SMLoc StartLoc = Parser.getTok().getLoc();927 928  // Handle integer values.929  if (Parser.getTok().is(AsmToken::Integer)) {930    const MCExpr *Register;931    if (Parser.parseExpression(Register))932      return ParseStatus::Failure;933 934    if (auto *CE = dyn_cast<MCConstantExpr>(Register)) {935      int64_t Value = CE->getValue();936      if (Value < 0 || Value > 15)937        return Error(StartLoc, "invalid register");938    }939 940    SMLoc EndLoc =941      SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);942 943    Operands.push_back(SystemZOperand::createImm(Register, StartLoc, EndLoc));944  }945  else {946    if (isParsingHLASM())947      return ParseStatus::NoMatch;948 949    Register Reg;950    if (parseRegister(Reg, /*RequirePercent=*/true))951      return ParseStatus::Failure;952 953    if (Reg.Num > 15)954      return Error(StartLoc, "invalid register");955 956    // Map to the correct register kind.957    RegisterKind Kind;958    unsigned RegNo;959    if (Reg.Group == RegGR) {960      Kind = GR64Reg;961      RegNo = SystemZMC::GR64Regs[Reg.Num];962    }963    else if (Reg.Group == RegFP) {964      Kind = FP64Reg;965      RegNo = SystemZMC::FP64Regs[Reg.Num];966    }967    else if (Reg.Group == RegV) {968      Kind = VR128Reg;969      RegNo = SystemZMC::VR128Regs[Reg.Num];970    }971    else if (Reg.Group == RegAR) {972      Kind = AR32Reg;973      RegNo = SystemZMC::AR32Regs[Reg.Num];974    }975    else if (Reg.Group == RegCR) {976      Kind = CR64Reg;977      RegNo = SystemZMC::CR64Regs[Reg.Num];978    }979    else {980      return ParseStatus::Failure;981    }982 983    Operands.push_back(SystemZOperand::createReg(Kind, RegNo,984                                                 Reg.StartLoc, Reg.EndLoc));985  }986  return ParseStatus::Success;987}988 989bool SystemZAsmParser::parseIntegerRegister(Register &Reg,990                                            RegisterGroup Group) {991  Reg.StartLoc = Parser.getTok().getLoc();992  // We have an integer token993  const MCExpr *Register;994  if (Parser.parseExpression(Register))995    return true;996 997  const auto *CE = dyn_cast<MCConstantExpr>(Register);998  if (!CE)999    return true;1000 1001  int64_t MaxRegNum = (Group == RegV) ? 31 : 15;1002  int64_t Value = CE->getValue();1003  if (Value < 0 || Value > MaxRegNum) {1004    Error(Parser.getTok().getLoc(), "invalid register");1005    return true;1006  }1007 1008  // Assign the Register Number1009  Reg.Num = (unsigned)Value;1010  Reg.Group = Group;1011  Reg.EndLoc = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);1012 1013  // At this point, successfully parsed an integer register.1014  return false;1015}1016 1017// Parse a memory operand into Reg1, Reg2, Disp, and Length.1018bool SystemZAsmParser::parseAddress(bool &HaveReg1, Register &Reg1,1019                                    bool &HaveReg2, Register &Reg2,1020                                    const MCExpr *&Disp, const MCExpr *&Length,1021                                    bool HasLength, bool HasVectorIndex) {1022  // Parse the displacement, which must always be present.1023  if (getParser().parseExpression(Disp))1024    return true;1025 1026  // Parse the optional base and index.1027  HaveReg1 = false;1028  HaveReg2 = false;1029  Length = nullptr;1030 1031  // If we have a scenario as below:1032  //   vgef %v0, 0(0), 01033  // This is an example of a "BDVMem" instruction type.1034  //1035  // So when we parse this as an integer register, the register group1036  // needs to be tied to "RegV". Usually when the prefix is passed in1037  // as %<prefix><reg-number> its easy to check which group it should belong to1038  // However, if we're passing in just the integer there's no real way to1039  // "check" what register group it should belong to.1040  //1041  // When the user passes in the register as an integer, the user assumes that1042  // the compiler is responsible for substituting it as the right kind of1043  // register. Whereas, when the user specifies a "prefix", the onus is on1044  // the user to make sure they pass in the right kind of register.1045  //1046  // The restriction only applies to the first Register (i.e. Reg1). Reg2 is1047  // always a general register. Reg1 should be of group RegV if "HasVectorIndex"1048  // (i.e. insn is of type BDVMem) is true.1049  RegisterGroup RegGroup = HasVectorIndex ? RegV : RegGR;1050 1051  if (getLexer().is(AsmToken::LParen)) {1052    Parser.Lex();1053 1054    if (isParsingGNU() && getLexer().is(AsmToken::Percent)) {1055      // Parse the first register.1056      HaveReg1 = true;1057      if (parseRegister(Reg1, /*RequirePercent=*/true))1058        return true;1059    }1060    // So if we have an integer as the first token in ([tok1], ..), it could:1061    // 1. Refer to a "Register" (i.e X,R,V fields in BD[X|R|V]Mem type of1062    // instructions)1063    // 2. Refer to a "Length" field (i.e L field in BDLMem type of instructions)1064    else if (getLexer().is(AsmToken::Integer)) {1065      if (HasLength) {1066        // Instruction has a "Length" field, safe to parse the first token as1067        // the "Length" field1068        if (getParser().parseExpression(Length))1069          return true;1070      } else {1071        // Otherwise, if the instruction has no "Length" field, parse the1072        // token as a "Register". We don't have to worry about whether the1073        // instruction is invalid here, because the caller will take care of1074        // error reporting.1075        HaveReg1 = true;1076        if (parseIntegerRegister(Reg1, RegGroup))1077          return true;1078      }1079    } else {1080      // If its not an integer or a percent token, then if the instruction1081      // is reported to have a "Length" then, parse it as "Length".1082      if (HasLength) {1083        if (getParser().parseExpression(Length))1084          return true;1085      }1086    }1087 1088    // Check whether there's a second register.1089    if (getLexer().is(AsmToken::Comma)) {1090      Parser.Lex();1091      HaveReg2 = true;1092 1093      if (getLexer().is(AsmToken::Integer)) {1094        if (parseIntegerRegister(Reg2, RegGR))1095          return true;1096      } else if (isParsingGNU()) {1097        if (Parser.getTok().is(AsmToken::Percent)) {1098          if (parseRegister(Reg2, /*RequirePercent=*/true))1099            return true;1100        } else {1101          // GAS allows ",)" to indicate a missing base register.1102          Reg2.Num = 0;1103          Reg2.Group = RegGR;1104          Reg2.StartLoc = Reg2.EndLoc = Parser.getTok().getLoc();1105        }1106      }1107    }1108 1109    // Consume the closing bracket.1110    if (getLexer().isNot(AsmToken::RParen))1111      return Error(Parser.getTok().getLoc(), "unexpected token in address");1112    Parser.Lex();1113  }1114  return false;1115}1116 1117// Verify that Reg is a valid address register (base or index).1118bool1119SystemZAsmParser::parseAddressRegister(Register &Reg) {1120  if (Reg.Group == RegV) {1121    Error(Reg.StartLoc, "invalid use of vector addressing");1122    return true;1123  }1124  if (Reg.Group != RegGR) {1125    Error(Reg.StartLoc, "invalid address register");1126    return true;1127  }1128  return false;1129}1130 1131// Parse a memory operand and add it to Operands.  The other arguments1132// are as above.1133ParseStatus SystemZAsmParser::parseAddress(OperandVector &Operands,1134                                           MemoryKind MemKind,1135                                           RegisterKind RegKind) {1136  SMLoc StartLoc = Parser.getTok().getLoc();1137  unsigned Base = 0, Index = 0, LengthReg = 0;1138  Register Reg1, Reg2;1139  bool HaveReg1, HaveReg2;1140  const MCExpr *Disp;1141  const MCExpr *Length;1142 1143  bool HasLength = (MemKind == BDLMem) ? true : false;1144  bool HasVectorIndex = (MemKind == BDVMem) ? true : false;1145  if (parseAddress(HaveReg1, Reg1, HaveReg2, Reg2, Disp, Length, HasLength,1146                   HasVectorIndex))1147    return ParseStatus::Failure;1148 1149  const unsigned *Regs;1150  switch (RegKind) {1151  case GR32Reg: Regs = SystemZMC::GR32Regs; break;1152  case GR64Reg: Regs = SystemZMC::GR64Regs; break;1153  default: llvm_unreachable("invalid RegKind");1154  }1155 1156  switch (MemKind) {1157  case BDMem:1158    // If we have Reg1, it must be an address register.1159    if (HaveReg1) {1160      if (parseAddressRegister(Reg1))1161        return ParseStatus::Failure;1162      Base = Reg1.Num == 0 ? 0 : Regs[Reg1.Num];1163    }1164    // There must be no Reg2.1165    if (HaveReg2)1166      return Error(StartLoc, "invalid use of indexed addressing");1167    break;1168  case BDXMem:1169  case LXAMem:1170    // If we have Reg1, it must be an address register.1171    if (HaveReg1) {1172      const unsigned *IndexRegs = Regs;1173      if (MemKind == LXAMem)1174        IndexRegs = SystemZMC::GR32Regs;1175 1176      if (parseAddressRegister(Reg1))1177        return ParseStatus::Failure;1178      // If there are two registers, the first one is the index and the1179      // second is the base.  If there is only a single register, it is1180      // used as base with GAS and as index with HLASM.1181      if (HaveReg2 || isParsingHLASM())1182        Index = Reg1.Num == 0 ? 0 : IndexRegs[Reg1.Num];1183      else1184        Base = Reg1.Num == 0 ? 0 : Regs[Reg1.Num];1185    }1186    // If we have Reg2, it must be an address register.1187    if (HaveReg2) {1188      if (parseAddressRegister(Reg2))1189        return ParseStatus::Failure;1190      Base = Reg2.Num == 0 ? 0 : Regs[Reg2.Num];1191    }1192    break;1193  case BDLMem:1194    // If we have Reg2, it must be an address register.1195    if (HaveReg2) {1196      if (parseAddressRegister(Reg2))1197        return ParseStatus::Failure;1198      Base = Reg2.Num == 0 ? 0 : Regs[Reg2.Num];1199    }1200    // We cannot support base+index addressing.1201    if (HaveReg1 && HaveReg2)1202      return Error(StartLoc, "invalid use of indexed addressing");1203    // We must have a length.1204    if (!Length)1205      return Error(StartLoc, "missing length in address");1206    break;1207  case BDRMem:1208    // We must have Reg1, and it must be a GPR.1209    if (!HaveReg1 || Reg1.Group != RegGR)1210      return Error(StartLoc, "invalid operand for instruction");1211    LengthReg = SystemZMC::GR64Regs[Reg1.Num];1212    // If we have Reg2, it must be an address register.1213    if (HaveReg2) {1214      if (parseAddressRegister(Reg2))1215        return ParseStatus::Failure;1216      Base = Reg2.Num == 0 ? 0 : Regs[Reg2.Num];1217    }1218    break;1219  case BDVMem:1220    // We must have Reg1, and it must be a vector register.1221    if (!HaveReg1 || Reg1.Group != RegV)1222      return Error(StartLoc, "vector index required in address");1223    Index = SystemZMC::VR128Regs[Reg1.Num];1224    // In GAS mode, we must have Reg2, since a single register would be1225    // interpreted as base register, which cannot be a vector register.1226    if (isParsingGNU() && !HaveReg2)1227      return Error(Reg1.StartLoc, "invalid use of vector addressing");1228    // If we have Reg2, it must be an address register.1229    if (HaveReg2) {1230      if (parseAddressRegister(Reg2))1231        return ParseStatus::Failure;1232      Base = Reg2.Num == 0 ? 0 : Regs[Reg2.Num];1233    }1234    break;1235  }1236 1237  SMLoc EndLoc =1238      SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);1239  Operands.push_back(SystemZOperand::createMem(MemKind, RegKind, Base, Disp,1240                                               Index, Length, LengthReg,1241                                               StartLoc, EndLoc));1242  return ParseStatus::Success;1243}1244 1245ParseStatus SystemZAsmParser::parseDirective(AsmToken DirectiveID) {1246  StringRef IDVal = DirectiveID.getIdentifier();1247 1248  if (IDVal == ".insn")1249    return parseDirectiveInsn(DirectiveID.getLoc());1250  if (IDVal == ".machine")1251    return parseDirectiveMachine(DirectiveID.getLoc());1252  if (IDVal.starts_with(".gnu_attribute"))1253    return parseGNUAttribute(DirectiveID.getLoc());1254 1255  return ParseStatus::NoMatch;1256}1257 1258/// ParseDirectiveInsn1259/// ::= .insn [ format, encoding, (operands (, operands)*) ]1260bool SystemZAsmParser::parseDirectiveInsn(SMLoc L) {1261  MCAsmParser &Parser = getParser();1262 1263  // Expect instruction format as identifier.1264  StringRef Format;1265  SMLoc ErrorLoc = Parser.getTok().getLoc();1266  if (Parser.parseIdentifier(Format))1267    return Error(ErrorLoc, "expected instruction format");1268 1269  SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> Operands;1270 1271  // Find entry for this format in InsnMatchTable.1272  auto EntryRange =1273    std::equal_range(std::begin(InsnMatchTable), std::end(InsnMatchTable),1274                     Format, CompareInsn());1275 1276  // If first == second, couldn't find a match in the table.1277  if (EntryRange.first == EntryRange.second)1278    return Error(ErrorLoc, "unrecognized format");1279 1280  struct InsnMatchEntry *Entry = EntryRange.first;1281 1282  // Format should match from equal_range.1283  assert(Entry->Format == Format);1284 1285  // Parse the following operands using the table's information.1286  for (int I = 0; I < Entry->NumOperands; I++) {1287    MatchClassKind Kind = Entry->OperandKinds[I];1288 1289    SMLoc StartLoc = Parser.getTok().getLoc();1290 1291    // Always expect commas as separators for operands.1292    if (getLexer().isNot(AsmToken::Comma))1293      return Error(StartLoc, "unexpected token in directive");1294    Lex();1295 1296    // Parse operands.1297    ParseStatus ResTy;1298    if (Kind == MCK_AnyReg)1299      ResTy = parseAnyReg(Operands);1300    else if (Kind == MCK_VR128)1301      ResTy = parseVR128(Operands);1302    else if (Kind == MCK_BDXAddr64Disp12 || Kind == MCK_BDXAddr64Disp20)1303      ResTy = parseBDXAddr64(Operands);1304    else if (Kind == MCK_BDAddr64Disp12 || Kind == MCK_BDAddr64Disp20)1305      ResTy = parseBDAddr64(Operands);1306    else if (Kind == MCK_BDVAddr64Disp12)1307      ResTy = parseBDVAddr64(Operands);1308    else if (Kind == MCK_LXAAddr64Disp20)1309      ResTy = parseLXAAddr64(Operands);1310    else if (Kind == MCK_PCRel32)1311      ResTy = parsePCRel32(Operands);1312    else if (Kind == MCK_PCRel16)1313      ResTy = parsePCRel16(Operands);1314    else {1315      // Only remaining operand kind is an immediate.1316      const MCExpr *Expr;1317      SMLoc StartLoc = Parser.getTok().getLoc();1318 1319      // Expect immediate expression.1320      if (Parser.parseExpression(Expr))1321        return Error(StartLoc, "unexpected token in directive");1322 1323      SMLoc EndLoc =1324        SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);1325 1326      Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));1327      ResTy = ParseStatus::Success;1328    }1329 1330    if (!ResTy.isSuccess())1331      return true;1332  }1333 1334  // Build the instruction with the parsed operands.1335  MCInst Inst = MCInstBuilder(Entry->Opcode);1336 1337  for (size_t I = 0; I < Operands.size(); I++) {1338    MCParsedAsmOperand &Operand = *Operands[I];1339    MatchClassKind Kind = Entry->OperandKinds[I];1340 1341    // Verify operand.1342    unsigned Res = validateOperandClass(Operand, Kind, *STI);1343    if (Res != Match_Success)1344      return Error(Operand.getStartLoc(), "unexpected operand type");1345 1346    // Add operands to instruction.1347    SystemZOperand &ZOperand = static_cast<SystemZOperand &>(Operand);1348    if (ZOperand.isReg())1349      ZOperand.addRegOperands(Inst, 1);1350    else if (ZOperand.isMem(BDMem))1351      ZOperand.addBDAddrOperands(Inst, 2);1352    else if (ZOperand.isMem(BDXMem))1353      ZOperand.addBDXAddrOperands(Inst, 3);1354    else if (ZOperand.isMem(BDVMem))1355      ZOperand.addBDVAddrOperands(Inst, 3);1356    else if (ZOperand.isMem(LXAMem))1357      ZOperand.addLXAAddrOperands(Inst, 3);1358    else if (ZOperand.isImm())1359      ZOperand.addImmOperands(Inst, 1);1360    else1361      llvm_unreachable("unexpected operand type");1362  }1363 1364  // Emit as a regular instruction.1365  Parser.getStreamer().emitInstruction(Inst, getSTI());1366 1367  return false;1368}1369 1370/// ParseDirectiveMachine1371/// ::= .machine [ mcpu ]1372bool SystemZAsmParser::parseDirectiveMachine(SMLoc L) {1373  MCAsmParser &Parser = getParser();1374  if (Parser.getTok().isNot(AsmToken::Identifier) &&1375      Parser.getTok().isNot(AsmToken::String))1376    return TokError("unexpected token in '.machine' directive");1377 1378  StringRef Id = Parser.getTok().getIdentifier();1379  SMLoc IdLoc = Parser.getTok().getLoc();1380 1381  Parser.Lex();1382  if (parseEOL())1383    return true;1384 1385  // Parse push and pop directives first1386  if (Id == "push") {1387    // Push the Current FeatureBitSet onto the stack.1388    MachineStack.push_back(getAvailableFeatures());1389  } else if (Id == "pop") {1390    // If the stack is not empty pop the topmost FeatureBitset and use it.1391    if (MachineStack.empty())1392      return Error(IdLoc,1393                   "pop without corresponding push in '.machine' directive");1394    setAvailableFeatures(MachineStack.back());1395    MachineStack.pop_back();1396  } else {1397    // Try to interpret the Identifier as a CPU spec and derive the1398    // FeatureBitset from that.1399    MCSubtargetInfo &STI = copySTI();1400    STI.setDefaultFeatures(Id, /*TuneCPU*/ Id, "");1401    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));1402  }1403  getTargetStreamer().emitMachine(Id);1404 1405  return false;1406}1407 1408bool SystemZAsmParser::parseGNUAttribute(SMLoc L) {1409  int64_t Tag;1410  int64_t IntegerValue;1411  if (!Parser.parseGNUAttribute(L, Tag, IntegerValue))1412    return Error(L, "malformed .gnu_attribute directive");1413 1414  // Tag_GNU_S390_ABI_Vector tag is '8' and can be 0, 1, or 2.1415  if (Tag != 8 || (IntegerValue < 0 || IntegerValue > 2))1416    return Error(L, "unrecognized .gnu_attribute tag/value pair.");1417 1418  Parser.getStreamer().emitGNUAttribute(Tag, IntegerValue);1419 1420  return parseEOL();1421}1422 1423bool SystemZAsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc,1424                                     SMLoc &EndLoc, bool RequirePercent,1425                                     bool RestoreOnFailure) {1426  Register Reg;1427  if (parseRegister(Reg, RequirePercent, RestoreOnFailure))1428    return true;1429  if (Reg.Group == RegGR)1430    RegNo = SystemZMC::GR64Regs[Reg.Num];1431  else if (Reg.Group == RegFP)1432    RegNo = SystemZMC::FP64Regs[Reg.Num];1433  else if (Reg.Group == RegV)1434    RegNo = SystemZMC::VR128Regs[Reg.Num];1435  else if (Reg.Group == RegAR)1436    RegNo = SystemZMC::AR32Regs[Reg.Num];1437  else if (Reg.Group == RegCR)1438    RegNo = SystemZMC::CR64Regs[Reg.Num];1439  StartLoc = Reg.StartLoc;1440  EndLoc = Reg.EndLoc;1441  return false;1442}1443 1444bool SystemZAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,1445                                     SMLoc &EndLoc) {1446  return ParseRegister(Reg, StartLoc, EndLoc, /*RequirePercent=*/false,1447                       /*RestoreOnFailure=*/false);1448}1449 1450ParseStatus SystemZAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,1451                                               SMLoc &EndLoc) {1452  bool Result = ParseRegister(Reg, StartLoc, EndLoc, /*RequirePercent=*/false,1453                              /*RestoreOnFailure=*/true);1454  bool PendingErrors = getParser().hasPendingError();1455  getParser().clearPendingErrors();1456  if (PendingErrors)1457    return ParseStatus::Failure;1458  if (Result)1459    return ParseStatus::NoMatch;1460  return ParseStatus::Success;1461}1462 1463bool SystemZAsmParser::parseInstruction(ParseInstructionInfo &Info,1464                                        StringRef Name, SMLoc NameLoc,1465                                        OperandVector &Operands) {1466 1467  // Apply mnemonic aliases first, before doing anything else, in1468  // case the target uses it.1469  applyMnemonicAliases(Name, getAvailableFeatures(), getMAIAssemblerDialect());1470 1471  Operands.push_back(SystemZOperand::createToken(Name, NameLoc));1472 1473  // Read the remaining operands.1474  if (getLexer().isNot(AsmToken::EndOfStatement)) {1475    // Read the first operand.1476    if (parseOperand(Operands, Name)) {1477      return true;1478    }1479 1480    // Read any subsequent operands.1481    while (getLexer().is(AsmToken::Comma)) {1482      Parser.Lex();1483 1484      if (isParsingHLASM() && getLexer().is(AsmToken::Space))1485        return Error(1486            Parser.getTok().getLoc(),1487            "No space allowed between comma that separates operand entries");1488 1489      if (parseOperand(Operands, Name)) {1490        return true;1491      }1492    }1493 1494    // Under the HLASM variant, we could have the remark field1495    // The remark field occurs after the operation entries1496    // There is a space that separates the operation entries and the1497    // remark field.1498    if (isParsingHLASM() && getTok().is(AsmToken::Space)) {1499      // We've confirmed that there is a Remark field.1500      StringRef Remark(getLexer().LexUntilEndOfStatement());1501      Parser.Lex();1502 1503      // If there is nothing after the space, then there is nothing to emit1504      // We could have a situation as this:1505      // "  \n"1506      // After lexing above, we will have1507      // "\n"1508      // This isn't an explicit remark field, so we don't have to output1509      // this as a comment.1510      if (Remark.size())1511        // Output the entire Remarks Field as a comment1512        getStreamer().AddComment(Remark);1513    }1514 1515    if (getLexer().isNot(AsmToken::EndOfStatement)) {1516      SMLoc Loc = getLexer().getLoc();1517      return Error(Loc, "unexpected token in argument list");1518    }1519  }1520 1521  // Consume the EndOfStatement.1522  Parser.Lex();1523  return false;1524}1525 1526bool SystemZAsmParser::parseOperand(OperandVector &Operands,1527                                    StringRef Mnemonic) {1528  // Check if the current operand has a custom associated parser, if so, try to1529  // custom parse the operand, or fallback to the general approach.  Force all1530  // features to be available during the operand check, or else we will fail to1531  // find the custom parser, and then we will later get an InvalidOperand error1532  // instead of a MissingFeature errror.1533  FeatureBitset AvailableFeatures = getAvailableFeatures();1534  FeatureBitset All;1535  All.set();1536  setAvailableFeatures(All);1537  ParseStatus Res = MatchOperandParserImpl(Operands, Mnemonic);1538  setAvailableFeatures(AvailableFeatures);1539  if (Res.isSuccess())1540    return false;1541 1542  // If there wasn't a custom match, try the generic matcher below. Otherwise,1543  // there was a match, but an error occurred, in which case, just return that1544  // the operand parsing failed.1545  if (Res.isFailure())1546    return true;1547 1548  // Check for a register.  All real register operands should have used1549  // a context-dependent parse routine, which gives the required register1550  // class.  The code is here to mop up other cases, like those where1551  // the instruction isn't recognized.1552  if (isParsingGNU() && Parser.getTok().is(AsmToken::Percent)) {1553    Register Reg;1554    if (parseRegister(Reg, /*RequirePercent=*/true))1555      return true;1556    Operands.push_back(SystemZOperand::createInvalid(Reg.StartLoc, Reg.EndLoc));1557    return false;1558  }1559 1560  // The only other type of operand is an immediate or address.  As above,1561  // real address operands should have used a context-dependent parse routine,1562  // so we treat any plain expression as an immediate.1563  SMLoc StartLoc = Parser.getTok().getLoc();1564  Register Reg1, Reg2;1565  bool HaveReg1, HaveReg2;1566  const MCExpr *Expr;1567  const MCExpr *Length;1568  if (parseAddress(HaveReg1, Reg1, HaveReg2, Reg2, Expr, Length,1569                   /*HasLength*/ true, /*HasVectorIndex*/ true))1570    return true;1571  // If the register combination is not valid for any instruction, reject it.1572  // Otherwise, fall back to reporting an unrecognized instruction.1573  if (HaveReg1 && Reg1.Group != RegGR && Reg1.Group != RegV1574      && parseAddressRegister(Reg1))1575    return true;1576  if (HaveReg2 && parseAddressRegister(Reg2))1577    return true;1578 1579  SMLoc EndLoc =1580    SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);1581  if (HaveReg1 || HaveReg2 || Length)1582    Operands.push_back(SystemZOperand::createInvalid(StartLoc, EndLoc));1583  else1584    Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));1585  return false;1586}1587 1588bool SystemZAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,1589                                               OperandVector &Operands,1590                                               MCStreamer &Out,1591                                               uint64_t &ErrorInfo,1592                                               bool MatchingInlineAsm) {1593  MCInst Inst;1594  unsigned MatchResult;1595 1596  unsigned Dialect = getMAIAssemblerDialect();1597 1598  FeatureBitset MissingFeatures;1599  MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,1600                                     MatchingInlineAsm, Dialect);1601  switch (MatchResult) {1602  case Match_Success:1603    Inst.setLoc(IDLoc);1604    Out.emitInstruction(Inst, getSTI());1605    return false;1606 1607  case Match_MissingFeature: {1608    assert(MissingFeatures.any() && "Unknown missing feature!");1609    // Special case the error message for the very common case where only1610    // a single subtarget feature is missing1611    std::string Msg = "instruction requires:";1612    for (unsigned I = 0, E = MissingFeatures.size(); I != E; ++I) {1613      if (MissingFeatures[I]) {1614        Msg += " ";1615        Msg += getSubtargetFeatureName(I);1616      }1617    }1618    return Error(IDLoc, Msg);1619  }1620 1621  case Match_InvalidOperand: {1622    SMLoc ErrorLoc = IDLoc;1623    if (ErrorInfo != ~0ULL) {1624      if (ErrorInfo >= Operands.size())1625        return Error(IDLoc, "too few operands for instruction");1626 1627      ErrorLoc = ((SystemZOperand &)*Operands[ErrorInfo]).getStartLoc();1628      if (ErrorLoc == SMLoc())1629        ErrorLoc = IDLoc;1630    }1631    return Error(ErrorLoc, "invalid operand for instruction");1632  }1633 1634  case Match_MnemonicFail: {1635    FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());1636    std::string Suggestion = SystemZMnemonicSpellCheck(1637        ((SystemZOperand &)*Operands[0]).getToken(), FBS, Dialect);1638    return Error(IDLoc, "invalid instruction" + Suggestion,1639                 ((SystemZOperand &)*Operands[0]).getLocRange());1640  }1641  }1642 1643  llvm_unreachable("Unexpected match type");1644}1645 1646ParseStatus SystemZAsmParser::parsePCRel(OperandVector &Operands,1647                                         int64_t MinVal, int64_t MaxVal,1648                                         bool AllowTLS) {1649  MCContext &Ctx = getContext();1650  MCStreamer &Out = getStreamer();1651  const MCExpr *Expr;1652  SMLoc StartLoc = Parser.getTok().getLoc();1653  if (getParser().parseExpression(Expr))1654    return ParseStatus::NoMatch;1655 1656  auto IsOutOfRangeConstant = [&](const MCExpr *E, bool Negate) -> bool {1657    if (auto *CE = dyn_cast<MCConstantExpr>(E)) {1658      int64_t Value = CE->getValue();1659      if (Negate)1660        Value = -Value;1661      if ((Value & 1) || Value < MinVal || Value > MaxVal)1662        return true;1663    }1664    return false;1665  };1666 1667  // For consistency with the GNU assembler, treat immediates as offsets1668  // from ".".1669  if (auto *CE = dyn_cast<MCConstantExpr>(Expr)) {1670    if (isParsingHLASM())1671      return Error(StartLoc, "Expected PC-relative expression");1672    if (IsOutOfRangeConstant(CE, false))1673      return Error(StartLoc, "offset out of range");1674    int64_t Value = CE->getValue();1675    MCSymbol *Sym = Ctx.createTempSymbol();1676    Out.emitLabel(Sym);1677    const MCExpr *Base = MCSymbolRefExpr::create(Sym, Ctx);1678    Expr = Value == 0 ? Base : MCBinaryExpr::createAdd(Base, Expr, Ctx);1679  }1680 1681  // For consistency with the GNU assembler, conservatively assume that a1682  // constant offset must by itself be within the given size range.1683  if (const auto *BE = dyn_cast<MCBinaryExpr>(Expr))1684    if (IsOutOfRangeConstant(BE->getLHS(), false) ||1685        IsOutOfRangeConstant(BE->getRHS(),1686                             BE->getOpcode() == MCBinaryExpr::Sub))1687      return Error(StartLoc, "offset out of range");1688 1689  // Optionally match :tls_gdcall: or :tls_ldcall: followed by a TLS symbol.1690  const MCExpr *Sym = nullptr;1691  if (AllowTLS && getLexer().is(AsmToken::Colon)) {1692    Parser.Lex();1693 1694    if (Parser.getTok().isNot(AsmToken::Identifier))1695      return Error(Parser.getTok().getLoc(), "unexpected token");1696 1697    auto Kind = SystemZ::S_None;1698    StringRef Name = Parser.getTok().getString();1699    if (Name == "tls_gdcall")1700      Kind = SystemZ::S_TLSGD;1701    else if (Name == "tls_ldcall")1702      Kind = SystemZ::S_TLSLDM;1703    else1704      return Error(Parser.getTok().getLoc(), "unknown TLS tag");1705    Parser.Lex();1706 1707    if (Parser.getTok().isNot(AsmToken::Colon))1708      return Error(Parser.getTok().getLoc(), "unexpected token");1709    Parser.Lex();1710 1711    if (Parser.getTok().isNot(AsmToken::Identifier))1712      return Error(Parser.getTok().getLoc(), "unexpected token");1713 1714    StringRef Identifier = Parser.getTok().getString();1715    Sym = MCSymbolRefExpr::create(Ctx.getOrCreateSymbol(Identifier),1716                                  Kind, Ctx);1717    Parser.Lex();1718  }1719 1720  SMLoc EndLoc =1721    SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);1722 1723  if (AllowTLS)1724    Operands.push_back(SystemZOperand::createImmTLS(Expr, Sym,1725                                                    StartLoc, EndLoc));1726  else1727    Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));1728 1729  return ParseStatus::Success;1730}1731 1732bool SystemZAsmParser::isLabel(AsmToken &Token) {1733  if (isParsingGNU())1734    return true;1735 1736  // HLASM labels are ordinary symbols.1737  // An HLASM label always starts at column 1.1738  // An ordinary symbol syntax is laid out as follows:1739  // Rules:1740  // 1. Has to start with an "alphabetic character". Can be followed by up to1741  //    62 alphanumeric characters. An "alphabetic character", in this scenario,1742  //    is a letter from 'A' through 'Z', or from 'a' through 'z',1743  //    or '$', '_', '#', or '@'1744  // 2. Labels are case-insensitive. E.g. "lab123", "LAB123", "lAb123", etc.1745  //    are all treated as the same symbol. However, the processing for the case1746  //    folding will not be done in this function.1747  StringRef RawLabel = Token.getString();1748  SMLoc Loc = Token.getLoc();1749 1750  // An HLASM label cannot be empty.1751  if (!RawLabel.size())1752    return !Error(Loc, "HLASM Label cannot be empty");1753 1754  // An HLASM label cannot exceed greater than 63 characters.1755  if (RawLabel.size() > 63)1756    return !Error(Loc, "Maximum length for HLASM Label is 63 characters");1757 1758  // A label must start with an "alphabetic character".1759  if (!isHLASMAlpha(RawLabel[0]))1760    return !Error(Loc, "HLASM Label has to start with an alphabetic "1761                       "character or the underscore character");1762 1763  // Now, we've established that the length is valid1764  // and the first character is alphabetic.1765  // Check whether remaining string is alphanumeric.1766  for (unsigned I = 1; I < RawLabel.size(); ++I)1767    if (!isHLASMAlnum(RawLabel[I]))1768      return !Error(Loc, "HLASM Label has to be alphanumeric");1769 1770  return true;1771}1772 1773// Force static initialization.1774// NOLINTNEXTLINE(readability-identifier-naming)1775extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void1776LLVMInitializeSystemZAsmParser() {1777  RegisterMCAsmParser<SystemZAsmParser> X(getTheSystemZTarget());1778}1779