31#define DEBUG_TYPE "msp430-asm-parser"
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"
117 :
Kind(k_Tok), Tok(Tok), Start(S),
End(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 {
138 else if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
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!");
186 assert(Kind == k_Reg &&
"Invalid access!");
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>
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);
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 =
263 switch (MatchResult) {
268 case Match_MnemonicFail:
269 return Error(Loc,
"invalid instruction mnemonic");
270 case Match_InvalidOperand: {
271 SMLoc ErrorLoc = Loc;
274 return Error(ErrorLoc,
"too few operands for instruction");
277 if (ErrorLoc ==
SMLoc())
280 return Error(ErrorLoc,
"invalid operand for instruction");
293 ParseStatus Res = tryParseRegister(Reg, StartLoc, EndLoc);
295 return Error(StartLoc,
"invalid register name");
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();
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));
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");
391 if (
Name.ends_with_insensitive(
".w"))
394 if (!parseJccInstruction(Info,
Name, NameLoc,
Operands))
398 Operands.push_back(MSP430Operand::CreateToken(
Name, NameLoc));
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");
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)) {
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));
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;
573 MSP430Operand &
Op =
static_cast<MSP430Operand &
>(AsmOp);
576 return Match_InvalidOperand;
580 MSP430MCRegisterClasses[MSP430::GR16RegClassID].contains(Reg);
582 if (isGR16 && (Kind == MCK_GR8)) {
584 return Match_Success;
587 return Match_InvalidOperand;
unsigned const MachineRegisterInfo * MRI
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...
Analysis containing CSE Info
#define LLVM_EXTERNAL_VISIBILITY
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
mir Rename Register Operands
static MCRegister MatchRegisterAltName(StringRef Name)
static MCRegister MatchRegisterName(StringRef Name)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMSP430AsmParser()
static MCRegister convertGR16ToGR8(MCRegister Reg)
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.
This class represents an Operation in the Expression.
Base class for user error types.
Lightweight error class with error context and mandatory checking.
This class is intended to be used as a base class for asm properties and features specific to the tar...
void printExpr(raw_ostream &, const MCExpr &) const
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
MCAsmParser & getParser()
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)
const MCRegisterInfo * getRegisterInfo() const
Base class for the full range of assembler expressions which are needed for parsing.
Instances of this class represent a single low-level machine instruction.
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.
virtual SMLoc getStartLoc() const =0
getStartLoc - Get the location of the first token of this operand.
virtual bool isReg() const =0
isReg - Is this a register operand?
virtual bool isMem() const =0
isMem - Is this a memory operand?
virtual MCRegister getReg() const =0
virtual bool isToken() const =0
isToken - Is this a token operand?
virtual bool isImm() const =0
isImm - Is this an immediate operand?
virtual void print(raw_ostream &, const MCAsmInfo &) const =0
print - Print a debug representation of the operand to the given stream.
virtual SMLoc getEndLoc() const =0
getEndLoc - Get the location of the last token of this 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
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
MCTargetAsmParser - Generic interface to target specific assembly parsers.
virtual ParseStatus parseDirective(AsmToken DirectiveID)
Parses a target-specific assembler directive.
virtual bool parseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands)=0
Parse one assembly instruction.
virtual bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
virtual ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
tryParseRegister - parse one register if possible
virtual bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm)=0
Recognize a series of operands of a parsed instruction as an actual MCInst and emit it to the specifi...
void setAvailableFeatures(const FeatureBitset &Value)
virtual unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, unsigned Kind)
Allow a target to add special case operand matching for things that tblgen doesn't/can't handle effec...
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.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
StringRef - Represent a constant reference to a string, i.e.
LLVM_ABI std::string lower() const
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream.
This class provides various memory handling functions that manipulate MemoryBlock instances.
#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)
Reg
All possible values of the reg field in the ModR/M byte.
This is an optimization pass for GlobalISel generic memory operations.
Target & getTheMSP430Target()
@ MCSA_Global
.type _foo, @gnu_unique_object
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...