48 class LanaiAsmParser :
public MCTargetAsmParser {
50 std::unique_ptr<LanaiOperand> parseRegister();
52 std::unique_ptr<LanaiOperand> parseImmediate();
54 std::unique_ptr<LanaiOperand> parseIdentifier();
56 unsigned parseAluOperator(
bool PreOp,
bool PostOp);
59 StringRef splitMnemonic(StringRef
Name, SMLoc NameLoc,
62 bool parsePrePost(StringRef
Type,
int *OffsetValue);
64 bool ParseDirective(AsmToken DirectiveID)
override;
66 bool ParseInstruction(ParseInstructionInfo &Info, StringRef
Name,
69 bool ParseRegister(
unsigned &RegNum, SMLoc &StartLoc, SMLoc &EndLoc)
override;
71 bool MatchAndEmitInstruction(SMLoc IdLoc,
unsigned &Opcode,
74 bool MatchingInlineAsm)
override;
77 #define GET_ASSEMBLER_HEADER
78 #include "LanaiGenAsmMatcher.inc"
86 LanaiAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &Parser,
87 const MCInstrInfo &MII,
const MCTargetOptions &Options)
88 : MCTargetAsmParser(Options, STI), Parser(Parser),
89 Lexer(Parser.getLexer()), SubtargetInfo(STI) {
91 ComputeAvailableFeatures(SubtargetInfo.getFeatureBits()));
98 const MCSubtargetInfo &SubtargetInfo;
103 struct LanaiOperand :
public MCParsedAsmOperand {
113 SMLoc StartLoc, EndLoc;
142 explicit LanaiOperand(KindTy
Kind) : MCParsedAsmOperand(), Kind(Kind) {}
149 SMLoc getStartLoc()
const override {
return StartLoc; }
152 SMLoc getEndLoc()
const override {
return EndLoc; }
154 unsigned 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 unsigned getMemBaseReg()
const {
174 unsigned 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; }
213 const MCConstantExpr *MCE =
dyn_cast<MCConstantExpr>(Imm.Value);
216 int64_t Value = MCE->getValue();
218 return isShiftedUInt<23, 2>(
static_cast<int32_t
>(Value));
221 bool isBrTarget() {
return isBrImm() || isToken(); }
223 bool isCallTarget() {
return isImm() || isToken(); }
230 if (
const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value)) {
231 int64_t Value = ConstExpr->getValue();
232 return Value != 0 && isShiftedUInt<16, 16>(Value);
236 if (
const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(Imm.Value))
240 if (
const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Imm.Value))
241 if (
const LanaiMCExpr *SymbolRefExpr =
242 dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS()))
248 bool isHiImm16And() {
252 const MCConstantExpr *ConstExpr =
dyn_cast<MCConstantExpr>(Imm.Value);
254 int64_t Value = ConstExpr->getValue();
256 return (Value != 0) && ((Value & ~0xffff0000) == 0xffff);
266 if (
const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value)) {
267 int64_t Value = ConstExpr->getValue();
269 return isUInt<16>(
static_cast<int32_t
>(Value));
273 if (
const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(Imm.Value))
277 if (
const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Imm.Value))
278 if (
const LanaiMCExpr *SymbolRefExpr =
279 dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS()))
285 bool isLoImm16Signed() {
290 if (
const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value)) {
291 int64_t Value = ConstExpr->getValue();
293 return isInt<16>(
static_cast<int32_t
>(Value));
297 if (
const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(Imm.Value))
301 if (
const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Imm.Value))
302 if (
const LanaiMCExpr *SymbolRefExpr =
303 dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS()))
309 bool isLoImm16And() {
313 const MCConstantExpr *ConstExpr =
dyn_cast<MCConstantExpr>(Imm.Value);
315 int64_t Value = ConstExpr->getValue();
317 return ((Value & ~0xffff) == 0xffff0000);
326 const MCConstantExpr *ConstExpr =
dyn_cast<MCConstantExpr>(Imm.Value);
329 int64_t Value = ConstExpr->getValue();
330 return (Value >= -31) && (Value <= 31);
338 if (
const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value)) {
339 int64_t Value = ConstExpr->getValue();
340 return isUInt<21>(Value);
344 if (
const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(Imm.Value))
346 if (
const MCSymbolRefExpr *SymbolRefExpr =
347 dyn_cast<MCSymbolRefExpr>(Imm.Value)) {
352 if (
const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Imm.Value)) {
353 if (
const LanaiMCExpr *SymbolRefExpr =
354 dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS()))
356 if (
const MCSymbolRefExpr *SymbolRefExpr =
357 dyn_cast<MCSymbolRefExpr>(BinaryExpr->getLHS()))
368 const MCConstantExpr *ConstExpr =
dyn_cast<MCConstantExpr>(Imm.Value);
371 int64_t Value = ConstExpr->getValue();
372 return isInt<10>(Value);
379 const MCConstantExpr *ConstExpr =
dyn_cast<MCConstantExpr>(Imm.Value);
382 uint64_t Value = ConstExpr->getValue();
389 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const {
393 else if (
const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Expr))
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!");
407 addExpr(Inst, getImm());
410 void addBrTargetOperands(MCInst &Inst,
unsigned N)
const {
411 assert(N == 1 &&
"Invalid number of operands!");
412 addExpr(Inst, getImm());
415 void addCallTargetOperands(MCInst &Inst,
unsigned N)
const {
416 assert(N == 1 &&
"Invalid number of operands!");
417 addExpr(Inst, getImm());
420 void addCondCodeOperands(MCInst &Inst,
unsigned N)
const {
421 assert(N == 1 &&
"Invalid number of operands!");
422 addExpr(Inst, getImm());
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() != 0 &&
"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!");
456 addExpr(Inst, getImm());
459 void addImm10Operands(MCInst &Inst,
unsigned N)
const {
460 assert(N == 1 &&
"Invalid number of operands!");
461 addExpr(Inst, getImm());
464 void addLoImm16Operands(MCInst &Inst,
unsigned N)
const {
465 assert(N == 1 &&
"Invalid number of operands!");
466 if (
const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
469 else if (isa<LanaiMCExpr>(getImm())) {
471 const LanaiMCExpr *SymbolRefExpr =
dyn_cast<LanaiMCExpr>(getImm());
475 }
else if (isa<MCBinaryExpr>(getImm())) {
477 const MCBinaryExpr *BinaryExpr =
dyn_cast<MCBinaryExpr>(getImm());
478 assert(dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS()) &&
479 dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS())->getKind() ==
484 assert(
false &&
"Operand type not supported.");
487 void addLoImm16AndOperands(MCInst &Inst,
unsigned N)
const {
488 assert(N == 1 &&
"Invalid number of operands!");
489 if (
const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
492 assert(
false &&
"Operand type not supported.");
495 void addHiImm16Operands(MCInst &Inst,
unsigned N)
const {
496 assert(N == 1 &&
"Invalid number of operands!");
497 if (
const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
499 else if (isa<LanaiMCExpr>(getImm())) {
501 const LanaiMCExpr *SymbolRefExpr =
dyn_cast<LanaiMCExpr>(getImm());
505 }
else if (isa<MCBinaryExpr>(getImm())) {
507 const MCBinaryExpr *BinaryExpr =
dyn_cast<MCBinaryExpr>(getImm());
508 assert(dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS()) &&
509 dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS())->getKind() ==
514 assert(
false &&
"Operand type not supported.");
517 void addHiImm16AndOperands(MCInst &Inst,
unsigned N)
const {
518 assert(N == 1 &&
"Invalid number of operands!");
519 if (
const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
522 assert(
false &&
"Operand type not supported.");
525 void addLoImm21Operands(MCInst &Inst,
unsigned N)
const {
526 assert(N == 1 &&
"Invalid number of operands!");
527 if (
const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
529 else if (isa<LanaiMCExpr>(getImm())) {
531 const LanaiMCExpr *SymbolRefExpr =
dyn_cast<LanaiMCExpr>(getImm());
536 }
else if (isa<MCSymbolRefExpr>(getImm())) {
538 const MCSymbolRefExpr *SymbolRefExpr =
539 dyn_cast<MCSymbolRefExpr>(getImm());
544 }
else if (isa<MCBinaryExpr>(getImm())) {
546 const MCBinaryExpr *BinaryExpr =
dyn_cast<MCBinaryExpr>(getImm());
547 const LanaiMCExpr *SymbolRefExpr =
548 dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS());
554 assert(
false &&
"Operand type not supported.");
557 void print(raw_ostream &OS)
const override {
560 OS <<
"Imm: " << getImm() <<
"\n";
563 OS <<
"Token: " <<
getToken() <<
"\n";
566 OS <<
"Reg: %r" <<
getReg() <<
"\n";
569 OS <<
"MemImm: " << *getMemOffset() <<
"\n";
572 OS <<
"MemRegImm: " << getMemBaseReg() <<
"+" << *getMemOffset() <<
"\n";
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 = make_unique<LanaiOperand>(TOKEN);
584 Op->Tok.Data = Str.data();
585 Op->Tok.Length = Str.size();
586 Op->StartLoc = Start;
591 static std::unique_ptr<LanaiOperand> createReg(
unsigned RegNum, SMLoc Start,
593 auto Op = make_unique<LanaiOperand>(REGISTER);
594 Op->Reg.RegNum = RegNum;
595 Op->StartLoc = Start;
600 static std::unique_ptr<LanaiOperand> createImm(
const MCExpr *Value,
601 SMLoc Start, SMLoc
End) {
602 auto Op = make_unique<LanaiOperand>(IMMEDIATE);
603 Op->Imm.Value = Value;
604 Op->StartLoc = Start;
609 static std::unique_ptr<LanaiOperand>
610 MorphToMemImm(std::unique_ptr<LanaiOperand>
Op) {
611 const MCExpr *Imm = Op->getImm();
612 Op->Kind = MEMORY_IMM;
615 Op->Mem.OffsetReg = 0;
616 Op->Mem.Offset = Imm;
620 static std::unique_ptr<LanaiOperand>
621 MorphToMemRegReg(
unsigned BaseReg, std::unique_ptr<LanaiOperand> Op,
623 unsigned OffsetReg = Op->getReg();
624 Op->Kind = MEMORY_REG_REG;
625 Op->Mem.BaseReg = BaseReg;
626 Op->Mem.AluOp = AluOp;
627 Op->Mem.OffsetReg = OffsetReg;
628 Op->Mem.Offset =
nullptr;
632 static std::unique_ptr<LanaiOperand>
633 MorphToMemRegImm(
unsigned BaseReg, std::unique_ptr<LanaiOperand> Op,
635 const MCExpr *Imm = Op->getImm();
636 Op->Kind = MEMORY_REG_IMM;
637 Op->Mem.BaseReg = BaseReg;
638 Op->Mem.AluOp = AluOp;
639 Op->Mem.OffsetReg = 0;
640 Op->Mem.Offset = Imm;
647 bool LanaiAsmParser::ParseDirective(AsmToken ) {
return true; }
649 bool LanaiAsmParser::MatchAndEmitInstruction(SMLoc IdLoc,
unsigned &Opcode,
653 bool MatchingInlineAsm) {
657 switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) {
659 Out.EmitInstruction(Inst, SubtargetInfo);
660 Opcode = Inst.getOpcode();
662 case Match_MissingFeature:
663 return Error(IdLoc,
"Instruction use requires option to be enabled");
664 case Match_MnemonicFail:
665 return Error(IdLoc,
"Unrecognized instruction mnemonic");
666 case Match_InvalidOperand: {
668 if (ErrorInfo != ~0U) {
669 if (ErrorInfo >= Operands.size())
670 return Error(IdLoc,
"Too few operands for instruction");
672 ErrorLoc = ((LanaiOperand &)*Operands[ErrorInfo]).getStartLoc();
673 if (ErrorLoc == SMLoc())
676 return Error(ErrorLoc,
"Invalid operand for instruction");
689 std::unique_ptr<LanaiOperand> LanaiAsmParser::parseRegister() {
690 SMLoc Start = Parser.getTok().getLoc();
702 return LanaiOperand::createReg(RegNum, Start, End);
707 bool LanaiAsmParser::ParseRegister(
unsigned &RegNum, SMLoc &StartLoc,
709 const AsmToken &Tok = getParser().getTok();
710 StartLoc = Tok.getLoc();
711 EndLoc = Tok.getEndLoc();
712 std::unique_ptr<LanaiOperand> Op = parseRegister();
714 RegNum = Op->getReg();
715 return (Op ==
nullptr);
718 std::unique_ptr<LanaiOperand> LanaiAsmParser::parseIdentifier() {
719 SMLoc Start = Parser.getTok().getLoc();
721 const MCExpr *Res, *RHS =
nullptr;
727 StringRef Identifier;
728 if (Parser.parseIdentifier(Identifier))
732 if (Identifier.equals_lower(
"hi"))
734 else if (Identifier.equals_lower(
"lo"))
741 Error(Lexer.getLoc(),
"Expected '('");
747 if (Parser.parseIdentifier(Identifier))
752 if (Lexer.getKind() ==
AsmToken::Plus && Parser.parseExpression(RHS))
758 Error(Lexer.getLoc(),
"Expected ')'");
765 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
773 return LanaiOperand::createImm(Res, Start, End);
776 std::unique_ptr<LanaiOperand> LanaiAsmParser::parseImmediate() {
777 SMLoc Start = Parser.getTok().getLoc();
780 const MCExpr *ExprVal;
781 switch (Lexer.getKind()) {
783 return parseIdentifier();
788 if (!Parser.parseExpression(ExprVal))
789 return LanaiOperand::createImm(ExprVal, Start, End);
803 unsigned LanaiAsmParser::parseAluOperator(
bool PreOp,
bool PostOp) {
805 Parser.parseIdentifier(IdString);
808 Error(Parser.getTok().getLoc(),
"Can't parse ALU operator");
818 bool LanaiAsmParser::parsePrePost(StringRef
Type,
int *OffsetValue) {
819 bool PreOrPost =
false;
820 if (Lexer.getKind() == Lexer.peekTok(
true).getKind()) {
843 if (
const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Op.getImm())) {
844 int64_t Value = ConstExpr->getValue();
845 return (Value % 4 == 0) && (Value >= 0) && (Value <= 0x1fffff);
849 if (
const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(Op.getImm()))
854 if (
const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Op.getImm())) {
857 return (LHSSymbolRefExpr &&
865 LanaiAsmParser::parseMemoryOperand(
OperandVector &Operands) {
878 if (Operands[0]->isToken())
879 Type =
static_cast<LanaiOperand *
>(Operands[0].get())->
getToken();
883 unsigned BaseReg = 0;
885 bool PostOp =
false, PreOp =
false;
888 std::unique_ptr<LanaiOperand> Op = parseRegister();
890 Op = parseImmediate();
900 Operands.push_back(std::move(Op));
905 std::unique_ptr<LanaiOperand>
Offset =
nullptr;
910 PreOp = parsePrePost(Type, &OffsetValue);
912 Op = parseRegister();
921 Operands.push_back(LanaiOperand::MorphToMemImm(std::move(Op)));
923 if (!Op->isLoImm16Signed()) {
924 Error(Parser.getTok().getLoc(),
925 "Memory address is not word "
926 "aligned and larger than class RM can handle");
929 Operands.push_back(LanaiOperand::MorphToMemRegImm(
936 Error(Parser.getTok().getLoc(),
937 "Unknown operand, expected register or immediate");
940 BaseReg = Op->getReg();
944 PostOp = parsePrePost(Type, &OffsetValue);
950 SMLoc Start = Parser.getTok().getLoc();
953 const MCConstantExpr *OffsetConstExpr =
955 Offset = LanaiOperand::createImm(OffsetConstExpr, Start, End);
958 if (Offset || OffsetValue != 0) {
959 Error(Parser.getTok().getLoc(),
"Expected ']'");
964 AluOp = parseAluOperator(PreOp, PostOp);
967 Offset = parseRegister();
969 Error(Parser.getTok().getLoc(),
"Expected ']'");
980 if (Offset->isImm() && !Offset->isLoImm16Signed()) {
981 Error(Parser.getTok().getLoc(),
982 "Memory address is not word "
983 "aligned and larger than class RM can handle");
989 ? LanaiOperand::MorphToMemRegImm(BaseReg, std::move(Offset), AluOp)
990 : LanaiOperand::MorphToMemRegReg(BaseReg, std::move(Offset), AluOp));
999 LanaiAsmParser::parseOperand(
OperandVector *Operands, StringRef Mnemonic) {
1007 Parser.eatToEndOfStatement();
1012 std::unique_ptr<LanaiOperand> Op = parseRegister();
1016 Op = parseImmediate();
1020 Error(Parser.getTok().getLoc(),
"Unknown operand");
1021 Parser.eatToEndOfStatement();
1026 Operands->push_back(std::move(Op));
1033 StringRef LanaiAsmParser::splitMnemonic(StringRef
Name, SMLoc NameLoc,
1035 size_t Next = Name.find(
'.');
1037 StringRef Mnemonic =
Name;
1040 if (Name.endswith(
".r")) {
1041 Mnemonic = Name.substr(0, Name.size() - 2);
1046 if (Mnemonic[0] ==
'b' ||
1047 (Mnemonic[0] ==
's' && !Mnemonic.startswith(
"sel") &&
1048 !Mnemonic.startswith(
"st"))) {
1054 Mnemonic = Mnemonic.slice(0, 1);
1055 Operands->push_back(LanaiOperand::CreateToken(Mnemonic, NameLoc));
1056 Operands->push_back(LanaiOperand::createImm(
1059 Operands->push_back(LanaiOperand::CreateToken(
".r", NameLoc));
1069 if (Mnemonic.startswith(
"sel") ||
1070 (!Mnemonic.endswith(
".f") && !Mnemonic.startswith(
"st"))) {
1073 size_t Next = Mnemonic.rfind(
'.', Name.size());
1079 if (Mnemonic.startswith(
"sel")) {
1080 Mnemonic = Mnemonic.substr(0, Next + 1);
1082 Mnemonic = Mnemonic.substr(0, Next);
1084 Operands->push_back(LanaiOperand::CreateToken(Mnemonic, NameLoc));
1085 Operands->push_back(LanaiOperand::createImm(
1091 Operands->push_back(LanaiOperand::CreateToken(Mnemonic, NameLoc));
1093 Operands->push_back(LanaiOperand::CreateToken(
".r", NameLoc));
1105 bool Modifies =
false;
1109 if (Operands.
size() < 5)
1111 else if (Operands[0]->isToken() && Operands[1]->isReg() &&
1112 Operands[2]->isImm() && Operands[3]->isImm() && Operands[4]->isReg())
1114 else if (Operands[0]->isToken() && Operands[1]->isToken() &&
1115 Operands[2]->isReg() && Operands[3]->isImm() &&
1116 Operands[4]->isImm() && Operands[5]->isReg())
1121 int PossibleAluOpIdx = Offset + 3;
1122 int PossibleBaseIdx = Offset + 1;
1123 int PossibleDestIdx = Offset + 4;
1124 if (LanaiOperand *PossibleAluOp =
1125 static_cast<LanaiOperand *>(Operands[PossibleAluOpIdx].
get()))
1126 if (PossibleAluOp->isImm())
1128 dyn_cast<MCConstantExpr>(PossibleAluOp->getImm()))
1130 return Modifies && Operands[PossibleBaseIdx]->isReg() &&
1131 Operands[PossibleDestIdx]->isReg() &&
1132 Operands[PossibleBaseIdx]->getReg() ==
1133 Operands[PossibleDestIdx]->getReg();
1137 return static_cast<const LanaiOperand &
>(
op).
isReg();
1145 static_cast<const LanaiOperand &
>(*Operands[0]).
getToken())
1146 .StartsWith(
"addc",
true)
1157 bool LanaiAsmParser::ParseInstruction(ParseInstructionInfo & ,
1158 StringRef Name, SMLoc NameLoc,
1161 StringRef Mnemonic = splitMnemonic(Name, NameLoc, &Operands);
1174 Operands.size() == 2) {
1175 Operands.erase(Operands.begin(), Operands.begin() + 1);
1176 Operands.insert(Operands.begin(), LanaiOperand::CreateToken(
"s", NameLoc));
1177 Operands.insert(Operands.begin() + 1,
1178 LanaiOperand::createImm(
1187 Operands.size() == 3) {
1188 Operands.erase(Operands.begin(), Operands.begin() + 2);
1189 Operands.insert(Operands.begin(), LanaiOperand::CreateToken(
"bt", NameLoc));
1203 Error(Parser.getTok().getLoc(),
1204 "the destination register can't equal the base register in an "
1205 "instruction that modifies the base register.");
1212 Operands.insert(Operands.begin() + 1,
1213 LanaiOperand::createImm(
1221 #define GET_REGISTER_MATCHER
1222 #define GET_MATCHER_IMPLEMENTATION
1223 #include "LanaiGenAsmMatcher.inc"
static bool isReg(const MCInst &MI, unsigned OpNo)
static CondCode suffixToLanaiCondCode(StringRef S)
static unsigned AluWithPrePost(unsigned AluCode, bool PreOp, bool PostOp)
static int SizeForSuffix(StringRef T)
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Target & getTheLanaiTarget()
static bool modifiesOp(unsigned AluOp)
static MCOperand createExpr(const MCExpr *Val)
constexpr bool isInt< 16 >(int64_t x)
static const LanaiMCExpr * create(VariantKind Kind, const MCExpr *Expr, MCContext &Ctx)
static unsigned makePostOp(unsigned AluOp)
static MCOperand createReg(unsigned Reg)
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 ...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
LLVM_ATTRIBUTE_ALWAYS_INLINE R Default(const T &Value) const
Reg
All possible values of the reg field in the ModR/M byte.
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & EndsWith(const char(&S)[N], const T &Value)
static bool isMem(const MachineInstr &MI, unsigned Op)
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand...
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out...
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
VariantKind getKind() const
A switch()-like statement whose cases are string literals.
static bool MaybePredicatedInst(const OperandVector &Operands)
static const unsigned End
Binary assembler expressions.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
static unsigned makePreOp(unsigned AluOp)
bool shouldBeSls(const LanaiOperand &Op)
void LLVMInitializeLanaiAsmParser()
static SMLoc getFromPointer(const char *Ptr)
static AluCode stringToLanaiAluCode(StringRef S)
RegisterMCAsmParser - Helper template for registering a target specific assembly parser, for use in the target machine initialization function.
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
static bool IsRegister(const MCParsedAsmOperand &op)
constexpr bool isUInt< 16 >(uint64_t x)
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool IsMemoryAssignmentError(const OperandVector &Operands)
static unsigned MatchRegisterName(StringRef Name)
Maps from the set of all register names to a register number.
StringRef - Represent a constant reference to a string, i.e.
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & StartsWith(const char(&S)[N], const T &Value)
static MCOperand createImm(int64_t Val)
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx)