37 #define DEBUG_TYPE "mips-asm-parser"
44 class MipsAssemblerOptions {
49 MipsAssemblerOptions(
const MipsAssemblerOptions *Opts) {
50 ATReg = Opts->getATRegIndex();
51 Reorder = Opts->isReorder();
52 Macro = Opts->isMacro();
56 unsigned getATRegIndex()
const {
return ATReg; }
57 bool setATRegIndex(
unsigned Reg) {
65 bool isReorder()
const {
return Reorder; }
66 void setReorder() { Reorder =
true; }
67 void setNoReorder() { Reorder =
false; }
69 bool isMacro()
const {
return Macro; }
70 void setMacro() { Macro =
true; }
71 void setNoMacro() { Macro =
false; }
91 const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
92 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
93 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
94 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
95 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
96 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
97 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
98 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
99 Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008
119 void printWarningWithFixIt(
const Twine &Msg,
const Twine &FixMsg,
120 SMRange Range,
bool ShowColors =
true);
122 #define GET_ASSEMBLER_HEADER
123 #include "MipsGenAsmMatcher.inc"
125 unsigned checkTargetMatchPredicate(
MCInst &Inst)
override;
127 bool MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
130 bool MatchingInlineAsm)
override;
133 bool ParseRegister(
unsigned &RegNo,
SMLoc &StartLoc,
SMLoc &EndLoc)
override;
142 bool ParseDirective(
AsmToken DirectiveID)
override;
146 MipsAsmParser::OperandMatchResultTy
150 MipsAsmParser::OperandMatchResultTy
163 MipsAsmParser::OperandMatchResultTy
166 MipsAsmParser::OperandMatchResultTy
169 MipsAsmParser::OperandMatchResultTy
176 bool needsExpansion(
MCInst &Inst);
186 bool loadImmediate(int64_t ImmValue,
unsigned DstReg,
unsigned SrcReg,
187 bool Is32BitImm,
SMLoc IDLoc,
190 bool loadAndAddSymbolAddress(
const MCExpr *SymExpr,
unsigned DstReg,
191 unsigned SrcReg,
bool Is32BitSym,
SMLoc IDLoc,
194 bool expandLoadImm(
MCInst &Inst,
bool Is32BitImm,
SMLoc IDLoc,
197 bool expandLoadAddressImm(
MCInst &Inst,
bool Is32BitImm,
SMLoc IDLoc,
200 bool expandLoadAddressReg(
MCInst &Inst,
bool Is32BitImm,
SMLoc IDLoc,
202 bool expandUncondBranchMMPseudo(
MCInst &Inst,
SMLoc IDLoc,
209 bool expandLoadStoreMultiple(
MCInst &Inst,
SMLoc IDLoc,
227 void createAddu(
unsigned DstReg,
unsigned SrcReg,
unsigned TrgReg,
230 bool reportParseError(
Twine ErrorMsg);
231 bool reportParseError(
SMLoc Loc,
Twine ErrorMsg);
233 bool parseMemOffset(
const MCExpr *&Res,
bool isParenExpr);
234 bool parseRelocOperand(
const MCExpr *&Res);
238 bool isEvaluated(
const MCExpr *Expr);
239 bool parseSetMips0Directive();
240 bool parseSetArchDirective();
241 bool parseSetFeature(uint64_t Feature);
242 bool parseDirectiveCpLoad(
SMLoc Loc);
243 bool parseDirectiveCPSetup();
244 bool parseDirectiveNaN();
245 bool parseDirectiveSet();
246 bool parseDirectiveOption();
247 bool parseInsnDirective();
249 bool parseSetAtDirective();
250 bool parseSetNoAtDirective();
251 bool parseSetMacroDirective();
252 bool parseSetNoMacroDirective();
253 bool parseSetMsaDirective();
254 bool parseSetNoMsaDirective();
255 bool parseSetNoDspDirective();
256 bool parseSetReorderDirective();
257 bool parseSetNoReorderDirective();
258 bool parseSetMips16Directive();
259 bool parseSetNoMips16Directive();
260 bool parseSetFpDirective();
261 bool parseSetOddSPRegDirective();
262 bool parseSetNoOddSPRegDirective();
263 bool parseSetPopDirective();
264 bool parseSetPushDirective();
265 bool parseSetSoftFloatDirective();
266 bool parseSetHardFloatDirective();
268 bool parseSetAssignment();
270 bool parseDataDirective(
unsigned Size,
SMLoc L);
271 bool parseDirectiveGpWord();
272 bool parseDirectiveGpDWord();
273 bool parseDirectiveModule();
274 bool parseDirectiveModuleFP();
278 bool parseInternalDirectiveReallowModule();
288 int matchRegisterByNumber(
unsigned RegNum,
unsigned RegClass);
300 unsigned getReg(
int RC,
int RegNo);
302 unsigned getGPR(
int RegNo);
307 unsigned getATReg(
SMLoc Loc);
315 bool validateMSAIndex(
int Val,
int RegKind);
341 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
342 STI.setFeatureBits(FeatureBits);
343 setAvailableFeatures(
344 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
345 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
348 void setFeatureBits(uint64_t Feature,
StringRef FeatureString) {
349 if (!(STI.getFeatureBits()[Feature])) {
350 setAvailableFeatures(
351 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
352 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
356 void clearFeatureBits(uint64_t Feature,
StringRef FeatureString) {
357 if (STI.getFeatureBits()[Feature]) {
358 setAvailableFeatures(
359 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
360 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
364 void setModuleFeatureBits(uint64_t Feature,
StringRef FeatureString) {
365 setFeatureBits(Feature, FeatureString);
366 AssemblerOptions.front()->setFeatures(STI.getFeatureBits());
369 void clearModuleFeatureBits(uint64_t Feature,
StringRef FeatureString) {
370 clearFeatureBits(Feature, FeatureString);
371 AssemblerOptions.front()->setFeatures(STI.getFeatureBits());
375 enum MipsMatchResultTy {
376 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
377 #define GET_OPERAND_DIAGNOSTIC_TYPES
378 #include "MipsGenAsmMatcher.inc"
379 #undef GET_OPERAND_DIAGNOSTIC_TYPES
387 sti.getCPU(), Options)) {
393 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
396 AssemblerOptions.push_back(
397 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
400 AssemblerOptions.push_back(
401 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
403 getTargetStreamer().updateABIInfo(*
this);
405 if (!isABI_O32() && !useOddSPReg() != 0)
413 IsLittleEndian =
false;
415 IsLittleEndian =
true;
419 bool hasEightFccRegisters()
const {
return hasMips4() || hasMips32(); }
421 bool isGP64bit()
const {
return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
422 bool isFP64bit()
const {
return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }
424 bool isABI_N32()
const {
return ABI.
IsN32(); }
425 bool isABI_N64()
const {
return ABI.IsN64(); }
426 bool isABI_O32()
const {
return ABI.IsO32(); }
427 bool isABI_FPXX()
const {
return STI.getFeatureBits()[Mips::FeatureFPXX]; }
429 bool useOddSPReg()
const {
430 return !(STI.getFeatureBits()[Mips::FeatureNoOddSPReg]);
433 bool inMicroMipsMode()
const {
434 return STI.getFeatureBits()[Mips::FeatureMicroMips];
436 bool hasMips1()
const {
return STI.getFeatureBits()[Mips::FeatureMips1]; }
437 bool hasMips2()
const {
return STI.getFeatureBits()[Mips::FeatureMips2]; }
438 bool hasMips3()
const {
return STI.getFeatureBits()[Mips::FeatureMips3]; }
439 bool hasMips4()
const {
return STI.getFeatureBits()[Mips::FeatureMips4]; }
440 bool hasMips5()
const {
return STI.getFeatureBits()[Mips::FeatureMips5]; }
441 bool hasMips32()
const {
442 return STI.getFeatureBits()[Mips::FeatureMips32];
444 bool hasMips64()
const {
445 return STI.getFeatureBits()[Mips::FeatureMips64];
447 bool hasMips32r2()
const {
448 return STI.getFeatureBits()[Mips::FeatureMips32r2];
450 bool hasMips64r2()
const {
451 return STI.getFeatureBits()[Mips::FeatureMips64r2];
453 bool hasMips32r3()
const {
454 return (STI.getFeatureBits()[Mips::FeatureMips32r3]);
456 bool hasMips64r3()
const {
457 return (STI.getFeatureBits()[Mips::FeatureMips64r3]);
459 bool hasMips32r5()
const {
460 return (STI.getFeatureBits()[Mips::FeatureMips32r5]);
462 bool hasMips64r5()
const {
463 return (STI.getFeatureBits()[Mips::FeatureMips64r5]);
465 bool hasMips32r6()
const {
466 return STI.getFeatureBits()[Mips::FeatureMips32r6];
468 bool hasMips64r6()
const {
469 return STI.getFeatureBits()[Mips::FeatureMips64r6];
472 bool hasDSP()
const {
return STI.getFeatureBits()[Mips::FeatureDSP]; }
473 bool hasDSPR2()
const {
return STI.getFeatureBits()[Mips::FeatureDSPR2]; }
474 bool hasMSA()
const {
return STI.getFeatureBits()[Mips::FeatureMSA]; }
475 bool hasCnMips()
const {
476 return (STI.getFeatureBits()[Mips::FeatureCnMips]);
479 bool inMips16Mode()
const {
480 return STI.getFeatureBits()[Mips::FeatureMips16];
483 bool useSoftFloat()
const {
484 return STI.getFeatureBits()[Mips::FeatureSoftFloat];
488 void warnIfRegIndexIsAT(
unsigned RegIndex,
SMLoc Loc);
490 void warnIfNoMacro(
SMLoc Loc);
492 bool isLittle()
const {
return IsLittleEndian; }
510 RegKind_MSACtrl = 16,
515 RegKind_HWRegs = 256,
519 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
520 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
521 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
536 MipsOperand(KindTy K, MipsAsmParser &Parser)
541 MipsAsmParser &AsmParser;
573 struct PhysRegOp PhysReg;
574 struct RegIdxOp RegIdx;
577 struct RegListOp RegList;
580 SMLoc StartLoc, EndLoc;
583 static std::unique_ptr<MipsOperand> CreateReg(
unsigned Index, RegKind RegKind,
586 MipsAsmParser &Parser) {
587 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
588 Op->RegIdx.Index = Index;
589 Op->RegIdx.RegInfo = RegInfo;
590 Op->RegIdx.Kind = RegKind;
599 unsigned getGPR32Reg()
const {
600 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
601 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
602 unsigned ClassID = Mips::GPR32RegClassID;
603 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
608 unsigned getGPRMM16Reg()
const {
609 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
610 unsigned ClassID = Mips::GPR32RegClassID;
611 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
616 unsigned getGPR64Reg()
const {
617 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
618 unsigned ClassID = Mips::GPR64RegClassID;
619 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
625 unsigned getAFGR64Reg()
const {
626 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
627 if (RegIdx.Index % 2 != 0)
628 AsmParser.Warning(StartLoc,
"Float register should be even.");
629 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
630 .getRegister(RegIdx.Index / 2);
635 unsigned getFGR64Reg()
const {
636 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
637 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
638 .getRegister(RegIdx.Index);
643 unsigned getFGR32Reg()
const {
644 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
645 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
646 .getRegister(RegIdx.Index);
651 unsigned getFGRH32Reg()
const {
652 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
653 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
654 .getRegister(RegIdx.Index);
659 unsigned getFCCReg()
const {
660 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) &&
"Invalid access!");
661 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
662 .getRegister(RegIdx.Index);
667 unsigned getMSA128Reg()
const {
668 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) &&
"Invalid access!");
671 unsigned ClassID = Mips::MSA128BRegClassID;
672 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
677 unsigned getMSACtrlReg()
const {
678 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) &&
"Invalid access!");
679 unsigned ClassID = Mips::MSACtrlRegClassID;
680 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
685 unsigned getCOP0Reg()
const {
686 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) &&
"Invalid access!");
687 unsigned ClassID = Mips::COP0RegClassID;
688 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
693 unsigned getCOP2Reg()
const {
694 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) &&
"Invalid access!");
695 unsigned ClassID = Mips::COP2RegClassID;
696 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
701 unsigned getCOP3Reg()
const {
702 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) &&
"Invalid access!");
703 unsigned ClassID = Mips::COP3RegClassID;
704 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
709 unsigned getACC64DSPReg()
const {
710 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
711 unsigned ClassID = Mips::ACC64DSPRegClassID;
712 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
717 unsigned getHI32DSPReg()
const {
718 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
719 unsigned ClassID = Mips::HI32DSPRegClassID;
720 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
725 unsigned getLO32DSPReg()
const {
726 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
727 unsigned ClassID = Mips::LO32DSPRegClassID;
728 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
733 unsigned getCCRReg()
const {
734 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) &&
"Invalid access!");
735 unsigned ClassID = Mips::CCRRegClassID;
736 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
741 unsigned getHWRegsReg()
const {
742 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) &&
"Invalid access!");
743 unsigned ClassID = Mips::HWRegsRegClassID;
744 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
752 else if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
758 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
765 void addGPR32AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
766 assert(N == 1 &&
"Invalid number of operands!");
770 void addGPRMM16AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
771 assert(N == 1 &&
"Invalid number of operands!");
775 void addGPRMM16AsmRegZeroOperands(
MCInst &Inst,
unsigned N)
const {
776 assert(N == 1 &&
"Invalid number of operands!");
780 void addGPRMM16AsmRegMovePOperands(
MCInst &Inst,
unsigned N)
const {
781 assert(N == 1 &&
"Invalid number of operands!");
788 void addGPR64AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
789 assert(N == 1 &&
"Invalid number of operands!");
793 void addAFGR64AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
794 assert(N == 1 &&
"Invalid number of operands!");
798 void addFGR64AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
799 assert(N == 1 &&
"Invalid number of operands!");
803 void addFGR32AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
804 assert(N == 1 &&
"Invalid number of operands!");
807 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
808 AsmParser.Error(StartLoc,
"-mno-odd-spreg prohibits the use of odd FPU "
812 void addFGRH32AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
813 assert(N == 1 &&
"Invalid number of operands!");
817 void addFCCAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
818 assert(N == 1 &&
"Invalid number of operands!");
822 void addMSA128AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
823 assert(N == 1 &&
"Invalid number of operands!");
827 void addMSACtrlAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
828 assert(N == 1 &&
"Invalid number of operands!");
832 void addCOP0AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
833 assert(N == 1 &&
"Invalid number of operands!");
837 void addCOP2AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
838 assert(N == 1 &&
"Invalid number of operands!");
842 void addCOP3AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
843 assert(N == 1 &&
"Invalid number of operands!");
847 void addACC64DSPAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
848 assert(N == 1 &&
"Invalid number of operands!");
852 void addHI32DSPAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
853 assert(N == 1 &&
"Invalid number of operands!");
857 void addLO32DSPAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
858 assert(N == 1 &&
"Invalid number of operands!");
862 void addCCRAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
863 assert(N == 1 &&
"Invalid number of operands!");
867 void addHWRegsAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
868 assert(N == 1 &&
"Invalid number of operands!");
872 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
873 assert(N == 1 &&
"Invalid number of operands!");
874 const MCExpr *Expr = getImm();
878 void addMemOperands(
MCInst &Inst,
unsigned N)
const {
879 assert(N == 2 &&
"Invalid number of operands!");
883 const MCExpr *Expr = getMemOff();
887 void addMicroMipsMemOperands(
MCInst &Inst,
unsigned N)
const {
888 assert(N == 2 &&
"Invalid number of operands!");
892 const MCExpr *Expr = getMemOff();
896 void addRegListOperands(
MCInst &Inst,
unsigned N)
const {
897 assert(N == 1 &&
"Invalid number of operands!");
899 for (
auto RegNo : getRegList())
903 void addRegPairOperands(
MCInst &Inst,
unsigned N)
const {
904 assert(N == 2 &&
"Invalid number of operands!");
905 unsigned RegNo = getRegPair();
910 void addMovePRegPairOperands(
MCInst &Inst,
unsigned N)
const {
911 assert(N == 2 &&
"Invalid number of operands!");
912 for (
auto RegNo : getRegList())
916 bool isReg()
const override {
919 if (isGPRAsmReg() && RegIdx.Index == 0)
922 return Kind == k_PhysRegister;
924 bool isRegIdx()
const {
return Kind == k_RegisterIndex; }
925 bool isImm()
const override {
return Kind == k_Immediate; }
926 bool isConstantImm()
const {
929 template <
unsigned Bits>
bool isUImm()
const {
930 return isImm() && isConstantImm() && isUInt<Bits>(getConstantImm());
932 bool isToken()
const override {
935 return Kind == k_Token;
937 bool isMem()
const override {
return Kind == k_Memory; }
938 bool isConstantMemOff()
const {
941 template <
unsigned Bits>
bool isMemWithSimmOffset()
const {
942 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
944 bool isMemWithGRPMM16Base()
const {
945 return isMem() && getMemBase()->isMM16AsmReg();
947 template <
unsigned Bits>
bool isMemWithUimmOffsetSP()
const {
948 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
949 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
951 template <
unsigned Bits>
bool isMemWithUimmWordAlignedOffsetSP()
const {
952 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
953 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
954 && (getMemBase()->getGPR32Reg() == Mips::SP);
956 bool isRegList16()
const {
960 int Size = RegList.List->size();
961 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
962 RegList.List->back() != Mips::RA)
965 int PrevReg = *RegList.List->begin();
966 for (
int i = 1; i < Size - 1; i++) {
967 int Reg = (*(RegList.List))[i];
968 if ( Reg != PrevReg + 1)
975 bool isInvNum()
const {
return Kind == k_Immediate; }
976 bool isLSAImm()
const {
977 if (!isConstantImm())
979 int64_t Val = getConstantImm();
980 return 1 <= Val && Val <= 4;
982 bool isRegList()
const {
return Kind == k_RegList; }
983 bool isMovePRegPair()
const {
984 if (
Kind != k_RegList || RegList.List->size() != 2)
987 unsigned R0 = RegList.List->front();
988 unsigned R1 = RegList.List->back();
990 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
991 (R0 == Mips::A1 && R1 == Mips::A3) ||
992 (R0 == Mips::A2 && R1 == Mips::A3) ||
993 (R0 == Mips::A0 && R1 == Mips::S5) ||
994 (R0 == Mips::A0 && R1 == Mips::S6) ||
995 (R0 == Mips::A0 && R1 == Mips::A1) ||
996 (R0 == Mips::A0 && R1 == Mips::A2) ||
997 (R0 == Mips::A0 && R1 == Mips::A3))
1004 assert(
Kind == k_Token &&
"Invalid access!");
1007 bool isRegPair()
const {
return Kind == k_RegPair; }
1009 unsigned getReg()
const override {
1012 if (
Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1013 RegIdx.Kind & RegKind_GPR)
1014 return getGPR32Reg();
1016 assert(
Kind == k_PhysRegister &&
"Invalid access!");
1020 const MCExpr *getImm()
const {
1021 assert((
Kind == k_Immediate) &&
"Invalid access!");
1025 int64_t getConstantImm()
const {
1026 const MCExpr *Val = getImm();
1030 MipsOperand *getMemBase()
const {
1031 assert((
Kind == k_Memory) &&
"Invalid access!");
1035 const MCExpr *getMemOff()
const {
1036 assert((
Kind == k_Memory) &&
"Invalid access!");
1040 int64_t getConstantMemOff()
const {
1041 return static_cast<const MCConstantExpr *
>(getMemOff())->getValue();
1045 assert((
Kind == k_RegList) &&
"Invalid access!");
1046 return *(RegList.List);
1049 unsigned getRegPair()
const {
1050 assert((
Kind == k_RegPair) &&
"Invalid access!");
1051 return RegIdx.Index;
1054 static std::unique_ptr<MipsOperand> CreateToken(
StringRef Str,
SMLoc S,
1055 MipsAsmParser &Parser) {
1056 auto Op = make_unique<MipsOperand>(k_Token, Parser);
1057 Op->Tok.Data = Str.
data();
1058 Op->Tok.Length = Str.
size();
1066 static std::unique_ptr<MipsOperand>
1068 SMLoc E, MipsAsmParser &Parser) {
1069 DEBUG(
dbgs() <<
"createNumericReg(" << Index <<
", ...)\n");
1070 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1075 static std::unique_ptr<MipsOperand>
1077 MipsAsmParser &Parser) {
1078 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1083 static std::unique_ptr<MipsOperand>
1085 MipsAsmParser &Parser) {
1086 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1091 static std::unique_ptr<MipsOperand>
1094 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1099 static std::unique_ptr<MipsOperand>
1101 MipsAsmParser &Parser) {
1102 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1107 static std::unique_ptr<MipsOperand>
1109 MipsAsmParser &Parser) {
1110 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1115 static std::unique_ptr<MipsOperand>
1117 SMLoc E, MipsAsmParser &Parser) {
1118 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1123 static std::unique_ptr<MipsOperand>
1125 SMLoc E, MipsAsmParser &Parser) {
1126 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1129 static std::unique_ptr<MipsOperand>
1131 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1138 static std::unique_ptr<MipsOperand>
1139 CreateMem(std::unique_ptr<MipsOperand> Base,
const MCExpr *Off,
SMLoc S,
1140 SMLoc E, MipsAsmParser &Parser) {
1141 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1142 Op->Mem.Base = Base.release();
1149 static std::unique_ptr<MipsOperand>
1151 MipsAsmParser &Parser) {
1152 assert (Regs.
size() > 0 &&
"Empty list not allowed");
1154 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1156 Op->StartLoc = StartLoc;
1157 Op->EndLoc = EndLoc;
1161 static std::unique_ptr<MipsOperand>
1162 CreateRegPair(
unsigned RegNo,
SMLoc S,
SMLoc E, MipsAsmParser &Parser) {
1163 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1164 Op->RegIdx.Index = RegNo;
1170 bool isGPRAsmReg()
const {
1171 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1173 bool isMM16AsmReg()
const {
1174 if (!(isRegIdx() && RegIdx.Kind))
1176 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1177 || RegIdx.Index == 16 || RegIdx.Index == 17);
1179 bool isMM16AsmRegZero()
const {
1180 if (!(isRegIdx() && RegIdx.Kind))
1182 return (RegIdx.Index == 0 ||
1183 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1184 RegIdx.Index == 17);
1186 bool isMM16AsmRegMoveP()
const {
1187 if (!(isRegIdx() && RegIdx.Kind))
1189 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1190 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1192 bool isFGRAsmReg()
const {
1194 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1196 bool isHWRegsAsmReg()
const {
1197 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1199 bool isCCRAsmReg()
const {
1200 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1202 bool isFCCAsmReg()
const {
1203 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1205 if (!AsmParser.hasEightFccRegisters())
1206 return RegIdx.Index == 0;
1207 return RegIdx.Index <= 7;
1209 bool isACCAsmReg()
const {
1210 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1212 bool isCOP0AsmReg()
const {
1213 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1215 bool isCOP2AsmReg()
const {
1216 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1218 bool isCOP3AsmReg()
const {
1219 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1221 bool isMSA128AsmReg()
const {
1222 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1224 bool isMSACtrlAsmReg()
const {
1225 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1229 SMLoc getStartLoc()
const override {
return StartLoc; }
1231 SMLoc getEndLoc()
const override {
return EndLoc; }
1233 virtual ~MipsOperand() {
1241 delete RegList.List;
1242 case k_PhysRegister:
1243 case k_RegisterIndex:
1259 Mem.Base->print(OS);
1264 case k_PhysRegister:
1265 OS <<
"PhysReg<" << PhysReg.Num <<
">";
1267 case k_RegisterIndex:
1268 OS <<
"RegIdx<" << RegIdx.Index <<
":" << RegIdx.Kind <<
">";
1275 for (
auto Reg : (*RegList.List))
1280 OS <<
"RegPair<" << RegIdx.Index <<
"," << RegIdx.Index + 1 <<
">";
1297 case Mips::JALRS_MM:
1298 case Mips::JALRS16_MM:
1299 case Mips::BGEZALS_MM:
1300 case Mips::BLTZALS_MM:
1314 const unsigned Opcode = Inst.
getOpcode();
1324 assert(hasCnMips() &&
"instruction only valid for octeon cpus");
1331 assert(MCID.
getNumOperands() == 3 &&
"unexpected number of operands");
1333 if (!Offset.isImm())
1335 if (!
isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1336 return Error(IDLoc,
"branch target out of range");
1338 1LL << (inMicroMipsMode() ? 1 : 2)))
1339 return Error(IDLoc,
"branch to misaligned address");
1353 case Mips::BGEZAL_MM:
1354 case Mips::BLTZAL_MM:
1357 assert(MCID.
getNumOperands() == 2 &&
"unexpected number of operands");
1359 if (!Offset.isImm())
1361 if (!
isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1362 return Error(IDLoc,
"branch target out of range");
1364 1LL << (inMicroMipsMode() ? 1 : 2)))
1365 return Error(IDLoc,
"branch to misaligned address");
1367 case Mips::BEQZ16_MM:
1368 case Mips::BNEZ16_MM:
1369 assert(MCID.
getNumOperands() == 2 &&
"unexpected number of operands");
1371 if (!Offset.isImm())
1373 if (!
isIntN(8, Offset.getImm()))
1374 return Error(IDLoc,
"branch target out of range");
1376 return Error(IDLoc,
"branch to misaligned address");
1383 if (hasMips32r6() && Inst.
getOpcode() == Mips::SSNOP) {
1384 std::string ISA = hasMips64r6() ?
"MIPS64r6" :
"MIPS32r6";
1385 Warning(IDLoc,
"ssnop is deprecated for " + ISA +
" and is equivalent to a "
1390 const unsigned Opcode = Inst.
getOpcode();
1402 assert(MCID.
getNumOperands() == 3 &&
"unexpected number of operands");
1406 return Error(IDLoc,
"expected immediate operand kind");
1407 Imm = Opnd.getImm();
1408 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1409 Opcode == Mips::BBIT1 ? 63 : 31))
1410 return Error(IDLoc,
"immediate operand value out of range");
1412 Inst.
setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1422 assert(MCID.
getNumOperands() == 4 &&
"unexpected number of operands");
1426 return Error(IDLoc,
"expected immediate operand kind");
1427 Imm = Opnd.getImm();
1428 if (Imm < 0 || Imm > 31)
1429 return Error(IDLoc,
"immediate operand value out of range");
1433 return Error(IDLoc,
"expected immediate operand kind");
1434 Imm = Opnd.getImm();
1435 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1436 Opcode == Mips::EXTS ? 63 : 31))
1437 return Error(IDLoc,
"immediate operand value out of range");
1439 Inst.
setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1446 assert(MCID.
getNumOperands() == 3 &&
"unexpected number of operands");
1449 return Error(IDLoc,
"expected immediate operand kind");
1450 Imm = Opnd.getImm();
1451 if (!isInt<10>(Imm))
1452 return Error(IDLoc,
"immediate operand value out of range");
1466 int MemOffset = Op.
getImm();
1467 if (MemOffset < -32768 || MemOffset > 32767) {
1469 expandMemInst(Inst, IDLoc, Instructions, MCID.
mayLoad(),
true);
1472 }
else if (Op.
isExpr()) {
1479 expandMemInst(Inst, IDLoc, Instructions, MCID.
mayLoad(),
false);
1482 }
else if (!isEvaluated(Expr)) {
1483 expandMemInst(Inst, IDLoc, Instructions, MCID.
mayLoad(),
false);
1491 if (inMicroMipsMode()) {
1500 int MemOffset = Op.
getImm();
1503 if (
isIntN(9, MemOffset) && (MemOffset % 4 == 0) &&
1506 BaseReg.
getReg() == Mips::GP) {
1529 case Mips::ADDIUS5_MM:
1532 return Error(IDLoc,
"expected immediate operand kind");
1534 if (Imm < -8 || Imm > 7)
1535 return Error(IDLoc,
"immediate operand value out of range");
1537 case Mips::ADDIUSP_MM:
1540 return Error(IDLoc,
"expected immediate operand kind");
1542 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1544 return Error(IDLoc,
"immediate operand value out of range");
1546 case Mips::SLL16_MM:
1547 case Mips::SRL16_MM:
1550 return Error(IDLoc,
"expected immediate operand kind");
1552 if (Imm < 1 || Imm > 8)
1553 return Error(IDLoc,
"immediate operand value out of range");
1558 return Error(IDLoc,
"expected immediate operand kind");
1560 if (Imm < -1 || Imm > 126)
1561 return Error(IDLoc,
"immediate operand value out of range");
1563 case Mips::ADDIUR2_MM:
1566 return Error(IDLoc,
"expected immediate operand kind");
1568 if (!(Imm == 1 || Imm == -1 ||
1569 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1570 return Error(IDLoc,
"immediate operand value out of range");
1572 case Mips::ADDIUR1SP_MM:
1575 return Error(IDLoc,
"expected immediate operand kind");
1578 return Error(IDLoc,
"misaligned immediate operand value");
1579 if (Imm < 0 || Imm > 255)
1580 return Error(IDLoc,
"immediate operand value out of range");
1582 case Mips::ANDI16_MM:
1585 return Error(IDLoc,
"expected immediate operand kind");
1587 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1588 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1589 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1590 return Error(IDLoc,
"immediate operand value out of range");
1592 case Mips::LBU16_MM:
1595 return Error(IDLoc,
"expected immediate operand kind");
1597 if (Imm < -1 || Imm > 14)
1598 return Error(IDLoc,
"immediate operand value out of range");
1603 return Error(IDLoc,
"expected immediate operand kind");
1605 if (Imm < 0 || Imm > 15)
1606 return Error(IDLoc,
"immediate operand value out of range");
1608 case Mips::LHU16_MM:
1612 return Error(IDLoc,
"expected immediate operand kind");
1614 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1615 return Error(IDLoc,
"immediate operand value out of range");
1621 return Error(IDLoc,
"expected immediate operand kind");
1623 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1624 return Error(IDLoc,
"immediate operand value out of range");
1630 return Error(IDLoc,
"expected immediate operand kind");
1632 if (!isUInt<5>(Imm))
1633 return Error(IDLoc,
"immediate operand value out of range");
1635 case Mips::ADDIUPC_MM:
1638 return Error(IDLoc,
"expected immediate operand kind");
1640 if ((Imm % 4 != 0) || !
isIntN(25, Imm))
1641 return Error(IDLoc,
"immediate operand value out of range");
1646 if (needsExpansion(Inst)) {
1647 if (expandInstruction(Inst, IDLoc, Instructions))
1654 if (MCID.
hasDelaySlot() && AssemblerOptions.back()->isReorder())
1660 bool MipsAsmParser::needsExpansion(
MCInst &Inst) {
1663 case Mips::LoadImm32:
1664 case Mips::LoadImm64:
1665 case Mips::LoadAddrImm32:
1666 case Mips::LoadAddrReg32:
1667 case Mips::B_MM_Pseudo:
1670 case Mips::JalOneReg:
1671 case Mips::JalTwoReg:
1690 bool MipsAsmParser::expandInstruction(
MCInst &Inst,
SMLoc IDLoc,
1694 case Mips::LoadImm32:
1695 return expandLoadImm(Inst,
true, IDLoc, Instructions);
1696 case Mips::LoadImm64:
1697 return expandLoadImm(Inst,
false, IDLoc, Instructions);
1698 case Mips::LoadAddrImm32:
1699 return expandLoadAddressImm(Inst,
true, IDLoc, Instructions);
1700 case Mips::LoadAddrReg32:
1701 return expandLoadAddressReg(Inst,
true, IDLoc, Instructions);
1702 case Mips::B_MM_Pseudo:
1703 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1706 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
1707 case Mips::JalOneReg:
1708 case Mips::JalTwoReg:
1709 return expandJalWithRegs(Inst, IDLoc, Instructions);
1712 return expandBranchImm(Inst, IDLoc, Instructions);
1721 return expandCondBranches(Inst, IDLoc, Instructions);
1723 return expandUlhu(Inst, IDLoc, Instructions);
1725 return expandUlw(Inst, IDLoc, Instructions);
1730 void emitRX(
unsigned Opcode,
unsigned DstReg,
MCOperand Imm,
SMLoc IDLoc,
1740 void emitRI(
unsigned Opcode,
unsigned DstReg, int16_t Imm,
SMLoc IDLoc,
1746 void emitRRX(
unsigned Opcode,
unsigned DstReg,
unsigned SrcReg,
MCOperand Imm,
1757 void emitRRR(
unsigned Opcode,
unsigned DstReg,
unsigned SrcReg,
1758 unsigned SrcReg2,
SMLoc IDLoc,
1764 void emitRRI(
unsigned Opcode,
unsigned DstReg,
unsigned SrcReg, int16_t Imm,
1770 template <
int16_t ShiftAmount>
1771 void createLShiftOri(
MCOperand Operand,
unsigned RegNo,
SMLoc IDLoc,
1773 if (ShiftAmount >= 32)
1774 emitRRI(Mips::DSLL32, RegNo, RegNo, ShiftAmount - 32, IDLoc, Instructions);
1775 else if (ShiftAmount > 0)
1776 emitRRI(Mips::DSLL, RegNo, RegNo, ShiftAmount, IDLoc, Instructions);
1782 emitRRX(Mips::ORi, RegNo, RegNo, Operand, IDLoc, Instructions);
1785 template <
unsigned ShiftAmount>
1786 void createLShiftOri(int64_t
Value,
unsigned RegNo,
SMLoc IDLoc,
1793 bool MipsAsmParser::expandJalWithRegs(
MCInst &Inst,
SMLoc IDLoc,
1799 const unsigned Opcode = Inst.
getOpcode();
1801 if (Opcode == Mips::JalOneReg) {
1803 if (inMicroMipsMode()) {
1811 }
else if (Opcode == Mips::JalTwoReg) {
1813 JalrInst.
setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1821 if (AssemblerOptions.back()->isReorder()) {
1835 bool MipsAsmParser::loadImmediate(int64_t ImmValue,
unsigned DstReg,
1836 unsigned SrcReg,
bool Is32BitImm,
SMLoc IDLoc,
1838 if (!Is32BitImm && !isGP64bit()) {
1839 Error(IDLoc,
"instruction requires a 64-bit architecture");
1848 ImmValue = SignExtend64<32>(ImmValue);
1850 Error(IDLoc,
"instruction requires a 32-bit immediate");
1855 bool UseSrcReg =
false;
1856 if (SrcReg != Mips::NoRegister)
1859 unsigned TmpReg = DstReg;
1860 if (UseSrcReg && (DstReg == SrcReg)) {
1863 unsigned ATReg = getATReg(IDLoc);
1874 SrcReg = Mips::ZERO;
1875 emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
1878 unsigned TmpReg = DstReg;
1879 if (SrcReg == DstReg) {
1880 unsigned ATReg = getATReg(IDLoc);
1886 emitRRI(Mips::ORi, TmpReg, Mips::ZERO, ImmValue, IDLoc, Instructions);
1888 emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
1890 warnIfNoMacro(IDLoc);
1895 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1896 uint16_t Bits15To0 = ImmValue & 0xffff;
1898 if (!Is32BitImm && !
isInt<32>(ImmValue)) {
1901 emitRRI(Mips::ORi, TmpReg, Mips::ZERO, Bits31To16, IDLoc, Instructions);
1902 emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, Instructions);
1904 emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, Instructions);
1905 createLShiftOri<0>(Bits15To0, TmpReg, IDLoc, Instructions);
1908 createAddu(DstReg, TmpReg, SrcReg, !Is32BitImm, Instructions);
1910 }
else if ((ImmValue & (0xffffLL << 48)) == 0) {
1911 warnIfNoMacro(IDLoc);
1926 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1927 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1928 uint16_t Bits15To0 = ImmValue & 0xffff;
1930 emitRI(Mips::LUi, TmpReg, Bits47To32, IDLoc, Instructions);
1931 createLShiftOri<0>(Bits31To16, TmpReg, IDLoc, Instructions);
1932 createLShiftOri<16>(Bits15To0, TmpReg, IDLoc, Instructions);
1935 createAddu(DstReg, TmpReg, SrcReg, !Is32BitImm, Instructions);
1938 warnIfNoMacro(IDLoc);
1954 uint16_t Bits63To48 = (ImmValue >> 48) & 0xffff;
1955 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1956 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1957 uint16_t Bits15To0 = ImmValue & 0xffff;
1959 emitRI(Mips::LUi, TmpReg, Bits63To48, IDLoc, Instructions);
1960 createLShiftOri<0>(Bits47To32, TmpReg, IDLoc, Instructions);
1964 if (Bits31To16 == 0) {
1965 createLShiftOri<32>(Bits15To0, TmpReg, IDLoc, Instructions);
1967 createLShiftOri<16>(Bits31To16, TmpReg, IDLoc, Instructions);
1968 createLShiftOri<16>(Bits15To0, TmpReg, IDLoc, Instructions);
1972 createAddu(DstReg, TmpReg, SrcReg, !Is32BitImm, Instructions);
1977 bool MipsAsmParser::expandLoadImm(
MCInst &Inst,
bool Is32BitImm,
SMLoc IDLoc,
1980 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
1982 assert(DstRegOp.isReg() &&
"expected register operand kind");
1984 if (loadImmediate(ImmOp.
getImm(), DstRegOp.getReg(), Mips::NoRegister,
1985 Is32BitImm, IDLoc, Instructions))
1992 MipsAsmParser::expandLoadAddressReg(
MCInst &Inst,
bool Is32BitImm,
SMLoc IDLoc,
1995 assert(DstRegOp.
isReg() &&
"expected register operand kind");
1998 assert(SrcRegOp.isReg() &&
"expected register operand kind");
2001 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
2002 "expected immediate operand kind");
2003 if (!ImmOp.isImm()) {
2004 if (loadAndAddSymbolAddress(ImmOp.getExpr(), DstRegOp.
getReg(),
2005 SrcRegOp.getReg(), Is32BitImm, IDLoc,
2012 if (loadImmediate(ImmOp.getImm(), DstRegOp.
getReg(), SrcRegOp.getReg(),
2013 Is32BitImm, IDLoc, Instructions))
2020 MipsAsmParser::expandLoadAddressImm(
MCInst &Inst,
bool Is32BitImm,
SMLoc IDLoc,
2023 assert(DstRegOp.
isReg() &&
"expected register operand kind");
2026 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
2027 "expected immediate operand kind");
2028 if (!ImmOp.isImm()) {
2029 if (loadAndAddSymbolAddress(ImmOp.getExpr(), DstRegOp.
getReg(),
2030 Mips::NoRegister, Is32BitImm, IDLoc,
2037 if (loadImmediate(ImmOp.getImm(), DstRegOp.
getReg(), Mips::NoRegister,
2038 Is32BitImm, IDLoc, Instructions))
2044 bool MipsAsmParser::loadAndAddSymbolAddress(
2045 const MCExpr *SymExpr,
unsigned DstReg,
unsigned SrcReg,
bool Is32BitSym,
2047 warnIfNoMacro(IDLoc);
2049 if (Is32BitSym && isABI_N64())
2050 Warning(IDLoc,
"instruction loads the 32-bit address of a 64-bit symbol");
2059 bool UseSrcReg = SrcReg != Mips::NoRegister;
2061 unsigned TmpReg = DstReg;
2062 if (UseSrcReg && (DstReg == SrcReg)) {
2065 unsigned ATReg = getATReg(IDLoc);
2109 createAddu(DstReg, TmpReg, SrcReg, !Is32BitSym, Instructions);
2114 bool MipsAsmParser::expandUncondBranchMMPseudo(
2117 "unexpected number of operands");
2120 if (Offset.isExpr()) {
2127 assert(Offset.isImm() &&
"expected immediate operand kind");
2128 if (
isIntN(11, Offset.getImm())) {
2133 if (!
isIntN(17, Offset.getImm()))
2134 Error(IDLoc,
"branch target out of range");
2136 Error(IDLoc,
"branch to misaligned address");
2147 if (AssemblerOptions.back()->isReorder())
2148 createNop(
true, IDLoc, Instructions);
2153 bool MipsAsmParser::expandBranchImm(
MCInst &Inst,
SMLoc IDLoc,
2156 assert(DstRegOp.
isReg() &&
"expected register operand kind");
2159 assert(ImmOp.isImm() &&
"expected immediate operand kind");
2162 assert(MemOffsetOp.isImm() &&
"expected immediate operand kind");
2164 unsigned OpCode = 0;
2177 int64_t ImmValue = ImmOp.getImm();
2178 if (ImmValue == 0) {
2186 warnIfNoMacro(IDLoc);
2188 unsigned ATReg = getATReg(IDLoc);
2192 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), IDLoc,
2206 void MipsAsmParser::expandMemInst(
MCInst &Inst,
SMLoc IDLoc,
2208 bool isLoad,
bool isImmOpnd) {
2210 unsigned ImmOffset, HiOffset, LoOffset;
2211 const MCExpr *ExprOffset;
2214 assert(Inst.
getOperand(0).
isReg() &&
"expected register operand kind");
2217 assert(Inst.
getOperand(1).
isReg() &&
"expected register operand kind");
2221 assert(Inst.
getOperand(2).
isImm() &&
"expected immediate operand kind");
2223 LoOffset = ImmOffset & 0x0000ffff;
2224 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2226 if (LoOffset & 0x8000)
2256 unsigned RegClassIDOp0 =
2257 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2258 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2259 (RegClassIDOp0 == Mips::GPR64RegClassID);
2260 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2261 TmpRegNum = RegOpNum;
2265 TmpRegNum = getATReg(IDLoc);
2275 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset,
"hi");
2283 if (BaseRegNum != Mips::ZERO) {
2299 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset,
"lo");
2307 MipsAsmParser::expandLoadStoreMultiple(
MCInst &Inst,
SMLoc IDLoc,
2311 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2315 Inst.
getOperand(OpNum - 3).
isReg() &&
"Invalid instruction operand.");
2322 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2329 bool MipsAsmParser::expandCondBranches(
MCInst &Inst,
SMLoc IDLoc,
2331 unsigned PseudoOpcode = Inst.
getOpcode();
2336 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2337 bool ReverseOrderSLT, IsUnsigned, AcceptsEquality;
2339 switch (PseudoOpcode) {
2342 AcceptsEquality =
false;
2343 ReverseOrderSLT =
false;
2344 IsUnsigned = (PseudoOpcode == Mips::BLTU);
2345 ZeroSrcOpcode = Mips::BGTZ;
2346 ZeroTrgOpcode = Mips::BLTZ;
2350 AcceptsEquality =
true;
2351 ReverseOrderSLT =
true;
2352 IsUnsigned = (PseudoOpcode == Mips::BLEU);
2353 ZeroSrcOpcode = Mips::BGEZ;
2354 ZeroTrgOpcode = Mips::BLEZ;
2358 AcceptsEquality =
true;
2359 ReverseOrderSLT =
false;
2360 IsUnsigned = (PseudoOpcode == Mips::BGEU);
2361 ZeroSrcOpcode = Mips::BLEZ;
2362 ZeroTrgOpcode = Mips::BGEZ;
2366 AcceptsEquality =
false;
2367 ReverseOrderSLT =
true;
2368 IsUnsigned = (PseudoOpcode == Mips::BGTU);
2369 ZeroSrcOpcode = Mips::BLTZ;
2370 ZeroTrgOpcode = Mips::BGTZ;
2377 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
2378 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
2379 if (IsSrcRegZero && IsTrgRegZero) {
2383 if (PseudoOpcode == Mips::BLT) {
2390 if (PseudoOpcode == Mips::BLE) {
2395 Warning(IDLoc,
"branch is always taken");
2398 if (PseudoOpcode == Mips::BGE) {
2403 Warning(IDLoc,
"branch is always taken");
2406 if (PseudoOpcode == Mips::BGT) {
2413 if (PseudoOpcode == Mips::BGTU) {
2421 if (AcceptsEquality) {
2429 Warning(IDLoc,
"branch is always taken");
2436 if (IsSrcRegZero || IsTrgRegZero) {
2437 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
2438 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
2445 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
2446 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
2457 Warning(IDLoc,
"branch is always taken");
2473 BranchInst.
setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2484 BranchInst.
setOpcode(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode);
2493 unsigned ATRegNum = getATReg(IDLoc);
2497 warnIfNoMacro(IDLoc);
2515 SetInst.
setOpcode(IsUnsigned ? Mips::SLTu : Mips::SLT);
2521 BranchInst.
setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2529 bool MipsAsmParser::expandUlhu(
MCInst &Inst,
SMLoc IDLoc,
2531 if (hasMips32r6() || hasMips64r6()) {
2532 Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
2536 warnIfNoMacro(IDLoc);
2539 assert(DstRegOp.
isReg() &&
"expected register operand kind");
2542 assert(SrcRegOp.isReg() &&
"expected register operand kind");
2545 assert(OffsetImmOp.isImm() &&
"expected immediate operand kind");
2547 unsigned DstReg = DstRegOp.
getReg();
2548 unsigned SrcReg = SrcRegOp.getReg();
2549 int64_t OffsetValue = OffsetImmOp.getImm();
2553 unsigned ATReg = getATReg(IDLoc);
2560 bool LoadedOffsetInAT =
false;
2562 LoadedOffsetInAT =
true;
2564 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
2565 IDLoc, Instructions))
2574 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
2575 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
2578 unsigned FirstLbuDstReg = LoadedOffsetInAT ? DstReg : ATReg;
2579 unsigned SecondLbuDstReg = LoadedOffsetInAT ? ATReg : DstReg;
2580 unsigned LbuSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
2582 int64_t FirstLbuOffset = 0, SecondLbuOffset = 0;
2584 FirstLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
2585 SecondLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2587 FirstLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2588 SecondLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
2591 unsigned SllReg = LoadedOffsetInAT ? DstReg : ATReg;
2624 bool MipsAsmParser::expandUlw(
MCInst &Inst,
SMLoc IDLoc,
2626 if (hasMips32r6() || hasMips64r6()) {
2627 Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
2632 assert(DstRegOp.
isReg() &&
"expected register operand kind");
2635 assert(SrcRegOp.isReg() &&
"expected register operand kind");
2638 assert(OffsetImmOp.isImm() &&
"expected immediate operand kind");
2640 unsigned SrcReg = SrcRegOp.getReg();
2641 int64_t OffsetValue = OffsetImmOp.getImm();
2647 bool LoadedOffsetInAT =
false;
2649 ATReg = getATReg(IDLoc);
2652 LoadedOffsetInAT =
true;
2654 warnIfNoMacro(IDLoc);
2656 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
2657 IDLoc, Instructions))
2666 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
2667 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
2670 unsigned FinalSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
2671 int64_t LeftLoadOffset = 0, RightLoadOffset = 0;
2673 LeftLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
2674 RightLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2676 LeftLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2677 RightLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
2700 if (hasShortDelaySlot) {
2713 void MipsAsmParser::createAddu(
unsigned DstReg,
unsigned SrcReg,
2714 unsigned TrgReg,
bool Is64Bit,
2716 emitRRR(Is64Bit ? Mips::DADDu : Mips::ADDu, DstReg, SrcReg, TrgReg,
SMLoc(),
2720 unsigned MipsAsmParser::checkTargetMatchPredicate(
MCInst &Inst) {
2725 if (Opcode == Mips::JALR_HB &&
2727 return Match_RequiresDifferentSrcAndDst;
2729 return Match_Success;
2732 bool MipsAsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
2735 uint64_t &ErrorInfo,
2736 bool MatchingInlineAsm) {
2740 unsigned MatchResult =
2741 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
2743 switch (MatchResult) {
2744 case Match_Success: {
2747 for (
unsigned i = 0; i < Instructions.
size(); i++)
2751 case Match_MissingFeature:
2752 Error(IDLoc,
"instruction requires a CPU feature not currently enabled");
2754 case Match_InvalidOperand: {
2755 SMLoc ErrorLoc = IDLoc;
2756 if (ErrorInfo != ~0ULL) {
2757 if (ErrorInfo >= Operands.
size())
2758 return Error(IDLoc,
"too few operands for instruction");
2760 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
2761 if (ErrorLoc ==
SMLoc())
2765 return Error(ErrorLoc,
"invalid operand for instruction");
2767 case Match_MnemonicFail:
2768 return Error(IDLoc,
"invalid instruction");
2769 case Match_RequiresDifferentSrcAndDst:
2770 return Error(IDLoc,
"source and destination must be different");
2776 void MipsAsmParser::warnIfRegIndexIsAT(
unsigned RegIndex,
SMLoc Loc) {
2777 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
2778 Warning(Loc,
"used $at (currently $" +
Twine(RegIndex) +
2779 ") without \".set noat\"");
2782 void MipsAsmParser::warnIfNoMacro(
SMLoc Loc) {
2783 if (!AssemblerOptions.back()->isMacro())
2784 Warning(Loc,
"macro instruction expanded into multiple instructions");
2788 MipsAsmParser::printWarningWithFixIt(
const Twine &Msg,
const Twine &FixMsg,
2789 SMRange Range,
bool ShowColors) {
2791 Range,
SMFixIt(Range, FixMsg),
2834 if (!(isABI_N32() || isABI_N64()))
2837 if (12 <= CC && CC <= 15) {
2839 AsmToken RegTok = getLexer().peekTok();
2848 assert(FixedName !=
"" &&
"Register name is not one of t4-t7.");
2850 printWarningWithFixIt(
"register names $t4-$t7 are only available in O32.",
2851 "Did you mean $" + FixedName +
"?", RegRange);
2857 if (8 <= CC && CC <= 11)
2873 int MipsAsmParser::matchHWRegsRegisterName(
StringRef Name) {
2877 .Case(
"hwr_cpunum", 0)
2878 .
Case(
"hwr_synci_step", 1)
2880 .
Case(
"hwr_ccres", 3)
2881 .
Case(
"hwr_ulr", 29)
2887 int MipsAsmParser::matchFPURegisterName(
StringRef Name) {
2889 if (Name[0] ==
'f') {
2901 int MipsAsmParser::matchFCCRegisterName(
StringRef Name) {
2915 int MipsAsmParser::matchACRegisterName(
StringRef Name) {
2929 int MipsAsmParser::matchMSA128RegisterName(
StringRef Name) {
2941 int MipsAsmParser::matchMSA128CtrlRegisterName(
StringRef Name) {
2947 .
Case(
"msaaccess", 2)
2949 .
Case(
"msamodify", 4)
2950 .
Case(
"msarequest", 5)
2952 .
Case(
"msaunmap", 7)
2958 unsigned MipsAsmParser::getATReg(
SMLoc Loc) {
2959 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
2961 reportParseError(Loc,
2962 "pseudo-instruction requires $at, which is not available");
2966 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
2971 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2974 unsigned MipsAsmParser::getGPR(
int RegNo) {
2975 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2979 int MipsAsmParser::matchRegisterByNumber(
unsigned RegNum,
unsigned RegClass) {
2981 getContext().getRegisterInfo()->
getRegClass(RegClass).getNumRegs() - 1)
2984 return getReg(RegClass, RegNum);
2993 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2994 if (ResTy == MatchOperand_Success)
2999 if (ResTy == MatchOperand_ParseFail)
3004 switch (getLexer().getKind()) {
3017 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
3026 MCSymbol *Sym = getContext().getOrCreateSymbol(
"$" + Identifier);
3031 Operands.
push_back(MipsOperand::CreateImm(Res, S, E, *
this));
3041 DEBUG(
dbgs() <<
".. generic integer\n");
3042 OperandMatchResultTy ResTy = parseImm(Operands);
3043 return ResTy != MatchOperand_Success;
3049 if (parseRelocOperand(IdVal))
3054 Operands.
push_back(MipsOperand::CreateImm(IdVal, S, E, *
this));
3061 const MCExpr *MipsAsmParser::evaluateRelocExpr(
const MCExpr *Expr,
3065 if (
const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
3071 Val = MCE->getValue() & 0xffff;
3076 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
3080 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
3084 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
3100 if (
const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3107 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
3108 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
3113 if (
const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
3114 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
3122 bool MipsAsmParser::isEvaluated(
const MCExpr *Expr) {
3130 if (
const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3131 if (!isEvaluated(BE->getLHS()))
3133 return isEvaluated(BE->getRHS());
3136 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
3143 bool MipsAsmParser::parseRelocOperand(
const MCExpr *&Res) {
3173 if (getParser().parseParenExpression(IdVal, EndLoc))
3182 Res = evaluateRelocExpr(IdVal, Str);
3186 bool MipsAsmParser::ParseRegister(
unsigned &RegNo,
SMLoc &StartLoc,
3189 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
3190 if (ResTy == MatchOperand_Success) {
3191 assert(Operands.
size() == 1);
3192 MipsOperand &Operand =
static_cast<MipsOperand &
>(*Operands.
front());
3193 StartLoc = Operand.getStartLoc();
3194 EndLoc = Operand.getEndLoc();
3200 if (Operand.isGPRAsmReg()) {
3202 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
3205 return (RegNo == (
unsigned)-1);
3208 assert(Operands.
size() == 0);
3209 return (RegNo == (
unsigned)-1);
3212 bool MipsAsmParser::parseMemOffset(
const MCExpr *&Res,
bool isParenExpr) {
3216 unsigned NumOfLParen = 0;
3223 switch (getLexer().getKind()) {
3232 Result = getParser().parseParenExprOfDepth(NumOfLParen, Res, S);
3234 Result = (getParser().parseExpression(Res));
3239 Result = parseRelocOperand(Res);
3244 MipsAsmParser::OperandMatchResultTy
3248 const MCExpr *IdVal =
nullptr;
3250 bool isParenExpr =
false;
3251 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
3261 if (parseMemOffset(IdVal, isParenExpr))
3262 return MatchOperand_ParseFail;
3266 MipsOperand &Mnemonic =
static_cast<MipsOperand &
>(*Operands[0]);
3267 if (Mnemonic.getToken() ==
"la") {
3270 Operands.
push_back(MipsOperand::CreateImm(IdVal, S, E, *
this));
3271 return MatchOperand_Success;
3279 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
3282 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *
this));
3283 return MatchOperand_Success;
3286 return MatchOperand_ParseFail;
3292 Res = parseAnyRegister(Operands);
3293 if (Res != MatchOperand_Success)
3298 return MatchOperand_ParseFail;
3309 std::unique_ptr<MipsOperand>
op(
3310 static_cast<MipsOperand *>(Operands.
back().release()));
3315 if (
const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
3317 if (IdVal->evaluateAsAbsolute(Imm))
3324 Operands.
push_back(MipsOperand::CreateMem(std::move(
op), IdVal, S, E, *
this));
3325 return MatchOperand_Success;
3328 bool MipsAsmParser::searchSymbolAlias(
OperandVector &Operands) {
3342 OperandMatchResultTy ResTy =
3343 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.
substr(1), S);
3344 if (ResTy == MatchOperand_Success) {
3347 }
else if (ResTy == MatchOperand_ParseFail)
3355 MipsOperand::CreateImm(Const, S, Parser.
getTok().
getLoc(), *
this));
3362 MipsAsmParser::OperandMatchResultTy
3363 MipsAsmParser::matchAnyRegisterNameWithoutDollar(
OperandVector &Operands,
3366 int Index = matchCPURegisterName(Identifier);
3368 Operands.
push_back(MipsOperand::createGPRReg(
3369 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *
this));
3370 return MatchOperand_Success;
3373 Index = matchHWRegsRegisterName(Identifier);
3375 Operands.
push_back(MipsOperand::createHWRegsReg(
3376 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *
this));
3377 return MatchOperand_Success;
3380 Index = matchFPURegisterName(Identifier);
3382 Operands.
push_back(MipsOperand::createFGRReg(
3383 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *
this));
3384 return MatchOperand_Success;
3387 Index = matchFCCRegisterName(Identifier);
3389 Operands.
push_back(MipsOperand::createFCCReg(
3390 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *
this));
3391 return MatchOperand_Success;
3394 Index = matchACRegisterName(Identifier);
3396 Operands.
push_back(MipsOperand::createACCReg(
3397 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *
this));
3398 return MatchOperand_Success;
3401 Index = matchMSA128RegisterName(Identifier);
3403 Operands.
push_back(MipsOperand::createMSA128Reg(
3404 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *
this));
3405 return MatchOperand_Success;
3408 Index = matchMSA128CtrlRegisterName(Identifier);
3410 Operands.
push_back(MipsOperand::createMSACtrlReg(
3411 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *
this));
3412 return MatchOperand_Success;
3415 return MatchOperand_NoMatch;
3418 MipsAsmParser::OperandMatchResultTy
3425 StringRef Identifier = Token.getIdentifier();
3426 OperandMatchResultTy ResTy =
3427 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
3431 Operands.
push_back(MipsOperand::createNumericReg(
3432 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
3434 return MatchOperand_Success;
3439 return MatchOperand_NoMatch;
3442 MipsAsmParser::OperandMatchResultTy
3447 auto Token = Parser.
getTok();
3449 SMLoc S = Token.getLoc();
3452 DEBUG(
dbgs() <<
".. !$ -> try sym aliasing\n");
3454 if (searchSymbolAlias(Operands))
3455 return MatchOperand_Success;
3457 DEBUG(
dbgs() <<
".. !symalias -> NoMatch\n");
3458 return MatchOperand_NoMatch;
3462 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
3463 if (ResTy == MatchOperand_Success) {
3470 MipsAsmParser::OperandMatchResultTy
3473 switch (getLexer().getKind()) {
3475 return MatchOperand_NoMatch;
3487 if (getParser().parseExpression(IdVal))
3488 return MatchOperand_ParseFail;
3491 Operands.
push_back(MipsOperand::CreateImm(IdVal, S, E, *
this));
3492 return MatchOperand_Success;
3495 MipsAsmParser::OperandMatchResultTy
3500 SMLoc S = getLexer().getLoc();
3503 OperandMatchResultTy ResTy = parseImm(Operands);
3504 if (ResTy != MatchOperand_NoMatch)
3508 ResTy = parseAnyRegister(Operands);
3509 if (ResTy != MatchOperand_NoMatch)
3512 const MCExpr *Expr =
nullptr;
3515 return MatchOperand_ParseFail;
3518 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *
this));
3519 return MatchOperand_Success;
3522 MipsAsmParser::OperandMatchResultTy
3528 return MatchOperand_NoMatch;
3530 if (getParser().parseExpression(IdVal))
3531 return MatchOperand_ParseFail;
3533 assert(MCE &&
"Unexpected MCExpr type.");
3536 Operands.
push_back(MipsOperand::CreateImm(
3538 return MatchOperand_Success;
3541 MipsAsmParser::OperandMatchResultTy
3544 switch (getLexer().getKind()) {
3546 return MatchOperand_NoMatch;
3557 if (getParser().parseExpression(Expr))
3558 return MatchOperand_ParseFail;
3561 if (!Expr->evaluateAsAbsolute(Val)) {
3562 Error(S,
"expected immediate value");
3563 return MatchOperand_ParseFail;
3571 if (Val < 1 || Val > 4) {
3572 Error(S,
"immediate not in range (1..4)");
3573 return MatchOperand_ParseFail;
3577 MipsOperand::CreateImm(Expr, S, Parser.
getTok().
getLoc(), *
this));
3578 return MatchOperand_Success;
3581 MipsAsmParser::OperandMatchResultTy
3586 unsigned PrevReg = Mips::NoRegister;
3587 bool RegRange =
false;
3591 return MatchOperand_ParseFail;
3594 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3595 SMLoc E = getLexer().getLoc();
3596 MipsOperand &
Reg =
static_cast<MipsOperand &
>(*TmpOperands.
back());
3597 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3601 if (RegNo == Mips::RA) {
3604 unsigned TmpReg = PrevReg + 1;
3605 while (TmpReg <= RegNo) {
3606 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3607 Error(E,
"invalid register operand");
3608 return MatchOperand_ParseFail;
3618 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
3619 (RegNo != Mips::RA)) {
3620 Error(E,
"$16 or $31 expected");
3621 return MatchOperand_ParseFail;
3622 }
else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
3623 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3624 Error(E,
"invalid register operand");
3625 return MatchOperand_ParseFail;
3626 }
else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
3627 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3628 Error(E,
"consecutive register numbers expected");
3629 return MatchOperand_ParseFail;
3640 Error(E,
"',' or '-' expected");
3641 return MatchOperand_ParseFail;
3652 Operands.
push_back(MipsOperand::CreateRegList(Regs, S, E, *
this));
3653 parseMemOperand(Operands);
3654 return MatchOperand_Success;
3657 MipsAsmParser::OperandMatchResultTy
3662 if (parseAnyRegister(Operands) != MatchOperand_Success)
3663 return MatchOperand_ParseFail;
3666 MipsOperand &Op =
static_cast<MipsOperand &
>(*Operands.
back());
3667 unsigned Reg = Op.getGPR32Reg();
3669 Operands.
push_back(MipsOperand::CreateRegPair(Reg, S, E, *
this));
3670 return MatchOperand_Success;
3673 MipsAsmParser::OperandMatchResultTy
3680 return MatchOperand_ParseFail;
3684 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3685 return MatchOperand_ParseFail;
3687 MipsOperand *Reg = &
static_cast<MipsOperand &
>(*TmpOperands.
back());
3688 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3693 Error(E,
"',' expected");
3694 return MatchOperand_ParseFail;
3700 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3701 return MatchOperand_ParseFail;
3703 Reg = &
static_cast<MipsOperand &
>(*TmpOperands.
back());
3704 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3707 Operands.
push_back(MipsOperand::CreateRegList(Regs, S, E, *
this));
3709 return MatchOperand_Success;
3757 MipsOperand::CreateToken(
"(", getLexer().getLoc(), *
this));
3759 if (parseOperand(Operands, Name)) {
3760 SMLoc Loc = getLexer().getLoc();
3762 return Error(Loc,
"unexpected token in argument list");
3765 SMLoc Loc = getLexer().getLoc();
3767 return Error(Loc,
"unexpected token, expected ')'");
3770 MipsOperand::CreateToken(
")", getLexer().getLoc(), *
this));
3782 bool MipsAsmParser::parseBracketSuffix(
StringRef Name,
3787 MipsOperand::CreateToken(
"[", getLexer().getLoc(), *
this));
3789 if (parseOperand(Operands, Name)) {
3790 SMLoc Loc = getLexer().getLoc();
3792 return Error(Loc,
"unexpected token in argument list");
3795 SMLoc Loc = getLexer().getLoc();
3797 return Error(Loc,
"unexpected token, expected ']'");
3800 MipsOperand::CreateToken(
"]", getLexer().getLoc(), *
this));
3812 getTargetStreamer().forbidModuleDirective();
3815 if (!mnemonicIsValid(Name, 0)) {
3817 return Error(NameLoc,
"unknown instruction");
3820 Operands.
push_back(MipsOperand::CreateToken(Name, NameLoc, *
this));
3825 if (parseOperand(Operands, Name)) {
3826 SMLoc Loc = getLexer().getLoc();
3828 return Error(Loc,
"unexpected token in argument list");
3830 if (getLexer().is(
AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
3837 if (parseOperand(Operands, Name)) {
3838 SMLoc Loc = getLexer().getLoc();
3840 return Error(Loc,
"unexpected token in argument list");
3844 if (parseBracketSuffix(Name, Operands))
3847 parseParenSuffix(Name, Operands))
3852 SMLoc Loc = getLexer().getLoc();
3854 return Error(Loc,
"unexpected token in argument list");
3860 bool MipsAsmParser::reportParseError(
Twine ErrorMsg) {
3862 SMLoc Loc = getLexer().getLoc();
3864 return Error(Loc, ErrorMsg);
3867 bool MipsAsmParser::reportParseError(
SMLoc Loc,
Twine ErrorMsg) {
3868 return Error(Loc, ErrorMsg);
3871 bool MipsAsmParser::parseSetNoAtDirective() {
3876 AssemblerOptions.back()->setATRegIndex(0);
3882 reportParseError(
"unexpected token, expected end of statement");
3886 getTargetStreamer().emitDirectiveSetNoAt();
3891 bool MipsAsmParser::parseSetAtDirective() {
3899 AssemblerOptions.back()->setATRegIndex(1);
3901 getTargetStreamer().emitDirectiveSetAt();
3907 reportParseError(
"unexpected token, expected equals sign");
3914 reportParseError(
"no register specified");
3917 reportParseError(
"unexpected token, expected dollar sign '$'");
3931 reportParseError(
"unexpected token, expected identifier or integer");
3936 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
3937 reportParseError(
"invalid register");
3944 reportParseError(
"unexpected token, expected end of statement");
3948 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
3954 bool MipsAsmParser::parseSetReorderDirective() {
3959 reportParseError(
"unexpected token, expected end of statement");
3962 AssemblerOptions.back()->setReorder();
3963 getTargetStreamer().emitDirectiveSetReorder();
3968 bool MipsAsmParser::parseSetNoReorderDirective() {
3973 reportParseError(
"unexpected token, expected end of statement");
3976 AssemblerOptions.back()->setNoReorder();
3977 getTargetStreamer().emitDirectiveSetNoReorder();
3982 bool MipsAsmParser::parseSetMacroDirective() {
3987 reportParseError(
"unexpected token, expected end of statement");
3990 AssemblerOptions.back()->setMacro();
3991 getTargetStreamer().emitDirectiveSetMacro();
3996 bool MipsAsmParser::parseSetNoMacroDirective() {
4001 reportParseError(
"unexpected token, expected end of statement");
4004 if (AssemblerOptions.back()->isReorder()) {
4005 reportParseError(
"`noreorder' must be set before `nomacro'");
4008 AssemblerOptions.back()->setNoMacro();
4009 getTargetStreamer().emitDirectiveSetNoMacro();
4014 bool MipsAsmParser::parseSetMsaDirective() {
4020 return reportParseError(
"unexpected token, expected end of statement");
4022 setFeatureBits(Mips::FeatureMSA,
"msa");
4023 getTargetStreamer().emitDirectiveSetMsa();
4027 bool MipsAsmParser::parseSetNoMsaDirective() {
4033 return reportParseError(
"unexpected token, expected end of statement");
4035 clearFeatureBits(Mips::FeatureMSA,
"msa");
4036 getTargetStreamer().emitDirectiveSetNoMsa();
4040 bool MipsAsmParser::parseSetNoDspDirective() {
4046 reportParseError(
"unexpected token, expected end of statement");
4050 clearFeatureBits(Mips::FeatureDSP,
"dsp");
4051 getTargetStreamer().emitDirectiveSetNoDsp();
4055 bool MipsAsmParser::parseSetMips16Directive() {
4061 reportParseError(
"unexpected token, expected end of statement");
4065 setFeatureBits(Mips::FeatureMips16,
"mips16");
4066 getTargetStreamer().emitDirectiveSetMips16();
4071 bool MipsAsmParser::parseSetNoMips16Directive() {
4077 reportParseError(
"unexpected token, expected end of statement");
4081 clearFeatureBits(Mips::FeatureMips16,
"mips16");
4082 getTargetStreamer().emitDirectiveSetNoMips16();
4087 bool MipsAsmParser::parseSetFpDirective() {
4096 reportParseError(
"unexpected token, expected equals sign '='");
4102 if (!parseFpABIValue(FpAbiVal,
".set"))
4106 reportParseError(
"unexpected token, expected end of statement");
4109 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
4114 bool MipsAsmParser::parseSetOddSPRegDirective() {
4119 reportParseError(
"unexpected token, expected end of statement");
4123 clearFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
4124 getTargetStreamer().emitDirectiveSetOddSPReg();
4128 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
4133 reportParseError(
"unexpected token, expected end of statement");
4137 setFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
4138 getTargetStreamer().emitDirectiveSetNoOddSPReg();
4142 bool MipsAsmParser::parseSetPopDirective() {
4144 SMLoc Loc = getLexer().getLoc();
4148 return reportParseError(
"unexpected token, expected end of statement");
4152 if (AssemblerOptions.size() == 2)
4153 return reportParseError(Loc,
".set pop with no .set push");
4155 AssemblerOptions.pop_back();
4156 setAvailableFeatures(
4157 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
4158 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
4160 getTargetStreamer().emitDirectiveSetPop();
4164 bool MipsAsmParser::parseSetPushDirective() {
4168 return reportParseError(
"unexpected token, expected end of statement");
4171 AssemblerOptions.push_back(
4172 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
4174 getTargetStreamer().emitDirectiveSetPush();
4178 bool MipsAsmParser::parseSetSoftFloatDirective() {
4182 return reportParseError(
"unexpected token, expected end of statement");
4184 setFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
4185 getTargetStreamer().emitDirectiveSetSoftFloat();
4189 bool MipsAsmParser::parseSetHardFloatDirective() {
4193 return reportParseError(
"unexpected token, expected end of statement");
4195 clearFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
4196 getTargetStreamer().emitDirectiveSetHardFloat();
4200 bool MipsAsmParser::parseSetAssignment() {
4206 reportParseError(
"expected identifier after .set");
4209 return reportParseError(
"unexpected token, expected comma");
4213 return reportParseError(
"expected valid expression after comma");
4215 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4221 bool MipsAsmParser::parseSetMips0Directive() {
4225 return reportParseError(
"unexpected token, expected end of statement");
4228 setAvailableFeatures(
4229 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
4230 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
4231 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
4233 getTargetStreamer().emitDirectiveSetMips0();
4237 bool MipsAsmParser::parseSetArchDirective() {
4241 return reportParseError(
"unexpected token, expected equals sign");
4246 return reportParseError(
"expected arch identifier");
4250 .Case(
"mips1",
"mips1")
4251 .
Case(
"mips2",
"mips2")
4252 .
Case(
"mips3",
"mips3")
4253 .
Case(
"mips4",
"mips4")
4254 .
Case(
"mips5",
"mips5")
4255 .
Case(
"mips32",
"mips32")
4256 .
Case(
"mips32r2",
"mips32r2")
4257 .
Case(
"mips32r3",
"mips32r3")
4258 .
Case(
"mips32r5",
"mips32r5")
4259 .
Case(
"mips32r6",
"mips32r6")
4260 .
Case(
"mips64",
"mips64")
4261 .
Case(
"mips64r2",
"mips64r2")
4262 .
Case(
"mips64r3",
"mips64r3")
4263 .
Case(
"mips64r5",
"mips64r5")
4264 .
Case(
"mips64r6",
"mips64r6")
4265 .
Case(
"cnmips",
"cnmips")
4266 .
Case(
"r4000",
"mips3")
4269 if (ArchFeatureName.
empty())
4270 return reportParseError(
"unsupported architecture");
4272 selectArch(ArchFeatureName);
4273 getTargetStreamer().emitDirectiveSetArch(Arch);
4277 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
4281 return reportParseError(
"unexpected token, expected end of statement");
4286 case Mips::FeatureDSP:
4287 setFeatureBits(Mips::FeatureDSP,
"dsp");
4288 getTargetStreamer().emitDirectiveSetDsp();
4290 case Mips::FeatureMicroMips:
4291 getTargetStreamer().emitDirectiveSetMicroMips();
4293 case Mips::FeatureMips1:
4294 selectArch(
"mips1");
4295 getTargetStreamer().emitDirectiveSetMips1();
4297 case Mips::FeatureMips2:
4298 selectArch(
"mips2");
4299 getTargetStreamer().emitDirectiveSetMips2();
4301 case Mips::FeatureMips3:
4302 selectArch(
"mips3");
4303 getTargetStreamer().emitDirectiveSetMips3();
4305 case Mips::FeatureMips4:
4306 selectArch(
"mips4");
4307 getTargetStreamer().emitDirectiveSetMips4();
4309 case Mips::FeatureMips5:
4310 selectArch(
"mips5");
4311 getTargetStreamer().emitDirectiveSetMips5();
4313 case Mips::FeatureMips32:
4314 selectArch(
"mips32");
4315 getTargetStreamer().emitDirectiveSetMips32();
4317 case Mips::FeatureMips32r2:
4318 selectArch(
"mips32r2");
4319 getTargetStreamer().emitDirectiveSetMips32R2();
4321 case Mips::FeatureMips32r3:
4322 selectArch(
"mips32r3");
4323 getTargetStreamer().emitDirectiveSetMips32R3();
4325 case Mips::FeatureMips32r5:
4326 selectArch(
"mips32r5");
4327 getTargetStreamer().emitDirectiveSetMips32R5();
4329 case Mips::FeatureMips32r6:
4330 selectArch(
"mips32r6");
4331 getTargetStreamer().emitDirectiveSetMips32R6();
4333 case Mips::FeatureMips64:
4334 selectArch(
"mips64");
4335 getTargetStreamer().emitDirectiveSetMips64();
4337 case Mips::FeatureMips64r2:
4338 selectArch(
"mips64r2");
4339 getTargetStreamer().emitDirectiveSetMips64R2();
4341 case Mips::FeatureMips64r3:
4342 selectArch(
"mips64r3");
4343 getTargetStreamer().emitDirectiveSetMips64R3();
4345 case Mips::FeatureMips64r5:
4346 selectArch(
"mips64r5");
4347 getTargetStreamer().emitDirectiveSetMips64R5();
4349 case Mips::FeatureMips64r6:
4350 selectArch(
"mips64r6");
4351 getTargetStreamer().emitDirectiveSetMips64R6();
4357 bool MipsAsmParser::eatComma(
StringRef ErrorStr) {
4360 SMLoc Loc = getLexer().getLoc();
4362 return Error(Loc, ErrorStr);
4369 bool MipsAsmParser::parseDirectiveCpLoad(
SMLoc Loc) {
4370 if (AssemblerOptions.back()->isReorder())
4371 Warning(Loc,
".cpload should be inside a noreorder section");
4373 if (inMips16Mode()) {
4374 reportParseError(
".cpload is not supported in Mips16 mode");
4379 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
4380 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4381 reportParseError(
"expected register containing function address");
4385 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*Reg[0]);
4386 if (!RegOpnd.isGPRAsmReg()) {
4387 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
4393 reportParseError(
"unexpected token, expected end of statement");
4397 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
4401 bool MipsAsmParser::parseDirectiveCPSetup() {
4405 bool SaveIsReg =
true;
4408 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4409 if (ResTy == MatchOperand_NoMatch) {
4410 reportParseError(
"expected register containing function address");
4415 MipsOperand &FuncRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
4416 if (!FuncRegOpnd.isGPRAsmReg()) {
4417 reportParseError(FuncRegOpnd.getStartLoc(),
"invalid register");
4422 FuncReg = FuncRegOpnd.getGPR32Reg();
4425 if (!eatComma(
"unexpected token, expected comma"))
4428 ResTy = parseAnyRegister(TmpReg);
4429 if (ResTy == MatchOperand_NoMatch) {
4436 reportParseError(
"expected save register or stack offset");
4441 MipsOperand &SaveOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
4442 if (!SaveOpnd.isGPRAsmReg()) {
4443 reportParseError(SaveOpnd.getStartLoc(),
"invalid register");
4447 Save = SaveOpnd.getGPR32Reg();
4450 if (!eatComma(
"unexpected token, expected comma"))
4455 reportParseError(
"expected expression");
4460 reportParseError(
"expected symbol");
4465 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->
getSymbol(),
4470 bool MipsAsmParser::parseDirectiveNaN() {
4477 getTargetStreamer().emitDirectiveNaN2008();
4479 }
else if (Tok.
getString() ==
"legacy") {
4481 getTargetStreamer().emitDirectiveNaNLegacy();
4487 reportParseError(
"invalid option in .nan directive");
4491 bool MipsAsmParser::parseDirectiveSet() {
4497 return parseSetNoAtDirective();
4499 return parseSetAtDirective();
4501 return parseSetArchDirective();
4503 return parseSetFpDirective();
4504 }
else if (Tok.
getString() ==
"oddspreg") {
4505 return parseSetOddSPRegDirective();
4506 }
else if (Tok.
getString() ==
"nooddspreg") {
4507 return parseSetNoOddSPRegDirective();
4509 return parseSetPopDirective();
4511 return parseSetPushDirective();
4512 }
else if (Tok.
getString() ==
"reorder") {
4513 return parseSetReorderDirective();
4514 }
else if (Tok.
getString() ==
"noreorder") {
4515 return parseSetNoReorderDirective();
4516 }
else if (Tok.
getString() ==
"macro") {
4517 return parseSetMacroDirective();
4518 }
else if (Tok.
getString() ==
"nomacro") {
4519 return parseSetNoMacroDirective();
4520 }
else if (Tok.
getString() ==
"mips16") {
4521 return parseSetMips16Directive();
4522 }
else if (Tok.
getString() ==
"nomips16") {
4523 return parseSetNoMips16Directive();
4524 }
else if (Tok.
getString() ==
"nomicromips") {
4525 getTargetStreamer().emitDirectiveSetNoMicroMips();
4528 }
else if (Tok.
getString() ==
"micromips") {
4529 return parseSetFeature(Mips::FeatureMicroMips);
4530 }
else if (Tok.
getString() ==
"mips0") {
4531 return parseSetMips0Directive();
4532 }
else if (Tok.
getString() ==
"mips1") {
4533 return parseSetFeature(Mips::FeatureMips1);
4534 }
else if (Tok.
getString() ==
"mips2") {
4535 return parseSetFeature(Mips::FeatureMips2);
4536 }
else if (Tok.
getString() ==
"mips3") {
4537 return parseSetFeature(Mips::FeatureMips3);
4538 }
else if (Tok.
getString() ==
"mips4") {
4539 return parseSetFeature(Mips::FeatureMips4);
4540 }
else if (Tok.
getString() ==
"mips5") {
4541 return parseSetFeature(Mips::FeatureMips5);
4542 }
else if (Tok.
getString() ==
"mips32") {
4543 return parseSetFeature(Mips::FeatureMips32);
4544 }
else if (Tok.
getString() ==
"mips32r2") {
4545 return parseSetFeature(Mips::FeatureMips32r2);
4546 }
else if (Tok.
getString() ==
"mips32r3") {
4547 return parseSetFeature(Mips::FeatureMips32r3);
4548 }
else if (Tok.
getString() ==
"mips32r5") {
4549 return parseSetFeature(Mips::FeatureMips32r5);
4550 }
else if (Tok.
getString() ==
"mips32r6") {
4551 return parseSetFeature(Mips::FeatureMips32r6);
4552 }
else if (Tok.
getString() ==
"mips64") {
4553 return parseSetFeature(Mips::FeatureMips64);
4554 }
else if (Tok.
getString() ==
"mips64r2") {
4555 return parseSetFeature(Mips::FeatureMips64r2);
4556 }
else if (Tok.
getString() ==
"mips64r3") {
4557 return parseSetFeature(Mips::FeatureMips64r3);
4558 }
else if (Tok.
getString() ==
"mips64r5") {
4559 return parseSetFeature(Mips::FeatureMips64r5);
4560 }
else if (Tok.
getString() ==
"mips64r6") {
4561 return parseSetFeature(Mips::FeatureMips64r6);
4563 return parseSetFeature(Mips::FeatureDSP);
4564 }
else if (Tok.
getString() ==
"nodsp") {
4565 return parseSetNoDspDirective();
4567 return parseSetMsaDirective();
4568 }
else if (Tok.
getString() ==
"nomsa") {
4569 return parseSetNoMsaDirective();
4570 }
else if (Tok.
getString() ==
"softfloat") {
4571 return parseSetSoftFloatDirective();
4572 }
else if (Tok.
getString() ==
"hardfloat") {
4573 return parseSetHardFloatDirective();
4576 parseSetAssignment();
4585 bool MipsAsmParser::parseDataDirective(
unsigned Size,
SMLoc L) {
4590 if (getParser().parseExpression(Value))
4593 getParser().getStreamer().EmitValue(Value, Size);
4599 return Error(L,
"unexpected token, expected comma");
4610 bool MipsAsmParser::parseDirectiveGpWord() {
4615 if (getParser().parseExpression(Value))
4617 getParser().getStreamer().EmitGPRel32Value(Value);
4620 return Error(getLexer().getLoc(),
4621 "unexpected token, expected end of statement");
4628 bool MipsAsmParser::parseDirectiveGpDWord() {
4633 if (getParser().parseExpression(Value))
4635 getParser().getStreamer().EmitGPRel64Value(Value);
4638 return Error(getLexer().getLoc(),
4639 "unexpected token, expected end of statement");
4644 bool MipsAsmParser::parseDirectiveOption() {
4657 if (Option ==
"pic0") {
4658 getTargetStreamer().emitDirectiveOptionPic0();
4662 "unexpected token, expected end of statement");
4668 if (Option ==
"pic2") {
4669 getTargetStreamer().emitDirectiveOptionPic2();
4673 "unexpected token, expected end of statement");
4681 "unknown option, expected 'pic0' or 'pic2'");
4688 bool MipsAsmParser::parseInsnDirective() {
4691 reportParseError(
"unexpected token, expected end of statement");
4697 getTargetStreamer().emitDirectiveInsn();
4709 bool MipsAsmParser::parseDirectiveModule() {
4714 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
4716 reportParseError(
".module directive must appear before any code");
4722 reportParseError(
"expected .module option identifier");
4726 if (Option ==
"oddspreg") {
4727 clearModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
4731 getTargetStreamer().updateABIInfo(*
this);
4736 getTargetStreamer().emitDirectiveModuleOddSPReg();
4740 reportParseError(
"unexpected token, expected end of statement");
4745 }
else if (Option ==
"nooddspreg") {
4747 Error(L,
"'.module nooddspreg' requires the O32 ABI");
4751 setModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
4755 getTargetStreamer().updateABIInfo(*
this);
4760 getTargetStreamer().emitDirectiveModuleOddSPReg();
4764 reportParseError(
"unexpected token, expected end of statement");
4769 }
else if (Option ==
"fp") {
4770 return parseDirectiveModuleFP();
4771 }
else if (Option ==
"softfloat") {
4772 setModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
4776 getTargetStreamer().updateABIInfo(*
this);
4781 getTargetStreamer().emitDirectiveModuleSoftFloat();
4785 reportParseError(
"unexpected token, expected end of statement");
4790 }
else if (Option ==
"hardfloat") {
4791 clearModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
4795 getTargetStreamer().updateABIInfo(*
this);
4800 getTargetStreamer().emitDirectiveModuleHardFloat();
4804 reportParseError(
"unexpected token, expected end of statement");
4810 return Error(L,
"'" +
Twine(Option) +
"' is not a valid .module option.");
4818 bool MipsAsmParser::parseDirectiveModuleFP() {
4823 reportParseError(
"unexpected token, expected equals sign '='");
4829 if (!parseFpABIValue(FpABI,
".module"))
4833 reportParseError(
"unexpected token, expected end of statement");
4839 getTargetStreamer().updateABIInfo(*
this);
4844 getTargetStreamer().emitDirectiveModuleFP();
4854 bool ModuleLevelOptions = Directive ==
".module";
4860 if (Value !=
"xx") {
4861 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
4866 reportParseError(
"'" + Directive +
" fp=xx' requires the O32 ABI");
4871 if (ModuleLevelOptions) {
4872 setModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
4873 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
4875 setFeatureBits(Mips::FeatureFPXX,
"fpxx");
4876 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
4885 if (Value != 32 && Value != 64) {
4886 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
4892 reportParseError(
"'" + Directive +
" fp=32' requires the O32 ABI");
4897 if (ModuleLevelOptions) {
4898 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
4899 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
4901 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
4902 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
4906 if (ModuleLevelOptions) {
4907 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
4908 setModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
4910 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
4911 setFeatureBits(Mips::FeatureFP64Bit,
"fp64");
4921 bool MipsAsmParser::ParseDirective(
AsmToken DirectiveID) {
4925 if (IDVal ==
".cpload")
4926 return parseDirectiveCpLoad(DirectiveID.
getLoc());
4927 if (IDVal ==
".dword") {
4928 parseDataDirective(8, DirectiveID.
getLoc());
4931 if (IDVal ==
".ent") {
4935 reportParseError(
"expected identifier after .ent");
4949 reportParseError(
"unexpected token, expected end of statement");
4953 const MCExpr *DummyNumber;
4954 int64_t DummyNumberVal;
4958 reportParseError(
"expected number after comma");
4961 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
4962 reportParseError(
"expected an absolute expression after comma");
4969 reportParseError(
"unexpected token, expected end of statement");
4973 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
4975 getTargetStreamer().emitDirectiveEnt(*Sym);
4980 if (IDVal ==
".end") {
4984 reportParseError(
"expected identifier after .end");
4989 reportParseError(
"unexpected token, expected end of statement");
4993 if (CurrentFn ==
nullptr) {
4994 reportParseError(
".end used without .ent");
4998 if ((SymbolName != CurrentFn->getName())) {
4999 reportParseError(
".end symbol does not match .ent symbol");
5003 getTargetStreamer().emitDirectiveEnd(SymbolName);
5004 CurrentFn =
nullptr;
5008 if (IDVal ==
".frame") {
5011 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5012 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5013 reportParseError(
"expected stack register");
5017 MipsOperand &StackRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
5018 if (!StackRegOpnd.isGPRAsmReg()) {
5019 reportParseError(StackRegOpnd.getStartLoc(),
5020 "expected general purpose register");
5023 unsigned StackReg = StackRegOpnd.getGPR32Reg();
5028 reportParseError(
"unexpected token, expected comma");
5034 int64_t FrameSizeVal;
5037 reportParseError(
"expected frame size value");
5041 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
5042 reportParseError(
"frame size not an absolute expression");
5049 reportParseError(
"unexpected token, expected comma");
5055 ResTy = parseAnyRegister(TmpReg);
5056 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5057 reportParseError(
"expected return register");
5061 MipsOperand &ReturnRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
5062 if (!ReturnRegOpnd.isGPRAsmReg()) {
5063 reportParseError(ReturnRegOpnd.getStartLoc(),
5064 "expected general purpose register");
5070 reportParseError(
"unexpected token, expected end of statement");
5074 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
5075 ReturnRegOpnd.getGPR32Reg());
5079 if (IDVal ==
".set") {
5080 return parseDirectiveSet();
5083 if (IDVal ==
".mask" || IDVal ==
".fmask") {
5098 reportParseError(
"expected bitmask value");
5102 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
5103 reportParseError(
"bitmask not an absolute expression");
5110 reportParseError(
"unexpected token, expected comma");
5115 const MCExpr *FrameOffset;
5116 int64_t FrameOffsetVal;
5119 reportParseError(
"expected frame offset value");
5123 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
5124 reportParseError(
"frame offset not an absolute expression");
5130 reportParseError(
"unexpected token, expected end of statement");
5134 if (IDVal ==
".mask")
5135 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
5137 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
5141 if (IDVal ==
".nan")
5142 return parseDirectiveNaN();
5144 if (IDVal ==
".gpword") {
5145 parseDirectiveGpWord();
5149 if (IDVal ==
".gpdword") {
5150 parseDirectiveGpDWord();
5154 if (IDVal ==
".word") {
5155 parseDataDirective(4, DirectiveID.
getLoc());
5159 if (IDVal ==
".option")
5160 return parseDirectiveOption();
5162 if (IDVal ==
".abicalls") {
5163 getTargetStreamer().emitDirectiveAbiCalls();
5166 "unexpected token, expected end of statement");
5173 if (IDVal ==
".cpsetup")
5174 return parseDirectiveCPSetup();
5176 if (IDVal ==
".module")
5177 return parseDirectiveModule();
5179 if (IDVal ==
".llvm_internal_mips_reallow_module_directive")
5180 return parseInternalDirectiveReallowModule();
5182 if (IDVal ==
".insn")
5183 return parseInsnDirective();
5188 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
5191 reportParseError(
"unexpected token, expected end of statement");
5195 getTargetStreamer().reallowModuleDirective();
5208 #define GET_REGISTER_MATCHER
5209 #define GET_MATCHER_IMPLEMENTATION
5210 #include "MipsGenAsmMatcher.inc"
static bool isReg(const MCInst &MI, unsigned OpNo)
bool isInt< 32 >(int64_t x)
std::enable_if< std::numeric_limits< T >::is_signed, bool >::type getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
Represents a range in source code.
void push_back(const T &Elt)
static ARMBaseTargetMachine::ARMABI computeTargetABI(const Triple &TT, StringRef CPU, const TargetOptions &Options)
static const MCUnaryExpr * create(Opcode Op, const MCExpr *Expr, MCContext &Ctx)
const MCSymbol & getSymbol() const
virtual const AsmToken peekTok(bool ShouldSkipSpace=true)=0
Look ahead at the next token to be lexed.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
const char * getPointer() const
size_t size() const
size - Get the string size.
TokenKind getKind() const
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Generic assembler parser interface, for use by target specific assembly parsers.
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
static MCOperand createExpr(const MCExpr *Val)
MCTargetAsmParser - Generic interface to target specific assembly parsers.
bool mayStore() const
Return true if this instruction could possibly modify memory.
Describe properties that are true of each instruction in the target description file.
Target specific streamer interface.
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
const FeatureBitset Features
StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
bool isNot(TokenKind K) const
SMLoc getLoc() const
Get the current source location.
static const MCInstrDesc & getInstDesc(unsigned Opcode)
StringSwitch & Case(const char(&S)[N], const T &Value)
virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
Reports a serious error, calling any installed error handler.
static const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static MCOperand createReg(unsigned Reg)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Generic assembler lexer interface, for use by target specific assembly lexers.
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 ...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static MCSymbolRefExpr::VariantKind getVariantKind(unsigned Flags)
const MCExpr * getVariableValue() const
getVariableValue() - Get the value for variable symbols.
bool isBranch() const
Returns true if this is a conditional, unconditional, or indirect branch.
bool isCall() const
Return true if the instruction is a call.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Base class for the full range of assembler expressions which are needed for parsing.
Reg
All possible values of the reg field in the ModR/M byte.
Target independent representation for an assembler token.
Represent a reference to a symbol from inside an expression.
Windows NT (Windows on ARM)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand...
This file implements a class to represent arbitrary precision integral constant values and operations...
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
uint8_t OperandType
Information about the type of the operand.
bool isNot(AsmToken::TokenKind K) const
Check if the current token has kind K.
unsigned getReg() const
Returns the register number.
const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Unary assembler expressions.
static bool processInstruction(Loop &L, Instruction &Inst, DominatorTree &DT, const SmallVectorImpl< BasicBlock * > &ExitBlocks, PredIteratorCache &PredCache, LoopInfo *LI)
Given an instruction in the loop, check to see if it has any uses that are outside the current loop...
int64_t getIntVal() const
const AsmToken & getTok() const
Get the current AsmToken from the stream.
Instances of this class represent a single low-level machine instruction.
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
const MCExpr * getExpr() const
A switch()-like statement whose cases are string literals.
Streaming machine code generation interface.
static bool isSupportedBinaryExpr(MCSymbolRefExpr::VariantKind VK, const MCBinaryExpr *BE)
BranchInst - Conditional or Unconditional Branch instruction.
Interface to description of machine instruction set.
virtual MCAsmLexer & getLexer()=0
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang","erlang-compatible garbage collector")
Represents a single fixit, a replacement of one range of text with another.
bool isIntN(unsigned N, int64_t x)
isIntN - Checks if an signed integer fits into the given (dynamic) bit width.
Binary assembler expressions.
bool is(AsmToken::TokenKind K) const
Check if the current token has kind K.
Triple - Helper class for working with autoconf configuration names.
static const MipsMCExpr * create(MCSymbolRefExpr::VariantKind VK, const MCExpr *Expr, MCContext &Ctx)
static unsigned getRegClass(bool IsVgpr, unsigned RegWidth)
void setOpcode(unsigned Op)
bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
SMRange getLocRange() const
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
bool mayLoad() const
Return true if this instruction could possibly read memory.
bool is(TokenKind K) const
void setVariableValue(const MCExpr *Value)
R Default(const T &Value) const
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
unsigned getOpcode() const
bool isUInt< 32 >(uint64_t x)
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
static SMLoc getFromPointer(const char *Ptr)
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string...
RegisterMCAsmParser - Helper template for registering a target specific assembly parser, for use in the target machine initialization function.
StringRef getName() const
getName - Get the symbol name.
int16_t RegClass
This specifies the register class enumeration of the operand if the operand is a register.
unsigned getNumOperands() const
MCSubtargetInfo - Generic base class for all target subtargets.
bool hasDelaySlot() const
Returns true if the specified instruction has a delay slot which must be filled by the code generator...
References to labels and assigned expressions.
static bool isMem(const MachineInstr *MI, unsigned Op)
bool isInt< 16 >(int64_t x)
const Triple & getTargetTriple() const
getTargetTriple - Return the target triple string.
static bool hasShortDelaySlot(unsigned Opcode)
const MCInstrDesc MipsInsts[]
bool isVariable() const
isVariable - Check if this is a variable symbol.
VariantKind getKind() const
char front() const
front - Get the first character in the string.
const ARM::ArchExtKind Kind
LLVM Value Representation.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
const MCOperandInfo * OpInfo
bool isUInt< 16 >(uint64_t x)
uint64_t OffsetToAlignment(uint64_t Value, uint64_t Align)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
This class implements an extremely fast bulk output stream that can only output to a stream...
void addOperand(const MCOperand &Op)
StringRef - Represent a constant reference to a string, i.e.
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents...
static FeatureBitset getFeatures(StringRef CPU, StringRef FS, ArrayRef< SubtargetFeatureKV > ProcDesc, ArrayRef< SubtargetFeatureKV > ProcFeatures)
Target specific expression.
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml","ocaml 3.10-compatible collector")
Represents a location in source code.
This holds information about one operand of a machine instruction, indicating the register class for ...
Instances of this class represent operands of the MCInst class.
static MCOperand createImm(int64_t Val)
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx)
const MCOperand & getOperand(unsigned i) const
void LLVMInitializeMipsAsmParser()
bool empty() const
empty - Check if the string is empty.