136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//===-- SparcAsmParser.cpp - Parse Sparc assembly to MCInst instructions --===//
236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//
336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//                     The LLVM Compiler Infrastructure
436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//
536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// This file is distributed under the University of Illinois Open Source
636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// License. See LICENSE.TXT for details.
736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//
836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//===----------------------------------------------------------------------===//
936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "MCTargetDesc/SparcMCTargetDesc.h"
1136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "MCTargetDesc/SparcMCExpr.h"
1236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/ADT/STLExtras.h"
1336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/MC/MCContext.h"
1436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/MC/MCInst.h"
1536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/MC/MCObjectFileInfo.h"
1636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
1736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/MC/MCStreamer.h"
1836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/MC/MCSubtargetInfo.h"
1936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/MC/MCSymbol.h"
2036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/MC/MCTargetAsmParser.h"
2136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/TargetRegistry.h"
2236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
2336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesusing namespace llvm;
2436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
2536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// The generated AsmMatcher SparcGenAsmMatcher uses "Sparc" as the target
2636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// namespace. But SPARC backend uses "SP" as its namespace.
2736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesnamespace llvm {
2836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  namespace Sparc {
2936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    using namespace SP;
3036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
3136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
3236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
3336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesnamespace {
3436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesclass SparcOperand;
3536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesclass SparcAsmParser : public MCTargetAsmParser {
3636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
3736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MCSubtargetInfo &STI;
3836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MCAsmParser &Parser;
3936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
4036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// @name Auto-generated Match Functions
4136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// {
4236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
4336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#define GET_ASSEMBLER_HEADER
4436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "SparcGenAsmMatcher.inc"
4536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
4636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// }
4736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
4836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // public interface of the MCTargetAsmParser.
4936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
50c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                               OperandVector &Operands, MCStreamer &Out,
5137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                               uint64_t &ErrorInfo,
52dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                               bool MatchingInlineAsm) override;
53dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
5436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
55c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                        SMLoc NameLoc, OperandVector &Operands) override;
56dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool ParseDirective(AsmToken DirectiveID) override;
5736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
58c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
59dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                      unsigned Kind) override;
6036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
6136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Custom parse functions for Sparc specific operands.
62c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  OperandMatchResultTy parseMEMOperand(OperandVector &Operands);
6336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
64c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  OperandMatchResultTy parseOperand(OperandVector &Operands, StringRef Name);
6536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
6636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  OperandMatchResultTy
67c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Operand,
68c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                       bool isCall = false);
6936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
70c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  OperandMatchResultTy parseBranchModifiers(OperandVector &Operands);
7136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
7236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // returns true if Tok is matched to a register and returns register in RegNo.
7336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool matchRegisterName(const AsmToken &Tok, unsigned &RegNo,
7436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                         unsigned &RegKind);
7536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
7636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool matchSparcAsmModifiers(const MCExpr *&EVal, SMLoc &EndLoc);
7736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool parseDirectiveWord(unsigned Size, SMLoc L);
7836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
7936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool is64Bit() const { return STI.getTargetTriple().startswith("sparcv9"); }
8036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinespublic:
8136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  SparcAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
82dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                const MCInstrInfo &MII,
83dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                const MCTargetOptions &Options)
8436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      : MCTargetAsmParser(), STI(sti), Parser(parser) {
8536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Initialize the set of available features.
8636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
8736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
8836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
8936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines};
9036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
9136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  static unsigned IntRegs[32] = {
9236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Sparc::G0, Sparc::G1, Sparc::G2, Sparc::G3,
9336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Sparc::G4, Sparc::G5, Sparc::G6, Sparc::G7,
9436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Sparc::O0, Sparc::O1, Sparc::O2, Sparc::O3,
9536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Sparc::O4, Sparc::O5, Sparc::O6, Sparc::O7,
9636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Sparc::L0, Sparc::L1, Sparc::L2, Sparc::L3,
9736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Sparc::L4, Sparc::L5, Sparc::L6, Sparc::L7,
9836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Sparc::I0, Sparc::I1, Sparc::I2, Sparc::I3,
9936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Sparc::I4, Sparc::I5, Sparc::I6, Sparc::I7 };
10036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
10136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  static unsigned FloatRegs[32] = {
10236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Sparc::F0,  Sparc::F1,  Sparc::F2,  Sparc::F3,
10336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Sparc::F4,  Sparc::F5,  Sparc::F6,  Sparc::F7,
10436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Sparc::F8,  Sparc::F9,  Sparc::F10, Sparc::F11,
10536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Sparc::F12, Sparc::F13, Sparc::F14, Sparc::F15,
10636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Sparc::F16, Sparc::F17, Sparc::F18, Sparc::F19,
10736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Sparc::F20, Sparc::F21, Sparc::F22, Sparc::F23,
10836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Sparc::F24, Sparc::F25, Sparc::F26, Sparc::F27,
10936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Sparc::F28, Sparc::F29, Sparc::F30, Sparc::F31 };
11036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
11136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  static unsigned DoubleRegs[32] = {
11236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Sparc::D0,  Sparc::D1,  Sparc::D2,  Sparc::D3,
11336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Sparc::D4,  Sparc::D5,  Sparc::D6,  Sparc::D7,
11436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Sparc::D8,  Sparc::D7,  Sparc::D8,  Sparc::D9,
11536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Sparc::D12, Sparc::D13, Sparc::D14, Sparc::D15,
11636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Sparc::D16, Sparc::D17, Sparc::D18, Sparc::D19,
11736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Sparc::D20, Sparc::D21, Sparc::D22, Sparc::D23,
11836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Sparc::D24, Sparc::D25, Sparc::D26, Sparc::D27,
11936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Sparc::D28, Sparc::D29, Sparc::D30, Sparc::D31 };
12036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
12136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  static unsigned QuadFPRegs[32] = {
12236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Sparc::Q0,  Sparc::Q1,  Sparc::Q2,  Sparc::Q3,
12336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Sparc::Q4,  Sparc::Q5,  Sparc::Q6,  Sparc::Q7,
12436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Sparc::Q8,  Sparc::Q9,  Sparc::Q10, Sparc::Q11,
12536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Sparc::Q12, Sparc::Q13, Sparc::Q14, Sparc::Q15 };
12636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
12736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
12836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// SparcOperand - Instances of this class represent a parsed Sparc machine
12936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// instruction.
13036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesclass SparcOperand : public MCParsedAsmOperand {
13136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinespublic:
13236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  enum RegisterKind {
13336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    rk_None,
13436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    rk_IntReg,
13536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    rk_FloatReg,
13636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    rk_DoubleReg,
13736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    rk_QuadReg,
13836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    rk_CCReg,
13936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    rk_Y
14036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  };
14136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesprivate:
14236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  enum KindTy {
14336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    k_Token,
14436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    k_Register,
14536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    k_Immediate,
14636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    k_MemoryReg,
14736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    k_MemoryImm
14836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } Kind;
14936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
15036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  SMLoc StartLoc, EndLoc;
15136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
15236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  struct Token {
15336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const char *Data;
15436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned Length;
15536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  };
15636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
15736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  struct RegOp {
15836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned RegNum;
15936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    RegisterKind Kind;
16036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  };
16136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
16236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  struct ImmOp {
16336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const MCExpr *Val;
16436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  };
16536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
16636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  struct MemOp {
16736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned Base;
16836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned OffsetReg;
16936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const MCExpr *Off;
17036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  };
17136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
17236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  union {
17336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    struct Token Tok;
17436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    struct RegOp Reg;
17536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    struct ImmOp Imm;
17636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    struct MemOp Mem;
17736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  };
17836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinespublic:
179c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  SparcOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
180c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
181dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isToken() const override { return Kind == k_Token; }
182dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isReg() const override { return Kind == k_Register; }
183dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isImm() const override { return Kind == k_Immediate; }
184dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isMem() const override { return isMEMrr() || isMEMri(); }
18536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool isMEMrr() const { return Kind == k_MemoryReg; }
18636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool isMEMri() const { return Kind == k_MemoryImm; }
18736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
18836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool isFloatReg() const {
18936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return (Kind == k_Register && Reg.Kind == rk_FloatReg);
19036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
19136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
19236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool isFloatOrDoubleReg() const {
19336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return (Kind == k_Register && (Reg.Kind == rk_FloatReg
19436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                   || Reg.Kind == rk_DoubleReg));
19536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
19636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
19736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
19836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  StringRef getToken() const {
19936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(Kind == k_Token && "Invalid access!");
20036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return StringRef(Tok.Data, Tok.Length);
20136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
20236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
203dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned getReg() const override {
20436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert((Kind == k_Register) && "Invalid access!");
20536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return Reg.RegNum;
20636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
20736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
20836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const MCExpr *getImm() const {
20936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert((Kind == k_Immediate) && "Invalid access!");
21036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return Imm.Val;
21136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
21236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
21336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned getMemBase() const {
21436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert((Kind == k_MemoryReg || Kind == k_MemoryImm) && "Invalid access!");
21536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return Mem.Base;
21636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
21736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
21836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned getMemOffsetReg() const {
21936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert((Kind == k_MemoryReg) && "Invalid access!");
22036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return Mem.OffsetReg;
22136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
22236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
22336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const MCExpr *getMemOff() const {
22436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert((Kind == k_MemoryImm) && "Invalid access!");
22536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return Mem.Off;
22636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
22736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
22836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// getStartLoc - Get the location of the first token of this operand.
229dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SMLoc getStartLoc() const override {
23036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return StartLoc;
23136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
23236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// getEndLoc - Get the location of the last token of this operand.
233dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SMLoc getEndLoc() const override {
23436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return EndLoc;
23536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
23636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
237dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void print(raw_ostream &OS) const override {
23836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    switch (Kind) {
23936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case k_Token:     OS << "Token: " << getToken() << "\n"; break;
24036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case k_Register:  OS << "Reg: #" << getReg() << "\n"; break;
24136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case k_Immediate: OS << "Imm: " << getImm() << "\n"; break;
24236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case k_MemoryReg: OS << "Mem: " << getMemBase() << "+"
24336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                         << getMemOffsetReg() << "\n"; break;
244dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case k_MemoryImm: assert(getMemOff() != nullptr);
24536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      OS << "Mem: " << getMemBase()
24636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines         << "+" << *getMemOff()
24736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines         << "\n"; break;
24836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
24936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
25036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
25136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void addRegOperands(MCInst &Inst, unsigned N) const {
25236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(N == 1 && "Invalid number of operands!");
25336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Inst.addOperand(MCOperand::CreateReg(getReg()));
25436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
25536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
25636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void addImmOperands(MCInst &Inst, unsigned N) const {
25736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(N == 1 && "Invalid number of operands!");
25836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const MCExpr *Expr = getImm();
25936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    addExpr(Inst, Expr);
26036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
26136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
26236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void addExpr(MCInst &Inst, const MCExpr *Expr) const{
26336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Add as immediate when possible.  Null MCExpr = 0.
264dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!Expr)
26536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Inst.addOperand(MCOperand::CreateImm(0));
26636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
26736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
26836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else
26936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Inst.addOperand(MCOperand::CreateExpr(Expr));
27036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
27136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
27236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void addMEMrrOperands(MCInst &Inst, unsigned N) const {
27336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(N == 2 && "Invalid number of operands!");
27436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
27536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Inst.addOperand(MCOperand::CreateReg(getMemBase()));
27636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
27736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(getMemOffsetReg() != 0 && "Invalid offset");
27836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Inst.addOperand(MCOperand::CreateReg(getMemOffsetReg()));
27936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
28036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
28136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void addMEMriOperands(MCInst &Inst, unsigned N) const {
28236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(N == 2 && "Invalid number of operands!");
28336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
28436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Inst.addOperand(MCOperand::CreateReg(getMemBase()));
28536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
28636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const MCExpr *Expr = getMemOff();
28736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    addExpr(Inst, Expr);
28836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
28936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
290c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  static std::unique_ptr<SparcOperand> CreateToken(StringRef Str, SMLoc S) {
291c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    auto Op = make_unique<SparcOperand>(k_Token);
29236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Op->Tok.Data = Str.data();
29336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Op->Tok.Length = Str.size();
29436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Op->StartLoc = S;
29536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Op->EndLoc = S;
29636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return Op;
29736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
29836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
299c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  static std::unique_ptr<SparcOperand> CreateReg(unsigned RegNum, unsigned Kind,
300c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                                 SMLoc S, SMLoc E) {
301c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    auto Op = make_unique<SparcOperand>(k_Register);
30236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Op->Reg.RegNum = RegNum;
30336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Op->Reg.Kind   = (SparcOperand::RegisterKind)Kind;
30436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Op->StartLoc = S;
30536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Op->EndLoc = E;
30636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return Op;
30736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
30836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
309c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  static std::unique_ptr<SparcOperand> CreateImm(const MCExpr *Val, SMLoc S,
310c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                                 SMLoc E) {
311c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    auto Op = make_unique<SparcOperand>(k_Immediate);
31236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Op->Imm.Val = Val;
31336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Op->StartLoc = S;
31436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Op->EndLoc = E;
31536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return Op;
31636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
31736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
318c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  static bool MorphToDoubleReg(SparcOperand &Op) {
319c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    unsigned Reg = Op.getReg();
320c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    assert(Op.Reg.Kind == rk_FloatReg);
32136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned regIdx = Reg - Sparc::F0;
32236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (regIdx % 2 || regIdx > 31)
323c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      return false;
324c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    Op.Reg.RegNum = DoubleRegs[regIdx / 2];
325c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    Op.Reg.Kind = rk_DoubleReg;
326c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    return true;
32736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
32836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
329c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  static bool MorphToQuadReg(SparcOperand &Op) {
330c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    unsigned Reg = Op.getReg();
33136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned regIdx = 0;
332c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    switch (Op.Reg.Kind) {
333c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    default: llvm_unreachable("Unexpected register kind!");
33436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case rk_FloatReg:
33536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      regIdx = Reg - Sparc::F0;
33636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (regIdx % 4 || regIdx > 31)
337c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines        return false;
33836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Reg = QuadFPRegs[regIdx / 4];
33936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      break;
34036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case rk_DoubleReg:
34136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      regIdx =  Reg - Sparc::D0;
34236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (regIdx % 2 || regIdx > 31)
343c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines        return false;
34436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Reg = QuadFPRegs[regIdx / 2];
34536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      break;
34636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
347c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    Op.Reg.RegNum = Reg;
348c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    Op.Reg.Kind = rk_QuadReg;
349c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    return true;
35036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
35136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
352c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  static std::unique_ptr<SparcOperand>
353c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  MorphToMEMrr(unsigned Base, std::unique_ptr<SparcOperand> Op) {
35436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned offsetReg = Op->getReg();
35536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Op->Kind = k_MemoryReg;
35636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Op->Mem.Base = Base;
35736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Op->Mem.OffsetReg = offsetReg;
358dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Op->Mem.Off = nullptr;
35936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return Op;
36036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
36136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
362c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  static std::unique_ptr<SparcOperand>
363c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  CreateMEMri(unsigned Base, const MCExpr *Off, SMLoc S, SMLoc E) {
364c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    auto Op = make_unique<SparcOperand>(k_MemoryImm);
36536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Op->Mem.Base = Base;
36636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Op->Mem.OffsetReg = 0;
36736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Op->Mem.Off = Off;
36836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Op->StartLoc = S;
36936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Op->EndLoc = E;
37036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return Op;
37136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
37236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
373c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  static std::unique_ptr<SparcOperand>
374c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  MorphToMEMri(unsigned Base, std::unique_ptr<SparcOperand> Op) {
37536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const MCExpr *Imm  = Op->getImm();
37636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Op->Kind = k_MemoryImm;
37736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Op->Mem.Base = Base;
37836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Op->Mem.OffsetReg = 0;
37936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Op->Mem.Off = Imm;
38036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return Op;
38136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
38236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines};
38336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
38436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} // end namespace
38536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
386c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesbool SparcAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
387c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                             OperandVector &Operands,
388c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                             MCStreamer &Out,
38937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                             uint64_t &ErrorInfo,
390c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                             bool MatchingInlineAsm) {
39136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MCInst Inst;
39236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  SmallVector<MCInst, 8> Instructions;
39336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
39436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                              MatchingInlineAsm);
39536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  switch (MatchResult) {
39636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Match_Success: {
39736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Inst.setLoc(IDLoc);
39836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Out.EmitInstruction(Inst, STI);
39936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
40036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
40136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
40236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Match_MissingFeature:
40336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return Error(IDLoc,
40436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                 "instruction requires a CPU feature not currently enabled");
40536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
40636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Match_InvalidOperand: {
40736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    SMLoc ErrorLoc = IDLoc;
40837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (ErrorInfo != ~0ULL) {
40936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (ErrorInfo >= Operands.size())
41036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return Error(IDLoc, "too few operands for instruction");
41136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
412c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      ErrorLoc = ((SparcOperand &)*Operands[ErrorInfo]).getStartLoc();
41336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (ErrorLoc == SMLoc())
41436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        ErrorLoc = IDLoc;
41536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
41636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
41736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return Error(ErrorLoc, "invalid operand for instruction");
41836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
41936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case Match_MnemonicFail:
42036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return Error(IDLoc, "invalid instruction mnemonic");
42136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
422ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  llvm_unreachable("Implement any new match types added!");
42336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
42436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
42536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool SparcAsmParser::
42636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc)
42736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines{
42836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const AsmToken &Tok = Parser.getTok();
42936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  StartLoc = Tok.getLoc();
43036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EndLoc = Tok.getEndLoc();
43136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  RegNo = 0;
43236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (getLexer().getKind() != AsmToken::Percent)
43336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
43436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Parser.Lex();
43536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned regKind = SparcOperand::rk_None;
43636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (matchRegisterName(Tok, RegNo, regKind)) {
43736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Parser.Lex();
43836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
43936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
44036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
44136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return Error(StartLoc, "invalid register name");
44236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
44336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
44437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic void applyMnemonicAliases(StringRef &Mnemonic, uint64_t Features,
44536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                 unsigned VariantID);
44636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
447c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesbool SparcAsmParser::ParseInstruction(ParseInstructionInfo &Info,
448c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                      StringRef Name, SMLoc NameLoc,
449c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                      OperandVector &Operands) {
45036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
45136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // First operand in MCInst is instruction mnemonic.
45236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Operands.push_back(SparcOperand::CreateToken(Name, NameLoc));
45336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
45436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // apply mnemonic aliases, if any, so that we can parse operands correctly.
45536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  applyMnemonicAliases(Name, getAvailableFeatures(), 0);
45636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
45736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (getLexer().isNot(AsmToken::EndOfStatement)) {
45836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Read the first operand.
45936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (getLexer().is(AsmToken::Comma)) {
46036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (parseBranchModifiers(Operands) != MatchOperand_Success) {
46136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        SMLoc Loc = getLexer().getLoc();
46236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Parser.eatToEndOfStatement();
46336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return Error(Loc, "unexpected token");
46436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      }
46536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
46636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (parseOperand(Operands, Name) != MatchOperand_Success) {
46736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      SMLoc Loc = getLexer().getLoc();
46836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Parser.eatToEndOfStatement();
46936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return Error(Loc, "unexpected token");
47036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
47136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
47236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    while (getLexer().is(AsmToken::Comma)) {
47336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Parser.Lex(); // Eat the comma.
47436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // Parse and remember the operand.
47536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (parseOperand(Operands, Name) != MatchOperand_Success) {
47636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        SMLoc Loc = getLexer().getLoc();
47736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Parser.eatToEndOfStatement();
47836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return Error(Loc, "unexpected token");
47936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      }
48036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
48136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
48236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (getLexer().isNot(AsmToken::EndOfStatement)) {
48336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    SMLoc Loc = getLexer().getLoc();
48436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Parser.eatToEndOfStatement();
48536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return Error(Loc, "unexpected token");
48636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
48736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Parser.Lex(); // Consume the EndOfStatement.
48836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return false;
48936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
49036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
49136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool SparcAsmParser::
49236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesParseDirective(AsmToken DirectiveID)
49336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines{
49436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  StringRef IDVal = DirectiveID.getString();
49536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
49636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (IDVal == ".byte")
49736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return parseDirectiveWord(1, DirectiveID.getLoc());
49836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
49936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (IDVal == ".half")
50036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return parseDirectiveWord(2, DirectiveID.getLoc());
50136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
50236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (IDVal == ".word")
50336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return parseDirectiveWord(4, DirectiveID.getLoc());
50436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
50536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (IDVal == ".nword")
50636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return parseDirectiveWord(is64Bit() ? 8 : 4, DirectiveID.getLoc());
50736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
50836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (is64Bit() && IDVal == ".xword")
50936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return parseDirectiveWord(8, DirectiveID.getLoc());
51036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
51136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (IDVal == ".register") {
51236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // For now, ignore .register directive.
51336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Parser.eatToEndOfStatement();
51436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
51536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
51636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
51736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Let the MC layer to handle other directives.
51836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return true;
51936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
52036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
52136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool SparcAsmParser:: parseDirectiveWord(unsigned Size, SMLoc L) {
52236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (getLexer().isNot(AsmToken::EndOfStatement)) {
52336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    for (;;) {
52436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      const MCExpr *Value;
52536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (getParser().parseExpression(Value))
52636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return true;
52736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
52836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      getParser().getStreamer().EmitValue(Value, Size);
52936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
53036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (getLexer().is(AsmToken::EndOfStatement))
53136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        break;
53236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
53336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // FIXME: Improve diagnostic.
53436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (getLexer().isNot(AsmToken::Comma))
53536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return Error(L, "unexpected token in directive");
53636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Parser.Lex();
53736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
53836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
53936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Parser.Lex();
54036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return false;
54136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
54236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
543c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesSparcAsmParser::OperandMatchResultTy
544c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesSparcAsmParser::parseMEMOperand(OperandVector &Operands) {
54536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
54636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  SMLoc S, E;
54736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned BaseReg = 0;
54836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
54936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (ParseRegister(BaseReg, S, E)) {
55036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return MatchOperand_NoMatch;
55136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
55236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
55336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  switch (getLexer().getKind()) {
55436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  default: return MatchOperand_NoMatch;
55536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
55636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case AsmToken::Comma:
55736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case AsmToken::RBrac:
55836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case AsmToken::EndOfStatement:
559dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Operands.push_back(SparcOperand::CreateMEMri(BaseReg, nullptr, S, E));
56036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return MatchOperand_Success;
56136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
56236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case AsmToken:: Plus:
56336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Parser.Lex(); // Eat the '+'
56436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
56536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case AsmToken::Minus:
56636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
56736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
56836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
569c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  std::unique_ptr<SparcOperand> Offset;
57036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  OperandMatchResultTy ResTy = parseSparcAsmOperand(Offset);
57136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (ResTy != MatchOperand_Success || !Offset)
57236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return MatchOperand_NoMatch;
57336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
574c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  Operands.push_back(
575c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      Offset->isImm() ? SparcOperand::MorphToMEMri(BaseReg, std::move(Offset))
576c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                      : SparcOperand::MorphToMEMrr(BaseReg, std::move(Offset)));
57736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
57836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return MatchOperand_Success;
57936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
58036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
581c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesSparcAsmParser::OperandMatchResultTy
582c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesSparcAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
58336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
58436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
58536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
58636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // If there wasn't a custom match, try the generic matcher below. Otherwise,
58736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // there was a match, but an error occurred, in which case, just return that
58836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // the operand parsing failed.
58936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (ResTy == MatchOperand_Success || ResTy == MatchOperand_ParseFail)
59036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return ResTy;
59136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
59236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (getLexer().is(AsmToken::LBrac)) {
59336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Memory operand
59436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Operands.push_back(SparcOperand::CreateToken("[",
59536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                                 Parser.getTok().getLoc()));
59636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Parser.Lex(); // Eat the [
59736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
59836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Mnemonic == "cas" || Mnemonic == "casx") {
59936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      SMLoc S = Parser.getTok().getLoc();
60036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (getLexer().getKind() != AsmToken::Percent)
60136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return MatchOperand_NoMatch;
60236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Parser.Lex(); // eat %
60336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
60436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      unsigned RegNo, RegKind;
60536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (!matchRegisterName(Parser.getTok(), RegNo, RegKind))
60636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return MatchOperand_NoMatch;
60736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
60836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Parser.Lex(); // Eat the identifier token.
60936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer()-1);
61036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Operands.push_back(SparcOperand::CreateReg(RegNo, RegKind, S, E));
61136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      ResTy = MatchOperand_Success;
61236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    } else {
61336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      ResTy = parseMEMOperand(Operands);
61436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
61536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
61636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (ResTy != MatchOperand_Success)
61736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return ResTy;
61836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
61936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (!getLexer().is(AsmToken::RBrac))
62036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return MatchOperand_ParseFail;
62136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
62236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Operands.push_back(SparcOperand::CreateToken("]",
62336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                                 Parser.getTok().getLoc()));
62436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Parser.Lex(); // Eat the ]
62536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return MatchOperand_Success;
62636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
62736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
628c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  std::unique_ptr<SparcOperand> Op;
62936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
63036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ResTy = parseSparcAsmOperand(Op, (Mnemonic == "call"));
63136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (ResTy != MatchOperand_Success || !Op)
63236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return MatchOperand_ParseFail;
63336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
63436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Push the parsed operand into the list of operands
635c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  Operands.push_back(std::move(Op));
63636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
63736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return MatchOperand_Success;
63836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
63936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
64036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesSparcAsmParser::OperandMatchResultTy
641c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesSparcAsmParser::parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Op,
642c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                     bool isCall) {
64336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
64436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  SMLoc S = Parser.getTok().getLoc();
64536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
64636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const MCExpr *EVal;
64736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
648dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Op = nullptr;
64936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  switch (getLexer().getKind()) {
65036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  default:  break;
65136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
65236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case AsmToken::Percent:
65336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Parser.Lex(); // Eat the '%'.
65436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned RegNo;
65536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned RegKind;
65636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (matchRegisterName(Parser.getTok(), RegNo, RegKind)) {
65736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      StringRef name = Parser.getTok().getString();
65836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Parser.Lex(); // Eat the identifier token.
65936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
66036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      switch (RegNo) {
66136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      default:
66236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Op = SparcOperand::CreateReg(RegNo, RegKind, S, E);
66336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        break;
66436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      case Sparc::Y:
66536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Op = SparcOperand::CreateToken("%y", S);
66636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        break;
66736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
66836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      case Sparc::ICC:
66936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        if (name == "xcc")
67036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          Op = SparcOperand::CreateToken("%xcc", S);
67136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        else
67236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          Op = SparcOperand::CreateToken("%icc", S);
67336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        break;
67436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      }
67536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      break;
67636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
67736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (matchSparcAsmModifiers(EVal, E)) {
67836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
67936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Op = SparcOperand::CreateImm(EVal, S, E);
68036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
68136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
68236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
68336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case AsmToken::Minus:
68436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case AsmToken::Integer:
68536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (!getParser().parseExpression(EVal, E))
68636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Op = SparcOperand::CreateImm(EVal, S, E);
68736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
68836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
68936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case AsmToken::Identifier: {
69036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    StringRef Identifier;
69136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (!getParser().parseIdentifier(Identifier)) {
69236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
69336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      MCSymbol *Sym = getContext().GetOrCreateSymbol(Identifier);
69436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
69536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
69636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                                  getContext());
69736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (isCall &&
69836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_)
69936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Res = SparcMCExpr::Create(SparcMCExpr::VK_Sparc_WPLT30, Res,
70036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                  getContext());
70136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Op = SparcOperand::CreateImm(Res, S, E);
70236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
70336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
70436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
70536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
70636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return (Op) ? MatchOperand_Success : MatchOperand_ParseFail;
70736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
70836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
709c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesSparcAsmParser::OperandMatchResultTy
710c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesSparcAsmParser::parseBranchModifiers(OperandVector &Operands) {
71136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
71236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // parse (,a|,pn|,pt)+
71336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
71436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  while (getLexer().is(AsmToken::Comma)) {
71536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
71636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Parser.Lex(); // Eat the comma
71736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
71836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (!getLexer().is(AsmToken::Identifier))
71936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return MatchOperand_ParseFail;
72036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    StringRef modName = Parser.getTok().getString();
72136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (modName == "a" || modName == "pn" || modName == "pt") {
72236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Operands.push_back(SparcOperand::CreateToken(modName,
72336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                                   Parser.getTok().getLoc()));
72436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Parser.Lex(); // eat the identifier.
72536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
72636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
72736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return MatchOperand_Success;
72836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
72936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
73036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool SparcAsmParser::matchRegisterName(const AsmToken &Tok,
73136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                       unsigned &RegNo,
73236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                       unsigned &RegKind)
73336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines{
73436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  int64_t intVal = 0;
73536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  RegNo = 0;
73636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  RegKind = SparcOperand::rk_None;
73736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Tok.is(AsmToken::Identifier)) {
73836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    StringRef name = Tok.getString();
73936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
74036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // %fp
74136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (name.equals("fp")) {
74236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      RegNo = Sparc::I6;
74336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      RegKind = SparcOperand::rk_IntReg;
74436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return true;
74536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
74636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // %sp
74736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (name.equals("sp")) {
74836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      RegNo = Sparc::O6;
74936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      RegKind = SparcOperand::rk_IntReg;
75036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return true;
75136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
75236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
75336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (name.equals("y")) {
75436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      RegNo = Sparc::Y;
75536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      RegKind = SparcOperand::rk_Y;
75636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return true;
75736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
75836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
75936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (name.equals("icc")) {
76036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      RegNo = Sparc::ICC;
76136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      RegKind = SparcOperand::rk_CCReg;
76236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return true;
76336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
76436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
76536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (name.equals("xcc")) {
76636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // FIXME:: check 64bit.
76736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      RegNo = Sparc::ICC;
76836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      RegKind = SparcOperand::rk_CCReg;
76936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return true;
77036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
77136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
77236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // %fcc0 - %fcc3
77336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (name.substr(0, 3).equals_lower("fcc")
77436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        && !name.substr(3).getAsInteger(10, intVal)
77536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        && intVal < 4) {
77636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // FIXME: check 64bit and  handle %fcc1 - %fcc3
77736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      RegNo = Sparc::FCC0 + intVal;
77836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      RegKind = SparcOperand::rk_CCReg;
77936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return true;
78036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
78136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
78236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // %g0 - %g7
78336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (name.substr(0, 1).equals_lower("g")
78436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        && !name.substr(1).getAsInteger(10, intVal)
78536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        && intVal < 8) {
78636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      RegNo = IntRegs[intVal];
78736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      RegKind = SparcOperand::rk_IntReg;
78836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return true;
78936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
79036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // %o0 - %o7
79136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (name.substr(0, 1).equals_lower("o")
79236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        && !name.substr(1).getAsInteger(10, intVal)
79336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        && intVal < 8) {
79436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      RegNo = IntRegs[8 + intVal];
79536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      RegKind = SparcOperand::rk_IntReg;
79636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return true;
79736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
79836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (name.substr(0, 1).equals_lower("l")
79936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        && !name.substr(1).getAsInteger(10, intVal)
80036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        && intVal < 8) {
80136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      RegNo = IntRegs[16 + intVal];
80236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      RegKind = SparcOperand::rk_IntReg;
80336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return true;
80436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
80536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (name.substr(0, 1).equals_lower("i")
80636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        && !name.substr(1).getAsInteger(10, intVal)
80736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        && intVal < 8) {
80836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      RegNo = IntRegs[24 + intVal];
80936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      RegKind = SparcOperand::rk_IntReg;
81036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return true;
81136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
81236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // %f0 - %f31
81336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (name.substr(0, 1).equals_lower("f")
81436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 32) {
81536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      RegNo = FloatRegs[intVal];
81636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      RegKind = SparcOperand::rk_FloatReg;
81736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return true;
81836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
81936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // %f32 - %f62
82036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (name.substr(0, 1).equals_lower("f")
82136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        && !name.substr(1, 2).getAsInteger(10, intVal)
82236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        && intVal >= 32 && intVal <= 62 && (intVal % 2 == 0)) {
82336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // FIXME: Check V9
82436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      RegNo = DoubleRegs[intVal/2];
82536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      RegKind = SparcOperand::rk_DoubleReg;
82636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return true;
82736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
82836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
82936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // %r0 - %r31
83036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (name.substr(0, 1).equals_lower("r")
83136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 31) {
83236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      RegNo = IntRegs[intVal];
83336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      RegKind = SparcOperand::rk_IntReg;
83436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return true;
83536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
83636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
83736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return false;
83836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
83936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
84036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic bool hasGOTReference(const MCExpr *Expr) {
84136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  switch (Expr->getKind()) {
84236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MCExpr::Target:
84336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (const SparcMCExpr *SE = dyn_cast<SparcMCExpr>(Expr))
84436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return hasGOTReference(SE->getSubExpr());
84536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
84636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
84736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MCExpr::Constant:
84836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
84936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
85036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MCExpr::Binary: {
85136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
85236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return hasGOTReference(BE->getLHS()) || hasGOTReference(BE->getRHS());
85336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
85436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
85536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MCExpr::SymbolRef: {
85636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr);
85736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return (SymRef.getSymbol().getName() == "_GLOBAL_OFFSET_TABLE_");
85836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
85936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
86036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MCExpr::Unary:
86136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return hasGOTReference(cast<MCUnaryExpr>(Expr)->getSubExpr());
86236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
86336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return false;
86436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
86536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
86636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal,
86736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                            SMLoc &EndLoc)
86836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines{
86936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  AsmToken Tok = Parser.getTok();
87036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!Tok.is(AsmToken::Identifier))
87136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
87236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
87336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  StringRef name = Tok.getString();
87436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
87536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  SparcMCExpr::VariantKind VK = SparcMCExpr::parseVariantKind(name);
87636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
87736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (VK == SparcMCExpr::VK_Sparc_None)
87836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
87936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
88036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Parser.Lex(); // Eat the identifier.
88136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Parser.getTok().getKind() != AsmToken::LParen)
88236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
88336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
88436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Parser.Lex(); // Eat the LParen token.
88536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const MCExpr *subExpr;
88636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Parser.parseParenExpression(subExpr, EndLoc))
88736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
88836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
88936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool isPIC = getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_;
89036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
89136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  switch(VK) {
89236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  default: break;
89336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case SparcMCExpr::VK_Sparc_LO:
89436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    VK =  (hasGOTReference(subExpr)
89536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines           ? SparcMCExpr::VK_Sparc_PC10
89636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines           : (isPIC ? SparcMCExpr::VK_Sparc_GOT10 : VK));
89736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
89836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case SparcMCExpr::VK_Sparc_HI:
89936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    VK =  (hasGOTReference(subExpr)
90036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines           ? SparcMCExpr::VK_Sparc_PC22
90136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines           : (isPIC ? SparcMCExpr::VK_Sparc_GOT22 : VK));
90236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
90336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
90436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
90536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EVal = SparcMCExpr::Create(VK, subExpr, getContext());
90636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return true;
90736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
90836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
90936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
91036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesextern "C" void LLVMInitializeSparcAsmParser() {
91136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  RegisterMCAsmParser<SparcAsmParser> A(TheSparcTarget);
91236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  RegisterMCAsmParser<SparcAsmParser> B(TheSparcV9Target);
91336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
91436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
91536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#define GET_REGISTER_MATCHER
91636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#define GET_MATCHER_IMPLEMENTATION
91736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "SparcGenAsmMatcher.inc"
91836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
919c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesunsigned SparcAsmParser::validateTargetOperandClass(MCParsedAsmOperand &GOp,
920c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                                    unsigned Kind) {
921c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  SparcOperand &Op = (SparcOperand &)GOp;
922c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (Op.isFloatOrDoubleReg()) {
92336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    switch (Kind) {
92436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    default: break;
92536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case MCK_DFPRegs:
926c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      if (!Op.isFloatReg() || SparcOperand::MorphToDoubleReg(Op))
92736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return MCTargetAsmParser::Match_Success;
92836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      break;
92936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case MCK_QFPRegs:
93036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (SparcOperand::MorphToQuadReg(Op))
93136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return MCTargetAsmParser::Match_Success;
93236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      break;
93336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
93436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
93536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return Match_InvalidOperand;
93636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
937