29#define DEBUG_TYPE "msp430-asm-parser"
44 bool MatchingInlineAsm)
override;
48 SMLoc &EndLoc)
override;
54 bool ParseDirectiveRefSym(
AsmToken DirectiveID);
57 unsigned Kind)
override;
64 bool ParseLiteralValues(
unsigned Size,
SMLoc L);
72#define GET_ASSEMBLER_HEADER
73#include "MSP430GenAsmMatcher.inc"
116 :
Kind(k_Tok), Tok(Tok), Start(S),
End(S) {}
123 :
Kind(k_Mem), Mem({
Reg, Expr}), Start(S),
End(E) {}
125 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
126 assert((Kind == k_Reg || Kind == k_IndReg || Kind == k_PostIndReg) &&
127 "Unexpected operand kind");
128 assert(
N == 1 &&
"Invalid number of operands!");
133 void addExprOperand(
MCInst &Inst,
const MCExpr *Expr)
const {
137 else if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
143 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
144 assert(Kind == k_Imm &&
"Unexpected operand kind");
145 assert(
N == 1 &&
"Invalid number of operands!");
147 addExprOperand(Inst, Imm);
150 void addMemOperands(
MCInst &Inst,
unsigned N)
const {
151 assert(Kind == k_Mem &&
"Unexpected operand kind");
152 assert(
N == 2 &&
"Invalid number of operands");
155 addExprOperand(Inst, Mem.Offset);
158 bool isReg()
const override {
return Kind == k_Reg; }
159 bool isImm()
const override {
return Kind == k_Imm; }
160 bool isToken()
const override {
return Kind == k_Tok; }
161 bool isMem()
const override {
return Kind == k_Mem; }
162 bool isIndReg()
const {
return Kind == k_IndReg; }
163 bool isPostIndReg()
const {
return Kind == k_PostIndReg; }
165 bool isCGImm()
const {
170 if (!
Imm->evaluateAsAbsolute(Val))
173 if (Val == 0 || Val == 1 || Val == 2 || Val == 4 || Val == 8 || Val == -1)
180 assert(Kind == k_Tok &&
"Invalid access!");
185 assert(Kind == k_Reg &&
"Invalid access!");
190 assert(Kind == k_Reg &&
"Invalid access!");
194 static std::unique_ptr<MSP430Operand> CreateToken(
StringRef Str,
SMLoc S) {
195 return std::make_unique<MSP430Operand>(Str, S);
198 static std::unique_ptr<MSP430Operand> CreateReg(
MCRegister Reg,
SMLoc S,
200 return std::make_unique<MSP430Operand>(k_Reg, Reg, S, E);
203 static std::unique_ptr<MSP430Operand> CreateImm(
const MCExpr *Val,
SMLoc S,
205 return std::make_unique<MSP430Operand>(Val, S, E);
208 static std::unique_ptr<MSP430Operand>
210 return std::make_unique<MSP430Operand>(Reg, Val, S, E);
213 static std::unique_ptr<MSP430Operand> CreateIndReg(
MCRegister Reg,
SMLoc S,
215 return std::make_unique<MSP430Operand>(k_IndReg, Reg, S, E);
218 static std::unique_ptr<MSP430Operand> CreatePostIndReg(
MCRegister Reg,
220 return std::make_unique<MSP430Operand>(k_PostIndReg, Reg, S, E);
229 O <<
"Token " << Tok;
232 O <<
"Register " <<
Reg;
235 O <<
"Immediate " << *
Imm;
239 O << *Mem.Offset <<
"(" <<
Reg <<
")";
242 O <<
"RegInd " <<
Reg;
245 O <<
"PostInc " <<
Reg;
252bool MSP430AsmParser::matchAndEmitInstruction(
SMLoc Loc,
unsigned &Opcode,
256 bool MatchingInlineAsm) {
258 unsigned MatchResult =
261 switch (MatchResult) {
266 case Match_MnemonicFail:
267 return Error(Loc,
"invalid instruction mnemonic");
268 case Match_InvalidOperand: {
269 SMLoc ErrorLoc = Loc;
272 return Error(ErrorLoc,
"too few operands for instruction");
275 if (ErrorLoc ==
SMLoc())
278 return Error(ErrorLoc,
"invalid operand for instruction");
291 ParseStatus Res = tryParseRegister(Reg, StartLoc, EndLoc);
293 return Error(StartLoc,
"invalid register name");
305 auto Name = getLexer().getTok().getIdentifier().lower();
307 if (Reg == MSP430::NoRegister) {
309 if (Reg == MSP430::NoRegister)
313 AsmToken const &
T = getParser().getTok();
314 StartLoc =
T.getLoc();
315 EndLoc =
T.getEndLoc();
327 if (!
Name.starts_with_insensitive(
"j"))
330 auto CC =
Name.drop_front().lower();
332 if (
CC ==
"ne" ||
CC ==
"nz")
334 else if (
CC ==
"eq" ||
CC ==
"z")
336 else if (
CC ==
"lo" ||
CC ==
"nc")
338 else if (
CC ==
"hs" ||
CC ==
"c")
349 return Error(NameLoc,
"unknown instruction");
352 Operands.push_back(MSP430Operand::CreateToken(
"jmp", NameLoc));
354 Operands.push_back(MSP430Operand::CreateToken(
"j", NameLoc));
363 SMLoc ExprLoc = getLexer().getLoc();
364 if (getParser().parseExpression(Val))
365 return Error(ExprLoc,
"expected expression operand");
368 if (Val->evaluateAsAbsolute(Res))
369 if (Res < -512 || Res > 511)
370 return Error(ExprLoc,
"invalid jump offset");
372 Operands.push_back(MSP430Operand::CreateImm(Val, ExprLoc,
373 getLexer().getLoc()));
376 SMLoc Loc = getLexer().getLoc();
377 getParser().eatToEndOfStatement();
378 return Error(Loc,
"unexpected token");
389 if (
Name.ends_with_insensitive(
".w"))
392 if (!parseJccInstruction(Info,
Name, NameLoc,
Operands))
396 Operands.push_back(MSP430Operand::CreateToken(
Name, NameLoc));
411 SMLoc Loc = getLexer().getLoc();
412 getParser().eatToEndOfStatement();
413 return Error(Loc,
"unexpected token");
420bool MSP430AsmParser::ParseDirectiveRefSym(
AsmToken DirectiveID) {
422 if (getParser().parseIdentifier(
Name))
423 return TokError(
"expected identifier in directive");
432 if (IDVal.
lower() ==
".long")
433 return ParseLiteralValues(4, DirectiveID.
getLoc());
434 if (IDVal.
lower() ==
".word" || IDVal.
lower() ==
".short")
435 return ParseLiteralValues(2, DirectiveID.
getLoc());
436 if (IDVal.
lower() ==
".byte")
437 return ParseLiteralValues(1, DirectiveID.
getLoc());
438 if (IDVal.
lower() ==
".refsym")
439 return ParseDirectiveRefSym(DirectiveID);
444 switch (getLexer().getKind()) {
445 default:
return true;
449 SMLoc StartLoc, EndLoc;
450 if (!parseRegister(RegNo, StartLoc, EndLoc)) {
451 Operands.push_back(MSP430Operand::CreateReg(RegNo, StartLoc, EndLoc));
459 SMLoc StartLoc = getParser().getTok().getLoc();
462 if (!getParser().parseExpression(Val)) {
464 SMLoc EndLoc = getParser().getTok().getLoc();
468 if (parseRegister(RegNo, RegStartLoc, EndLoc))
470 EndLoc = getParser().getTok().getEndLoc();
474 Operands.push_back(MSP430Operand::CreateMem(RegNo, Val, StartLoc,
482 SMLoc StartLoc = getParser().getTok().getLoc();
485 if (!getParser().parseExpression(Val)) {
486 SMLoc EndLoc = getParser().getTok().getLoc();
487 Operands.push_back(MSP430Operand::CreateMem(MSP430::SR, Val, StartLoc,
495 SMLoc StartLoc = getParser().getTok().getLoc();
498 SMLoc RegStartLoc, EndLoc;
499 if (parseRegister(RegNo, RegStartLoc, EndLoc))
502 Operands.push_back(MSP430Operand::CreatePostIndReg(RegNo, StartLoc, EndLoc));
506 Operands.push_back(MSP430Operand::CreateMem(RegNo,
509 Operands.push_back(MSP430Operand::CreateIndReg(RegNo, StartLoc, EndLoc));
514 SMLoc StartLoc = getParser().getTok().getLoc();
517 if (!getParser().parseExpression(Val)) {
518 SMLoc EndLoc = getParser().getTok().getLoc();
519 Operands.push_back(MSP430Operand::CreateImm(Val, StartLoc, EndLoc));
526bool MSP430AsmParser::ParseLiteralValues(
unsigned Size,
SMLoc L) {
527 auto parseOne = [&]() ->
bool {
529 if (getParser().parseExpression(
Value))
531 getParser().getStreamer().emitValue(
Value,
Size, L);
534 return (parseMany(parseOne));
541#define GET_REGISTER_MATCHER
542#define GET_MATCHER_IMPLEMENTATION
543#include "MSP430GenAsmMatcher.inc"
549 case MSP430::PC:
return MSP430::PCB;
550 case MSP430::SP:
return MSP430::SPB;
551 case MSP430::SR:
return MSP430::SRB;
552 case MSP430::CG:
return MSP430::CGB;
553 case MSP430::R4:
return MSP430::R4B;
554 case MSP430::R5:
return MSP430::R5B;
555 case MSP430::R6:
return MSP430::R6B;
556 case MSP430::R7:
return MSP430::R7B;
557 case MSP430::R8:
return MSP430::R8B;
558 case MSP430::R9:
return MSP430::R9B;
559 case MSP430::R10:
return MSP430::R10B;
560 case MSP430::R11:
return MSP430::R11B;
561 case MSP430::R12:
return MSP430::R12B;
562 case MSP430::R13:
return MSP430::R13B;
563 case MSP430::R14:
return MSP430::R14B;
564 case MSP430::R15:
return MSP430::R15B;
570 MSP430Operand &
Op =
static_cast<MSP430Operand &
>(AsmOp);
573 return Match_InvalidOperand;
577 MSP430MCRegisterClasses[MSP430::GR16RegClassID].contains(Reg);
579 if (isGR16 && (Kind == MCK_GR8)) {
581 return Match_Success;
584 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 MCRegister convertGR16ToGR8(MCRegister 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 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 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 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...
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,...