31#define DEBUG_TYPE "msp430-asm-parser"
42 bool matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
45 bool MatchingInlineAsm)
override;
49 SMLoc &EndLoc)
override;
55 bool ParseDirectiveRefSym(
AsmToken DirectiveID);
58 unsigned Kind)
override;
65 bool ParseLiteralValues(
unsigned Size,
SMLoc L);
73#define GET_ASSEMBLER_HEADER
74#include "MSP430GenAsmMatcher.inc"
83 MRI = getContext().getRegisterInfo();
85 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
91 typedef MCParsedAsmOperand Base;
104 const MCExpr *Offset;
116 MSP430Operand(StringRef Tok, SMLoc
const &S)
117 : Kind(k_Tok), Tok(Tok), Start(S), End(S) {}
118 MSP430Operand(KindTy Kind, MCRegister
Reg, SMLoc
const &S, SMLoc
const &
E)
119 : Kind(Kind),
Reg(
Reg), Start(S), End(
E) {}
120 MSP430Operand(MCExpr
const *Imm, SMLoc
const &S, SMLoc
const &
E)
121 : Kind(k_Imm),
Imm(
Imm), Start(S), End(
E) {}
122 MSP430Operand(MCRegister
Reg, MCExpr
const *Expr, SMLoc
const &S,
124 : Kind(k_Mem), Mem({
Reg, Expr}), Start(S), End(
E) {}
126 void addRegOperands(MCInst &Inst,
unsigned N)
const {
127 assert((Kind == k_Reg || Kind == k_IndReg || Kind == k_PostIndReg) &&
128 "Unexpected operand kind");
129 assert(
N == 1 &&
"Invalid number of operands!");
134 void addExprOperand(MCInst &Inst,
const MCExpr *Expr)
const {
144 void addImmOperands(MCInst &Inst,
unsigned N)
const {
145 assert(Kind == k_Imm &&
"Unexpected operand kind");
146 assert(
N == 1 &&
"Invalid number of operands!");
148 addExprOperand(Inst, Imm);
151 void addMemOperands(MCInst &Inst,
unsigned N)
const {
152 assert(Kind == k_Mem &&
"Unexpected operand kind");
153 assert(
N == 2 &&
"Invalid number of operands");
156 addExprOperand(Inst, Mem.Offset);
159 bool isReg()
const override {
return Kind == k_Reg; }
160 bool isImm()
const override {
return Kind == k_Imm; }
161 bool isToken()
const override {
return Kind == k_Tok; }
162 bool isMem()
const override {
return Kind == k_Mem; }
163 bool isIndReg()
const {
return Kind == k_IndReg; }
164 bool isPostIndReg()
const {
return Kind == k_PostIndReg; }
166 bool isCGImm()
const {
171 if (!
Imm->evaluateAsAbsolute(Val))
174 if (Val == 0 || Val == 1 || Val == 2 || Val == 4 || Val == 8 || Val == -1)
181 assert(Kind == k_Tok &&
"Invalid access!");
185 MCRegister
getReg()
const override {
186 assert(Kind == k_Reg &&
"Invalid access!");
190 void setReg(MCRegister RegNo) {
191 assert(Kind == k_Reg &&
"Invalid access!");
195 static std::unique_ptr<MSP430Operand> CreateToken(StringRef Str, SMLoc S) {
196 return std::make_unique<MSP430Operand>(Str, S);
199 static std::unique_ptr<MSP430Operand> CreateReg(MCRegister
Reg, SMLoc S,
201 return std::make_unique<MSP430Operand>(k_Reg,
Reg, S,
E);
204 static std::unique_ptr<MSP430Operand> CreateImm(
const MCExpr *Val, SMLoc S,
206 return std::make_unique<MSP430Operand>(Val, S,
E);
209 static std::unique_ptr<MSP430Operand>
210 CreateMem(MCRegister
Reg,
const MCExpr *Val, SMLoc S, SMLoc
E) {
211 return std::make_unique<MSP430Operand>(
Reg, Val, S,
E);
214 static std::unique_ptr<MSP430Operand> CreateIndReg(MCRegister
Reg, SMLoc S,
216 return std::make_unique<MSP430Operand>(k_IndReg,
Reg, S,
E);
219 static std::unique_ptr<MSP430Operand> CreatePostIndReg(MCRegister
Reg,
221 return std::make_unique<MSP430Operand>(k_PostIndReg,
Reg, S,
E);
224 SMLoc getStartLoc()
const override {
return Start; }
225 SMLoc getEndLoc()
const override {
return End; }
227 void print(raw_ostream &O,
const MCAsmInfo &MAI)
const override {
230 O <<
"Token " << Tok;
233 O <<
"Register " <<
Reg;
244 O <<
"RegInd " <<
Reg;
247 O <<
"PostInc " <<
Reg;
254bool MSP430AsmParser::matchAndEmitInstruction(
SMLoc Loc,
unsigned &Opcode,
258 bool MatchingInlineAsm) {
260 unsigned MatchResult =
261 MatchInstructionImpl(
Operands, Inst, ErrorInfo, MatchingInlineAsm);
263 switch (MatchResult) {
268 case Match_MnemonicFail:
269 return Error(Loc,
"invalid instruction mnemonic");
270 case Match_InvalidOperand: {
271 SMLoc ErrorLoc = Loc;
272 if (ErrorInfo != ~0U) {
274 return Error(ErrorLoc,
"too few operands for instruction");
276 ErrorLoc = ((MSP430Operand &)*
Operands[ErrorInfo]).getStartLoc();
277 if (ErrorLoc == SMLoc())
280 return Error(ErrorLoc,
"invalid operand for instruction");
295 return Error(StartLoc,
"invalid register name");
304ParseStatus MSP430AsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
307 auto Name = getLexer().getTok().getIdentifier().lower();
309 if (
Reg == MSP430::NoRegister) {
311 if (
Reg == MSP430::NoRegister)
315 AsmToken
const &
T = getParser().getTok();
316 StartLoc =
T.getLoc();
317 EndLoc =
T.getEndLoc();
326bool MSP430AsmParser::parseJccInstruction(ParseInstructionInfo &
Info,
327 StringRef Name, SMLoc NameLoc,
329 if (!
Name.starts_with_insensitive(
"j"))
332 auto CC =
Name.drop_front().lower();
334 if (CC ==
"ne" || CC ==
"nz")
336 else if (CC ==
"eq" || CC ==
"z")
338 else if (CC ==
"lo" || CC ==
"nc")
340 else if (CC ==
"hs" || CC ==
"c")
351 return Error(NameLoc,
"unknown instruction");
354 Operands.push_back(MSP430Operand::CreateToken(
"jmp", NameLoc));
356 Operands.push_back(MSP430Operand::CreateToken(
"j", NameLoc));
358 Operands.push_back(MSP430Operand::CreateImm(CCode, SMLoc(), SMLoc()));
365 SMLoc ExprLoc = getLexer().getLoc();
366 if (getParser().parseExpression(Val))
367 return Error(ExprLoc,
"expected expression operand");
370 if (Val->evaluateAsAbsolute(Res))
371 if (Res < -512 || Res > 511)
372 return Error(ExprLoc,
"invalid jump offset");
374 Operands.push_back(MSP430Operand::CreateImm(Val, ExprLoc,
375 getLexer().getLoc()));
378 SMLoc Loc = getLexer().getLoc();
379 getParser().eatToEndOfStatement();
380 return Error(Loc,
"unexpected token");
387bool MSP430AsmParser::parseInstruction(ParseInstructionInfo &
Info,
388 StringRef Name, SMLoc NameLoc,
391 if (
Name.ends_with_insensitive(
".w"))
394 if (!parseJccInstruction(
Info, Name, NameLoc,
Operands))
398 Operands.push_back(MSP430Operand::CreateToken(Name, NameLoc));
413 SMLoc Loc = getLexer().getLoc();
414 getParser().eatToEndOfStatement();
415 return Error(Loc,
"unexpected token");
422bool MSP430AsmParser::ParseDirectiveRefSym(AsmToken DirectiveID) {
424 if (getParser().parseIdentifier(Name))
425 return TokError(
"expected identifier in directive");
428 getStreamer().emitSymbolAttribute(Sym,
MCSA_Global);
432ParseStatus MSP430AsmParser::parseDirective(AsmToken DirectiveID) {
434 if (IDVal.
lower() ==
".long")
435 return ParseLiteralValues(4, DirectiveID.
getLoc());
436 if (IDVal.
lower() ==
".word" || IDVal.
lower() ==
".short")
437 return ParseLiteralValues(2, DirectiveID.
getLoc());
438 if (IDVal.
lower() ==
".byte")
439 return ParseLiteralValues(1, DirectiveID.
getLoc());
440 if (IDVal.
lower() ==
".refsym")
441 return ParseDirectiveRefSym(DirectiveID);
446 switch (getLexer().getKind()) {
447 default:
return true;
451 SMLoc StartLoc, EndLoc;
452 if (!parseRegister(RegNo, StartLoc, EndLoc)) {
453 Operands.push_back(MSP430Operand::CreateReg(RegNo, StartLoc, EndLoc));
461 SMLoc StartLoc = getParser().getTok().getLoc();
464 if (!getParser().parseExpression(Val)) {
465 MCRegister RegNo = MSP430::PC;
466 SMLoc EndLoc = getParser().getTok().getLoc();
470 if (parseRegister(RegNo, RegStartLoc, EndLoc))
472 EndLoc = getParser().getTok().getEndLoc();
476 Operands.push_back(MSP430Operand::CreateMem(RegNo, Val, StartLoc,
484 SMLoc StartLoc = getParser().getTok().getLoc();
487 if (!getParser().parseExpression(Val)) {
488 SMLoc EndLoc = getParser().getTok().getLoc();
489 Operands.push_back(MSP430Operand::CreateMem(MSP430::SR, Val, StartLoc,
497 SMLoc StartLoc = getParser().getTok().getLoc();
500 SMLoc RegStartLoc, EndLoc;
501 if (parseRegister(RegNo, RegStartLoc, EndLoc))
504 Operands.push_back(MSP430Operand::CreatePostIndReg(RegNo, StartLoc, EndLoc));
508 Operands.push_back(MSP430Operand::CreateMem(RegNo,
511 Operands.push_back(MSP430Operand::CreateIndReg(RegNo, StartLoc, EndLoc));
516 SMLoc StartLoc = getParser().getTok().getLoc();
519 if (!getParser().parseExpression(Val)) {
520 SMLoc EndLoc = getParser().getTok().getLoc();
521 Operands.push_back(MSP430Operand::CreateImm(Val, StartLoc, EndLoc));
528bool MSP430AsmParser::ParseLiteralValues(
unsigned Size, SMLoc L) {
529 auto parseOne = [&]() ->
bool {
531 if (getParser().parseExpression(
Value))
533 getParser().getStreamer().emitValue(
Value,
Size, L);
536 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;
571unsigned MSP430AsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
573 MSP430Operand &
Op =
static_cast<MSP430Operand &
>(AsmOp);
576 return Match_InvalidOperand;
578 MCRegister
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 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")
Analysis containing CSE Info
#define LLVM_EXTERNAL_VISIBILITY
mir Rename Register Operands
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMSP430AsmParser()
static MCRegister convertGR16ToGR8(MCRegister Reg)
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
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
Represents a location in source code.
StringRef - 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)
Context & getContext() const
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
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()
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,...