31#define DEBUG_TYPE "msp430-asm-parser"
46 bool MatchingInlineAsm)
override;
50 SMLoc &EndLoc)
override;
56 bool ParseDirectiveRefSym(
AsmToken DirectiveID);
59 unsigned Kind)
override;
66 bool ParseLiteralValues(
unsigned Size,
SMLoc L);
74#define GET_ASSEMBLER_HEADER
75#include "MSP430GenAsmMatcher.inc"
118 :
Kind(k_Tok), Tok(Tok), Start(S),
End(S) {}
119 MSP430Operand(KindTy Kind,
unsigned Reg,
SMLoc const &S,
SMLoc const &E)
123 MSP430Operand(
unsigned Reg,
MCExpr const *Expr,
SMLoc const &S,
125 :
Kind(k_Mem), Mem({
Reg, Expr}), Start(S),
End(E) {}
127 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
128 assert((Kind == k_Reg || Kind == k_IndReg || Kind == k_PostIndReg) &&
129 "Unexpected operand kind");
130 assert(
N == 1 &&
"Invalid number of operands!");
135 void addExprOperand(
MCInst &Inst,
const MCExpr *Expr)
const {
139 else if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
145 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
146 assert(Kind == k_Imm &&
"Unexpected operand kind");
147 assert(
N == 1 &&
"Invalid number of operands!");
149 addExprOperand(Inst, Imm);
152 void addMemOperands(
MCInst &Inst,
unsigned N)
const {
153 assert(Kind == k_Mem &&
"Unexpected operand kind");
154 assert(
N == 2 &&
"Invalid number of operands");
157 addExprOperand(Inst, Mem.Offset);
160 bool isReg()
const override {
return Kind == k_Reg; }
161 bool isImm()
const override {
return Kind == k_Imm; }
162 bool isToken()
const override {
return Kind == k_Tok; }
163 bool isMem()
const override {
return Kind == k_Mem; }
164 bool isIndReg()
const {
return Kind == k_IndReg; }
165 bool isPostIndReg()
const {
return Kind == k_PostIndReg; }
167 bool isCGImm()
const {
172 if (!
Imm->evaluateAsAbsolute(Val))
175 if (Val == 0 || Val == 1 || Val == 2 || Val == 4 || Val == 8 || Val == -1)
182 assert(Kind == k_Tok &&
"Invalid access!");
187 assert(Kind == k_Reg &&
"Invalid access!");
191 void setReg(
unsigned RegNo) {
192 assert(Kind == k_Reg &&
"Invalid access!");
196 static std::unique_ptr<MSP430Operand> CreateToken(
StringRef Str,
SMLoc S) {
197 return std::make_unique<MSP430Operand>(Str, S);
200 static std::unique_ptr<MSP430Operand> CreateReg(
unsigned RegNum,
SMLoc S,
202 return std::make_unique<MSP430Operand>(k_Reg, RegNum, S, E);
205 static std::unique_ptr<MSP430Operand> CreateImm(
const MCExpr *Val,
SMLoc S,
207 return std::make_unique<MSP430Operand>(Val, S, E);
210 static std::unique_ptr<MSP430Operand> CreateMem(
unsigned RegNum,
213 return std::make_unique<MSP430Operand>(RegNum, Val, S, E);
216 static std::unique_ptr<MSP430Operand> CreateIndReg(
unsigned RegNum,
SMLoc S,
218 return std::make_unique<MSP430Operand>(k_IndReg, RegNum, S, E);
221 static std::unique_ptr<MSP430Operand> CreatePostIndReg(
unsigned RegNum,
SMLoc S,
223 return std::make_unique<MSP430Operand>(k_PostIndReg, RegNum, S, E);
232 O <<
"Token " << Tok;
235 O <<
"Register " <<
Reg;
238 O <<
"Immediate " << *
Imm;
242 O << *Mem.Offset <<
"(" <<
Reg <<
")";
245 O <<
"RegInd " <<
Reg;
248 O <<
"PostInc " <<
Reg;
255bool MSP430AsmParser::MatchAndEmitInstruction(
SMLoc Loc,
unsigned &Opcode,
259 bool MatchingInlineAsm) {
261 unsigned MatchResult =
264 switch (MatchResult) {
269 case Match_MnemonicFail:
270 return Error(Loc,
"invalid instruction mnemonic");
271 case Match_InvalidOperand: {
272 SMLoc ErrorLoc = Loc;
275 return Error(ErrorLoc,
"too few operands for instruction");
278 if (ErrorLoc ==
SMLoc())
281 return Error(ErrorLoc,
"invalid operand for instruction");
294 ParseStatus Res = tryParseRegister(Reg, StartLoc, EndLoc);
296 return Error(StartLoc,
"invalid register name");
308 auto Name = getLexer().getTok().getIdentifier().lower();
310 if (Reg == MSP430::NoRegister) {
312 if (Reg == MSP430::NoRegister)
316 AsmToken const &
T = getParser().getTok();
317 StartLoc =
T.getLoc();
318 EndLoc =
T.getEndLoc();
330 if (!
Name.starts_with_insensitive(
"j"))
333 auto CC =
Name.drop_front().lower();
335 if (
CC ==
"ne" ||
CC ==
"nz")
337 else if (
CC ==
"eq" ||
CC ==
"z")
339 else if (
CC ==
"lo" ||
CC ==
"nc")
341 else if (
CC ==
"hs" ||
CC ==
"c")
352 return Error(NameLoc,
"unknown instruction");
355 Operands.push_back(MSP430Operand::CreateToken(
"jmp", NameLoc));
357 Operands.push_back(MSP430Operand::CreateToken(
"j", NameLoc));
366 SMLoc ExprLoc = getLexer().getLoc();
367 if (getParser().parseExpression(Val))
368 return Error(ExprLoc,
"expected expression operand");
371 if (Val->evaluateAsAbsolute(Res))
372 if (Res < -512 || Res > 511)
373 return Error(ExprLoc,
"invalid jump offset");
375 Operands.push_back(MSP430Operand::CreateImm(Val, ExprLoc,
376 getLexer().getLoc()));
379 SMLoc Loc = getLexer().getLoc();
380 getParser().eatToEndOfStatement();
381 return Error(Loc,
"unexpected token");
392 if (
Name.ends_with_insensitive(
".w"))
395 if (!parseJccInstruction(Info,
Name, NameLoc,
Operands))
399 Operands.push_back(MSP430Operand::CreateToken(
Name, NameLoc));
414 SMLoc Loc = getLexer().getLoc();
415 getParser().eatToEndOfStatement();
416 return Error(Loc,
"unexpected token");
423bool MSP430AsmParser::ParseDirectiveRefSym(
AsmToken DirectiveID) {
425 if (getParser().parseIdentifier(
Name))
426 return TokError(
"expected identifier in directive");
435 if (IDVal.
lower() ==
".long")
436 return ParseLiteralValues(4, DirectiveID.
getLoc());
437 if (IDVal.
lower() ==
".word" || IDVal.
lower() ==
".short")
438 return ParseLiteralValues(2, DirectiveID.
getLoc());
439 if (IDVal.
lower() ==
".byte")
440 return ParseLiteralValues(1, DirectiveID.
getLoc());
441 if (IDVal.
lower() ==
".refsym")
442 return ParseDirectiveRefSym(DirectiveID);
447 switch (getLexer().getKind()) {
448 default:
return true;
452 SMLoc StartLoc, EndLoc;
453 if (!parseRegister(RegNo, StartLoc, EndLoc)) {
454 Operands.push_back(MSP430Operand::CreateReg(RegNo, StartLoc, EndLoc));
462 SMLoc StartLoc = getParser().getTok().getLoc();
465 if (!getParser().parseExpression(Val)) {
467 SMLoc EndLoc = getParser().getTok().getLoc();
471 if (parseRegister(RegNo, RegStartLoc, EndLoc))
473 EndLoc = getParser().getTok().getEndLoc();
477 Operands.push_back(MSP430Operand::CreateMem(RegNo, Val, StartLoc,
485 SMLoc StartLoc = getParser().getTok().getLoc();
488 if (!getParser().parseExpression(Val)) {
489 SMLoc EndLoc = getParser().getTok().getLoc();
490 Operands.push_back(MSP430Operand::CreateMem(MSP430::SR, Val, StartLoc,
498 SMLoc StartLoc = getParser().getTok().getLoc();
501 SMLoc RegStartLoc, EndLoc;
502 if (parseRegister(RegNo, RegStartLoc, EndLoc))
505 Operands.push_back(MSP430Operand::CreatePostIndReg(RegNo, StartLoc, EndLoc));
509 Operands.push_back(MSP430Operand::CreateMem(RegNo,
512 Operands.push_back(MSP430Operand::CreateIndReg(RegNo, StartLoc, EndLoc));
517 SMLoc StartLoc = getParser().getTok().getLoc();
520 if (!getParser().parseExpression(Val)) {
521 SMLoc EndLoc = getParser().getTok().getLoc();
522 Operands.push_back(MSP430Operand::CreateImm(Val, StartLoc, EndLoc));
529bool MSP430AsmParser::ParseLiteralValues(
unsigned Size,
SMLoc L) {
530 auto parseOne = [&]() ->
bool {
532 if (getParser().parseExpression(
Value))
534 getParser().getStreamer().emitValue(
Value,
Size, L);
537 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;
578 unsigned 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 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_EXTERNAL_VISIBILITY void LLVMInitializeMSP430AsmParser()
static unsigned convertGR16ToGR8(unsigned Reg)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Target independent representation for an assembler token.
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.
Generic assembler lexer interface, for use by target specific assembly lexers.
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.
virtual MCAsmLexer & getLexer()=0
static 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 createReg(unsigned Reg)
static MCOperand createExpr(const MCExpr *Val)
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 void print(raw_ostream &OS) const =0
print - Print a debug representation of the operand to the given stream.
virtual bool isToken() const =0
isToken - Is this a token operand?
virtual bool isImm() const =0
isImm - Is this an immediate operand?
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 parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
virtual ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
tryParseRegister - parse one register if possible
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...
virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands)=0
ParseInstruction - Parse one assembly instruction.
virtual bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm)=0
MatchAndEmitInstruction - Recognize a series of operands of a parsed instruction as an actual MCInst ...
const MCSubtargetInfo * STI
Current STI.
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.
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,...