40 #define DEBUG_TYPE "mips-asm-parser"
47 class MipsAssemblerOptions {
52 MipsAssemblerOptions(
const MipsAssemblerOptions *Opts) {
53 ATReg = Opts->getATRegIndex();
54 Reorder = Opts->isReorder();
55 Macro = Opts->isMacro();
59 unsigned getATRegIndex()
const {
return ATReg; }
60 bool setATRegIndex(
unsigned Reg) {
68 bool isReorder()
const {
return Reorder; }
69 void setReorder() { Reorder =
true; }
70 void setNoReorder() { Reorder =
false; }
72 bool isMacro()
const {
return Macro; }
73 void setMacro() {
Macro =
true; }
74 void setNoMacro() {
Macro =
false; }
94 const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
95 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
96 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
97 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
98 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
99 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
100 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
101 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
102 Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008
122 unsigned CpSaveLocation;
124 bool CpSaveLocationIsRegister;
127 void printWarningWithFixIt(
const Twine &Msg,
const Twine &FixMsg,
128 SMRange Range,
bool ShowColors =
true);
130 #define GET_ASSEMBLER_HEADER
131 #include "MipsGenAsmMatcher.inc"
134 checkEarlyTargetMatchPredicate(
MCInst &Inst,
136 unsigned checkTargetMatchPredicate(
MCInst &Inst)
override;
138 bool MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
141 bool MatchingInlineAsm)
override;
144 bool ParseRegister(
unsigned &RegNo,
SMLoc &StartLoc,
SMLoc &EndLoc)
override;
153 bool ParseDirective(
AsmToken DirectiveID)
override;
173 enum MacroExpanderResultTy {
180 MacroExpanderResultTy tryExpandInstruction(
MCInst &Inst,
SMLoc IDLoc,
187 bool loadImmediate(int64_t ImmValue,
unsigned DstReg,
unsigned SrcReg,
188 bool Is32BitImm,
bool IsAddress,
SMLoc IDLoc,
191 bool loadAndAddSymbolAddress(
const MCExpr *SymExpr,
unsigned DstReg,
192 unsigned SrcReg,
bool Is32BitSym,
SMLoc IDLoc,
195 bool expandLoadImm(
MCInst &Inst,
bool Is32BitImm,
SMLoc IDLoc,
198 bool expandLoadAddress(
unsigned DstReg,
unsigned BaseReg,
231 bool expandTrunc(
MCInst &Inst,
bool IsDouble,
bool Is64FPU,
SMLoc IDLoc,
264 bool reportParseError(
Twine ErrorMsg);
265 bool reportParseError(
SMLoc Loc,
Twine ErrorMsg);
267 bool parseMemOffset(
const MCExpr *&Res,
bool isParenExpr);
269 bool isEvaluated(
const MCExpr *Expr);
270 bool parseSetMips0Directive();
271 bool parseSetArchDirective();
272 bool parseSetFeature(uint64_t Feature);
273 bool isPicAndNotNxxAbi();
274 bool parseDirectiveCpLoad(
SMLoc Loc);
275 bool parseDirectiveCpRestore(
SMLoc Loc);
276 bool parseDirectiveCPSetup();
277 bool parseDirectiveCPReturn();
278 bool parseDirectiveNaN();
279 bool parseDirectiveSet();
280 bool parseDirectiveOption();
281 bool parseInsnDirective();
284 bool parseSetAtDirective();
285 bool parseSetNoAtDirective();
286 bool parseSetMacroDirective();
287 bool parseSetNoMacroDirective();
288 bool parseSetMsaDirective();
289 bool parseSetNoMsaDirective();
290 bool parseSetNoDspDirective();
291 bool parseSetReorderDirective();
292 bool parseSetNoReorderDirective();
293 bool parseSetMips16Directive();
294 bool parseSetNoMips16Directive();
295 bool parseSetFpDirective();
296 bool parseSetOddSPRegDirective();
297 bool parseSetNoOddSPRegDirective();
298 bool parseSetPopDirective();
299 bool parseSetPushDirective();
300 bool parseSetSoftFloatDirective();
301 bool parseSetHardFloatDirective();
303 bool parseSetAssignment();
305 bool parseDataDirective(
unsigned Size,
SMLoc L);
306 bool parseDirectiveGpWord();
307 bool parseDirectiveGpDWord();
308 bool parseDirectiveDtpRelWord();
309 bool parseDirectiveDtpRelDWord();
310 bool parseDirectiveTpRelWord();
311 bool parseDirectiveTpRelDWord();
312 bool parseDirectiveModule();
313 bool parseDirectiveModuleFP();
317 bool parseInternalDirectiveReallowModule();
335 unsigned getReg(
int RC,
int RegNo);
340 unsigned getATReg(
SMLoc Loc);
348 bool validateMSAIndex(
int Val,
int RegKind);
375 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
377 setAvailableFeatures(
382 void setFeatureBits(uint64_t Feature,
StringRef FeatureString) {
383 if (!(getSTI().getFeatureBits()[Feature])) {
385 setAvailableFeatures(
391 void clearFeatureBits(uint64_t Feature,
StringRef FeatureString) {
392 if (getSTI().getFeatureBits()[Feature]) {
394 setAvailableFeatures(
400 void setModuleFeatureBits(uint64_t Feature,
StringRef FeatureString) {
401 setFeatureBits(Feature, FeatureString);
402 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
405 void clearModuleFeatureBits(uint64_t Feature,
StringRef FeatureString) {
406 clearFeatureBits(Feature, FeatureString);
407 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
411 enum MipsMatchResultTy {
412 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
413 Match_RequiresDifferentOperands,
414 Match_RequiresNoZeroRegister,
415 Match_RequiresSameSrcAndDst,
416 Match_NoFCCRegisterForCurrentISA,
417 Match_NonZeroOperandForSync,
418 #define GET_OPERAND_DIAGNOSTIC_TYPES
419 #include "MipsGenAsmMatcher.inc"
420 #undef GET_OPERAND_DIAGNOSTIC_TYPES
433 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
436 AssemblerOptions.push_back(
437 llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
440 AssemblerOptions.push_back(
441 llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
443 getTargetStreamer().updateABIInfo(*
this);
445 if (!isABI_O32() && !useOddSPReg() != 0)
450 IsPicEnabled = getContext().getObjectFileInfo()->isPositionIndependent();
452 IsCpRestoreSet =
false;
453 CpRestoreOffset = -1;
458 IsLittleEndian =
false;
460 IsLittleEndian =
true;
464 bool hasEightFccRegisters()
const {
return hasMips4() || hasMips32(); }
466 bool isGP64bit()
const {
467 return getSTI().getFeatureBits()[Mips::FeatureGP64Bit];
469 bool isFP64bit()
const {
470 return getSTI().getFeatureBits()[Mips::FeatureFP64Bit];
473 bool isABI_N32()
const {
return ABI.
IsN32(); }
474 bool isABI_N64()
const {
return ABI.IsN64(); }
475 bool isABI_O32()
const {
return ABI.IsO32(); }
476 bool isABI_FPXX()
const {
477 return getSTI().getFeatureBits()[Mips::FeatureFPXX];
480 bool useOddSPReg()
const {
481 return !(getSTI().getFeatureBits()[Mips::FeatureNoOddSPReg]);
484 bool inMicroMipsMode()
const {
485 return getSTI().getFeatureBits()[Mips::FeatureMicroMips];
487 bool hasMips1()
const {
488 return getSTI().getFeatureBits()[Mips::FeatureMips1];
490 bool hasMips2()
const {
491 return getSTI().getFeatureBits()[Mips::FeatureMips2];
493 bool hasMips3()
const {
494 return getSTI().getFeatureBits()[Mips::FeatureMips3];
496 bool hasMips4()
const {
497 return getSTI().getFeatureBits()[Mips::FeatureMips4];
499 bool hasMips5()
const {
500 return getSTI().getFeatureBits()[Mips::FeatureMips5];
502 bool hasMips32()
const {
503 return getSTI().getFeatureBits()[Mips::FeatureMips32];
505 bool hasMips64()
const {
506 return getSTI().getFeatureBits()[Mips::FeatureMips64];
508 bool hasMips32r2()
const {
509 return getSTI().getFeatureBits()[Mips::FeatureMips32r2];
511 bool hasMips64r2()
const {
512 return getSTI().getFeatureBits()[Mips::FeatureMips64r2];
514 bool hasMips32r3()
const {
515 return (getSTI().getFeatureBits()[Mips::FeatureMips32r3]);
517 bool hasMips64r3()
const {
518 return (getSTI().getFeatureBits()[Mips::FeatureMips64r3]);
520 bool hasMips32r5()
const {
521 return (getSTI().getFeatureBits()[Mips::FeatureMips32r5]);
523 bool hasMips64r5()
const {
524 return (getSTI().getFeatureBits()[Mips::FeatureMips64r5]);
526 bool hasMips32r6()
const {
527 return getSTI().getFeatureBits()[Mips::FeatureMips32r6];
529 bool hasMips64r6()
const {
530 return getSTI().getFeatureBits()[Mips::FeatureMips64r6];
533 bool hasDSP()
const {
534 return getSTI().getFeatureBits()[Mips::FeatureDSP];
536 bool hasDSPR2()
const {
537 return getSTI().getFeatureBits()[Mips::FeatureDSPR2];
539 bool hasDSPR3()
const {
540 return getSTI().getFeatureBits()[Mips::FeatureDSPR3];
542 bool hasMSA()
const {
543 return getSTI().getFeatureBits()[Mips::FeatureMSA];
545 bool hasCnMips()
const {
546 return (getSTI().getFeatureBits()[Mips::FeatureCnMips]);
553 bool inMips16Mode()
const {
554 return getSTI().getFeatureBits()[Mips::FeatureMips16];
557 bool useTraps()
const {
558 return getSTI().getFeatureBits()[Mips::FeatureUseTCCInDIV];
561 bool useSoftFloat()
const {
562 return getSTI().getFeatureBits()[Mips::FeatureSoftFloat];
566 void warnIfRegIndexIsAT(
unsigned RegIndex,
SMLoc Loc);
568 void warnIfNoMacro(
SMLoc Loc);
570 bool isLittle()
const {
return IsLittleEndian; }
575 switch(OperatorToken) {
646 RegKind_MSACtrl = 16,
651 RegKind_HWRegs = 256,
655 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
656 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
657 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
671 MipsOperand(KindTy K, MipsAsmParser &Parser)
676 MipsAsmParser &AsmParser;
705 struct RegIdxOp RegIdx;
708 struct RegListOp RegList;
711 SMLoc StartLoc, EndLoc;
714 static std::unique_ptr<MipsOperand> CreateReg(
unsigned Index,
StringRef Str,
718 MipsAsmParser &Parser) {
719 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
720 Op->RegIdx.Index = Index;
721 Op->RegIdx.RegInfo = RegInfo;
722 Op->RegIdx.Kind = RegKind;
723 Op->RegIdx.Tok.Data = Str.
data();
724 Op->RegIdx.Tok.Length = Str.
size();
733 unsigned getGPR32Reg()
const {
734 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
735 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
736 unsigned ClassID = Mips::GPR32RegClassID;
737 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
742 unsigned getGPRMM16Reg()
const {
743 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
744 unsigned ClassID = Mips::GPR32RegClassID;
745 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
750 unsigned getGPR64Reg()
const {
751 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
752 unsigned ClassID = Mips::GPR64RegClassID;
753 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
759 unsigned getAFGR64Reg()
const {
760 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
761 if (RegIdx.Index % 2 != 0)
762 AsmParser.Warning(StartLoc,
"Float register should be even.");
763 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
764 .getRegister(RegIdx.Index / 2);
769 unsigned getFGR64Reg()
const {
770 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
771 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
772 .getRegister(RegIdx.Index);
777 unsigned getFGR32Reg()
const {
778 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
779 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
780 .getRegister(RegIdx.Index);
785 unsigned getFGRH32Reg()
const {
786 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
787 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
788 .getRegister(RegIdx.Index);
793 unsigned getFCCReg()
const {
794 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) &&
"Invalid access!");
795 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
796 .getRegister(RegIdx.Index);
801 unsigned getMSA128Reg()
const {
802 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) &&
"Invalid access!");
805 unsigned ClassID = Mips::MSA128BRegClassID;
806 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
811 unsigned getMSACtrlReg()
const {
812 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) &&
"Invalid access!");
813 unsigned ClassID = Mips::MSACtrlRegClassID;
814 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
819 unsigned getCOP0Reg()
const {
820 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) &&
"Invalid access!");
821 unsigned ClassID = Mips::COP0RegClassID;
822 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
827 unsigned getCOP2Reg()
const {
828 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) &&
"Invalid access!");
829 unsigned ClassID = Mips::COP2RegClassID;
830 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
835 unsigned getCOP3Reg()
const {
836 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) &&
"Invalid access!");
837 unsigned ClassID = Mips::COP3RegClassID;
838 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
843 unsigned getACC64DSPReg()
const {
844 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
845 unsigned ClassID = Mips::ACC64DSPRegClassID;
846 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
851 unsigned getHI32DSPReg()
const {
852 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
853 unsigned ClassID = Mips::HI32DSPRegClassID;
854 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
859 unsigned getLO32DSPReg()
const {
860 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
861 unsigned ClassID = Mips::LO32DSPRegClassID;
862 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
867 unsigned getCCRReg()
const {
868 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) &&
"Invalid access!");
869 unsigned ClassID = Mips::CCRRegClassID;
870 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
875 unsigned getHWRegsReg()
const {
876 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) &&
"Invalid access!");
877 unsigned ClassID = Mips::HWRegsRegClassID;
878 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
886 else if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
892 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
899 void addGPR32AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
900 assert(N == 1 &&
"Invalid number of operands!");
904 void addGPRMM16AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
905 assert(N == 1 &&
"Invalid number of operands!");
909 void addGPRMM16AsmRegZeroOperands(
MCInst &Inst,
unsigned N)
const {
910 assert(N == 1 &&
"Invalid number of operands!");
914 void addGPRMM16AsmRegMovePOperands(
MCInst &Inst,
unsigned N)
const {
915 assert(N == 1 &&
"Invalid number of operands!");
922 void addGPR64AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
923 assert(N == 1 &&
"Invalid number of operands!");
927 void addAFGR64AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
928 assert(N == 1 &&
"Invalid number of operands!");
932 void addFGR64AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
933 assert(N == 1 &&
"Invalid number of operands!");
937 void addFGR32AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
938 assert(N == 1 &&
"Invalid number of operands!");
942 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
943 AsmParser.getParser().printError(
944 StartLoc,
"-mno-odd-spreg prohibits the use of odd FPU "
948 void addFGRH32AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
949 assert(N == 1 &&
"Invalid number of operands!");
953 void addFCCAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
954 assert(N == 1 &&
"Invalid number of operands!");
958 void addMSA128AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
959 assert(N == 1 &&
"Invalid number of operands!");
963 void addMSACtrlAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
964 assert(N == 1 &&
"Invalid number of operands!");
968 void addCOP0AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
969 assert(N == 1 &&
"Invalid number of operands!");
973 void addCOP2AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
974 assert(N == 1 &&
"Invalid number of operands!");
978 void addCOP3AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
979 assert(N == 1 &&
"Invalid number of operands!");
983 void addACC64DSPAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
984 assert(N == 1 &&
"Invalid number of operands!");
988 void addHI32DSPAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
989 assert(N == 1 &&
"Invalid number of operands!");
993 void addLO32DSPAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
994 assert(N == 1 &&
"Invalid number of operands!");
998 void addCCRAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
999 assert(N == 1 &&
"Invalid number of operands!");
1003 void addHWRegsAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1004 assert(N == 1 &&
"Invalid number of operands!");
1008 template <
unsigned Bits,
int Offset = 0,
int AdjustOffset = 0>
1009 void addConstantUImmOperands(
MCInst &Inst,
unsigned N)
const {
1010 assert(N == 1 &&
"Invalid number of operands!");
1011 uint64_t Imm = getConstantImm() -
Offset;
1012 Imm &= (1ULL <<
Bits) - 1;
1014 Imm += AdjustOffset;
1018 template <
unsigned Bits>
1019 void addSImmOperands(
MCInst &Inst,
unsigned N)
const {
1020 if (isImm() && !isConstantImm()) {
1021 addExpr(Inst, getImm());
1024 addConstantSImmOperands<Bits, 0, 0>(Inst,
N);
1027 template <
unsigned Bits>
1028 void addUImmOperands(
MCInst &Inst,
unsigned N)
const {
1029 if (isImm() && !isConstantImm()) {
1030 addExpr(Inst, getImm());
1033 addConstantUImmOperands<Bits, 0, 0>(Inst,
N);
1036 template <
unsigned Bits,
int Offset = 0,
int AdjustOffset = 0>
1037 void addConstantSImmOperands(
MCInst &Inst,
unsigned N)
const {
1038 assert(N == 1 &&
"Invalid number of operands!");
1039 int64_t Imm = getConstantImm() -
Offset;
1040 Imm = SignExtend64<Bits>(Imm);
1042 Imm += AdjustOffset;
1046 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
1047 assert(N == 1 &&
"Invalid number of operands!");
1048 const MCExpr *Expr = getImm();
1049 addExpr(Inst, Expr);
1052 void addMemOperands(
MCInst &Inst,
unsigned N)
const {
1053 assert(N == 2 &&
"Invalid number of operands!");
1056 ? getMemBase()->getGPR64Reg()
1057 : getMemBase()->getGPR32Reg()));
1059 const MCExpr *Expr = getMemOff();
1060 addExpr(Inst, Expr);
1063 void addMicroMipsMemOperands(
MCInst &Inst,
unsigned N)
const {
1064 assert(N == 2 &&
"Invalid number of operands!");
1068 const MCExpr *Expr = getMemOff();
1069 addExpr(Inst, Expr);
1072 void addRegListOperands(
MCInst &Inst,
unsigned N)
const {
1073 assert(N == 1 &&
"Invalid number of operands!");
1075 for (
auto RegNo : getRegList())
1079 void addRegPairOperands(
MCInst &Inst,
unsigned N)
const {
1080 assert(N == 2 &&
"Invalid number of operands!");
1081 assert((RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
1082 unsigned RegNo = getRegPair();
1083 AsmParser.warnIfRegIndexIsAT(RegNo, StartLoc);
1085 RegIdx.RegInfo->getRegClass(
1086 AsmParser.getABI().AreGprs64bit()
1087 ? Mips::GPR64RegClassID
1088 : Mips::GPR32RegClassID).getRegister(RegNo++)));
1090 RegIdx.RegInfo->getRegClass(
1091 AsmParser.getABI().AreGprs64bit()
1092 ? Mips::GPR64RegClassID
1093 : Mips::GPR32RegClassID).getRegister(RegNo)));
1096 void addMovePRegPairOperands(
MCInst &Inst,
unsigned N)
const {
1097 assert(N == 2 &&
"Invalid number of operands!");
1098 for (
auto RegNo : getRegList())
1102 bool isReg()
const override {
1105 return isGPRAsmReg() && RegIdx.Index == 0;
1107 bool isRegIdx()
const {
return Kind == k_RegisterIndex; }
1108 bool isImm()
const override {
return Kind == k_Immediate; }
1109 bool isConstantImm()
const {
1111 return isImm() && getImm()->evaluateAsAbsolute(Res);
1113 bool isConstantImmz()
const {
1114 return isConstantImm() && getConstantImm() == 0;
1116 template <
unsigned Bits,
int Offset = 0>
bool isConstantUImm()
const {
1117 return isConstantImm() && isUInt<Bits>(getConstantImm() -
Offset);
1119 template <
unsigned Bits>
bool isSImm()
const {
1120 return isConstantImm() ? isInt<Bits>(getConstantImm()) : isImm();
1122 template <
unsigned Bits>
bool isUImm()
const {
1123 return isConstantImm() ? isUInt<Bits>(getConstantImm()) : isImm();
1125 template <
unsigned Bits>
bool isAnyImm()
const {
1126 return isConstantImm() ? (isInt<Bits>(getConstantImm()) ||
1127 isUInt<Bits>(getConstantImm()))
1130 template <
unsigned Bits,
int Offset = 0>
bool isConstantSImm()
const {
1131 return isConstantImm() && isInt<Bits>(getConstantImm() -
Offset);
1133 template <
unsigned Bottom,
unsigned Top>
bool isConstantUImmRange()
const {
1134 return isConstantImm() && getConstantImm() >= Bottom &&
1135 getConstantImm() <= Top;
1137 bool isToken()
const override {
1140 return Kind == k_Token;
1142 bool isMem()
const override {
return Kind == k_Memory; }
1143 bool isConstantMemOff()
const {
1144 return isMem() && isa<MCConstantExpr>(getMemOff());
1149 template <
unsigned Bits,
unsigned ShiftAmount = 0>
1150 bool isMemWithSimmOffset()
const {
1153 if (!getMemBase()->isGPRAsmReg())
1155 if (isa<MCTargetExpr>(getMemOff()) ||
1156 (isConstantMemOff() &&
1157 isShiftedInt<Bits, ShiftAmount>(getConstantMemOff())))
1160 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res,
nullptr,
nullptr);
1161 return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.
getConstant());
1163 bool isMemWithGRPMM16Base()
const {
1164 return isMem() && getMemBase()->isMM16AsmReg();
1166 template <
unsigned Bits>
bool isMemWithUimmOffsetSP()
const {
1167 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1168 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1170 template <
unsigned Bits>
bool isMemWithUimmWordAlignedOffsetSP()
const {
1171 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1172 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1173 && (getMemBase()->getGPR32Reg() == Mips::SP);
1175 template <
unsigned Bits>
bool isMemWithSimmWordAlignedOffsetGP()
const {
1176 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
1177 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1178 && (getMemBase()->getGPR32Reg() == Mips::GP);
1180 template <
unsigned Bits,
unsigned ShiftLeftAmount>
1181 bool isScaledUImm()
const {
1182 return isConstantImm() &&
1183 isShiftedUInt<Bits, ShiftLeftAmount>(getConstantImm());
1185 template <
unsigned Bits,
unsigned ShiftLeftAmount>
1186 bool isScaledSImm()
const {
1187 if (isConstantImm() && isShiftedInt<Bits, ShiftLeftAmount>(getConstantImm()))
1190 if (
Kind != k_Immediate)
1193 bool Success = getImm()->evaluateAsRelocatable(Res,
nullptr,
nullptr);
1194 return Success && isShiftedInt<Bits, ShiftLeftAmount>(Res.
getConstant());
1196 bool isRegList16()
const {
1200 int Size = RegList.List->size();
1201 if (Size < 2 || Size > 5)
1204 unsigned R0 = RegList.List->front();
1205 unsigned R1 = RegList.List->back();
1206 if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1207 (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1210 int PrevReg = *RegList.List->begin();
1211 for (
int i = 1;
i < Size - 1;
i++) {
1212 int Reg = (*(RegList.List))[
i];
1213 if ( Reg != PrevReg + 1)
1220 bool isInvNum()
const {
return Kind == k_Immediate; }
1221 bool isLSAImm()
const {
1222 if (!isConstantImm())
1224 int64_t Val = getConstantImm();
1225 return 1 <= Val && Val <= 4;
1227 bool isRegList()
const {
return Kind == k_RegList; }
1228 bool isMovePRegPair()
const {
1229 if (
Kind != k_RegList || RegList.List->size() != 2)
1232 unsigned R0 = RegList.List->front();
1233 unsigned R1 = RegList.List->back();
1235 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
1236 (R0 == Mips::A1 && R1 == Mips::A3) ||
1237 (R0 == Mips::A2 && R1 == Mips::A3) ||
1238 (R0 == Mips::A0 && R1 == Mips::S5) ||
1239 (R0 == Mips::A0 && R1 == Mips::S6) ||
1240 (R0 == Mips::A0 && R1 == Mips::A1) ||
1241 (R0 == Mips::A0 && R1 == Mips::A2) ||
1242 (R0 == Mips::A0 && R1 == Mips::A3) ||
1243 (R0 == Mips::A1_64 && R1 == Mips::A2_64) ||
1244 (R0 == Mips::A1_64 && R1 == Mips::A3_64) ||
1245 (R0 == Mips::A2_64 && R1 == Mips::A3_64) ||
1246 (R0 == Mips::A0_64 && R1 == Mips::S5_64) ||
1247 (R0 == Mips::A0_64 && R1 == Mips::S6_64) ||
1248 (R0 == Mips::A0_64 && R1 == Mips::A1_64) ||
1249 (R0 == Mips::A0_64 && R1 == Mips::A2_64) ||
1250 (R0 == Mips::A0_64 && R1 == Mips::A3_64))
1257 assert(
Kind == k_Token &&
"Invalid access!");
1260 bool isRegPair()
const {
1261 return Kind == k_RegPair && RegIdx.Index <= 30;
1264 unsigned getReg()
const override {
1267 if (
Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1268 RegIdx.Kind & RegKind_GPR)
1269 return getGPR32Reg();
1275 const MCExpr *getImm()
const {
1276 assert((
Kind == k_Immediate) &&
"Invalid access!");
1280 int64_t getConstantImm()
const {
1281 const MCExpr *Val = getImm();
1283 (void)Val->evaluateAsAbsolute(Value);
1287 MipsOperand *getMemBase()
const {
1288 assert((
Kind == k_Memory) &&
"Invalid access!");
1292 const MCExpr *getMemOff()
const {
1293 assert((
Kind == k_Memory) &&
"Invalid access!");
1297 int64_t getConstantMemOff()
const {
1298 return static_cast<const MCConstantExpr *
>(getMemOff())->getValue();
1302 assert((
Kind == k_RegList) &&
"Invalid access!");
1303 return *(RegList.List);
1306 unsigned getRegPair()
const {
1307 assert((
Kind == k_RegPair) &&
"Invalid access!");
1308 return RegIdx.Index;
1311 static std::unique_ptr<MipsOperand> CreateToken(
StringRef Str,
SMLoc S,
1312 MipsAsmParser &Parser) {
1313 auto Op = make_unique<MipsOperand>(k_Token, Parser);
1314 Op->Tok.Data = Str.
data();
1315 Op->Tok.Length = Str.
size();
1323 static std::unique_ptr<MipsOperand>
1326 DEBUG(
dbgs() <<
"createNumericReg(" << Index <<
", ...)\n");
1327 return CreateReg(Index, Str, RegKind_Numeric, RegInfo, S, E, Parser);
1332 static std::unique_ptr<MipsOperand>
1335 return CreateReg(Index, Str, RegKind_GPR, RegInfo, S, E, Parser);
1340 static std::unique_ptr<MipsOperand>
1343 return CreateReg(Index, Str, RegKind_FGR, RegInfo, S, E, Parser);
1348 static std::unique_ptr<MipsOperand>
1351 return CreateReg(Index, Str, RegKind_HWRegs, RegInfo, S, E, Parser);
1356 static std::unique_ptr<MipsOperand>
1359 return CreateReg(Index, Str, RegKind_FCC, RegInfo, S, E, Parser);
1364 static std::unique_ptr<MipsOperand>
1367 return CreateReg(Index, Str, RegKind_ACC, RegInfo, S, E, Parser);
1372 static std::unique_ptr<MipsOperand>
1375 return CreateReg(Index, Str, RegKind_MSA128, RegInfo, S, E, Parser);
1380 static std::unique_ptr<MipsOperand>
1383 return CreateReg(Index, Str, RegKind_MSACtrl, RegInfo, S, E, Parser);
1386 static std::unique_ptr<MipsOperand>
1388 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1395 static std::unique_ptr<MipsOperand>
1396 CreateMem(std::unique_ptr<MipsOperand> Base,
const MCExpr *Off,
SMLoc S,
1397 SMLoc E, MipsAsmParser &Parser) {
1398 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1399 Op->Mem.Base = Base.release();
1406 static std::unique_ptr<MipsOperand>
1408 MipsAsmParser &Parser) {
1409 assert (Regs.
size() > 0 &&
"Empty list not allowed");
1411 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1413 Op->StartLoc = StartLoc;
1414 Op->EndLoc = EndLoc;
1418 static std::unique_ptr<MipsOperand> CreateRegPair(
const MipsOperand &MOP,
1420 MipsAsmParser &Parser) {
1421 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1422 Op->RegIdx.Index = MOP.RegIdx.Index;
1423 Op->RegIdx.RegInfo = MOP.RegIdx.RegInfo;
1424 Op->RegIdx.Kind = MOP.RegIdx.Kind;
1430 bool isGPRAsmReg()
const {
1431 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1433 bool isMM16AsmReg()
const {
1434 if (!(isRegIdx() && RegIdx.Kind))
1436 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1437 || RegIdx.Index == 16 || RegIdx.Index == 17);
1439 bool isMM16AsmRegZero()
const {
1440 if (!(isRegIdx() && RegIdx.Kind))
1442 return (RegIdx.Index == 0 ||
1443 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1444 RegIdx.Index == 17);
1446 bool isMM16AsmRegMoveP()
const {
1447 if (!(isRegIdx() && RegIdx.Kind))
1449 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1450 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1452 bool isFGRAsmReg()
const {
1454 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1456 bool isHWRegsAsmReg()
const {
1457 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1459 bool isCCRAsmReg()
const {
1460 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1462 bool isFCCAsmReg()
const {
1463 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1465 return RegIdx.Index <= 7;
1467 bool isACCAsmReg()
const {
1468 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1470 bool isCOP0AsmReg()
const {
1471 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1473 bool isCOP2AsmReg()
const {
1474 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1476 bool isCOP3AsmReg()
const {
1477 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1479 bool isMSA128AsmReg()
const {
1480 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1482 bool isMSACtrlAsmReg()
const {
1483 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1487 SMLoc getStartLoc()
const override {
return StartLoc; }
1489 SMLoc getEndLoc()
const override {
return EndLoc; }
1491 virtual ~MipsOperand() {
1499 delete RegList.List;
1500 case k_RegisterIndex:
1516 Mem.Base->print(OS);
1521 case k_RegisterIndex:
1522 OS <<
"RegIdx<" << RegIdx.Index <<
":" << RegIdx.Kind <<
", "
1523 <<
StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) <<
">";
1530 for (
auto Reg : (*RegList.List))
1535 OS <<
"RegPair<" << RegIdx.Index <<
"," << RegIdx.Index + 1 <<
">";
1540 bool isValidForTie(
const MipsOperand &
Other)
const {
1541 if (
Kind != Other.Kind)
1548 case k_RegisterIndex: {
1550 StringRef OtherToken(Other.RegIdx.Tok.Data, Other.RegIdx.Tok.Length);
1551 return Token == OtherToken;
1568 case Mips::JALRS_MM:
1569 case Mips::JALRS16_MM:
1570 case Mips::BGEZALS_MM:
1571 case Mips::BLTZALS_MM:
1579 if (
const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1580 return &SRExpr->getSymbol();
1583 if (
const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1596 if (
const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1603 if (isa<MCSymbolRefExpr>(Expr))
1606 if (
const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1610 if (
const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1616 bool MipsAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
1621 bool ExpandedJalSym =
false;
1626 const unsigned Opcode = Inst.
getOpcode();
1636 assert(hasCnMips() &&
"instruction only valid for octeon cpus");
1645 if (!Offset.isImm())
1647 if (!
isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1648 return Error(IDLoc,
"branch target out of range");
1650 1LL << (inMicroMipsMode() ? 1 : 2)))
1651 return Error(IDLoc,
"branch to misaligned address");
1665 case Mips::BGEZAL_MM:
1666 case Mips::BLTZAL_MM:
1669 case Mips::BC1EQZC_MMR6:
1670 case Mips::BC1NEZC_MMR6:
1671 case Mips::BC2EQZC_MMR6:
1672 case Mips::BC2NEZC_MMR6:
1675 if (!Offset.isImm())
1677 if (!
isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1678 return Error(IDLoc,
"branch target out of range");
1680 1LL << (inMicroMipsMode() ? 1 : 2)))
1681 return Error(IDLoc,
"branch to misaligned address");
1683 case Mips::BGEC:
case Mips::BGEC_MMR6:
1684 case Mips::BLTC:
case Mips::BLTC_MMR6:
1685 case Mips::BGEUC:
case Mips::BGEUC_MMR6:
1686 case Mips::BLTUC:
case Mips::BLTUC_MMR6:
1687 case Mips::BEQC:
case Mips::BEQC_MMR6:
1688 case Mips::BNEC:
case Mips::BNEC_MMR6:
1691 if (!Offset.isImm())
1693 if (!
isIntN(18, Offset.getImm()))
1694 return Error(IDLoc,
"branch target out of range");
1696 return Error(IDLoc,
"branch to misaligned address");
1698 case Mips::BLEZC:
case Mips::BLEZC_MMR6:
1699 case Mips::BGEZC:
case Mips::BGEZC_MMR6:
1700 case Mips::BGTZC:
case Mips::BGTZC_MMR6:
1701 case Mips::BLTZC:
case Mips::BLTZC_MMR6:
1704 if (!Offset.isImm())
1706 if (!
isIntN(18, Offset.getImm()))
1707 return Error(IDLoc,
"branch target out of range");
1709 return Error(IDLoc,
"branch to misaligned address");
1711 case Mips::BEQZC:
case Mips::BEQZC_MMR6:
1712 case Mips::BNEZC:
case Mips::BNEZC_MMR6:
1715 if (!Offset.isImm())
1717 if (!
isIntN(23, Offset.getImm()))
1718 return Error(IDLoc,
"branch target out of range");
1720 return Error(IDLoc,
"branch to misaligned address");
1722 case Mips::BEQZ16_MM:
1723 case Mips::BEQZC16_MMR6:
1724 case Mips::BNEZ16_MM:
1725 case Mips::BNEZC16_MMR6:
1728 if (!Offset.isImm())
1731 return Error(IDLoc,
"branch target out of range");
1733 return Error(IDLoc,
"branch to misaligned address");
1740 if (hasMips32r6() && Inst.
getOpcode() == Mips::SSNOP) {
1741 std::string ISA = hasMips64r6() ?
"MIPS64r6" :
"MIPS32r6";
1742 Warning(IDLoc,
"ssnop is deprecated for " + ISA +
" and is equivalent to a "
1747 const unsigned Opcode = Inst.
getOpcode();
1763 return Error(IDLoc,
"expected immediate operand kind");
1764 Imm = Opnd.getImm();
1765 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1766 Opcode == Mips::BBIT1 ? 63 : 31))
1767 return Error(IDLoc,
"immediate operand value out of range");
1769 Inst.
setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1780 return Error(IDLoc,
"expected immediate operand kind");
1781 Imm = Opnd.getImm();
1782 if (!isInt<10>(Imm))
1783 return Error(IDLoc,
"immediate operand value out of range");
1792 BInst.
setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
1803 warnIfNoMacro(IDLoc);
1810 return Error(IDLoc,
"jal doesn't support multiple symbols in PIC mode");
1828 const MCExpr *Got16RelocExpr =
1830 const MCExpr *Lo16RelocExpr =
1833 TOut.
emitRRX(Mips::LW, Mips::T9, Mips::GP,
1835 TOut.
emitRRX(Mips::ADDiu, Mips::T9, Mips::T9,
1837 }
else if (isABI_N32() || isABI_N64()) {
1843 const MCExpr *GotDispRelocExpr =
1855 const MCExpr *Call16RelocExpr =
1858 TOut.
emitRRX(ABI.ArePtrs64bit() ?
Mips::LD : Mips::LW, Mips::T9, Mips::GP,
1863 if (IsCpRestoreSet && inMicroMipsMode())
1866 JalrInst.
setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1875 ExpandedJalSym =
true;
1888 int MemOffset = Op.
getImm();
1889 if (MemOffset < -32768 || MemOffset > 32767) {
1891 expandMemInst(Inst, IDLoc, Out, STI, MCID.
mayLoad(),
true);
1892 return getParser().hasPendingError();
1894 }
else if (Op.
isExpr()) {
1901 expandMemInst(Inst, IDLoc, Out, STI, MCID.
mayLoad(),
false);
1902 return getParser().hasPendingError();
1904 }
else if (!isEvaluated(Expr)) {
1905 expandMemInst(Inst, IDLoc, Out, STI, MCID.
mayLoad(),
false);
1906 return getParser().hasPendingError();
1913 if (inMicroMipsMode()) {
1922 int MemOffset = Op.
getImm();
1925 if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
1928 (BaseReg.
getReg() == Mips::GP ||
1929 BaseReg.
getReg() == Mips::GP_64)) {
1931 TOut.
emitRRI(Mips::LWGP_MM, DstReg.
getReg(), Mips::GP, MemOffset,
1948 case Mips::ADDIUSP_MM:
1951 return Error(IDLoc,
"expected immediate operand kind");
1953 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1955 return Error(IDLoc,
"immediate operand value out of range");
1957 case Mips::SLL16_MM:
1958 case Mips::SRL16_MM:
1961 return Error(IDLoc,
"expected immediate operand kind");
1963 if (Imm < 1 || Imm > 8)
1964 return Error(IDLoc,
"immediate operand value out of range");
1969 return Error(IDLoc,
"expected immediate operand kind");
1971 if (Imm < -1 || Imm > 126)
1972 return Error(IDLoc,
"immediate operand value out of range");
1974 case Mips::ADDIUR2_MM:
1977 return Error(IDLoc,
"expected immediate operand kind");
1979 if (!(Imm == 1 || Imm == -1 ||
1980 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1981 return Error(IDLoc,
"immediate operand value out of range");
1983 case Mips::ANDI16_MM:
1986 return Error(IDLoc,
"expected immediate operand kind");
1988 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1989 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1990 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1991 return Error(IDLoc,
"immediate operand value out of range");
1993 case Mips::LBU16_MM:
1996 return Error(IDLoc,
"expected immediate operand kind");
1998 if (Imm < -1 || Imm > 14)
1999 return Error(IDLoc,
"immediate operand value out of range");
2002 case Mips::SB16_MMR6:
2005 return Error(IDLoc,
"expected immediate operand kind");
2007 if (Imm < 0 || Imm > 15)
2008 return Error(IDLoc,
"immediate operand value out of range");
2010 case Mips::LHU16_MM:
2012 case Mips::SH16_MMR6:
2015 return Error(IDLoc,
"expected immediate operand kind");
2017 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
2018 return Error(IDLoc,
"immediate operand value out of range");
2022 case Mips::SW16_MMR6:
2025 return Error(IDLoc,
"expected immediate operand kind");
2027 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
2028 return Error(IDLoc,
"immediate operand value out of range");
2030 case Mips::ADDIUPC_MM:
2033 return Error(IDLoc,
"expected immediate operand kind");
2035 if ((Imm % 4 != 0) || !isInt<25>(Imm))
2036 return Error(IDLoc,
"immediate operand value out of range");
2041 bool FillDelaySlot =
2042 MCID.
hasDelaySlot() && AssemblerOptions.back()->isReorder();
2046 MacroExpanderResultTy ExpandResult =
2047 tryExpandInstruction(Inst, IDLoc, Out, STI);
2048 switch (ExpandResult) {
2060 if (inMicroMipsMode())
2065 if (FillDelaySlot) {
2070 if ((Inst.
getOpcode() == Mips::JalOneReg ||
2071 Inst.
getOpcode() == Mips::JalTwoReg || ExpandedJalSym) &&
2072 isPicAndNotNxxAbi()) {
2073 if (IsCpRestoreSet) {
2077 if (!AssemblerOptions.back()->isReorder())
2084 Warning(IDLoc,
"no .cprestore used in PIC mode");
2090 MipsAsmParser::MacroExpanderResultTy
2095 return MER_NotAMacro;
2096 case Mips::LoadImm32:
2097 return expandLoadImm(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2098 case Mips::LoadImm64:
2099 return expandLoadImm(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2100 case Mips::LoadAddrImm32:
2101 case Mips::LoadAddrImm64:
2104 "expected immediate operand kind");
2108 Inst.
getOpcode() == Mips::LoadAddrImm32, IDLoc,
2112 case Mips::LoadAddrReg32:
2113 case Mips::LoadAddrReg64:
2117 "expected immediate operand kind");
2121 Inst.
getOpcode() == Mips::LoadAddrReg32, IDLoc,
2125 case Mips::B_MM_Pseudo:
2126 case Mips::B_MMR6_Pseudo:
2127 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2131 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2133 case Mips::JalOneReg:
2134 case Mips::JalTwoReg:
2135 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2138 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2155 case Mips::BLTImmMacro:
2156 case Mips::BLEImmMacro:
2157 case Mips::BGEImmMacro:
2158 case Mips::BGTImmMacro:
2159 case Mips::BLTUImmMacro:
2160 case Mips::BLEUImmMacro:
2161 case Mips::BGEUImmMacro:
2162 case Mips::BGTUImmMacro:
2163 case Mips::BLTLImmMacro:
2164 case Mips::BLELImmMacro:
2165 case Mips::BGELImmMacro:
2166 case Mips::BGTLImmMacro:
2167 case Mips::BLTULImmMacro:
2168 case Mips::BLEULImmMacro:
2169 case Mips::BGEULImmMacro:
2170 case Mips::BGTULImmMacro:
2171 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2172 case Mips::SDivMacro:
2173 return expandDiv(Inst, IDLoc, Out, STI,
false,
true) ? MER_Fail
2175 case Mips::DSDivMacro:
2176 return expandDiv(Inst, IDLoc, Out, STI,
true,
true) ? MER_Fail
2178 case Mips::UDivMacro:
2179 return expandDiv(Inst, IDLoc, Out, STI,
false,
false) ? MER_Fail
2181 case Mips::DUDivMacro:
2182 return expandDiv(Inst, IDLoc, Out, STI,
true,
false) ? MER_Fail
2184 case Mips::PseudoTRUNC_W_S:
2185 return expandTrunc(Inst,
false,
false, IDLoc, Out, STI) ? MER_Fail
2187 case Mips::PseudoTRUNC_W_D32:
2188 return expandTrunc(Inst,
true,
false, IDLoc, Out, STI) ? MER_Fail
2190 case Mips::PseudoTRUNC_W_D:
2191 return expandTrunc(Inst,
true,
true, IDLoc, Out, STI) ? MER_Fail
2194 return expandUlh(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2196 return expandUlh(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2198 return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2201 return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2203 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2212 return MER_NotAMacro;
2213 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2216 return MER_NotAMacro;
2224 return MER_NotAMacro;
2225 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2228 return MER_NotAMacro;
2231 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2234 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2237 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2240 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2241 case Mips::ABSMacro:
2242 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2245 return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2249 case Mips::SEQMacro:
2250 return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2251 case Mips::SEQIMacro:
2252 return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2256 bool MipsAsmParser::expandJalWithRegs(
MCInst &Inst,
SMLoc IDLoc,
2265 const unsigned Opcode = Inst.
getOpcode();
2267 if (Opcode == Mips::JalOneReg) {
2269 if (IsCpRestoreSet && inMicroMipsMode()) {
2272 }
else if (inMicroMipsMode()) {
2273 JalrInst.
setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2280 }
else if (Opcode == Mips::JalTwoReg) {
2282 if (IsCpRestoreSet && inMicroMipsMode())
2285 JalrInst.
setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2295 if (MCID.
hasDelaySlot() && AssemblerOptions.back()->isReorder())
2306 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2319 bool MipsAsmParser::loadImmediate(int64_t ImmValue,
unsigned DstReg,
2320 unsigned SrcReg,
bool Is32BitImm,
2325 if (!Is32BitImm && !isGP64bit()) {
2326 Error(IDLoc,
"instruction requires a 64-bit architecture");
2335 ImmValue = SignExtend64<32>(ImmValue);
2337 Error(IDLoc,
"instruction requires a 32-bit immediate");
2342 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2343 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2345 bool UseSrcReg =
false;
2346 if (SrcReg != Mips::NoRegister)
2349 unsigned TmpReg = DstReg;
2351 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2354 unsigned ATReg = getATReg(IDLoc);
2367 if (IsAddress && !Is32BitImm) {
2368 TOut.
emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2372 TOut.
emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2377 unsigned TmpReg = DstReg;
2378 if (SrcReg == DstReg) {
2379 TmpReg = getATReg(IDLoc);
2384 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2386 TOut.
emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2391 warnIfNoMacro(IDLoc);
2393 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2394 uint16_t Bits15To0 = ImmValue & 0xffff;
2396 if (!Is32BitImm && !
isInt<32>(ImmValue)) {
2399 if (ImmValue == 0xffffffff) {
2400 TOut.
emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2401 TOut.
emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2403 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2409 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2410 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2412 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2414 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2418 TOut.
emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2420 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2422 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2426 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2428 Error(IDLoc,
"instruction requires a 32-bit immediate");
2435 unsigned LastSet =
findLastSet((uint64_t)ImmValue);
2436 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2437 uint16_t
Bits = (ImmValue >> ShiftAmount) & 0xffff;
2438 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2439 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2442 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2447 warnIfNoMacro(IDLoc);
2454 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister,
true,
false,
2460 unsigned ShiftCarriedForwards = 16;
2461 for (
int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2462 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2464 if (ImmChunk != 0) {
2465 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2466 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2467 ShiftCarriedForwards = 0;
2470 ShiftCarriedForwards += 16;
2472 ShiftCarriedForwards -= 16;
2475 if (ShiftCarriedForwards)
2476 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2479 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2484 bool MipsAsmParser::expandLoadImm(
MCInst &Inst,
bool Is32BitImm,
SMLoc IDLoc,
2487 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
2489 assert(DstRegOp.isReg() &&
"expected register operand kind");
2491 if (loadImmediate(ImmOp.
getImm(), DstRegOp.getReg(), Mips::NoRegister,
2492 Is32BitImm,
false, IDLoc, Out, STI))
2498 bool MipsAsmParser::expandLoadAddress(
unsigned DstReg,
unsigned BaseReg,
2500 bool Is32BitAddress,
SMLoc IDLoc,
2504 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2508 Error(IDLoc,
"la used to load 64-bit address");
2510 Is32BitAddress =
false;
2515 if (!Is32BitAddress && !hasMips3()) {
2516 Error(IDLoc,
"instruction requires a 64-bit architecture");
2520 if (!Offset.
isImm())
2521 return loadAndAddSymbolAddress(Offset.
getExpr(), DstReg, BaseReg,
2522 Is32BitAddress, IDLoc, Out, STI);
2524 if (!ABI.ArePtrs64bit()) {
2526 Is32BitAddress =
true;
2529 return loadImmediate(Offset.
getImm(), DstReg, BaseReg, Is32BitAddress,
true,
2533 bool MipsAsmParser::loadAndAddSymbolAddress(
const MCExpr *SymExpr,
2534 unsigned DstReg,
unsigned SrcReg,
2535 bool Is32BitSym,
SMLoc IDLoc,
2539 bool UseSrcReg = SrcReg != Mips::NoRegister;
2540 warnIfNoMacro(IDLoc);
2542 if (inPicMode() && ABI.IsO32()) {
2545 Error(IDLoc,
"expected relocatable expression");
2548 if (Res.
getSymB() !=
nullptr) {
2549 Error(IDLoc,
"expected relocatable expression with only one symbol");
2556 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2561 TOut.
emitRRX(Mips::LW, DstReg, ABI.GetGlobalPtr(),
2578 const MCExpr *LoExpr =
nullptr;
2589 unsigned TmpReg = DstReg;
2591 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2595 unsigned ATReg = getATReg(IDLoc);
2601 TOut.
emitRRX(Mips::LW, TmpReg, ABI.GetGlobalPtr(),
2609 TOut.
emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
2620 if (ABI.ArePtrs64bit() && isGP64bit()) {
2623 unsigned ATReg = getATReg(IDLoc);
2633 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2645 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
2647 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
2650 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
2653 TOut.
emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
2669 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
2673 TOut.
emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
2674 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
2676 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
2690 unsigned TmpReg = DstReg;
2692 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2695 unsigned ATReg = getATReg(IDLoc);
2706 TOut.
emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
2709 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
2714 bool MipsAsmParser::expandUncondBranchMMPseudo(
MCInst &Inst,
SMLoc IDLoc,
2720 "unexpected number of operands");
2723 if (Offset.isExpr()) {
2730 assert(Offset.isImm() &&
"expected immediate operand kind");
2731 if (isInt<11>(Offset.getImm())) {
2734 if (inMicroMipsMode())
2735 Inst.
setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
2737 if (!isInt<17>(Offset.getImm()))
2738 return Error(IDLoc,
"branch target out of range");
2740 return Error(IDLoc,
"branch to misaligned address");
2753 if (MCID.
hasDelaySlot() && AssemblerOptions.back()->isReorder())
2763 assert(DstRegOp.
isReg() &&
"expected register operand kind");
2766 assert(ImmOp.isImm() &&
"expected immediate operand kind");
2769 assert((MemOffsetOp.isImm() || MemOffsetOp.isExpr()) &&
2770 "expected immediate or expression operand");
2772 unsigned OpCode = 0;
2785 int64_t ImmValue = ImmOp.getImm();
2787 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
2790 warnIfNoMacro(IDLoc);
2792 unsigned ATReg = getATReg(IDLoc);
2796 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(),
true,
2800 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), ATReg, MemOffsetOp, IDLoc, STI);
2809 expandLoadInst(Inst, IDLoc, Out, STI, IsImmOpnd);
2812 expandStoreInst(Inst, IDLoc, Out, STI, IsImmOpnd);
2824 unsigned DstRegClassID =
2825 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
2826 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
2827 (DstRegClassID == Mips::GPR64RegClassID);
2831 if (IsGPR && (BaseReg != DstReg)) {
2840 unsigned ATReg = getATReg(IDLoc);
2856 if (IsGPR && (BaseReg != DstReg)) {
2858 LoOperand, DstReg, IDLoc, STI);
2864 unsigned ATReg = getATReg(IDLoc);
2869 LoOperand, ATReg, IDLoc, STI);
2883 [&]() {
return getATReg(IDLoc); }, IDLoc, STI);
2887 unsigned ATReg = getATReg(IDLoc);
2897 LoOperand, ATReg, IDLoc, STI);
2900 bool MipsAsmParser::expandLoadStoreMultiple(
MCInst &Inst,
SMLoc IDLoc,
2905 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2909 Inst.
getOperand(OpNum - 3).
isReg() &&
"Invalid instruction operand.");
2918 if (inMicroMipsMode() && hasMips32r6())
2919 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
2921 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2929 bool MipsAsmParser::expandCondBranches(
MCInst &Inst,
SMLoc IDLoc,
2933 bool EmittedNoMacroWarning =
false;
2934 unsigned PseudoOpcode = Inst.
getOpcode();
2939 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2940 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
2945 else if (TrgOp.
isImm()) {
2946 warnIfNoMacro(IDLoc);
2947 EmittedNoMacroWarning =
true;
2949 TrgReg = getATReg(IDLoc);
2953 switch(PseudoOpcode) {
2956 case Mips::BLTImmMacro:
2957 PseudoOpcode = Mips::BLT;
2959 case Mips::BLEImmMacro:
2960 PseudoOpcode = Mips::BLE;
2962 case Mips::BGEImmMacro:
2963 PseudoOpcode = Mips::BGE;
2965 case Mips::BGTImmMacro:
2966 PseudoOpcode = Mips::BGT;
2968 case Mips::BLTUImmMacro:
2969 PseudoOpcode = Mips::BLTU;
2971 case Mips::BLEUImmMacro:
2972 PseudoOpcode = Mips::BLEU;
2974 case Mips::BGEUImmMacro:
2975 PseudoOpcode = Mips::BGEU;
2977 case Mips::BGTUImmMacro:
2978 PseudoOpcode = Mips::BGTU;
2980 case Mips::BLTLImmMacro:
2981 PseudoOpcode = Mips::BLTL;
2983 case Mips::BLELImmMacro:
2984 PseudoOpcode = Mips::BLEL;
2986 case Mips::BGELImmMacro:
2987 PseudoOpcode = Mips::BGEL;
2989 case Mips::BGTLImmMacro:
2990 PseudoOpcode = Mips::BGTL;
2992 case Mips::BLTULImmMacro:
2993 PseudoOpcode = Mips::BLTUL;
2995 case Mips::BLEULImmMacro:
2996 PseudoOpcode = Mips::BLEUL;
2998 case Mips::BGEULImmMacro:
2999 PseudoOpcode = Mips::BGEUL;
3001 case Mips::BGTULImmMacro:
3002 PseudoOpcode = Mips::BGTUL;
3006 if (loadImmediate(TrgOp.
getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
3007 false, IDLoc, Out, STI))
3011 switch (PseudoOpcode) {
3016 AcceptsEquality =
false;
3017 ReverseOrderSLT =
false;
3018 IsUnsigned = ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
3019 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
3020 ZeroSrcOpcode = Mips::BGTZ;
3021 ZeroTrgOpcode = Mips::BLTZ;
3027 AcceptsEquality =
true;
3028 ReverseOrderSLT =
true;
3029 IsUnsigned = ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
3030 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
3031 ZeroSrcOpcode = Mips::BGEZ;
3032 ZeroTrgOpcode = Mips::BLEZ;
3038 AcceptsEquality =
true;
3039 ReverseOrderSLT =
false;
3040 IsUnsigned = ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
3041 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
3042 ZeroSrcOpcode = Mips::BLEZ;
3043 ZeroTrgOpcode = Mips::BGEZ;
3049 AcceptsEquality =
false;
3050 ReverseOrderSLT =
true;
3051 IsUnsigned = ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
3052 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
3053 ZeroSrcOpcode = Mips::BLTZ;
3054 ZeroTrgOpcode = Mips::BGTZ;
3060 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
3061 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
3062 if (IsSrcRegZero && IsTrgRegZero) {
3066 if (PseudoOpcode == Mips::BLT) {
3071 if (PseudoOpcode == Mips::BLE) {
3074 Warning(IDLoc,
"branch is always taken");
3077 if (PseudoOpcode == Mips::BGE) {
3080 Warning(IDLoc,
"branch is always taken");
3083 if (PseudoOpcode == Mips::BGT) {
3088 if (PseudoOpcode == Mips::BGTU) {
3089 TOut.
emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
3093 if (AcceptsEquality) {
3096 TOut.
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
3098 Warning(IDLoc,
"branch is always taken");
3105 if (IsSrcRegZero || IsTrgRegZero) {
3106 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
3107 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
3114 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
3115 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
3121 TOut.
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
3123 Warning(IDLoc,
"branch is always taken");
3139 TOut.
emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
3140 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
3147 TOut.
emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
3148 IsSrcRegZero ? TrgReg : SrcReg,
3155 unsigned ATRegNum = getATReg(IDLoc);
3159 if (!EmittedNoMacroWarning)
3160 warnIfNoMacro(IDLoc);
3177 TOut.
emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
3178 ReverseOrderSLT ? TrgReg : SrcReg,
3179 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
3181 TOut.
emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
3182 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
3193 warnIfNoMacro(IDLoc);
3196 assert(RdRegOp.
isReg() &&
"expected register operand kind");
3197 unsigned RdReg = RdRegOp.
getReg();
3200 assert(RsRegOp.
isReg() &&
"expected register operand kind");
3201 unsigned RsReg = RsRegOp.
getReg();
3204 assert(RtRegOp.
isReg() &&
"expected register operand kind");
3205 unsigned RtReg = RtRegOp.
getReg();
3210 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
3211 ZeroReg = Mips::ZERO_64;
3214 ZeroReg = Mips::ZERO;
3217 bool UseTraps = useTraps();
3219 if (RsReg == Mips::ZERO || RsReg == Mips::ZERO_64) {
3220 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)
3221 Warning(IDLoc,
"dividing zero by zero");
3223 if (Signed && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
3225 TOut.
emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
3229 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
3233 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
3238 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
3239 Warning(IDLoc,
"division by zero");
3242 TOut.
emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
3246 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
3253 unsigned BranchTargetNoTraps;
3254 unsigned BranchTarget;
3257 BranchTarget = IsMips64 ? 12 : 8;
3258 TOut.
emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
3260 BranchTarget = IsMips64 ? 20 : 16;
3261 BranchTargetNoTraps = 8;
3263 TOut.
emitRRI(Mips::BNE, RtReg, ZeroReg, BranchTargetNoTraps, IDLoc, STI);
3266 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
3269 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
3276 unsigned ATReg = getATReg(IDLoc);
3280 TOut.
emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
3283 TOut.
emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, STI);
3284 TOut.
emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
3285 TOut.
emitRRI(Mips::DSLL32, ATReg, ATReg, 0x1f, IDLoc, STI);
3288 TOut.
emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, STI);
3289 TOut.
emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, STI);
3293 TOut.
emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
3296 TOut.
emitRRI(Mips::BNE, RsReg, ATReg, BranchTargetNoTraps, IDLoc, STI);
3297 TOut.
emitRRI(Mips::SLL, ZeroReg, ZeroReg, 0, IDLoc, STI);
3298 TOut.
emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
3304 bool MipsAsmParser::expandTrunc(
MCInst &Inst,
bool IsDouble,
bool Is64FPU,
3317 if (hasMips1() && !hasMips2()) {
3318 unsigned ATReg = getATReg(IDLoc);
3321 TOut.
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
3322 TOut.
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
3324 TOut.
emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
3325 TOut.
emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
3326 TOut.
emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
3328 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
3330 FirstReg, SecondReg, IDLoc, STI);
3331 TOut.
emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
3336 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
3338 FirstReg, SecondReg, IDLoc, STI);
3343 bool MipsAsmParser::expandUlh(
MCInst &Inst,
bool Signed,
SMLoc IDLoc,
3345 if (hasMips32r6() || hasMips64r6()) {
3346 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
3350 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3352 assert(SrcRegOp.isReg() &&
"expected register operand kind");
3354 assert(OffsetImmOp.isImm() &&
"expected immediate operand kind");
3357 unsigned DstReg = DstRegOp.
getReg();
3358 unsigned SrcReg = SrcRegOp.getReg();
3359 int64_t OffsetValue = OffsetImmOp.getImm();
3363 warnIfNoMacro(IDLoc);
3364 unsigned ATReg = getATReg(IDLoc);
3369 if (IsLargeOffset) {
3370 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(),
true,
3375 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
3376 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
3380 unsigned FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
3381 unsigned SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
3383 unsigned LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
3384 unsigned SllReg = IsLargeOffset ? DstReg : ATReg;
3386 TOut.emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
3387 FirstOffset, IDLoc, STI);
3388 TOut.emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
3389 TOut.emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
3390 TOut.emitRRR(
Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
3397 if (hasMips32r6() || hasMips64r6()) {
3398 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
3402 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3404 assert(SrcRegOp.isReg() &&
"expected register operand kind");
3406 assert(OffsetImmOp.isImm() &&
"expected immediate operand kind");
3409 unsigned DstReg = DstRegOp.
getReg();
3410 unsigned SrcReg = SrcRegOp.getReg();
3411 int64_t OffsetValue = OffsetImmOp.getImm();
3413 warnIfNoMacro(IDLoc);
3414 unsigned ATReg = getATReg(IDLoc);
3419 if (IsLargeOffset) {
3420 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(),
true,
3425 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
3426 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
3430 if (IsLargeOffset) {
3431 TOut.emitRRI(
Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
3432 TOut.emitRRI(
Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
3433 TOut.emitRRI(
Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
3434 TOut.emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
3435 TOut.emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
3436 TOut.emitRRR(
Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
3438 TOut.emitRRI(
Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
3439 TOut.emitRRI(
Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
3440 TOut.emitRRI(
Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
3448 if (hasMips32r6() || hasMips64r6()) {
3449 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
3453 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3455 assert(SrcRegOp.isReg() &&
"expected register operand kind");
3457 assert(OffsetImmOp.isImm() &&
"expected immediate operand kind");
3460 unsigned DstReg = DstRegOp.
getReg();
3461 unsigned SrcReg = SrcRegOp.getReg();
3462 int64_t OffsetValue = OffsetImmOp.getImm();
3466 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
3467 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
3471 bool IsLoadInst = (Inst.
getOpcode() == Mips::Ulw);
3472 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
3473 unsigned TmpReg = SrcReg;
3474 if (IsLargeOffset || DoMove) {
3475 warnIfNoMacro(IDLoc);
3476 TmpReg = getATReg(IDLoc);
3481 if (IsLargeOffset) {
3482 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !ABI.ArePtrs64bit(),
true,
3492 TOut.emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
3493 TOut.emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
3496 TOut.emitRRR(
Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
3501 bool MipsAsmParser::expandAliasImmediate(
MCInst &Inst,
SMLoc IDLoc,
3511 unsigned ATReg = Mips::NoRegister;
3512 unsigned FinalDstReg = Mips::NoRegister;
3519 unsigned FinalOpcode = Inst.
getOpcode();
3521 if (DstReg == SrcReg) {
3522 ATReg = getATReg(Inst.
getLoc());
3525 FinalDstReg = DstReg;
3529 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit,
false, Inst.
getLoc(), Out, STI)) {
3530 switch (FinalOpcode) {
3537 FinalOpcode = Mips::ADDu;
3542 case (Mips::NORImm):
3543 FinalOpcode = Mips::NOR;
3549 FinalOpcode = Mips::SLT;
3552 FinalOpcode = Mips::SLTu;
3559 if (FinalDstReg == Mips::NoRegister)
3560 TOut.
emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
3562 TOut.
emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
3571 unsigned ATReg = Mips::NoRegister;
3575 unsigned TmpReg = DReg;
3577 unsigned FirstShift = Mips::NOP;
3578 unsigned SecondShift = Mips::NOP;
3580 if (hasMips32r2()) {
3583 TmpReg = getATReg(Inst.
getLoc());
3589 TOut.
emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
3590 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
3595 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
3608 FirstShift = Mips::SRLV;
3609 SecondShift = Mips::SLLV;
3612 FirstShift = Mips::SLLV;
3613 SecondShift = Mips::SRLV;
3617 ATReg = getATReg(Inst.
getLoc());
3621 TOut.
emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
3622 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
3623 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
3632 bool MipsAsmParser::expandRotationImm(
MCInst &Inst,
SMLoc IDLoc,
3636 unsigned ATReg = Mips::NoRegister;
3641 unsigned FirstShift = Mips::NOP;
3642 unsigned SecondShift = Mips::NOP;
3644 if (hasMips32r2()) {
3647 uint64_t MaxShift = 32;
3648 uint64_t ShiftValue = ImmValue;
3650 ShiftValue = MaxShift - ImmValue;
3665 if (ImmValue == 0) {
3674 FirstShift = Mips::SLL;
3679 SecondShift = Mips::SLL;
3683 ATReg = getATReg(Inst.
getLoc());
3687 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.
getLoc(), STI);
3688 TOut.
emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.
getLoc(), STI);
3700 unsigned ATReg = Mips::NoRegister;
3704 unsigned TmpReg = DReg;
3706 unsigned FirstShift = Mips::NOP;
3707 unsigned SecondShift = Mips::NOP;
3709 if (hasMips64r2()) {
3711 if (TmpReg == SReg) {
3712 TmpReg = getATReg(Inst.
getLoc());
3718 TOut.
emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
3719 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
3724 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
3737 FirstShift = Mips::DSRLV;
3738 SecondShift = Mips::DSLLV;
3741 FirstShift = Mips::DSLLV;
3742 SecondShift = Mips::DSRLV;
3746 ATReg = getATReg(Inst.
getLoc());
3750 TOut.
emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
3751 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
3752 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
3761 bool MipsAsmParser::expandDRotationImm(
MCInst &Inst,
SMLoc IDLoc,
3765 unsigned ATReg = Mips::NoRegister;
3770 unsigned FirstShift = Mips::NOP;
3771 unsigned SecondShift = Mips::NOP;
3775 if (hasMips64r2()) {
3777 unsigned FinalOpcode = Mips::NOP;
3779 FinalOpcode = Mips::DROTR;
3780 else if (ImmValue % 32 == 0)
3781 FinalOpcode = Mips::DROTR32;
3782 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
3784 FinalOpcode = Mips::DROTR32;
3786 FinalOpcode = Mips::DROTR;
3787 }
else if (ImmValue >= 33) {
3789 FinalOpcode = Mips::DROTR;
3791 FinalOpcode = Mips::DROTR32;
3794 uint64_t ShiftValue = ImmValue % 32;
3796 ShiftValue = (32 - ImmValue % 32) % 32;
3798 TOut.
emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
3805 if (ImmValue == 0) {
3806 TOut.
emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.
getLoc(), STI);
3814 if ((ImmValue >= 1) && (ImmValue <= 31)) {
3815 FirstShift = Mips::DSLL;
3816 SecondShift = Mips::DSRL32;
3818 if (ImmValue == 32) {
3819 FirstShift = Mips::DSLL32;
3820 SecondShift = Mips::DSRL32;
3822 if ((ImmValue >= 33) && (ImmValue <= 63)) {
3823 FirstShift = Mips::DSLL32;
3824 SecondShift = Mips::DSRL;
3828 if ((ImmValue >= 1) && (ImmValue <= 31)) {
3829 FirstShift = Mips::DSRL;
3830 SecondShift = Mips::DSLL32;
3832 if (ImmValue == 32) {
3833 FirstShift = Mips::DSRL32;
3834 SecondShift = Mips::DSLL32;
3836 if ((ImmValue >= 33) && (ImmValue <= 63)) {
3837 FirstShift = Mips::DSRL32;
3838 SecondShift = Mips::DSLL;
3843 ATReg = getATReg(Inst.
getLoc());
3847 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.
getLoc(), STI);
3848 TOut.
emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
3864 TOut.
emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
3865 if (FirstRegOp != SecondRegOp)
3866 TOut.
emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
3876 case Mips::ZERO:
return Mips::AT;
3877 case Mips::AT:
return Mips::V0;
3878 case Mips::V0:
return Mips::V1;
3879 case Mips::V1:
return Mips::A0;
3880 case Mips::A0:
return Mips::A1;
3881 case Mips::A1:
return Mips::A2;
3882 case Mips::A2:
return Mips::A3;
3883 case Mips::A3:
return Mips::T0;
3886 case Mips::T2:
return Mips::T3;
3887 case Mips::T3:
return Mips::T4;
3888 case Mips::T4:
return Mips::T5;
3889 case Mips::T5:
return Mips::T6;
3890 case Mips::T6:
return Mips::T7;
3891 case Mips::T7:
return Mips::S0;
3892 case Mips::S0:
return Mips::S1;
3893 case Mips::S1:
return Mips::S2;
3894 case Mips::S2:
return Mips::S3;
3895 case Mips::S3:
return Mips::S4;
3896 case Mips::S4:
return Mips::S5;
3897 case Mips::S5:
return Mips::S6;
3898 case Mips::S6:
return Mips::S7;
3901 case Mips::T9:
return Mips::K0;
3902 case Mips::K0:
return Mips::K1;
3903 case Mips::K1:
return Mips::GP;
3904 case Mips::GP:
return Mips::SP;
3905 case Mips::SP:
return Mips::FP;
3906 case Mips::FP:
return Mips::RA;
3907 case Mips::RA:
return Mips::ZERO;
3918 bool MipsAsmParser::expandLoadStoreDMacro(
MCInst &Inst,
SMLoc IDLoc,
3925 warnIfNoMacro(IDLoc);
3928 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
3930 unsigned SecondReg =
nextReg(FirstReg);
3935 warnIfRegIndexIsAT(FirstReg, IDLoc);
3938 "Offset for load macro is not immediate!");
3941 signed NextOffset = FirstOffset.
getImm() + 4;
3949 if (FirstReg != BaseReg || !IsLoad) {
3950 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
3951 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
3953 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
3954 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
3963 warnIfNoMacro(IDLoc);
3989 warnIfNoMacro(IDLoc);
4002 if (Reg == Mips::ZERO) {
4003 Warning(IDLoc,
"comparison is always false");
4004 TOut.
emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
4009 if (Imm > -0x8000 && Imm < 0) {
4011 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
4017 unsigned ATReg = getATReg(IDLoc);
4021 if (loadImmediate(Imm, ATReg, Mips::NoRegister,
true, isGP64bit(), IDLoc,
4040 MipsAsmParser::checkEarlyTargetMatchPredicate(
MCInst &Inst,
4044 return Match_Success;
4047 case Mips::DATI_MM64R6:
4048 case Mips::DAHI_MM64R6:
4049 if (static_cast<MipsOperand &>(*Operands[1])
4050 .isValidForTie(static_cast<MipsOperand &>(*Operands[2])))
4051 return Match_Success;
4052 return Match_RequiresSameSrcAndDst;
4056 unsigned MipsAsmParser::checkTargetMatchPredicate(
MCInst &Inst) {
4061 case Mips::DAUI_MM64R6:
4064 return Match_RequiresNoZeroRegister;
4065 return Match_Success;
4071 case Mips::JALRC_HB_MMR6:
4072 case Mips::JALRC_MMR6:
4074 return Match_RequiresDifferentSrcAndDst;
4075 return Match_Success;
4077 case Mips::LWP_MMR6:
4079 return Match_RequiresDifferentSrcAndDst;
4080 return Match_Success;
4083 return Match_NonZeroOperandForSync;
4084 return Match_Success;
4097 case Mips::BLEZC:
case Mips::BLEZC_MMR6:
4098 case Mips::BGEZC:
case Mips::BGEZC_MMR6:
4099 case Mips::BGTZC:
case Mips::BGTZC_MMR6:
4100 case Mips::BLTZC:
case Mips::BLTZC_MMR6:
4101 case Mips::BEQZC:
case Mips::BEQZC_MMR6:
4102 case Mips::BNEZC:
case Mips::BNEZC_MMR6:
4111 return Match_RequiresNoZeroRegister;
4112 return Match_Success;
4113 case Mips::BGEC:
case Mips::BGEC_MMR6:
4114 case Mips::BLTC:
case Mips::BLTC_MMR6:
4115 case Mips::BGEUC:
case Mips::BGEUC_MMR6:
4116 case Mips::BLTUC:
case Mips::BLTUC_MMR6:
4117 case Mips::BEQC:
case Mips::BEQC_MMR6:
4118 case Mips::BNEC:
case Mips::BNEC_MMR6:
4127 return Match_RequiresNoZeroRegister;
4130 return Match_RequiresNoZeroRegister;
4132 return Match_RequiresDifferentOperands;
4133 return Match_Success;
4139 return Match_NoFCCRegisterForCurrentISA;
4141 return Match_Success;
4147 if (ErrorInfo != ~0ULL && ErrorInfo < Operands.
size()) {
4148 SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc();
4149 if (ErrorLoc ==
SMLoc())
4156 bool MipsAsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
4160 bool MatchingInlineAsm) {
4163 unsigned MatchResult =
4164 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
4166 switch (MatchResult) {
4167 case Match_Success: {
4168 if (processInstruction(Inst, IDLoc, Out, STI))
4172 case Match_MissingFeature:
4173 Error(IDLoc,
"instruction requires a CPU feature not currently enabled");
4175 case Match_InvalidOperand: {
4176 SMLoc ErrorLoc = IDLoc;
4177 if (ErrorInfo != ~0ULL) {
4178 if (ErrorInfo >= Operands.
size())
4179 return Error(IDLoc,
"too few operands for instruction");
4181 ErrorLoc = Operands[ErrorInfo]->getStartLoc();
4182 if (ErrorLoc ==
SMLoc())
4186 return Error(ErrorLoc,
"invalid operand for instruction");
4188 case Match_NonZeroOperandForSync:
4189 return Error(IDLoc,
"s-type must be zero or unspecified for pre-MIPS32 ISAs");
4190 case Match_MnemonicFail:
4191 return Error(IDLoc,
"invalid instruction");
4192 case Match_RequiresDifferentSrcAndDst:
4193 return Error(IDLoc,
"source and destination must be different");
4194 case Match_RequiresDifferentOperands:
4195 return Error(IDLoc,
"registers must be different");
4196 case Match_RequiresNoZeroRegister:
4197 return Error(IDLoc,
"invalid operand ($zero) for instruction");
4198 case Match_RequiresSameSrcAndDst:
4199 return Error(IDLoc,
"source and destination must match");
4200 case Match_NoFCCRegisterForCurrentISA:
4202 "non-zero fcc register doesn't exist in current ISA level");
4207 "expected 1-bit unsigned immediate");
4210 "expected 2-bit unsigned immediate");
4213 "expected immediate in range 1 .. 4");
4216 "expected 3-bit unsigned immediate");
4219 "expected 4-bit unsigned immediate");
4222 "expected 4-bit signed immediate");
4225 "expected 5-bit unsigned immediate");
4228 "expected 5-bit signed immediate");
4231 "expected immediate in range 1 .. 32");
4232 case Match_UImm5_32:
4234 "expected immediate in range 32 .. 63");
4235 case Match_UImm5_33:
4237 "expected immediate in range 33 .. 64");
4238 case Match_UImm5_0_Report_UImm6:
4242 "expected 6-bit unsigned immediate");
4243 case Match_UImm5_Lsl2:
4245 "expected both 7-bit unsigned immediate and multiple of 4");
4246 case Match_UImmRange2_64:
4248 "expected immediate in range 2 .. 64");
4251 "expected 6-bit unsigned immediate");
4252 case Match_UImm6_Lsl2:
4254 "expected both 8-bit unsigned immediate and multiple of 4");
4257 "expected 6-bit signed immediate");
4260 "expected 7-bit unsigned immediate");
4261 case Match_UImm7_N1:
4263 "expected immediate in range -1 .. 126");
4264 case Match_SImm7_Lsl2:
4266 "expected both 9-bit signed immediate and multiple of 4");
4269 "expected 8-bit unsigned immediate");
4270 case Match_UImm10_0:
4272 "expected 10-bit unsigned immediate");
4273 case Match_SImm10_0:
4275 "expected 10-bit signed immediate");
4276 case Match_SImm11_0:
4278 "expected 11-bit signed immediate");
4280 case Match_UImm16_Relaxed:
4282 "expected 16-bit unsigned immediate");
4284 case Match_SImm16_Relaxed:
4286 "expected 16-bit signed immediate");
4287 case Match_SImm19_Lsl2:
4289 "expected both 19-bit signed immediate and multiple of 4");
4290 case Match_UImm20_0:
4292 "expected 20-bit unsigned immediate");
4293 case Match_UImm26_0:
4295 "expected 26-bit unsigned immediate");
4297 case Match_SImm32_Relaxed:
4299 "expected 32-bit signed immediate");
4300 case Match_UImm32_Coerced:
4302 "expected 32-bit immediate");
4303 case Match_MemSImm9:
4305 "expected memory with 9-bit signed offset");
4306 case Match_MemSImm10:
4308 "expected memory with 10-bit signed offset");
4309 case Match_MemSImm10Lsl1:
4311 "expected memory with 11-bit signed offset and multiple of 2");
4312 case Match_MemSImm10Lsl2:
4314 "expected memory with 12-bit signed offset and multiple of 4");
4315 case Match_MemSImm10Lsl3:
4317 "expected memory with 13-bit signed offset and multiple of 8");
4318 case Match_MemSImm11:
4320 "expected memory with 11-bit signed offset");
4321 case Match_MemSImm12:
4323 "expected memory with 12-bit signed offset");
4324 case Match_MemSImm16:
4326 "expected memory with 16-bit signed offset");
4332 void MipsAsmParser::warnIfRegIndexIsAT(
unsigned RegIndex,
SMLoc Loc) {
4333 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
4334 Warning(Loc,
"used $at (currently $" +
Twine(RegIndex) +
4335 ") without \".set noat\"");
4338 void MipsAsmParser::warnIfNoMacro(
SMLoc Loc) {
4339 if (!AssemblerOptions.back()->isMacro())
4340 Warning(Loc,
"macro instruction expanded into multiple instructions");
4344 MipsAsmParser::printWarningWithFixIt(
const Twine &Msg,
const Twine &FixMsg,
4345 SMRange Range,
bool ShowColors) {
4347 Range,
SMFixIt(Range, FixMsg),
4390 if (!(isABI_N32() || isABI_N64()))
4393 if (12 <= CC && CC <= 15) {
4395 AsmToken RegTok = getLexer().peekTok();
4404 assert(FixedName !=
"" &&
"Register name is not one of t4-t7.");
4406 printWarningWithFixIt(
"register names $t4-$t7 are only available in O32.",
4407 "Did you mean $" + FixedName +
"?", RegRange);
4413 if (8 <= CC && CC <= 11)
4429 int MipsAsmParser::matchHWRegsRegisterName(
StringRef Name) {
4433 .Case(
"hwr_cpunum", 0)
4434 .
Case(
"hwr_synci_step", 1)
4436 .
Case(
"hwr_ccres", 3)
4437 .
Case(
"hwr_ulr", 29)
4443 int MipsAsmParser::matchFPURegisterName(
StringRef Name) {
4445 if (Name[0] ==
'f') {
4457 int MipsAsmParser::matchFCCRegisterName(
StringRef Name) {
4471 int MipsAsmParser::matchACRegisterName(
StringRef Name) {
4485 int MipsAsmParser::matchMSA128RegisterName(
StringRef Name) {
4497 int MipsAsmParser::matchMSA128CtrlRegisterName(
StringRef Name) {
4503 .
Case(
"msaaccess", 2)
4505 .
Case(
"msamodify", 4)
4506 .
Case(
"msarequest", 5)
4508 .
Case(
"msaunmap", 7)
4514 unsigned MipsAsmParser::getATReg(
SMLoc Loc) {
4515 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
4517 reportParseError(Loc,
4518 "pseudo-instruction requires $at, which is not available");
4522 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
4527 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
4547 switch (getLexer().getKind()) {
4566 MCSymbol *Sym = getContext().getOrCreateSymbol(
"$" + Identifier);
4571 Operands.
push_back(MipsOperand::CreateImm(Res, S, E, *
this));
4575 DEBUG(
dbgs() <<
".. generic integer expression\n");
4579 if (getParser().parseExpression(Expr))
4584 Operands.
push_back(MipsOperand::CreateImm(Expr, S, E, *
this));
4591 bool MipsAsmParser::isEvaluated(
const MCExpr *Expr) {
4599 if (
const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
4600 if (!isEvaluated(BE->getLHS()))
4602 return isEvaluated(BE->getRHS());
4605 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
4612 bool MipsAsmParser::ParseRegister(
unsigned &RegNo,
SMLoc &StartLoc,
4618 MipsOperand &Operand =
static_cast<MipsOperand &
>(*Operands.
front());
4619 StartLoc = Operand.getStartLoc();
4620 EndLoc = Operand.getEndLoc();
4626 if (Operand.isGPRAsmReg()) {
4628 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
4631 return (RegNo == (
unsigned)-1);
4635 return (RegNo == (
unsigned)-1);
4638 bool MipsAsmParser::parseMemOffset(
const MCExpr *&Res,
bool isParenExpr) {
4642 return getParser().parseParenExprOfDepth(0, Res, S);
4643 return getParser().parseExpression(Res);
4650 const MCExpr *IdVal =
nullptr;
4652 bool isParenExpr =
false;
4663 if (parseMemOffset(IdVal, isParenExpr))
4668 MipsOperand &Mnemonic =
static_cast<MipsOperand &
>(*Operands[0]);
4669 if (Mnemonic.getToken() ==
"la" || Mnemonic.getToken() ==
"dla") {
4672 Operands.
push_back(MipsOperand::CreateImm(IdVal, S, E, *
this));
4681 auto Base = MipsOperand::createGPRReg(
4682 0,
"0", getContext().getRegisterInfo(), S, E, *
this);
4684 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *
this));
4738 if (getParser().parseExpression(NextExpr))
4746 Res = parseAnyRegister(Operands);
4763 std::unique_ptr<MipsOperand>
op(
4764 static_cast<MipsOperand *>(Operands.
back().release()));
4769 if (
const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
4771 if (IdVal->evaluateAsAbsolute(Imm))
4778 Operands.
push_back(MipsOperand::CreateMem(std::move(
op), IdVal, S, E, *
this));
4782 bool MipsAsmParser::searchSymbolAlias(
OperandVector &Operands) {
4797 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.
substr(1), S);
4811 MipsAsmParser::matchAnyRegisterNameWithoutDollar(
OperandVector &Operands,
4814 int Index = matchCPURegisterName(Identifier);
4816 Operands.
push_back(MipsOperand::createGPRReg(
4817 Index, Identifier, getContext().getRegisterInfo(), S,
4818 getLexer().getLoc(), *
this));
4822 Index = matchHWRegsRegisterName(Identifier);
4824 Operands.
push_back(MipsOperand::createHWRegsReg(
4825 Index, Identifier, getContext().getRegisterInfo(), S,
4826 getLexer().getLoc(), *
this));
4830 Index = matchFPURegisterName(Identifier);
4832 Operands.
push_back(MipsOperand::createFGRReg(
4833 Index, Identifier, getContext().getRegisterInfo(), S,
4834 getLexer().getLoc(), *
this));
4838 Index = matchFCCRegisterName(Identifier);
4840 Operands.
push_back(MipsOperand::createFCCReg(
4841 Index, Identifier, getContext().getRegisterInfo(), S,
4842 getLexer().getLoc(), *
this));
4846 Index = matchACRegisterName(Identifier);
4848 Operands.
push_back(MipsOperand::createACCReg(
4849 Index, Identifier, getContext().getRegisterInfo(), S,
4850 getLexer().getLoc(), *
this));
4854 Index = matchMSA128RegisterName(Identifier);
4856 Operands.
push_back(MipsOperand::createMSA128Reg(
4857 Index, Identifier, getContext().getRegisterInfo(), S,
4858 getLexer().getLoc(), *
this));
4862 Index = matchMSA128CtrlRegisterName(Identifier);
4864 Operands.
push_back(MipsOperand::createMSACtrlReg(
4865 Index, Identifier, getContext().getRegisterInfo(), S,
4866 getLexer().getLoc(), *
this));
4882 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
4886 Operands.
push_back(MipsOperand::createNumericReg(
4887 Token.getIntVal(),
Token.getString(), getContext().getRegisterInfo(), S,
4888 Token.getLoc(), *
this));
4907 DEBUG(
dbgs() <<
".. !$ -> try sym aliasing\n");
4909 if (searchSymbolAlias(Operands))
4912 DEBUG(
dbgs() <<
".. !symalias -> NoMatch\n");
4930 SMLoc S = getLexer().getLoc();
4938 const MCExpr *Expr =
nullptr;
4944 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *
this));
4956 if (getParser().parseExpression(IdVal))
4959 assert(MCE &&
"Unexpected MCExpr type.");
4962 Operands.
push_back(MipsOperand::CreateImm(
4972 unsigned PrevReg = Mips::NoRegister;
4973 bool RegRange =
false;
4981 SMLoc E = getLexer().getLoc();
4982 MipsOperand &Reg =
static_cast<MipsOperand &
>(*TmpOperands.
back());
4983 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
4987 if ((isGP64bit() && RegNo == Mips::RA_64) ||
4988 (!isGP64bit() && RegNo == Mips::RA)) {
4991 unsigned TmpReg = PrevReg + 1;
4992 while (TmpReg <= RegNo) {
4993 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
4994 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
4996 Error(E,
"invalid register operand");
5007 if ((PrevReg == Mips::NoRegister) &&
5008 ((isGP64bit() && (RegNo != Mips::S0_64) && (RegNo != Mips::RA_64)) ||
5009 (!isGP64bit() && (RegNo != Mips::S0) && (RegNo != Mips::RA)))) {
5010 Error(E,
"$16 or $31 expected");
5012 }
else if (!(((RegNo == Mips::FP || RegNo == Mips::RA ||
5013 (RegNo >= Mips::S0 && RegNo <= Mips::S7)) &&
5015 ((RegNo == Mips::FP_64 || RegNo == Mips::RA_64 ||
5016 (RegNo >= Mips::S0_64 && RegNo <= Mips::S7_64)) &&
5018 Error(E,
"invalid register operand");
5020 }
else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
5021 ((RegNo != Mips::FP && RegNo != Mips::RA && !isGP64bit()) ||
5022 (RegNo != Mips::FP_64 && RegNo != Mips::RA_64 &&
5024 Error(E,
"consecutive register numbers expected");
5036 Error(E,
"',' or '-' expected");
5048 Operands.
push_back(MipsOperand::CreateRegList(Regs, S, E, *
this));
5049 parseMemOperand(Operands);
5062 MipsOperand Op =
static_cast<MipsOperand &
>(*Operands.
back());
5065 Operands.
push_back(MipsOperand::CreateRegPair(Op, S, E, *
this));
5083 MipsOperand *Reg = &
static_cast<MipsOperand &
>(*TmpOperands.
back());
5084 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
5089 Error(E,
"',' expected");
5099 Reg = &
static_cast<MipsOperand &
>(*TmpOperands.
back());
5100 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
5103 Operands.
push_back(MipsOperand::CreateRegList(Regs, S, E, *
this));
5117 MipsOperand::CreateToken(
"(", getLexer().getLoc(), *
this));
5119 if (parseOperand(Operands, Name)) {
5120 SMLoc Loc = getLexer().getLoc();
5121 return Error(Loc,
"unexpected token in argument list");
5124 SMLoc Loc = getLexer().getLoc();
5125 return Error(Loc,
"unexpected token, expected ')'");
5128 MipsOperand::CreateToken(
")", getLexer().getLoc(), *
this));
5140 bool MipsAsmParser::parseBracketSuffix(
StringRef Name,
5145 MipsOperand::CreateToken(
"[", getLexer().getLoc(), *
this));
5147 if (parseOperand(Operands, Name)) {
5148 SMLoc Loc = getLexer().getLoc();
5149 return Error(Loc,
"unexpected token in argument list");
5152 SMLoc Loc = getLexer().getLoc();
5153 return Error(Loc,
"unexpected token, expected ']'");
5156 MipsOperand::CreateToken(
"]", getLexer().getLoc(), *
this));
5168 getTargetStreamer().forbidModuleDirective();
5171 if (!mnemonicIsValid(Name, 0)) {
5172 return Error(NameLoc,
"unknown instruction");
5175 Operands.
push_back(MipsOperand::CreateToken(Name, NameLoc, *
this));
5180 if (parseOperand(Operands, Name)) {
5181 SMLoc Loc = getLexer().getLoc();
5182 return Error(Loc,
"unexpected token in argument list");
5184 if (getLexer().is(
AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
5191 if (parseOperand(Operands, Name)) {
5192 SMLoc Loc = getLexer().getLoc();
5193 return Error(Loc,
"unexpected token in argument list");
5197 if (parseBracketSuffix(Name, Operands))
5200 parseParenSuffix(Name, Operands))
5205 SMLoc Loc = getLexer().getLoc();
5206 return Error(Loc,
"unexpected token in argument list");
5214 bool MipsAsmParser::reportParseError(
Twine ErrorMsg) {
5215 SMLoc Loc = getLexer().getLoc();
5216 return Error(Loc, ErrorMsg);
5219 bool MipsAsmParser::reportParseError(
SMLoc Loc,
Twine ErrorMsg) {
5220 return Error(Loc, ErrorMsg);
5223 bool MipsAsmParser::parseSetNoAtDirective() {
5228 AssemblerOptions.back()->setATRegIndex(0);
5234 reportParseError(
"unexpected token, expected end of statement");
5238 getTargetStreamer().emitDirectiveSetNoAt();
5243 bool MipsAsmParser::parseSetAtDirective() {
5251 AssemblerOptions.back()->setATRegIndex(1);
5253 getTargetStreamer().emitDirectiveSetAt();
5259 reportParseError(
"unexpected token, expected equals sign");
5266 reportParseError(
"no register specified");
5269 reportParseError(
"unexpected token, expected dollar sign '$'");
5283 reportParseError(
"unexpected token, expected identifier or integer");
5288 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
5289 reportParseError(
"invalid register");
5296 reportParseError(
"unexpected token, expected end of statement");
5300 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
5306 bool MipsAsmParser::parseSetReorderDirective() {
5311 reportParseError(
"unexpected token, expected end of statement");
5314 AssemblerOptions.back()->setReorder();
5315 getTargetStreamer().emitDirectiveSetReorder();
5320 bool MipsAsmParser::parseSetNoReorderDirective() {
5325 reportParseError(
"unexpected token, expected end of statement");
5328 AssemblerOptions.back()->setNoReorder();
5329 getTargetStreamer().emitDirectiveSetNoReorder();
5334 bool MipsAsmParser::parseSetMacroDirective() {
5339 reportParseError(
"unexpected token, expected end of statement");
5342 AssemblerOptions.back()->setMacro();
5343 getTargetStreamer().emitDirectiveSetMacro();
5348 bool MipsAsmParser::parseSetNoMacroDirective() {
5353 reportParseError(
"unexpected token, expected end of statement");
5356 if (AssemblerOptions.back()->isReorder()) {
5357 reportParseError(
"`noreorder' must be set before `nomacro'");
5360 AssemblerOptions.back()->setNoMacro();
5361 getTargetStreamer().emitDirectiveSetNoMacro();
5366 bool MipsAsmParser::parseSetMsaDirective() {
5372 return reportParseError(
"unexpected token, expected end of statement");
5374 setFeatureBits(Mips::FeatureMSA,
"msa");
5375 getTargetStreamer().emitDirectiveSetMsa();
5379 bool MipsAsmParser::parseSetNoMsaDirective() {
5385 return reportParseError(
"unexpected token, expected end of statement");
5387 clearFeatureBits(Mips::FeatureMSA,
"msa");
5388 getTargetStreamer().emitDirectiveSetNoMsa();
5392 bool MipsAsmParser::parseSetNoDspDirective() {
5398 reportParseError(
"unexpected token, expected end of statement");
5402 clearFeatureBits(Mips::FeatureDSP,
"dsp");
5403 getTargetStreamer().emitDirectiveSetNoDsp();
5407 bool MipsAsmParser::parseSetMips16Directive() {
5413 reportParseError(
"unexpected token, expected end of statement");
5417 setFeatureBits(Mips::FeatureMips16,
"mips16");
5418 getTargetStreamer().emitDirectiveSetMips16();
5423 bool MipsAsmParser::parseSetNoMips16Directive() {
5429 reportParseError(
"unexpected token, expected end of statement");
5433 clearFeatureBits(Mips::FeatureMips16,
"mips16");
5434 getTargetStreamer().emitDirectiveSetNoMips16();
5439 bool MipsAsmParser::parseSetFpDirective() {
5448 reportParseError(
"unexpected token, expected equals sign '='");
5454 if (!parseFpABIValue(FpAbiVal,
".set"))
5458 reportParseError(
"unexpected token, expected end of statement");
5461 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
5466 bool MipsAsmParser::parseSetOddSPRegDirective() {
5471 reportParseError(
"unexpected token, expected end of statement");
5475 clearFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
5476 getTargetStreamer().emitDirectiveSetOddSPReg();
5480 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
5485 reportParseError(
"unexpected token, expected end of statement");
5489 setFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
5490 getTargetStreamer().emitDirectiveSetNoOddSPReg();
5494 bool MipsAsmParser::parseSetPopDirective() {
5496 SMLoc Loc = getLexer().getLoc();
5500 return reportParseError(
"unexpected token, expected end of statement");
5504 if (AssemblerOptions.size() == 2)
5505 return reportParseError(Loc,
".set pop with no .set push");
5508 AssemblerOptions.pop_back();
5509 setAvailableFeatures(
5510 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
5513 getTargetStreamer().emitDirectiveSetPop();
5517 bool MipsAsmParser::parseSetPushDirective() {
5521 return reportParseError(
"unexpected token, expected end of statement");
5524 AssemblerOptions.push_back(
5525 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
5527 getTargetStreamer().emitDirectiveSetPush();
5531 bool MipsAsmParser::parseSetSoftFloatDirective() {
5535 return reportParseError(
"unexpected token, expected end of statement");
5537 setFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
5538 getTargetStreamer().emitDirectiveSetSoftFloat();
5542 bool MipsAsmParser::parseSetHardFloatDirective() {
5546 return reportParseError(
"unexpected token, expected end of statement");
5548 clearFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
5549 getTargetStreamer().emitDirectiveSetHardFloat();
5553 bool MipsAsmParser::parseSetAssignment() {
5559 reportParseError(
"expected identifier after .set");
5562 return reportParseError(
"unexpected token, expected comma");
5566 return reportParseError(
"expected valid expression after comma");
5568 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
5574 bool MipsAsmParser::parseSetMips0Directive() {
5578 return reportParseError(
"unexpected token, expected end of statement");
5582 setAvailableFeatures(
5583 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
5585 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
5587 getTargetStreamer().emitDirectiveSetMips0();
5591 bool MipsAsmParser::parseSetArchDirective() {
5595 return reportParseError(
"unexpected token, expected equals sign");
5600 return reportParseError(
"expected arch identifier");
5604 .Case(
"mips1",
"mips1")
5605 .
Case(
"mips2",
"mips2")
5606 .
Case(
"mips3",
"mips3")
5607 .
Case(
"mips4",
"mips4")
5608 .
Case(
"mips5",
"mips5")
5609 .
Case(
"mips32",
"mips32")
5610 .
Case(
"mips32r2",
"mips32r2")
5611 .
Case(
"mips32r3",
"mips32r3")
5612 .
Case(
"mips32r5",
"mips32r5")
5613 .
Case(
"mips32r6",
"mips32r6")
5614 .
Case(
"mips64",
"mips64")
5615 .
Case(
"mips64r2",
"mips64r2")
5616 .
Case(
"mips64r3",
"mips64r3")
5617 .
Case(
"mips64r5",
"mips64r5")
5618 .
Case(
"mips64r6",
"mips64r6")
5619 .
Case(
"octeon",
"cnmips")
5620 .
Case(
"r4000",
"mips3")
5623 if (ArchFeatureName.
empty())
5624 return reportParseError(
"unsupported architecture");
5626 selectArch(ArchFeatureName);
5627 getTargetStreamer().emitDirectiveSetArch(Arch);
5631 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
5635 return reportParseError(
"unexpected token, expected end of statement");
5640 case Mips::FeatureDSP:
5641 setFeatureBits(Mips::FeatureDSP,
"dsp");
5642 getTargetStreamer().emitDirectiveSetDsp();
5644 case Mips::FeatureMicroMips:
5645 setFeatureBits(Mips::FeatureMicroMips,
"micromips");
5646 getTargetStreamer().emitDirectiveSetMicroMips();
5648 case Mips::FeatureMips1:
5649 selectArch(
"mips1");
5650 getTargetStreamer().emitDirectiveSetMips1();
5652 case Mips::FeatureMips2:
5653 selectArch(
"mips2");
5654 getTargetStreamer().emitDirectiveSetMips2();
5656 case Mips::FeatureMips3:
5657 selectArch(
"mips3");
5658 getTargetStreamer().emitDirectiveSetMips3();
5660 case Mips::FeatureMips4:
5661 selectArch(
"mips4");
5662 getTargetStreamer().emitDirectiveSetMips4();
5664 case Mips::FeatureMips5:
5665 selectArch(
"mips5");
5666 getTargetStreamer().emitDirectiveSetMips5();
5668 case Mips::FeatureMips32:
5669 selectArch(
"mips32");
5670 getTargetStreamer().emitDirectiveSetMips32();
5672 case Mips::FeatureMips32r2:
5673 selectArch(
"mips32r2");
5674 getTargetStreamer().emitDirectiveSetMips32R2();
5676 case Mips::FeatureMips32r3:
5677 selectArch(
"mips32r3");
5678 getTargetStreamer().emitDirectiveSetMips32R3();
5680 case Mips::FeatureMips32r5:
5681 selectArch(
"mips32r5");
5682 getTargetStreamer().emitDirectiveSetMips32R5();
5684 case Mips::FeatureMips32r6:
5685 selectArch(
"mips32r6");
5686 getTargetStreamer().emitDirectiveSetMips32R6();
5688 case Mips::FeatureMips64:
5689 selectArch(
"mips64");
5690 getTargetStreamer().emitDirectiveSetMips64();
5692 case Mips::FeatureMips64r2:
5693 selectArch(
"mips64r2");
5694 getTargetStreamer().emitDirectiveSetMips64R2();
5696 case Mips::FeatureMips64r3:
5697 selectArch(
"mips64r3");
5698 getTargetStreamer().emitDirectiveSetMips64R3();
5700 case Mips::FeatureMips64r5:
5701 selectArch(
"mips64r5");
5702 getTargetStreamer().emitDirectiveSetMips64R5();
5704 case Mips::FeatureMips64r6:
5705 selectArch(
"mips64r6");
5706 getTargetStreamer().emitDirectiveSetMips64R6();
5712 bool MipsAsmParser::eatComma(
StringRef ErrorStr) {
5715 SMLoc Loc = getLexer().getLoc();
5716 return Error(Loc, ErrorStr);
5727 bool MipsAsmParser::isPicAndNotNxxAbi() {
5728 return inPicMode() && !(isABI_N32() || isABI_N64());
5731 bool MipsAsmParser::parseDirectiveCpLoad(
SMLoc Loc) {
5732 if (AssemblerOptions.back()->isReorder())
5733 Warning(Loc,
".cpload should be inside a noreorder section");
5735 if (inMips16Mode()) {
5736 reportParseError(
".cpload is not supported in Mips16 mode");
5743 reportParseError(
"expected register containing function address");
5747 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*Reg[0]);
5748 if (!RegOpnd.isGPRAsmReg()) {
5749 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
5755 reportParseError(
"unexpected token, expected end of statement");
5759 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
5763 bool MipsAsmParser::parseDirectiveCpRestore(
SMLoc Loc) {
5769 if (inMips16Mode()) {
5770 reportParseError(
".cprestore is not supported in Mips16 mode");
5775 const MCExpr *StackOffset;
5776 int64_t StackOffsetVal;
5778 reportParseError(
"expected stack offset value");
5782 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
5783 reportParseError(
"stack offset is not an absolute expression");
5787 if (StackOffsetVal < 0) {
5788 Warning(Loc,
".cprestore with negative stack offset has no effect");
5789 IsCpRestoreSet =
false;
5791 IsCpRestoreSet =
true;
5792 CpRestoreOffset = StackOffsetVal;
5797 reportParseError(
"unexpected token, expected end of statement");
5801 if (!getTargetStreamer().emitDirectiveCpRestore(
5802 CpRestoreOffset, [&]() {
return getATReg(Loc); }, Loc, STI))
5808 bool MipsAsmParser::parseDirectiveCPSetup() {
5812 bool SaveIsReg =
true;
5817 reportParseError(
"expected register containing function address");
5821 MipsOperand &FuncRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
5822 if (!FuncRegOpnd.isGPRAsmReg()) {
5823 reportParseError(FuncRegOpnd.getStartLoc(),
"invalid register");
5827 FuncReg = FuncRegOpnd.getGPR32Reg();
5830 if (!eatComma(
"unexpected token, expected comma"))
5833 ResTy = parseAnyRegister(TmpReg);
5835 const MCExpr *OffsetExpr;
5837 SMLoc ExprLoc = getLexer().getLoc();
5840 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
5841 reportParseError(ExprLoc,
"expected save register or stack offset");
5848 MipsOperand &SaveOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
5849 if (!SaveOpnd.isGPRAsmReg()) {
5850 reportParseError(SaveOpnd.getStartLoc(),
"invalid register");
5853 Save = SaveOpnd.getGPR32Reg();
5856 if (!eatComma(
"unexpected token, expected comma"))
5861 reportParseError(
"expected expression");
5866 reportParseError(
"expected symbol");
5871 CpSaveLocation = Save;
5872 CpSaveLocationIsRegister = SaveIsReg;
5874 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->
getSymbol(),
5879 bool MipsAsmParser::parseDirectiveCPReturn() {
5880 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
5881 CpSaveLocationIsRegister);
5885 bool MipsAsmParser::parseDirectiveNaN() {
5892 getTargetStreamer().emitDirectiveNaN2008();
5894 }
else if (Tok.
getString() ==
"legacy") {
5896 getTargetStreamer().emitDirectiveNaNLegacy();
5902 reportParseError(
"invalid option in .nan directive");
5906 bool MipsAsmParser::parseDirectiveSet() {
5912 return parseSetNoAtDirective();
5914 return parseSetAtDirective();
5916 return parseSetArchDirective();
5918 return parseSetFpDirective();
5919 }
else if (Tok.
getString() ==
"oddspreg") {
5920 return parseSetOddSPRegDirective();
5921 }
else if (Tok.
getString() ==
"nooddspreg") {
5922 return parseSetNoOddSPRegDirective();
5924 return parseSetPopDirective();
5926 return parseSetPushDirective();
5927 }
else if (Tok.
getString() ==
"reorder") {
5928 return parseSetReorderDirective();
5929 }
else if (Tok.
getString() ==
"noreorder") {
5930 return parseSetNoReorderDirective();
5931 }
else if (Tok.
getString() ==
"macro") {
5932 return parseSetMacroDirective();
5933 }
else if (Tok.
getString() ==
"nomacro") {
5934 return parseSetNoMacroDirective();
5935 }
else if (Tok.
getString() ==
"mips16") {
5936 return parseSetMips16Directive();
5937 }
else if (Tok.
getString() ==
"nomips16") {
5938 return parseSetNoMips16Directive();
5939 }
else if (Tok.
getString() ==
"nomicromips") {
5940 clearFeatureBits(Mips::FeatureMicroMips,
"micromips");
5941 getTargetStreamer().emitDirectiveSetNoMicroMips();
5944 }
else if (Tok.
getString() ==
"micromips") {
5945 return parseSetFeature(Mips::FeatureMicroMips);
5946 }
else if (Tok.
getString() ==
"mips0") {
5947 return parseSetMips0Directive();
5948 }
else if (Tok.
getString() ==
"mips1") {
5949 return parseSetFeature(Mips::FeatureMips1);
5950 }
else if (Tok.
getString() ==
"mips2") {
5951 return parseSetFeature(Mips::FeatureMips2);
5952 }
else if (Tok.
getString() ==
"mips3") {
5953 return parseSetFeature(Mips::FeatureMips3);
5954 }
else if (Tok.
getString() ==
"mips4") {
5955 return parseSetFeature(Mips::FeatureMips4);
5956 }
else if (Tok.
getString() ==
"mips5") {
5957 return parseSetFeature(Mips::FeatureMips5);
5958 }
else if (Tok.
getString() ==
"mips32") {
5959 return parseSetFeature(Mips::FeatureMips32);
5960 }
else if (Tok.
getString() ==
"mips32r2") {
5961 return parseSetFeature(Mips::FeatureMips32r2);
5962 }
else if (Tok.
getString() ==
"mips32r3") {
5963 return parseSetFeature(Mips::FeatureMips32r3);
5964 }
else if (Tok.
getString() ==
"mips32r5") {
5965 return parseSetFeature(Mips::FeatureMips32r5);
5966 }
else if (Tok.
getString() ==
"mips32r6") {
5967 return parseSetFeature(Mips::FeatureMips32r6);
5968 }
else if (Tok.
getString() ==
"mips64") {
5969 return parseSetFeature(Mips::FeatureMips64);
5970 }
else if (Tok.
getString() ==
"mips64r2") {
5971 return parseSetFeature(Mips::FeatureMips64r2);
5972 }
else if (Tok.
getString() ==
"mips64r3") {
5973 return parseSetFeature(Mips::FeatureMips64r3);
5974 }
else if (Tok.
getString() ==
"mips64r5") {
5975 return parseSetFeature(Mips::FeatureMips64r5);
5976 }
else if (Tok.
getString() ==
"mips64r6") {
5977 return parseSetFeature(Mips::FeatureMips64r6);
5979 return parseSetFeature(Mips::FeatureDSP);
5980 }
else if (Tok.
getString() ==
"nodsp") {
5981 return parseSetNoDspDirective();
5983 return parseSetMsaDirective();
5984 }
else if (Tok.
getString() ==
"nomsa") {
5985 return parseSetNoMsaDirective();
5986 }
else if (Tok.
getString() ==
"softfloat") {
5987 return parseSetSoftFloatDirective();
5988 }
else if (Tok.
getString() ==
"hardfloat") {
5989 return parseSetHardFloatDirective();
5992 parseSetAssignment();
6001 bool MipsAsmParser::parseDataDirective(
unsigned Size,
SMLoc L) {
6006 if (getParser().parseExpression(Value))
6009 getParser().getStreamer().EmitValue(Value, Size);
6015 return Error(L,
"unexpected token, expected comma");
6026 bool MipsAsmParser::parseDirectiveGpWord() {
6031 if (getParser().parseExpression(Value))
6033 getParser().getStreamer().EmitGPRel32Value(Value);
6036 return Error(getLexer().getLoc(),
6037 "unexpected token, expected end of statement");
6044 bool MipsAsmParser::parseDirectiveGpDWord() {
6049 if (getParser().parseExpression(Value))
6051 getParser().getStreamer().EmitGPRel64Value(Value);
6054 return Error(getLexer().getLoc(),
6055 "unexpected token, expected end of statement");
6062 bool MipsAsmParser::parseDirectiveDtpRelWord() {
6067 if (getParser().parseExpression(Value))
6069 getParser().getStreamer().EmitDTPRel32Value(Value);
6072 return Error(getLexer().getLoc(),
6073 "unexpected token, expected end of statement");
6080 bool MipsAsmParser::parseDirectiveDtpRelDWord() {
6085 if (getParser().parseExpression(Value))
6087 getParser().getStreamer().EmitDTPRel64Value(Value);
6090 return Error(getLexer().getLoc(),
6091 "unexpected token, expected end of statement");
6098 bool MipsAsmParser::parseDirectiveTpRelWord() {
6103 if (getParser().parseExpression(Value))
6105 getParser().getStreamer().EmitTPRel32Value(Value);
6108 return Error(getLexer().getLoc(),
6109 "unexpected token, expected end of statement");
6116 bool MipsAsmParser::parseDirectiveTpRelDWord() {
6121 if (getParser().parseExpression(Value))
6123 getParser().getStreamer().EmitTPRel64Value(Value);
6126 return Error(getLexer().getLoc(),
6127 "unexpected token, expected end of statement");
6132 bool MipsAsmParser::parseDirectiveOption() {
6139 "unexpected token, expected identifier");
6144 if (Option ==
"pic0") {
6146 IsPicEnabled =
false;
6148 getTargetStreamer().emitDirectiveOptionPic0();
6152 "unexpected token, expected end of statement");
6157 if (Option ==
"pic2") {
6159 IsPicEnabled =
true;
6161 getTargetStreamer().emitDirectiveOptionPic2();
6165 "unexpected token, expected end of statement");
6172 "unknown option, expected 'pic0' or 'pic2'");
6179 bool MipsAsmParser::parseInsnDirective() {
6182 reportParseError(
"unexpected token, expected end of statement");
6188 getTargetStreamer().emitDirectiveInsn();
6200 reportParseError(
"unexpected token, expected end of statement");
6204 MCSection *ELFSection = getContext().getELFSection(
6206 getParser().getStreamer().SwitchSection(ELFSection);
6218 bool MipsAsmParser::parseDirectiveModule() {
6223 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
6225 reportParseError(
".module directive must appear before any code");
6231 reportParseError(
"expected .module option identifier");
6235 if (Option ==
"oddspreg") {
6236 clearModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
6240 getTargetStreamer().updateABIInfo(*
this);
6245 getTargetStreamer().emitDirectiveModuleOddSPReg();
6249 reportParseError(
"unexpected token, expected end of statement");
6254 }
else if (Option ==
"nooddspreg") {
6256 return Error(L,
"'.module nooddspreg' requires the O32 ABI");
6259 setModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
6263 getTargetStreamer().updateABIInfo(*
this);
6268 getTargetStreamer().emitDirectiveModuleOddSPReg();
6272 reportParseError(
"unexpected token, expected end of statement");
6277 }
else if (Option ==
"fp") {
6278 return parseDirectiveModuleFP();
6279 }
else if (Option ==
"softfloat") {
6280 setModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
6284 getTargetStreamer().updateABIInfo(*
this);
6289 getTargetStreamer().emitDirectiveModuleSoftFloat();
6293 reportParseError(
"unexpected token, expected end of statement");
6298 }
else if (Option ==
"hardfloat") {
6299 clearModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
6303 getTargetStreamer().updateABIInfo(*
this);
6308 getTargetStreamer().emitDirectiveModuleHardFloat();
6312 reportParseError(
"unexpected token, expected end of statement");
6318 return Error(L,
"'" +
Twine(Option) +
"' is not a valid .module option.");
6326 bool MipsAsmParser::parseDirectiveModuleFP() {
6331 reportParseError(
"unexpected token, expected equals sign '='");
6337 if (!parseFpABIValue(FpABI,
".module"))
6341 reportParseError(
"unexpected token, expected end of statement");
6347 getTargetStreamer().updateABIInfo(*
this);
6352 getTargetStreamer().emitDirectiveModuleFP();
6362 bool ModuleLevelOptions = Directive ==
".module";
6368 if (Value !=
"xx") {
6369 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
6374 reportParseError(
"'" + Directive +
" fp=xx' requires the O32 ABI");
6379 if (ModuleLevelOptions) {
6380 setModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
6381 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
6383 setFeatureBits(Mips::FeatureFPXX,
"fpxx");
6384 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
6393 if (Value != 32 && Value != 64) {
6394 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
6400 reportParseError(
"'" + Directive +
" fp=32' requires the O32 ABI");
6405 if (ModuleLevelOptions) {
6406 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
6407 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
6409 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
6410 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
6414 if (ModuleLevelOptions) {
6415 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
6416 setModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
6418 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
6419 setFeatureBits(Mips::FeatureFP64Bit,
"fp64");
6429 bool MipsAsmParser::ParseDirective(
AsmToken DirectiveID) {
6438 if (IDVal ==
".cpload") {
6439 parseDirectiveCpLoad(DirectiveID.
getLoc());
6442 if (IDVal ==
".cprestore") {
6443 parseDirectiveCpRestore(DirectiveID.
getLoc());
6446 if (IDVal ==
".dword") {
6447 parseDataDirective(8, DirectiveID.
getLoc());
6450 if (IDVal ==
".ent") {
6454 reportParseError(
"expected identifier after .ent");
6468 reportParseError(
"unexpected token, expected end of statement");
6472 const MCExpr *DummyNumber;
6473 int64_t DummyNumberVal;
6477 reportParseError(
"expected number after comma");
6480 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
6481 reportParseError(
"expected an absolute expression after comma");
6488 reportParseError(
"unexpected token, expected end of statement");
6492 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
6494 getTargetStreamer().emitDirectiveEnt(*Sym);
6496 IsCpRestoreSet =
false;
6500 if (IDVal ==
".end") {
6504 reportParseError(
"expected identifier after .end");
6509 reportParseError(
"unexpected token, expected end of statement");
6513 if (CurrentFn ==
nullptr) {
6514 reportParseError(
".end used without .ent");
6518 if ((SymbolName != CurrentFn->getName())) {
6519 reportParseError(
".end symbol does not match .ent symbol");
6523 getTargetStreamer().emitDirectiveEnd(SymbolName);
6524 CurrentFn =
nullptr;
6525 IsCpRestoreSet =
false;
6529 if (IDVal ==
".frame") {
6534 reportParseError(
"expected stack register");
6538 MipsOperand &StackRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
6539 if (!StackRegOpnd.isGPRAsmReg()) {
6540 reportParseError(StackRegOpnd.getStartLoc(),
6541 "expected general purpose register");
6544 unsigned StackReg = StackRegOpnd.getGPR32Reg();
6549 reportParseError(
"unexpected token, expected comma");
6555 int64_t FrameSizeVal;
6558 reportParseError(
"expected frame size value");
6562 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
6563 reportParseError(
"frame size not an absolute expression");
6570 reportParseError(
"unexpected token, expected comma");
6576 ResTy = parseAnyRegister(TmpReg);
6578 reportParseError(
"expected return register");
6582 MipsOperand &ReturnRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
6583 if (!ReturnRegOpnd.isGPRAsmReg()) {
6584 reportParseError(ReturnRegOpnd.getStartLoc(),
6585 "expected general purpose register");
6591 reportParseError(
"unexpected token, expected end of statement");
6595 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
6596 ReturnRegOpnd.getGPR32Reg());
6597 IsCpRestoreSet =
false;
6601 if (IDVal ==
".set") {
6602 parseDirectiveSet();
6606 if (IDVal ==
".mask" || IDVal ==
".fmask") {
6621 reportParseError(
"expected bitmask value");
6625 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
6626 reportParseError(
"bitmask not an absolute expression");
6633 reportParseError(
"unexpected token, expected comma");
6638 const MCExpr *FrameOffset;
6639 int64_t FrameOffsetVal;
6642 reportParseError(
"expected frame offset value");
6646 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
6647 reportParseError(
"frame offset not an absolute expression");
6653 reportParseError(
"unexpected token, expected end of statement");
6657 if (IDVal ==
".mask")
6658 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
6660 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
6664 if (IDVal ==
".nan")
6665 return parseDirectiveNaN();
6667 if (IDVal ==
".gpword") {
6668 parseDirectiveGpWord();
6672 if (IDVal ==
".gpdword") {
6673 parseDirectiveGpDWord();
6677 if (IDVal ==
".dtprelword") {
6678 parseDirectiveDtpRelWord();
6682 if (IDVal ==
".dtpreldword") {
6683 parseDirectiveDtpRelDWord();
6687 if (IDVal ==
".tprelword") {
6688 parseDirectiveTpRelWord();
6692 if (IDVal ==
".tpreldword") {
6693 parseDirectiveTpRelDWord();
6697 if (IDVal ==
".word") {
6698 parseDataDirective(4, DirectiveID.
getLoc());
6702 if (IDVal ==
".hword") {
6703 parseDataDirective(2, DirectiveID.
getLoc());
6707 if (IDVal ==
".option") {
6708 parseDirectiveOption();
6712 if (IDVal ==
".abicalls") {
6713 getTargetStreamer().emitDirectiveAbiCalls();
6716 "unexpected token, expected end of statement");
6721 if (IDVal ==
".cpsetup") {
6722 parseDirectiveCPSetup();
6725 if (IDVal ==
".cpreturn") {
6726 parseDirectiveCPReturn();
6729 if (IDVal ==
".module") {
6730 parseDirectiveModule();
6733 if (IDVal ==
".llvm_internal_mips_reallow_module_directive") {
6734 parseInternalDirectiveReallowModule();
6737 if (IDVal ==
".insn") {
6738 parseInsnDirective();
6741 if (IDVal ==
".sbss") {
6745 if (IDVal ==
".sdata") {
6753 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
6756 reportParseError(
"unexpected token, expected end of statement");
6760 getTargetStreamer().reallowModuleDirective();
6773 #define GET_REGISTER_MATCHER
6774 #define GET_MATCHER_IMPLEMENTATION
6775 #include "MipsGenAsmMatcher.inc"
static bool isReg(const MCInst &MI, unsigned OpNo)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
void emitRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, SMLoc IDLoc, const MCSubtargetInfo *STI)
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.
constexpr bool isUInt< 32 >(uint64_t x)
Represents a range in source code.
Instances of this class represent a uniqued identifier for a section in the current translation unit...
void push_back(const T &Elt)
static ARMBaseTargetMachine::ARMABI computeTargetABI(const Triple &TT, StringRef CPU, const TargetOptions &Options)
T findLastSet(T Val, ZeroBehavior ZB=ZB_Max)
Get the index of the last set bit starting from the least significant bit.
const MCSymbol & getSymbol() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
const char * getPointer() const
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
TokenKind getKind() const
void setFeatureBits(const FeatureBitset &FeatureBits_)
setFeatureBits - Set the feature bits.
This represents an "assembler immediate".
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.
MachineInstrBuilder MachineInstrBuilder &DefMI const MCInstrDesc & Desc
Target specific streamer interface.
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
Target & getTheMipselTarget()
virtual void emitDirectiveSetNoReorder()
constexpr bool isInt< 8 >(int64_t x)
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
bool isNot(TokenKind K) const
constexpr bool isInt< 16 >(int64_t x)
SMLoc getLoc() const
Get the current source location.
void emitGPRestore(int Offset, SMLoc IDLoc, const MCSubtargetInfo *STI)
Emit the $gp restore operation for .cprestore.
static const MCInstrDesc & getInstDesc(unsigned Opcode)
static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands, uint64_t ErrorInfo)
virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
return AArch64::GPR64RegClass contains(Reg)
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...
void emitLoadWithImmOffset(unsigned Opcode, unsigned DstReg, unsigned BaseReg, int64_t Offset, unsigned TmpReg, SMLoc IDLoc, const MCSubtargetInfo *STI)
Emit a load instruction with an immediate offset.
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 ...
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.
LLVM_ATTRIBUTE_ALWAYS_INLINE R Default(const T &Value) const
Reg
All possible values of the reg field in the ModR/M byte.
Target independent representation for an assembler token.
static int getRegClass(RegisterKind Is, unsigned RegWidth)
Represent a reference to a symbol from inside an expression.
Windows NT (Windows on ARM)
static bool isMem(const MachineInstr &MI, unsigned Op)
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand...
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
Context object for machine code objects.
void emitNop(SMLoc IDLoc, const MCSubtargetInfo *STI)
uint8_t OperandType
Information about the type of the operand.
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Case(const char(&S)[N], const T &Value)
bool isNot(AsmToken::TokenKind K) const
Check if the current token has kind K.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
unsigned getReg() const
Returns the register number.
Target & getTheMips64Target()
Unary assembler expressions.
Simple integer binary arithmetic operators.
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
ArchType getArch() const
getArch - Get the parsed architecture type of this triple.
LLVM_NODISCARD char front() const
front - Get the first character in the string.
int64_t getIntVal() const
IsPCRelativeLoad - A Load instruction with implicit source register ($pc) with explicit offset and de...
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
static bool isShiftedUIntAtAnyPosition(uint64_t x)
Can the value be represented by a unsigned N-bit value and a shift left?
HasFCCRegOperand - Instruction uses an $fcc<x> register.
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.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
void emitRX(unsigned Opcode, unsigned Reg0, MCOperand Op1, SMLoc IDLoc, const MCSubtargetInfo *STI)
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
virtual void setUsesMicroMips()
INITIALIZE_PASS(HexagonEarlyIfConversion,"hexagon-eif","Hexagon early if conversion", false, false) bool HexagonEarlyIfConversion MachineBasicBlock * SB
FeatureBitset ToggleFeature(uint64_t FB)
ToggleFeature - Toggle a feature and returns the re-computed feature bits.
const MCExpr * getExpr() const
A switch()-like statement whose cases are string literals.
Streaming machine code generation interface.
Target & getTheMips64elTarget()
The instances of the Type class are immutable: once they are created, they are never changed...
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
static ManagedStatic< OptionRegistry > OR
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Interface to description of machine instruction set.
static unsigned countMCSymbolRefExpr(const MCExpr *Expr)
virtual MCAsmLexer & getLexer()=0
void emitRI(unsigned Opcode, unsigned Reg0, int32_t Imm, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitR(unsigned Opcode, unsigned Reg0, SMLoc IDLoc, const MCSubtargetInfo *STI)
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang","erlang-compatible garbage collector")
static const MCSymbol * getSingleMCSymbol(const MCExpr *Expr)
static unsigned nextReg(unsigned Reg)
const AsmToken peekTok(bool ShouldSkipSpace=true)
Look ahead at the next token to be lexed.
Represents a single fixit, a replacement of one range of text with another.
bool isInSection(bool SetUsed=true) const
isInSection - Check if this symbol is defined in some section (i.e., it is defined but not absolute)...
bool isIntN(unsigned N, int64_t x)
isIntN - Checks if an signed integer fits into the given (dynamic) bit width.
const MCSymbolRefExpr * getSymB() const
Binary assembler expressions.
T findFirstSet(T Val, ZeroBehavior ZB=ZB_Max)
Get the index of the first set bit starting from the least significant bit.
void emitLoadWithSymOffset(unsigned Opcode, unsigned DstReg, unsigned BaseReg, MCOperand &HiOperand, MCOperand &LoOperand, unsigned ATReg, SMLoc IDLoc, const MCSubtargetInfo *STI)
Emit a load instruction with an symbol offset.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool is(AsmToken::TokenKind K) const
Check if the current token has kind K.
Triple - Helper class for working with autoconf configuration names.
void emitRRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, unsigned Reg2, SMLoc IDLoc, const MCSubtargetInfo *STI)
void setOpcode(unsigned Op)
constexpr bool isInt< 32 >(int64_t x)
const MCSymbolRefExpr * getSymA() const
SMRange getLocRange() const
void emitDSLL(unsigned DstReg, unsigned SrcReg, int16_t ShiftAmount, SMLoc IDLoc, const MCSubtargetInfo *STI)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
void emitEmptyDelaySlot(bool hasShortDelaySlot, SMLoc IDLoc, const MCSubtargetInfo *STI)
bool mayLoad() const
Return true if this instruction could possibly read memory.
const FeatureBitset & getFeatureBits() const
getFeatureBits - Return the feature bits.
bool is(TokenKind K) const
void setVariableValue(const MCExpr *Value)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
bool evaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout, const MCFixup *Fixup) const
Try to evaluate the expression to a relocatable value, i.e.
unsigned getOpcode() const
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
const MCExpr * getVariableValue(bool SetUsed=true) const
getVariableValue - Get the value for variable symbols.
bool isTemporary() const
isTemporary - Check if this is an assembler temporary symbol.
Base class for user error types.
static const MipsMCExpr * create(MipsExprKind Kind, const MCExpr *Expr, MCContext &Ctx)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
Target & getTheMipsTarget()
void emitStoreWithImmOffset(unsigned Opcode, unsigned SrcReg, unsigned BaseReg, int64_t Offset, function_ref< unsigned()> GetATReg, SMLoc IDLoc, const MCSubtargetInfo *STI)
Emit a store instruction with an offset.
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...
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
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.
Bitwise operators - logical and, logical or, logical xor.
int16_t RegClass
This specifies the register class enumeration of the operand if the operand is a register.
unsigned getNumOperands() const
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() 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...
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
References to labels and assigned expressions.
const Triple & getTargetTriple() const
getTargetTriple - Return the target triple string.
constexpr bool isUInt< 16 >(uint64_t x)
static bool hasShortDelaySlot(unsigned Opcode)
const MCInstrDesc MipsInsts[]
bool isVariable() const
isVariable - Check if this is a variable symbol.
static StringRef getCPU(StringRef CPU)
Processes a CPU name.
void emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1, int16_t Imm, SMLoc IDLoc, const MCSubtargetInfo *STI)
VariantKind getKind() const
void emitRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1, MCOperand Op2, SMLoc IDLoc, const MCSubtargetInfo *STI)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
int64_t getConstant() const
virtual void emitDirectiveSetReorder()
LLVM Value Representation.
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
const FeatureBitset Features
const MCOperandInfo * OpInfo
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...
void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc, const MCSubtargetInfo *STI)
This class implements an extremely fast bulk output stream that can only output to a stream...
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
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 GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
static MCOperand createImm(int64_t Val)
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx)
const MCOperand & getOperand(unsigned i) const
void emitStoreWithSymOffset(unsigned Opcode, unsigned SrcReg, unsigned BaseReg, MCOperand &HiOperand, MCOperand &LoOperand, unsigned ATReg, SMLoc IDLoc, const MCSubtargetInfo *STI)
Emit a store instruction with an symbol offset.
void LLVMInitializeMipsAsmParser()