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;
74 bool MatchingInlineAsm)
override;
77#define GET_ASSEMBLER_HEADER
78#include "LanaiGenAsmMatcher.inc"
88 Lexer(Parser.getLexer()), SubtargetInfo(STI) {
90 ComputeAvailableFeatures(SubtargetInfo.getFeatureBits()));
112 SMLoc StartLoc, EndLoc;
141 explicit LanaiOperand(KindTy Kind) :
Kind(
Kind) {}
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(); }
217 return isShiftedUInt<23, 2>(
static_cast<int32_t
>(
Value));
220 bool isBrTarget() {
return isBrImm() ||
isToken(); }
230 int64_t
Value = ConstExpr->getValue();
231 return Value != 0 && isShiftedUInt<16, 16>(
Value);
235 if (
const auto *SymbolRefExpr = dyn_cast<MCSpecifierExpr>(
Imm.Value))
240 if (
const auto *SymbolRefExpr =
241 dyn_cast<MCSpecifierExpr>(
BinaryExpr->getLHS()))
247 bool isHiImm16And() {
255 return (
Value != 0) && ((
Value & ~0xffff0000) == 0xffff);
268 return isUInt<16>(
static_cast<int32_t
>(
Value));
272 if (
const auto *SymbolRefExpr = dyn_cast<MCSpecifierExpr>(
Imm.Value))
277 if (
const auto *SymbolRefExpr =
278 dyn_cast<MCSpecifierExpr>(
BinaryExpr->getLHS()))
284 bool isLoImm16Signed() {
292 return isInt<16>(
static_cast<int32_t
>(
Value));
296 if (
const auto *SymbolRefExpr = dyn_cast<MCSpecifierExpr>(
Imm.Value))
301 if (
const auto *SymbolRefExpr =
302 dyn_cast<MCSpecifierExpr>(
BinaryExpr->getLHS()))
308 bool isLoImm16And() {
316 return ((
Value & ~0xffff) == 0xffff0000);
339 return isUInt<21>(
Value);
343 if (
const auto *SymbolRefExpr = dyn_cast<MCSpecifierExpr>(
Imm.Value))
346 dyn_cast<MCSymbolRefExpr>(
Imm.Value)) {
347 return SymbolRefExpr->getSpecifier() == 0;
352 if (
const auto *SymbolRefExpr =
353 dyn_cast<MCSpecifierExpr>(
BinaryExpr->getLHS()))
356 dyn_cast<MCSymbolRefExpr>(
BinaryExpr->getLHS()))
357 return SymbolRefExpr->getSpecifier() == 0;
371 return isInt<10>(
Value);
392 else if (
const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Expr))
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!");
468 else if (isa<MCSpecifierExpr>(
getImm())) {
470 const auto *SymbolRefExpr = dyn_cast<MCSpecifierExpr>(
getImm());
474 }
else if (isa<MCBinaryExpr>(
getImm())) {
478 cast<MCSpecifierExpr>(
BinaryExpr->getLHS())->getSpecifier() ==
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!");
498 else if (isa<MCSpecifierExpr>(
getImm())) {
500 const auto *SymbolRefExpr = dyn_cast<MCSpecifierExpr>(
getImm());
504 }
else if (isa<MCBinaryExpr>(
getImm())) {
508 cast<MCSpecifierExpr>(
BinaryExpr->getLHS())->getSpecifier() ==
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!");
528 else if (isa<MCSpecifierExpr>(
getImm())) {
530 const auto *SymbolRefExpr = dyn_cast<MCSpecifierExpr>(
getImm());
534 }
else if (isa<MCSymbolRefExpr>(
getImm())) {
537 dyn_cast<MCSymbolRefExpr>(
getImm());
541 }
else if (isa<MCBinaryExpr>(
getImm())) {
545 cast<MCSpecifierExpr>(
BinaryExpr->getLHS())->getSpecifier() ==
550 assert(
false &&
"Operand type not supported.");
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();
586 Op->StartLoc = Start;
593 auto Op = std::make_unique<LanaiOperand>(REGISTER);
594 Op->Reg.RegNum =
Reg;
595 Op->StartLoc = Start;
600 static std::unique_ptr<LanaiOperand> createImm(
const MCExpr *
Value,
602 auto Op = std::make_unique<LanaiOperand>(IMMEDIATE);
604 Op->StartLoc = Start;
609 static std::unique_ptr<LanaiOperand>
610 MorphToMemImm(std::unique_ptr<LanaiOperand>
Op) {
612 Op->Kind = MEMORY_IMM;
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,
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,
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) {
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: {
668 return Error(IdLoc,
"Too few operands for instruction");
671 if (ErrorLoc ==
SMLoc())
674 return Error(ErrorLoc,
"Invalid operand for instruction");
687std::unique_ptr<LanaiOperand>
688LanaiAsmParser::parseRegister(
bool RestoreOnFailure) {
689 SMLoc Start = Parser.getTok().getLoc();
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);
716 const AsmToken &Tok = getParser().getTok();
719 std::unique_ptr<LanaiOperand>
Op = parseRegister(
false);
721 RegNum =
Op->getReg();
722 return (
Op ==
nullptr);
727 const AsmToken &Tok = getParser().getTok();
730 std::unique_ptr<LanaiOperand>
Op = parseRegister(
true);
737std::unique_ptr<LanaiOperand> LanaiAsmParser::parseIdentifier() {
738 SMLoc Start = Parser.getTok().getLoc();
747 if (Parser.parseIdentifier(Identifier))
760 Error(Lexer.getLoc(),
"Expected '('");
766 if (Parser.parseIdentifier(Identifier))
771 if (Lexer.getKind() ==
AsmToken::Plus && Parser.parseExpression(RHS))
777 Error(Lexer.getLoc(),
"Expected ')'");
784 MCSymbol *
Sym = getContext().getOrCreateSymbol(Identifier);
791 return LanaiOperand::createImm(Res, Start,
End);
794std::unique_ptr<LanaiOperand> LanaiAsmParser::parseImmediate() {
795 SMLoc Start = Parser.getTok().getLoc();
799 switch (Lexer.getKind()) {
801 return parseIdentifier();
806 if (!Parser.parseExpression(ExprVal))
807 return LanaiOperand::createImm(ExprVal, Start,
End);
822unsigned LanaiAsmParser::parseAluOperator(
bool PreOp,
bool PostOp) {
824 Parser.parseIdentifier(IdString);
827 Error(Parser.getTok().getLoc(),
"Can't parse ALU operator");
837bool LanaiAsmParser::parsePrePost(
StringRef Type,
int *OffsetValue) {
838 bool PreOrPost =
false;
839 if (Lexer.getKind() == Lexer.peekTok(
true).getKind()) {
862 if (
const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(
Op.getImm())) {
868 if (
const auto *SymbolRefExpr = dyn_cast<MCSpecifierExpr>(
Op.getImm()))
874 const auto *LHSSymbolRefExpr =
875 dyn_cast<MCSpecifierExpr>(
BinaryExpr->getLHS());
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())
942 return Error(Parser.getTok().getLoc(),
943 "Memory address is not word aligned and larger than "
944 "class RM can handle");
945 Operands.push_back(LanaiOperand::MorphToMemRegImm(
952 return Error(Parser.getTok().getLoc(),
953 "Unknown operand, expected register or immediate");
959 PostOp = parsePrePost(
Type, &OffsetValue);
965 SMLoc Start = Parser.getTok().getLoc();
970 Offset = LanaiOperand::createImm(OffsetConstExpr, Start,
End);
973 if (
Offset || OffsetValue != 0)
974 return Error(Parser.getTok().getLoc(),
"Expected ']'");
977 AluOp = parseAluOperator(PreOp, PostOp);
982 return Error(Parser.getTok().getLoc(),
"Expected ']'");
992 return Error(Parser.getTok().getLoc(),
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));
1015 if (
Result.isFailure()) {
1016 Parser.eatToEndOfStatement();
1021 std::unique_ptr<LanaiOperand>
Op = parseRegister();
1029 Error(Parser.getTok().getLoc(),
"Unknown operand");
1030 Parser.eatToEndOfStatement();
1044 size_t Next =
Name.find(
'.');
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));
1078 size_t Next = Mnemonic.
rfind(
'.',
Name.size());
1085 Mnemonic = Mnemonic.
substr(0, Next + 1);
1087 Mnemonic = Mnemonic.
substr(0, Next);
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())
1133 dyn_cast<MCConstantExpr>(PossibleAluOp->getImm()))
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();
1150 static_cast<const LanaiOperand &
>(*
Operands[0]).getToken())
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())
1208 Error(Parser.getTok().getLoc(),
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"
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)
mir Rename Register Operands
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)
Target independent representation for an assembler token.
LLVM_ABI SMLoc getLoc() const
LLVM_ABI SMLoc getEndLoc() const
This class represents an Operation in the Expression.
Base class for user error types.
Lightweight error class with error context and mandatory checking.
This class is intended to be used as a base class for asm properties and features specific to the tar...
void printExpr(raw_ostream &, const MCExpr &) const
Generic assembler parser interface, for use by target specific assembly parsers.
Binary assembler expressions.
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)
Base class for the full range of assembler expressions which are needed for parsing.
Instances of this class represent a single low-level machine instruction.
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.
virtual SMLoc getStartLoc() const =0
getStartLoc - Get the location of the first token of this operand.
virtual bool isReg() const =0
isReg - Is this a register operand?
virtual bool isMem() const =0
isMem - Is this a memory operand?
virtual MCRegister getReg() const =0
virtual bool isToken() const =0
isToken - Is this a token operand?
virtual bool isImm() const =0
isImm - Is this an immediate operand?
virtual void print(raw_ostream &, const MCAsmInfo &) const =0
print - Print a debug representation of the operand to the given stream.
virtual SMLoc getEndLoc() const =0
getEndLoc - Get the location of the last token of this 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.
Represent a reference to a symbol from inside an expression.
uint16_t getSpecifier() const
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
MCTargetAsmParser - Generic interface to target specific assembly parsers.
virtual bool parseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands)=0
Parse one assembly instruction.
virtual bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
virtual ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
tryParseRegister - parse one register if possible
virtual bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm)=0
Recognize a series of operands of a parsed instruction as an actual MCInst and emit it to the specifi...
void setAvailableFeatures(const FeatureBitset &Value)
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)
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
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.
This class implements an extremely fast bulk output stream that can only output to a stream.
#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)
Reg
All possible values of the reg field in the ModR/M byte.
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
Target & getTheLanaiTarget()
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
DWARFExpression::Operation Op
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...