31#define DEBUG_TYPE "msp430-asm-parser" 
   42  bool matchAndEmitInstruction(
SMLoc IDLoc, 
unsigned &Opcode,
 
   45                               bool MatchingInlineAsm) 
override;
 
   49                               SMLoc &EndLoc) 
override;
 
   55  bool ParseDirectiveRefSym(
AsmToken DirectiveID);
 
   58                                      unsigned Kind) 
override;
 
   65  bool ParseLiteralValues(
unsigned Size, 
SMLoc L);
 
   73#define GET_ASSEMBLER_HEADER 
   74#include "MSP430GenAsmMatcher.inc" 
   83    MRI = getContext().getRegisterInfo();
 
   85    setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
 
   91  typedef MCParsedAsmOperand Base;
 
  104    const MCExpr *Offset;
 
  116  MSP430Operand(StringRef Tok, SMLoc 
const &S)
 
  117      : Kind(k_Tok), Tok(Tok), Start(S), End(S) {}
 
  118  MSP430Operand(KindTy Kind, MCRegister 
Reg, SMLoc 
const &S, SMLoc 
const &
E)
 
  119      : Kind(Kind), 
Reg(
Reg), Start(S), End(
E) {}
 
  120  MSP430Operand(MCExpr 
const *Imm, SMLoc 
const &S, SMLoc 
const &
E)
 
  121      : Kind(k_Imm), 
Imm(
Imm), Start(S), End(
E) {}
 
  122  MSP430Operand(MCRegister 
Reg, MCExpr 
const *Expr, SMLoc 
const &S,
 
  124      : Kind(k_Mem), Mem({
Reg, Expr}), Start(S), End(
E) {}
 
  126  void addRegOperands(MCInst &Inst, 
unsigned N)
 const {
 
  127    assert((Kind == k_Reg || Kind == k_IndReg || Kind == k_PostIndReg) &&
 
  128        "Unexpected operand kind");
 
  129    assert(
N == 1 && 
"Invalid number of operands!");
 
  134  void addExprOperand(MCInst &Inst, 
const MCExpr *Expr)
 const {
 
  144  void addImmOperands(MCInst &Inst, 
unsigned N)
 const {
 
  145    assert(Kind == k_Imm && 
"Unexpected operand kind");
 
  146    assert(
N == 1 && 
"Invalid number of operands!");
 
  148    addExprOperand(Inst, Imm);
 
  151  void addMemOperands(MCInst &Inst, 
unsigned N)
 const {
 
  152    assert(Kind == k_Mem && 
"Unexpected operand kind");
 
  153    assert(
N == 2 && 
"Invalid number of operands");
 
  156    addExprOperand(Inst, Mem.Offset);
 
  159  bool isReg()
   const override { 
return Kind == k_Reg; }
 
  160  bool isImm()
   const override { 
return Kind == k_Imm; }
 
  161  bool isToken()
 const override { 
return Kind == k_Tok; }
 
  162  bool isMem()
   const override { 
return Kind == k_Mem; }
 
  163  bool isIndReg()
         const { 
return Kind == k_IndReg; }
 
  164  bool isPostIndReg()
     const { 
return Kind == k_PostIndReg; }
 
  166  bool isCGImm()
 const {
 
  171    if (!
Imm->evaluateAsAbsolute(Val))
 
  174    if (Val == 0 || Val == 1 || Val == 2 || Val == 4 || Val == 8 || Val == -1)
 
  181    assert(Kind == k_Tok && 
"Invalid access!");
 
  185  MCRegister 
getReg()
 const override {
 
  186    assert(Kind == k_Reg && 
"Invalid access!");
 
  190  void setReg(MCRegister RegNo) {
 
  191    assert(Kind == k_Reg && 
"Invalid access!");
 
  195  static std::unique_ptr<MSP430Operand> CreateToken(StringRef Str, SMLoc S) {
 
  196    return std::make_unique<MSP430Operand>(Str, S);
 
  199  static std::unique_ptr<MSP430Operand> CreateReg(MCRegister 
Reg, SMLoc S,
 
  201    return std::make_unique<MSP430Operand>(k_Reg, 
Reg, S, 
E);
 
  204  static std::unique_ptr<MSP430Operand> CreateImm(
const MCExpr *Val, SMLoc S,
 
  206    return std::make_unique<MSP430Operand>(Val, S, 
E);
 
  209  static std::unique_ptr<MSP430Operand>
 
  210  CreateMem(MCRegister 
Reg, 
const MCExpr *Val, SMLoc S, SMLoc 
E) {
 
  211    return std::make_unique<MSP430Operand>(
Reg, Val, S, 
E);
 
  214  static std::unique_ptr<MSP430Operand> CreateIndReg(MCRegister 
Reg, SMLoc S,
 
  216    return std::make_unique<MSP430Operand>(k_IndReg, 
Reg, S, 
E);
 
  219  static std::unique_ptr<MSP430Operand> CreatePostIndReg(MCRegister 
Reg,
 
  221    return std::make_unique<MSP430Operand>(k_PostIndReg, 
Reg, S, 
E);
 
  224  SMLoc getStartLoc()
 const override { 
return Start; }
 
  225  SMLoc getEndLoc()
 const override { 
return End; }
 
  227  void print(raw_ostream &O, 
const MCAsmInfo &MAI)
 const override {
 
  230      O << 
"Token " << Tok;
 
  233      O << 
"Register " << 
Reg;
 
  244      O << 
"RegInd " << 
Reg;
 
  247      O << 
"PostInc " << 
Reg;
 
  254bool MSP430AsmParser::matchAndEmitInstruction(
SMLoc Loc, 
unsigned &Opcode,
 
  258                                              bool MatchingInlineAsm) {
 
  260  unsigned MatchResult =
 
  261      MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
 
  263  switch (MatchResult) {
 
  268  case Match_MnemonicFail:
 
  269    return Error(Loc, 
"invalid instruction mnemonic");
 
  270  case Match_InvalidOperand: {
 
  271    SMLoc ErrorLoc = Loc;
 
  272    if (ErrorInfo != ~0U) {
 
  273      if (ErrorInfo >= Operands.
size())
 
  274        return Error(ErrorLoc, 
"too few operands for instruction");
 
  276      ErrorLoc = ((MSP430Operand &)*Operands[ErrorInfo]).getStartLoc();
 
  277      if (ErrorLoc == SMLoc())
 
  280    return Error(ErrorLoc, 
"invalid operand for instruction");
 
  295    return Error(StartLoc, 
"invalid register name");
 
  304ParseStatus MSP430AsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
 
  307    auto Name = getLexer().getTok().getIdentifier().lower();
 
  309    if (
Reg == MSP430::NoRegister) {
 
  311      if (
Reg == MSP430::NoRegister)
 
  315    AsmToken 
const &
T = getParser().getTok();
 
  316    StartLoc = 
T.getLoc();
 
  317    EndLoc = 
T.getEndLoc();
 
  326bool MSP430AsmParser::parseJccInstruction(ParseInstructionInfo &
Info,
 
  327                                          StringRef Name, SMLoc NameLoc,
 
  329  if (!
Name.starts_with_insensitive(
"j"))
 
  332  auto CC = 
Name.drop_front().lower();
 
  334  if (CC == 
"ne" || CC == 
"nz")
 
  336  else if (CC == 
"eq" || CC == 
"z")
 
  338  else if (CC == 
"lo" || CC == 
"nc")
 
  340  else if (CC == 
"hs" || CC == 
"c")
 
  351    return Error(NameLoc, 
"unknown instruction");
 
  354    Operands.
push_back(MSP430Operand::CreateToken(
"jmp", NameLoc));
 
  356    Operands.
push_back(MSP430Operand::CreateToken(
"j", NameLoc));
 
  358    Operands.
push_back(MSP430Operand::CreateImm(CCode, SMLoc(), SMLoc()));
 
  365  SMLoc ExprLoc = getLexer().getLoc();
 
  366  if (getParser().parseExpression(Val))
 
  367    return Error(ExprLoc, 
"expected expression operand");
 
  370  if (Val->evaluateAsAbsolute(Res))
 
  371    if (Res < -512 || Res > 511)
 
  372      return Error(ExprLoc, 
"invalid jump offset");
 
  374  Operands.
push_back(MSP430Operand::CreateImm(Val, ExprLoc,
 
  375    getLexer().getLoc()));
 
  378    SMLoc Loc = getLexer().getLoc();
 
  379    getParser().eatToEndOfStatement();
 
  380    return Error(Loc, 
"unexpected token");
 
  387bool MSP430AsmParser::parseInstruction(ParseInstructionInfo &
Info,
 
  388                                       StringRef Name, SMLoc NameLoc,
 
  391  if (
Name.ends_with_insensitive(
".w"))
 
  394  if (!parseJccInstruction(
Info, Name, NameLoc, Operands))
 
  398  Operands.
push_back(MSP430Operand::CreateToken(Name, NameLoc));
 
  405  if (ParseOperand(Operands))
 
  413    SMLoc Loc = getLexer().getLoc();
 
  414    getParser().eatToEndOfStatement();
 
  415    return Error(Loc, 
"unexpected token");
 
  422bool MSP430AsmParser::ParseDirectiveRefSym(AsmToken DirectiveID) {
 
  424  if (getParser().parseIdentifier(Name))
 
  425    return TokError(
"expected identifier in directive");
 
  428  getStreamer().emitSymbolAttribute(Sym, 
MCSA_Global);
 
  432ParseStatus MSP430AsmParser::parseDirective(AsmToken DirectiveID) {
 
  434  if (IDVal.
lower() == 
".long")
 
  435    return ParseLiteralValues(4, DirectiveID.
getLoc());
 
  436  if (IDVal.
lower() == 
".word" || IDVal.
lower() == 
".short")
 
  437    return ParseLiteralValues(2, DirectiveID.
getLoc());
 
  438  if (IDVal.
lower() == 
".byte")
 
  439    return ParseLiteralValues(1, DirectiveID.
getLoc());
 
  440  if (IDVal.
lower() == 
".refsym")
 
  441    return ParseDirectiveRefSym(DirectiveID);
 
  446  switch (getLexer().getKind()) {
 
  447    default: 
return true;
 
  451      SMLoc StartLoc, EndLoc;
 
  452      if (!parseRegister(RegNo, StartLoc, EndLoc)) {
 
  453        Operands.
push_back(MSP430Operand::CreateReg(RegNo, StartLoc, EndLoc));
 
  461      SMLoc StartLoc = getParser().getTok().getLoc();
 
  464      if (!getParser().parseExpression(Val)) {
 
  465        MCRegister RegNo = MSP430::PC;
 
  466        SMLoc EndLoc = getParser().getTok().getLoc();
 
  470          if (parseRegister(RegNo, RegStartLoc, EndLoc))
 
  472          EndLoc = getParser().getTok().getEndLoc();
 
  476        Operands.
push_back(MSP430Operand::CreateMem(RegNo, Val, StartLoc,
 
  484      SMLoc StartLoc = getParser().getTok().getLoc();
 
  487      if (!getParser().parseExpression(Val)) {
 
  488        SMLoc EndLoc = getParser().getTok().getLoc();
 
  489        Operands.
push_back(MSP430Operand::CreateMem(MSP430::SR, Val, StartLoc,
 
  497      SMLoc StartLoc = getParser().getTok().getLoc();
 
  500      SMLoc RegStartLoc, EndLoc;
 
  501      if (parseRegister(RegNo, RegStartLoc, EndLoc))
 
  504        Operands.
push_back(MSP430Operand::CreatePostIndReg(RegNo, StartLoc, EndLoc));
 
  507      if (Operands.
size() > 1) 
 
  508        Operands.
push_back(MSP430Operand::CreateMem(RegNo,
 
  511        Operands.
push_back(MSP430Operand::CreateIndReg(RegNo, StartLoc, EndLoc));
 
  516      SMLoc StartLoc = getParser().getTok().getLoc();
 
  519      if (!getParser().parseExpression(Val)) {
 
  520        SMLoc EndLoc = getParser().getTok().getLoc();
 
  521        Operands.
push_back(MSP430Operand::CreateImm(Val, StartLoc, EndLoc));
 
  528bool MSP430AsmParser::ParseLiteralValues(
unsigned Size, SMLoc L) {
 
  529  auto parseOne = [&]() -> 
bool {
 
  531    if (getParser().parseExpression(
Value))
 
  533    getParser().getStreamer().emitValue(
Value, 
Size, L);
 
  536  return (parseMany(parseOne));
 
  544#define GET_REGISTER_MATCHER 
  545#define GET_MATCHER_IMPLEMENTATION 
  546#include "MSP430GenAsmMatcher.inc" 
  552  case MSP430::PC:  
return MSP430::PCB;
 
  553  case MSP430::SP:  
return MSP430::SPB;
 
  554  case MSP430::SR:  
return MSP430::SRB;
 
  555  case MSP430::CG:  
return MSP430::CGB;
 
  556  case MSP430::R4:  
return MSP430::R4B;
 
  557  case MSP430::R5:  
return MSP430::R5B;
 
  558  case MSP430::R6:  
return MSP430::R6B;
 
  559  case MSP430::R7:  
return MSP430::R7B;
 
  560  case MSP430::R8:  
return MSP430::R8B;
 
  561  case MSP430::R9:  
return MSP430::R9B;
 
  562  case MSP430::R10: 
return MSP430::R10B;
 
  563  case MSP430::R11: 
return MSP430::R11B;
 
  564  case MSP430::R12: 
return MSP430::R12B;
 
  565  case MSP430::R13: 
return MSP430::R13B;
 
  566  case MSP430::R14: 
return MSP430::R14B;
 
  567  case MSP430::R15: 
return MSP430::R15B;
 
 
  571unsigned MSP430AsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
 
  573  MSP430Operand &
Op = 
static_cast<MSP430Operand &
>(AsmOp);
 
  576    return Match_InvalidOperand;
 
  578  MCRegister 
Reg = 
Op.getReg();
 
  580      MSP430MCRegisterClasses[MSP430::GR16RegClassID].contains(
Reg);
 
  582  if (isGR16 && (Kind == MCK_GR8)) {
 
  584    return Match_Success;
 
  587  return Match_InvalidOperand;
 
unsigned const MachineRegisterInfo * MRI
 
static MCRegister MatchRegisterName(StringRef Name)
 
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
 
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
 
This file implements a class to represent arbitrary precision integral constant values and operations...
 
static MCRegister MatchRegisterAltName(StringRef Name)
Maps from the set of all alternative registernames to a register number.
 
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
 
Analysis containing CSE Info
 
#define LLVM_EXTERNAL_VISIBILITY
 
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMSP430AsmParser()
 
static MCRegister convertGR16ToGR8(MCRegister Reg)
 
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
 
static bool isReg(const MCInst &MI, unsigned OpNo)
 
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
 
Target independent representation for an assembler token.
 
LLVM_ABI SMLoc getLoc() const
 
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
 
Base class for user error types.
 
void printExpr(raw_ostream &, const MCExpr &) const
 
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
 
Generic assembler parser interface, for use by target specific assembly parsers.
 
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
 
void addOperand(const MCOperand Op)
 
Interface to description of machine instruction set.
 
static MCOperand createExpr(const MCExpr *Val)
 
static MCOperand createReg(MCRegister Reg)
 
static MCOperand createImm(int64_t Val)
 
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
 
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
 
Wrapper class representing physical registers. Should be passed by value.
 
Streaming machine code generation interface.
 
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
 
Generic base class for all target subtargets.
 
const FeatureBitset & getFeatureBits() const
 
MCTargetAsmParser - Generic interface to target specific assembly parsers.
 
Ternary parse status returned by various parse* methods.
 
constexpr bool isFailure() const
 
static constexpr StatusTy Failure
 
constexpr bool isSuccess() const
 
static constexpr StatusTy Success
 
static constexpr StatusTy NoMatch
 
constexpr bool isNoMatch() const
 
Represents a location in source code.
 
void push_back(const T &Elt)
 
StringRef - Represent a constant reference to a string, i.e.
 
LLVM_ABI std::string lower() const
 
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
 
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
 
@ CE
Windows NT (Windows on ARM)
 
Context & getContext() const
 
This is an optimization pass for GlobalISel generic memory operations.
 
FunctionAddr VTableAddr Value
 
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
 
static bool isMem(const MachineInstr &MI, unsigned Op)
 
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
 
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
 
Target & getTheMSP430Target()
 
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
 
DWARFExpression::Operation Op
 
@ MCSA_Global
.type _foo, @gnu_unique_object
 
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...