brintos

brintos / llvm-project-archived public Read only

0
0
Text · 58.6 KiB · b07f950 Raw
1839 lines · cpp
1//===-- PPCAsmParser.cpp - Parse PowerPC asm to MCInst 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/PPCMCAsmInfo.h"10#include "MCTargetDesc/PPCMCTargetDesc.h"11#include "MCTargetDesc/PPCTargetStreamer.h"12#include "PPCInstrInfo.h"13#include "TargetInfo/PowerPCTargetInfo.h"14#include "llvm/ADT/Twine.h"15#include "llvm/MC/MCContext.h"16#include "llvm/MC/MCExpr.h"17#include "llvm/MC/MCInst.h"18#include "llvm/MC/MCInstrInfo.h"19#include "llvm/MC/MCParser/AsmLexer.h"20#include "llvm/MC/MCParser/MCAsmParser.h"21#include "llvm/MC/MCParser/MCParsedAsmOperand.h"22#include "llvm/MC/MCParser/MCTargetAsmParser.h"23#include "llvm/MC/MCStreamer.h"24#include "llvm/MC/MCSubtargetInfo.h"25#include "llvm/MC/MCSymbolELF.h"26#include "llvm/MC/TargetRegistry.h"27#include "llvm/Support/Compiler.h"28#include "llvm/Support/SourceMgr.h"29#include "llvm/Support/raw_ostream.h"30 31using namespace llvm;32 33DEFINE_PPC_REGCLASSES34 35// Evaluate an expression containing condition register36// or condition register field symbols.  Returns positive37// value on success, or -1 on error.38static int64_t39EvaluateCRExpr(const MCExpr *E) {40  switch (E->getKind()) {41  case MCExpr::Constant: {42    int64_t Res = cast<MCConstantExpr>(E)->getValue();43    return Res < 0 ? -1 : Res;44  }45 46  case MCExpr::SymbolRef: {47    const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);48    StringRef Name = SRE->getSymbol().getName();49 50    if (Name == "lt") return 0;51    if (Name == "gt") return 1;52    if (Name == "eq") return 2;53    if (Name == "so") return 3;54    if (Name == "un") return 3;55 56    if (Name == "cr0") return 0;57    if (Name == "cr1") return 1;58    if (Name == "cr2") return 2;59    if (Name == "cr3") return 3;60    if (Name == "cr4") return 4;61    if (Name == "cr5") return 5;62    if (Name == "cr6") return 6;63    if (Name == "cr7") return 7;64 65    return -1;66  }67 68  case MCExpr::Unary:69    return -1;70 71  case MCExpr::Binary: {72    const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);73    int64_t LHSVal = EvaluateCRExpr(BE->getLHS());74    int64_t RHSVal = EvaluateCRExpr(BE->getRHS());75    int64_t Res;76 77    if (LHSVal < 0 || RHSVal < 0)78      return -1;79 80    switch (BE->getOpcode()) {81    default: return -1;82    case MCBinaryExpr::Add: Res = LHSVal + RHSVal; break;83    case MCBinaryExpr::Mul: Res = LHSVal * RHSVal; break;84    }85 86    return Res < 0 ? -1 : Res;87  }88  case MCExpr::Specifier:89    return -1;90  case MCExpr::Target:91    llvm_unreachable("unused by this backend");92  }93 94  llvm_unreachable("Invalid expression kind!");95}96 97namespace {98 99struct PPCOperand;100 101class PPCAsmParser : public MCTargetAsmParser {102  const bool IsPPC64;103 104  void Warning(SMLoc L, const Twine &Msg) { getParser().Warning(L, Msg); }105 106  bool isPPC64() const { return IsPPC64; }107 108  MCRegister matchRegisterName(int64_t &IntVal);109 110  bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override;111  ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,112                               SMLoc &EndLoc) override;113 114  const MCExpr *extractSpecifier(const MCExpr *E,115                                 PPCMCExpr::Specifier &Variant);116  bool parseExpression(const MCExpr *&EVal);117 118  bool parseOperand(OperandVector &Operands);119 120  bool parseDirectiveWord(unsigned Size, AsmToken ID);121  bool parseDirectiveTC(unsigned Size, AsmToken ID);122  bool parseDirectiveMachine(SMLoc L);123  bool parseDirectiveAbiVersion(SMLoc L);124  bool parseDirectiveLocalEntry(SMLoc L);125  bool parseGNUAttribute(SMLoc L);126 127  bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,128                               OperandVector &Operands, MCStreamer &Out,129                               uint64_t &ErrorInfo,130                               bool MatchingInlineAsm) override;131 132  void processInstruction(MCInst &Inst, const OperandVector &Ops);133 134  /// @name Auto-generated Match Functions135  /// {136 137#define GET_ASSEMBLER_HEADER138#include "PPCGenAsmMatcher.inc"139 140  /// }141 142 143public:144  PPCAsmParser(const MCSubtargetInfo &STI, MCAsmParser &,145               const MCInstrInfo &MII, const MCTargetOptions &Options)146      : MCTargetAsmParser(Options, STI, MII),147        IsPPC64(STI.getTargetTriple().isPPC64()) {148    // Initialize the set of available features.149    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));150  }151 152  bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,153                        SMLoc NameLoc, OperandVector &Operands) override;154 155  bool ParseDirective(AsmToken DirectiveID) override;156 157  unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,158                                      unsigned Kind) override;159 160  const MCExpr *applySpecifier(const MCExpr *E, uint32_t,161                               MCContext &Ctx) override;162};163 164/// PPCOperand - Instances of this class represent a parsed PowerPC machine165/// instruction.166struct PPCOperand : public MCParsedAsmOperand {167  enum KindTy {168    Token,169    Immediate,170    ContextImmediate,171    Expression,172    TLSRegister173  } Kind;174 175  SMLoc StartLoc, EndLoc;176  bool IsPPC64;177 178  struct TokOp {179    const char *Data;180    unsigned Length;181  };182 183  struct ImmOp {184    int64_t Val;185    bool IsMemOpBase;186  };187 188  struct ExprOp {189    const MCExpr *Val;190    int64_t CRVal;     // Cached result of EvaluateCRExpr(Val)191  };192 193  struct TLSRegOp {194    const MCSymbolRefExpr *Sym;195  };196 197  union {198    struct TokOp Tok;199    struct ImmOp Imm;200    struct ExprOp Expr;201    struct TLSRegOp TLSReg;202  };203 204  PPCOperand(KindTy K) : Kind(K) {}205 206public:207  PPCOperand(const PPCOperand &o) : MCParsedAsmOperand() {208    Kind = o.Kind;209    StartLoc = o.StartLoc;210    EndLoc = o.EndLoc;211    IsPPC64 = o.IsPPC64;212    switch (Kind) {213    case Token:214      Tok = o.Tok;215      break;216    case Immediate:217    case ContextImmediate:218      Imm = o.Imm;219      break;220    case Expression:221      Expr = o.Expr;222      break;223    case TLSRegister:224      TLSReg = o.TLSReg;225      break;226    }227  }228 229  // Disable use of sized deallocation due to overallocation of PPCOperand230  // objects in CreateTokenWithStringCopy.231  void operator delete(void *p) { ::operator delete(p); }232 233  /// getStartLoc - Get the location of the first token of this operand.234  SMLoc getStartLoc() const override { return StartLoc; }235 236  /// getEndLoc - Get the location of the last token of this operand.237  SMLoc getEndLoc() const override { return EndLoc; }238 239  /// getLocRange - Get the range between the first and last token of this240  /// operand.241  SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }242 243  /// isPPC64 - True if this operand is for an instruction in 64-bit mode.244  bool isPPC64() const { return IsPPC64; }245 246  /// isMemOpBase - True if this operand is the base of a memory operand.247  bool isMemOpBase() const { return Kind == Immediate && Imm.IsMemOpBase; }248 249  int64_t getImm() const {250    assert(Kind == Immediate && "Invalid access!");251    return Imm.Val;252  }253  int64_t getImmS16Context() const {254    assert((Kind == Immediate || Kind == ContextImmediate) &&255           "Invalid access!");256    if (Kind == Immediate)257      return Imm.Val;258    return static_cast<int16_t>(Imm.Val);259  }260  int64_t getImmU16Context() const {261    assert((Kind == Immediate || Kind == ContextImmediate) &&262           "Invalid access!");263    return Imm.Val;264  }265 266  const MCExpr *getExpr() const {267    assert(Kind == Expression && "Invalid access!");268    return Expr.Val;269  }270 271  int64_t getExprCRVal() const {272    assert(Kind == Expression && "Invalid access!");273    return Expr.CRVal;274  }275 276  const MCExpr *getTLSReg() const {277    assert(Kind == TLSRegister && "Invalid access!");278    return TLSReg.Sym;279  }280 281  MCRegister getReg() const override { llvm_unreachable("Not implemented"); }282 283  unsigned getRegNum() const {284    assert(isRegNumber() && "Invalid access!");285    return (unsigned)Imm.Val;286  }287 288  unsigned getFpReg() const {289    assert(isEvenRegNumber() && "Invalid access!");290    return (unsigned)(Imm.Val >> 1);291  }292 293  unsigned getVSReg() const {294    assert(isVSRegNumber() && "Invalid access!");295    return (unsigned) Imm.Val;296  }297 298  unsigned getACCReg() const {299    assert(isACCRegNumber() && "Invalid access!");300    return (unsigned) Imm.Val;301  }302 303  unsigned getDMRROWReg() const {304    assert(isDMRROWRegNumber() && "Invalid access!");305    return (unsigned)Imm.Val;306  }307 308  unsigned getDMRROWpReg() const {309    assert(isDMRROWpRegNumber() && "Invalid access!");310    return (unsigned)Imm.Val;311  }312 313  unsigned getDMRReg() const {314    assert(isDMRRegNumber() && "Invalid access!");315    return (unsigned)Imm.Val;316  }317 318  unsigned getDMRpReg() const {319    assert(isDMRpRegNumber() && "Invalid access!");320    return (unsigned)Imm.Val;321  }322 323  unsigned getVSRpEvenReg() const {324    assert(isVSRpEvenRegNumber() && "Invalid access!");325    return (unsigned) Imm.Val >> 1;326  }327 328  unsigned getG8pReg() const {329    assert(isEvenRegNumber() && "Invalid access!");330    return (unsigned)Imm.Val;331  }332 333  unsigned getCCReg() const {334    assert(isCCRegNumber() && "Invalid access!");335    return (unsigned) (Kind == Immediate ? Imm.Val : Expr.CRVal);336  }337 338  unsigned getCRBit() const {339    assert(isCRBitNumber() && "Invalid access!");340    return (unsigned) (Kind == Immediate ? Imm.Val : Expr.CRVal);341  }342 343  unsigned getCRBitMask() const {344    assert(isCRBitMask() && "Invalid access!");345    return 7 - llvm::countr_zero<uint64_t>(Imm.Val);346  }347 348  bool isToken() const override { return Kind == Token; }349  bool isImm() const override {350    return Kind == Immediate || Kind == Expression;351  }352 353  template <uint64_t N> bool isUImm() const {354    return Kind == Immediate && isUInt<N>(getImm());355  }356  template <uint64_t N> bool isSImm() const {357    return Kind == Immediate && isInt<N>(getImm());358  }359  bool isU6ImmX2() const { return isUImm<6>() && (getImm() & 1) == 0; }360  bool isU7ImmX4() const { return isUImm<7>() && (getImm() & 3) == 0; }361  bool isU8ImmX8() const { return isUImm<8>() && (getImm() & 7) == 0; }362 363  bool isU16Imm() const { return isExtImm<16>(/*Signed*/ false, 1); }364  bool isS16Imm() const { return isExtImm<16>(/*Signed*/ true, 1); }365  bool isS16ImmX4() const { return isExtImm<16>(/*Signed*/ true, 4); }366  bool isS16ImmX16() const { return isExtImm<16>(/*Signed*/ true, 16); }367  bool isS17Imm() const { return isExtImm<17>(/*Signed*/ true, 1); }368  bool isS32Imm() const {369    // TODO: Is ContextImmediate needed?370    return Kind == Expression || isSImm<32>();371  }372  bool isS34Imm() const {373    // Once the PC-Rel ABI is finalized, evaluate whether a 34-bit374    // ContextImmediate is needed.375    return Kind == Expression || isSImm<34>();376  }377  bool isS34ImmX16() const {378    return Kind == Expression || (isSImm<34>() && (getImm() & 15) == 0);379  }380 381  bool isHashImmX8() const {382    // The Hash Imm form is used for instructions that check or store a hash.383    // These instructions have a small immediate range that spans between384    // -8 and -512.385    return (Kind == Immediate && getImm() <= -8 && getImm() >= -512 &&386            (getImm() & 7) == 0);387  }388 389  bool isTLSReg() const { return Kind == TLSRegister; }390  bool isDirectBr() const {391    if (Kind == Expression)392      return true;393    if (Kind != Immediate)394      return false;395    // Operand must be 64-bit aligned, signed 27-bit immediate.396    if ((getImm() & 3) != 0)397      return false;398    if (isInt<26>(getImm()))399      return true;400    if (!IsPPC64) {401      // In 32-bit mode, large 32-bit quantities wrap around.402      if (isUInt<32>(getImm()) && isInt<26>(static_cast<int32_t>(getImm())))403        return true;404    }405    return false;406  }407  bool isCondBr() const { return Kind == Expression ||408                                 (Kind == Immediate && isInt<16>(getImm()) &&409                                  (getImm() & 3) == 0); }410  bool isImmZero() const { return Kind == Immediate && getImm() == 0; }411  bool isRegNumber() const { return Kind == Immediate && isUInt<5>(getImm()); }412  bool isACCRegNumber() const {413    return Kind == Immediate && isUInt<3>(getImm());414  }415  bool isDMRROWRegNumber() const {416    return Kind == Immediate && isUInt<6>(getImm());417  }418  bool isDMRROWpRegNumber() const {419    return Kind == Immediate && isUInt<5>(getImm());420  }421  bool isDMRRegNumber() const {422    return Kind == Immediate && isUInt<3>(getImm());423  }424  bool isDMRpRegNumber() const {425    return Kind == Immediate && isUInt<2>(getImm());426  }427  bool isVSRpEvenRegNumber() const {428    return Kind == Immediate && isUInt<6>(getImm()) && ((getImm() & 1) == 0);429  }430  bool isVSRegNumber() const {431    return Kind == Immediate && isUInt<6>(getImm());432  }433  bool isCCRegNumber() const { return (Kind == Expression434                                       && isUInt<3>(getExprCRVal())) ||435                                      (Kind == Immediate436                                       && isUInt<3>(getImm())); }437  bool isCRBitNumber() const { return (Kind == Expression438                                       && isUInt<5>(getExprCRVal())) ||439                                      (Kind == Immediate440                                       && isUInt<5>(getImm())); }441 442  bool isEvenRegNumber() const { return isRegNumber() && (getImm() & 1) == 0; }443 444  bool isCRBitMask() const {445    return Kind == Immediate && isUInt<8>(getImm()) &&446           llvm::has_single_bit<uint32_t>(getImm());447  }448  bool isATBitsAsHint() const { return false; }449  bool isMem() const override { return false; }450  bool isReg() const override { return false; }451 452  void addRegOperands(MCInst &Inst, unsigned N) const {453    llvm_unreachable("addRegOperands");454  }455 456  void addRegGPRCOperands(MCInst &Inst, unsigned N) const {457    assert(N == 1 && "Invalid number of operands!");458    Inst.addOperand(MCOperand::createReg(RRegs[getRegNum()]));459  }460 461  void addRegGPRCNoR0Operands(MCInst &Inst, unsigned N) const {462    assert(N == 1 && "Invalid number of operands!");463    Inst.addOperand(MCOperand::createReg(RRegsNoR0[getRegNum()]));464  }465 466  void addRegG8RCOperands(MCInst &Inst, unsigned N) const {467    assert(N == 1 && "Invalid number of operands!");468    Inst.addOperand(MCOperand::createReg(XRegs[getRegNum()]));469  }470 471  void addRegG8RCNoX0Operands(MCInst &Inst, unsigned N) const {472    assert(N == 1 && "Invalid number of operands!");473    Inst.addOperand(MCOperand::createReg(XRegsNoX0[getRegNum()]));474  }475 476  void addRegG8pRCOperands(MCInst &Inst, unsigned N) const {477    assert(N == 1 && "Invalid number of operands!");478    Inst.addOperand(MCOperand::createReg(XRegs[getG8pReg()]));479  }480 481  void addRegGxRCOperands(MCInst &Inst, unsigned N) const {482    if (isPPC64())483      addRegG8RCOperands(Inst, N);484    else485      addRegGPRCOperands(Inst, N);486  }487 488  void addRegGxRCNoR0Operands(MCInst &Inst, unsigned N) const {489    if (isPPC64())490      addRegG8RCNoX0Operands(Inst, N);491    else492      addRegGPRCNoR0Operands(Inst, N);493  }494 495  void addRegF4RCOperands(MCInst &Inst, unsigned N) const {496    assert(N == 1 && "Invalid number of operands!");497    Inst.addOperand(MCOperand::createReg(FRegs[getRegNum()]));498  }499 500  void addRegF8RCOperands(MCInst &Inst, unsigned N) const {501    assert(N == 1 && "Invalid number of operands!");502    Inst.addOperand(MCOperand::createReg(FRegs[getRegNum()]));503  }504 505  void addRegFpRCOperands(MCInst &Inst, unsigned N) const {506    assert(N == 1 && "Invalid number of operands!");507    Inst.addOperand(MCOperand::createReg(FpRegs[getFpReg()]));508  }509 510  void addRegVFRCOperands(MCInst &Inst, unsigned N) const {511    assert(N == 1 && "Invalid number of operands!");512    Inst.addOperand(MCOperand::createReg(VFRegs[getRegNum()]));513  }514 515  void addRegVRRCOperands(MCInst &Inst, unsigned N) const {516    assert(N == 1 && "Invalid number of operands!");517    Inst.addOperand(MCOperand::createReg(VRegs[getRegNum()]));518  }519 520  void addRegVSRCOperands(MCInst &Inst, unsigned N) const {521    assert(N == 1 && "Invalid number of operands!");522    Inst.addOperand(MCOperand::createReg(VSRegs[getVSReg()]));523  }524 525  void addRegVSFRCOperands(MCInst &Inst, unsigned N) const {526    assert(N == 1 && "Invalid number of operands!");527    Inst.addOperand(MCOperand::createReg(VSFRegs[getVSReg()]));528  }529 530  void addRegVSSRCOperands(MCInst &Inst, unsigned N) const {531    assert(N == 1 && "Invalid number of operands!");532    Inst.addOperand(MCOperand::createReg(VSSRegs[getVSReg()]));533  }534 535  void addRegSPE4RCOperands(MCInst &Inst, unsigned N) const {536    assert(N == 1 && "Invalid number of operands!");537    Inst.addOperand(MCOperand::createReg(RRegs[getRegNum()]));538  }539 540  void addRegSPERCOperands(MCInst &Inst, unsigned N) const {541    assert(N == 1 && "Invalid number of operands!");542    Inst.addOperand(MCOperand::createReg(SPERegs[getRegNum()]));543  }544 545  void addRegACCRCOperands(MCInst &Inst, unsigned N) const {546    assert(N == 1 && "Invalid number of operands!");547    Inst.addOperand(MCOperand::createReg(ACCRegs[getACCReg()]));548  }549 550  void addRegDMRROWRCOperands(MCInst &Inst, unsigned N) const {551    assert(N == 1 && "Invalid number of operands!");552    Inst.addOperand(MCOperand::createReg(DMRROWRegs[getDMRROWReg()]));553  }554 555  void addRegDMRROWpRCOperands(MCInst &Inst, unsigned N) const {556    assert(N == 1 && "Invalid number of operands!");557    Inst.addOperand(MCOperand::createReg(DMRROWpRegs[getDMRROWpReg()]));558  }559 560  void addRegDMRRCOperands(MCInst &Inst, unsigned N) const {561    assert(N == 1 && "Invalid number of operands!");562    Inst.addOperand(MCOperand::createReg(DMRRegs[getDMRReg()]));563  }564 565  void addRegDMRpRCOperands(MCInst &Inst, unsigned N) const {566    assert(N == 1 && "Invalid number of operands!");567    Inst.addOperand(MCOperand::createReg(DMRpRegs[getDMRpReg()]));568  }569 570  void addRegWACCRCOperands(MCInst &Inst, unsigned N) const {571    assert(N == 1 && "Invalid number of operands!");572    Inst.addOperand(MCOperand::createReg(WACCRegs[getACCReg()]));573  }574 575  void addRegWACC_HIRCOperands(MCInst &Inst, unsigned N) const {576    assert(N == 1 && "Invalid number of operands!");577    Inst.addOperand(MCOperand::createReg(WACC_HIRegs[getACCReg()]));578  }579 580  void addRegVSRpRCOperands(MCInst &Inst, unsigned N) const {581    assert(N == 1 && "Invalid number of operands!");582    Inst.addOperand(MCOperand::createReg(VSRpRegs[getVSRpEvenReg()]));583  }584 585  void addRegVSRpEvenRCOperands(MCInst &Inst, unsigned N) const {586    assert(N == 1 && "Invalid number of operands!");587    Inst.addOperand(MCOperand::createReg(VSRpRegs[getVSRpEvenReg()]));588  }589 590  void addRegCRBITRCOperands(MCInst &Inst, unsigned N) const {591    assert(N == 1 && "Invalid number of operands!");592    Inst.addOperand(MCOperand::createReg(CRBITRegs[getCRBit()]));593  }594 595  void addRegCRRCOperands(MCInst &Inst, unsigned N) const {596    assert(N == 1 && "Invalid number of operands!");597    Inst.addOperand(MCOperand::createReg(CRRegs[getCCReg()]));598  }599 600  void addCRBitMaskOperands(MCInst &Inst, unsigned N) const {601    assert(N == 1 && "Invalid number of operands!");602    Inst.addOperand(MCOperand::createReg(CRRegs[getCRBitMask()]));603  }604 605  void addImmOperands(MCInst &Inst, unsigned N) const {606    assert(N == 1 && "Invalid number of operands!");607    if (Kind == Immediate)608      Inst.addOperand(MCOperand::createImm(getImm()));609    else610      Inst.addOperand(MCOperand::createExpr(getExpr()));611  }612 613  void addS16ImmOperands(MCInst &Inst, unsigned N) const {614    assert(N == 1 && "Invalid number of operands!");615    switch (Kind) {616      case Immediate:617        Inst.addOperand(MCOperand::createImm(getImm()));618        break;619      case ContextImmediate:620        Inst.addOperand(MCOperand::createImm(getImmS16Context()));621        break;622      default:623        Inst.addOperand(MCOperand::createExpr(getExpr()));624        break;625    }626  }627 628  void addU16ImmOperands(MCInst &Inst, unsigned N) const {629    assert(N == 1 && "Invalid number of operands!");630    switch (Kind) {631      case Immediate:632        Inst.addOperand(MCOperand::createImm(getImm()));633        break;634      case ContextImmediate:635        Inst.addOperand(MCOperand::createImm(getImmU16Context()));636        break;637      default:638        Inst.addOperand(MCOperand::createExpr(getExpr()));639        break;640    }641  }642 643  void addBranchTargetOperands(MCInst &Inst, unsigned N) const {644    assert(N == 1 && "Invalid number of operands!");645    if (Kind == Immediate)646      Inst.addOperand(MCOperand::createImm(getImm() / 4));647    else648      Inst.addOperand(MCOperand::createExpr(getExpr()));649  }650 651  void addTLSRegOperands(MCInst &Inst, unsigned N) const {652    assert(N == 1 && "Invalid number of operands!");653    Inst.addOperand(MCOperand::createExpr(getTLSReg()));654  }655 656  StringRef getToken() const {657    assert(Kind == Token && "Invalid access!");658    return StringRef(Tok.Data, Tok.Length);659  }660 661  void print(raw_ostream &OS, const MCAsmInfo &MAI) const override;662 663  static std::unique_ptr<PPCOperand> CreateToken(StringRef Str, SMLoc S,664                                                 bool IsPPC64) {665    auto Op = std::make_unique<PPCOperand>(Token);666    Op->Tok.Data = Str.data();667    Op->Tok.Length = Str.size();668    Op->StartLoc = S;669    Op->EndLoc = S;670    Op->IsPPC64 = IsPPC64;671    return Op;672  }673 674  static std::unique_ptr<PPCOperand>675  CreateTokenWithStringCopy(StringRef Str, SMLoc S, bool IsPPC64) {676    // Allocate extra memory for the string and copy it.677    // FIXME: This is incorrect, Operands are owned by unique_ptr with a default678    // deleter which will destroy them by simply using "delete", not correctly679    // calling operator delete on this extra memory after calling the dtor680    // explicitly.681    void *Mem = ::operator new(sizeof(PPCOperand) + Str.size());682    std::unique_ptr<PPCOperand> Op(new (Mem) PPCOperand(Token));683    Op->Tok.Data = reinterpret_cast<const char *>(Op.get() + 1);684    Op->Tok.Length = Str.size();685    std::memcpy(const_cast<char *>(Op->Tok.Data), Str.data(), Str.size());686    Op->StartLoc = S;687    Op->EndLoc = S;688    Op->IsPPC64 = IsPPC64;689    return Op;690  }691 692  static std::unique_ptr<PPCOperand> CreateImm(int64_t Val, SMLoc S, SMLoc E,693                                               bool IsPPC64,694                                               bool IsMemOpBase = false) {695    auto Op = std::make_unique<PPCOperand>(Immediate);696    Op->Imm.Val = Val;697    Op->Imm.IsMemOpBase = IsMemOpBase;698    Op->StartLoc = S;699    Op->EndLoc = E;700    Op->IsPPC64 = IsPPC64;701    return Op;702  }703 704  static std::unique_ptr<PPCOperand> CreateExpr(const MCExpr *Val, SMLoc S,705                                                SMLoc E, bool IsPPC64) {706    auto Op = std::make_unique<PPCOperand>(Expression);707    Op->Expr.Val = Val;708    Op->Expr.CRVal = EvaluateCRExpr(Val);709    Op->StartLoc = S;710    Op->EndLoc = E;711    Op->IsPPC64 = IsPPC64;712    return Op;713  }714 715  static std::unique_ptr<PPCOperand>716  CreateTLSReg(const MCSymbolRefExpr *Sym, SMLoc S, SMLoc E, bool IsPPC64) {717    auto Op = std::make_unique<PPCOperand>(TLSRegister);718    Op->TLSReg.Sym = Sym;719    Op->StartLoc = S;720    Op->EndLoc = E;721    Op->IsPPC64 = IsPPC64;722    return Op;723  }724 725  static std::unique_ptr<PPCOperand>726  CreateContextImm(int64_t Val, SMLoc S, SMLoc E, bool IsPPC64) {727    auto Op = std::make_unique<PPCOperand>(ContextImmediate);728    Op->Imm.Val = Val;729    Op->StartLoc = S;730    Op->EndLoc = E;731    Op->IsPPC64 = IsPPC64;732    return Op;733  }734 735  static std::unique_ptr<PPCOperand>736  CreateFromMCExpr(const MCExpr *Val, SMLoc S, SMLoc E, bool IsPPC64) {737    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Val))738      return CreateImm(CE->getValue(), S, E, IsPPC64);739 740    if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(Val))741      if (getSpecifier(SRE) == PPC::S_TLS ||742          getSpecifier(SRE) == PPC::S_TLS_PCREL)743        return CreateTLSReg(SRE, S, E, IsPPC64);744 745    if (const auto *SE = dyn_cast<MCSpecifierExpr>(Val)) {746      int64_t Res;747      if (PPC::evaluateAsConstant(*SE, Res))748        return CreateContextImm(Res, S, E, IsPPC64);749    }750 751    return CreateExpr(Val, S, E, IsPPC64);752  }753 754private:755  template <unsigned Width>756  bool isExtImm(bool Signed, unsigned Multiple) const {757    switch (Kind) {758    default:759      return false;760    case Expression:761      return true;762    case Immediate:763    case ContextImmediate:764      if (Signed)765        return isInt<Width>(getImmS16Context()) &&766               (getImmS16Context() & (Multiple - 1)) == 0;767      else768        return isUInt<Width>(getImmU16Context()) &&769               (getImmU16Context() & (Multiple - 1)) == 0;770    }771  }772};773 774} // end anonymous namespace.775 776void PPCOperand::print(raw_ostream &OS, const MCAsmInfo &MAI) const {777  switch (Kind) {778  case Token:779    OS << "'" << getToken() << "'";780    break;781  case Immediate:782  case ContextImmediate:783    OS << getImm();784    break;785  case Expression:786    MAI.printExpr(OS, *getExpr());787    break;788  case TLSRegister:789    MAI.printExpr(OS, *getTLSReg());790    break;791  }792}793 794static void795addNegOperand(MCInst &Inst, MCOperand &Op, MCContext &Ctx) {796  if (Op.isImm()) {797    Inst.addOperand(MCOperand::createImm(-Op.getImm()));798    return;799  }800  const MCExpr *Expr = Op.getExpr();801  if (const MCUnaryExpr *UnExpr = dyn_cast<MCUnaryExpr>(Expr)) {802    if (UnExpr->getOpcode() == MCUnaryExpr::Minus) {803      Inst.addOperand(MCOperand::createExpr(UnExpr->getSubExpr()));804      return;805    }806  } else if (const MCBinaryExpr *BinExpr = dyn_cast<MCBinaryExpr>(Expr)) {807    if (BinExpr->getOpcode() == MCBinaryExpr::Sub) {808      const MCExpr *NE = MCBinaryExpr::createSub(BinExpr->getRHS(),809                                                 BinExpr->getLHS(), Ctx);810      Inst.addOperand(MCOperand::createExpr(NE));811      return;812    }813  }814  Inst.addOperand(MCOperand::createExpr(MCUnaryExpr::createMinus(Expr, Ctx)));815}816 817void PPCAsmParser::processInstruction(MCInst &Inst,818                                      const OperandVector &Operands) {819  int Opcode = Inst.getOpcode();820  switch (Opcode) {821  case PPC::DCBTx:822  case PPC::DCBTT:823  case PPC::DCBTSTx:824  case PPC::DCBTSTT: {825    MCInst TmpInst;826    TmpInst.setOpcode((Opcode == PPC::DCBTx || Opcode == PPC::DCBTT) ?827                      PPC::DCBT : PPC::DCBTST);828    TmpInst.addOperand(MCOperand::createImm(829      (Opcode == PPC::DCBTx || Opcode == PPC::DCBTSTx) ? 0 : 16));830    TmpInst.addOperand(Inst.getOperand(0));831    TmpInst.addOperand(Inst.getOperand(1));832    Inst = TmpInst;833    break;834  }835  case PPC::DCBTCT:836  case PPC::DCBTDS: {837    MCInst TmpInst;838    TmpInst.setOpcode(PPC::DCBT);839    TmpInst.addOperand(Inst.getOperand(2));840    TmpInst.addOperand(Inst.getOperand(0));841    TmpInst.addOperand(Inst.getOperand(1));842    Inst = TmpInst;843    break;844  }845  case PPC::DCBTSTCT:846  case PPC::DCBTSTDS: {847    MCInst TmpInst;848    TmpInst.setOpcode(PPC::DCBTST);849    TmpInst.addOperand(Inst.getOperand(2));850    TmpInst.addOperand(Inst.getOperand(0));851    TmpInst.addOperand(Inst.getOperand(1));852    Inst = TmpInst;853    break;854  }855  case PPC::DCBFx:856  case PPC::DCBFL:857  case PPC::DCBFLP:858  case PPC::DCBFPS:859  case PPC::DCBSTPS: {860    int L = 0;861    if (Opcode == PPC::DCBFL)862      L = 1;863    else if (Opcode == PPC::DCBFLP)864      L = 3;865    else if (Opcode == PPC::DCBFPS)866      L = 4;867    else if (Opcode == PPC::DCBSTPS)868      L = 6;869 870    MCInst TmpInst;871    TmpInst.setOpcode(PPC::DCBF);872    TmpInst.addOperand(MCOperand::createImm(L));873    TmpInst.addOperand(Inst.getOperand(0));874    TmpInst.addOperand(Inst.getOperand(1));875    Inst = TmpInst;876    break;877  }878  case PPC::LAx: {879    MCInst TmpInst;880    TmpInst.setOpcode(PPC::LA);881    TmpInst.addOperand(Inst.getOperand(0));882    TmpInst.addOperand(Inst.getOperand(2));883    TmpInst.addOperand(Inst.getOperand(1));884    Inst = TmpInst;885    break;886  }887  case PPC::PLA8:888  case PPC::PLA: {889    MCInst TmpInst;890    TmpInst.setOpcode(Opcode == PPC::PLA ? PPC::PADDI : PPC::PADDI8);891    TmpInst.addOperand(Inst.getOperand(0));892    TmpInst.addOperand(Inst.getOperand(1));893    TmpInst.addOperand(Inst.getOperand(2));894    Inst = TmpInst;895    break;896  }897  case PPC::PLA8pc:898  case PPC::PLApc: {899    MCInst TmpInst;900    TmpInst.setOpcode(Opcode == PPC::PLApc ? PPC::PADDIpc : PPC::PADDI8pc);901    TmpInst.addOperand(Inst.getOperand(0));902    TmpInst.addOperand(MCOperand::createImm(0));903    TmpInst.addOperand(Inst.getOperand(1));904    Inst = TmpInst;905    break;906  }907  case PPC::SUBI: {908    MCInst TmpInst;909    TmpInst.setOpcode(PPC::ADDI);910    TmpInst.addOperand(Inst.getOperand(0));911    TmpInst.addOperand(Inst.getOperand(1));912    addNegOperand(TmpInst, Inst.getOperand(2), getContext());913    Inst = TmpInst;914    break;915  }916  case PPC::PSUBI: {917    MCInst TmpInst;918    TmpInst.setOpcode(PPC::PADDI);919    TmpInst.addOperand(Inst.getOperand(0));920    TmpInst.addOperand(Inst.getOperand(1));921    addNegOperand(TmpInst, Inst.getOperand(2), getContext());922    Inst = TmpInst;923    break;924  }925  case PPC::SUBIS: {926    MCInst TmpInst;927    TmpInst.setOpcode(PPC::ADDIS);928    TmpInst.addOperand(Inst.getOperand(0));929    TmpInst.addOperand(Inst.getOperand(1));930    addNegOperand(TmpInst, Inst.getOperand(2), getContext());931    Inst = TmpInst;932    break;933  }934  case PPC::SUBIC: {935    MCInst TmpInst;936    TmpInst.setOpcode(PPC::ADDIC);937    TmpInst.addOperand(Inst.getOperand(0));938    TmpInst.addOperand(Inst.getOperand(1));939    addNegOperand(TmpInst, Inst.getOperand(2), getContext());940    Inst = TmpInst;941    break;942  }943  case PPC::SUBIC_rec: {944    MCInst TmpInst;945    TmpInst.setOpcode(PPC::ADDIC_rec);946    TmpInst.addOperand(Inst.getOperand(0));947    TmpInst.addOperand(Inst.getOperand(1));948    addNegOperand(TmpInst, Inst.getOperand(2), getContext());949    Inst = TmpInst;950    break;951  }952  case PPC::EXTLWI:953  case PPC::EXTLWI_rec: {954    MCInst TmpInst;955    int64_t N = Inst.getOperand(2).getImm();956    int64_t B = Inst.getOperand(3).getImm();957    TmpInst.setOpcode(Opcode == PPC::EXTLWI ? PPC::RLWINM : PPC::RLWINM_rec);958    TmpInst.addOperand(Inst.getOperand(0));959    TmpInst.addOperand(Inst.getOperand(1));960    TmpInst.addOperand(MCOperand::createImm(B));961    TmpInst.addOperand(MCOperand::createImm(0));962    TmpInst.addOperand(MCOperand::createImm(N - 1));963    Inst = TmpInst;964    break;965  }966  case PPC::EXTRWI:967  case PPC::EXTRWI_rec: {968    MCInst TmpInst;969    int64_t N = Inst.getOperand(2).getImm();970    int64_t B = Inst.getOperand(3).getImm();971    TmpInst.setOpcode(Opcode == PPC::EXTRWI ? PPC::RLWINM : PPC::RLWINM_rec);972    TmpInst.addOperand(Inst.getOperand(0));973    TmpInst.addOperand(Inst.getOperand(1));974    TmpInst.addOperand(MCOperand::createImm(B + N));975    TmpInst.addOperand(MCOperand::createImm(32 - N));976    TmpInst.addOperand(MCOperand::createImm(31));977    Inst = TmpInst;978    break;979  }980  case PPC::INSLWI:981  case PPC::INSLWI_rec: {982    MCInst TmpInst;983    int64_t N = Inst.getOperand(2).getImm();984    int64_t B = Inst.getOperand(3).getImm();985    TmpInst.setOpcode(Opcode == PPC::INSLWI ? PPC::RLWIMI : PPC::RLWIMI_rec);986    TmpInst.addOperand(Inst.getOperand(0));987    TmpInst.addOperand(Inst.getOperand(0));988    TmpInst.addOperand(Inst.getOperand(1));989    TmpInst.addOperand(MCOperand::createImm(32 - B));990    TmpInst.addOperand(MCOperand::createImm(B));991    TmpInst.addOperand(MCOperand::createImm((B + N) - 1));992    Inst = TmpInst;993    break;994  }995  case PPC::INSRWI:996  case PPC::INSRWI_rec: {997    MCInst TmpInst;998    int64_t N = Inst.getOperand(2).getImm();999    int64_t B = Inst.getOperand(3).getImm();1000    TmpInst.setOpcode(Opcode == PPC::INSRWI ? PPC::RLWIMI : PPC::RLWIMI_rec);1001    TmpInst.addOperand(Inst.getOperand(0));1002    TmpInst.addOperand(Inst.getOperand(0));1003    TmpInst.addOperand(Inst.getOperand(1));1004    TmpInst.addOperand(MCOperand::createImm(32 - (B + N)));1005    TmpInst.addOperand(MCOperand::createImm(B));1006    TmpInst.addOperand(MCOperand::createImm((B + N) - 1));1007    Inst = TmpInst;1008    break;1009  }1010  case PPC::ROTRWI:1011  case PPC::ROTRWI_rec: {1012    MCInst TmpInst;1013    int64_t N = Inst.getOperand(2).getImm();1014    TmpInst.setOpcode(Opcode == PPC::ROTRWI ? PPC::RLWINM : PPC::RLWINM_rec);1015    TmpInst.addOperand(Inst.getOperand(0));1016    TmpInst.addOperand(Inst.getOperand(1));1017    TmpInst.addOperand(MCOperand::createImm(32 - N));1018    TmpInst.addOperand(MCOperand::createImm(0));1019    TmpInst.addOperand(MCOperand::createImm(31));1020    Inst = TmpInst;1021    break;1022  }1023  case PPC::SLWI:1024  case PPC::SLWI_rec: {1025    MCInst TmpInst;1026    int64_t N = Inst.getOperand(2).getImm();1027    TmpInst.setOpcode(Opcode == PPC::SLWI ? PPC::RLWINM : PPC::RLWINM_rec);1028    TmpInst.addOperand(Inst.getOperand(0));1029    TmpInst.addOperand(Inst.getOperand(1));1030    TmpInst.addOperand(MCOperand::createImm(N));1031    TmpInst.addOperand(MCOperand::createImm(0));1032    TmpInst.addOperand(MCOperand::createImm(31 - N));1033    Inst = TmpInst;1034    break;1035  }1036  case PPC::SRWI:1037  case PPC::SRWI_rec: {1038    MCInst TmpInst;1039    int64_t N = Inst.getOperand(2).getImm();1040    TmpInst.setOpcode(Opcode == PPC::SRWI ? PPC::RLWINM : PPC::RLWINM_rec);1041    TmpInst.addOperand(Inst.getOperand(0));1042    TmpInst.addOperand(Inst.getOperand(1));1043    TmpInst.addOperand(MCOperand::createImm(32 - N));1044    TmpInst.addOperand(MCOperand::createImm(N));1045    TmpInst.addOperand(MCOperand::createImm(31));1046    Inst = TmpInst;1047    break;1048  }1049  case PPC::CLRRWI:1050  case PPC::CLRRWI_rec: {1051    MCInst TmpInst;1052    int64_t N = Inst.getOperand(2).getImm();1053    TmpInst.setOpcode(Opcode == PPC::CLRRWI ? PPC::RLWINM : PPC::RLWINM_rec);1054    TmpInst.addOperand(Inst.getOperand(0));1055    TmpInst.addOperand(Inst.getOperand(1));1056    TmpInst.addOperand(MCOperand::createImm(0));1057    TmpInst.addOperand(MCOperand::createImm(0));1058    TmpInst.addOperand(MCOperand::createImm(31 - N));1059    Inst = TmpInst;1060    break;1061  }1062  case PPC::CLRLSLWI:1063  case PPC::CLRLSLWI_rec: {1064    MCInst TmpInst;1065    int64_t B = Inst.getOperand(2).getImm();1066    int64_t N = Inst.getOperand(3).getImm();1067    TmpInst.setOpcode(Opcode == PPC::CLRLSLWI ? PPC::RLWINM : PPC::RLWINM_rec);1068    TmpInst.addOperand(Inst.getOperand(0));1069    TmpInst.addOperand(Inst.getOperand(1));1070    TmpInst.addOperand(MCOperand::createImm(N));1071    TmpInst.addOperand(MCOperand::createImm(B - N));1072    TmpInst.addOperand(MCOperand::createImm(31 - N));1073    Inst = TmpInst;1074    break;1075  }1076  case PPC::EXTLDI:1077  case PPC::EXTLDI_rec: {1078    MCInst TmpInst;1079    int64_t N = Inst.getOperand(2).getImm();1080    int64_t B = Inst.getOperand(3).getImm();1081    TmpInst.setOpcode(Opcode == PPC::EXTLDI ? PPC::RLDICR : PPC::RLDICR_rec);1082    TmpInst.addOperand(Inst.getOperand(0));1083    TmpInst.addOperand(Inst.getOperand(1));1084    TmpInst.addOperand(MCOperand::createImm(B));1085    TmpInst.addOperand(MCOperand::createImm(N - 1));1086    Inst = TmpInst;1087    break;1088  }1089  case PPC::EXTRDI:1090  case PPC::EXTRDI_rec: {1091    MCInst TmpInst;1092    int64_t N = Inst.getOperand(2).getImm();1093    int64_t B = Inst.getOperand(3).getImm();1094    TmpInst.setOpcode(Opcode == PPC::EXTRDI ? PPC::RLDICL : PPC::RLDICL_rec);1095    TmpInst.addOperand(Inst.getOperand(0));1096    TmpInst.addOperand(Inst.getOperand(1));1097    TmpInst.addOperand(MCOperand::createImm(B + N));1098    TmpInst.addOperand(MCOperand::createImm(64 - N));1099    Inst = TmpInst;1100    break;1101  }1102  case PPC::INSRDI:1103  case PPC::INSRDI_rec: {1104    MCInst TmpInst;1105    int64_t N = Inst.getOperand(2).getImm();1106    int64_t B = Inst.getOperand(3).getImm();1107    TmpInst.setOpcode(Opcode == PPC::INSRDI ? PPC::RLDIMI : PPC::RLDIMI_rec);1108    TmpInst.addOperand(Inst.getOperand(0));1109    TmpInst.addOperand(Inst.getOperand(0));1110    TmpInst.addOperand(Inst.getOperand(1));1111    TmpInst.addOperand(MCOperand::createImm(64 - (B + N)));1112    TmpInst.addOperand(MCOperand::createImm(B));1113    Inst = TmpInst;1114    break;1115  }1116  case PPC::ROTRDI:1117  case PPC::ROTRDI_rec: {1118    MCInst TmpInst;1119    int64_t N = Inst.getOperand(2).getImm();1120    TmpInst.setOpcode(Opcode == PPC::ROTRDI ? PPC::RLDICL : PPC::RLDICL_rec);1121    TmpInst.addOperand(Inst.getOperand(0));1122    TmpInst.addOperand(Inst.getOperand(1));1123    TmpInst.addOperand(MCOperand::createImm(64 - N));1124    TmpInst.addOperand(MCOperand::createImm(0));1125    Inst = TmpInst;1126    break;1127  }1128  case PPC::SLDI:1129  case PPC::SLDI_rec: {1130    MCInst TmpInst;1131    int64_t N = Inst.getOperand(2).getImm();1132    TmpInst.setOpcode(Opcode == PPC::SLDI ? PPC::RLDICR : PPC::RLDICR_rec);1133    TmpInst.addOperand(Inst.getOperand(0));1134    TmpInst.addOperand(Inst.getOperand(1));1135    TmpInst.addOperand(MCOperand::createImm(N));1136    TmpInst.addOperand(MCOperand::createImm(63 - N));1137    Inst = TmpInst;1138    break;1139  }1140  case PPC::SUBPCIS: {1141    MCInst TmpInst;1142    int64_t N = Inst.getOperand(1).getImm();1143    TmpInst.setOpcode(PPC::ADDPCIS);1144    TmpInst.addOperand(Inst.getOperand(0));1145    TmpInst.addOperand(MCOperand::createImm(-N));1146    Inst = TmpInst;1147    break;1148  }1149  case PPC::SRDI:1150  case PPC::SRDI_rec: {1151    MCInst TmpInst;1152    int64_t N = Inst.getOperand(2).getImm();1153    TmpInst.setOpcode(Opcode == PPC::SRDI ? PPC::RLDICL : PPC::RLDICL_rec);1154    TmpInst.addOperand(Inst.getOperand(0));1155    TmpInst.addOperand(Inst.getOperand(1));1156    TmpInst.addOperand(MCOperand::createImm(64 - N));1157    TmpInst.addOperand(MCOperand::createImm(N));1158    Inst = TmpInst;1159    break;1160  }1161  case PPC::CLRRDI:1162  case PPC::CLRRDI_rec: {1163    MCInst TmpInst;1164    int64_t N = Inst.getOperand(2).getImm();1165    TmpInst.setOpcode(Opcode == PPC::CLRRDI ? PPC::RLDICR : PPC::RLDICR_rec);1166    TmpInst.addOperand(Inst.getOperand(0));1167    TmpInst.addOperand(Inst.getOperand(1));1168    TmpInst.addOperand(MCOperand::createImm(0));1169    TmpInst.addOperand(MCOperand::createImm(63 - N));1170    Inst = TmpInst;1171    break;1172  }1173  case PPC::CLRLSLDI:1174  case PPC::CLRLSLDI_rec: {1175    MCInst TmpInst;1176    int64_t B = Inst.getOperand(2).getImm();1177    int64_t N = Inst.getOperand(3).getImm();1178    TmpInst.setOpcode(Opcode == PPC::CLRLSLDI ? PPC::RLDIC : PPC::RLDIC_rec);1179    TmpInst.addOperand(Inst.getOperand(0));1180    TmpInst.addOperand(Inst.getOperand(1));1181    TmpInst.addOperand(MCOperand::createImm(N));1182    TmpInst.addOperand(MCOperand::createImm(B - N));1183    Inst = TmpInst;1184    break;1185  }1186  case PPC::RLWINMbm:1187  case PPC::RLWINMbm_rec: {1188    unsigned MB, ME;1189    int64_t BM = Inst.getOperand(3).getImm();1190    if (!isRunOfOnes(BM, MB, ME))1191      break;1192 1193    MCInst TmpInst;1194    TmpInst.setOpcode(Opcode == PPC::RLWINMbm ? PPC::RLWINM : PPC::RLWINM_rec);1195    TmpInst.addOperand(Inst.getOperand(0));1196    TmpInst.addOperand(Inst.getOperand(1));1197    TmpInst.addOperand(Inst.getOperand(2));1198    TmpInst.addOperand(MCOperand::createImm(MB));1199    TmpInst.addOperand(MCOperand::createImm(ME));1200    Inst = TmpInst;1201    break;1202  }1203  case PPC::RLWIMIbm:1204  case PPC::RLWIMIbm_rec: {1205    unsigned MB, ME;1206    int64_t BM = Inst.getOperand(3).getImm();1207    if (!isRunOfOnes(BM, MB, ME))1208      break;1209 1210    MCInst TmpInst;1211    TmpInst.setOpcode(Opcode == PPC::RLWIMIbm ? PPC::RLWIMI : PPC::RLWIMI_rec);1212    TmpInst.addOperand(Inst.getOperand(0));1213    TmpInst.addOperand(Inst.getOperand(0)); // The tied operand.1214    TmpInst.addOperand(Inst.getOperand(1));1215    TmpInst.addOperand(Inst.getOperand(2));1216    TmpInst.addOperand(MCOperand::createImm(MB));1217    TmpInst.addOperand(MCOperand::createImm(ME));1218    Inst = TmpInst;1219    break;1220  }1221  case PPC::RLWNMbm:1222  case PPC::RLWNMbm_rec: {1223    unsigned MB, ME;1224    int64_t BM = Inst.getOperand(3).getImm();1225    if (!isRunOfOnes(BM, MB, ME))1226      break;1227 1228    MCInst TmpInst;1229    TmpInst.setOpcode(Opcode == PPC::RLWNMbm ? PPC::RLWNM : PPC::RLWNM_rec);1230    TmpInst.addOperand(Inst.getOperand(0));1231    TmpInst.addOperand(Inst.getOperand(1));1232    TmpInst.addOperand(Inst.getOperand(2));1233    TmpInst.addOperand(MCOperand::createImm(MB));1234    TmpInst.addOperand(MCOperand::createImm(ME));1235    Inst = TmpInst;1236    break;1237  }1238  case PPC::MFTB: {1239    if (getSTI().hasFeature(PPC::FeatureMFTB)) {1240      assert(Inst.getNumOperands() == 2 && "Expecting two operands");1241      Inst.setOpcode(PPC::MFSPR);1242    }1243    break;1244  }1245  }1246}1247 1248static std::string PPCMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,1249                                         unsigned VariantID = 0);1250 1251// Check that the register+immediate memory operand is in the right position and1252// is expected by the instruction. Returns true if the memory operand syntax is1253// valid; otherwise, returns false.1254static bool validateMemOp(const OperandVector &Operands, bool isMemriOp) {1255  for (size_t idx = 0; idx < Operands.size(); ++idx) {1256    const PPCOperand &Op = static_cast<const PPCOperand &>(*Operands[idx]);1257    if (Op.isMemOpBase() != (idx == 3 && isMemriOp))1258      return false;1259  }1260  return true;1261}1262 1263bool PPCAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,1264                                           OperandVector &Operands,1265                                           MCStreamer &Out, uint64_t &ErrorInfo,1266                                           bool MatchingInlineAsm) {1267  MCInst Inst;1268  const PPCInstrInfo *TII = static_cast<const PPCInstrInfo *>(&MII);1269 1270  switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) {1271  case Match_Success:1272    if (!validateMemOp(Operands, TII->isMemriOp(Inst.getOpcode())))1273      return Error(IDLoc, "invalid operand for instruction");1274    // Post-process instructions (typically extended mnemonics)1275    processInstruction(Inst, Operands);1276    Inst.setLoc(IDLoc);1277    Out.emitInstruction(Inst, getSTI());1278    return false;1279  case Match_MissingFeature:1280    return Error(IDLoc, "instruction use requires an option to be enabled");1281  case Match_MnemonicFail: {1282    FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());1283    std::string Suggestion = PPCMnemonicSpellCheck(1284        ((PPCOperand &)*Operands[0]).getToken(), FBS);1285    return Error(IDLoc, "invalid instruction" + Suggestion,1286                 ((PPCOperand &)*Operands[0]).getLocRange());1287  }1288  case Match_InvalidOperand: {1289    SMLoc ErrorLoc = IDLoc;1290    if (ErrorInfo != ~0ULL) {1291      if (ErrorInfo >= Operands.size())1292        return Error(IDLoc, "too few operands for instruction");1293 1294      ErrorLoc = ((PPCOperand &)*Operands[ErrorInfo]).getStartLoc();1295      if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;1296    }1297 1298    return Error(ErrorLoc, "invalid operand for instruction");1299  }1300  }1301 1302  llvm_unreachable("Implement any new match types added!");1303}1304 1305#define GET_REGISTER_MATCHER1306#include "PPCGenAsmMatcher.inc"1307 1308MCRegister PPCAsmParser::matchRegisterName(int64_t &IntVal) {1309  if (getParser().getTok().is(AsmToken::Percent))1310    getParser().Lex(); // Eat the '%'.1311 1312  if (!getParser().getTok().is(AsmToken::Identifier))1313    return MCRegister();1314 1315  // MatchRegisterName() expects lower-case registers, but we want to support1316  // case-insensitive spelling.1317  std::string NameBuf = getParser().getTok().getString().lower();1318  StringRef Name(NameBuf);1319  MCRegister RegNo = MatchRegisterName(Name);1320  if (!RegNo)1321    return RegNo;1322 1323  Name.substr(Name.find_first_of("1234567890")).getAsInteger(10, IntVal);1324 1325  // MatchRegisterName doesn't seem to have special handling for 64bit vs 32bit1326  // register types.1327  if (Name == "lr") {1328    RegNo = isPPC64() ? PPC::LR8 : PPC::LR;1329    IntVal = 8;1330  } else if (Name == "ctr") {1331    RegNo = isPPC64() ? PPC::CTR8 : PPC::CTR;1332    IntVal = 9;1333  } else if (Name == "vrsave")1334    IntVal = 256;1335  else if (Name.starts_with("r"))1336    RegNo = isPPC64() ? XRegs[IntVal] : RRegs[IntVal];1337 1338  getParser().Lex();1339  return RegNo;1340}1341 1342bool PPCAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,1343                                 SMLoc &EndLoc) {1344  if (!tryParseRegister(Reg, StartLoc, EndLoc).isSuccess())1345    return TokError("invalid register name");1346  return false;1347}1348 1349ParseStatus PPCAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,1350                                           SMLoc &EndLoc) {1351  const AsmToken &Tok = getParser().getTok();1352  StartLoc = Tok.getLoc();1353  EndLoc = Tok.getEndLoc();1354  int64_t IntVal;1355  if (!(Reg = matchRegisterName(IntVal)))1356    return ParseStatus::NoMatch;1357  return ParseStatus::Success;1358}1359 1360// Extract the @l or @ha specifier from the expression, returning a modified1361// expression with the specifier removed. Stores the extracted specifier in1362// `Spec`. Reports an error if multiple specifiers are detected.1363const MCExpr *PPCAsmParser::extractSpecifier(const MCExpr *E,1364                                             PPCMCExpr::Specifier &Spec) {1365  MCContext &Context = getParser().getContext();1366  switch (E->getKind()) {1367  case MCExpr::Constant:1368    break;1369  case MCExpr::Specifier: {1370    // Detect error but do not return a modified expression.1371    auto *TE = cast<MCSpecifierExpr>(E);1372    Spec = TE->getSpecifier();1373    (void)extractSpecifier(TE->getSubExpr(), Spec);1374    Spec = PPC::S_None;1375  } break;1376 1377  case MCExpr::SymbolRef: {1378    const auto *SRE = cast<MCSymbolRefExpr>(E);1379    switch (getSpecifier(SRE)) {1380    case PPC::S_None:1381    default:1382      break;1383    case PPC::S_LO:1384    case PPC::S_HI:1385    case PPC::S_HA:1386    case PPC::S_HIGH:1387    case PPC::S_HIGHA:1388    case PPC::S_HIGHER:1389    case PPC::S_HIGHERA:1390    case PPC::S_HIGHEST:1391    case PPC::S_HIGHESTA:1392      if (Spec == PPC::S_None)1393        Spec = getSpecifier(SRE);1394      else1395        Error(E->getLoc(), "cannot contain more than one relocation specifier");1396      return MCSymbolRefExpr::create(&SRE->getSymbol(), Context);1397    }1398    break;1399  }1400 1401  case MCExpr::Unary: {1402    const MCUnaryExpr *UE = cast<MCUnaryExpr>(E);1403    const MCExpr *Sub = extractSpecifier(UE->getSubExpr(), Spec);1404    if (Spec != PPC::S_None)1405      return MCUnaryExpr::create(UE->getOpcode(), Sub, Context);1406    break;1407  }1408 1409  case MCExpr::Binary: {1410    const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);1411    const MCExpr *LHS = extractSpecifier(BE->getLHS(), Spec);1412    const MCExpr *RHS = extractSpecifier(BE->getRHS(), Spec);1413    if (Spec != PPC::S_None)1414      return MCBinaryExpr::create(BE->getOpcode(), LHS, RHS, Context);1415    break;1416  }1417  case MCExpr::Target:1418    llvm_unreachable("unused by this backend");1419  }1420 1421  return E;1422}1423 1424/// This differs from the default "parseExpression" in that it handles1425/// specifiers.1426bool PPCAsmParser::parseExpression(const MCExpr *&EVal) {1427  // (ELF Platforms)1428  // Handle \code @l/@ha \endcode1429  if (getParser().parseExpression(EVal))1430    return true;1431 1432  uint16_t Spec = PPC::S_None;1433  const MCExpr *E = extractSpecifier(EVal, Spec);1434  if (Spec != PPC::S_None)1435    EVal = MCSpecifierExpr::create(E, Spec, getParser().getContext());1436 1437  return false;1438}1439 1440/// This handles registers in the form 'NN', '%rNN' for ELF platforms and1441/// rNN for MachO.1442bool PPCAsmParser::parseOperand(OperandVector &Operands) {1443  MCAsmParser &Parser = getParser();1444  SMLoc S = Parser.getTok().getLoc();1445  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);1446  const MCExpr *EVal;1447 1448  // Attempt to parse the next token as an immediate1449  switch (getLexer().getKind()) {1450  // Special handling for register names.  These are interpreted1451  // as immediates corresponding to the register number.1452  case AsmToken::Percent: {1453    int64_t IntVal;1454    if (!matchRegisterName(IntVal))1455      return Error(S, "invalid register name");1456 1457    Operands.push_back(PPCOperand::CreateImm(IntVal, S, E, isPPC64()));1458    return false;1459  }1460  case AsmToken::Identifier:1461  case AsmToken::LParen:1462  case AsmToken::Plus:1463  case AsmToken::Minus:1464  case AsmToken::Integer:1465  case AsmToken::Dot:1466  case AsmToken::Dollar:1467  case AsmToken::Exclaim:1468  case AsmToken::Tilde:1469    if (!parseExpression(EVal))1470      break;1471    // Fall-through1472    [[fallthrough]];1473  default:1474    return Error(S, "unknown operand");1475  }1476 1477  // Push the parsed operand into the list of operands1478  Operands.push_back(PPCOperand::CreateFromMCExpr(EVal, S, E, isPPC64()));1479 1480  // Check whether this is a TLS call expression1481  const char TlsGetAddr[] = "__tls_get_addr";1482  bool TlsCall = false;1483  const MCExpr *TlsCallAddend = nullptr;1484  if (auto *Ref = dyn_cast<MCSymbolRefExpr>(EVal)) {1485    TlsCall = Ref->getSymbol().getName() == TlsGetAddr;1486  } else if (auto *Bin = dyn_cast<MCBinaryExpr>(EVal);1487             Bin && Bin->getOpcode() == MCBinaryExpr::Add) {1488    if (auto *Ref = dyn_cast<MCSymbolRefExpr>(Bin->getLHS())) {1489      TlsCall = Ref->getSymbol().getName() == TlsGetAddr;1490      TlsCallAddend = Bin->getRHS();1491    }1492  }1493 1494  if (TlsCall && parseOptionalToken(AsmToken::LParen)) {1495    const MCExpr *TLSSym;1496    const SMLoc S2 = Parser.getTok().getLoc();1497    if (parseExpression(TLSSym))1498      return Error(S2, "invalid TLS call expression");1499    E = Parser.getTok().getLoc();1500    if (parseToken(AsmToken::RParen, "expected ')'"))1501      return true;1502    // PPC32 allows bl __tls_get_addr[+a](x@tlsgd)@plt+b. Parse "@plt[+b]".1503    if (!isPPC64() && parseOptionalToken(AsmToken::At)) {1504      AsmToken Tok = getTok();1505      if (!(parseOptionalToken(AsmToken::Identifier) &&1506            Tok.getString().compare_insensitive("plt") == 0))1507        return Error(Tok.getLoc(), "expected 'plt'");1508      EVal = MCSymbolRefExpr::create(getContext().getOrCreateSymbol(TlsGetAddr),1509                                     PPC::S_PLT, getContext());1510      if (parseOptionalToken(AsmToken::Plus)) {1511        const MCExpr *Addend = nullptr;1512        SMLoc EndLoc;1513        if (parsePrimaryExpr(Addend, EndLoc))1514          return true;1515        if (TlsCallAddend) // __tls_get_addr+a(x@tlsgd)@plt+b1516          TlsCallAddend =1517              MCBinaryExpr::createAdd(TlsCallAddend, Addend, getContext());1518        else // __tls_get_addr(x@tlsgd)@plt+b1519          TlsCallAddend = Addend;1520      }1521      if (TlsCallAddend)1522        EVal = MCBinaryExpr::createAdd(EVal, TlsCallAddend, getContext());1523      // Add a __tls_get_addr operand with addend a, b, or a+b.1524      Operands.back() = PPCOperand::CreateFromMCExpr(1525          EVal, S, Parser.getTok().getLoc(), false);1526    }1527 1528    Operands.push_back(PPCOperand::CreateFromMCExpr(TLSSym, S, E, isPPC64()));1529  }1530 1531  // Otherwise, check for D-form memory operands1532  if (!TlsCall && parseOptionalToken(AsmToken::LParen)) {1533    S = Parser.getTok().getLoc();1534 1535    int64_t IntVal;1536    switch (getLexer().getKind()) {1537    case AsmToken::Percent: {1538      if (!matchRegisterName(IntVal))1539        return Error(S, "invalid register name");1540      break;1541    }1542    case AsmToken::Integer:1543      if (getParser().parseAbsoluteExpression(IntVal) || IntVal < 0 ||1544          IntVal > 31)1545        return Error(S, "invalid register number");1546      break;1547    case AsmToken::Identifier:1548    default:1549      return Error(S, "invalid memory operand");1550    }1551 1552    E = Parser.getTok().getLoc();1553    if (parseToken(AsmToken::RParen, "missing ')'"))1554      return true;1555    Operands.push_back(1556        PPCOperand::CreateImm(IntVal, S, E, isPPC64(), /*IsMemOpBase=*/true));1557  }1558 1559  return false;1560}1561 1562/// Parse an instruction mnemonic followed by its operands.1563bool PPCAsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,1564                                    SMLoc NameLoc, OperandVector &Operands) {1565  // The first operand is the token for the instruction name.1566  // If the next character is a '+' or '-', we need to add it to the1567  // instruction name, to match what TableGen is doing.1568  std::string NewOpcode;1569  if (parseOptionalToken(AsmToken::Plus)) {1570    NewOpcode = std::string(Name);1571    NewOpcode += '+';1572    Name = NewOpcode;1573  }1574  if (parseOptionalToken(AsmToken::Minus)) {1575    NewOpcode = std::string(Name);1576    NewOpcode += '-';1577    Name = NewOpcode;1578  }1579  // If the instruction ends in a '.', we need to create a separate1580  // token for it, to match what TableGen is doing.1581  size_t Dot = Name.find('.');1582  StringRef Mnemonic = Name.slice(0, Dot);1583  if (!NewOpcode.empty()) // Underlying memory for Name is volatile.1584    Operands.push_back(1585        PPCOperand::CreateTokenWithStringCopy(Mnemonic, NameLoc, isPPC64()));1586  else1587    Operands.push_back(PPCOperand::CreateToken(Mnemonic, NameLoc, isPPC64()));1588  if (Dot != StringRef::npos) {1589    SMLoc DotLoc = SMLoc::getFromPointer(NameLoc.getPointer() + Dot);1590    StringRef DotStr = Name.substr(Dot);1591    if (!NewOpcode.empty()) // Underlying memory for Name is volatile.1592      Operands.push_back(1593          PPCOperand::CreateTokenWithStringCopy(DotStr, DotLoc, isPPC64()));1594    else1595      Operands.push_back(PPCOperand::CreateToken(DotStr, DotLoc, isPPC64()));1596  }1597 1598  // If there are no more operands then finish1599  if (parseOptionalToken(AsmToken::EndOfStatement))1600    return false;1601 1602  // Parse the first operand1603  if (parseOperand(Operands))1604    return true;1605 1606  while (!parseOptionalToken(AsmToken::EndOfStatement)) {1607    if (parseToken(AsmToken::Comma) || parseOperand(Operands))1608      return true;1609  }1610 1611  // We'll now deal with an unfortunate special case: the syntax for the dcbt1612  // and dcbtst instructions differs for server vs. embedded cores.1613  //  The syntax for dcbt is:1614  //    dcbt ra, rb, th [server]1615  //    dcbt th, ra, rb [embedded]1616  //  where th can be omitted when it is 0. dcbtst is the same. We take the1617  //  server form to be the default, so swap the operands if we're parsing for1618  //  an embedded core (they'll be swapped again upon printing).1619  if (getSTI().hasFeature(PPC::FeatureBookE) &&1620      Operands.size() == 4 &&1621      (Name == "dcbt" || Name == "dcbtst")) {1622    std::swap(Operands[1], Operands[3]);1623    std::swap(Operands[2], Operands[1]);1624  }1625 1626  // Handle base mnemonic for atomic loads where the EH bit is zero.1627  if (Name == "lqarx" || Name == "ldarx" || Name == "lwarx" ||1628      Name == "lharx" || Name == "lbarx") {1629    if (Operands.size() != 5)1630      return false;1631    PPCOperand &EHOp = (PPCOperand &)*Operands[4];1632    if (EHOp.isUImm<1>() && EHOp.getImm() == 0)1633      Operands.pop_back();1634  }1635 1636  return false;1637}1638 1639/// Parses the PPC specific directives1640bool PPCAsmParser::ParseDirective(AsmToken DirectiveID) {1641  StringRef IDVal = DirectiveID.getIdentifier();1642  if (IDVal == ".word")1643    parseDirectiveWord(2, DirectiveID);1644  else if (IDVal == ".llong")1645    parseDirectiveWord(8, DirectiveID);1646  else if (IDVal == ".tc")1647    parseDirectiveTC(isPPC64() ? 8 : 4, DirectiveID);1648  else if (IDVal == ".machine")1649    parseDirectiveMachine(DirectiveID.getLoc());1650  else if (IDVal == ".abiversion")1651    parseDirectiveAbiVersion(DirectiveID.getLoc());1652  else if (IDVal == ".localentry")1653    parseDirectiveLocalEntry(DirectiveID.getLoc());1654  else if (IDVal.starts_with(".gnu_attribute"))1655    parseGNUAttribute(DirectiveID.getLoc());1656  else1657    return true;1658  return false;1659}1660 1661///  ::= .word [ expression (, expression)* ]1662bool PPCAsmParser::parseDirectiveWord(unsigned Size, AsmToken ID) {1663  auto parseOp = [&]() -> bool {1664    const MCExpr *Value;1665    SMLoc ExprLoc = getParser().getTok().getLoc();1666    if (getParser().parseExpression(Value))1667      return true;1668    if (const auto *MCE = dyn_cast<MCConstantExpr>(Value)) {1669      assert(Size <= 8 && "Invalid size");1670      uint64_t IntValue = MCE->getValue();1671      if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue))1672        return Error(ExprLoc, "literal value out of range for '" +1673                                  ID.getIdentifier() + "' directive");1674      getStreamer().emitIntValue(IntValue, Size);1675    } else1676      getStreamer().emitValue(Value, Size, ExprLoc);1677    return false;1678  };1679 1680  if (parseMany(parseOp))1681    return addErrorSuffix(" in '" + ID.getIdentifier() + "' directive");1682  return false;1683}1684 1685///  ::= .tc [ symbol (, expression)* ]1686bool PPCAsmParser::parseDirectiveTC(unsigned Size, AsmToken ID) {1687  MCAsmParser &Parser = getParser();1688  // Skip TC symbol, which is only used with XCOFF.1689  while (getLexer().isNot(AsmToken::EndOfStatement)1690         && getLexer().isNot(AsmToken::Comma))1691    Parser.Lex();1692  if (parseToken(AsmToken::Comma))1693    return addErrorSuffix(" in '.tc' directive");1694 1695  // Align to word size.1696  getParser().getStreamer().emitValueToAlignment(Align(Size));1697 1698  // Emit expressions.1699  return parseDirectiveWord(Size, ID);1700}1701 1702/// ELF platforms.1703///  ::= .machine [ cpu | "push" | "pop" ]1704bool PPCAsmParser::parseDirectiveMachine(SMLoc L) {1705  MCAsmParser &Parser = getParser();1706  if (Parser.getTok().isNot(AsmToken::Identifier) &&1707      Parser.getTok().isNot(AsmToken::String))1708    return Error(L, "unexpected token in '.machine' directive");1709 1710  StringRef CPU = Parser.getTok().getIdentifier();1711 1712  // FIXME: Right now, the parser always allows any available1713  // instruction, so the .machine directive is not useful.1714  // In the wild, any/push/pop/ppc64/altivec/power[4-9] are seen.1715 1716  Parser.Lex();1717 1718  if (parseToken(AsmToken::EndOfStatement))1719    return addErrorSuffix(" in '.machine' directive");1720 1721  PPCTargetStreamer *TStreamer = static_cast<PPCTargetStreamer *>(1722      getParser().getStreamer().getTargetStreamer());1723  if (TStreamer != nullptr)1724    TStreamer->emitMachine(CPU);1725 1726  return false;1727}1728 1729///  ::= .abiversion constant-expression1730bool PPCAsmParser::parseDirectiveAbiVersion(SMLoc L) {1731  int64_t AbiVersion;1732  if (check(getParser().parseAbsoluteExpression(AbiVersion), L,1733            "expected constant expression") ||1734      parseToken(AsmToken::EndOfStatement))1735    return addErrorSuffix(" in '.abiversion' directive");1736 1737  PPCTargetStreamer *TStreamer = static_cast<PPCTargetStreamer *>(1738      getParser().getStreamer().getTargetStreamer());1739  if (TStreamer != nullptr)1740    TStreamer->emitAbiVersion(AbiVersion);1741 1742  return false;1743}1744 1745///  ::= .localentry symbol, expression1746bool PPCAsmParser::parseDirectiveLocalEntry(SMLoc L) {1747  StringRef Name;1748  if (getParser().parseIdentifier(Name))1749    return Error(L, "expected identifier in '.localentry' directive");1750 1751  auto *Sym = static_cast<MCSymbolELF *>(getContext().getOrCreateSymbol(Name));1752  const MCExpr *Expr;1753 1754  if (parseToken(AsmToken::Comma) ||1755      check(getParser().parseExpression(Expr), L, "expected expression") ||1756      parseToken(AsmToken::EndOfStatement))1757    return addErrorSuffix(" in '.localentry' directive");1758 1759  PPCTargetStreamer *TStreamer = static_cast<PPCTargetStreamer *>(1760      getParser().getStreamer().getTargetStreamer());1761  if (TStreamer != nullptr)1762    TStreamer->emitLocalEntry(Sym, Expr);1763 1764  return false;1765}1766 1767bool PPCAsmParser::parseGNUAttribute(SMLoc L) {1768  int64_t Tag;1769  int64_t IntegerValue;1770  if (!getParser().parseGNUAttribute(L, Tag, IntegerValue))1771    return false;1772 1773  getParser().getStreamer().emitGNUAttribute(Tag, IntegerValue);1774 1775  return true;1776}1777 1778/// Force static initialization.1779extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void1780LLVMInitializePowerPCAsmParser() {1781  RegisterMCAsmParser<PPCAsmParser> A(getThePPC32Target());1782  RegisterMCAsmParser<PPCAsmParser> B(getThePPC32LETarget());1783  RegisterMCAsmParser<PPCAsmParser> C(getThePPC64Target());1784  RegisterMCAsmParser<PPCAsmParser> D(getThePPC64LETarget());1785}1786 1787#define GET_MATCHER_IMPLEMENTATION1788#define GET_MNEMONIC_SPELL_CHECKER1789#include "PPCGenAsmMatcher.inc"1790 1791// Define this matcher function after the auto-generated include so we1792// have the match class enum definitions.1793unsigned PPCAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,1794                                                  unsigned Kind) {1795  // If the kind is a token for a literal immediate, check if our asm1796  // operand matches. This is for InstAliases which have a fixed-value1797  // immediate in the syntax.1798  int64_t ImmVal;1799  switch (Kind) {1800    case MCK_0: ImmVal = 0; break;1801    case MCK_1: ImmVal = 1; break;1802    case MCK_2: ImmVal = 2; break;1803    case MCK_3: ImmVal = 3; break;1804    case MCK_4: ImmVal = 4; break;1805    case MCK_5: ImmVal = 5; break;1806    case MCK_6: ImmVal = 6; break;1807    case MCK_7: ImmVal = 7; break;1808    default: return Match_InvalidOperand;1809  }1810 1811  PPCOperand &Op = static_cast<PPCOperand &>(AsmOp);1812  if (Op.isUImm<3>() && Op.getImm() == ImmVal)1813    return Match_Success;1814 1815  return Match_InvalidOperand;1816}1817 1818const MCExpr *PPCAsmParser::applySpecifier(const MCExpr *E, uint32_t Spec,1819                                           MCContext &Ctx) {1820  if (isa<MCConstantExpr>(E)) {1821    switch (PPCMCExpr::Specifier(Spec)) {1822    case PPC::S_LO:1823    case PPC::S_HI:1824    case PPC::S_HA:1825    case PPC::S_HIGH:1826    case PPC::S_HIGHA:1827    case PPC::S_HIGHER:1828    case PPC::S_HIGHERA:1829    case PPC::S_HIGHEST:1830    case PPC::S_HIGHESTA:1831      break;1832    default:1833      return nullptr;1834    }1835  }1836 1837  return MCSpecifierExpr::create(E, Spec, Ctx);1838}1839