50 std::unique_ptr<LanaiOperand> parseRegister(
bool RestoreOnFailure =
false);
54 std::unique_ptr<LanaiOperand> parseIdentifier();
56 unsigned parseAluOperator(
bool PreOp,
bool PostOp);
69 SMLoc &EndLoc)
override;
71 bool matchAndEmitInstruction(
SMLoc IdLoc,
unsigned &Opcode,
74 bool MatchingInlineAsm)
override;
77#define GET_ASSEMBLER_HEADER
78#include "LanaiGenAsmMatcher.inc"
88 Lexer(Parser.getLexer()), SubtargetInfo(STI) {
90 ComputeAvailableFeatures(SubtargetInfo.getFeatureBits()));
97 const MCSubtargetInfo &SubtargetInfo;
112 SMLoc StartLoc, EndLoc;
129 MCRegister OffsetReg;
131 const MCExpr *Offset;
141 explicit LanaiOperand(KindTy Kind) : Kind(Kind) {}
148 SMLoc getStartLoc()
const override {
return StartLoc; }
151 SMLoc getEndLoc()
const override {
return EndLoc; }
153 MCRegister
getReg()
const override {
158 const MCExpr *
getImm()
const {
159 assert(isImm() &&
"Invalid type access!");
164 assert(isToken() &&
"Invalid type access!");
165 return StringRef(Tok.Data, Tok.Length);
168 MCRegister getMemBaseReg()
const {
173 MCRegister getMemOffsetReg()
const {
175 return Mem.OffsetReg;
178 const MCExpr *getMemOffset()
const {
183 unsigned getMemOp()
const {
189 bool isReg()
const override {
return Kind == REGISTER; }
191 bool isImm()
const override {
return Kind == IMMEDIATE; }
193 bool isMem()
const override {
194 return isMemImm() || isMemRegImm() || isMemRegReg();
197 bool isMemImm()
const {
return Kind == MEMORY_IMM; }
199 bool isMemRegImm()
const {
return Kind == MEMORY_REG_IMM; }
201 bool isMemRegReg()
const {
return Kind == MEMORY_REG_REG; }
203 bool isMemSpls()
const {
return isMemRegImm() || isMemRegReg(); }
205 bool isToken()
const override {
return Kind == TOKEN; }
220 bool isBrTarget() {
return isBrImm() || isToken(); }
222 bool isCallTarget() {
return isImm() || isToken(); }
230 int64_t
Value = ConstExpr->getValue();
240 if (
const auto *SymbolRefExpr =
247 bool isHiImm16And() {
255 return (
Value != 0) && ((
Value & ~0xffff0000) == 0xffff);
277 if (
const auto *SymbolRefExpr =
284 bool isLoImm16Signed() {
301 if (
const auto *SymbolRefExpr =
308 bool isLoImm16And() {
316 return ((
Value & ~0xffff) == 0xffff0000);
345 if (
const MCSymbolRefExpr *SymbolRefExpr =
347 return SymbolRefExpr->getSpecifier() == 0;
352 if (
const auto *SymbolRefExpr =
355 if (
const MCSymbolRefExpr *SymbolRefExpr =
357 return SymbolRefExpr->getSpecifier() == 0;
388 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const {
399 void addRegOperands(MCInst &Inst,
unsigned N)
const {
400 assert(
N == 1 &&
"Invalid number of operands!");
404 void addImmOperands(MCInst &Inst,
unsigned N)
const {
405 assert(
N == 1 &&
"Invalid number of operands!");
409 void addBrTargetOperands(MCInst &Inst,
unsigned N)
const {
410 assert(
N == 1 &&
"Invalid number of operands!");
415 assert(
N == 1 &&
"Invalid number of operands!");
419 void addCondCodeOperands(MCInst &Inst,
unsigned N)
const {
420 assert(
N == 1 &&
"Invalid number of operands!");
424 void addMemImmOperands(MCInst &Inst,
unsigned N)
const {
425 assert(
N == 1 &&
"Invalid number of operands!");
426 const MCExpr *Expr = getMemOffset();
430 void addMemRegImmOperands(MCInst &Inst,
unsigned N)
const {
431 assert(
N == 3 &&
"Invalid number of operands!");
433 const MCExpr *Expr = getMemOffset();
438 void addMemRegRegOperands(MCInst &Inst,
unsigned N)
const {
439 assert(
N == 3 &&
"Invalid number of operands!");
441 assert(getMemOffsetReg() &&
"Invalid offset");
446 void addMemSplsOperands(MCInst &Inst,
unsigned N)
const {
448 addMemRegImmOperands(Inst,
N);
450 addMemRegRegOperands(Inst,
N);
453 void addImmShiftOperands(MCInst &Inst,
unsigned N)
const {
454 assert(
N == 1 &&
"Invalid number of operands!");
458 void addImm10Operands(MCInst &Inst,
unsigned N)
const {
459 assert(
N == 1 &&
"Invalid number of operands!");
463 void addLoImm16Operands(MCInst &Inst,
unsigned N)
const {
464 assert(
N == 1 &&
"Invalid number of operands!");
483 assert(
false &&
"Operand type not supported.");
486 void addLoImm16AndOperands(MCInst &Inst,
unsigned N)
const {
487 assert(
N == 1 &&
"Invalid number of operands!");
491 assert(
false &&
"Operand type not supported.");
494 void addHiImm16Operands(MCInst &Inst,
unsigned N)
const {
495 assert(
N == 1 &&
"Invalid number of operands!");
513 assert(
false &&
"Operand type not supported.");
516 void addHiImm16AndOperands(MCInst &Inst,
unsigned N)
const {
517 assert(
N == 1 &&
"Invalid number of operands!");
521 assert(
false &&
"Operand type not supported.");
524 void addLoImm21Operands(MCInst &Inst,
unsigned N)
const {
525 assert(
N == 1 &&
"Invalid number of operands!");
536 const MCSymbolRefExpr *SymbolRefExpr =
550 assert(
false &&
"Operand type not supported.");
553 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
556 OS <<
"Imm: " <<
getImm() <<
"\n";
559 OS <<
"Token: " <<
getToken() <<
"\n";
562 OS <<
"Reg: %r" <<
getReg() <<
"\n";
570 OS <<
"MemRegImm: " << getMemBaseReg() <<
"+";
575 assert(getMemOffset() ==
nullptr);
576 OS <<
"MemRegReg: " << getMemBaseReg() <<
"+"
577 <<
"%r" << getMemOffsetReg() <<
"\n";
582 static std::unique_ptr<LanaiOperand> CreateToken(StringRef Str, SMLoc Start) {
583 auto Op = std::make_unique<LanaiOperand>(TOKEN);
584 Op->Tok.Data = Str.data();
585 Op->Tok.Length = Str.size();
591 static std::unique_ptr<LanaiOperand> createReg(MCRegister
Reg, SMLoc Start,
593 auto Op = std::make_unique<LanaiOperand>(REGISTER);
594 Op->Reg.RegNum =
Reg;
600 static std::unique_ptr<LanaiOperand> createImm(
const MCExpr *
Value,
601 SMLoc Start, SMLoc End) {
602 auto Op = std::make_unique<LanaiOperand>(IMMEDIATE);
609 static std::unique_ptr<LanaiOperand>
610 MorphToMemImm(std::unique_ptr<LanaiOperand>
Op) {
611 const MCExpr *
Imm =
Op->getImm();
612 Op->Kind = MEMORY_IMM;
613 Op->Mem.BaseReg = MCRegister();
615 Op->Mem.OffsetReg = 0;
616 Op->Mem.Offset =
Imm;
620 static std::unique_ptr<LanaiOperand>
621 MorphToMemRegReg(MCRegister BaseReg, std::unique_ptr<LanaiOperand>
Op,
623 MCRegister OffsetReg =
Op->getReg();
624 Op->Kind = MEMORY_REG_REG;
626 Op->Mem.AluOp = AluOp;
627 Op->Mem.OffsetReg = OffsetReg;
628 Op->Mem.Offset =
nullptr;
632 static std::unique_ptr<LanaiOperand>
633 MorphToMemRegImm(MCRegister BaseReg, std::unique_ptr<LanaiOperand>
Op,
635 const MCExpr *
Imm =
Op->getImm();
636 Op->Kind = MEMORY_REG_IMM;
638 Op->Mem.AluOp = AluOp;
639 Op->Mem.OffsetReg = 0;
640 Op->Mem.Offset =
Imm;
647bool LanaiAsmParser::matchAndEmitInstruction(
SMLoc IdLoc,
unsigned &Opcode,
651 bool MatchingInlineAsm) {
655 switch (MatchInstructionImpl(
Operands, Inst, ErrorInfo, MatchingInlineAsm)) {
660 case Match_MissingFeature:
661 return Error(IdLoc,
"Instruction use requires option to be enabled");
662 case Match_MnemonicFail:
663 return Error(IdLoc,
"Unrecognized instruction mnemonic");
664 case Match_InvalidOperand: {
666 if (ErrorInfo != ~0U) {
668 return Error(IdLoc,
"Too few operands for instruction");
670 ErrorLoc = ((LanaiOperand &)*
Operands[ErrorInfo]).getStartLoc();
671 if (ErrorLoc == SMLoc())
674 return Error(ErrorLoc,
"Invalid operand for instruction");
687std::unique_ptr<LanaiOperand>
688LanaiAsmParser::parseRegister(
bool RestoreOnFailure) {
691 std::optional<AsmToken> PercentTok;
696 PercentTok = Parser.
getTok();
702 if (PercentTok && RestoreOnFailure)
703 Lexer.
UnLex(*PercentTok);
707 return LanaiOperand::createReg(
Reg, Start, End);
709 if (PercentTok && RestoreOnFailure)
710 Lexer.
UnLex(*PercentTok);
714bool LanaiAsmParser::parseRegister(MCRegister &RegNum, SMLoc &StartLoc,
716 const AsmToken &Tok = getParser().getTok();
719 std::unique_ptr<LanaiOperand>
Op = parseRegister(
false);
721 RegNum =
Op->getReg();
722 return (
Op ==
nullptr);
725ParseStatus LanaiAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
727 const AsmToken &Tok = getParser().getTok();
730 std::unique_ptr<LanaiOperand>
Op = parseRegister(
true);
737std::unique_ptr<LanaiOperand> LanaiAsmParser::parseIdentifier() {
740 const MCExpr *Res, *
RHS =
nullptr;
791 return LanaiOperand::createImm(Res, Start, End);
794std::unique_ptr<LanaiOperand> LanaiAsmParser::parseImmediate() {
798 const MCExpr *ExprVal;
801 return parseIdentifier();
807 return LanaiOperand::createImm(ExprVal, Start, End);
822unsigned LanaiAsmParser::parseAluOperator(
bool PreOp,
bool PostOp) {
837bool LanaiAsmParser::parsePrePost(StringRef
Type,
int *OffsetValue) {
838 bool PreOrPost =
false;
874 const auto *LHSSymbolRefExpr =
876 return (LHSSymbolRefExpr &&
897 Type =
static_cast<LanaiOperand *
>(
Operands[0].get())->getToken();
903 bool PostOp =
false, PreOp =
false;
906 std::unique_ptr<LanaiOperand>
Op = parseRegister();
923 std::unique_ptr<LanaiOperand>
Offset =
nullptr;
928 PreOp = parsePrePost(
Type, &OffsetValue);
930 Op = parseRegister();
939 Operands.push_back(LanaiOperand::MorphToMemImm(std::move(
Op)));
941 if (!
Op->isLoImm16Signed())
943 "Memory address is not word aligned and larger than "
944 "class RM can handle");
945 Operands.push_back(LanaiOperand::MorphToMemRegImm(
953 "Unknown operand, expected register or immediate");
959 PostOp = parsePrePost(
Type, &OffsetValue);
968 const MCConstantExpr *OffsetConstExpr =
970 Offset = LanaiOperand::createImm(OffsetConstExpr, Start, End);
973 if (
Offset || OffsetValue != 0)
977 AluOp = parseAluOperator(PreOp, PostOp);
993 "Memory address is not word aligned and larger than class RM "
998 ? LanaiOperand::MorphToMemRegImm(BaseReg, std::move(
Offset), AluOp)
999 : LanaiOperand::MorphToMemRegReg(BaseReg, std::move(
Offset), AluOp));
1008 StringRef Mnemonic) {
1011 ParseStatus
Result = MatchOperandParserImpl(*
Operands, Mnemonic);
1015 if (
Result.isFailure()) {
1021 std::unique_ptr<LanaiOperand>
Op = parseRegister();
1042StringRef LanaiAsmParser::splitMnemonic(StringRef Name, SMLoc NameLoc,
1046 StringRef Mnemonic =
Name;
1051 if (Mnemonic[0] ==
'b' ||
1052 (Mnemonic[0] ==
's' && !Mnemonic.
starts_with(
"sel") &&
1059 Mnemonic = Mnemonic.
slice(0, 1);
1060 Operands->push_back(LanaiOperand::CreateToken(Mnemonic, NameLoc));
1061 Operands->push_back(LanaiOperand::createImm(
1064 Operands->push_back(LanaiOperand::CreateToken(
".r", NameLoc));
1089 Operands->push_back(LanaiOperand::CreateToken(Mnemonic, NameLoc));
1090 Operands->push_back(LanaiOperand::createImm(
1096 Operands->push_back(LanaiOperand::CreateToken(Mnemonic, NameLoc));
1098 Operands->push_back(LanaiOperand::CreateToken(
".r", NameLoc));
1110 bool Modifies =
false;
1126 int PossibleAluOpIdx =
Offset + 3;
1127 int PossibleBaseIdx =
Offset + 1;
1128 int PossibleDestIdx =
Offset + 4;
1129 if (LanaiOperand *PossibleAluOp =
1130 static_cast<LanaiOperand *
>(
Operands[PossibleAluOpIdx].
get()))
1131 if (PossibleAluOp->isImm())
1135 return Modifies &&
Operands[PossibleBaseIdx]->isReg() &&
1136 Operands[PossibleDestIdx]->isReg() &&
1137 Operands[PossibleBaseIdx]->getReg() ==
1138 Operands[PossibleDestIdx]->getReg();
1142 return static_cast<const LanaiOperand &
>(
op).
isReg();
1162bool LanaiAsmParser::parseInstruction(ParseInstructionInfo & ,
1163 StringRef Name, SMLoc NameLoc,
1166 StringRef Mnemonic = splitMnemonic(Name, NameLoc, &
Operands);
1173 if (!parseOperand(&
Operands, Mnemonic).isSuccess())
1181 Operands.insert(
Operands.begin(), LanaiOperand::CreateToken(
"s", NameLoc));
1183 LanaiOperand::createImm(
1194 Operands.insert(
Operands.begin(), LanaiOperand::CreateToken(
"bt", NameLoc));
1203 if (!parseOperand(&
Operands, Mnemonic).isSuccess())
1209 "the destination register can't equal the base register in an "
1210 "instruction that modifies the base register.");
1218 LanaiOperand::createImm(
1226#define GET_REGISTER_MATCHER
1227#define GET_MATCHER_IMPLEMENTATION
1228#include "LanaiGenAsmMatcher.inc"
static MCRegister MatchRegisterName(StringRef Name)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool addCallTargetOperands(MachineInstrBuilder &CallInst, MachineIRBuilder &MIRBuilder, AMDGPUCallLowering::CallLoweringInfo &Info, bool IsDynamicVGPRChainCall=false)
Analysis containing CSE Info
#define LLVM_EXTERNAL_VISIBILITY
static int SizeForSuffix(StringRef T)
static bool IsMemoryAssignmentError(const OperandVector &Operands)
bool shouldBeSls(const LanaiOperand &Op)
static MCRegister MatchRegisterName(StringRef Name)
static bool MaybePredicatedInst(const OperandVector &Operands)
static unsigned AluWithPrePost(unsigned AluCode, bool PreOp, bool PostOp)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLanaiAsmParser()
static bool IsRegister(const MCParsedAsmOperand &op)
mir Rename Register Operands
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
bool parseImmediate(MCInst &MI, uint64_t &Size, ArrayRef< uint8_t > Bytes)
SMLoc getLoc() const
Get the current source location.
const AsmToken peekTok(bool ShouldSkipSpace=true)
Look ahead at the next token to be lexed.
void UnLex(AsmToken const &Token)
AsmToken::TokenKind getKind() const
Get the kind of current token.
const AsmToken & getTok() const
Get the current (last) lexed token.
bool is(AsmToken::TokenKind K) const
Check if the current token has kind K.
const AsmToken & Lex()
Consume the next token from the input stream and return it.
bool isNot(AsmToken::TokenKind K) const
Check if the current token has kind K.
LLVM_ABI SMLoc getLoc() const
TokenKind getKind() const
LLVM_ABI SMLoc getEndLoc() 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
Generic assembler parser interface, for use by target specific assembly parsers.
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
Binary assembler expressions.
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
unsigned getOpcode() const
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.
Wrapper class representing physical registers. Should be passed by value.
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
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.
uint16_t getSpecifier() const
MCTargetAsmParser - Generic interface to target specific assembly parsers.
Ternary parse status returned by various parse* methods.
static constexpr StatusTy Failure
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
StringRef - Represent a constant reference to a string, i.e.
bool consume_back(StringRef Suffix)
Returns true if this StringRef has the given suffix and removes that suffix.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
size_t rfind(char C, size_t From=npos) const
Search for the last character C in the string.
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
A switch()-like statement whose cases are string literals.
StringSwitch & StartsWith(StringLiteral S, T Value)
StringSwitch & EndsWith(StringLiteral S, T Value)
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
#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,...
static unsigned makePostOp(unsigned AluOp)
static unsigned makePreOp(unsigned AluOp)
static AluCode stringToLanaiAluCode(StringRef S)
static bool modifiesOp(unsigned AluOp)
static CondCode suffixToLanaiCondCode(StringRef S)
Context & getContext() const
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
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)
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
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 & getTheLanaiTarget()
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
FunctionAddr VTableAddr Next
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
constexpr bool isShiftedUInt(uint64_t x)
Checks if a unsigned integer is an N bit number shifted left by S.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...