60 #define DEBUG_TYPE "mips-asm-parser" 72 class MipsAssemblerOptions {
76 MipsAssemblerOptions(
const MipsAssemblerOptions *Opts) {
77 ATReg = Opts->getATRegIndex();
78 Reorder = Opts->isReorder();
79 Macro = Opts->isMacro();
83 unsigned getATRegIndex()
const {
return ATReg; }
84 bool setATRegIndex(
unsigned Reg) {
92 bool isReorder()
const {
return Reorder; }
93 void setReorder() { Reorder =
true; }
94 void setNoReorder() { Reorder =
false; }
96 bool isMacro()
const {
return Macro; }
97 void setMacro() {
Macro =
true; }
98 void setNoMacro() {
Macro =
false; }
119 const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
120 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
121 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
122 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
123 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
124 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
125 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
126 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
127 Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008
148 unsigned CpSaveLocation;
150 bool CpSaveLocationIsRegister;
156 void printWarningWithFixIt(
const Twine &Msg,
const Twine &FixMsg,
157 SMRange Range,
bool ShowColors =
true);
161 #define GET_ASSEMBLER_HEADER 162 #include "MipsGenAsmMatcher.inc" 165 checkEarlyTargetMatchPredicate(
MCInst &Inst,
167 unsigned checkTargetMatchPredicate(
MCInst &Inst)
override;
169 bool MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
172 bool MatchingInlineAsm)
override;
175 bool ParseRegister(
unsigned &RegNo,
SMLoc &StartLoc,
SMLoc &EndLoc)
override;
181 bool mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID);
186 bool ParseDirective(
AsmToken DirectiveID)
override;
207 enum MacroExpanderResultTy {
214 MacroExpanderResultTy tryExpandInstruction(
MCInst &Inst,
SMLoc IDLoc,
221 bool loadImmediate(int64_t ImmValue,
unsigned DstReg,
unsigned SrcReg,
222 bool Is32BitImm,
bool IsAddress,
SMLoc IDLoc,
225 bool loadAndAddSymbolAddress(
const MCExpr *SymExpr,
unsigned DstReg,
226 unsigned SrcReg,
bool Is32BitSym,
SMLoc IDLoc,
231 bool expandLoadImm(
MCInst &Inst,
bool Is32BitImm,
SMLoc IDLoc,
234 bool expandLoadImmReal(
MCInst &Inst,
bool IsSingle,
bool IsGPR,
bool Is64FPU,
238 bool expandLoadAddress(
unsigned DstReg,
unsigned BaseReg,
265 bool expandTrunc(
MCInst &Inst,
bool IsDouble,
bool Is64FPU,
SMLoc IDLoc,
313 bool reportParseError(
Twine ErrorMsg);
314 bool reportParseError(
SMLoc Loc,
Twine ErrorMsg);
316 bool parseMemOffset(
const MCExpr *&Res,
bool isParenExpr);
318 bool isEvaluated(
const MCExpr *Expr);
319 bool parseSetMips0Directive();
320 bool parseSetArchDirective();
321 bool parseSetFeature(uint64_t Feature);
322 bool isPicAndNotNxxAbi();
323 bool parseDirectiveCpLoad(
SMLoc Loc);
324 bool parseDirectiveCpRestore(
SMLoc Loc);
325 bool parseDirectiveCPSetup();
326 bool parseDirectiveCPReturn();
327 bool parseDirectiveNaN();
328 bool parseDirectiveSet();
329 bool parseDirectiveOption();
330 bool parseInsnDirective();
334 bool parseSetAtDirective();
335 bool parseSetNoAtDirective();
336 bool parseSetMacroDirective();
337 bool parseSetNoMacroDirective();
338 bool parseSetMsaDirective();
339 bool parseSetNoMsaDirective();
340 bool parseSetNoDspDirective();
341 bool parseSetReorderDirective();
342 bool parseSetNoReorderDirective();
343 bool parseSetMips16Directive();
344 bool parseSetNoMips16Directive();
345 bool parseSetFpDirective();
346 bool parseSetOddSPRegDirective();
347 bool parseSetNoOddSPRegDirective();
348 bool parseSetPopDirective();
349 bool parseSetPushDirective();
350 bool parseSetSoftFloatDirective();
351 bool parseSetHardFloatDirective();
352 bool parseSetMtDirective();
353 bool parseSetNoMtDirective();
354 bool parseSetNoCRCDirective();
355 bool parseSetNoVirtDirective();
356 bool parseSetNoGINVDirective();
358 bool parseSetAssignment();
360 bool parseDirectiveGpWord();
361 bool parseDirectiveGpDWord();
362 bool parseDirectiveDtpRelWord();
363 bool parseDirectiveDtpRelDWord();
364 bool parseDirectiveTpRelWord();
365 bool parseDirectiveTpRelDWord();
366 bool parseDirectiveModule();
367 bool parseDirectiveModuleFP();
371 bool parseInternalDirectiveReallowModule();
389 unsigned getReg(
int RC,
int RegNo);
394 unsigned getATReg(
SMLoc Loc);
404 bool validateMSAIndex(
int Val,
int RegKind);
431 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
433 setAvailableFeatures(
438 void setFeatureBits(uint64_t Feature,
StringRef FeatureString) {
439 if (!(getSTI().getFeatureBits()[Feature])) {
441 setAvailableFeatures(
447 void clearFeatureBits(uint64_t Feature,
StringRef FeatureString) {
448 if (getSTI().getFeatureBits()[Feature]) {
450 setAvailableFeatures(
456 void setModuleFeatureBits(uint64_t Feature,
StringRef FeatureString) {
457 setFeatureBits(Feature, FeatureString);
458 AssemblerOptions.
front()->setFeatures(getSTI().getFeatureBits());
461 void clearModuleFeatureBits(uint64_t Feature,
StringRef FeatureString) {
462 clearFeatureBits(Feature, FeatureString);
463 AssemblerOptions.
front()->setFeatures(getSTI().getFeatureBits());
467 enum MipsMatchResultTy {
468 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
469 Match_RequiresDifferentOperands,
470 Match_RequiresNoZeroRegister,
471 Match_RequiresSameSrcAndDst,
472 Match_NoFCCRegisterForCurrentISA,
473 Match_NonZeroOperandForSync,
474 Match_NonZeroOperandForMTCX,
475 Match_RequiresPosSizeRange0_32,
476 Match_RequiresPosSizeRange33_64,
477 Match_RequiresPosSizeUImm6,
478 #define GET_OPERAND_DIAGNOSTIC_TYPES 479 #include "MipsGenAsmMatcher.inc" 480 #undef GET_OPERAND_DIAGNOSTIC_TYPES 496 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
500 llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
504 llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
506 getTargetStreamer().updateABIInfo(*
this);
508 if (!isABI_O32() && !useOddSPReg() != 0)
513 IsPicEnabled = getContext().getObjectFileInfo()->isPositionIndependent();
515 IsCpRestoreSet =
false;
516 CpRestoreOffset = -1;
521 if (getSTI().
getCPU() ==
"mips64r6" && inMicroMipsMode())
524 if (!isABI_O32() && inMicroMipsMode())
529 bool hasEightFccRegisters()
const {
return hasMips4() || hasMips32(); }
531 bool isGP64bit()
const {
532 return getSTI().getFeatureBits()[Mips::FeatureGP64Bit];
535 bool isFP64bit()
const {
536 return getSTI().getFeatureBits()[Mips::FeatureFP64Bit];
540 bool isABI_N32()
const {
return ABI.
IsN32(); }
541 bool isABI_N64()
const {
return ABI.
IsN64(); }
542 bool isABI_O32()
const {
return ABI.
IsO32(); }
543 bool isABI_FPXX()
const {
544 return getSTI().getFeatureBits()[Mips::FeatureFPXX];
547 bool useOddSPReg()
const {
548 return !(getSTI().getFeatureBits()[Mips::FeatureNoOddSPReg]);
551 bool inMicroMipsMode()
const {
552 return getSTI().getFeatureBits()[Mips::FeatureMicroMips];
555 bool hasMips1()
const {
556 return getSTI().getFeatureBits()[Mips::FeatureMips1];
559 bool hasMips2()
const {
560 return getSTI().getFeatureBits()[Mips::FeatureMips2];
563 bool hasMips3()
const {
564 return getSTI().getFeatureBits()[Mips::FeatureMips3];
567 bool hasMips4()
const {
568 return getSTI().getFeatureBits()[Mips::FeatureMips4];
571 bool hasMips5()
const {
572 return getSTI().getFeatureBits()[Mips::FeatureMips5];
575 bool hasMips32()
const {
576 return getSTI().getFeatureBits()[Mips::FeatureMips32];
579 bool hasMips64()
const {
580 return getSTI().getFeatureBits()[Mips::FeatureMips64];
583 bool hasMips32r2()
const {
584 return getSTI().getFeatureBits()[Mips::FeatureMips32r2];
587 bool hasMips64r2()
const {
588 return getSTI().getFeatureBits()[Mips::FeatureMips64r2];
591 bool hasMips32r3()
const {
592 return (getSTI().getFeatureBits()[Mips::FeatureMips32r3]);
595 bool hasMips64r3()
const {
596 return (getSTI().getFeatureBits()[Mips::FeatureMips64r3]);
599 bool hasMips32r5()
const {
600 return (getSTI().getFeatureBits()[Mips::FeatureMips32r5]);
603 bool hasMips64r5()
const {
604 return (getSTI().getFeatureBits()[Mips::FeatureMips64r5]);
607 bool hasMips32r6()
const {
608 return getSTI().getFeatureBits()[Mips::FeatureMips32r6];
611 bool hasMips64r6()
const {
612 return getSTI().getFeatureBits()[Mips::FeatureMips64r6];
615 bool hasDSP()
const {
616 return getSTI().getFeatureBits()[Mips::FeatureDSP];
619 bool hasDSPR2()
const {
620 return getSTI().getFeatureBits()[Mips::FeatureDSPR2];
623 bool hasDSPR3()
const {
624 return getSTI().getFeatureBits()[Mips::FeatureDSPR3];
627 bool hasMSA()
const {
628 return getSTI().getFeatureBits()[Mips::FeatureMSA];
631 bool hasCnMips()
const {
632 return (getSTI().getFeatureBits()[Mips::FeatureCnMips]);
639 bool inMips16Mode()
const {
640 return getSTI().getFeatureBits()[Mips::FeatureMips16];
643 bool useTraps()
const {
644 return getSTI().getFeatureBits()[Mips::FeatureUseTCCInDIV];
647 bool useSoftFloat()
const {
648 return getSTI().getFeatureBits()[Mips::FeatureSoftFloat];
651 return getSTI().getFeatureBits()[Mips::FeatureMT];
654 bool hasCRC()
const {
655 return getSTI().getFeatureBits()[Mips::FeatureCRC];
658 bool hasVirt()
const {
659 return getSTI().getFeatureBits()[Mips::FeatureVirt];
662 bool hasGINV()
const {
663 return getSTI().getFeatureBits()[Mips::FeatureGINV];
667 void warnIfRegIndexIsAT(
unsigned RegIndex,
SMLoc Loc);
669 void warnIfNoMacro(
SMLoc Loc);
671 bool isLittle()
const {
return IsLittleEndian; }
676 switch(OperatorToken) {
744 RegKind_MSACtrl = 16,
749 RegKind_HWRegs = 256,
753 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
754 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
755 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
768 MipsOperand(KindTy K, MipsAsmParser &Parser)
771 ~MipsOperand()
override {
780 case k_RegisterIndex:
788 MipsAsmParser &AsmParser;
817 struct RegIdxOp RegIdx;
820 struct RegListOp RegList;
823 SMLoc StartLoc, EndLoc;
826 static std::unique_ptr<MipsOperand> CreateReg(
unsigned Index,
StringRef Str,
830 MipsAsmParser &Parser) {
831 auto Op = llvm::make_unique<MipsOperand>(k_RegisterIndex, Parser);
833 Op->RegIdx.RegInfo = RegInfo;
835 Op->RegIdx.Tok.Data = Str.
data();
836 Op->RegIdx.Tok.Length = Str.
size();
845 unsigned getGPR32Reg()
const {
846 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
847 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
848 unsigned ClassID = Mips::GPR32RegClassID;
849 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
854 unsigned getGPRMM16Reg()
const {
855 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
856 unsigned ClassID = Mips::GPR32RegClassID;
857 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
862 unsigned getGPR64Reg()
const {
863 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
864 unsigned ClassID = Mips::GPR64RegClassID;
865 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
871 unsigned getAFGR64Reg()
const {
872 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
873 if (RegIdx.Index % 2 != 0)
874 AsmParser.Warning(StartLoc,
"Float register should be even.");
875 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
876 .getRegister(RegIdx.Index / 2);
881 unsigned getFGR64Reg()
const {
882 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
883 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
884 .getRegister(RegIdx.Index);
889 unsigned getFGR32Reg()
const {
890 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
891 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
892 .getRegister(RegIdx.Index);
897 unsigned getFGRH32Reg()
const {
898 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
899 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
900 .getRegister(RegIdx.Index);
905 unsigned getFCCReg()
const {
906 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) &&
"Invalid access!");
907 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
908 .getRegister(RegIdx.Index);
913 unsigned getMSA128Reg()
const {
914 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) &&
"Invalid access!");
917 unsigned ClassID = Mips::MSA128BRegClassID;
918 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
923 unsigned getMSACtrlReg()
const {
924 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) &&
"Invalid access!");
925 unsigned ClassID = Mips::MSACtrlRegClassID;
926 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
931 unsigned getCOP0Reg()
const {
932 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) &&
"Invalid access!");
933 unsigned ClassID = Mips::COP0RegClassID;
934 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
939 unsigned getCOP2Reg()
const {
940 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) &&
"Invalid access!");
941 unsigned ClassID = Mips::COP2RegClassID;
942 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
947 unsigned getCOP3Reg()
const {
948 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) &&
"Invalid access!");
949 unsigned ClassID = Mips::COP3RegClassID;
950 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
955 unsigned getACC64DSPReg()
const {
956 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
957 unsigned ClassID = Mips::ACC64DSPRegClassID;
958 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
963 unsigned getHI32DSPReg()
const {
964 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
965 unsigned ClassID = Mips::HI32DSPRegClassID;
966 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
971 unsigned getLO32DSPReg()
const {
972 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
973 unsigned ClassID = Mips::LO32DSPRegClassID;
974 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
979 unsigned getCCRReg()
const {
980 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) &&
"Invalid access!");
981 unsigned ClassID = Mips::CCRRegClassID;
982 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
987 unsigned getHWRegsReg()
const {
988 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) &&
"Invalid access!");
989 unsigned ClassID = Mips::HWRegsRegClassID;
990 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
998 else if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
1004 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
1011 void addGPR32ZeroAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1012 assert(N == 1 &&
"Invalid number of operands!");
1016 void addGPR32NonZeroAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1017 assert(N == 1 &&
"Invalid number of operands!");
1021 void addGPR32AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1022 assert(N == 1 &&
"Invalid number of operands!");
1026 void addGPRMM16AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1027 assert(N == 1 &&
"Invalid number of operands!");
1031 void addGPRMM16AsmRegZeroOperands(
MCInst &Inst,
unsigned N)
const {
1032 assert(N == 1 &&
"Invalid number of operands!");
1036 void addGPRMM16AsmRegMovePOperands(
MCInst &Inst,
unsigned N)
const {
1037 assert(N == 1 &&
"Invalid number of operands!");
1041 void addGPRMM16AsmRegMovePPairFirstOperands(
MCInst &Inst,
unsigned N)
const {
1042 assert(N == 1 &&
"Invalid number of operands!");
1046 void addGPRMM16AsmRegMovePPairSecondOperands(
MCInst &Inst,
1048 assert(N == 1 &&
"Invalid number of operands!");
1055 void addGPR64AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1056 assert(N == 1 &&
"Invalid number of operands!");
1060 void addAFGR64AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1061 assert(N == 1 &&
"Invalid number of operands!");
1065 void addStrictlyAFGR64AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1066 assert(N == 1 &&
"Invalid number of operands!");
1070 void addStrictlyFGR64AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1071 assert(N == 1 &&
"Invalid number of operands!");
1075 void addFGR64AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1076 assert(N == 1 &&
"Invalid number of operands!");
1080 void addFGR32AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1081 assert(N == 1 &&
"Invalid number of operands!");
1085 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1086 AsmParser.getParser().printError(
1087 StartLoc,
"-mno-odd-spreg prohibits the use of odd FPU " 1091 void addStrictlyFGR32AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1092 assert(N == 1 &&
"Invalid number of operands!");
1095 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1096 AsmParser.Error(StartLoc,
"-mno-odd-spreg prohibits the use of odd FPU " 1100 void addFGRH32AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1101 assert(N == 1 &&
"Invalid number of operands!");
1105 void addFCCAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1106 assert(N == 1 &&
"Invalid number of operands!");
1110 void addMSA128AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1111 assert(N == 1 &&
"Invalid number of operands!");
1115 void addMSACtrlAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1116 assert(N == 1 &&
"Invalid number of operands!");
1120 void addCOP0AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1121 assert(N == 1 &&
"Invalid number of operands!");
1125 void addCOP2AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1126 assert(N == 1 &&
"Invalid number of operands!");
1130 void addCOP3AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1131 assert(N == 1 &&
"Invalid number of operands!");
1135 void addACC64DSPAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1136 assert(N == 1 &&
"Invalid number of operands!");
1140 void addHI32DSPAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1141 assert(N == 1 &&
"Invalid number of operands!");
1145 void addLO32DSPAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1146 assert(N == 1 &&
"Invalid number of operands!");
1150 void addCCRAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1151 assert(N == 1 &&
"Invalid number of operands!");
1155 void addHWRegsAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1156 assert(N == 1 &&
"Invalid number of operands!");
1160 template <
unsigned Bits,
int Offset = 0,
int AdjustOffset = 0>
1161 void addConstantUImmOperands(
MCInst &Inst,
unsigned N)
const {
1162 assert(N == 1 &&
"Invalid number of operands!");
1163 uint64_t Imm = getConstantImm() -
Offset;
1164 Imm &= (1ULL <<
Bits) - 1;
1166 Imm += AdjustOffset;
1170 template <
unsigned Bits>
1171 void addSImmOperands(
MCInst &Inst,
unsigned N)
const {
1172 if (isImm() && !isConstantImm()) {
1173 addExpr(Inst, getImm());
1176 addConstantSImmOperands<Bits, 0, 0>(Inst,
N);
1179 template <
unsigned Bits>
1180 void addUImmOperands(
MCInst &Inst,
unsigned N)
const {
1181 if (isImm() && !isConstantImm()) {
1182 addExpr(Inst, getImm());
1185 addConstantUImmOperands<Bits, 0, 0>(Inst,
N);
1188 template <
unsigned Bits,
int Offset = 0,
int AdjustOffset = 0>
1189 void addConstantSImmOperands(
MCInst &Inst,
unsigned N)
const {
1190 assert(N == 1 &&
"Invalid number of operands!");
1191 int64_t Imm = getConstantImm() -
Offset;
1192 Imm = SignExtend64<Bits>(Imm);
1194 Imm += AdjustOffset;
1198 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
1199 assert(N == 1 &&
"Invalid number of operands!");
1200 const MCExpr *Expr = getImm();
1201 addExpr(Inst, Expr);
1204 void addMemOperands(
MCInst &Inst,
unsigned N)
const {
1205 assert(N == 2 &&
"Invalid number of operands!");
1208 ? getMemBase()->getGPR64Reg()
1209 : getMemBase()->getGPR32Reg()));
1211 const MCExpr *Expr = getMemOff();
1212 addExpr(Inst, Expr);
1215 void addMicroMipsMemOperands(
MCInst &Inst,
unsigned N)
const {
1216 assert(N == 2 &&
"Invalid number of operands!");
1220 const MCExpr *Expr = getMemOff();
1221 addExpr(Inst, Expr);
1224 void addRegListOperands(
MCInst &Inst,
unsigned N)
const {
1225 assert(N == 1 &&
"Invalid number of operands!");
1227 for (
auto RegNo : getRegList())
1231 bool isReg()
const override {
1234 return isGPRAsmReg() && RegIdx.Index == 0;
1237 bool isRegIdx()
const {
return Kind == k_RegisterIndex; }
1238 bool isImm()
const override {
return Kind == k_Immediate; }
1240 bool isConstantImm()
const {
1242 return isImm() && getImm()->evaluateAsAbsolute(Res);
1245 bool isConstantImmz()
const {
1246 return isConstantImm() && getConstantImm() == 0;
1249 template <
unsigned Bits,
int Offset = 0>
bool isConstantUImm()
const {
1250 return isConstantImm() && isUInt<Bits>(getConstantImm() -
Offset);
1253 template <
unsigned Bits>
bool isSImm()
const {
1254 return isConstantImm() ? isInt<Bits>(getConstantImm()) : isImm();
1257 template <
unsigned Bits>
bool isUImm()
const {
1258 return isConstantImm() ? isUInt<Bits>(getConstantImm()) : isImm();
1261 template <
unsigned Bits>
bool isAnyImm()
const {
1262 return isConstantImm() ? (isInt<Bits>(getConstantImm()) ||
1263 isUInt<Bits>(getConstantImm()))
1267 template <
unsigned Bits,
int Offset = 0>
bool isConstantSImm()
const {
1268 return isConstantImm() && isInt<Bits>(getConstantImm() -
Offset);
1271 template <
unsigned Bottom,
unsigned Top>
bool isConstantUImmRange()
const {
1272 return isConstantImm() && getConstantImm() >= Bottom &&
1273 getConstantImm() <= Top;
1276 bool isToken()
const override {
1279 return Kind == k_Token;
1282 bool isMem()
const override {
return Kind == k_Memory; }
1284 bool isConstantMemOff()
const {
1285 return isMem() && isa<MCConstantExpr>(getMemOff());
1291 template <
unsigned Bits,
unsigned ShiftAmount = 0>
1292 bool isMemWithSimmOffset()
const {
1295 if (!getMemBase()->isGPRAsmReg())
1297 if (isa<MCTargetExpr>(getMemOff()) ||
1298 (isConstantMemOff() &&
1299 isShiftedInt<Bits, ShiftAmount>(getConstantMemOff())))
1302 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res,
nullptr,
nullptr);
1303 return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.
getConstant());
1306 bool isMemWithPtrSizeOffset()
const {
1309 if (!getMemBase()->isGPRAsmReg())
1311 const unsigned PtrBits = AsmParser.getABI().ArePtrs64bit() ? 64 : 32;
1312 if (isa<MCTargetExpr>(getMemOff()) ||
1313 (isConstantMemOff() &&
isIntN(PtrBits, getConstantMemOff())))
1316 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res,
nullptr,
nullptr);
1320 bool isMemWithGRPMM16Base()
const {
1321 return isMem() && getMemBase()->isMM16AsmReg();
1324 template <
unsigned Bits>
bool isMemWithUimmOffsetSP()
const {
1325 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1326 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1329 template <
unsigned Bits>
bool isMemWithUimmWordAlignedOffsetSP()
const {
1330 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1331 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1332 && (getMemBase()->getGPR32Reg() == Mips::SP);
1335 template <
unsigned Bits>
bool isMemWithSimmWordAlignedOffsetGP()
const {
1336 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
1337 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1338 && (getMemBase()->getGPR32Reg() == Mips::GP);
1341 template <
unsigned Bits,
unsigned ShiftLeftAmount>
1342 bool isScaledUImm()
const {
1343 return isConstantImm() &&
1344 isShiftedUInt<Bits, ShiftLeftAmount>(getConstantImm());
1347 template <
unsigned Bits,
unsigned ShiftLeftAmount>
1348 bool isScaledSImm()
const {
1349 if (isConstantImm() &&
1350 isShiftedInt<Bits, ShiftLeftAmount>(getConstantImm()))
1354 if (Kind != k_Immediate)
1357 bool Success = getImm()->evaluateAsRelocatable(Res,
nullptr,
nullptr);
1358 return Success && isShiftedInt<Bits, ShiftLeftAmount>(Res.
getConstant());
1361 bool isRegList16()
const {
1365 int Size = RegList.List->size();
1366 if (Size < 2 || Size > 5)
1369 unsigned R0 = RegList.List->front();
1370 unsigned R1 = RegList.List->back();
1371 if (!((R0 == Mips::S0 && R1 ==
Mips::RA) ||
1372 (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1375 int PrevReg = *RegList.List->begin();
1376 for (
int i = 1; i < Size - 1; i++) {
1377 int Reg = (*(RegList.List))[i];
1378 if ( Reg != PrevReg + 1)
1386 bool isInvNum()
const {
return Kind == k_Immediate; }
1388 bool isLSAImm()
const {
1389 if (!isConstantImm())
1391 int64_t Val = getConstantImm();
1392 return 1 <= Val && Val <= 4;
1395 bool isRegList()
const {
return Kind == k_RegList; }
1398 assert(Kind == k_Token &&
"Invalid access!");
1402 unsigned getReg()
const override {
1405 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1406 RegIdx.Kind & RegKind_GPR)
1407 return getGPR32Reg();
1413 const MCExpr *getImm()
const {
1414 assert((Kind == k_Immediate) &&
"Invalid access!");
1418 int64_t getConstantImm()
const {
1419 const MCExpr *Val = getImm();
1421 (void)Val->evaluateAsAbsolute(Value);
1425 MipsOperand *getMemBase()
const {
1426 assert((Kind == k_Memory) &&
"Invalid access!");
1430 const MCExpr *getMemOff()
const {
1431 assert((Kind == k_Memory) &&
"Invalid access!");
1435 int64_t getConstantMemOff()
const {
1436 return static_cast<const MCConstantExpr *
>(getMemOff())->getValue();
1440 assert((Kind == k_RegList) &&
"Invalid access!");
1441 return *(RegList.List);
1444 static std::unique_ptr<MipsOperand> CreateToken(
StringRef Str,
SMLoc S,
1445 MipsAsmParser &Parser) {
1446 auto Op = llvm::make_unique<MipsOperand>(k_Token, Parser);
1447 Op->Tok.Data = Str.
data();
1448 Op->Tok.Length = Str.
size();
1456 static std::unique_ptr<MipsOperand>
1459 LLVM_DEBUG(
dbgs() <<
"createNumericReg(" << Index <<
", ...)\n");
1460 return CreateReg(Index, Str, RegKind_Numeric, RegInfo, S, E, Parser);
1465 static std::unique_ptr<MipsOperand>
1468 return CreateReg(Index, Str, RegKind_GPR, RegInfo, S, E, Parser);
1473 static std::unique_ptr<MipsOperand>
1476 return CreateReg(Index, Str, RegKind_FGR, RegInfo, S, E, Parser);
1481 static std::unique_ptr<MipsOperand>
1484 return CreateReg(Index, Str, RegKind_HWRegs, RegInfo, S, E, Parser);
1489 static std::unique_ptr<MipsOperand>
1492 return CreateReg(Index, Str, RegKind_FCC, RegInfo, S, E, Parser);
1497 static std::unique_ptr<MipsOperand>
1500 return CreateReg(Index, Str, RegKind_ACC, RegInfo, S, E, Parser);
1505 static std::unique_ptr<MipsOperand>
1508 return CreateReg(Index, Str, RegKind_MSA128, RegInfo, S, E, Parser);
1513 static std::unique_ptr<MipsOperand>
1516 return CreateReg(Index, Str, RegKind_MSACtrl, RegInfo, S, E, Parser);
1519 static std::unique_ptr<MipsOperand>
1521 auto Op = llvm::make_unique<MipsOperand>(k_Immediate, Parser);
1528 static std::unique_ptr<MipsOperand>
1529 CreateMem(std::unique_ptr<MipsOperand>
Base,
const MCExpr *Off,
SMLoc S,
1530 SMLoc E, MipsAsmParser &Parser) {
1531 auto Op = llvm::make_unique<MipsOperand>(k_Memory, Parser);
1532 Op->Mem.Base = Base.release();
1539 static std::unique_ptr<MipsOperand>
1541 MipsAsmParser &Parser) {
1542 assert(Regs.
size() > 0 &&
"Empty list not allowed");
1544 auto Op = llvm::make_unique<MipsOperand>(k_RegList, Parser);
1546 Op->StartLoc = StartLoc;
1547 Op->EndLoc = EndLoc;
1551 bool isGPRZeroAsmReg()
const {
1552 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
1555 bool isGPRNonZeroAsmReg()
const {
1556 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index > 0 &&
1560 bool isGPRAsmReg()
const {
1561 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1564 bool isMM16AsmReg()
const {
1565 if (!(isRegIdx() && RegIdx.Kind))
1567 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1568 || RegIdx.Index == 16 || RegIdx.Index == 17);
1571 bool isMM16AsmRegZero()
const {
1572 if (!(isRegIdx() && RegIdx.Kind))
1574 return (RegIdx.Index == 0 ||
1575 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1576 RegIdx.Index == 17);
1579 bool isMM16AsmRegMoveP()
const {
1580 if (!(isRegIdx() && RegIdx.Kind))
1582 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1583 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1586 bool isMM16AsmRegMovePPairFirst()
const {
1587 if (!(isRegIdx() && RegIdx.Kind))
1589 return RegIdx.Index >= 4 && RegIdx.Index <= 6;
1592 bool isMM16AsmRegMovePPairSecond()
const {
1593 if (!(isRegIdx() && RegIdx.Kind))
1595 return (RegIdx.Index == 21 || RegIdx.Index == 22 ||
1596 (RegIdx.Index >= 5 && RegIdx.Index <= 7));
1599 bool isFGRAsmReg()
const {
1601 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1604 bool isStrictlyFGRAsmReg()
const {
1606 return isRegIdx() && RegIdx.Kind == RegKind_FGR && RegIdx.Index <= 31;
1609 bool isHWRegsAsmReg()
const {
1610 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1613 bool isCCRAsmReg()
const {
1614 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1617 bool isFCCAsmReg()
const {
1618 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1620 return RegIdx.Index <= 7;
1623 bool isACCAsmReg()
const {
1624 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1627 bool isCOP0AsmReg()
const {
1628 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1631 bool isCOP2AsmReg()
const {
1632 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1635 bool isCOP3AsmReg()
const {
1636 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1639 bool isMSA128AsmReg()
const {
1640 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1643 bool isMSACtrlAsmReg()
const {
1644 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1648 SMLoc getStartLoc()
const override {
return StartLoc; }
1650 SMLoc getEndLoc()
const override {
return EndLoc; }
1661 Mem.Base->print(OS);
1666 case k_RegisterIndex:
1667 OS <<
"RegIdx<" << RegIdx.Index <<
":" << RegIdx.Kind <<
", " 1668 <<
StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) <<
">";
1675 for (
auto Reg : (*RegList.List))
1682 bool isValidForTie(
const MipsOperand &
Other)
const {
1683 if (Kind != Other.Kind)
1690 case k_RegisterIndex: {
1691 StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length);
1692 StringRef OtherToken(Other.RegIdx.Tok.Data, Other.RegIdx.Tok.Length);
1693 return Token == OtherToken;
1719 case Mips::JRC16_MM:
1721 case Mips::JALRS_MM:
1722 case Mips::JALRS16_MM:
1723 case Mips::BGEZALS_MM:
1724 case Mips::BLTZALS_MM:
1734 if (
const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1735 return &SRExpr->getSymbol();
1738 if (
const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1751 if (
const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1758 if (isa<MCSymbolRefExpr>(Expr))
1761 if (
const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1765 if (
const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1771 bool MipsAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
1776 bool ExpandedJalSym =
false;
1781 const unsigned Opcode = Inst.
getOpcode();
1791 assert(hasCnMips() &&
"instruction only valid for octeon cpus");
1800 if (!Offset.isImm())
1802 if (!
isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1803 return Error(IDLoc,
"branch target out of range");
1805 1LL << (inMicroMipsMode() ? 1 : 2)))
1806 return Error(IDLoc,
"branch to misaligned address");
1820 case Mips::BGEZAL_MM:
1821 case Mips::BLTZAL_MM:
1824 case Mips::BC1EQZC_MMR6:
1825 case Mips::BC1NEZC_MMR6:
1826 case Mips::BC2EQZC_MMR6:
1827 case Mips::BC2NEZC_MMR6:
1830 if (!Offset.isImm())
1832 if (!
isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1833 return Error(IDLoc,
"branch target out of range");
1835 1LL << (inMicroMipsMode() ? 1 : 2)))
1836 return Error(IDLoc,
"branch to misaligned address");
1838 case Mips::BGEC:
case Mips::BGEC_MMR6:
1839 case Mips::BLTC:
case Mips::BLTC_MMR6:
1840 case Mips::BGEUC:
case Mips::BGEUC_MMR6:
1841 case Mips::BLTUC:
case Mips::BLTUC_MMR6:
1842 case Mips::BEQC:
case Mips::BEQC_MMR6:
1843 case Mips::BNEC:
case Mips::BNEC_MMR6:
1846 if (!Offset.isImm())
1848 if (!
isIntN(18, Offset.getImm()))
1849 return Error(IDLoc,
"branch target out of range");
1851 return Error(IDLoc,
"branch to misaligned address");
1853 case Mips::BLEZC:
case Mips::BLEZC_MMR6:
1854 case Mips::BGEZC:
case Mips::BGEZC_MMR6:
1855 case Mips::BGTZC:
case Mips::BGTZC_MMR6:
1856 case Mips::BLTZC:
case Mips::BLTZC_MMR6:
1859 if (!Offset.isImm())
1861 if (!
isIntN(18, Offset.getImm()))
1862 return Error(IDLoc,
"branch target out of range");
1864 return Error(IDLoc,
"branch to misaligned address");
1866 case Mips::BEQZC:
case Mips::BEQZC_MMR6:
1867 case Mips::BNEZC:
case Mips::BNEZC_MMR6:
1870 if (!Offset.isImm())
1872 if (!
isIntN(23, Offset.getImm()))
1873 return Error(IDLoc,
"branch target out of range");
1875 return Error(IDLoc,
"branch to misaligned address");
1877 case Mips::BEQZ16_MM:
1878 case Mips::BEQZC16_MMR6:
1879 case Mips::BNEZ16_MM:
1880 case Mips::BNEZC16_MMR6:
1883 if (!Offset.isImm())
1886 return Error(IDLoc,
"branch target out of range");
1888 return Error(IDLoc,
"branch to misaligned address");
1895 if (hasMips32r6() && Inst.
getOpcode() == Mips::SSNOP) {
1896 std::string ISA = hasMips64r6() ?
"MIPS64r6" :
"MIPS32r6";
1897 Warning(IDLoc,
"ssnop is deprecated for " + ISA +
" and is equivalent to a " 1902 const unsigned Opcode = Inst.
getOpcode();
1918 return Error(IDLoc,
"expected immediate operand kind");
1919 Imm = Opnd.getImm();
1920 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1921 Opcode == Mips::BBIT1 ? 63 : 31))
1922 return Error(IDLoc,
"immediate operand value out of range");
1924 Inst.
setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1935 return Error(IDLoc,
"expected immediate operand kind");
1936 Imm = Opnd.getImm();
1937 if (!isInt<10>(Imm))
1938 return Error(IDLoc,
"immediate operand value out of range");
1950 unsigned FirstOp = 1;
1951 unsigned SecondOp = 2;
1955 case Mips::SDivIMacro:
1956 case Mips::UDivIMacro:
1957 case Mips::DSDivIMacro:
1958 case Mips::DUDivIMacro:
1962 Warning(IDLoc,
"dividing zero by zero");
1964 Warning(IDLoc,
"division by zero");
1976 case Mips::SDivMacro:
1977 case Mips::DSDivMacro:
1978 case Mips::UDivMacro:
1979 case Mips::DUDivMacro:
1984 case Mips::DIVU_MMR6:
1985 case Mips::DIV_MMR6:
1990 Warning(IDLoc,
"dividing zero by zero");
1992 Warning(IDLoc,
"division by zero");
2001 BInst.
setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
2012 warnIfNoMacro(IDLoc);
2019 return Error(IDLoc,
"jal doesn't support multiple symbols in PIC mode");
2038 const MCExpr *Got16RelocExpr =
2040 const MCExpr *Lo16RelocExpr =
2043 TOut.
emitRRX(Mips::LW, Mips::T9, Mips::GP,
2045 TOut.
emitRRX(Mips::ADDiu, Mips::T9, Mips::T9,
2047 }
else if (isABI_N32() || isABI_N64()) {
2053 const MCExpr *GotDispRelocExpr =
2065 const MCExpr *Call16RelocExpr =
2073 if (IsCpRestoreSet && inMicroMipsMode())
2076 JalrInst.
setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2080 if (EmitJalrReloc) {
2084 MCSymbol *TmpLabel = getContext().createTempSymbol();
2086 const MCExpr *RelocJalrExpr =
2088 getContext(), IDLoc);
2091 inMicroMipsMode() ?
"R_MICROMIPS_JALR" :
"R_MIPS_JALR",
2092 RelocJalrExpr, IDLoc, *STI);
2097 ExpandedJalSym =
true;
2110 int64_t MemOffset = Op.
getImm();
2111 if (MemOffset < -32768 || MemOffset > 32767) {
2113 expandMemInst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2114 return getParser().hasPendingError();
2116 }
else if (Op.
isExpr()) {
2123 expandMemInst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2124 return getParser().hasPendingError();
2126 }
else if (!isEvaluated(Expr)) {
2127 expandMemInst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2128 return getParser().hasPendingError();
2135 if (inMicroMipsMode()) {
2144 int MemOffset = Op.
getImm();
2147 if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
2150 (BaseReg.
getReg() == Mips::GP ||
2151 BaseReg.
getReg() == Mips::GP_64)) {
2153 TOut.
emitRRI(Mips::LWGP_MM, DstReg.
getReg(), Mips::GP, MemOffset,
2170 case Mips::ADDIUSP_MM:
2173 return Error(IDLoc,
"expected immediate operand kind");
2175 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
2177 return Error(IDLoc,
"immediate operand value out of range");
2179 case Mips::SLL16_MM:
2180 case Mips::SRL16_MM:
2183 return Error(IDLoc,
"expected immediate operand kind");
2185 if (Imm < 1 || Imm > 8)
2186 return Error(IDLoc,
"immediate operand value out of range");
2191 return Error(IDLoc,
"expected immediate operand kind");
2193 if (Imm < -1 || Imm > 126)
2194 return Error(IDLoc,
"immediate operand value out of range");
2196 case Mips::ADDIUR2_MM:
2199 return Error(IDLoc,
"expected immediate operand kind");
2201 if (!(Imm == 1 || Imm == -1 ||
2202 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
2203 return Error(IDLoc,
"immediate operand value out of range");
2205 case Mips::ANDI16_MM:
2208 return Error(IDLoc,
"expected immediate operand kind");
2210 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
2211 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
2212 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
2213 return Error(IDLoc,
"immediate operand value out of range");
2215 case Mips::LBU16_MM:
2218 return Error(IDLoc,
"expected immediate operand kind");
2220 if (Imm < -1 || Imm > 14)
2221 return Error(IDLoc,
"immediate operand value out of range");
2224 case Mips::SB16_MMR6:
2227 return Error(IDLoc,
"expected immediate operand kind");
2229 if (Imm < 0 || Imm > 15)
2230 return Error(IDLoc,
"immediate operand value out of range");
2232 case Mips::LHU16_MM:
2234 case Mips::SH16_MMR6:
2237 return Error(IDLoc,
"expected immediate operand kind");
2239 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
2240 return Error(IDLoc,
"immediate operand value out of range");
2244 case Mips::SW16_MMR6:
2247 return Error(IDLoc,
"expected immediate operand kind");
2249 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
2250 return Error(IDLoc,
"immediate operand value out of range");
2252 case Mips::ADDIUPC_MM:
2255 return Error(IDLoc,
"expected immediate operand kind");
2257 if ((Imm % 4 != 0) || !isInt<25>(Imm))
2258 return Error(IDLoc,
"immediate operand value out of range");
2263 return Error(IDLoc,
"invalid operand for instruction");
2265 case Mips::MOVEP_MM:
2266 case Mips::MOVEP_MMR6: {
2269 bool RegPair = ((R0 == Mips::A1 && R1 == Mips::A2) ||
2270 (R0 == Mips::A1 && R1 == Mips::A3) ||
2271 (R0 == Mips::A2 && R1 == Mips::A3) ||
2272 (R0 == Mips::A0 && R1 == Mips::S5) ||
2273 (R0 == Mips::A0 && R1 == Mips::S6) ||
2274 (R0 == Mips::A0 && R1 == Mips::A1) ||
2275 (R0 == Mips::A0 && R1 == Mips::A2) ||
2276 (R0 == Mips::A0 && R1 == Mips::A3));
2278 return Error(IDLoc,
"invalid operand for instruction");
2284 bool FillDelaySlot =
2289 MacroExpanderResultTy ExpandResult =
2290 tryExpandInstruction(Inst, IDLoc, Out, STI);
2291 switch (ExpandResult) {
2303 if (inMicroMipsMode()) {
2310 if (FillDelaySlot) {
2315 if ((Inst.
getOpcode() == Mips::JalOneReg ||
2316 Inst.
getOpcode() == Mips::JalTwoReg || ExpandedJalSym) &&
2317 isPicAndNotNxxAbi()) {
2318 if (IsCpRestoreSet) {
2322 if (!AssemblerOptions.
back()->isReorder())
2329 Warning(IDLoc,
"no .cprestore used in PIC mode");
2335 MipsAsmParser::MacroExpanderResultTy
2340 return MER_NotAMacro;
2341 case Mips::LoadImm32:
2342 return expandLoadImm(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2343 case Mips::LoadImm64:
2344 return expandLoadImm(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2345 case Mips::LoadAddrImm32:
2346 case Mips::LoadAddrImm64:
2349 "expected immediate operand kind");
2353 Inst.
getOpcode() == Mips::LoadAddrImm32, IDLoc,
2357 case Mips::LoadAddrReg32:
2358 case Mips::LoadAddrReg64:
2362 "expected immediate operand kind");
2366 Inst.
getOpcode() == Mips::LoadAddrReg32, IDLoc,
2370 case Mips::B_MM_Pseudo:
2371 case Mips::B_MMR6_Pseudo:
2372 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2376 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2378 case Mips::JalOneReg:
2379 case Mips::JalTwoReg:
2380 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2383 case Mips::BEQLImmMacro:
2384 case Mips::BNELImmMacro:
2385 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2402 case Mips::BLTImmMacro:
2403 case Mips::BLEImmMacro:
2404 case Mips::BGEImmMacro:
2405 case Mips::BGTImmMacro:
2406 case Mips::BLTUImmMacro:
2407 case Mips::BLEUImmMacro:
2408 case Mips::BGEUImmMacro:
2409 case Mips::BGTUImmMacro:
2410 case Mips::BLTLImmMacro:
2411 case Mips::BLELImmMacro:
2412 case Mips::BGELImmMacro:
2413 case Mips::BGTLImmMacro:
2414 case Mips::BLTULImmMacro:
2415 case Mips::BLEULImmMacro:
2416 case Mips::BGEULImmMacro:
2417 case Mips::BGTULImmMacro:
2418 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2419 case Mips::SDivMacro:
2420 case Mips::SDivIMacro:
2421 case Mips::SRemMacro:
2422 case Mips::SRemIMacro:
2423 return expandDivRem(Inst, IDLoc, Out, STI,
false,
true) ? MER_Fail
2425 case Mips::DSDivMacro:
2426 case Mips::DSDivIMacro:
2427 case Mips::DSRemMacro:
2428 case Mips::DSRemIMacro:
2429 return expandDivRem(Inst, IDLoc, Out, STI,
true,
true) ? MER_Fail
2431 case Mips::UDivMacro:
2432 case Mips::UDivIMacro:
2433 case Mips::URemMacro:
2434 case Mips::URemIMacro:
2435 return expandDivRem(Inst, IDLoc, Out, STI,
false,
false) ? MER_Fail
2437 case Mips::DUDivMacro:
2438 case Mips::DUDivIMacro:
2439 case Mips::DURemMacro:
2440 case Mips::DURemIMacro:
2441 return expandDivRem(Inst, IDLoc, Out, STI,
true,
false) ? MER_Fail
2443 case Mips::PseudoTRUNC_W_S:
2444 return expandTrunc(Inst,
false,
false, IDLoc, Out, STI) ? MER_Fail
2446 case Mips::PseudoTRUNC_W_D32:
2447 return expandTrunc(Inst,
true,
false, IDLoc, Out, STI) ? MER_Fail
2449 case Mips::PseudoTRUNC_W_D:
2450 return expandTrunc(Inst,
true,
true, IDLoc, Out, STI) ? MER_Fail
2453 case Mips::LoadImmSingleGPR:
2454 return expandLoadImmReal(Inst,
true,
true,
false, IDLoc, Out, STI)
2457 case Mips::LoadImmSingleFGR:
2458 return expandLoadImmReal(Inst,
true,
false,
false, IDLoc, Out, STI)
2461 case Mips::LoadImmDoubleGPR:
2462 return expandLoadImmReal(Inst,
false,
true,
false, IDLoc, Out, STI)
2465 case Mips::LoadImmDoubleFGR:
2466 return expandLoadImmReal(Inst,
false,
false,
true, IDLoc, Out, STI)
2469 case Mips::LoadImmDoubleFGR_32:
2470 return expandLoadImmReal(Inst,
false,
false,
false, IDLoc, Out, STI)
2474 return expandUlh(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2476 return expandUlh(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2478 return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2481 return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2483 case Mips::NORImm64:
2484 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2485 case Mips::SLTImm64:
2488 return MER_NotAMacro;
2490 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2491 case Mips::SLTUImm64:
2494 return MER_NotAMacro;
2496 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2497 case Mips::ADDi:
case Mips::ADDi_MM:
2498 case Mips::ADDiu:
case Mips::ADDiu_MM:
2499 case Mips::SLTi:
case Mips::SLTi_MM:
2500 case Mips::SLTiu:
case Mips::SLTiu_MM:
2505 return MER_NotAMacro;
2506 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2509 return MER_NotAMacro;
2510 case Mips::ANDi:
case Mips::ANDi_MM:
case Mips::ANDi64:
2511 case Mips::ORi:
case Mips::ORi_MM:
case Mips::ORi64:
2512 case Mips::XORi:
case Mips::XORi_MM:
case Mips::XORi64:
2517 return MER_NotAMacro;
2518 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2521 return MER_NotAMacro;
2524 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2527 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2530 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2533 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2534 case Mips::ABSMacro:
2535 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2536 case Mips::MULImmMacro:
2537 case Mips::DMULImmMacro:
2538 return expandMulImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2539 case Mips::MULOMacro:
2540 case Mips::DMULOMacro:
2541 return expandMulO(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2542 case Mips::MULOUMacro:
2543 case Mips::DMULOUMacro:
2544 return expandMulOU(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2545 case Mips::DMULMacro:
2546 return expandDMULMacro(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2549 return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2553 case Mips::SEQMacro:
2554 return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2555 case Mips::SEQIMacro:
2556 return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2557 case Mips::MFTC0:
case Mips::MTTC0:
2558 case Mips::MFTGPR:
case Mips::MTTGPR:
2559 case Mips::MFTLO:
case Mips::MTTLO:
2560 case Mips::MFTHI:
case Mips::MTTHI:
2561 case Mips::MFTACX:
case Mips::MTTACX:
2562 case Mips::MFTDSP:
case Mips::MTTDSP:
2563 case Mips::MFTC1:
case Mips::MTTC1:
2564 case Mips::MFTHC1:
case Mips::MTTHC1:
2565 case Mips::CFTC1:
case Mips::CTTC1:
2566 return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2570 bool MipsAsmParser::expandJalWithRegs(
MCInst &Inst,
SMLoc IDLoc,
2579 const unsigned Opcode = Inst.
getOpcode();
2581 if (Opcode == Mips::JalOneReg) {
2583 if (IsCpRestoreSet && inMicroMipsMode()) {
2586 }
else if (inMicroMipsMode()) {
2587 JalrInst.
setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2594 }
else if (Opcode == Mips::JalTwoReg) {
2596 if (IsCpRestoreSet && inMicroMipsMode())
2599 JalrInst.
setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2620 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2633 bool MipsAsmParser::loadImmediate(int64_t ImmValue,
unsigned DstReg,
2634 unsigned SrcReg,
bool Is32BitImm,
2639 if (!Is32BitImm && !isGP64bit()) {
2640 Error(IDLoc,
"instruction requires a 64-bit architecture");
2649 ImmValue = SignExtend64<32>(ImmValue);
2651 Error(IDLoc,
"instruction requires a 32-bit immediate");
2657 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2659 bool UseSrcReg =
false;
2660 if (SrcReg != Mips::NoRegister)
2663 unsigned TmpReg = DstReg;
2665 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2668 unsigned ATReg = getATReg(IDLoc);
2681 if (IsAddress && !Is32BitImm) {
2682 TOut.
emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2686 TOut.
emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2691 unsigned TmpReg = DstReg;
2692 if (SrcReg == DstReg) {
2693 TmpReg = getATReg(IDLoc);
2698 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2705 warnIfNoMacro(IDLoc);
2707 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2708 uint16_t Bits15To0 = ImmValue & 0xffff;
2709 if (!Is32BitImm && !
isInt<32>(ImmValue)) {
2712 if (ImmValue == 0xffffffff) {
2713 TOut.
emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2714 TOut.
emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2716 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2722 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2723 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2725 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2727 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2731 TOut.
emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2733 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2735 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2739 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2741 Error(IDLoc,
"instruction requires a 32-bit immediate");
2748 unsigned LastSet =
findLastSet((uint64_t)ImmValue);
2749 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2750 uint16_t
Bits = (ImmValue >> ShiftAmount) & 0xffff;
2751 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2752 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2755 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2760 warnIfNoMacro(IDLoc);
2767 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister,
true,
false,
2773 unsigned ShiftCarriedForwards = 16;
2774 for (
int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2775 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2777 if (ImmChunk != 0) {
2778 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2779 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2780 ShiftCarriedForwards = 0;
2783 ShiftCarriedForwards += 16;
2785 ShiftCarriedForwards -= 16;
2788 if (ShiftCarriedForwards)
2789 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2792 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2797 bool MipsAsmParser::expandLoadImm(
MCInst &Inst,
bool Is32BitImm,
SMLoc IDLoc,
2800 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
2802 assert(DstRegOp.isReg() &&
"expected register operand kind");
2804 if (loadImmediate(ImmOp.
getImm(), DstRegOp.getReg(), Mips::NoRegister,
2805 Is32BitImm,
false, IDLoc, Out, STI))
2811 bool MipsAsmParser::expandLoadAddress(
unsigned DstReg,
unsigned BaseReg,
2813 bool Is32BitAddress,
SMLoc IDLoc,
2821 Error(IDLoc,
"la used to load 64-bit address");
2823 Is32BitAddress =
false;
2828 if (!Is32BitAddress && !hasMips3()) {
2829 Error(IDLoc,
"instruction requires a 64-bit architecture");
2833 if (!Offset.
isImm())
2834 return loadAndAddSymbolAddress(Offset.
getExpr(), DstReg, BaseReg,
2835 Is32BitAddress, IDLoc, Out, STI);
2839 Is32BitAddress =
true;
2842 return loadImmediate(Offset.
getImm(), DstReg, BaseReg, Is32BitAddress,
true,
2846 bool MipsAsmParser::loadAndAddSymbolAddress(
const MCExpr *SymExpr,
2847 unsigned DstReg,
unsigned SrcReg,
2848 bool Is32BitSym,
SMLoc IDLoc,
2853 bool UseSrcReg = SrcReg != Mips::NoRegister;
2854 warnIfNoMacro(IDLoc);
2856 if (inPicMode() && ABI.
IsO32()) {
2859 Error(IDLoc,
"expected relocatable expression");
2862 if (Res.
getSymB() !=
nullptr) {
2863 Error(IDLoc,
"expected relocatable expression with only one symbol");
2870 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2896 const MCExpr *LoExpr =
nullptr;
2907 unsigned TmpReg = DstReg;
2909 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2913 unsigned ATReg = getATReg(IDLoc);
2927 TOut.
emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
2935 Error(IDLoc,
"expected relocatable expression");
2938 if (Res.
getSymB() !=
nullptr) {
2939 Error(IDLoc,
"expected relocatable expression with only one symbol");
2946 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2970 const MCExpr *LoExpr =
nullptr;
2980 Error(IDLoc,
"macro instruction uses large offset, which is not " 2981 "currently supported");
2986 unsigned TmpReg = DstReg;
2988 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2992 unsigned ATReg = getATReg(IDLoc);
3006 TOut.
emitRRR(Mips::DADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3031 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
3033 if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
3034 unsigned ATReg = getATReg(IDLoc);
3046 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3048 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3051 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3054 TOut.
emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
3057 }
else if (canUseATReg() && !RdRegIsRsReg) {
3058 unsigned ATReg = getATReg(IDLoc);
3074 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3078 TOut.
emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3079 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3081 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3084 }
else if (!canUseATReg() && !RdRegIsRsReg) {
3095 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3097 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3098 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3100 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3101 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3104 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3110 assert(SrcReg == DstReg && !canUseATReg() &&
3111 "Could have expanded dla but didn't?");
3112 reportParseError(IDLoc,
3113 "pseudo-instruction requires $at, which is not available");
3127 unsigned TmpReg = DstReg;
3129 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
3132 unsigned ATReg = getATReg(IDLoc);
3143 TOut.
emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3146 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
3155 if (MipsMCRegisterClasses[Mips::FGR32RegClassID].
contains(Reg))
3156 return Reg == (
unsigned)Mips::F31 ? (
unsigned)Mips::F0 : Reg + 1;
3158 default:
llvm_unreachable(
"Unknown register in assembly macro expansion!");
3159 case Mips::ZERO:
return Mips::AT;
3160 case Mips::AT:
return Mips::V0;
3161 case Mips::V0:
return Mips::V1;
3162 case Mips::V1:
return Mips::A0;
3163 case Mips::A0:
return Mips::A1;
3164 case Mips::A1:
return Mips::A2;
3165 case Mips::A2:
return Mips::A3;
3166 case Mips::A3:
return Mips::T0;
3169 case Mips::T2:
return Mips::T3;
3170 case Mips::T3:
return Mips::T4;
3171 case Mips::T4:
return Mips::T5;
3172 case Mips::T5:
return Mips::T6;
3173 case Mips::T6:
return Mips::T7;
3174 case Mips::T7:
return Mips::S0;
3175 case Mips::S0:
return Mips::S1;
3176 case Mips::S1:
return Mips::S2;
3177 case Mips::S2:
return Mips::S3;
3178 case Mips::S3:
return Mips::S4;
3179 case Mips::S4:
return Mips::S5;
3180 case Mips::S5:
return Mips::S6;
3181 case Mips::S6:
return Mips::S7;
3184 case Mips::T9:
return Mips::K0;
3185 case Mips::K0:
return Mips::K1;
3186 case Mips::K1:
return Mips::GP;
3187 case Mips::GP:
return Mips::SP;
3191 case Mips::D0:
return Mips::F1;
3192 case Mips::D1:
return Mips::F3;
3193 case Mips::D2:
return Mips::F5;
3194 case Mips::D3:
return Mips::F7;
3195 case Mips::D4:
return Mips::F9;
3196 case Mips::D5:
return Mips::F11;
3197 case Mips::D6:
return Mips::F13;
3198 case Mips::D7:
return Mips::F15;
3199 case Mips::D8:
return Mips::F17;
3200 case Mips::D9:
return Mips::F19;
3201 case Mips::D10:
return Mips::F21;
3202 case Mips::D11:
return Mips::F23;
3203 case Mips::D12:
return Mips::F25;
3204 case Mips::D13:
return Mips::F27;
3205 case Mips::D14:
return Mips::F29;
3206 case Mips::D15:
return Mips::F31;
3218 unsigned ATReg = getATReg(IDLoc);
3228 if(isABI_O32() || isABI_N32()) {
3247 if(isABI_O32() || isABI_N32()) {
3250 const MCExpr *HighestSym =
3254 const MCExpr *HigherSym =
3261 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3263 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3266 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3272 bool MipsAsmParser::expandLoadImmReal(
MCInst &Inst,
bool IsSingle,
bool IsGPR,
3273 bool Is64FPU,
SMLoc IDLoc,
3279 "Invalid instruction operand.");
3284 uint32_t HiImmOp64 = (ImmOp64 & 0xffffffff00000000) >> 32;
3287 if ((HiImmOp64 & 0x7ff00000) == 0) {
3292 uint32_t LoImmOp64 = ImmOp64 & 0xffffffff;
3293 HiImmOp64 = (ImmOp64 & 0xffffffff00000000) >> 32;
3300 float tmp_float =
static_cast<float>(doubleImm);
3304 if (loadImmediate(ImmOp32, FirstReg, Mips::NoRegister,
true,
true, IDLoc,
3309 unsigned ATReg = getATReg(IDLoc);
3312 if (LoImmOp64 == 0) {
3313 if (loadImmediate(ImmOp32, ATReg, Mips::NoRegister,
true,
true, IDLoc,
3316 TOut.
emitRR(Mips::MTC1, FirstReg, ATReg, IDLoc, STI);
3320 MCSection *CS = getStreamer().getCurrentSectionOnly();
3323 MCSection *ReadOnlySection = getContext().getELFSection(
3326 MCSymbol *Sym = getContext().createTempSymbol();
3332 getStreamer().SwitchSection(ReadOnlySection);
3333 getStreamer().EmitLabel(Sym, IDLoc);
3334 getStreamer().EmitIntValue(ImmOp32, 4);
3335 getStreamer().SwitchSection(CS);
3337 if(emitPartialAddress(TOut, IDLoc, Sym))
3339 TOut.
emitRRX(Mips::LWC1, FirstReg, ATReg,
3346 unsigned ATReg = getATReg(IDLoc);
3351 if (LoImmOp64 == 0) {
3352 if(isABI_N32() || isABI_N64()) {
3353 if (loadImmediate(HiImmOp64, FirstReg, Mips::NoRegister,
false,
true,
3358 if (loadImmediate(HiImmOp64, FirstReg, Mips::NoRegister,
true,
true,
3362 if (loadImmediate(0,
nextReg(FirstReg), Mips::NoRegister,
true,
true,
3369 MCSection *CS = getStreamer().getCurrentSectionOnly();
3370 MCSection *ReadOnlySection = getContext().getELFSection(
3373 MCSymbol *Sym = getContext().createTempSymbol();
3379 getStreamer().SwitchSection(ReadOnlySection);
3380 getStreamer().EmitLabel(Sym, IDLoc);
3381 getStreamer().EmitIntValue(HiImmOp64, 4);
3382 getStreamer().EmitIntValue(LoImmOp64, 4);
3383 getStreamer().SwitchSection(CS);
3385 if(emitPartialAddress(TOut, IDLoc, Sym))
3388 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3391 TOut.
emitRRX(Mips::ADDiu, ATReg, ATReg,
3394 if(isABI_N32() || isABI_N64())
3397 TOut.
emitRRI(Mips::LW, FirstReg, ATReg, 0, IDLoc, STI);
3402 if ((LoImmOp64 == 0) &&
3403 !((HiImmOp64 & 0xffff0000) && (HiImmOp64 & 0x0000ffff))) {
3406 if (loadImmediate(HiImmOp64, ATReg, Mips::NoRegister,
true,
true, IDLoc,
3409 if (isABI_N32() || isABI_N64())
3410 TOut.
emitRR(Mips::DMTC1, FirstReg, ATReg, IDLoc, STI);
3411 else if (hasMips32r2()) {
3412 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3413 TOut.
emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, ATReg, IDLoc, STI);
3415 TOut.
emitRR(Mips::MTC1,
nextReg(FirstReg), ATReg, IDLoc, STI);
3416 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3421 MCSection *CS = getStreamer().getCurrentSectionOnly();
3424 MCSection *ReadOnlySection = getContext().getELFSection(
3427 MCSymbol *Sym = getContext().createTempSymbol();
3433 getStreamer().SwitchSection(ReadOnlySection);
3434 getStreamer().EmitLabel(Sym, IDLoc);
3435 getStreamer().EmitIntValue(HiImmOp64, 4);
3436 getStreamer().EmitIntValue(LoImmOp64, 4);
3437 getStreamer().SwitchSection(CS);
3439 if(emitPartialAddress(TOut, IDLoc, Sym))
3441 TOut.
emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, ATReg,
3447 bool MipsAsmParser::expandUncondBranchMMPseudo(
MCInst &Inst,
SMLoc IDLoc,
3453 "unexpected number of operands");
3456 if (Offset.isExpr()) {
3463 assert(Offset.isImm() &&
"expected immediate operand kind");
3464 if (isInt<11>(Offset.getImm())) {
3467 if (inMicroMipsMode())
3468 Inst.
setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3470 if (!isInt<17>(Offset.getImm()))
3471 return Error(IDLoc,
"branch target out of range");
3473 return Error(IDLoc,
"branch to misaligned address");
3496 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3499 assert(ImmOp.isImm() &&
"expected immediate operand kind");
3502 assert((MemOffsetOp.isImm() || MemOffsetOp.isExpr()) &&
3503 "expected immediate or expression operand");
3505 bool IsLikely =
false;
3507 unsigned OpCode = 0;
3515 case Mips::BEQLImmMacro:
3516 OpCode = Mips::BEQL;
3519 case Mips::BNELImmMacro:
3520 OpCode = Mips::BNEL;
3528 int64_t ImmValue = ImmOp.getImm();
3529 if (ImmValue == 0) {
3533 TOut.
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3535 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3538 warnIfNoMacro(IDLoc);
3540 unsigned ATReg = getATReg(IDLoc);
3544 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(),
true,
3551 TOut.
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3553 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3561 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3563 assert(BaseRegOp.isReg() &&
"expected register operand kind");
3567 unsigned DstReg = DstRegOp.
getReg();
3568 unsigned BaseReg = BaseRegOp.getReg();
3569 unsigned TmpReg = DstReg;
3573 unsigned DstRegClassID =
3574 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3575 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3576 (DstRegClassID == Mips::GPR64RegClassID);
3578 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3581 TmpReg = getATReg(IDLoc);
3586 if (OffsetOp.isImm()) {
3587 int64_t LoOffset = OffsetOp.getImm() & 0xffff;
3588 int64_t HiOffset = OffsetOp.getImm() & ~0xffff;
3592 if (LoOffset & 0x8000)
3593 HiOffset += 0x10000;
3595 bool IsLargeOffset = HiOffset != 0;
3597 if (IsLargeOffset) {
3598 bool Is32BitImm = (HiOffset >> 32) == 0;
3599 if (loadImmediate(HiOffset, TmpReg, Mips::NoRegister, Is32BitImm,
true,
3604 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3605 TOut.
emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg,
3606 BaseReg, IDLoc, STI);
3609 assert(OffsetOp.isExpr() &&
"expected expression operand kind");
3610 const MCExpr *ExprOffset = OffsetOp.getExpr();
3618 LoOperand, TmpReg, IDLoc, STI);
3621 LoOperand, TmpReg, IDLoc, STI);
3625 bool MipsAsmParser::expandLoadStoreMultiple(
MCInst &Inst,
SMLoc IDLoc,
3630 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3634 Inst.
getOperand(OpNum - 3).
isReg() &&
"Invalid instruction operand.");
3643 if (inMicroMipsMode() && hasMips32r6())
3644 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3646 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3654 bool MipsAsmParser::expandCondBranches(
MCInst &Inst,
SMLoc IDLoc,
3658 bool EmittedNoMacroWarning =
false;
3659 unsigned PseudoOpcode = Inst.
getOpcode();
3664 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3665 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3670 else if (TrgOp.
isImm()) {
3671 warnIfNoMacro(IDLoc);
3672 EmittedNoMacroWarning =
true;
3674 TrgReg = getATReg(IDLoc);
3678 switch(PseudoOpcode) {
3681 case Mips::BLTImmMacro:
3682 PseudoOpcode = Mips::BLT;
3684 case Mips::BLEImmMacro:
3685 PseudoOpcode = Mips::BLE;
3687 case Mips::BGEImmMacro:
3688 PseudoOpcode = Mips::BGE;
3690 case Mips::BGTImmMacro:
3691 PseudoOpcode = Mips::BGT;
3693 case Mips::BLTUImmMacro:
3694 PseudoOpcode = Mips::BLTU;
3696 case Mips::BLEUImmMacro:
3697 PseudoOpcode = Mips::BLEU;
3699 case Mips::BGEUImmMacro:
3700 PseudoOpcode = Mips::BGEU;
3702 case Mips::BGTUImmMacro:
3703 PseudoOpcode = Mips::BGTU;
3705 case Mips::BLTLImmMacro:
3706 PseudoOpcode = Mips::BLTL;
3708 case Mips::BLELImmMacro:
3709 PseudoOpcode = Mips::BLEL;
3711 case Mips::BGELImmMacro:
3712 PseudoOpcode = Mips::BGEL;
3714 case Mips::BGTLImmMacro:
3715 PseudoOpcode = Mips::BGTL;
3717 case Mips::BLTULImmMacro:
3718 PseudoOpcode = Mips::BLTUL;
3720 case Mips::BLEULImmMacro:
3721 PseudoOpcode = Mips::BLEUL;
3723 case Mips::BGEULImmMacro:
3724 PseudoOpcode = Mips::BGEUL;
3726 case Mips::BGTULImmMacro:
3727 PseudoOpcode = Mips::BGTUL;
3731 if (loadImmediate(TrgOp.
getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
3732 false, IDLoc, Out, STI))
3736 switch (PseudoOpcode) {
3741 AcceptsEquality =
false;
3742 ReverseOrderSLT =
false;
3744 ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
3745 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
3746 ZeroSrcOpcode = Mips::BGTZ;
3747 ZeroTrgOpcode = Mips::BLTZ;
3753 AcceptsEquality =
true;
3754 ReverseOrderSLT =
true;
3756 ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
3757 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
3758 ZeroSrcOpcode = Mips::BGEZ;
3759 ZeroTrgOpcode = Mips::BLEZ;
3765 AcceptsEquality =
true;
3766 ReverseOrderSLT =
false;
3768 ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
3769 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
3770 ZeroSrcOpcode = Mips::BLEZ;
3771 ZeroTrgOpcode = Mips::BGEZ;
3777 AcceptsEquality =
false;
3778 ReverseOrderSLT =
true;
3780 ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
3781 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
3782 ZeroSrcOpcode = Mips::BLTZ;
3783 ZeroTrgOpcode = Mips::BGTZ;
3789 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
3790 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
3791 if (IsSrcRegZero && IsTrgRegZero) {
3795 if (PseudoOpcode == Mips::BLT) {
3800 if (PseudoOpcode == Mips::BLE) {
3803 Warning(IDLoc,
"branch is always taken");
3806 if (PseudoOpcode == Mips::BGE) {
3809 Warning(IDLoc,
"branch is always taken");
3812 if (PseudoOpcode == Mips::BGT) {
3817 if (PseudoOpcode == Mips::BGTU) {
3818 TOut.
emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
3822 if (AcceptsEquality) {
3825 TOut.
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
3827 Warning(IDLoc,
"branch is always taken");
3834 if (IsSrcRegZero || IsTrgRegZero) {
3835 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
3836 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
3843 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
3844 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
3850 TOut.
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
3852 Warning(IDLoc,
"branch is always taken");
3868 TOut.
emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
3869 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
3876 TOut.
emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
3877 IsSrcRegZero ? TrgReg : SrcReg,
3884 unsigned ATRegNum = getATReg(IDLoc);
3888 if (!EmittedNoMacroWarning)
3889 warnIfNoMacro(IDLoc);
3906 TOut.
emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
3907 ReverseOrderSLT ? TrgReg : SrcReg,
3908 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
3910 TOut.
emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
3911 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
3930 warnIfNoMacro(IDLoc);
3933 assert(RdRegOp.
isReg() &&
"expected register operand kind");
3934 unsigned RdReg = RdRegOp.
getReg();
3937 assert(RsRegOp.
isReg() &&
"expected register operand kind");
3938 unsigned RsReg = RsRegOp.
getReg();
3945 "expected register or immediate operand kind");
3949 ImmValue = RtOp.
getImm();
3956 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
3957 ZeroReg = Mips::ZERO_64;
3961 ZeroReg = Mips::ZERO;
3965 bool UseTraps = useTraps();
3968 bool isDiv = Opcode == Mips::SDivMacro || Opcode == Mips::SDivIMacro ||
3969 Opcode == Mips::UDivMacro || Opcode == Mips::UDivIMacro ||
3970 Opcode == Mips::DSDivMacro || Opcode == Mips::DSDivIMacro ||
3971 Opcode == Mips::DUDivMacro || Opcode == Mips::DUDivIMacro;
3973 bool isRem = Opcode == Mips::SRemMacro || Opcode == Mips::SRemIMacro ||
3974 Opcode == Mips::URemMacro || Opcode == Mips::URemIMacro ||
3975 Opcode == Mips::DSRemMacro || Opcode == Mips::DSRemIMacro ||
3976 Opcode == Mips::DURemMacro || Opcode == Mips::DURemIMacro;
3979 unsigned ATReg = getATReg(IDLoc);
3983 if (ImmValue == 0) {
3985 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
3987 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
3991 if (isRem && (ImmValue == 1 || (Signed && (ImmValue == -1)))) {
3994 }
else if (isDiv && ImmValue == 1) {
3997 }
else if (isDiv && Signed && ImmValue == -1) {
3998 TOut.
emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
4001 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister,
isInt<32>(ImmValue),
4002 false, Inst.
getLoc(), Out, STI))
4004 TOut.
emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
4015 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
4017 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4020 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4026 if (isRem && (RdReg == Mips::ZERO || RdReg == Mips::ZERO_64)) {
4027 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4037 TOut.
emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4042 TOut.
emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4045 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4048 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4058 unsigned ATReg = getATReg(IDLoc);
4065 TOut.
emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
4073 TOut.
emitRRX(Mips::BNE, RtReg, ATReg, LabelOpEnd, IDLoc, STI);
4076 TOut.
emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
4077 TOut.
emitDSLL(ATReg, ATReg, 63, IDLoc, STI);
4079 TOut.
emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, STI);
4083 TOut.
emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
4086 TOut.
emitRRX(Mips::BNE, RsReg, ATReg, LabelOpEnd, IDLoc, STI);
4088 TOut.
emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
4096 bool MipsAsmParser::expandTrunc(
MCInst &Inst,
bool IsDouble,
bool Is64FPU,
4109 if (hasMips1() && !hasMips2()) {
4110 unsigned ATReg = getATReg(IDLoc);
4116 TOut.
emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4117 TOut.
emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4120 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4122 FirstReg, SecondReg, IDLoc, STI);
4128 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4130 FirstReg, SecondReg, IDLoc, STI);
4135 bool MipsAsmParser::expandUlh(
MCInst &Inst,
bool Signed,
SMLoc IDLoc,
4137 if (hasMips32r6() || hasMips64r6()) {
4138 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4142 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4144 assert(SrcRegOp.isReg() &&
"expected register operand kind");
4146 assert(OffsetImmOp.isImm() &&
"expected immediate operand kind");
4149 unsigned DstReg = DstRegOp.
getReg();
4150 unsigned SrcReg = SrcRegOp.getReg();
4151 int64_t OffsetValue = OffsetImmOp.getImm();
4155 warnIfNoMacro(IDLoc);
4156 unsigned ATReg = getATReg(IDLoc);
4161 if (IsLargeOffset) {
4162 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.
ArePtrs64bit(),
true,
4167 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4168 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4172 unsigned FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4173 unsigned SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4175 unsigned LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4176 unsigned SllReg = IsLargeOffset ? DstReg : ATReg;
4178 TOut.emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4179 FirstOffset, IDLoc, STI);
4180 TOut.emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4181 TOut.emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4182 TOut.emitRRR(
Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4189 if (hasMips32r6() || hasMips64r6()) {
4190 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4194 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4196 assert(SrcRegOp.isReg() &&
"expected register operand kind");
4198 assert(OffsetImmOp.isImm() &&
"expected immediate operand kind");
4201 unsigned DstReg = DstRegOp.
getReg();
4202 unsigned SrcReg = SrcRegOp.getReg();
4203 int64_t OffsetValue = OffsetImmOp.getImm();
4205 warnIfNoMacro(IDLoc);
4206 unsigned ATReg = getATReg(IDLoc);
4211 if (IsLargeOffset) {
4212 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.
ArePtrs64bit(),
true,
4217 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4218 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4222 if (IsLargeOffset) {
4223 TOut.emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4224 TOut.emitRRI(
Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4225 TOut.emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4226 TOut.emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4227 TOut.emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4228 TOut.emitRRR(
Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4230 TOut.emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4231 TOut.emitRRI(
Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4232 TOut.emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4240 if (hasMips32r6() || hasMips64r6()) {
4241 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4245 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4247 assert(SrcRegOp.isReg() &&
"expected register operand kind");
4249 assert(OffsetImmOp.isImm() &&
"expected immediate operand kind");
4252 unsigned DstReg = DstRegOp.
getReg();
4253 unsigned SrcReg = SrcRegOp.getReg();
4254 int64_t OffsetValue = OffsetImmOp.getImm();
4258 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4259 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4263 bool IsLoadInst = (Inst.
getOpcode() == Mips::Ulw);
4264 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4265 unsigned TmpReg = SrcReg;
4266 if (IsLargeOffset || DoMove) {
4267 warnIfNoMacro(IDLoc);
4268 TmpReg = getATReg(IDLoc);
4273 if (IsLargeOffset) {
4274 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !ABI.
ArePtrs64bit(),
true,
4284 TOut.emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4285 TOut.emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4288 TOut.emitRRR(
Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4293 bool MipsAsmParser::expandAliasImmediate(
MCInst &Inst,
SMLoc IDLoc,
4303 unsigned ATReg = Mips::NoRegister;
4304 unsigned FinalDstReg = Mips::NoRegister;
4311 unsigned FinalOpcode = Inst.
getOpcode();
4313 if (DstReg == SrcReg) {
4314 ATReg = getATReg(Inst.
getLoc());
4317 FinalDstReg = DstReg;
4321 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit,
false,
4322 Inst.
getLoc(), Out, STI)) {
4323 switch (FinalOpcode) {
4330 FinalOpcode = Mips::ADDu;
4336 FinalOpcode = Mips::NOR;
4342 FinalOpcode = Mips::SLT;
4345 FinalOpcode = Mips::SLTu;
4351 FinalOpcode = Mips::ADD_MM;
4353 case Mips::ADDiu_MM:
4354 FinalOpcode = Mips::ADDu_MM;
4357 FinalOpcode = Mips::AND_MM;
4360 FinalOpcode = Mips::OR_MM;
4363 FinalOpcode = Mips::SLT_MM;
4365 case Mips::SLTiu_MM:
4366 FinalOpcode = Mips::SLTu_MM;
4369 FinalOpcode = Mips::XOR_MM;
4372 FinalOpcode = Mips::AND64;
4374 case Mips::NORImm64:
4375 FinalOpcode = Mips::NOR64;
4378 FinalOpcode = Mips::OR64;
4380 case Mips::SLTImm64:
4381 FinalOpcode = Mips::SLT64;
4383 case Mips::SLTUImm64:
4384 FinalOpcode = Mips::SLTu64;
4387 FinalOpcode = Mips::XOR64;
4391 if (FinalDstReg == Mips::NoRegister)
4392 TOut.
emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4394 TOut.
emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4403 unsigned ATReg = Mips::NoRegister;
4407 unsigned TmpReg = DReg;
4409 unsigned FirstShift = Mips::NOP;
4410 unsigned SecondShift = Mips::NOP;
4412 if (hasMips32r2()) {
4414 TmpReg = getATReg(Inst.
getLoc());
4420 TOut.
emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4421 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
4426 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
4438 FirstShift = Mips::SRLV;
4439 SecondShift = Mips::SLLV;
4442 FirstShift = Mips::SLLV;
4443 SecondShift = Mips::SRLV;
4447 ATReg = getATReg(Inst.
getLoc());
4451 TOut.
emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4452 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
4453 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
4462 bool MipsAsmParser::expandRotationImm(
MCInst &Inst,
SMLoc IDLoc,
4466 unsigned ATReg = Mips::NoRegister;
4471 unsigned FirstShift = Mips::NOP;
4472 unsigned SecondShift = Mips::NOP;
4474 if (hasMips32r2()) {
4476 uint64_t MaxShift = 32;
4477 uint64_t ShiftValue = ImmValue;
4479 ShiftValue = MaxShift - ImmValue;
4493 if (ImmValue == 0) {
4502 FirstShift = Mips::SLL;
4507 SecondShift = Mips::SLL;
4511 ATReg = getATReg(Inst.
getLoc());
4515 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.
getLoc(), STI);
4516 TOut.
emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.
getLoc(), STI);
4528 unsigned ATReg = Mips::NoRegister;
4532 unsigned TmpReg = DReg;
4534 unsigned FirstShift = Mips::NOP;
4535 unsigned SecondShift = Mips::NOP;
4537 if (hasMips64r2()) {
4538 if (TmpReg == SReg) {
4539 TmpReg = getATReg(Inst.
getLoc());
4545 TOut.
emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4546 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
4551 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
4563 FirstShift = Mips::DSRLV;
4564 SecondShift = Mips::DSLLV;
4567 FirstShift = Mips::DSLLV;
4568 SecondShift = Mips::DSRLV;
4572 ATReg = getATReg(Inst.
getLoc());
4576 TOut.
emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4577 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
4578 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
4587 bool MipsAsmParser::expandDRotationImm(
MCInst &Inst,
SMLoc IDLoc,
4591 unsigned ATReg = Mips::NoRegister;
4596 unsigned FirstShift = Mips::NOP;
4597 unsigned SecondShift = Mips::NOP;
4601 if (hasMips64r2()) {
4602 unsigned FinalOpcode = Mips::NOP;
4604 FinalOpcode = Mips::DROTR;
4605 else if (ImmValue % 32 == 0)
4606 FinalOpcode = Mips::DROTR32;
4607 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
4609 FinalOpcode = Mips::DROTR32;
4611 FinalOpcode = Mips::DROTR;
4612 }
else if (ImmValue >= 33) {
4614 FinalOpcode = Mips::DROTR;
4616 FinalOpcode = Mips::DROTR32;
4619 uint64_t ShiftValue = ImmValue % 32;
4621 ShiftValue = (32 - ImmValue % 32) % 32;
4623 TOut.
emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
4629 if (ImmValue == 0) {
4630 TOut.
emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.
getLoc(), STI);
4638 if ((ImmValue >= 1) && (ImmValue <= 31)) {
4639 FirstShift = Mips::DSLL;
4640 SecondShift = Mips::DSRL32;
4642 if (ImmValue == 32) {
4643 FirstShift = Mips::DSLL32;
4644 SecondShift = Mips::DSRL32;
4646 if ((ImmValue >= 33) && (ImmValue <= 63)) {
4647 FirstShift = Mips::DSLL32;
4648 SecondShift = Mips::DSRL;
4652 if ((ImmValue >= 1) && (ImmValue <= 31)) {
4653 FirstShift = Mips::DSRL;
4654 SecondShift = Mips::DSLL32;
4656 if (ImmValue == 32) {
4657 FirstShift = Mips::DSRL32;
4658 SecondShift = Mips::DSLL32;
4660 if ((ImmValue >= 33) && (ImmValue <= 63)) {
4661 FirstShift = Mips::DSRL32;
4662 SecondShift = Mips::DSLL;
4667 ATReg = getATReg(Inst.
getLoc());
4671 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.
getLoc(), STI);
4672 TOut.
emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
4688 TOut.
emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
4689 if (FirstRegOp != SecondRegOp)
4690 TOut.
emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
4701 unsigned ATReg = Mips::NoRegister;
4706 ATReg = getATReg(IDLoc);
4710 loadImmediate(ImmValue, ATReg, Mips::NoRegister,
true,
false, IDLoc, Out,
4714 SrcReg, ATReg, IDLoc, STI);
4724 unsigned ATReg = Mips::NoRegister;
4729 ATReg = getATReg(Inst.
getLoc());
4734 SrcReg, TmpReg, IDLoc, STI);
4739 DstReg, DstReg, 0x1F, IDLoc, STI);
4744 TOut.
emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
4751 TOut.
emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
4752 if (AssemblerOptions.
back()->isReorder())
4754 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
4766 unsigned ATReg = Mips::NoRegister;
4771 ATReg = getATReg(IDLoc);
4775 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
4776 SrcReg, TmpReg, IDLoc, STI);
4781 TOut.
emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);
4788 TOut.
emitRRX(Mips::BEQ, ATReg, Mips::ZERO, LabelOp, IDLoc, STI);
4789 if (AssemblerOptions.
back()->isReorder())
4791 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
4806 TOut.
emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
4817 bool MipsAsmParser::expandLoadStoreDMacro(
MCInst &Inst,
SMLoc IDLoc,
4824 warnIfNoMacro(IDLoc);
4827 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
4829 unsigned SecondReg =
nextReg(FirstReg);
4834 warnIfRegIndexIsAT(FirstReg, IDLoc);
4837 "Offset for load macro is not immediate!");
4840 signed NextOffset = FirstOffset.
getImm() + 4;
4848 if (FirstReg != BaseReg || !IsLoad) {
4849 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
4850 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
4852 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
4853 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
4862 warnIfNoMacro(IDLoc);
4887 warnIfNoMacro(IDLoc);
4900 if (Reg == Mips::ZERO) {
4901 Warning(IDLoc,
"comparison is always false");
4902 TOut.
emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
4907 if (Imm > -0x8000 && Imm < 0) {
4909 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
4915 unsigned ATReg = getATReg(IDLoc);
4919 if (loadImmediate(Imm, ATReg, Mips::NoRegister,
true, isGP64bit(), IDLoc,
4996 case Mips::F0:
return Mips::ZERO;
4997 case Mips::F1:
return Mips::AT;
4998 case Mips::F2:
return Mips::V0;
4999 case Mips::F3:
return Mips::V1;
5000 case Mips::F4:
return Mips::A0;
5001 case Mips::F5:
return Mips::A1;
5002 case Mips::F6:
return Mips::A2;
5003 case Mips::F7:
return Mips::A3;
5004 case Mips::F8:
return Mips::T0;
5006 case Mips::F10:
return Mips::T2;
5007 case Mips::F11:
return Mips::T3;
5008 case Mips::F12:
return Mips::T4;
5009 case Mips::F13:
return Mips::T5;
5010 case Mips::F14:
return Mips::T6;
5011 case Mips::F15:
return Mips::T7;
5012 case Mips::F16:
return Mips::S0;
5013 case Mips::F17:
return Mips::S1;
5014 case Mips::F18:
return Mips::S2;
5015 case Mips::F19:
return Mips::S3;
5016 case Mips::F20:
return Mips::S4;
5017 case Mips::F21:
return Mips::S5;
5018 case Mips::F22:
return Mips::S6;
5019 case Mips::F23:
return Mips::S7;
5021 case Mips::F25:
return Mips::T9;
5022 case Mips::F26:
return Mips::K0;
5023 case Mips::F27:
return Mips::K1;
5024 case Mips::F28:
return Mips::GP;
5025 case Mips::F29:
return Mips::SP;
5035 case Mips::COP00:
return Mips::ZERO;
5036 case Mips::COP01:
return Mips::AT;
5037 case Mips::COP02:
return Mips::V0;
5038 case Mips::COP03:
return Mips::V1;
5039 case Mips::COP04:
return Mips::A0;
5040 case Mips::COP05:
return Mips::A1;
5041 case Mips::COP06:
return Mips::A2;
5042 case Mips::COP07:
return Mips::A3;
5043 case Mips::COP08:
return Mips::T0;
5045 case Mips::COP010:
return Mips::T2;
5046 case Mips::COP011:
return Mips::T3;
5047 case Mips::COP012:
return Mips::T4;
5048 case Mips::COP013:
return Mips::T5;
5049 case Mips::COP014:
return Mips::T6;
5050 case Mips::COP015:
return Mips::T7;
5051 case Mips::COP016:
return Mips::S0;
5052 case Mips::COP017:
return Mips::S1;
5053 case Mips::COP018:
return Mips::S2;
5054 case Mips::COP019:
return Mips::S3;
5055 case Mips::COP020:
return Mips::S4;
5056 case Mips::COP021:
return Mips::S5;
5057 case Mips::COP022:
return Mips::S6;
5058 case Mips::COP023:
return Mips::S7;
5059 case Mips::COP024:
return Mips::T8;
5060 case Mips::COP025:
return Mips::T9;
5061 case Mips::COP026:
return Mips::K0;
5062 case Mips::COP027:
return Mips::K1;
5063 case Mips::COP028:
return Mips::GP;
5064 case Mips::COP029:
return Mips::SP;
5065 case Mips::COP030:
return Mips::FP;
5066 case Mips::COP031:
return Mips::RA;
5080 bool IsMFTR =
false;
5138 TOut.
emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, u, sel, h, IDLoc,
5144 MipsAsmParser::checkEarlyTargetMatchPredicate(
MCInst &Inst,
5148 return Match_Success;
5151 if (static_cast<MipsOperand &>(*Operands[1])
5152 .isValidForTie(static_cast<MipsOperand &>(*Operands[2])))
5153 return Match_Success;
5154 return Match_RequiresSameSrcAndDst;
5158 unsigned MipsAsmParser::checkTargetMatchPredicate(
MCInst &Inst) {
5165 return Match_RequiresNoZeroRegister;
5166 return Match_Success;
5172 case Mips::JALR_HB64:
5173 case Mips::JALRC_HB_MMR6:
5174 case Mips::JALRC_MMR6:
5176 return Match_RequiresDifferentSrcAndDst;
5177 return Match_Success;
5180 return Match_RequiresDifferentSrcAndDst;
5181 return Match_Success;
5184 return Match_NonZeroOperandForSync;
5185 return Match_Success;
5191 return Match_NonZeroOperandForMTCX;
5192 return Match_Success;
5205 case Mips::BLEZC:
case Mips::BLEZC_MMR6:
5206 case Mips::BGEZC:
case Mips::BGEZC_MMR6:
5207 case Mips::BGTZC:
case Mips::BGTZC_MMR6:
5208 case Mips::BLTZC:
case Mips::BLTZC_MMR6:
5209 case Mips::BEQZC:
case Mips::BEQZC_MMR6:
5210 case Mips::BNEZC:
case Mips::BNEZC_MMR6:
5219 return Match_RequiresNoZeroRegister;
5220 return Match_Success;
5221 case Mips::BGEC:
case Mips::BGEC_MMR6:
5222 case Mips::BLTC:
case Mips::BLTC_MMR6:
5223 case Mips::BGEUC:
case Mips::BGEUC_MMR6:
5224 case Mips::BLTUC:
case Mips::BLTUC_MMR6:
5225 case Mips::BEQC:
case Mips::BEQC_MMR6:
5226 case Mips::BNEC:
case Mips::BNEC_MMR6:
5235 return Match_RequiresNoZeroRegister;
5238 return Match_RequiresNoZeroRegister;
5240 return Match_RequiresDifferentOperands;
5241 return Match_Success;
5244 "Operands must be immediates for dins!");
5247 if ((0 > (Pos + Size)) || ((Pos + Size) > 32))
5248 return Match_RequiresPosSizeRange0_32;
5249 return Match_Success;
5254 "Operands must be immediates for dinsm/dinsu!");
5257 if ((32 >= (Pos + Size)) || ((Pos + Size) > 64))
5258 return Match_RequiresPosSizeRange33_64;
5259 return Match_Success;
5263 "Operands must be immediates for DEXTM!");
5266 if ((1 > (Pos + Size)) || ((Pos + Size) > 63))
5267 return Match_RequiresPosSizeUImm6;
5268 return Match_Success;
5273 "Operands must be immediates for dextm/dextu!");
5276 if ((32 > (Pos + Size)) || ((Pos + Size) > 64))
5277 return Match_RequiresPosSizeRange33_64;
5278 return Match_Success;
5280 case Mips::CRC32B:
case Mips::CRC32CB:
5281 case Mips::CRC32H:
case Mips::CRC32CH:
5282 case Mips::CRC32W:
case Mips::CRC32CW:
5283 case Mips::CRC32D:
case Mips::CRC32CD:
5285 return Match_RequiresSameSrcAndDst;
5286 return Match_Success;
5292 return Match_NoFCCRegisterForCurrentISA;
5294 return Match_Success;
5300 if (ErrorInfo != ~0ULL && ErrorInfo < Operands.
size()) {
5301 SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5302 if (ErrorLoc ==
SMLoc())
5309 bool MipsAsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
5313 bool MatchingInlineAsm) {
5315 unsigned MatchResult =
5316 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
5318 switch (MatchResult) {
5320 if (processInstruction(Inst, IDLoc, Out, STI))
5323 case Match_MissingFeature:
5324 Error(IDLoc,
"instruction requires a CPU feature not currently enabled");
5326 case Match_InvalidOperand: {
5327 SMLoc ErrorLoc = IDLoc;
5328 if (ErrorInfo != ~0ULL) {
5329 if (ErrorInfo >= Operands.
size())
5330 return Error(IDLoc,
"too few operands for instruction");
5332 ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5333 if (ErrorLoc ==
SMLoc())
5337 return Error(ErrorLoc,
"invalid operand for instruction");
5339 case Match_NonZeroOperandForSync:
5341 "s-type must be zero or unspecified for pre-MIPS32 ISAs");
5342 case Match_NonZeroOperandForMTCX:
5343 return Error(IDLoc,
"selector must be zero for pre-MIPS32 ISAs");
5344 case Match_MnemonicFail:
5345 return Error(IDLoc,
"invalid instruction");
5346 case Match_RequiresDifferentSrcAndDst:
5347 return Error(IDLoc,
"source and destination must be different");
5348 case Match_RequiresDifferentOperands:
5349 return Error(IDLoc,
"registers must be different");
5350 case Match_RequiresNoZeroRegister:
5351 return Error(IDLoc,
"invalid operand ($zero) for instruction");
5352 case Match_RequiresSameSrcAndDst:
5353 return Error(IDLoc,
"source and destination must match");
5354 case Match_NoFCCRegisterForCurrentISA:
5356 "non-zero fcc register doesn't exist in current ISA level");
5361 "expected 1-bit unsigned immediate");
5364 "expected 2-bit unsigned immediate");
5367 "expected immediate in range 1 .. 4");
5370 "expected 3-bit unsigned immediate");
5373 "expected 4-bit unsigned immediate");
5376 "expected 4-bit signed immediate");
5379 "expected 5-bit unsigned immediate");
5382 "expected 5-bit signed immediate");
5385 "expected immediate in range 1 .. 32");
5386 case Match_UImm5_32:
5388 "expected immediate in range 32 .. 63");
5389 case Match_UImm5_33:
5391 "expected immediate in range 33 .. 64");
5392 case Match_UImm5_0_Report_UImm6:
5396 "expected 6-bit unsigned immediate");
5397 case Match_UImm5_Lsl2:
5399 "expected both 7-bit unsigned immediate and multiple of 4");
5400 case Match_UImmRange2_64:
5402 "expected immediate in range 2 .. 64");
5405 "expected 6-bit unsigned immediate");
5406 case Match_UImm6_Lsl2:
5408 "expected both 8-bit unsigned immediate and multiple of 4");
5411 "expected 6-bit signed immediate");
5414 "expected 7-bit unsigned immediate");
5415 case Match_UImm7_N1:
5417 "expected immediate in range -1 .. 126");
5418 case Match_SImm7_Lsl2:
5420 "expected both 9-bit signed immediate and multiple of 4");
5423 "expected 8-bit unsigned immediate");
5424 case Match_UImm10_0:
5426 "expected 10-bit unsigned immediate");
5427 case Match_SImm10_0:
5429 "expected 10-bit signed immediate");
5430 case Match_SImm11_0:
5432 "expected 11-bit signed immediate");
5434 case Match_UImm16_Relaxed:
5435 case Match_UImm16_AltRelaxed:
5437 "expected 16-bit unsigned immediate");
5439 case Match_SImm16_Relaxed:
5441 "expected 16-bit signed immediate");
5442 case Match_SImm19_Lsl2:
5444 "expected both 19-bit signed immediate and multiple of 4");
5445 case Match_UImm20_0:
5447 "expected 20-bit unsigned immediate");
5448 case Match_UImm26_0:
5450 "expected 26-bit unsigned immediate");
5452 case Match_SImm32_Relaxed:
5454 "expected 32-bit signed immediate");
5455 case Match_UImm32_Coerced:
5457 "expected 32-bit immediate");
5458 case Match_MemSImm9:
5460 "expected memory with 9-bit signed offset");
5461 case Match_MemSImm10:
5463 "expected memory with 10-bit signed offset");
5464 case Match_MemSImm10Lsl1:
5466 "expected memory with 11-bit signed offset and multiple of 2");
5467 case Match_MemSImm10Lsl2:
5469 "expected memory with 12-bit signed offset and multiple of 4");
5470 case Match_MemSImm10Lsl3:
5472 "expected memory with 13-bit signed offset and multiple of 8");
5473 case Match_MemSImm11:
5475 "expected memory with 11-bit signed offset");
5476 case Match_MemSImm12:
5478 "expected memory with 12-bit signed offset");
5479 case Match_MemSImm16:
5481 "expected memory with 16-bit signed offset");
5482 case Match_MemSImmPtr:
5484 "expected memory with 32-bit signed offset");
5485 case Match_RequiresPosSizeRange0_32: {
5486 SMLoc ErrorStart = Operands[3]->getStartLoc();
5487 SMLoc ErrorEnd = Operands[4]->getEndLoc();
5488 return Error(ErrorStart,
"size plus position are not in the range 0 .. 32",
5489 SMRange(ErrorStart, ErrorEnd));
5491 case Match_RequiresPosSizeUImm6: {
5492 SMLoc ErrorStart = Operands[3]->getStartLoc();
5493 SMLoc ErrorEnd = Operands[4]->getEndLoc();
5494 return Error(ErrorStart,
"size plus position are not in the range 1 .. 63",
5495 SMRange(ErrorStart, ErrorEnd));
5497 case Match_RequiresPosSizeRange33_64: {
5498 SMLoc ErrorStart = Operands[3]->getStartLoc();
5499 SMLoc ErrorEnd = Operands[4]->getEndLoc();
5500 return Error(ErrorStart,
"size plus position are not in the range 33 .. 64",
5501 SMRange(ErrorStart, ErrorEnd));
5508 void MipsAsmParser::warnIfRegIndexIsAT(
unsigned RegIndex,
SMLoc Loc) {
5509 if (RegIndex != 0 && AssemblerOptions.
back()->getATRegIndex() == RegIndex)
5510 Warning(Loc,
"used $at (currently $" +
Twine(RegIndex) +
5511 ") without \".set noat\"");
5514 void MipsAsmParser::warnIfNoMacro(
SMLoc Loc) {
5515 if (!AssemblerOptions.
back()->isMacro())
5516 Warning(Loc,
"macro instruction expanded into multiple instructions");
5519 void MipsAsmParser::ConvertXWPOperands(
MCInst &Inst,
5523 "Unexpected instruction!");
5524 ((MipsOperand &)*Operands[1]).addGPR32ZeroAsmRegOperands(Inst, 1);
5525 int NextReg =
nextReg(((MipsOperand &)*Operands[1]).getGPR32Reg());
5527 ((MipsOperand &)*Operands[2]).addMemOperands(Inst, 2);
5531 MipsAsmParser::printWarningWithFixIt(
const Twine &Msg,
const Twine &FixMsg,
5532 SMRange Range,
bool ShowColors) {
5534 Range,
SMFixIt(Range, FixMsg),
5543 .
Cases(
"at",
"AT", 1)
5577 if (!(isABI_N32() || isABI_N64()))
5580 if (12 <= CC && CC <= 15) {
5582 AsmToken RegTok = getLexer().peekTok();
5591 assert(FixedName !=
"" &&
"Register name is not one of t4-t7.");
5593 printWarningWithFixIt(
"register names $t4-$t7 are only available in O32.",
5594 "Did you mean $" + FixedName +
"?", RegRange);
5600 if (8 <= CC && CC <= 11)
5616 int MipsAsmParser::matchHWRegsRegisterName(
StringRef Name) {
5620 .Case(
"hwr_cpunum", 0)
5621 .
Case(
"hwr_synci_step", 1)
5623 .
Case(
"hwr_ccres", 3)
5624 .
Case(
"hwr_ulr", 29)
5630 int MipsAsmParser::matchFPURegisterName(
StringRef Name) {
5631 if (Name[0] ==
'f') {
5643 int MipsAsmParser::matchFCCRegisterName(
StringRef Name) {
5656 int MipsAsmParser::matchACRegisterName(
StringRef Name) {
5669 int MipsAsmParser::matchMSA128RegisterName(
StringRef Name) {
5681 int MipsAsmParser::matchMSA128CtrlRegisterName(
StringRef Name) {
5687 .
Case(
"msaaccess", 2)
5689 .
Case(
"msamodify", 4)
5690 .
Case(
"msarequest", 5)
5692 .
Case(
"msaunmap", 7)
5698 bool MipsAsmParser::canUseATReg() {
5699 return AssemblerOptions.
back()->getATRegIndex() != 0;
5702 unsigned MipsAsmParser::getATReg(
SMLoc Loc) {
5703 unsigned ATIndex = AssemblerOptions.
back()->getATRegIndex();
5705 reportParseError(Loc,
5706 "pseudo-instruction requires $at, which is not available");
5710 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
5715 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
5735 switch (getLexer().getKind()) {
5754 MCSymbol *Sym = getContext().getOrCreateSymbol(
"$" + Identifier);
5759 Operands.
push_back(MipsOperand::CreateImm(Res, S, E, *
this));
5767 if (getParser().parseExpression(Expr))
5772 Operands.
push_back(MipsOperand::CreateImm(Expr, S, E, *
this));
5779 bool MipsAsmParser::isEvaluated(
const MCExpr *Expr) {
5787 if (!isEvaluated(BE->
getLHS()))
5789 return isEvaluated(BE->
getRHS());
5792 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
5799 bool MipsAsmParser::ParseRegister(
unsigned &RegNo,
SMLoc &StartLoc,
5805 MipsOperand &Operand =
static_cast<MipsOperand &
>(*Operands.
front());
5806 StartLoc = Operand.getStartLoc();
5807 EndLoc = Operand.getEndLoc();
5813 if (Operand.isGPRAsmReg()) {
5815 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
5818 return (RegNo == (
unsigned)-1);
5822 return (RegNo == (
unsigned)-1);
5825 bool MipsAsmParser::parseMemOffset(
const MCExpr *&Res,
bool isParenExpr) {
5829 return getParser().parseParenExprOfDepth(0, Res, S);
5830 return getParser().parseExpression(Res);
5837 const MCExpr *IdVal =
nullptr;
5839 bool isParenExpr =
false;
5850 if (parseMemOffset(IdVal, isParenExpr))
5855 MipsOperand &Mnemonic =
static_cast<MipsOperand &
>(*Operands[0]);
5856 if (Mnemonic.getToken() ==
"la" || Mnemonic.getToken() ==
"dla") {
5859 Operands.
push_back(MipsOperand::CreateImm(IdVal, S, E, *
this));
5868 auto Base = MipsOperand::createGPRReg(
5869 0,
"0", getContext().getRegisterInfo(), S, E, *
this);
5871 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *
this));
5925 if (getParser().parseExpression(NextExpr))
5933 Res = parseAnyRegister(Operands);
5950 std::unique_ptr<MipsOperand>
op(
5951 static_cast<MipsOperand *>(Operands.
back().release()));
5956 if (
const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
5958 if (IdVal->evaluateAsAbsolute(Imm))
5965 Operands.
push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *
this));
5969 bool MipsAsmParser::searchSymbolAlias(
OperandVector &Operands) {
5983 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.
substr(1), S);
5997 if (Entry != RegisterSets.
end()) {
5999 matchAnyRegisterWithoutDollar(Operands, Entry->getValue(), S);
6011 MipsAsmParser::matchAnyRegisterNameWithoutDollar(
OperandVector &Operands,
6014 int Index = matchCPURegisterName(Identifier);
6016 Operands.
push_back(MipsOperand::createGPRReg(
6017 Index, Identifier, getContext().getRegisterInfo(), S,
6018 getLexer().getLoc(), *
this));
6022 Index = matchHWRegsRegisterName(Identifier);
6024 Operands.
push_back(MipsOperand::createHWRegsReg(
6025 Index, Identifier, getContext().getRegisterInfo(), S,
6026 getLexer().getLoc(), *
this));
6030 Index = matchFPURegisterName(Identifier);
6032 Operands.
push_back(MipsOperand::createFGRReg(
6033 Index, Identifier, getContext().getRegisterInfo(), S,
6034 getLexer().getLoc(), *
this));
6038 Index = matchFCCRegisterName(Identifier);
6040 Operands.
push_back(MipsOperand::createFCCReg(
6041 Index, Identifier, getContext().getRegisterInfo(), S,
6042 getLexer().getLoc(), *
this));
6046 Index = matchACRegisterName(Identifier);
6048 Operands.
push_back(MipsOperand::createACCReg(
6049 Index, Identifier, getContext().getRegisterInfo(), S,
6050 getLexer().getLoc(), *
this));
6054 Index = matchMSA128RegisterName(Identifier);
6056 Operands.
push_back(MipsOperand::createMSA128Reg(
6057 Index, Identifier, getContext().getRegisterInfo(), S,
6058 getLexer().getLoc(), *
this));
6062 Index = matchMSA128CtrlRegisterName(Identifier);
6064 Operands.
push_back(MipsOperand::createMSACtrlReg(
6065 Index, Identifier, getContext().getRegisterInfo(), S,
6066 getLexer().getLoc(), *
this));
6074 MipsAsmParser::matchAnyRegisterWithoutDollar(
OperandVector &Operands,
6080 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
6085 if (RegNum < 0 || RegNum > 31) {
6089 Error(getLexer().getLoc(),
"invalid register number");
6091 Operands.
push_back(MipsOperand::createNumericReg(
6092 RegNum, Token.
getString(), getContext().getRegisterInfo(), S,
6104 auto Token = getLexer().peekTok(
false);
6105 return matchAnyRegisterWithoutDollar(Operands, Token, S);
6113 auto Token = Parser.
getTok();
6120 if (searchSymbolAlias(Operands))
6141 SMLoc S = getLexer().getLoc();
6149 const MCExpr *Expr =
nullptr;
6155 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *
this));
6173 if (getParser().parseExpression(IdVal))
6180 Operands.
push_back(MipsOperand::CreateImm(
6190 unsigned PrevReg = Mips::NoRegister;
6191 bool RegRange =
false;
6199 SMLoc E = getLexer().getLoc();
6200 MipsOperand &
Reg =
static_cast<MipsOperand &
>(*TmpOperands.
back());
6201 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
6205 if ((isGP64bit() && RegNo == Mips::RA_64) ||
6206 (!isGP64bit() && RegNo ==
Mips::RA)) {
6209 unsigned TmpReg = PrevReg + 1;
6210 while (TmpReg <= RegNo) {
6211 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
6212 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
6214 Error(E,
"invalid register operand");
6225 if ((PrevReg == Mips::NoRegister) &&
6226 ((isGP64bit() && (RegNo != Mips::S0_64) && (RegNo != Mips::RA_64)) ||
6227 (!isGP64bit() && (RegNo != Mips::S0) && (RegNo !=
Mips::RA)))) {
6228 Error(E,
"$16 or $31 expected");
6231 (RegNo >= Mips::S0 && RegNo <= Mips::S7)) &&
6233 ((RegNo == Mips::FP_64 || RegNo == Mips::RA_64 ||
6234 (RegNo >= Mips::S0_64 && RegNo <= Mips::S7_64)) &&
6236 Error(E,
"invalid register operand");
6238 }
else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
6240 (RegNo != Mips::FP_64 && RegNo != Mips::RA_64 &&
6242 Error(E,
"consecutive register numbers expected");
6254 Error(E,
"',' or '-' expected");
6266 Operands.
push_back(MipsOperand::CreateRegList(Regs, S, E, *
this));
6267 parseMemOperand(Operands);
6280 MipsOperand::CreateToken(
"(", getLexer().getLoc(), *
this));
6282 if (parseOperand(Operands, Name)) {
6283 SMLoc Loc = getLexer().getLoc();
6284 return Error(Loc,
"unexpected token in argument list");
6287 SMLoc Loc = getLexer().getLoc();
6288 return Error(Loc,
"unexpected token, expected ')'");
6291 MipsOperand::CreateToken(
")", getLexer().getLoc(), *
this));
6303 bool MipsAsmParser::parseBracketSuffix(
StringRef Name,
6308 MipsOperand::CreateToken(
"[", getLexer().getLoc(), *
this));
6310 if (parseOperand(Operands, Name)) {
6311 SMLoc Loc = getLexer().getLoc();
6312 return Error(Loc,
"unexpected token in argument list");
6315 SMLoc Loc = getLexer().getLoc();
6316 return Error(Loc,
"unexpected token, expected ']'");
6319 MipsOperand::CreateToken(
"]", getLexer().getLoc(), *
this));
6326 unsigned VariantID = 0);
6334 getTargetStreamer().forbidModuleDirective();
6337 if (!mnemonicIsValid(Name, 0)) {
6338 uint64_t FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
6340 return Error(NameLoc,
"unknown instruction" + Suggestion);
6343 Operands.
push_back(MipsOperand::CreateToken(Name, NameLoc, *
this));
6348 if (parseOperand(Operands, Name)) {
6349 SMLoc Loc = getLexer().getLoc();
6350 return Error(Loc,
"unexpected token in argument list");
6352 if (getLexer().is(
AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
6359 if (parseOperand(Operands, Name)) {
6360 SMLoc Loc = getLexer().getLoc();
6361 return Error(Loc,
"unexpected token in argument list");
6365 if (parseBracketSuffix(Name, Operands))
6368 parseParenSuffix(Name, Operands))
6373 SMLoc Loc = getLexer().getLoc();
6374 return Error(Loc,
"unexpected token in argument list");
6382 bool MipsAsmParser::reportParseError(
Twine ErrorMsg) {
6383 SMLoc Loc = getLexer().getLoc();
6384 return Error(Loc, ErrorMsg);
6387 bool MipsAsmParser::reportParseError(
SMLoc Loc,
Twine ErrorMsg) {
6388 return Error(Loc, ErrorMsg);
6391 bool MipsAsmParser::parseSetNoAtDirective() {
6396 AssemblerOptions.
back()->setATRegIndex(0);
6402 reportParseError(
"unexpected token, expected end of statement");
6406 getTargetStreamer().emitDirectiveSetNoAt();
6411 bool MipsAsmParser::parseSetAtDirective() {
6419 AssemblerOptions.
back()->setATRegIndex(1);
6421 getTargetStreamer().emitDirectiveSetAt();
6427 reportParseError(
"unexpected token, expected equals sign");
6434 reportParseError(
"no register specified");
6437 reportParseError(
"unexpected token, expected dollar sign '$'");
6451 reportParseError(
"unexpected token, expected identifier or integer");
6456 if (!AssemblerOptions.
back()->setATRegIndex(AtRegNo)) {
6457 reportParseError(
"invalid register");
6464 reportParseError(
"unexpected token, expected end of statement");
6468 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
6474 bool MipsAsmParser::parseSetReorderDirective() {
6479 reportParseError(
"unexpected token, expected end of statement");
6482 AssemblerOptions.
back()->setReorder();
6483 getTargetStreamer().emitDirectiveSetReorder();
6488 bool MipsAsmParser::parseSetNoReorderDirective() {
6493 reportParseError(
"unexpected token, expected end of statement");
6496 AssemblerOptions.
back()->setNoReorder();
6497 getTargetStreamer().emitDirectiveSetNoReorder();
6502 bool MipsAsmParser::parseSetMacroDirective() {
6507 reportParseError(
"unexpected token, expected end of statement");
6510 AssemblerOptions.
back()->setMacro();
6511 getTargetStreamer().emitDirectiveSetMacro();
6516 bool MipsAsmParser::parseSetNoMacroDirective() {
6521 reportParseError(
"unexpected token, expected end of statement");
6524 if (AssemblerOptions.
back()->isReorder()) {
6525 reportParseError(
"`noreorder' must be set before `nomacro'");
6528 AssemblerOptions.
back()->setNoMacro();
6529 getTargetStreamer().emitDirectiveSetNoMacro();
6534 bool MipsAsmParser::parseSetMsaDirective() {
6540 return reportParseError(
"unexpected token, expected end of statement");
6542 setFeatureBits(Mips::FeatureMSA,
"msa");
6543 getTargetStreamer().emitDirectiveSetMsa();
6547 bool MipsAsmParser::parseSetNoMsaDirective() {
6553 return reportParseError(
"unexpected token, expected end of statement");
6555 clearFeatureBits(Mips::FeatureMSA,
"msa");
6556 getTargetStreamer().emitDirectiveSetNoMsa();
6560 bool MipsAsmParser::parseSetNoDspDirective() {
6566 reportParseError(
"unexpected token, expected end of statement");
6570 clearFeatureBits(Mips::FeatureDSP,
"dsp");
6571 getTargetStreamer().emitDirectiveSetNoDsp();
6575 bool MipsAsmParser::parseSetMips16Directive() {
6581 reportParseError(
"unexpected token, expected end of statement");
6585 setFeatureBits(Mips::FeatureMips16,
"mips16");
6586 getTargetStreamer().emitDirectiveSetMips16();
6591 bool MipsAsmParser::parseSetNoMips16Directive() {
6597 reportParseError(
"unexpected token, expected end of statement");
6601 clearFeatureBits(Mips::FeatureMips16,
"mips16");
6602 getTargetStreamer().emitDirectiveSetNoMips16();
6607 bool MipsAsmParser::parseSetFpDirective() {
6616 reportParseError(
"unexpected token, expected equals sign '='");
6622 if (!parseFpABIValue(FpAbiVal,
".set"))
6626 reportParseError(
"unexpected token, expected end of statement");
6629 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
6634 bool MipsAsmParser::parseSetOddSPRegDirective() {
6639 reportParseError(
"unexpected token, expected end of statement");
6643 clearFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
6644 getTargetStreamer().emitDirectiveSetOddSPReg();
6648 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
6653 reportParseError(
"unexpected token, expected end of statement");
6657 setFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
6658 getTargetStreamer().emitDirectiveSetNoOddSPReg();
6662 bool MipsAsmParser::parseSetMtDirective() {
6668 reportParseError(
"unexpected token, expected end of statement");
6672 setFeatureBits(Mips::FeatureMT,
"mt");
6673 getTargetStreamer().emitDirectiveSetMt();
6678 bool MipsAsmParser::parseSetNoMtDirective() {
6684 reportParseError(
"unexpected token, expected end of statement");
6688 clearFeatureBits(Mips::FeatureMT,
"mt");
6690 getTargetStreamer().emitDirectiveSetNoMt();
6695 bool MipsAsmParser::parseSetNoCRCDirective() {
6701 reportParseError(
"unexpected token, expected end of statement");
6705 clearFeatureBits(Mips::FeatureCRC,
"crc");
6707 getTargetStreamer().emitDirectiveSetNoCRC();
6712 bool MipsAsmParser::parseSetNoVirtDirective() {
6718 reportParseError(
"unexpected token, expected end of statement");
6722 clearFeatureBits(Mips::FeatureVirt,
"virt");
6724 getTargetStreamer().emitDirectiveSetNoVirt();
6729 bool MipsAsmParser::parseSetNoGINVDirective() {
6735 reportParseError(
"unexpected token, expected end of statement");
6739 clearFeatureBits(Mips::FeatureGINV,
"ginv");
6741 getTargetStreamer().emitDirectiveSetNoGINV();
6746 bool MipsAsmParser::parseSetPopDirective() {
6748 SMLoc Loc = getLexer().getLoc();
6752 return reportParseError(
"unexpected token, expected end of statement");
6756 if (AssemblerOptions.
size() == 2)
6757 return reportParseError(Loc,
".set pop with no .set push");
6761 setAvailableFeatures(
6762 ComputeAvailableFeatures(AssemblerOptions.
back()->getFeatures()));
6765 getTargetStreamer().emitDirectiveSetPop();
6769 bool MipsAsmParser::parseSetPushDirective() {
6773 return reportParseError(
"unexpected token, expected end of statement");
6777 llvm::make_unique<MipsAssemblerOptions>(AssemblerOptions.
back().get()));
6779 getTargetStreamer().emitDirectiveSetPush();
6783 bool MipsAsmParser::parseSetSoftFloatDirective() {
6787 return reportParseError(
"unexpected token, expected end of statement");
6789 setFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
6790 getTargetStreamer().emitDirectiveSetSoftFloat();
6794 bool MipsAsmParser::parseSetHardFloatDirective() {
6798 return reportParseError(
"unexpected token, expected end of statement");
6800 clearFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
6801 getTargetStreamer().emitDirectiveSetHardFloat();
6805 bool MipsAsmParser::parseSetAssignment() {
6811 return reportParseError(
"expected identifier after .set");
6814 return reportParseError(
"unexpected token, expected comma");
6824 getContext().getOrCreateSymbol(Name);
6830 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
6833 return reportParseError(
"expected valid expression after comma");
6839 bool MipsAsmParser::parseSetMips0Directive() {
6843 return reportParseError(
"unexpected token, expected end of statement");
6847 setAvailableFeatures(
6848 ComputeAvailableFeatures(AssemblerOptions.
front()->getFeatures()));
6850 AssemblerOptions.
back()->setFeatures(AssemblerOptions.
front()->getFeatures());
6852 getTargetStreamer().emitDirectiveSetMips0();
6856 bool MipsAsmParser::parseSetArchDirective() {
6860 return reportParseError(
"unexpected token, expected equals sign");
6865 return reportParseError(
"expected arch identifier");
6869 .Case(
"mips1",
"mips1")
6870 .
Case(
"mips2",
"mips2")
6871 .
Case(
"mips3",
"mips3")
6872 .
Case(
"mips4",
"mips4")
6873 .
Case(
"mips5",
"mips5")
6874 .
Case(
"mips32",
"mips32")
6875 .
Case(
"mips32r2",
"mips32r2")
6876 .
Case(
"mips32r3",
"mips32r3")
6877 .
Case(
"mips32r5",
"mips32r5")
6878 .
Case(
"mips32r6",
"mips32r6")
6879 .
Case(
"mips64",
"mips64")
6880 .
Case(
"mips64r2",
"mips64r2")
6881 .
Case(
"mips64r3",
"mips64r3")
6882 .
Case(
"mips64r5",
"mips64r5")
6883 .
Case(
"mips64r6",
"mips64r6")
6884 .
Case(
"octeon",
"cnmips")
6885 .
Case(
"r4000",
"mips3")
6888 if (ArchFeatureName.
empty())
6889 return reportParseError(
"unsupported architecture");
6891 if (ArchFeatureName ==
"mips64r6" && inMicroMipsMode())
6892 return reportParseError(
"mips64r6 does not support microMIPS");
6894 selectArch(ArchFeatureName);
6895 getTargetStreamer().emitDirectiveSetArch(Arch);
6899 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
6903 return reportParseError(
"unexpected token, expected end of statement");
6908 case Mips::FeatureDSP:
6909 setFeatureBits(Mips::FeatureDSP,
"dsp");
6910 getTargetStreamer().emitDirectiveSetDsp();
6912 case Mips::FeatureDSPR2:
6913 setFeatureBits(Mips::FeatureDSPR2,
"dspr2");
6914 getTargetStreamer().emitDirectiveSetDspr2();
6916 case Mips::FeatureMicroMips:
6917 setFeatureBits(Mips::FeatureMicroMips,
"micromips");
6918 getTargetStreamer().emitDirectiveSetMicroMips();
6920 case Mips::FeatureMips1:
6921 selectArch(
"mips1");
6922 getTargetStreamer().emitDirectiveSetMips1();
6924 case Mips::FeatureMips2:
6925 selectArch(
"mips2");
6926 getTargetStreamer().emitDirectiveSetMips2();
6928 case Mips::FeatureMips3:
6929 selectArch(
"mips3");
6930 getTargetStreamer().emitDirectiveSetMips3();
6932 case Mips::FeatureMips4:
6933 selectArch(
"mips4");
6934 getTargetStreamer().emitDirectiveSetMips4();
6936 case Mips::FeatureMips5:
6937 selectArch(
"mips5");
6938 getTargetStreamer().emitDirectiveSetMips5();
6940 case Mips::FeatureMips32:
6941 selectArch(
"mips32");
6942 getTargetStreamer().emitDirectiveSetMips32();
6944 case Mips::FeatureMips32r2:
6945 selectArch(
"mips32r2");
6946 getTargetStreamer().emitDirectiveSetMips32R2();
6948 case Mips::FeatureMips32r3:
6949 selectArch(
"mips32r3");
6950 getTargetStreamer().emitDirectiveSetMips32R3();
6952 case Mips::FeatureMips32r5:
6953 selectArch(
"mips32r5");
6954 getTargetStreamer().emitDirectiveSetMips32R5();
6956 case Mips::FeatureMips32r6:
6957 selectArch(
"mips32r6");
6958 getTargetStreamer().emitDirectiveSetMips32R6();
6960 case Mips::FeatureMips64:
6961 selectArch(
"mips64");
6962 getTargetStreamer().emitDirectiveSetMips64();
6964 case Mips::FeatureMips64r2:
6965 selectArch(
"mips64r2");
6966 getTargetStreamer().emitDirectiveSetMips64R2();
6968 case Mips::FeatureMips64r3:
6969 selectArch(
"mips64r3");
6970 getTargetStreamer().emitDirectiveSetMips64R3();
6972 case Mips::FeatureMips64r5:
6973 selectArch(
"mips64r5");
6974 getTargetStreamer().emitDirectiveSetMips64R5();
6976 case Mips::FeatureMips64r6:
6977 selectArch(
"mips64r6");
6978 getTargetStreamer().emitDirectiveSetMips64R6();
6980 case Mips::FeatureCRC:
6981 setFeatureBits(Mips::FeatureCRC,
"crc");
6982 getTargetStreamer().emitDirectiveSetCRC();
6984 case Mips::FeatureVirt:
6985 setFeatureBits(Mips::FeatureVirt,
"virt");
6986 getTargetStreamer().emitDirectiveSetVirt();
6988 case Mips::FeatureGINV:
6989 setFeatureBits(Mips::FeatureGINV,
"ginv");
6990 getTargetStreamer().emitDirectiveSetGINV();
6996 bool MipsAsmParser::eatComma(
StringRef ErrorStr) {
6999 SMLoc Loc = getLexer().getLoc();
7000 return Error(Loc, ErrorStr);
7011 bool MipsAsmParser::isPicAndNotNxxAbi() {
7012 return inPicMode() && !(isABI_N32() || isABI_N64());
7015 bool MipsAsmParser::parseDirectiveCpLoad(
SMLoc Loc) {
7016 if (AssemblerOptions.
back()->isReorder())
7017 Warning(Loc,
".cpload should be inside a noreorder section");
7019 if (inMips16Mode()) {
7020 reportParseError(
".cpload is not supported in Mips16 mode");
7027 reportParseError(
"expected register containing function address");
7031 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*Reg[0]);
7032 if (!RegOpnd.isGPRAsmReg()) {
7033 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7039 reportParseError(
"unexpected token, expected end of statement");
7043 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
7047 bool MipsAsmParser::parseDirectiveCpRestore(
SMLoc Loc) {
7053 if (inMips16Mode()) {
7054 reportParseError(
".cprestore is not supported in Mips16 mode");
7059 const MCExpr *StackOffset;
7060 int64_t StackOffsetVal;
7062 reportParseError(
"expected stack offset value");
7066 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
7067 reportParseError(
"stack offset is not an absolute expression");
7071 if (StackOffsetVal < 0) {
7072 Warning(Loc,
".cprestore with negative stack offset has no effect");
7073 IsCpRestoreSet =
false;
7075 IsCpRestoreSet =
true;
7076 CpRestoreOffset = StackOffsetVal;
7081 reportParseError(
"unexpected token, expected end of statement");
7085 if (!getTargetStreamer().emitDirectiveCpRestore(
7086 CpRestoreOffset, [&]() {
return getATReg(Loc); }, Loc, STI))
7092 bool MipsAsmParser::parseDirectiveCPSetup() {
7096 bool SaveIsReg =
true;
7101 reportParseError(
"expected register containing function address");
7105 MipsOperand &FuncRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7106 if (!FuncRegOpnd.isGPRAsmReg()) {
7107 reportParseError(FuncRegOpnd.getStartLoc(),
"invalid register");
7111 FuncReg = FuncRegOpnd.getGPR32Reg();
7114 if (!eatComma(
"unexpected token, expected comma"))
7117 ResTy = parseAnyRegister(TmpReg);
7119 const MCExpr *OffsetExpr;
7121 SMLoc ExprLoc = getLexer().getLoc();
7124 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
7125 reportParseError(ExprLoc,
"expected save register or stack offset");
7132 MipsOperand &SaveOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7133 if (!SaveOpnd.isGPRAsmReg()) {
7134 reportParseError(SaveOpnd.getStartLoc(),
"invalid register");
7137 Save = SaveOpnd.getGPR32Reg();
7140 if (!eatComma(
"unexpected token, expected comma"))
7145 reportParseError(
"expected expression");
7150 reportParseError(
"expected symbol");
7155 CpSaveLocation = Save;
7156 CpSaveLocationIsRegister = SaveIsReg;
7158 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->
getSymbol(),
7163 bool MipsAsmParser::parseDirectiveCPReturn() {
7164 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
7165 CpSaveLocationIsRegister);
7169 bool MipsAsmParser::parseDirectiveNaN() {
7176 getTargetStreamer().emitDirectiveNaN2008();
7178 }
else if (Tok.
getString() ==
"legacy") {
7180 getTargetStreamer().emitDirectiveNaNLegacy();
7186 reportParseError(
"invalid option in .nan directive");
7190 bool MipsAsmParser::parseDirectiveSet() {
7191 const AsmToken &Tok = getParser().getTok();
7195 if (IdVal ==
"noat")
7196 return parseSetNoAtDirective();
7198 return parseSetAtDirective();
7199 if (IdVal ==
"arch")
7200 return parseSetArchDirective();
7201 if (IdVal ==
"bopt") {
7202 Warning(Loc,
"'bopt' feature is unsupported");
7206 if (IdVal ==
"nobopt") {
7212 return parseSetFpDirective();
7213 if (IdVal ==
"oddspreg")
7214 return parseSetOddSPRegDirective();
7215 if (IdVal ==
"nooddspreg")
7216 return parseSetNoOddSPRegDirective();
7218 return parseSetPopDirective();
7219 if (IdVal ==
"push")
7220 return parseSetPushDirective();
7221 if (IdVal ==
"reorder")
7222 return parseSetReorderDirective();
7223 if (IdVal ==
"noreorder")
7224 return parseSetNoReorderDirective();
7225 if (IdVal ==
"macro")
7226 return parseSetMacroDirective();
7227 if (IdVal ==
"nomacro")
7228 return parseSetNoMacroDirective();
7229 if (IdVal ==
"mips16")
7230 return parseSetMips16Directive();
7231 if (IdVal ==
"nomips16")
7232 return parseSetNoMips16Directive();
7233 if (IdVal ==
"nomicromips") {
7234 clearFeatureBits(Mips::FeatureMicroMips,
"micromips");
7235 getTargetStreamer().emitDirectiveSetNoMicroMips();
7236 getParser().eatToEndOfStatement();
7239 if (IdVal ==
"micromips") {
7240 if (hasMips64r6()) {
7241 Error(Loc,
".set micromips directive is not supported with MIPS64R6");
7244 return parseSetFeature(Mips::FeatureMicroMips);
7246 if (IdVal ==
"mips0")
7247 return parseSetMips0Directive();
7248 if (IdVal ==
"mips1")
7249 return parseSetFeature(Mips::FeatureMips1);
7250 if (IdVal ==
"mips2")
7251 return parseSetFeature(Mips::FeatureMips2);
7252 if (IdVal ==
"mips3")
7253 return parseSetFeature(Mips::FeatureMips3);
7254 if (IdVal ==
"mips4")
7255 return parseSetFeature(Mips::FeatureMips4);
7256 if (IdVal ==
"mips5")
7257 return parseSetFeature(Mips::FeatureMips5);
7258 if (IdVal ==
"mips32")
7259 return parseSetFeature(Mips::FeatureMips32);
7260 if (IdVal ==
"mips32r2")
7261 return parseSetFeature(Mips::FeatureMips32r2);
7262 if (IdVal ==
"mips32r3")
7263 return parseSetFeature(Mips::FeatureMips32r3);
7264 if (IdVal ==
"mips32r5")
7265 return parseSetFeature(Mips::FeatureMips32r5);
7266 if (IdVal ==
"mips32r6")
7267 return parseSetFeature(Mips::FeatureMips32r6);
7268 if (IdVal ==
"mips64")
7269 return parseSetFeature(Mips::FeatureMips64);
7270 if (IdVal ==
"mips64r2")
7271 return parseSetFeature(Mips::FeatureMips64r2);
7272 if (IdVal ==
"mips64r3")
7273 return parseSetFeature(Mips::FeatureMips64r3);
7274 if (IdVal ==
"mips64r5")
7275 return parseSetFeature(Mips::FeatureMips64r5);
7276 if (IdVal ==
"mips64r6") {
7277 if (inMicroMipsMode()) {
7278 Error(Loc,
"MIPS64R6 is not supported with microMIPS");
7281 return parseSetFeature(Mips::FeatureMips64r6);
7284 return parseSetFeature(Mips::FeatureDSP);
7285 if (IdVal ==
"dspr2")
7286 return parseSetFeature(Mips::FeatureDSPR2);
7287 if (IdVal ==
"nodsp")
7288 return parseSetNoDspDirective();
7290 return parseSetMsaDirective();
7291 if (IdVal ==
"nomsa")
7292 return parseSetNoMsaDirective();
7294 return parseSetMtDirective();
7295 if (IdVal ==
"nomt")
7296 return parseSetNoMtDirective();
7297 if (IdVal ==
"softfloat")
7298 return parseSetSoftFloatDirective();
7299 if (IdVal ==
"hardfloat")
7300 return parseSetHardFloatDirective();
7302 return parseSetFeature(Mips::FeatureCRC);
7303 if (IdVal ==
"nocrc")
7304 return parseSetNoCRCDirective();
7305 if (IdVal ==
"virt")
7306 return parseSetFeature(Mips::FeatureVirt);
7307 if (IdVal ==
"novirt")
7308 return parseSetNoVirtDirective();
7309 if (IdVal ==
"ginv")
7310 return parseSetFeature(Mips::FeatureGINV);
7311 if (IdVal ==
"noginv")
7312 return parseSetNoGINVDirective();
7315 return parseSetAssignment();
7320 bool MipsAsmParser::parseDirectiveGpWord() {
7325 if (getParser().parseExpression(Value))
7327 getParser().getStreamer().EmitGPRel32Value(Value);
7330 return Error(getLexer().getLoc(),
7331 "unexpected token, expected end of statement");
7338 bool MipsAsmParser::parseDirectiveGpDWord() {
7343 if (getParser().parseExpression(Value))
7345 getParser().getStreamer().EmitGPRel64Value(Value);
7348 return Error(getLexer().getLoc(),
7349 "unexpected token, expected end of statement");
7356 bool MipsAsmParser::parseDirectiveDtpRelWord() {
7361 if (getParser().parseExpression(Value))
7363 getParser().getStreamer().EmitDTPRel32Value(Value);
7366 return Error(getLexer().getLoc(),
7367 "unexpected token, expected end of statement");
7374 bool MipsAsmParser::parseDirectiveDtpRelDWord() {
7379 if (getParser().parseExpression(Value))
7381 getParser().getStreamer().EmitDTPRel64Value(Value);
7384 return Error(getLexer().getLoc(),
7385 "unexpected token, expected end of statement");
7392 bool MipsAsmParser::parseDirectiveTpRelWord() {
7397 if (getParser().parseExpression(Value))
7399 getParser().getStreamer().EmitTPRel32Value(Value);
7402 return Error(getLexer().getLoc(),
7403 "unexpected token, expected end of statement");
7410 bool MipsAsmParser::parseDirectiveTpRelDWord() {
7415 if (getParser().parseExpression(Value))
7417 getParser().getStreamer().EmitTPRel64Value(Value);
7420 return Error(getLexer().getLoc(),
7421 "unexpected token, expected end of statement");
7426 bool MipsAsmParser::parseDirectiveOption() {
7433 "unexpected token, expected identifier");
7438 if (Option ==
"pic0") {
7440 IsPicEnabled =
false;
7442 getTargetStreamer().emitDirectiveOptionPic0();
7446 "unexpected token, expected end of statement");
7451 if (Option ==
"pic2") {
7453 IsPicEnabled =
true;
7455 getTargetStreamer().emitDirectiveOptionPic2();
7459 "unexpected token, expected end of statement");
7466 "unknown option, expected 'pic0' or 'pic2'");
7473 bool MipsAsmParser::parseInsnDirective() {
7476 reportParseError(
"unexpected token, expected end of statement");
7482 getTargetStreamer().emitDirectiveInsn();
7493 reportParseError(
"unexpected token, expected end of statement");
7497 MCSection *ELFSection = getContext().getELFSection(
7499 getParser().getStreamer().SwitchSection(ELFSection);
7508 bool MipsAsmParser::parseSSectionDirective(
StringRef Section,
unsigned Type) {
7511 reportParseError(
"unexpected token, expected end of statement");
7515 MCSection *ELFSection = getContext().getELFSection(
7517 getParser().getStreamer().SwitchSection(ELFSection);
7536 bool MipsAsmParser::parseDirectiveModule() {
7541 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
7543 reportParseError(
".module directive must appear before any code");
7549 reportParseError(
"expected .module option identifier");
7553 if (Option ==
"oddspreg") {
7554 clearModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
7558 getTargetStreamer().updateABIInfo(*
this);
7563 getTargetStreamer().emitDirectiveModuleOddSPReg();
7567 reportParseError(
"unexpected token, expected end of statement");
7572 }
else if (Option ==
"nooddspreg") {
7574 return Error(L,
"'.module nooddspreg' requires the O32 ABI");
7577 setModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
7581 getTargetStreamer().updateABIInfo(*
this);
7586 getTargetStreamer().emitDirectiveModuleOddSPReg();
7590 reportParseError(
"unexpected token, expected end of statement");
7595 }
else if (Option ==
"fp") {
7596 return parseDirectiveModuleFP();
7597 }
else if (Option ==
"softfloat") {
7598 setModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
7602 getTargetStreamer().updateABIInfo(*
this);
7607 getTargetStreamer().emitDirectiveModuleSoftFloat();
7611 reportParseError(
"unexpected token, expected end of statement");
7616 }
else if (Option ==
"hardfloat") {
7617 clearModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
7621 getTargetStreamer().updateABIInfo(*
this);
7626 getTargetStreamer().emitDirectiveModuleHardFloat();
7630 reportParseError(
"unexpected token, expected end of statement");
7635 }
else if (Option ==
"mt") {
7636 setModuleFeatureBits(Mips::FeatureMT,
"mt");
7640 getTargetStreamer().updateABIInfo(*
this);
7645 getTargetStreamer().emitDirectiveModuleMT();
7649 reportParseError(
"unexpected token, expected end of statement");
7654 }
else if (Option ==
"crc") {
7655 setModuleFeatureBits(Mips::FeatureCRC,
"crc");
7659 getTargetStreamer().updateABIInfo(*
this);
7664 getTargetStreamer().emitDirectiveModuleCRC();
7668 reportParseError(
"unexpected token, expected end of statement");
7673 }
else if (Option ==
"nocrc") {
7674 clearModuleFeatureBits(Mips::FeatureCRC,
"crc");
7678 getTargetStreamer().updateABIInfo(*
this);
7683 getTargetStreamer().emitDirectiveModuleNoCRC();
7687 reportParseError(
"unexpected token, expected end of statement");
7692 }
else if (Option ==
"virt") {
7693 setModuleFeatureBits(Mips::FeatureVirt,
"virt");
7697 getTargetStreamer().updateABIInfo(*
this);
7702 getTargetStreamer().emitDirectiveModuleVirt();
7706 reportParseError(
"unexpected token, expected end of statement");
7711 }
else if (Option ==
"novirt") {
7712 clearModuleFeatureBits(Mips::FeatureVirt,
"virt");
7716 getTargetStreamer().updateABIInfo(*
this);
7721 getTargetStreamer().emitDirectiveModuleNoVirt();
7725 reportParseError(
"unexpected token, expected end of statement");
7730 }
else if (Option ==
"ginv") {
7731 setModuleFeatureBits(Mips::FeatureGINV,
"ginv");
7735 getTargetStreamer().updateABIInfo(*
this);
7740 getTargetStreamer().emitDirectiveModuleGINV();
7744 reportParseError(
"unexpected token, expected end of statement");
7749 }
else if (Option ==
"noginv") {
7750 clearModuleFeatureBits(Mips::FeatureGINV,
"ginv");
7754 getTargetStreamer().updateABIInfo(*
this);
7759 getTargetStreamer().emitDirectiveModuleNoGINV();
7763 reportParseError(
"unexpected token, expected end of statement");
7769 return Error(L,
"'" +
Twine(Option) +
"' is not a valid .module option.");
7777 bool MipsAsmParser::parseDirectiveModuleFP() {
7782 reportParseError(
"unexpected token, expected equals sign '='");
7788 if (!parseFpABIValue(FpABI,
".module"))
7792 reportParseError(
"unexpected token, expected end of statement");
7798 getTargetStreamer().updateABIInfo(*
this);
7803 getTargetStreamer().emitDirectiveModuleFP();
7813 bool ModuleLevelOptions = Directive ==
".module";
7819 if (Value !=
"xx") {
7820 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
7825 reportParseError(
"'" + Directive +
" fp=xx' requires the O32 ABI");
7830 if (ModuleLevelOptions) {
7831 setModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
7832 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
7834 setFeatureBits(Mips::FeatureFPXX,
"fpxx");
7835 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
7844 if (Value != 32 && Value != 64) {
7845 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
7851 reportParseError(
"'" + Directive +
" fp=32' requires the O32 ABI");
7856 if (ModuleLevelOptions) {
7857 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
7858 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
7860 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
7861 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
7865 if (ModuleLevelOptions) {
7866 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
7867 setModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
7869 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
7870 setFeatureBits(Mips::FeatureFP64Bit,
"fp64");
7880 bool MipsAsmParser::ParseDirective(
AsmToken DirectiveID) {
7889 if (IDVal ==
".cpload") {
7890 parseDirectiveCpLoad(DirectiveID.
getLoc());
7893 if (IDVal ==
".cprestore") {
7894 parseDirectiveCpRestore(DirectiveID.
getLoc());
7897 if (IDVal ==
".ent") {
7901 reportParseError(
"expected identifier after .ent");
7915 reportParseError(
"unexpected token, expected end of statement");
7919 const MCExpr *DummyNumber;
7920 int64_t DummyNumberVal;
7924 reportParseError(
"expected number after comma");
7927 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
7928 reportParseError(
"expected an absolute expression after comma");
7935 reportParseError(
"unexpected token, expected end of statement");
7939 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
7941 getTargetStreamer().emitDirectiveEnt(*Sym);
7943 IsCpRestoreSet =
false;
7947 if (IDVal ==
".end") {
7951 reportParseError(
"expected identifier after .end");
7956 reportParseError(
"unexpected token, expected end of statement");
7960 if (CurrentFn ==
nullptr) {
7961 reportParseError(
".end used without .ent");
7965 if ((SymbolName != CurrentFn->
getName())) {
7966 reportParseError(
".end symbol does not match .ent symbol");
7970 getTargetStreamer().emitDirectiveEnd(SymbolName);
7971 CurrentFn =
nullptr;
7972 IsCpRestoreSet =
false;
7976 if (IDVal ==
".frame") {
7981 reportParseError(
"expected stack register");
7985 MipsOperand &StackRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7986 if (!StackRegOpnd.isGPRAsmReg()) {
7987 reportParseError(StackRegOpnd.getStartLoc(),
7988 "expected general purpose register");
7991 unsigned StackReg = StackRegOpnd.getGPR32Reg();
7996 reportParseError(
"unexpected token, expected comma");
8002 int64_t FrameSizeVal;
8005 reportParseError(
"expected frame size value");
8009 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
8010 reportParseError(
"frame size not an absolute expression");
8017 reportParseError(
"unexpected token, expected comma");
8023 ResTy = parseAnyRegister(TmpReg);
8025 reportParseError(
"expected return register");
8029 MipsOperand &ReturnRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
8030 if (!ReturnRegOpnd.isGPRAsmReg()) {
8031 reportParseError(ReturnRegOpnd.getStartLoc(),
8032 "expected general purpose register");
8038 reportParseError(
"unexpected token, expected end of statement");
8042 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
8043 ReturnRegOpnd.getGPR32Reg());
8044 IsCpRestoreSet =
false;
8048 if (IDVal ==
".set") {
8049 parseDirectiveSet();
8053 if (IDVal ==
".mask" || IDVal ==
".fmask") {
8068 reportParseError(
"expected bitmask value");
8072 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
8073 reportParseError(
"bitmask not an absolute expression");
8080 reportParseError(
"unexpected token, expected comma");
8085 const MCExpr *FrameOffset;
8086 int64_t FrameOffsetVal;
8089 reportParseError(
"expected frame offset value");
8093 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
8094 reportParseError(
"frame offset not an absolute expression");
8100 reportParseError(
"unexpected token, expected end of statement");
8104 if (IDVal ==
".mask")
8105 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
8107 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
8111 if (IDVal ==
".nan")
8112 return parseDirectiveNaN();
8114 if (IDVal ==
".gpword") {
8115 parseDirectiveGpWord();
8119 if (IDVal ==
".gpdword") {
8120 parseDirectiveGpDWord();
8124 if (IDVal ==
".dtprelword") {
8125 parseDirectiveDtpRelWord();
8129 if (IDVal ==
".dtpreldword") {
8130 parseDirectiveDtpRelDWord();
8134 if (IDVal ==
".tprelword") {
8135 parseDirectiveTpRelWord();
8139 if (IDVal ==
".tpreldword") {
8140 parseDirectiveTpRelDWord();
8144 if (IDVal ==
".option") {
8145 parseDirectiveOption();
8149 if (IDVal ==
".abicalls") {
8150 getTargetStreamer().emitDirectiveAbiCalls();
8153 "unexpected token, expected end of statement");
8158 if (IDVal ==
".cpsetup") {
8159 parseDirectiveCPSetup();
8162 if (IDVal ==
".cpreturn") {
8163 parseDirectiveCPReturn();
8166 if (IDVal ==
".module") {
8167 parseDirectiveModule();
8170 if (IDVal ==
".llvm_internal_mips_reallow_module_directive") {
8171 parseInternalDirectiveReallowModule();
8174 if (IDVal ==
".insn") {
8175 parseInsnDirective();
8178 if (IDVal ==
".rdata") {
8179 parseRSectionDirective(
".rodata");
8182 if (IDVal ==
".sbss") {
8186 if (IDVal ==
".sdata") {
8194 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
8197 reportParseError(
"unexpected token, expected end of statement");
8201 getTargetStreamer().reallowModuleDirective();
8214 #define GET_REGISTER_MATCHER 8215 #define GET_MATCHER_IMPLEMENTATION 8216 #define GET_MNEMONIC_SPELL_CHECKER 8217 #include "MipsGenAsmMatcher.inc" 8219 bool MipsAsmParser::mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID) {
8221 const MatchEntry *Start, *End;
8222 switch (VariantID) {
8227 auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
8228 return MnemonicRange.first != MnemonicRange.second;
static bool isReg(const MCInst &MI, unsigned OpNo)
void emitRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, SMLoc IDLoc, const MCSubtargetInfo *STI)
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...
const_iterator end(StringRef path)
Get end iterator over path.
static ARMBaseTargetMachine::ARMABI computeTargetABI(const Triple &TT, StringRef CPU, const TargetOptions &Options)
void emitRRIII(unsigned Opcode, unsigned Reg0, unsigned Reg1, int16_t Imm0, int16_t Imm1, int16_t Imm2, SMLoc IDLoc, const MCSubtargetInfo *STI)
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
T findLastSet(T Val, ZeroBehavior ZB=ZB_Max)
Get the index of the last set bit starting from the least significant bit.
unsigned GetPtrAdduOp() const
uint64_t getZExtValue() const
Get zero extended value.
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
This class represents lattice values for constants.
bool isVariable() const
isVariable - Check if this is a variable symbol.
void setFeatureBits(const FeatureBitset &FeatureBits_)
This represents an "assembler immediate".
bool is(AsmToken::TokenKind K) const
Check if the current token has kind K.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
VariantKind getKind() const
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)
bool ArePtrs64bit() const
MCTargetAsmParser - Generic interface to target specific assembly parsers.
void push_back(const T &Elt)
Describe properties that are true of each instruction in the target description file.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
Target specific streamer interface.
bool isNot(TokenKind K) const
const FeatureBitset Features
Target & getTheMipselTarget()
iterator find(StringRef Key)
virtual void emitDirectiveSetNoReorder()
constexpr bool isInt< 8 >(int64_t x)
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
IsPCRelativeLoad - A Load instruction with implicit source register ($pc) with explicit offset and de...
constexpr bool isInt< 16 >(int64_t x)
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)
const AsmToken & getTok() const
Get the current AsmToken from the stream.
bool mayLoad() const
Return true if this instruction could possibly read memory.
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).
SMRange getLocRange() const
virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI, bool PrintSchedInfo=false)
Emit the given Instruction into the current section.
return AArch64::GPR64RegClass contains(Reg)
bool isBranch() const
Returns true if this is a conditional, unconditional, or indirect branch.
const Triple & getTargetTriple() const
SI optimize exec mask operations pre RA
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
MCContext & getContext() const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string...
int64_t getConstant() const
SMLoc getLoc() const
Get the current source location.
const MCSymbolRefExpr * getSymB() const
amdgpu Simplify well known AMD library false Value Value const Twine & Name
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
static MCOperand createReg(unsigned Reg)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
const FeatureBitset & getFeatureBits() const
Generic assembler lexer interface, for use by target specific assembly lexers.
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.
bool isInSection() const
isInSection - Check if this symbol is defined in some section (i.e., it is defined but not absolute)...
The access may reference the value stored in memory.
Target independent representation for an assembler token.
static int getRegClass(RegisterKind Is, unsigned RegWidth)
Represent a reference to a symbol from inside an expression.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE R Default(T Value)
unsigned GetGlobalPtr() const
static bool isMem(const MachineInstr &MI, unsigned Op)
HasFCCRegOperand - Instruction uses an $fcc<x> register.
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand...
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
unsigned getReg() const
Returns the register number.
Context object for machine code objects.
void emitNop(SMLoc IDLoc, const MCSubtargetInfo *STI)
std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \\\)
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
uint8_t OperandType
Information about the type of the operand.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser, for use in the target machine initialization function.
bool evaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout, const MCFixup *Fixup) const
Try to evaluate the expression to a relocatable value, i.e.
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
Target & getTheMips64Target()
Unary assembler expressions.
Simple integer binary arithmetic operators.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
static unsigned getRegisterForMxtrFP(MCInst &Inst, bool IsMFTC1)
const MCExpr * getExpr() const
static const fltSemantics & IEEEdouble() LLVM_READNONE
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).
static bool isShiftedUIntAtAnyPosition(uint64_t x)
Can the value be represented by a unsigned N-bit value and a shift left?
Analysis containing CSE Info
Instances of this class represent a single low-level machine instruction.
static const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
void emitRX(unsigned Opcode, unsigned Reg0, MCOperand Op1, SMLoc IDLoc, const MCSubtargetInfo *STI)
uint32_t FloatToBits(float Float)
This function takes a float and returns the bit equivalent 32-bit integer.
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()
FeatureBitset ToggleFeature(uint64_t FB)
Toggle a feature and return the re-computed feature bits.
const char * getPointer() const
A switch()-like statement whose cases are string literals.
Streaming machine code generation interface.
MCSymbol * createTempSymbol(bool CanBeUnnamed=true)
Create and return a new assembler temporary symbol with a unique but unspecified name.
Target & getTheMips64elTarget()
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
MCTargetStreamer * getTargetStreamer()
Container class for subtarget features.
bool isLittleEndian() const
Tests whether the target triple is little endian.
static bool hasShortDelaySlot(MCInst &Inst)
The instances of the Type class are immutable: once they are created, they are never changed...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
static ManagedStatic< OptionRegistry > OR
static unsigned getRegisterForMxtrC0(MCInst &Inst, bool IsMFTC0)
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)
This file declares a class to represent arbitrary precision floating point values and provide a varie...
bool isTemporary() const
isTemporary - Check if this is an assembler temporary symbol.
void emitR(unsigned Opcode, unsigned Reg0, SMLoc IDLoc, const MCSubtargetInfo *STI)
const MCSymbolRefExpr * getSymA() const
static const MCSymbol * getSingleMCSymbol(const MCExpr *Expr)
static unsigned nextReg(unsigned Reg)
int64_t getIntVal() const
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
unsigned getNumOperands() const
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 isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
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.
Triple - Helper class for working with autoconf configuration names.
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.
static std::string MipsMnemonicSpellCheck(StringRef S, uint64_t FBS, unsigned VariantID=0)
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 emitRRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, unsigned Reg2, SMLoc IDLoc, const MCSubtargetInfo *STI)
MCStreamer & getStreamer()
void setOpcode(unsigned Op)
constexpr bool isInt< 32 >(int64_t x)
void emitDSLL(unsigned DstReg, unsigned SrcReg, int16_t ShiftAmount, SMLoc IDLoc, const MCSubtargetInfo *STI)
const MCSymbol & getSymbol() const
bool hasDelaySlot() const
Returns true if the specified instruction has a delay slot which must be filled by the code generator...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
const MCOperand & getOperand(unsigned i) const
static unsigned getRegisterForMxtrDSP(MCInst &Inst, bool IsMFDSP)
virtual bool EmitRelocDirective(const MCExpr &Offset, StringRef Name, const MCExpr *Expr, SMLoc Loc, const MCSubtargetInfo &STI)
Emit a .reloc directive.
void emitEmptyDelaySlot(bool hasShortDelaySlot, SMLoc IDLoc, const MCSubtargetInfo *STI)
void setVariableValue(const MCExpr *Value)
double BitsToDouble(uint64_t Bits)
This function takes a 64-bit integer and returns the bit equivalent double.
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.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings"...
bool is(TokenKind K) const
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
Base class for user error types.
bool mayStore() const
Return true if this instruction could possibly modify memory.
static const MipsMCExpr * create(MipsExprKind Kind, const MCExpr *Expr, MCContext &Ctx)
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Case(StringLiteral S, T Value)
Target & getTheMipsTarget()
static SMLoc getFromPointer(const char *Ptr)
cl::opt< bool > EmitJalrReloc
void updateABIInfo(const PredicateLibrary &P)
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
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.
bool isCall() const
Return true if the instruction is a call.
Generic base class for all target subtargets.
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.
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Cases(StringLiteral S0, StringLiteral S1, T Value)
constexpr bool isUInt< 16 >(uint64_t x)
bool isNot(AsmToken::TokenKind K) const
Check if the current token has kind K.
unsigned GetZeroReg() const
const MCInstrDesc MipsInsts[]
StringRef getName() const
getName - Get the symbol name.
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)
void emitRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1, MCOperand Op2, SMLoc IDLoc, const MCSubtargetInfo *STI)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM_NODISCARD char front() const
front - Get the first character in the string.
const MCExpr * getVariableValue(bool SetUsed=true) const
getVariableValue - Get the value for variable symbols.
virtual void emitDirectiveSetReorder()
LLVM Value Representation.
const MCOperandInfo * OpInfo
virtual void EmitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
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...
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...
APInt bitcastToAPInt() const
static FeatureBitset getFeatures(StringRef CPU, StringRef FS, ArrayRef< SubtargetFeatureKV > ProcDesc, ArrayRef< SubtargetFeatureKV > ProcFeatures)
Target specific expression.
unsigned GetNullPtr() const
Represents a location in source code.
This holds information about one operand of a machine instruction, indicating the register class for ...
unsigned getOpcode() const
Instances of this class represent operands of the MCInst class.
static MCOperand createImm(int64_t Val)
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx)
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()
TokenKind getKind() const