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
const &S)
116 : Kind(k_Tok), Tok(Tok), Start(S), End(S) {}
117 MSP430Operand(KindTy Kind, MCRegister
Reg, SMLoc
const &S, SMLoc
const &
E)
118 : Kind(Kind),
Reg(
Reg), Start(S), End(
E) {}
119 MSP430Operand(MCExpr
const *
Imm, SMLoc
const &S, SMLoc
const &
E)
120 : Kind(k_Imm),
Imm(
Imm), Start(S), End(
E) {}
121 MSP430Operand(MCRegister
Reg, MCExpr
const *Expr, SMLoc
const &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 {
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!");
184 MCRegister
getReg()
const override {
185 assert(Kind == k_Reg &&
"Invalid access!");
189 void setReg(MCRegister RegNo) {
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>
209 CreateMem(MCRegister
Reg,
const MCExpr *Val, SMLoc S, SMLoc
E) {
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);
223 SMLoc getStartLoc()
const override {
return Start; }
224 SMLoc getEndLoc()
const override {
return End; }
226 void print(raw_ostream &O,
const MCAsmInfo &MAI)
const override {
229 O <<
"Token " << Tok;
232 O <<
"Register " <<
Reg.
id();
243 O <<
"RegInd " <<
Reg.
id();
246 O <<
"PostInc " <<
Reg.
id();
253bool MSP430AsmParser::matchAndEmitInstruction(
SMLoc Loc,
unsigned &Opcode,
257 bool MatchingInlineAsm) {
259 unsigned MatchResult =
260 MatchInstructionImpl(
Operands, Inst, ErrorInfo, MatchingInlineAsm);
262 switch (MatchResult) {
267 case Match_MnemonicFail:
268 return Error(Loc,
"invalid instruction mnemonic");
269 case Match_InvalidOperand: {
270 SMLoc ErrorLoc = Loc;
271 if (ErrorInfo != ~0U) {
273 return Error(ErrorLoc,
"too few operands for instruction");
275 ErrorLoc = ((MSP430Operand &)*
Operands[ErrorInfo]).getStartLoc();
276 if (ErrorLoc == SMLoc())
279 return Error(ErrorLoc,
"invalid operand for instruction");
294 return Error(StartLoc,
"invalid register name");
303ParseStatus MSP430AsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
306 auto Name = getLexer().getTok().getIdentifier().lower();
308 if (
Reg == MSP430::NoRegister) {
310 if (
Reg == MSP430::NoRegister)
314 AsmToken
const &
T = getParser().getTok();
315 StartLoc =
T.getLoc();
316 EndLoc =
T.getEndLoc();
325bool MSP430AsmParser::parseJccInstruction(ParseInstructionInfo &Info,
326 StringRef Name, SMLoc NameLoc,
328 if (!
Name.starts_with_insensitive(
"j"))
331 auto CC =
Name.drop_front().lower();
333 if (CC ==
"ne" || CC ==
"nz")
335 else if (CC ==
"eq" || CC ==
"z")
337 else if (CC ==
"lo" || CC ==
"nc")
339 else if (CC ==
"hs" || CC ==
"c")
350 return Error(NameLoc,
"unknown instruction");
353 Operands.push_back(MSP430Operand::CreateToken(
"jmp", NameLoc));
355 Operands.push_back(MSP430Operand::CreateToken(
"j", NameLoc));
357 Operands.push_back(MSP430Operand::CreateImm(CCode, SMLoc(), SMLoc()));
364 SMLoc ExprLoc = getLexer().getLoc();
365 if (getParser().parseExpression(Val))
366 return Error(ExprLoc,
"expected expression operand");
369 if (Val->evaluateAsAbsolute(Res))
370 if (Res < -512 || Res > 511)
371 return Error(ExprLoc,
"invalid jump offset");
373 Operands.push_back(MSP430Operand::CreateImm(Val, ExprLoc,
374 getLexer().getLoc()));
377 SMLoc Loc = getLexer().getLoc();
378 getParser().eatToEndOfStatement();
379 return Error(Loc,
"unexpected token");
386bool MSP430AsmParser::parseInstruction(ParseInstructionInfo &Info,
387 StringRef Name, SMLoc NameLoc,
390 if (
Name.ends_with_insensitive(
".w"))
393 if (!parseJccInstruction(Info, Name, NameLoc,
Operands))
397 Operands.push_back(MSP430Operand::CreateToken(Name, NameLoc));
412 SMLoc Loc = getLexer().getLoc();
413 getParser().eatToEndOfStatement();
414 return Error(Loc,
"unexpected token");
421bool MSP430AsmParser::ParseDirectiveRefSym(AsmToken DirectiveID) {
423 if (getParser().parseIdentifier(Name))
424 return TokError(
"expected identifier in directive");
427 getStreamer().emitSymbolAttribute(Sym,
MCSA_Global);
431ParseStatus MSP430AsmParser::parseDirective(AsmToken DirectiveID) {
433 if (IDVal.
lower() ==
".long")
434 return ParseLiteralValues(4, DirectiveID.
getLoc());
435 if (IDVal.
lower() ==
".word" || IDVal.
lower() ==
".short")
436 return ParseLiteralValues(2, DirectiveID.
getLoc());
437 if (IDVal.
lower() ==
".byte")
438 return ParseLiteralValues(1, DirectiveID.
getLoc());
439 if (IDVal.
lower() ==
".refsym")
440 return ParseDirectiveRefSym(DirectiveID);
445 switch (getLexer().getKind()) {
446 default:
return true;
450 SMLoc StartLoc, EndLoc;
451 if (!parseRegister(RegNo, StartLoc, EndLoc)) {
452 Operands.push_back(MSP430Operand::CreateReg(RegNo, StartLoc, EndLoc));
460 SMLoc StartLoc = getParser().getTok().getLoc();
463 if (!getParser().parseExpression(Val)) {
464 MCRegister RegNo = MSP430::PC;
465 SMLoc EndLoc = getParser().getTok().getLoc();
469 if (parseRegister(RegNo, RegStartLoc, EndLoc))
471 EndLoc = getParser().getTok().getEndLoc();
475 Operands.push_back(MSP430Operand::CreateMem(RegNo, Val, StartLoc,
483 SMLoc StartLoc = getParser().getTok().getLoc();
486 if (!getParser().parseExpression(Val)) {
487 SMLoc EndLoc = getParser().getTok().getLoc();
488 Operands.push_back(MSP430Operand::CreateMem(MSP430::SR, Val, StartLoc,
496 SMLoc StartLoc = getParser().getTok().getLoc();
499 SMLoc RegStartLoc, EndLoc;
500 if (parseRegister(RegNo, RegStartLoc, EndLoc))
503 Operands.push_back(MSP430Operand::CreatePostIndReg(RegNo, StartLoc, EndLoc));
507 Operands.push_back(MSP430Operand::CreateMem(RegNo,
510 Operands.push_back(MSP430Operand::CreateIndReg(RegNo, StartLoc, EndLoc));
515 SMLoc StartLoc = getParser().getTok().getLoc();
518 if (!getParser().parseExpression(Val)) {
519 SMLoc EndLoc = getParser().getTok().getLoc();
520 Operands.push_back(MSP430Operand::CreateImm(Val, StartLoc, EndLoc));
527bool MSP430AsmParser::ParseLiteralValues(
unsigned Size, SMLoc L) {
528 auto parseOne = [&]() ->
bool {
530 if (getParser().parseExpression(
Value))
532 getParser().getStreamer().emitValue(
Value,
Size, L);
535 return (parseMany(parseOne));
543#define GET_REGISTER_MATCHER
544#define GET_MATCHER_IMPLEMENTATION
545#include "MSP430GenAsmMatcher.inc"
551 case MSP430::PC:
return MSP430::PCB;
552 case MSP430::SP:
return MSP430::SPB;
553 case MSP430::SR:
return MSP430::SRB;
554 case MSP430::CG:
return MSP430::CGB;
555 case MSP430::R4:
return MSP430::R4B;
556 case MSP430::R5:
return MSP430::R5B;
557 case MSP430::R6:
return MSP430::R6B;
558 case MSP430::R7:
return MSP430::R7B;
559 case MSP430::R8:
return MSP430::R8B;
560 case MSP430::R9:
return MSP430::R9B;
561 case MSP430::R10:
return MSP430::R10B;
562 case MSP430::R11:
return MSP430::R11B;
563 case MSP430::R12:
return MSP430::R12B;
564 case MSP430::R13:
return MSP430::R13B;
565 case MSP430::R14:
return MSP430::R14B;
566 case MSP430::R15:
return MSP430::R15B;
570unsigned MSP430AsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
572 MSP430Operand &
Op =
static_cast<MSP430Operand &
>(AsmOp);
575 return Match_InvalidOperand;
577 MCRegister
Reg =
Op.getReg();
578 bool isGR16 = getMSP430MCRegisterClass(MSP430::GR16RegClassID).contains(
Reg);
580 if (isGR16 && (Kind == MCK_GR8)) {
582 return Match_Success;
585 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.
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
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
@ MCSA_Global
.type _foo, @gnu_unique_object
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...