30#define DEBUG_TYPE "msp430-asm-parser"
41 bool matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
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"
84 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
90 typedef MCParsedAsmOperand Base;
103 const MCExpr *Offset;
115 MSP430Operand(StringRef Tok, SMLoc S)
116 : Kind(k_Tok), Tok(Tok), Start(S), End(S) {}
117 MSP430Operand(KindTy Kind, MCRegister
Reg, SMLoc S, SMLoc
E)
118 : Kind(Kind),
Reg(
Reg), Start(S), End(
E) {}
119 MSP430Operand(MCExpr
const *
Imm, SMLoc S, SMLoc
E)
120 : Kind(k_Imm),
Imm(
Imm), Start(S), End(
E) {}
121 MSP430Operand(MCRegister
Reg, MCExpr
const *Expr, SMLoc S, SMLoc
E)
122 : 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 {
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 override {
return Kind == k_Reg; }
158 bool isImm()
const override {
return Kind == k_Imm; }
159 bool isToken()
const override {
return Kind == k_Tok; }
160 bool isMem()
const override {
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!");
183 MCRegister
getReg()
const override {
184 assert(Kind == k_Reg &&
"Invalid access!");
188 void setReg(MCRegister RegNo) {
189 assert(Kind == k_Reg &&
"Invalid access!");
193 static std::unique_ptr<MSP430Operand> CreateToken(StringRef Str, SMLoc S) {
194 return std::make_unique<MSP430Operand>(Str, S);
197 static std::unique_ptr<MSP430Operand> CreateReg(MCRegister
Reg, SMLoc S,
199 return std::make_unique<MSP430Operand>(k_Reg,
Reg, S,
E);
202 static std::unique_ptr<MSP430Operand> CreateImm(
const MCExpr *Val, SMLoc S,
204 return std::make_unique<MSP430Operand>(Val, S,
E);
207 static std::unique_ptr<MSP430Operand>
208 CreateMem(MCRegister
Reg,
const MCExpr *Val, SMLoc S, SMLoc
E) {
209 return std::make_unique<MSP430Operand>(
Reg, Val, S,
E);
212 static std::unique_ptr<MSP430Operand> CreateIndReg(MCRegister
Reg, SMLoc S,
214 return std::make_unique<MSP430Operand>(k_IndReg,
Reg, S,
E);
217 static std::unique_ptr<MSP430Operand> CreatePostIndReg(MCRegister
Reg,
219 return std::make_unique<MSP430Operand>(k_PostIndReg,
Reg, S,
E);
222 SMLoc getStartLoc()
const override {
return Start; }
223 SMLoc getEndLoc()
const override {
return End; }
225 void print(raw_ostream &O,
const MCAsmInfo &MAI)
const override {
228 O <<
"Token " << Tok;
231 O <<
"Register " <<
Reg.
id();
242 O <<
"RegInd " <<
Reg.
id();
245 O <<
"PostInc " <<
Reg.
id();
252bool MSP430AsmParser::matchAndEmitInstruction(
SMLoc Loc,
unsigned &Opcode,
256 bool MatchingInlineAsm) {
258 unsigned MatchResult =
259 MatchInstructionImpl(
Operands, Inst, ErrorInfo, MatchingInlineAsm);
261 switch (MatchResult) {
264 Out.emitInstruction(Inst, *STI);
266 case Match_MnemonicFail:
267 return Error(Loc,
"invalid instruction mnemonic");
268 case Match_InvalidOperand: {
269 SMLoc ErrorLoc = Loc;
270 if (ErrorInfo != ~0U) {
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");
293 return Error(StartLoc,
"invalid register name");
302ParseStatus MSP430AsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
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();
324bool MSP430AsmParser::parseJccInstruction(ParseInstructionInfo &Info,
325 StringRef Name, SMLoc NameLoc,
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));
356 Operands.push_back(MSP430Operand::CreateImm(CCode, SMLoc(), SMLoc()));
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");
385bool MSP430AsmParser::parseInstruction(ParseInstructionInfo &Info,
386 StringRef Name, SMLoc NameLoc,
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");
426 getStreamer().emitSymbolAttribute(Sym,
MCSA_Global);
430ParseStatus MSP430AsmParser::parseDirective(AsmToken DirectiveID) {
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)) {
463 MCRegister RegNo = MSP430::PC;
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));
542#define GET_REGISTER_MATCHER
543#define GET_MATCHER_IMPLEMENTATION
544#include "MSP430GenAsmMatcher.inc"
550 case MSP430::PC:
return MSP430::PCB;
551 case MSP430::SP:
return MSP430::SPB;
552 case MSP430::SR:
return MSP430::SRB;
553 case MSP430::CG:
return MSP430::CGB;
554 case MSP430::R4:
return MSP430::R4B;
555 case MSP430::R5:
return MSP430::R5B;
556 case MSP430::R6:
return MSP430::R6B;
557 case MSP430::R7:
return MSP430::R7B;
558 case MSP430::R8:
return MSP430::R8B;
559 case MSP430::R9:
return MSP430::R9B;
560 case MSP430::R10:
return MSP430::R10B;
561 case MSP430::R11:
return MSP430::R11B;
562 case MSP430::R12:
return MSP430::R12B;
563 case MSP430::R13:
return MSP430::R13B;
564 case MSP430::R14:
return MSP430::R14B;
565 case MSP430::R15:
return MSP430::R15B;
569unsigned MSP430AsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
571 MSP430Operand &
Op =
static_cast<MSP430Operand &
>(AsmOp);
574 return Match_InvalidOperand;
576 MCRegister
Reg =
Op.getReg();
577 bool isGR16 = getMSP430MCRegisterClass(MSP430::GR16RegClassID).contains(
Reg);
579 if (isGR16 && (Kind == MCK_GR8)) {
581 return Match_Success;
584 return Match_InvalidOperand;
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")
#define LLVM_EXTERNAL_VISIBILITY
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMSP430AsmParser()
static MCRegister convertGR16ToGR8(MCRegister Reg)
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
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.
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
constexpr unsigned id() const
Represents a location in source code.
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)
This is an optimization pass for GlobalISel generic memory operations.
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()
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
DWARFExpression::Operation Op
@ End
Run the machine verifier once, at the end of the pipeline.
@ MCSA_Global
.type _foo, @gnu_unique_object
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...