51 std::unique_ptr<LanaiOperand> parseRegister(
bool RestoreOnFailure =
false);
55 std::unique_ptr<LanaiOperand> parseIdentifier();
57 unsigned parseAluOperator(
bool PreOp,
bool PostOp);
70 SMLoc &EndLoc)
override;
72 bool matchAndEmitInstruction(
SMLoc IdLoc,
unsigned &Opcode,
75 bool MatchingInlineAsm)
override;
78#define GET_ASSEMBLER_HEADER
79#include "LanaiGenAsmMatcher.inc"
91 ComputeAvailableFeatures(SubtargetInfo.getFeatureBits()));
98 const MCSubtargetInfo &SubtargetInfo;
113 SMLoc StartLoc, EndLoc;
130 MCRegister OffsetReg;
132 const MCExpr *Offset;
142 explicit LanaiOperand(KindTy Kind) : Kind(Kind) {}
149 SMLoc getStartLoc()
const override {
return StartLoc; }
152 SMLoc getEndLoc()
const override {
return EndLoc; }
154 MCRegister
getReg()
const override {
159 const MCExpr *
getImm()
const {
160 assert(isImm() &&
"Invalid type access!");
165 assert(isToken() &&
"Invalid type access!");
166 return StringRef(Tok.Data, Tok.Length);
169 MCRegister getMemBaseReg()
const {
174 MCRegister getMemOffsetReg()
const {
176 return Mem.OffsetReg;
179 const MCExpr *getMemOffset()
const {
184 unsigned getMemOp()
const {
190 bool isReg()
const override {
return Kind == REGISTER; }
192 bool isImm()
const override {
return Kind == IMMEDIATE; }
194 bool isMem()
const override {
195 return isMemImm() || isMemRegImm() || isMemRegReg();
198 bool isMemImm()
const {
return Kind == MEMORY_IMM; }
200 bool isMemRegImm()
const {
return Kind == MEMORY_REG_IMM; }
202 bool isMemRegReg()
const {
return Kind == MEMORY_REG_REG; }
204 bool isMemSpls()
const {
return isMemRegImm() || isMemRegReg(); }
206 bool isToken()
const override {
return Kind == TOKEN; }
221 bool isBrTarget() {
return isBrImm() || isToken(); }
223 bool isCallTarget() {
return isImm() || isToken(); }
231 int64_t
Value = ConstExpr->getValue();
241 if (
const auto *SymbolRefExpr =
248 bool isHiImm16And() {
256 return (
Value != 0) && ((
Value & ~0xffff0000) == 0xffff);
278 if (
const auto *SymbolRefExpr =
285 bool isLoImm16Signed() {
302 if (
const auto *SymbolRefExpr =
309 bool isLoImm16And() {
317 return ((
Value & ~0xffff) == 0xffff0000);
346 if (
const MCSymbolRefExpr *SymbolRefExpr =
348 return SymbolRefExpr->getSpecifier() == 0;
353 if (
const auto *SymbolRefExpr =
356 if (
const MCSymbolRefExpr *SymbolRefExpr =
358 return SymbolRefExpr->getSpecifier() == 0;
389 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const {
400 void addRegOperands(MCInst &Inst,
unsigned N)
const {
401 assert(
N == 1 &&
"Invalid number of operands!");
405 void addImmOperands(MCInst &Inst,
unsigned N)
const {
406 assert(
N == 1 &&
"Invalid number of operands!");
410 void addBrTargetOperands(MCInst &Inst,
unsigned N)
const {
411 assert(
N == 1 &&
"Invalid number of operands!");
416 assert(
N == 1 &&
"Invalid number of operands!");
420 void addCondCodeOperands(MCInst &Inst,
unsigned N)
const {
421 assert(
N == 1 &&
"Invalid number of operands!");
425 void addMemImmOperands(MCInst &Inst,
unsigned N)
const {
426 assert(
N == 1 &&
"Invalid number of operands!");
427 const MCExpr *Expr = getMemOffset();
431 void addMemRegImmOperands(MCInst &Inst,
unsigned N)
const {
432 assert(
N == 3 &&
"Invalid number of operands!");
434 const MCExpr *Expr = getMemOffset();
439 void addMemRegRegOperands(MCInst &Inst,
unsigned N)
const {
440 assert(
N == 3 &&
"Invalid number of operands!");
442 assert(getMemOffsetReg() &&
"Invalid offset");
447 void addMemSplsOperands(MCInst &Inst,
unsigned N)
const {
449 addMemRegImmOperands(Inst,
N);
451 addMemRegRegOperands(Inst,
N);
454 void addImmShiftOperands(MCInst &Inst,
unsigned N)
const {
455 assert(
N == 1 &&
"Invalid number of operands!");
459 void addImm10Operands(MCInst &Inst,
unsigned N)
const {
460 assert(
N == 1 &&
"Invalid number of operands!");
464 void addLoImm16Operands(MCInst &Inst,
unsigned N)
const {
465 assert(
N == 1 &&
"Invalid number of operands!");
484 assert(
false &&
"Operand type not supported.");
487 void addLoImm16AndOperands(MCInst &Inst,
unsigned N)
const {
488 assert(
N == 1 &&
"Invalid number of operands!");
492 assert(
false &&
"Operand type not supported.");
495 void addHiImm16Operands(MCInst &Inst,
unsigned N)
const {
496 assert(
N == 1 &&
"Invalid number of operands!");
514 assert(
false &&
"Operand type not supported.");
517 void addHiImm16AndOperands(MCInst &Inst,
unsigned N)
const {
518 assert(
N == 1 &&
"Invalid number of operands!");
522 assert(
false &&
"Operand type not supported.");
525 void addLoImm21Operands(MCInst &Inst,
unsigned N)
const {
526 assert(
N == 1 &&
"Invalid number of operands!");
537 const MCSymbolRefExpr *SymbolRefExpr =
551 assert(
false &&
"Operand type not supported.");
554 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
557 OS <<
"Imm: " <<
getImm() <<
"\n";
560 OS <<
"Token: " <<
getToken() <<
"\n";
563 OS <<
"Reg: %r" <<
getReg().
id() <<
"\n";
571 OS <<
"MemRegImm: " << getMemBaseReg().id() <<
"+";
576 assert(getMemOffset() ==
nullptr);
577 OS <<
"MemRegReg: " << getMemBaseReg().id() <<
"+"
578 <<
"%r" << getMemOffsetReg().id() <<
"\n";
583 static std::unique_ptr<LanaiOperand> CreateToken(StringRef Str, SMLoc Start) {
584 auto Op = std::make_unique<LanaiOperand>(TOKEN);
585 Op->Tok.Data = Str.data();
586 Op->Tok.Length = Str.size();
592 static std::unique_ptr<LanaiOperand> createReg(MCRegister
Reg, SMLoc Start,
594 auto Op = std::make_unique<LanaiOperand>(REGISTER);
595 Op->Reg.RegNum =
Reg;
601 static std::unique_ptr<LanaiOperand> createImm(
const MCExpr *
Value,
602 SMLoc Start, SMLoc End) {
603 auto Op = std::make_unique<LanaiOperand>(IMMEDIATE);
610 static std::unique_ptr<LanaiOperand>
611 MorphToMemImm(std::unique_ptr<LanaiOperand>
Op) {
612 const MCExpr *
Imm =
Op->getImm();
613 Op->Kind = MEMORY_IMM;
614 Op->Mem.BaseReg = MCRegister();
616 Op->Mem.OffsetReg = 0;
617 Op->Mem.Offset =
Imm;
621 static std::unique_ptr<LanaiOperand>
622 MorphToMemRegReg(MCRegister BaseReg, std::unique_ptr<LanaiOperand>
Op,
624 MCRegister OffsetReg =
Op->getReg();
625 Op->Kind = MEMORY_REG_REG;
627 Op->Mem.AluOp = AluOp;
628 Op->Mem.OffsetReg = OffsetReg;
629 Op->Mem.Offset =
nullptr;
633 static std::unique_ptr<LanaiOperand>
634 MorphToMemRegImm(MCRegister BaseReg, std::unique_ptr<LanaiOperand>
Op,
636 const MCExpr *
Imm =
Op->getImm();
637 Op->Kind = MEMORY_REG_IMM;
639 Op->Mem.AluOp = AluOp;
640 Op->Mem.OffsetReg = 0;
641 Op->Mem.Offset =
Imm;
648bool LanaiAsmParser::matchAndEmitInstruction(
SMLoc IdLoc,
unsigned &Opcode,
652 bool MatchingInlineAsm) {
656 switch (MatchInstructionImpl(
Operands, Inst, ErrorInfo, MatchingInlineAsm)) {
661 case Match_MissingFeature:
662 return Error(IdLoc,
"Instruction use requires option to be enabled");
663 case Match_MnemonicFail:
664 return Error(IdLoc,
"Unrecognized instruction mnemonic");
665 case Match_InvalidOperand: {
667 if (ErrorInfo != ~0U) {
669 return Error(IdLoc,
"Too few operands for instruction");
671 ErrorLoc = ((LanaiOperand &)*
Operands[ErrorInfo]).getStartLoc();
672 if (ErrorLoc == SMLoc())
675 return Error(ErrorLoc,
"Invalid operand for instruction");
688std::unique_ptr<LanaiOperand>
689LanaiAsmParser::parseRegister(
bool RestoreOnFailure) {
692 std::optional<AsmToken> PercentTok;
697 PercentTok = Parser.
getTok();
703 if (PercentTok && RestoreOnFailure)
704 Lexer.
UnLex(*PercentTok);
708 return LanaiOperand::createReg(
Reg, Start, End);
710 if (PercentTok && RestoreOnFailure)
711 Lexer.
UnLex(*PercentTok);
715bool LanaiAsmParser::parseRegister(MCRegister &RegNum, SMLoc &StartLoc,
717 const AsmToken &Tok = getParser().getTok();
720 std::unique_ptr<LanaiOperand>
Op = parseRegister(
false);
722 RegNum =
Op->getReg();
723 return (
Op ==
nullptr);
726ParseStatus LanaiAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
728 const AsmToken &Tok = getParser().getTok();
731 std::unique_ptr<LanaiOperand>
Op = parseRegister(
true);
738std::unique_ptr<LanaiOperand> LanaiAsmParser::parseIdentifier() {
741 const MCExpr *Res, *
RHS =
nullptr;
792 return LanaiOperand::createImm(Res, Start, End);
795std::unique_ptr<LanaiOperand> LanaiAsmParser::parseImmediate() {
799 const MCExpr *ExprVal;
802 return parseIdentifier();
808 return LanaiOperand::createImm(ExprVal, Start, End);
823unsigned LanaiAsmParser::parseAluOperator(
bool PreOp,
bool PostOp) {
838bool LanaiAsmParser::parsePrePost(StringRef
Type,
int *OffsetValue) {
839 bool PreOrPost =
false;
875 const auto *LHSSymbolRefExpr =
877 return (LHSSymbolRefExpr &&
898 Type =
static_cast<LanaiOperand *
>(
Operands[0].get())->getToken();
904 bool PostOp =
false, PreOp =
false;
907 std::unique_ptr<LanaiOperand>
Op = parseRegister();
924 std::unique_ptr<LanaiOperand>
Offset =
nullptr;
929 PreOp = parsePrePost(
Type, &OffsetValue);
931 Op = parseRegister();
940 Operands.push_back(LanaiOperand::MorphToMemImm(std::move(
Op)));
942 if (!
Op->isLoImm16Signed())
944 "Memory address is not word aligned and larger than "
945 "class RM can handle");
946 Operands.push_back(LanaiOperand::MorphToMemRegImm(
954 "Unknown operand, expected register or immediate");
960 PostOp = parsePrePost(
Type, &OffsetValue);
969 const MCConstantExpr *OffsetConstExpr =
971 Offset = LanaiOperand::createImm(OffsetConstExpr, Start, End);
974 if (
Offset || OffsetValue != 0)
978 AluOp = parseAluOperator(PreOp, PostOp);
994 "Memory address is not word aligned and larger than class RM "
999 ? LanaiOperand::MorphToMemRegImm(BaseReg, std::move(
Offset), AluOp)
1000 : LanaiOperand::MorphToMemRegReg(BaseReg, std::move(
Offset), AluOp));
1009 StringRef Mnemonic) {
1012 ParseStatus
Result = MatchOperandParserImpl(*
Operands, Mnemonic);
1016 if (
Result.isFailure()) {
1022 std::unique_ptr<LanaiOperand>
Op = parseRegister();
1043StringRef LanaiAsmParser::splitMnemonic(StringRef Name, SMLoc NameLoc,
1047 StringRef Mnemonic =
Name;
1052 if (Mnemonic[0] ==
'b' ||
1053 (Mnemonic[0] ==
's' && !Mnemonic.
starts_with(
"sel") &&
1060 Mnemonic = Mnemonic.
slice(0, 1);
1061 Operands->push_back(LanaiOperand::CreateToken(Mnemonic, NameLoc));
1062 Operands->push_back(LanaiOperand::createImm(
1065 Operands->push_back(LanaiOperand::CreateToken(
".r", NameLoc));
1090 Operands->push_back(LanaiOperand::CreateToken(Mnemonic, NameLoc));
1091 Operands->push_back(LanaiOperand::createImm(
1097 Operands->push_back(LanaiOperand::CreateToken(Mnemonic, NameLoc));
1099 Operands->push_back(LanaiOperand::CreateToken(
".r", NameLoc));
1111 bool Modifies =
false;
1127 int PossibleAluOpIdx =
Offset + 3;
1128 int PossibleBaseIdx =
Offset + 1;
1129 int PossibleDestIdx =
Offset + 4;
1130 if (LanaiOperand *PossibleAluOp =
1131 static_cast<LanaiOperand *
>(
Operands[PossibleAluOpIdx].
get()))
1132 if (PossibleAluOp->isImm())
1136 return Modifies &&
Operands[PossibleBaseIdx]->isReg() &&
1137 Operands[PossibleDestIdx]->isReg() &&
1138 Operands[PossibleBaseIdx]->getReg() ==
1139 Operands[PossibleDestIdx]->getReg();
1143 return static_cast<const LanaiOperand &
>(
op).
isReg();
1163bool LanaiAsmParser::parseInstruction(ParseInstructionInfo & ,
1164 StringRef Name, SMLoc NameLoc,
1167 StringRef Mnemonic = splitMnemonic(Name, NameLoc, &
Operands);
1174 if (!parseOperand(&
Operands, Mnemonic).isSuccess())
1182 Operands.insert(
Operands.begin(), LanaiOperand::CreateToken(
"s", NameLoc));
1184 LanaiOperand::createImm(
1195 Operands.insert(
Operands.begin(), LanaiOperand::CreateToken(
"bt", NameLoc));
1204 if (!parseOperand(&
Operands, Mnemonic).isSuccess())
1210 "the destination register can't equal the base register in an "
1211 "instruction that modifies the base register.");
1219 LanaiOperand::createImm(
1227#define GET_REGISTER_MATCHER
1228#define GET_MATCHER_IMPLEMENTATION
1229#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)
#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)
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
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.
constexpr unsigned id() const
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
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)
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
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()
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
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...
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
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,...