31 #define DEBUG_TYPE "msp430-asm-parser" 43 bool MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
46 bool MatchingInlineAsm)
override;
48 bool ParseRegister(
unsigned &RegNo,
SMLoc &StartLoc,
SMLoc &EndLoc)
override;
53 bool ParseDirective(
AsmToken DirectiveID)
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" 82 MRI = getContext().getRegisterInfo();
84 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
116 : Base(),
Kind(k_Tok), Tok(Tok), Start(S), End(S) {}
117 MSP430Operand(KindTy Kind,
unsigned Reg,
SMLoc const &S,
SMLoc const &
E)
118 : Base(),
Kind(Kind),
Reg(Reg), Start(S), End(E) {}
120 : Base(),
Kind(k_Imm), Imm(Imm), Start(S), End(E) {}
121 MSP430Operand(
unsigned Reg,
MCExpr const *Expr,
SMLoc const &S,
SMLoc const &E)
122 : Base(),
Kind(k_Mem), Mem({
Reg, Expr}), Start(S), End(E) {}
124 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
125 assert((Kind == k_Reg || Kind == k_IndReg || Kind == k_PostIndReg) &&
126 "Unexpected operand kind");
127 assert(N == 1 &&
"Invalid number of operands!");
132 void addExprOperand(
MCInst &Inst,
const MCExpr *Expr)
const {
136 else if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
142 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
143 assert(Kind == k_Imm &&
"Unexpected operand kind");
144 assert(N == 1 &&
"Invalid number of operands!");
146 addExprOperand(Inst, Imm);
149 void addMemOperands(
MCInst &Inst,
unsigned N)
const {
150 assert(Kind == k_Mem &&
"Unexpected operand kind");
151 assert(N == 2 &&
"Invalid number of operands");
154 addExprOperand(Inst, Mem.Offset);
157 bool isReg()
const {
return Kind == k_Reg; }
158 bool isImm()
const {
return Kind == k_Imm; }
159 bool isToken()
const {
return Kind == k_Tok; }
160 bool isMem()
const {
return Kind == k_Mem; }
161 bool isIndReg()
const {
return Kind == k_IndReg; }
162 bool isPostIndReg()
const {
return Kind == k_PostIndReg; }
164 bool isCGImm()
const {
169 if (!Imm->evaluateAsAbsolute(Val))
172 if (Val == 0 || Val == 1 || Val == 2 || Val == 4 || Val == 8 || Val == -1)
179 assert(Kind == k_Tok &&
"Invalid access!");
184 assert(Kind == k_Reg &&
"Invalid access!");
188 void setReg(
unsigned RegNo) {
189 assert(Kind == k_Reg &&
"Invalid access!");
193 static std::unique_ptr<MSP430Operand> CreateToken(
StringRef Str,
SMLoc S) {
194 return make_unique<MSP430Operand>(Str, S);
197 static std::unique_ptr<MSP430Operand> CreateReg(
unsigned RegNum,
SMLoc S,
199 return make_unique<MSP430Operand>(k_Reg, RegNum, S,
E);
202 static std::unique_ptr<MSP430Operand> CreateImm(
const MCExpr *Val,
SMLoc S,
204 return make_unique<MSP430Operand>(Val, S,
E);
207 static std::unique_ptr<MSP430Operand> CreateMem(
unsigned RegNum,
210 return make_unique<MSP430Operand>(RegNum, Val, S,
E);
213 static std::unique_ptr<MSP430Operand> CreateIndReg(
unsigned RegNum,
SMLoc S,
215 return make_unique<MSP430Operand>(k_IndReg, RegNum, S,
E);
218 static std::unique_ptr<MSP430Operand> CreatePostIndReg(
unsigned RegNum,
SMLoc S,
220 return make_unique<MSP430Operand>(k_PostIndReg, RegNum, S,
E);
223 SMLoc getStartLoc()
const {
return Start; }
224 SMLoc getEndLoc()
const {
return End; }
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;
252 bool MSP430AsmParser::MatchAndEmitInstruction(
SMLoc Loc,
unsigned &Opcode,
256 bool MatchingInlineAsm) {
258 unsigned MatchResult =
259 MatchInstructionImpl(Operands, Inst,
ErrorInfo, MatchingInlineAsm);
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");
274 ErrorLoc = ((MSP430Operand &)*Operands[
ErrorInfo]).getStartLoc();
275 if (ErrorLoc ==
SMLoc())
278 return Error(ErrorLoc,
"invalid operand for instruction");
289 bool MSP430AsmParser::ParseRegister(
unsigned &RegNo,
SMLoc &StartLoc,
292 auto Name = getLexer().getTok().getIdentifier().
lower();
294 if (RegNo == MSP430::NoRegister) {
296 if (RegNo == MSP430::NoRegister)
300 AsmToken const &
T = getParser().getTok();
308 return Error(StartLoc,
"invalid register name");
319 if (CC ==
"ne" || CC ==
"nz")
321 else if (CC ==
"eq" || CC ==
"z")
323 else if (CC ==
"lo" || CC ==
"nc")
325 else if (CC ==
"hs" || CC ==
"c")
336 return Error(NameLoc,
"unknown instruction");
339 Operands.
push_back(MSP430Operand::CreateToken(
"jmp", NameLoc));
341 Operands.
push_back(MSP430Operand::CreateToken(
"j", NameLoc));
351 SMLoc ExprLoc = getLexer().getLoc();
352 if (getParser().parseExpression(Val))
353 return Error(ExprLoc,
"expected expression operand");
356 if (Val->evaluateAsAbsolute(Res))
357 if (Res < -512 || Res > 511)
358 return Error(ExprLoc,
"invalid jump offset");
360 Operands.
push_back(MSP430Operand::CreateImm(Val, ExprLoc,
361 getLexer().getLoc()));
364 SMLoc Loc = getLexer().getLoc();
365 getParser().eatToEndOfStatement();
366 return Error(Loc,
"unexpected token");
380 if (!parseJccInstruction(Info, Name, NameLoc, Operands))
384 Operands.
push_back(MSP430Operand::CreateToken(Name, NameLoc));
391 if (ParseOperand(Operands))
397 if (ParseOperand(Operands))
402 SMLoc Loc = getLexer().getLoc();
403 getParser().eatToEndOfStatement();
404 return Error(Loc,
"unexpected token");
411 bool MSP430AsmParser::ParseDirectiveRefSym(
AsmToken DirectiveID) {
413 if (getParser().parseIdentifier(Name))
414 return TokError(
"expected identifier in directive");
416 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
417 getStreamer().EmitSymbolAttribute(Sym,
MCSA_Global);
421 bool MSP430AsmParser::ParseDirective(
AsmToken DirectiveID) {
423 if (IDVal.
lower() ==
".long") {
424 ParseLiteralValues(4, DirectiveID.
getLoc());
425 }
else if (IDVal.
lower() ==
".word" || IDVal.
lower() ==
".short") {
426 ParseLiteralValues(2, DirectiveID.
getLoc());
427 }
else if (IDVal.
lower() ==
".byte") {
428 ParseLiteralValues(1, DirectiveID.
getLoc());
429 }
else if (IDVal.
lower() ==
".refsym") {
430 return ParseDirectiveRefSym(DirectiveID);
435 bool MSP430AsmParser::ParseOperand(
OperandVector &Operands) {
436 switch (getLexer().getKind()) {
437 default:
return true;
441 SMLoc StartLoc, EndLoc;
442 if (!ParseRegister(RegNo, StartLoc, EndLoc)) {
443 Operands.
push_back(MSP430Operand::CreateReg(RegNo, StartLoc, EndLoc));
451 SMLoc StartLoc = getParser().getTok().getLoc();
454 if (!getParser().parseExpression(Val)) {
455 unsigned RegNo = MSP430::PC;
456 SMLoc EndLoc = getParser().getTok().getLoc();
461 if (ParseRegister(RegNo, RegStartLoc, EndLoc))
465 EndLoc = getParser().getTok().getEndLoc();
468 Operands.
push_back(MSP430Operand::CreateMem(RegNo, Val, StartLoc,
476 SMLoc StartLoc = getParser().getTok().getLoc();
479 if (!getParser().parseExpression(Val)) {
480 SMLoc EndLoc = getParser().getTok().getLoc();
481 Operands.
push_back(MSP430Operand::CreateMem(MSP430::SR, Val, StartLoc,
489 SMLoc StartLoc = getParser().getTok().getLoc();
492 SMLoc RegStartLoc, EndLoc;
493 if (ParseRegister(RegNo, RegStartLoc, EndLoc))
496 Operands.
push_back(MSP430Operand::CreatePostIndReg(RegNo, StartLoc, EndLoc));
500 if (Operands.
size() > 1)
501 Operands.
push_back(MSP430Operand::CreateMem(RegNo,
504 Operands.
push_back(MSP430Operand::CreateIndReg(RegNo, StartLoc, EndLoc));
509 SMLoc StartLoc = getParser().getTok().getLoc();
512 if (!getParser().parseExpression(Val)) {
513 SMLoc EndLoc = getParser().getTok().getLoc();
514 Operands.
push_back(MSP430Operand::CreateImm(Val, StartLoc, EndLoc));
521 bool MSP430AsmParser::ParseLiteralValues(
unsigned Size,
SMLoc L) {
522 auto parseOne = [&]() ->
bool {
524 if (getParser().parseExpression(Value))
526 getParser().getStreamer().EmitValue(Value, Size, L);
529 return (parseMany(parseOne));
536 #define GET_REGISTER_MATCHER 537 #define GET_MATCHER_IMPLEMENTATION 538 #include "MSP430GenAsmMatcher.inc" 544 case MSP430::PC:
return MSP430::PCB;
545 case MSP430::SP:
return MSP430::SPB;
546 case MSP430::SR:
return MSP430::SRB;
547 case MSP430::CG:
return MSP430::CGB;
549 case MSP430::R5:
return MSP430::R5B;
551 case MSP430::R7:
return MSP430::R7B;
552 case MSP430::R8:
return MSP430::R8B;
553 case MSP430::R9:
return MSP430::R9B;
554 case MSP430::R10:
return MSP430::R10B;
555 case MSP430::R11:
return MSP430::R11B;
556 case MSP430::R12:
return MSP430::R12B;
557 case MSP430::R13:
return MSP430::R13B;
558 case MSP430::R14:
return MSP430::R14B;
559 case MSP430::R15:
return MSP430::R15B;
565 MSP430Operand &
Op =
static_cast<MSP430Operand &
>(AsmOp);
568 return Match_InvalidOperand;
570 unsigned Reg = Op.getReg();
572 MSP430MCRegisterClasses[MSP430::GR16RegClassID].contains(Reg);
574 if (isGR16 && (Kind == MCK_GR8)) {
576 return Match_Success;
579 return Match_InvalidOperand;
static bool isReg(const MCInst &MI, unsigned OpNo)
static unsigned convertGR16ToGR8(unsigned Reg)
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
Target & getTheMSP430Target()
LLVM_NODISCARD bool startswith_lower(StringRef Prefix) const
Check if this string starts with the given Prefix, ignoring case.
This class represents lattice values for constants.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Generic assembler parser interface, for use by target specific assembly parsers.
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
static MCOperand createExpr(const MCExpr *Val)
This class provides various memory handling functions that manipulate MemoryBlock instances...
MCTargetAsmParser - Generic interface to target specific assembly parsers.
void push_back(const T &Elt)
LLVM_NODISCARD bool endswith_lower(StringRef Suffix) const
Check if this string ends with the given Suffix, ignoring case.
static unsigned MatchRegisterAltName(StringRef Name)
virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI, bool PrintSchedInfo=false)
Emit the given Instruction into the current section.
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string...
amdgpu Simplify well known AMD library false Value Value const Twine & Name
static MCOperand createReg(unsigned Reg)
const FeatureBitset & getFeatureBits() const
Generic assembler lexer interface, for use by target specific assembly lexers.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Base class for the full range of assembler expressions which are needed for parsing.
Target independent representation for an assembler token.
static bool isMem(const MachineInstr &MI, unsigned Op)
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand...
This file implements a class to represent arbitrary precision integral constant values and operations...
std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \\\)
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
RegisterMCAsmParser - Helper template for registering a target specific assembly parser, for use in the target machine initialization function.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out...
Instances of this class represent a single low-level machine instruction.
Analysis containing CSE Info
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Streaming machine code generation interface.
unsigned const MachineRegisterInfo * MRI
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Interface to description of machine instruction set.
virtual MCAsmLexer & getLexer()=0
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static unsigned MatchRegisterName(StringRef Name)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef drop_back(size_t N=1) const
Return a StringRef equal to 'this' but with the last N elements dropped.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
Base class for user error types.
void LLVMInitializeMSP430AsmParser()
Generic base class for all target subtargets.
LLVM_NODISCARD std::string lower() const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream...
void addOperand(const MCOperand &Op)
StringRef - Represent a constant reference to a string, i.e.
Represents a location in source code.
static MCOperand createImm(int64_t Val)
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx)