brintos

brintos / llvm-project-archived public Read only

0
0
Text · 56.8 KiB · ef45d31 Raw
1792 lines · cpp
1//===-- SparcAsmParser.cpp - Parse Sparc assembly 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/SparcMCAsmInfo.h"10#include "MCTargetDesc/SparcMCTargetDesc.h"11#include "TargetInfo/SparcTargetInfo.h"12#include "llvm/ADT/SmallVector.h"13#include "llvm/ADT/StringRef.h"14#include "llvm/BinaryFormat/ELF.h"15#include "llvm/MC/MCAsmMacro.h"16#include "llvm/MC/MCContext.h"17#include "llvm/MC/MCExpr.h"18#include "llvm/MC/MCInst.h"19#include "llvm/MC/MCInstBuilder.h"20#include "llvm/MC/MCInstrInfo.h"21#include "llvm/MC/MCObjectFileInfo.h"22#include "llvm/MC/MCParser/AsmLexer.h"23#include "llvm/MC/MCParser/MCAsmParser.h"24#include "llvm/MC/MCParser/MCParsedAsmOperand.h"25#include "llvm/MC/MCParser/MCTargetAsmParser.h"26#include "llvm/MC/MCRegisterInfo.h"27#include "llvm/MC/MCStreamer.h"28#include "llvm/MC/MCSubtargetInfo.h"29#include "llvm/MC/MCSymbol.h"30#include "llvm/MC/TargetRegistry.h"31#include "llvm/Support/Casting.h"32#include "llvm/Support/Compiler.h"33#include "llvm/Support/ErrorHandling.h"34#include "llvm/Support/MathExtras.h"35#include "llvm/Support/SMLoc.h"36#include "llvm/Support/raw_ostream.h"37#include "llvm/TargetParser/Triple.h"38#include <algorithm>39#include <cassert>40#include <cstdint>41#include <memory>42 43using namespace llvm;44 45// The generated AsmMatcher SparcGenAsmMatcher uses "Sparc" as the target46// namespace. But SPARC backend uses "SP" as its namespace.47namespace llvm {48namespace Sparc {49 50    using namespace SP;51 52} // end namespace Sparc53} // end namespace llvm54 55namespace {56 57class SparcOperand;58 59class SparcAsmParser : public MCTargetAsmParser {60  MCAsmParser &Parser;61  const MCRegisterInfo &MRI;62 63  enum class TailRelocKind { Load_GOT, Add_TLS, Load_TLS, Call_TLS };64 65  /// @name Auto-generated Match Functions66  /// {67 68#define GET_ASSEMBLER_HEADER69#include "SparcGenAsmMatcher.inc"70 71  /// }72 73  // public interface of the MCTargetAsmParser.74  bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,75                               OperandVector &Operands, MCStreamer &Out,76                               uint64_t &ErrorInfo,77                               bool MatchingInlineAsm) override;78  bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override;79  ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,80                               SMLoc &EndLoc) override;81  bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,82                        SMLoc NameLoc, OperandVector &Operands) override;83  ParseStatus parseDirective(AsmToken DirectiveID) override;84 85  unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,86                                      unsigned Kind) override;87 88  // Custom parse functions for Sparc specific operands.89  ParseStatus parseMEMOperand(OperandVector &Operands);90 91  ParseStatus parseMembarTag(OperandVector &Operands);92 93  ParseStatus parseASITag(OperandVector &Operands);94 95  ParseStatus parsePrefetchTag(OperandVector &Operands);96 97  template <TailRelocKind Kind>98  ParseStatus parseTailRelocSym(OperandVector &Operands);99 100  template <unsigned N> ParseStatus parseShiftAmtImm(OperandVector &Operands);101 102  ParseStatus parseCallTarget(OperandVector &Operands);103 104  ParseStatus parseOperand(OperandVector &Operands, StringRef Name);105 106  ParseStatus parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Operand);107 108  ParseStatus parseBranchModifiers(OperandVector &Operands);109 110  ParseStatus parseExpression(int64_t &Val);111 112  // Helper function for dealing with %lo / %hi in PIC mode.113  const MCSpecifierExpr *adjustPICRelocation(uint16_t VK,114                                             const MCExpr *subExpr);115 116  // Helper function to see if current token can start an expression.117  bool isPossibleExpression(const AsmToken &Token);118 119  // Check if mnemonic is valid.120  MatchResultTy mnemonicIsValid(StringRef Mnemonic, unsigned VariantID);121 122  // returns true if Tok is matched to a register and returns register in RegNo.123  MCRegister matchRegisterName(const AsmToken &Tok, unsigned &RegKind);124 125  bool matchSparcAsmModifiers(const MCExpr *&EVal, SMLoc &EndLoc);126 127  bool is64Bit() const {128    return getSTI().getTargetTriple().getArch() == Triple::sparcv9;129  }130 131  bool expandSET(MCInst &Inst, SMLoc IDLoc,132                 SmallVectorImpl<MCInst> &Instructions);133 134  bool expandSETSW(MCInst &Inst, SMLoc IDLoc,135                   SmallVectorImpl<MCInst> &Instructions);136 137  bool expandSETX(MCInst &Inst, SMLoc IDLoc,138                  SmallVectorImpl<MCInst> &Instructions);139 140  SMLoc getLoc() const { return getParser().getTok().getLoc(); }141 142public:143  SparcAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,144                 const MCInstrInfo &MII, const MCTargetOptions &Options)145      : MCTargetAsmParser(Options, sti, MII), Parser(parser),146        MRI(*Parser.getContext().getRegisterInfo()) {147    Parser.addAliasForDirective(".half", ".2byte");148    Parser.addAliasForDirective(".uahalf", ".2byte");149    Parser.addAliasForDirective(".word", ".4byte");150    Parser.addAliasForDirective(".uaword", ".4byte");151    Parser.addAliasForDirective(".nword", is64Bit() ? ".8byte" : ".4byte");152    if (is64Bit())153      Parser.addAliasForDirective(".xword", ".8byte");154 155    // Initialize the set of available features.156    setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));157  }158};159 160} // end anonymous namespace161 162  static const MCPhysReg IntRegs[32] = {163    Sparc::G0, Sparc::G1, Sparc::G2, Sparc::G3,164    Sparc::G4, Sparc::G5, Sparc::G6, Sparc::G7,165    Sparc::O0, Sparc::O1, Sparc::O2, Sparc::O3,166    Sparc::O4, Sparc::O5, Sparc::O6, Sparc::O7,167    Sparc::L0, Sparc::L1, Sparc::L2, Sparc::L3,168    Sparc::L4, Sparc::L5, Sparc::L6, Sparc::L7,169    Sparc::I0, Sparc::I1, Sparc::I2, Sparc::I3,170    Sparc::I4, Sparc::I5, Sparc::I6, Sparc::I7 };171 172  static const MCPhysReg DoubleRegs[32] = {173    Sparc::D0,  Sparc::D1,  Sparc::D2,  Sparc::D3,174    Sparc::D4,  Sparc::D5,  Sparc::D6,  Sparc::D7,175    Sparc::D8,  Sparc::D9,  Sparc::D10, Sparc::D11,176    Sparc::D12, Sparc::D13, Sparc::D14, Sparc::D15,177    Sparc::D16, Sparc::D17, Sparc::D18, Sparc::D19,178    Sparc::D20, Sparc::D21, Sparc::D22, Sparc::D23,179    Sparc::D24, Sparc::D25, Sparc::D26, Sparc::D27,180    Sparc::D28, Sparc::D29, Sparc::D30, Sparc::D31 };181 182  static const MCPhysReg QuadFPRegs[32] = {183    Sparc::Q0,  Sparc::Q1,  Sparc::Q2,  Sparc::Q3,184    Sparc::Q4,  Sparc::Q5,  Sparc::Q6,  Sparc::Q7,185    Sparc::Q8,  Sparc::Q9,  Sparc::Q10, Sparc::Q11,186    Sparc::Q12, Sparc::Q13, Sparc::Q14, Sparc::Q15 };187 188  static const MCPhysReg IntPairRegs[] = {189    Sparc::G0_G1, Sparc::G2_G3, Sparc::G4_G5, Sparc::G6_G7,190    Sparc::O0_O1, Sparc::O2_O3, Sparc::O4_O5, Sparc::O6_O7,191    Sparc::L0_L1, Sparc::L2_L3, Sparc::L4_L5, Sparc::L6_L7,192    Sparc::I0_I1, Sparc::I2_I3, Sparc::I4_I5, Sparc::I6_I7};193 194  static const MCPhysReg CoprocPairRegs[] = {195    Sparc::C0_C1,   Sparc::C2_C3,   Sparc::C4_C5,   Sparc::C6_C7,196    Sparc::C8_C9,   Sparc::C10_C11, Sparc::C12_C13, Sparc::C14_C15,197    Sparc::C16_C17, Sparc::C18_C19, Sparc::C20_C21, Sparc::C22_C23,198    Sparc::C24_C25, Sparc::C26_C27, Sparc::C28_C29, Sparc::C30_C31};199 200namespace {201 202/// SparcOperand - Instances of this class represent a parsed Sparc machine203/// instruction.204class SparcOperand : public MCParsedAsmOperand {205public:206  enum RegisterKind {207    rk_None,208    rk_IntReg,209    rk_IntPairReg,210    rk_FloatReg,211    rk_DoubleReg,212    rk_QuadReg,213    rk_CoprocReg,214    rk_CoprocPairReg,215    rk_Special,216  };217 218private:219  enum KindTy {220    k_Token,221    k_Register,222    k_Immediate,223    k_MemoryReg,224    k_MemoryImm,225    k_ASITag,226    k_PrefetchTag,227    k_TailRelocSym, // Special kind of immediate for TLS relocation purposes.228  } Kind;229 230  SMLoc StartLoc, EndLoc;231 232  struct Token {233    const char *Data;234    unsigned Length;235  };236 237  struct RegOp {238    MCRegister Reg;239    RegisterKind Kind;240  };241 242  struct ImmOp {243    const MCExpr *Val;244  };245 246  struct MemOp {247    MCRegister Base;248    MCRegister OffsetReg;249    const MCExpr *Off;250  };251 252  union {253    struct Token Tok;254    struct RegOp Reg;255    struct ImmOp Imm;256    struct MemOp Mem;257    unsigned ASI;258    unsigned Prefetch;259  };260 261public:262  SparcOperand(KindTy K) : Kind(K) {}263 264  bool isToken() const override { return Kind == k_Token; }265  bool isReg() const override { return Kind == k_Register; }266  bool isImm() const override { return Kind == k_Immediate; }267  bool isMem() const override { return isMEMrr() || isMEMri(); }268  bool isMEMrr() const { return Kind == k_MemoryReg; }269  bool isMEMri() const { return Kind == k_MemoryImm; }270  bool isMembarTag() const { return Kind == k_Immediate; }271  bool isASITag() const { return Kind == k_ASITag; }272  bool isPrefetchTag() const { return Kind == k_PrefetchTag; }273  bool isTailRelocSym() const { return Kind == k_TailRelocSym; }274 275  bool isCallTarget() const {276    if (!isImm())277      return false;278 279    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val))280      return CE->getValue() % 4 == 0;281 282    return true;283  }284 285  bool isShiftAmtImm5() const {286    if (!isImm())287      return false;288 289    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val))290      return isUInt<5>(CE->getValue());291 292    return false;293  }294 295  bool isShiftAmtImm6() const {296    if (!isImm())297      return false;298 299    if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val))300      return isUInt<6>(CE->getValue());301 302    return false;303  }304 305  bool isIntReg() const {306    return (Kind == k_Register && Reg.Kind == rk_IntReg);307  }308 309  bool isFloatReg() const {310    return (Kind == k_Register && Reg.Kind == rk_FloatReg);311  }312 313  bool isFloatOrDoubleReg() const {314    return (Kind == k_Register && (Reg.Kind == rk_FloatReg315                                   || Reg.Kind == rk_DoubleReg));316  }317 318  bool isCoprocReg() const {319    return (Kind == k_Register && Reg.Kind == rk_CoprocReg);320  }321 322  StringRef getToken() const {323    assert(Kind == k_Token && "Invalid access!");324    return StringRef(Tok.Data, Tok.Length);325  }326 327  MCRegister getReg() const override {328    assert((Kind == k_Register) && "Invalid access!");329    return Reg.Reg;330  }331 332  const MCExpr *getImm() const {333    assert((Kind == k_Immediate) && "Invalid access!");334    return Imm.Val;335  }336 337  MCRegister getMemBase() const {338    assert((Kind == k_MemoryReg || Kind == k_MemoryImm) && "Invalid access!");339    return Mem.Base;340  }341 342  MCRegister getMemOffsetReg() const {343    assert((Kind == k_MemoryReg) && "Invalid access!");344    return Mem.OffsetReg;345  }346 347  const MCExpr *getMemOff() const {348    assert((Kind == k_MemoryImm) && "Invalid access!");349    return Mem.Off;350  }351 352  unsigned getASITag() const {353    assert((Kind == k_ASITag) && "Invalid access!");354    return ASI;355  }356 357  unsigned getPrefetchTag() const {358    assert((Kind == k_PrefetchTag) && "Invalid access!");359    return Prefetch;360  }361 362  const MCExpr *getTailRelocSym() const {363    assert((Kind == k_TailRelocSym) && "Invalid access!");364    return Imm.Val;365  }366 367  /// getStartLoc - Get the location of the first token of this operand.368  SMLoc getStartLoc() const override {369    return StartLoc;370  }371  /// getEndLoc - Get the location of the last token of this operand.372  SMLoc getEndLoc() const override {373    return EndLoc;374  }375 376  void print(raw_ostream &OS, const MCAsmInfo &MAI) const override {377    switch (Kind) {378    case k_Token:     OS << "Token: " << getToken() << "\n"; break;379    case k_Register:380      OS << "Reg: #" << getReg().id() << "\n";381      break;382    case k_Immediate: OS << "Imm: " << getImm() << "\n"; break;383    case k_MemoryReg:384      OS << "Mem: " << getMemBase().id() << "+" << getMemOffsetReg().id()385         << "\n";386      break;387    case k_MemoryImm: assert(getMemOff() != nullptr);388      OS << "Mem: " << getMemBase().id() << "+";389      MAI.printExpr(OS, *getMemOff());390      OS << "\n";391      break;392    case k_ASITag:393      OS << "ASI tag: " << getASITag() << "\n";394      break;395    case k_PrefetchTag:396      OS << "Prefetch tag: " << getPrefetchTag() << "\n";397      break;398    case k_TailRelocSym:399      OS << "TailReloc: " << getTailRelocSym() << "\n";400      break;401    }402  }403 404  void addRegOperands(MCInst &Inst, unsigned N) const {405    assert(N == 1 && "Invalid number of operands!");406    Inst.addOperand(MCOperand::createReg(getReg()));407  }408 409  void addImmOperands(MCInst &Inst, unsigned N) const {410    assert(N == 1 && "Invalid number of operands!");411    const MCExpr *Expr = getImm();412    addExpr(Inst, Expr);413  }414 415  void addShiftAmtImm5Operands(MCInst &Inst, unsigned N) const {416    assert(N == 1 && "Invalid number of operands!");417    addExpr(Inst, getImm());418  }419  void addShiftAmtImm6Operands(MCInst &Inst, unsigned N) const {420    assert(N == 1 && "Invalid number of operands!");421    addExpr(Inst, getImm());422  }423 424  void addExpr(MCInst &Inst, const MCExpr *Expr) const{425    // Add as immediate when possible.  Null MCExpr = 0.426    if (!Expr)427      Inst.addOperand(MCOperand::createImm(0));428    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))429      Inst.addOperand(MCOperand::createImm(CE->getValue()));430    else431      Inst.addOperand(MCOperand::createExpr(Expr));432  }433 434  void addMEMrrOperands(MCInst &Inst, unsigned N) const {435    assert(N == 2 && "Invalid number of operands!");436 437    Inst.addOperand(MCOperand::createReg(getMemBase()));438 439    assert(getMemOffsetReg().isValid() && "Invalid offset");440    Inst.addOperand(MCOperand::createReg(getMemOffsetReg()));441  }442 443  void addMEMriOperands(MCInst &Inst, unsigned N) const {444    assert(N == 2 && "Invalid number of operands!");445 446    Inst.addOperand(MCOperand::createReg(getMemBase()));447 448    const MCExpr *Expr = getMemOff();449    addExpr(Inst, Expr);450  }451 452  void addASITagOperands(MCInst &Inst, unsigned N) const {453    assert(N == 1 && "Invalid number of operands!");454    Inst.addOperand(MCOperand::createImm(getASITag()));455  }456 457  void addPrefetchTagOperands(MCInst &Inst, unsigned N) const {458    assert(N == 1 && "Invalid number of operands!");459    Inst.addOperand(MCOperand::createImm(getPrefetchTag()));460  }461 462  void addMembarTagOperands(MCInst &Inst, unsigned N) const {463    assert(N == 1 && "Invalid number of operands!");464    const MCExpr *Expr = getImm();465    addExpr(Inst, Expr);466  }467 468  void addCallTargetOperands(MCInst &Inst, unsigned N) const {469    assert(N == 1 && "Invalid number of operands!");470    addExpr(Inst, getImm());471  }472 473  void addTailRelocSymOperands(MCInst &Inst, unsigned N) const {474    assert(N == 1 && "Invalid number of operands!");475    addExpr(Inst, getTailRelocSym());476  }477 478  static std::unique_ptr<SparcOperand> CreateToken(StringRef Str, SMLoc S) {479    auto Op = std::make_unique<SparcOperand>(k_Token);480    Op->Tok.Data = Str.data();481    Op->Tok.Length = Str.size();482    Op->StartLoc = S;483    Op->EndLoc = S;484    return Op;485  }486 487  static std::unique_ptr<SparcOperand> CreateReg(MCRegister Reg, unsigned Kind,488                                                 SMLoc S, SMLoc E) {489    auto Op = std::make_unique<SparcOperand>(k_Register);490    Op->Reg.Reg = Reg;491    Op->Reg.Kind   = (SparcOperand::RegisterKind)Kind;492    Op->StartLoc = S;493    Op->EndLoc = E;494    return Op;495  }496 497  static std::unique_ptr<SparcOperand> CreateImm(const MCExpr *Val, SMLoc S,498                                                 SMLoc E) {499    auto Op = std::make_unique<SparcOperand>(k_Immediate);500    Op->Imm.Val = Val;501    Op->StartLoc = S;502    Op->EndLoc = E;503    return Op;504  }505 506  static std::unique_ptr<SparcOperand> CreateASITag(unsigned Val, SMLoc S,507                                                    SMLoc E) {508    auto Op = std::make_unique<SparcOperand>(k_ASITag);509    Op->ASI = Val;510    Op->StartLoc = S;511    Op->EndLoc = E;512    return Op;513  }514 515  static std::unique_ptr<SparcOperand> CreatePrefetchTag(unsigned Val, SMLoc S,516                                                         SMLoc E) {517    auto Op = std::make_unique<SparcOperand>(k_PrefetchTag);518    Op->Prefetch = Val;519    Op->StartLoc = S;520    Op->EndLoc = E;521    return Op;522  }523 524  static std::unique_ptr<SparcOperand> CreateTailRelocSym(const MCExpr *Val,525                                                          SMLoc S, SMLoc E) {526    auto Op = std::make_unique<SparcOperand>(k_TailRelocSym);527    Op->Imm.Val = Val;528    Op->StartLoc = S;529    Op->EndLoc = E;530    return Op;531  }532 533  static bool MorphToIntPairReg(SparcOperand &Op) {534    MCRegister Reg = Op.getReg();535    assert(Op.Reg.Kind == rk_IntReg);536    unsigned regIdx = 32;537    if (Reg >= Sparc::G0 && Reg <= Sparc::G7)538      regIdx = Reg - Sparc::G0;539    else if (Reg >= Sparc::O0 && Reg <= Sparc::O7)540      regIdx = Reg - Sparc::O0 + 8;541    else if (Reg >= Sparc::L0 && Reg <= Sparc::L7)542      regIdx = Reg - Sparc::L0 + 16;543    else if (Reg >= Sparc::I0 && Reg <= Sparc::I7)544      regIdx = Reg - Sparc::I0 + 24;545    if (regIdx % 2 || regIdx > 31)546      return false;547    Op.Reg.Reg = IntPairRegs[regIdx / 2];548    Op.Reg.Kind = rk_IntPairReg;549    return true;550  }551 552  static bool MorphToDoubleReg(SparcOperand &Op) {553    MCRegister Reg = Op.getReg();554    assert(Op.Reg.Kind == rk_FloatReg);555    unsigned regIdx = Reg - Sparc::F0;556    if (regIdx % 2 || regIdx > 31)557      return false;558    Op.Reg.Reg = DoubleRegs[regIdx / 2];559    Op.Reg.Kind = rk_DoubleReg;560    return true;561  }562 563  static bool MorphToQuadReg(SparcOperand &Op) {564    MCRegister Reg = Op.getReg();565    unsigned regIdx = 0;566    switch (Op.Reg.Kind) {567    default: llvm_unreachable("Unexpected register kind!");568    case rk_FloatReg:569      regIdx = Reg - Sparc::F0;570      if (regIdx % 4 || regIdx > 31)571        return false;572      Reg = QuadFPRegs[regIdx / 4];573      break;574    case rk_DoubleReg:575      regIdx =  Reg - Sparc::D0;576      if (regIdx % 2 || regIdx > 31)577        return false;578      Reg = QuadFPRegs[regIdx / 2];579      break;580    }581    Op.Reg.Reg = Reg;582    Op.Reg.Kind = rk_QuadReg;583    return true;584  }585 586  static bool MorphToCoprocPairReg(SparcOperand &Op) {587    MCRegister Reg = Op.getReg();588    assert(Op.Reg.Kind == rk_CoprocReg);589    unsigned regIdx = 32;590    if (Reg >= Sparc::C0 && Reg <= Sparc::C31)591      regIdx = Reg - Sparc::C0;592    if (regIdx % 2 || regIdx > 31)593      return false;594    Op.Reg.Reg = CoprocPairRegs[regIdx / 2];595    Op.Reg.Kind = rk_CoprocPairReg;596    return true;597  }598 599  static std::unique_ptr<SparcOperand>600  MorphToMEMrr(MCRegister Base, std::unique_ptr<SparcOperand> Op) {601    MCRegister offsetReg = Op->getReg();602    Op->Kind = k_MemoryReg;603    Op->Mem.Base = Base;604    Op->Mem.OffsetReg = offsetReg;605    Op->Mem.Off = nullptr;606    return Op;607  }608 609  static std::unique_ptr<SparcOperand> CreateMEMr(MCRegister Base, SMLoc S,610                                                  SMLoc E) {611    auto Op = std::make_unique<SparcOperand>(k_MemoryReg);612    Op->Mem.Base = Base;613    Op->Mem.OffsetReg = Sparc::G0;  // always 0614    Op->Mem.Off = nullptr;615    Op->StartLoc = S;616    Op->EndLoc = E;617    return Op;618  }619 620  static std::unique_ptr<SparcOperand>621  MorphToMEMri(MCRegister Base, std::unique_ptr<SparcOperand> Op) {622    const MCExpr *Imm  = Op->getImm();623    Op->Kind = k_MemoryImm;624    Op->Mem.Base = Base;625    Op->Mem.OffsetReg = MCRegister();626    Op->Mem.Off = Imm;627    return Op;628  }629};630 631} // end anonymous namespace632 633#define GET_MATCHER_IMPLEMENTATION634#define GET_REGISTER_MATCHER635#define GET_MNEMONIC_SPELL_CHECKER636#include "SparcGenAsmMatcher.inc"637 638// Use a custom function instead of the one from SparcGenAsmMatcher639// so we can differentiate between unavailable and unknown instructions.640SparcAsmParser::MatchResultTy641SparcAsmParser::mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) {642  // Process all MnemonicAliases to remap the mnemonic.643  applyMnemonicAliases(Mnemonic, getAvailableFeatures(), VariantID);644 645  // Find the appropriate table for this asm variant.646  const MatchEntry *Start, *End;647  switch (VariantID) {648  default:649    llvm_unreachable("invalid variant!");650  case 0:651    Start = std::begin(MatchTable0);652    End = std::end(MatchTable0);653    break;654  }655 656  // Search the table.657  auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());658 659  if (MnemonicRange.first == MnemonicRange.second)660    return Match_MnemonicFail;661 662  for (const MatchEntry *it = MnemonicRange.first, *ie = MnemonicRange.second;663       it != ie; ++it) {664    const FeatureBitset &RequiredFeatures =665        FeatureBitsets[it->RequiredFeaturesIdx];666    if ((getAvailableFeatures() & RequiredFeatures) == RequiredFeatures)667      return Match_Success;668  }669  return Match_MissingFeature;670}671 672bool SparcAsmParser::expandSET(MCInst &Inst, SMLoc IDLoc,673                               SmallVectorImpl<MCInst> &Instructions) {674  MCOperand MCRegOp = Inst.getOperand(0);675  MCOperand MCValOp = Inst.getOperand(1);676  assert(MCRegOp.isReg());677  assert(MCValOp.isImm() || MCValOp.isExpr());678 679  // the imm operand can be either an expression or an immediate.680  bool IsImm = Inst.getOperand(1).isImm();681  int64_t RawImmValue = IsImm ? MCValOp.getImm() : 0;682 683  // Allow either a signed or unsigned 32-bit immediate.684  if (RawImmValue < -2147483648LL || RawImmValue > 4294967295LL) {685    return Error(IDLoc,686                 "set: argument must be between -2147483648 and 4294967295");687  }688 689  // If the value was expressed as a large unsigned number, that's ok.690  // We want to see if it "looks like" a small signed number.691  int32_t ImmValue = RawImmValue;692  // For 'set' you can't use 'or' with a negative operand on V9 because693  // that would splat the sign bit across the upper half of the destination694  // register, whereas 'set' is defined to zero the high 32 bits.695  bool IsEffectivelyImm13 =696      IsImm && ((is64Bit() ? 0 : -4096) <= ImmValue && ImmValue < 4096);697  const MCExpr *ValExpr;698  if (IsImm)699    ValExpr = MCConstantExpr::create(ImmValue, getContext());700  else701    ValExpr = MCValOp.getExpr();702 703  MCOperand PrevReg = MCOperand::createReg(Sparc::G0);704 705  // If not just a signed imm13 value, then either we use a 'sethi' with a706  // following 'or', or a 'sethi' by itself if there are no more 1 bits.707  // In either case, start with the 'sethi'.708  if (!IsEffectivelyImm13) {709    MCInst TmpInst;710    const MCExpr *Expr = adjustPICRelocation(ELF::R_SPARC_HI22, ValExpr);711    TmpInst.setLoc(IDLoc);712    TmpInst.setOpcode(SP::SETHIi);713    TmpInst.addOperand(MCRegOp);714    TmpInst.addOperand(MCOperand::createExpr(Expr));715    Instructions.push_back(TmpInst);716    PrevReg = MCRegOp;717  }718 719  // The low bits require touching in 3 cases:720  // * A non-immediate value will always require both instructions.721  // * An effectively imm13 value needs only an 'or' instruction.722  // * Otherwise, an immediate that is not effectively imm13 requires the723  //   'or' only if bits remain after clearing the 22 bits that 'sethi' set.724  // If the low bits are known zeros, there's nothing to do.725  // In the second case, and only in that case, must we NOT clear726  // bits of the immediate value via the %lo() assembler function.727  // Note also, the 'or' instruction doesn't mind a large value in the case728  // where the operand to 'set' was 0xFFFFFzzz - it does exactly what you mean.729  if (!IsImm || IsEffectivelyImm13 || (ImmValue & 0x3ff)) {730    MCInst TmpInst;731    const MCExpr *Expr;732    if (IsEffectivelyImm13)733      Expr = ValExpr;734    else735      Expr = adjustPICRelocation(ELF::R_SPARC_LO10, ValExpr);736    TmpInst.setLoc(IDLoc);737    TmpInst.setOpcode(SP::ORri);738    TmpInst.addOperand(MCRegOp);739    TmpInst.addOperand(PrevReg);740    TmpInst.addOperand(MCOperand::createExpr(Expr));741    Instructions.push_back(TmpInst);742  }743  return false;744}745 746bool SparcAsmParser::expandSETSW(MCInst &Inst, SMLoc IDLoc,747                                 SmallVectorImpl<MCInst> &Instructions) {748  MCOperand MCRegOp = Inst.getOperand(0);749  MCOperand MCValOp = Inst.getOperand(1);750  assert(MCRegOp.isReg());751  assert(MCValOp.isImm() || MCValOp.isExpr());752 753  // The imm operand can be either an expression or an immediate.754  bool IsImm = Inst.getOperand(1).isImm();755  int64_t ImmValue = IsImm ? MCValOp.getImm() : 0;756  const MCExpr *ValExpr = IsImm ? MCConstantExpr::create(ImmValue, getContext())757                                : MCValOp.getExpr();758 759  bool IsSmallImm = IsImm && isInt<13>(ImmValue);760  bool NoLowBitsImm = IsImm && ((ImmValue & 0x3FF) == 0);761 762  MCOperand PrevReg = MCOperand::createReg(Sparc::G0);763 764  if (!isInt<32>(ImmValue)) {765    return Error(IDLoc,766                 "set: argument must be between -2147483648 and 2147483647");767  }768 769  // Very small immediates can be expressed without emitting a sethi.770  if (!IsSmallImm) {771    // sethi %hi(val), rd772    Instructions.push_back(773        MCInstBuilder(SP::SETHIi)774            .addReg(MCRegOp.getReg())775            .addExpr(adjustPICRelocation(ELF::R_SPARC_HI22, ValExpr)));776 777    PrevReg = MCRegOp;778  }779 780  // If the immediate has the lower bits set or is small, we need to emit an or.781  if (!NoLowBitsImm || IsSmallImm) {782    const MCExpr *Expr =783        IsSmallImm ? ValExpr : adjustPICRelocation(ELF::R_SPARC_LO10, ValExpr);784 785    // or rd, %lo(val), rd786    Instructions.push_back(MCInstBuilder(SP::ORri)787                               .addReg(MCRegOp.getReg())788                               .addReg(PrevReg.getReg())789                               .addExpr(Expr));790 791    // If it's a small immediate there's nothing more to do.792    if (IsSmallImm)793      return false;794  }795 796  // Large negative or non-immediate expressions would need an sra.797  if (!IsImm || ImmValue < 0) {798    // sra rd, %g0, rd799    Instructions.push_back(MCInstBuilder(SP::SRArr)800                               .addReg(MCRegOp.getReg())801                               .addReg(MCRegOp.getReg())802                               .addReg(Sparc::G0));803  }804 805  return false;806}807 808bool SparcAsmParser::expandSETX(MCInst &Inst, SMLoc IDLoc,809                                SmallVectorImpl<MCInst> &Instructions) {810  MCOperand MCRegOp = Inst.getOperand(0);811  MCOperand MCValOp = Inst.getOperand(1);812  MCOperand MCTmpOp = Inst.getOperand(2);813  assert(MCRegOp.isReg() && MCTmpOp.isReg());814  assert(MCValOp.isImm() || MCValOp.isExpr());815 816  // the imm operand can be either an expression or an immediate.817  bool IsImm = MCValOp.isImm();818  int64_t ImmValue = IsImm ? MCValOp.getImm() : 0;819 820  const MCExpr *ValExpr = IsImm ? MCConstantExpr::create(ImmValue, getContext())821                                : MCValOp.getExpr();822 823  // Very small immediates can be expressed directly as a single `or`.824  if (IsImm && isInt<13>(ImmValue)) {825    // or rd, val, rd826    Instructions.push_back(MCInstBuilder(SP::ORri)827                               .addReg(MCRegOp.getReg())828                               .addReg(Sparc::G0)829                               .addExpr(ValExpr));830    return false;831  }832 833  // Otherwise, first we set the lower half of the register.834 835  // sethi %hi(val), rd836  Instructions.push_back(837      MCInstBuilder(SP::SETHIi)838          .addReg(MCRegOp.getReg())839          .addExpr(adjustPICRelocation(ELF::R_SPARC_HI22, ValExpr)));840  // or    rd, %lo(val), rd841  Instructions.push_back(842      MCInstBuilder(SP::ORri)843          .addReg(MCRegOp.getReg())844          .addReg(MCRegOp.getReg())845          .addExpr(adjustPICRelocation(ELF::R_SPARC_LO10, ValExpr)));846 847  // Small positive immediates can be expressed as a single `sethi`+`or`848  // combination, so we can just return here.849  if (IsImm && isUInt<32>(ImmValue))850    return false;851 852  // For bigger immediates, we need to generate the upper half, then shift and853  // merge it with the lower half that has just been generated above.854 855  // sethi %hh(val), tmp856  Instructions.push_back(MCInstBuilder(SP::SETHIi)857                             .addReg(MCTmpOp.getReg())858                             .addExpr(MCSpecifierExpr::create(859                                 ValExpr, ELF::R_SPARC_HH22, getContext())));860  // or    tmp, %hm(val), tmp861  Instructions.push_back(MCInstBuilder(SP::ORri)862                             .addReg(MCTmpOp.getReg())863                             .addReg(MCTmpOp.getReg())864                             .addExpr(MCSpecifierExpr::create(865                                 ValExpr, ELF::R_SPARC_HM10, getContext())));866  // sllx  tmp, 32, tmp867  Instructions.push_back(MCInstBuilder(SP::SLLXri)868                             .addReg(MCTmpOp.getReg())869                             .addReg(MCTmpOp.getReg())870                             .addImm(32));871  // or    tmp, rd, rd872  Instructions.push_back(MCInstBuilder(SP::ORrr)873                             .addReg(MCRegOp.getReg())874                             .addReg(MCTmpOp.getReg())875                             .addReg(MCRegOp.getReg()));876 877  return false;878}879 880bool SparcAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,881                                             OperandVector &Operands,882                                             MCStreamer &Out,883                                             uint64_t &ErrorInfo,884                                             bool MatchingInlineAsm) {885  MCInst Inst;886  SmallVector<MCInst, 8> Instructions;887  unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,888                                              MatchingInlineAsm);889  switch (MatchResult) {890  case Match_Success: {891    switch (Inst.getOpcode()) {892    default:893      Inst.setLoc(IDLoc);894      Instructions.push_back(Inst);895      break;896    case SP::SET:897      if (expandSET(Inst, IDLoc, Instructions))898        return true;899      break;900    case SP::SETSW:901      if (expandSETSW(Inst, IDLoc, Instructions))902        return true;903      break;904    case SP::SETX:905      if (expandSETX(Inst, IDLoc, Instructions))906        return true;907      break;908    }909 910    for (const MCInst &I : Instructions) {911      Out.emitInstruction(I, getSTI());912    }913    return false;914  }915 916  case Match_MissingFeature:917    return Error(IDLoc,918                 "instruction requires a CPU feature not currently enabled");919 920  case Match_InvalidOperand: {921    SMLoc ErrorLoc = IDLoc;922    if (ErrorInfo != ~0ULL) {923      if (ErrorInfo >= Operands.size())924        return Error(IDLoc, "too few operands for instruction");925 926      ErrorLoc = ((SparcOperand &)*Operands[ErrorInfo]).getStartLoc();927      if (ErrorLoc == SMLoc())928        ErrorLoc = IDLoc;929    }930 931    return Error(ErrorLoc, "invalid operand for instruction");932  }933  case Match_MnemonicFail:934    return Error(IDLoc, "invalid instruction mnemonic");935  }936  llvm_unreachable("Implement any new match types added!");937}938 939bool SparcAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,940                                   SMLoc &EndLoc) {941  if (!tryParseRegister(Reg, StartLoc, EndLoc).isSuccess())942    return Error(StartLoc, "invalid register name");943  return false;944}945 946ParseStatus SparcAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,947                                             SMLoc &EndLoc) {948  const AsmToken &Tok = Parser.getTok();949  StartLoc = Tok.getLoc();950  EndLoc = Tok.getEndLoc();951  Reg = Sparc::NoRegister;952  if (getLexer().getKind() != AsmToken::Percent)953    return ParseStatus::NoMatch;954  Parser.Lex();955  unsigned RegKind = SparcOperand::rk_None;956  Reg = matchRegisterName(Tok, RegKind);957  if (Reg) {958    Parser.Lex();959    return ParseStatus::Success;960  }961 962  getLexer().UnLex(Tok);963  return ParseStatus::NoMatch;964}965 966bool SparcAsmParser::parseInstruction(ParseInstructionInfo &Info,967                                      StringRef Name, SMLoc NameLoc,968                                      OperandVector &Operands) {969  // Validate and reject unavailable mnemonics early before970  // running any operand parsing.971  // This is needed because some operands (mainly memory ones)972  // differ between V8 and V9 ISA and so any operand parsing errors973  // will cause IAS to bail out before it reaches matchAndEmitInstruction974  // (where the instruction as a whole, including the mnemonic, is validated975  // once again just before emission).976  // As a nice side effect this also allows us to reject unknown977  // instructions and suggest replacements.978  MatchResultTy MS = mnemonicIsValid(Name, 0);979  switch (MS) {980  case Match_Success:981    break;982  case Match_MissingFeature:983    return Error(NameLoc,984                 "instruction requires a CPU feature not currently enabled");985  case Match_MnemonicFail:986    return Error(NameLoc,987                 "invalid instruction mnemonic" +988                     SparcMnemonicSpellCheck(Name, getAvailableFeatures(), 0));989  default:990    llvm_unreachable("invalid return status!");991  }992 993  // First operand in MCInst is instruction mnemonic.994  Operands.push_back(SparcOperand::CreateToken(Name, NameLoc));995 996  // apply mnemonic aliases, if any, so that we can parse operands correctly.997  applyMnemonicAliases(Name, getAvailableFeatures(), 0);998 999  if (getLexer().isNot(AsmToken::EndOfStatement)) {1000    // Read the first operand.1001    if (getLexer().is(AsmToken::Comma)) {1002      if (!parseBranchModifiers(Operands).isSuccess()) {1003        SMLoc Loc = getLexer().getLoc();1004        return Error(Loc, "unexpected token");1005      }1006    }1007    if (!parseOperand(Operands, Name).isSuccess()) {1008      SMLoc Loc = getLexer().getLoc();1009      return Error(Loc, "unexpected token");1010    }1011 1012    while (getLexer().is(AsmToken::Comma) || getLexer().is(AsmToken::Plus)) {1013      if (getLexer().is(AsmToken::Plus)) {1014      // Plus tokens are significant in software_traps (p83, sparcv8.pdf). We must capture them.1015        Operands.push_back(SparcOperand::CreateToken("+", Parser.getTok().getLoc()));1016      }1017      Parser.Lex(); // Eat the comma or plus.1018      // Parse and remember the operand.1019      if (!parseOperand(Operands, Name).isSuccess()) {1020        SMLoc Loc = getLexer().getLoc();1021        return Error(Loc, "unexpected token");1022      }1023    }1024  }1025  if (getLexer().isNot(AsmToken::EndOfStatement)) {1026    SMLoc Loc = getLexer().getLoc();1027    return Error(Loc, "unexpected token");1028  }1029  Parser.Lex(); // Consume the EndOfStatement.1030  return false;1031}1032 1033ParseStatus SparcAsmParser::parseDirective(AsmToken DirectiveID) {1034  StringRef IDVal = DirectiveID.getString();1035 1036  if (IDVal == ".register") {1037    // For now, ignore .register directive.1038    Parser.eatToEndOfStatement();1039    return ParseStatus::Success;1040  }1041  if (IDVal == ".proc") {1042    // For compatibility, ignore this directive.1043    // (It's supposed to be an "optimization" in the Sun assembler)1044    Parser.eatToEndOfStatement();1045    return ParseStatus::Success;1046  }1047 1048  // Let the MC layer to handle other directives.1049  return ParseStatus::NoMatch;1050}1051 1052ParseStatus SparcAsmParser::parseMEMOperand(OperandVector &Operands) {1053  SMLoc S, E;1054 1055  std::unique_ptr<SparcOperand> LHS;1056  if (!parseSparcAsmOperand(LHS).isSuccess())1057    return ParseStatus::NoMatch;1058 1059  // Single immediate operand1060  if (LHS->isImm()) {1061    Operands.push_back(SparcOperand::MorphToMEMri(Sparc::G0, std::move(LHS)));1062    return ParseStatus::Success;1063  }1064 1065  if (!LHS->isIntReg())1066    return Error(LHS->getStartLoc(), "invalid register kind for this operand");1067 1068  AsmToken Tok = getLexer().getTok();1069  // The plus token may be followed by a register or an immediate value, the1070  // minus one is always interpreted as sign for the immediate value1071  if (Tok.is(AsmToken::Plus) || Tok.is(AsmToken::Minus)) {1072    (void)Parser.parseOptionalToken(AsmToken::Plus);1073 1074    std::unique_ptr<SparcOperand> RHS;1075    if (!parseSparcAsmOperand(RHS).isSuccess())1076      return ParseStatus::NoMatch;1077 1078    if (RHS->isReg() && !RHS->isIntReg())1079      return Error(RHS->getStartLoc(),1080                   "invalid register kind for this operand");1081 1082    Operands.push_back(1083        RHS->isImm()1084            ? SparcOperand::MorphToMEMri(LHS->getReg(), std::move(RHS))1085            : SparcOperand::MorphToMEMrr(LHS->getReg(), std::move(RHS)));1086 1087    return ParseStatus::Success;1088  }1089 1090  Operands.push_back(SparcOperand::CreateMEMr(LHS->getReg(), S, E));1091  return ParseStatus::Success;1092}1093 1094template <unsigned N>1095ParseStatus SparcAsmParser::parseShiftAmtImm(OperandVector &Operands) {1096  SMLoc S = Parser.getTok().getLoc();1097  SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);1098 1099  // This is a register, not an immediate1100  if (getLexer().getKind() == AsmToken::Percent)1101    return ParseStatus::NoMatch;1102 1103  const MCExpr *Expr;1104  if (getParser().parseExpression(Expr))1105    return ParseStatus::Failure;1106 1107  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);1108  if (!CE)1109    return Error(S, "constant expression expected");1110 1111  if (!isUInt<N>(CE->getValue()))1112    return Error(S, "immediate shift value out of range");1113 1114  Operands.push_back(SparcOperand::CreateImm(Expr, S, E));1115  return ParseStatus::Success;1116}1117 1118template <SparcAsmParser::TailRelocKind Kind>1119ParseStatus SparcAsmParser::parseTailRelocSym(OperandVector &Operands) {1120  SMLoc S = getLoc();1121  SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);1122 1123  auto MatchesKind = [](uint16_t RelType) -> bool {1124    switch (Kind) {1125    case TailRelocKind::Load_GOT:1126      // Non-TLS relocations on ld (or ldx).1127      // ld [%rr + %rr], %rr, %rel(sym)1128      return RelType == ELF::R_SPARC_GOTDATA_OP;1129    case TailRelocKind::Add_TLS:1130      // TLS relocations on add.1131      // add %rr, %rr, %rr, %rel(sym)1132      switch (RelType) {1133      case ELF::R_SPARC_TLS_GD_ADD:1134      case ELF::R_SPARC_TLS_IE_ADD:1135      case ELF::R_SPARC_TLS_LDM_ADD:1136      case ELF::R_SPARC_TLS_LDO_ADD:1137        return true;1138      default:1139        return false;1140      }1141    case TailRelocKind::Load_TLS:1142      // TLS relocations on ld (or ldx).1143      // ld[x] %addr, %rr, %rel(sym)1144      switch (RelType) {1145      case ELF::R_SPARC_TLS_IE_LD:1146      case ELF::R_SPARC_TLS_IE_LDX:1147        return true;1148      default:1149        return false;1150      }1151    case TailRelocKind::Call_TLS:1152      // TLS relocations on call.1153      // call sym, %rel(sym)1154      switch (RelType) {1155      case ELF::R_SPARC_TLS_GD_CALL:1156      case ELF::R_SPARC_TLS_LDM_CALL:1157        return true;1158      default:1159        return false;1160      }1161    }1162    llvm_unreachable("Unhandled SparcAsmParser::TailRelocKind enum");1163  };1164 1165  if (getLexer().getKind() != AsmToken::Percent)1166    return ParseStatus::NoMatch;1167 1168  const AsmToken Tok = Parser.getTok();1169  getParser().Lex(); // Eat '%'1170 1171  if (getLexer().getKind() != AsmToken::Identifier)1172    return Error(getLoc(), "expected valid identifier for operand modifier");1173 1174  StringRef Name = getParser().getTok().getIdentifier();1175  uint16_t RelType = Sparc::parseSpecifier(Name);1176  if (RelType == 0)1177    return Error(getLoc(), "invalid relocation specifier");1178 1179  if (!MatchesKind(RelType)) {1180    // Did not match the specified set of relocation types, put '%' back.1181    getLexer().UnLex(Tok);1182    return ParseStatus::NoMatch;1183  }1184 1185  Parser.Lex(); // Eat the identifier.1186  if (getLexer().getKind() != AsmToken::LParen)1187    return Error(getLoc(), "expected '('");1188 1189  getParser().Lex(); // Eat '('1190  const MCExpr *SubExpr;1191  if (getParser().parseParenExpression(SubExpr, E))1192    return ParseStatus::Failure;1193 1194  const MCExpr *Val = adjustPICRelocation(RelType, SubExpr);1195  Operands.push_back(SparcOperand::CreateTailRelocSym(Val, S, E));1196  return ParseStatus::Success;1197}1198 1199ParseStatus SparcAsmParser::parseMembarTag(OperandVector &Operands) {1200  SMLoc S = Parser.getTok().getLoc();1201  const MCExpr *EVal;1202  int64_t ImmVal = 0;1203 1204  std::unique_ptr<SparcOperand> Mask;1205  if (parseSparcAsmOperand(Mask).isSuccess()) {1206    if (!Mask->isImm() || !Mask->getImm()->evaluateAsAbsolute(ImmVal) ||1207        ImmVal < 0 || ImmVal > 127)1208      return Error(S, "invalid membar mask number");1209  }1210 1211  while (getLexer().getKind() == AsmToken::Hash) {1212    SMLoc TagStart = getLexer().getLoc();1213    Parser.Lex(); // Eat the '#'.1214    unsigned MaskVal = StringSwitch<unsigned>(Parser.getTok().getString())1215      .Case("LoadLoad", 0x1)1216      .Case("StoreLoad", 0x2)1217      .Case("LoadStore", 0x4)1218      .Case("StoreStore", 0x8)1219      .Case("Lookaside", 0x10)1220      .Case("MemIssue", 0x20)1221      .Case("Sync", 0x40)1222      .Default(0);1223 1224    Parser.Lex(); // Eat the identifier token.1225 1226    if (!MaskVal)1227      return Error(TagStart, "unknown membar tag");1228 1229    ImmVal |= MaskVal;1230 1231    if (getLexer().getKind() == AsmToken::Pipe)1232      Parser.Lex(); // Eat the '|'.1233  }1234 1235  EVal = MCConstantExpr::create(ImmVal, getContext());1236  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);1237  Operands.push_back(SparcOperand::CreateImm(EVal, S, E));1238  return ParseStatus::Success;1239}1240 1241ParseStatus SparcAsmParser::parseASITag(OperandVector &Operands) {1242  SMLoc S = Parser.getTok().getLoc();1243  SMLoc E = Parser.getTok().getEndLoc();1244  int64_t ASIVal = 0;1245 1246  if (getLexer().getKind() != AsmToken::Hash) {1247    // If the ASI tag provided is not a named tag, then it1248    // must be a constant expression.1249    ParseStatus ParseExprStatus = parseExpression(ASIVal);1250    if (!ParseExprStatus.isSuccess())1251      return ParseExprStatus;1252 1253    if (!isUInt<8>(ASIVal))1254      return Error(S, "invalid ASI number, must be between 0 and 255");1255 1256    Operands.push_back(SparcOperand::CreateASITag(ASIVal, S, E));1257    return ParseStatus::Success;1258  }1259 1260  // For now we only support named tags for 64-bit/V9 systems.1261  // TODO: add support for 32-bit/V8 systems.1262  SMLoc TagStart = getLexer().peekTok(false).getLoc();1263  Parser.Lex(); // Eat the '#'.1264  const StringRef ASIName = Parser.getTok().getString();1265  const SparcASITag::ASITag *ASITag = SparcASITag::lookupASITagByName(ASIName);1266  if (!ASITag)1267    ASITag = SparcASITag::lookupASITagByAltName(ASIName);1268  Parser.Lex(); // Eat the identifier token.1269 1270  if (!ASITag)1271    return Error(TagStart, "unknown ASI tag");1272 1273  ASIVal = ASITag->Encoding;1274 1275  Operands.push_back(SparcOperand::CreateASITag(ASIVal, S, E));1276  return ParseStatus::Success;1277}1278 1279ParseStatus SparcAsmParser::parsePrefetchTag(OperandVector &Operands) {1280  SMLoc S = Parser.getTok().getLoc();1281  SMLoc E = Parser.getTok().getEndLoc();1282  int64_t PrefetchVal = 0;1283 1284  if (getLexer().getKind() != AsmToken::Hash) {1285    // If the prefetch tag provided is not a named tag, then it1286    // must be a constant expression.1287    ParseStatus ParseExprStatus = parseExpression(PrefetchVal);1288    if (!ParseExprStatus.isSuccess())1289      return ParseExprStatus;1290 1291    if (!isUInt<8>(PrefetchVal))1292      return Error(S, "invalid prefetch number, must be between 0 and 31");1293 1294    Operands.push_back(SparcOperand::CreatePrefetchTag(PrefetchVal, S, E));1295    return ParseStatus::Success;1296  }1297 1298  SMLoc TagStart = getLexer().peekTok(false).getLoc();1299  Parser.Lex(); // Eat the '#'.1300  const StringRef PrefetchName = Parser.getTok().getString();1301  const SparcPrefetchTag::PrefetchTag *PrefetchTag =1302      SparcPrefetchTag::lookupPrefetchTagByName(PrefetchName);1303  Parser.Lex(); // Eat the identifier token.1304 1305  if (!PrefetchTag)1306    return Error(TagStart, "unknown prefetch tag");1307 1308  PrefetchVal = PrefetchTag->Encoding;1309 1310  Operands.push_back(SparcOperand::CreatePrefetchTag(PrefetchVal, S, E));1311  return ParseStatus::Success;1312}1313 1314ParseStatus SparcAsmParser::parseCallTarget(OperandVector &Operands) {1315  SMLoc S = Parser.getTok().getLoc();1316  SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);1317 1318  switch (getLexer().getKind()) {1319  default:1320    return ParseStatus::NoMatch;1321  case AsmToken::LParen:1322  case AsmToken::Integer:1323  case AsmToken::Identifier:1324  case AsmToken::Dot:1325    break;1326  }1327 1328  const MCExpr *DestValue;1329  if (getParser().parseExpression(DestValue))1330    return ParseStatus::NoMatch;1331 1332  Operands.push_back(SparcOperand::CreateImm(DestValue, S, E));1333  return ParseStatus::Success;1334}1335 1336ParseStatus SparcAsmParser::parseOperand(OperandVector &Operands,1337                                         StringRef Mnemonic) {1338 1339  ParseStatus Res = MatchOperandParserImpl(Operands, Mnemonic);1340 1341  // If there wasn't a custom match, try the generic matcher below. Otherwise,1342  // there was a match, but an error occurred, in which case, just return that1343  // the operand parsing failed.1344  if (Res.isSuccess() || Res.isFailure())1345    return Res;1346 1347  if (getLexer().is(AsmToken::LBrac)) {1348    // Memory operand1349    Operands.push_back(SparcOperand::CreateToken("[",1350                                                 Parser.getTok().getLoc()));1351    Parser.Lex(); // Eat the [1352 1353    if (Mnemonic == "cas" || Mnemonic == "casl" || Mnemonic == "casa" ||1354        Mnemonic == "casx" || Mnemonic == "casxl" || Mnemonic == "casxa") {1355      SMLoc S = Parser.getTok().getLoc();1356      if (getLexer().getKind() != AsmToken::Percent)1357        return ParseStatus::NoMatch;1358      Parser.Lex(); // eat %1359 1360      unsigned RegKind;1361      MCRegister Reg = matchRegisterName(Parser.getTok(), RegKind);1362      if (!Reg)1363        return ParseStatus::NoMatch;1364 1365      Parser.Lex(); // Eat the identifier token.1366      SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer()-1);1367      Operands.push_back(SparcOperand::CreateReg(Reg, RegKind, S, E));1368      Res = ParseStatus::Success;1369    } else {1370      Res = parseMEMOperand(Operands);1371    }1372 1373    if (!Res.isSuccess())1374      return Res;1375 1376    if (!getLexer().is(AsmToken::RBrac))1377      return ParseStatus::Failure;1378 1379    Operands.push_back(SparcOperand::CreateToken("]",1380                                                 Parser.getTok().getLoc()));1381    Parser.Lex(); // Eat the ]1382 1383    // Parse an optional address-space identifier after the address.1384    // This will be either an immediate constant expression, or, on 64-bit1385    // processors, the %asi register.1386    if (getLexer().is(AsmToken::Percent)) {1387      SMLoc S = Parser.getTok().getLoc();1388      if (!is64Bit())1389        return Error(1390            S, "malformed ASI tag, must be a constant integer expression");1391 1392      Parser.Lex(); // Eat the %.1393      const AsmToken Tok = Parser.getTok();1394      if (Tok.is(AsmToken::Identifier) && Tok.getString() == "asi") {1395        // Here we patch the MEM operand from [base + %g0] into [base + 0]1396        // as memory operations with ASI tag stored in %asi register needs1397        // to use immediate offset. We need to do this because Reg addressing1398        // will be parsed as Reg+G0 initially.1399        // This allows forms such as `ldxa [%o0] %asi, %o0` to parse correctly.1400        SparcOperand &OldMemOp = (SparcOperand &)*Operands[Operands.size() - 2];1401        if (OldMemOp.isMEMrr()) {1402          if (OldMemOp.getMemOffsetReg() != Sparc::G0) {1403            return Error(S, "invalid operand for instruction");1404          }1405          Operands[Operands.size() - 2] = SparcOperand::MorphToMEMri(1406              OldMemOp.getMemBase(),1407              SparcOperand::CreateImm(MCConstantExpr::create(0, getContext()),1408                                      OldMemOp.getStartLoc(),1409                                      OldMemOp.getEndLoc()));1410        }1411        Parser.Lex(); // Eat the identifier.1412        // In this context, we convert the register operand into1413        // a plain "%asi" token since the register access is already1414        // implicit in the instruction definition and encoding.1415        // See LoadASI/StoreASI in SparcInstrInfo.td.1416        Operands.push_back(SparcOperand::CreateToken("%asi", S));1417        return ParseStatus::Success;1418      }1419 1420      return Error(S, "malformed ASI tag, must be %asi, a constant integer "1421                      "expression, or a named tag");1422    }1423 1424    // If we're not at the end of statement and the next token is not a comma,1425    // then it is an immediate ASI value.1426    if (getLexer().isNot(AsmToken::EndOfStatement) &&1427        getLexer().isNot(AsmToken::Comma))1428      return parseASITag(Operands);1429    return ParseStatus::Success;1430  }1431 1432  std::unique_ptr<SparcOperand> Op;1433 1434  Res = parseSparcAsmOperand(Op);1435  if (!Res.isSuccess() || !Op)1436    return ParseStatus::Failure;1437 1438  // Push the parsed operand into the list of operands1439  Operands.push_back(std::move(Op));1440 1441  return ParseStatus::Success;1442}1443 1444ParseStatus1445SparcAsmParser::parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Op) {1446  SMLoc S = Parser.getTok().getLoc();1447  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);1448  const MCExpr *EVal;1449 1450  Op = nullptr;1451  switch (getLexer().getKind()) {1452  default:  break;1453 1454  case AsmToken::Percent: {1455    Parser.Lex(); // Eat the '%'.1456    unsigned RegKind;1457    if (MCRegister Reg = matchRegisterName(Parser.getTok(), RegKind)) {1458      StringRef Name = Parser.getTok().getString();1459      Parser.Lex(); // Eat the identifier token.1460      E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);1461      if (Reg == Sparc::ICC && Name == "xcc")1462        Op = SparcOperand::CreateToken("%xcc", S);1463      else1464        Op = SparcOperand::CreateReg(Reg, RegKind, S, E);1465      break;1466    }1467    if (matchSparcAsmModifiers(EVal, E)) {1468      E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);1469      Op = SparcOperand::CreateImm(EVal, S, E);1470    }1471    break;1472  }1473 1474  case AsmToken::Plus:1475  case AsmToken::Minus:1476  case AsmToken::Integer:1477  case AsmToken::LParen:1478  case AsmToken::Dot:1479  case AsmToken::Identifier:1480    if (getParser().parseExpression(EVal, E))1481      break;1482 1483    Op = SparcOperand::CreateImm(EVal, S, E);1484    break;1485  }1486  return Op ? ParseStatus::Success : ParseStatus::Failure;1487}1488 1489ParseStatus SparcAsmParser::parseBranchModifiers(OperandVector &Operands) {1490  // parse (,a|,pn|,pt)+1491 1492  while (getLexer().is(AsmToken::Comma)) {1493    Parser.Lex(); // Eat the comma1494 1495    if (!getLexer().is(AsmToken::Identifier))1496      return ParseStatus::Failure;1497    StringRef modName = Parser.getTok().getString();1498    if (modName == "a" || modName == "pn" || modName == "pt") {1499      Operands.push_back(SparcOperand::CreateToken(modName,1500                                                   Parser.getTok().getLoc()));1501      Parser.Lex(); // eat the identifier.1502    }1503  }1504  return ParseStatus::Success;1505}1506 1507ParseStatus SparcAsmParser::parseExpression(int64_t &Val) {1508  AsmToken Tok = getLexer().getTok();1509 1510  if (!isPossibleExpression(Tok))1511    return ParseStatus::NoMatch;1512 1513  return getParser().parseAbsoluteExpression(Val);1514}1515 1516MCRegister SparcAsmParser::matchRegisterName(const AsmToken &Tok,1517                                             unsigned &RegKind) {1518  RegKind = SparcOperand::rk_None;1519  if (!Tok.is(AsmToken::Identifier))1520    return SP::NoRegister;1521 1522  StringRef Name = Tok.getString();1523  MCRegister Reg = MatchRegisterName(Name.lower());1524  if (!Reg)1525    Reg = MatchRegisterAltName(Name.lower());1526 1527  if (Reg) {1528    // Some registers have identical spellings. The generated matcher might1529    // have chosen one or another spelling, e.g. "%fp" or "%i6" might have been1530    // matched to either SP::I6 or SP::I6_I7. Other parts of SparcAsmParser1531    // are not prepared for this, so we do some canonicalization.1532 1533    // See the note in SparcRegisterInfo.td near ASRRegs register class.1534    if (Reg == SP::ASR4 && Name == "tick") {1535      RegKind = SparcOperand::rk_Special;1536      return SP::TICK;1537    }1538 1539    if (MRI.getRegClass(SP::IntRegsRegClassID).contains(Reg)) {1540      RegKind = SparcOperand::rk_IntReg;1541      return Reg;1542    }1543    if (MRI.getRegClass(SP::FPRegsRegClassID).contains(Reg)) {1544      RegKind = SparcOperand::rk_FloatReg;1545      return Reg;1546    }1547    if (MRI.getRegClass(SP::CoprocRegsRegClassID).contains(Reg)) {1548      RegKind = SparcOperand::rk_CoprocReg;1549      return Reg;1550    }1551 1552    // Canonicalize G0_G1 ... G30_G31 etc. to G0 ... G30.1553    if (MRI.getRegClass(SP::IntPairRegClassID).contains(Reg)) {1554      RegKind = SparcOperand::rk_IntReg;1555      return MRI.getSubReg(Reg, SP::sub_even);1556    }1557 1558    // Canonicalize D0 ... D15 to F0 ... F30.1559    if (MRI.getRegClass(SP::DFPRegsRegClassID).contains(Reg)) {1560      // D16 ... D31 do not have sub-registers.1561      if (MCRegister SubReg = MRI.getSubReg(Reg, SP::sub_even)) {1562        RegKind = SparcOperand::rk_FloatReg;1563        return SubReg;1564      }1565      RegKind = SparcOperand::rk_DoubleReg;1566      return Reg;1567    }1568 1569    // The generated matcher does not currently return QFP registers.1570    // If it changes, we will need to handle them in a similar way.1571    assert(!MRI.getRegClass(SP::QFPRegsRegClassID).contains(Reg));1572 1573    // Canonicalize C0_C1 ... C30_C31 to C0 ... C30.1574    if (MRI.getRegClass(SP::CoprocPairRegClassID).contains(Reg)) {1575      RegKind = SparcOperand::rk_CoprocReg;1576      return MRI.getSubReg(Reg, SP::sub_even);1577    }1578 1579    // Other registers do not need special handling.1580    RegKind = SparcOperand::rk_Special;1581    return Reg;1582  }1583 1584  // If we still have no match, try custom parsing.1585  // Not all registers and their spellings are modeled in td files.1586 1587  // %r0 - %r311588  int64_t RegNo = 0;1589  if (Name.starts_with_insensitive("r") &&1590      !Name.substr(1, 2).getAsInteger(10, RegNo) && RegNo < 31) {1591    RegKind = SparcOperand::rk_IntReg;1592    return IntRegs[RegNo];1593  }1594 1595  if (Name == "xcc") {1596    // FIXME:: check 64bit.1597    RegKind = SparcOperand::rk_Special;1598    return SP::ICC;1599  }1600 1601  // JPS1 extension - aliases for ASRs1602  // Section 5.2.11 - Ancillary State Registers (ASRs)1603  if (Name == "pcr") {1604    RegKind = SparcOperand::rk_Special;1605    return SP::ASR16;1606  }1607  if (Name == "pic") {1608    RegKind = SparcOperand::rk_Special;1609    return SP::ASR17;1610  }1611  if (Name == "dcr") {1612    RegKind = SparcOperand::rk_Special;1613    return SP::ASR18;1614  }1615  if (Name == "gsr") {1616    RegKind = SparcOperand::rk_Special;1617    return SP::ASR19;1618  }1619  if (Name == "set_softint") {1620    RegKind = SparcOperand::rk_Special;1621    return SP::ASR20;1622  }1623  if (Name == "clear_softint") {1624    RegKind = SparcOperand::rk_Special;1625    return SP::ASR21;1626  }1627  if (Name == "softint") {1628    RegKind = SparcOperand::rk_Special;1629    return SP::ASR22;1630  }1631  if (Name == "tick_cmpr") {1632    RegKind = SparcOperand::rk_Special;1633    return SP::ASR23;1634  }1635  if (Name == "stick" || Name == "sys_tick") {1636    RegKind = SparcOperand::rk_Special;1637    return SP::ASR24;1638  }1639  if (Name == "stick_cmpr" || Name == "sys_tick_cmpr") {1640    RegKind = SparcOperand::rk_Special;1641    return SP::ASR25;1642  }1643 1644  return SP::NoRegister;1645}1646 1647// Determine if an expression contains a reference to the symbol1648// "_GLOBAL_OFFSET_TABLE_".1649static bool hasGOTReference(const MCExpr *Expr) {1650  switch (Expr->getKind()) {1651  case MCExpr::Target:1652    if (const MCSpecifierExpr *SE = dyn_cast<MCSpecifierExpr>(Expr))1653      return hasGOTReference(SE->getSubExpr());1654    break;1655 1656  case MCExpr::Constant:1657    break;1658 1659  case MCExpr::Binary: {1660    const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);1661    return hasGOTReference(BE->getLHS()) || hasGOTReference(BE->getRHS());1662  }1663 1664  case MCExpr::SymbolRef: {1665    const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr);1666    return (SymRef.getSymbol().getName() == "_GLOBAL_OFFSET_TABLE_");1667  }1668 1669  case MCExpr::Unary:1670    return hasGOTReference(cast<MCUnaryExpr>(Expr)->getSubExpr());1671 1672  case MCExpr::Specifier:1673    llvm_unreachable("unused by this backend");1674  }1675  return false;1676}1677 1678const MCSpecifierExpr *1679SparcAsmParser::adjustPICRelocation(uint16_t RelType, const MCExpr *subExpr) {1680  // When in PIC mode, "%lo(...)" and "%hi(...)" behave differently.1681  // If the expression refers contains _GLOBAL_OFFSET_TABLE, it is1682  // actually a %pc10 or %pc22 relocation. Otherwise, they are interpreted1683  // as %got10 or %got22 relocation.1684 1685  if (getContext().getObjectFileInfo()->isPositionIndependent()) {1686    switch (RelType) {1687    default: break;1688    case ELF::R_SPARC_LO10:1689      RelType =1690          hasGOTReference(subExpr) ? ELF::R_SPARC_PC10 : ELF::R_SPARC_GOT10;1691      break;1692    case ELF::R_SPARC_HI22:1693      RelType =1694          hasGOTReference(subExpr) ? ELF::R_SPARC_PC22 : ELF::R_SPARC_GOT22;1695      break;1696    }1697  }1698 1699  return MCSpecifierExpr::create(subExpr, RelType, getContext());1700}1701 1702bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal,1703                                            SMLoc &EndLoc) {1704  AsmToken Tok = Parser.getTok();1705  if (!Tok.is(AsmToken::Identifier))1706    return false;1707 1708  StringRef name = Tok.getString();1709 1710  auto VK = Sparc::parseSpecifier(name);1711  switch (VK) {1712  case 0:1713    Error(getLoc(), "invalid relocation specifier");1714    return false;1715 1716  case ELF::R_SPARC_GOTDATA_OP:1717  case ELF::R_SPARC_TLS_GD_ADD:1718  case ELF::R_SPARC_TLS_GD_CALL:1719  case ELF::R_SPARC_TLS_IE_ADD:1720  case ELF::R_SPARC_TLS_IE_LD:1721  case ELF::R_SPARC_TLS_IE_LDX:1722  case ELF::R_SPARC_TLS_LDM_ADD:1723  case ELF::R_SPARC_TLS_LDM_CALL:1724  case ELF::R_SPARC_TLS_LDO_ADD:1725    // These are special-cased at tablegen level.1726    return false;1727 1728  default:1729    break;1730  }1731 1732  Parser.Lex(); // Eat the identifier.1733  if (Parser.getTok().getKind() != AsmToken::LParen)1734    return false;1735 1736  Parser.Lex(); // Eat the LParen token.1737  const MCExpr *subExpr;1738  if (Parser.parseParenExpression(subExpr, EndLoc))1739    return false;1740 1741  EVal = adjustPICRelocation(VK, subExpr);1742  return true;1743}1744 1745bool SparcAsmParser::isPossibleExpression(const AsmToken &Token) {1746  switch (Token.getKind()) {1747  case AsmToken::LParen:1748  case AsmToken::Integer:1749  case AsmToken::Identifier:1750  case AsmToken::Plus:1751  case AsmToken::Minus:1752  case AsmToken::Tilde:1753    return true;1754  default:1755    return false;1756  }1757}1758 1759extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void1760LLVMInitializeSparcAsmParser() {1761  RegisterMCAsmParser<SparcAsmParser> A(getTheSparcTarget());1762  RegisterMCAsmParser<SparcAsmParser> B(getTheSparcV9Target());1763  RegisterMCAsmParser<SparcAsmParser> C(getTheSparcelTarget());1764}1765 1766unsigned SparcAsmParser::validateTargetOperandClass(MCParsedAsmOperand &GOp,1767                                                    unsigned Kind) {1768  SparcOperand &Op = (SparcOperand &)GOp;1769  if (Op.isFloatOrDoubleReg()) {1770    switch (Kind) {1771    default: break;1772    case MCK_DFPRegs:1773      if (!Op.isFloatReg() || SparcOperand::MorphToDoubleReg(Op))1774        return MCTargetAsmParser::Match_Success;1775      break;1776    case MCK_QFPRegs:1777      if (SparcOperand::MorphToQuadReg(Op))1778        return MCTargetAsmParser::Match_Success;1779      break;1780    }1781  }1782  if (Op.isIntReg() && Kind == MCK_IntPair) {1783    if (SparcOperand::MorphToIntPairReg(Op))1784      return MCTargetAsmParser::Match_Success;1785  }1786  if (Op.isCoprocReg() && Kind == MCK_CoprocPair) {1787     if (SparcOperand::MorphToCoprocPairReg(Op))1788       return MCTargetAsmParser::Match_Success;1789   }1790  return Match_InvalidOperand;1791}1792