62#define DEBUG_TYPE "mips-asm-parser"
74class MipsAssemblerOptions {
76 MipsAssemblerOptions(
const FeatureBitset &Features_) : Features(Features_) {}
78 MipsAssemblerOptions(
const MipsAssemblerOptions *Opts) {
79 ATReg = Opts->getATRegIndex();
80 Reorder = Opts->isReorder();
81 Macro = Opts->isMacro();
82 Features = Opts->getFeatures();
85 unsigned getATRegIndex()
const {
return ATReg; }
86 bool setATRegIndex(
unsigned Reg) {
94 bool isReorder()
const {
return Reorder; }
95 void setReorder() { Reorder =
true; }
96 void setNoReorder() { Reorder =
false; }
98 bool isMacro()
const {
return Macro; }
99 void setMacro() {
Macro =
true; }
100 void setNoMacro() {
Macro =
false; }
103 void setFeatures(
const FeatureBitset &Features_) { Features = Features_; }
121const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
122 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
123 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
124 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
125 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
126 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
127 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
128 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
129 Mips::FeatureCnMipsP, Mips::FeatureFP64Bit, Mips::FeatureGP64Bit,
138 "do not have a target streamer");
152 bool CurForbiddenSlotAttr;
155 unsigned CpSaveLocation;
157 bool CpSaveLocationIsRegister;
163 void printWarningWithFixIt(
const Twine &Msg,
const Twine &FixMsg,
168#define GET_ASSEMBLER_HEADER
169#include "MipsGenAsmMatcher.inc"
179 bool MatchingInlineAsm)
override;
184 SMLoc &EndLoc)
override;
190 bool mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID);
213 enum MacroExpanderResultTy {
220 MacroExpanderResultTy tryExpandInstruction(
MCInst &Inst,
SMLoc IDLoc,
227 bool loadImmediate(int64_t ImmValue,
unsigned DstReg,
unsigned SrcReg,
228 bool Is32BitImm,
bool IsAddress,
SMLoc IDLoc,
231 bool loadAndAddSymbolAddress(
const MCExpr *SymExpr,
unsigned DstReg,
232 unsigned SrcReg,
bool Is32BitSym,
SMLoc IDLoc,
237 bool expandLoadImm(
MCInst &Inst,
bool Is32BitImm,
SMLoc IDLoc,
246 bool expandLoadDoubleImmToFPR(
MCInst &Inst,
bool Is64FPU,
SMLoc IDLoc,
249 bool expandLoadAddress(
unsigned DstReg,
unsigned BaseReg,
278 bool expandTrunc(
MCInst &Inst,
bool IsDouble,
bool Is64FPU,
SMLoc IDLoc,
353 bool reportParseError(
const Twine &ErrorMsg);
354 bool reportParseError(
SMLoc Loc,
const Twine &ErrorMsg);
356 bool parseMemOffset(
const MCExpr *&Res,
bool isParenExpr);
358 bool parseSetMips0Directive();
359 bool parseSetArchDirective();
360 bool parseSetFeature(
uint64_t Feature);
361 bool isPicAndNotNxxAbi();
362 bool parseDirectiveCpAdd(
SMLoc Loc);
363 bool parseDirectiveCpLoad(
SMLoc Loc);
364 bool parseDirectiveCpLocal(
SMLoc Loc);
365 bool parseDirectiveCpRestore(
SMLoc Loc);
366 bool parseDirectiveCPSetup();
367 bool parseDirectiveCPReturn();
368 bool parseDirectiveNaN();
369 bool parseDirectiveSet();
370 bool parseDirectiveOption();
371 bool parseInsnDirective();
372 bool parseRSectionDirective(
StringRef Section);
373 bool parseSSectionDirective(
StringRef Section,
unsigned Type);
375 bool parseSetAtDirective();
376 bool parseSetNoAtDirective();
377 bool parseSetMacroDirective();
378 bool parseSetNoMacroDirective();
379 bool parseSetMsaDirective();
380 bool parseSetNoMsaDirective();
381 bool parseSetNoDspDirective();
382 bool parseSetNoMips3DDirective();
383 bool parseSetReorderDirective();
384 bool parseSetNoReorderDirective();
385 bool parseSetMips16Directive();
386 bool parseSetNoMips16Directive();
387 bool parseSetFpDirective();
388 bool parseSetOddSPRegDirective();
389 bool parseSetNoOddSPRegDirective();
390 bool parseSetPopDirective();
391 bool parseSetPushDirective();
392 bool parseSetSoftFloatDirective();
393 bool parseSetHardFloatDirective();
394 bool parseSetMtDirective();
395 bool parseSetNoMtDirective();
396 bool parseSetNoCRCDirective();
397 bool parseSetNoVirtDirective();
398 bool parseSetNoGINVDirective();
400 bool parseSetAssignment();
402 bool parseDirectiveGpWord();
403 bool parseDirectiveGpDWord();
404 bool parseDirectiveDtpRelWord();
405 bool parseDirectiveDtpRelDWord();
406 bool parseDirectiveTpRelWord();
407 bool parseDirectiveTpRelDWord();
408 bool parseDirectiveModule();
409 bool parseDirectiveModuleFP();
413 bool parseInternalDirectiveReallowModule();
417 int matchCPURegisterName(
StringRef Symbol);
419 int matchHWRegsRegisterName(
StringRef Symbol);
431 unsigned getReg(
int RC,
int RegNo);
436 unsigned getATReg(
SMLoc Loc);
446 bool validateMSAIndex(
int Val,
int RegKind);
473 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
481 if (!(
getSTI().hasFeature(Feature))) {
490 if (
getSTI().hasFeature(Feature)) {
499 setFeatureBits(Feature, FeatureString);
500 AssemblerOptions.
front()->setFeatures(
getSTI().getFeatureBits());
504 clearFeatureBits(Feature, FeatureString);
505 AssemblerOptions.
front()->setFeatures(
getSTI().getFeatureBits());
509 enum MipsMatchResultTy {
511 Match_RequiresDifferentOperands,
512 Match_RequiresNoZeroRegister,
513 Match_RequiresSameSrcAndDst,
514 Match_NoFCCRegisterForCurrentISA,
515 Match_NonZeroOperandForSync,
516 Match_NonZeroOperandForMTCX,
517 Match_RequiresPosSizeRange0_32,
518 Match_RequiresPosSizeRange33_64,
519 Match_RequiresPosSizeUImm6,
520#define GET_OPERAND_DIAGNOSTIC_TYPES
521#include "MipsGenAsmMatcher.inc"
522#undef GET_OPERAND_DIAGNOSTIC_TYPES
542 std::make_unique<MipsAssemblerOptions>(
getSTI().getFeatureBits()));
546 std::make_unique<MipsAssemblerOptions>(
getSTI().getFeatureBits()));
548 getTargetStreamer().updateABIInfo(*
this);
550 if (!isABI_O32() && !useOddSPReg() != 0)
555 CurForbiddenSlotAttr =
false;
558 IsCpRestoreSet =
false;
559 CpRestoreOffset = -1;
560 GPReg =
ABI.GetGlobalPtr();
565 if (
getSTI().
getCPU() ==
"mips64r6" && inMicroMipsMode())
568 if (!isABI_O32() && inMicroMipsMode())
573 bool hasEightFccRegisters()
const {
return hasMips4() || hasMips32(); }
575 bool isGP64bit()
const {
579 bool isFP64bit()
const {
583 bool isJalrRelocAvailable(
const MCExpr *JalExpr) {
592 return ABI.IsN32() ||
ABI.IsN64();
597 bool isABI_N32()
const {
return ABI.IsN32(); }
598 bool isABI_N64()
const {
return ABI.IsN64(); }
599 bool isABI_O32()
const {
return ABI.IsO32(); }
600 bool isABI_FPXX()
const {
604 bool useOddSPReg()
const {
608 bool inMicroMipsMode()
const {
612 bool hasMips1()
const {
616 bool hasMips2()
const {
620 bool hasMips3()
const {
624 bool hasMips4()
const {
628 bool hasMips5()
const {
632 bool hasMips32()
const {
636 bool hasMips64()
const {
640 bool hasMips32r2()
const {
644 bool hasMips64r2()
const {
648 bool hasMips32r3()
const {
649 return (
getSTI().hasFeature(Mips::FeatureMips32r3));
652 bool hasMips64r3()
const {
653 return (
getSTI().hasFeature(Mips::FeatureMips64r3));
656 bool hasMips32r5()
const {
657 return (
getSTI().hasFeature(Mips::FeatureMips32r5));
660 bool hasMips64r5()
const {
661 return (
getSTI().hasFeature(Mips::FeatureMips64r5));
664 bool hasMips32r6()
const {
668 bool hasMips64r6()
const {
672 bool hasDSP()
const {
676 bool hasDSPR2()
const {
680 bool hasDSPR3()
const {
684 bool hasMSA()
const {
688 bool hasCnMips()
const {
689 return (
getSTI().hasFeature(Mips::FeatureCnMips));
692 bool hasCnMipsP()
const {
693 return (
getSTI().hasFeature(Mips::FeatureCnMipsP));
700 bool inMips16Mode()
const {
704 bool useTraps()
const {
708 bool useSoftFloat()
const {
715 bool hasCRC()
const {
719 bool hasVirt()
const {
723 bool hasGINV()
const {
727 bool hasForbiddenSlot(
const MCInstrDesc &MCID)
const {
731 bool SafeInForbiddenSlot(
const MCInstrDesc &MCID)
const {
738 void warnIfRegIndexIsAT(
unsigned RegIndex,
SMLoc Loc);
740 void warnIfNoMacro(
SMLoc Loc);
742 bool isLittle()
const {
return IsLittleEndian; }
747 switch(OperatorToken) {
818 RegKind_MSACtrl = 16,
823 RegKind_HWRegs = 256,
827 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
828 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
829 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
842 MipsOperand(KindTy K, MipsAsmParser &Parser) :
Kind(
K), AsmParser(Parser) {}
844 ~MipsOperand()
override {
853 case k_RegisterIndex:
861 MipsAsmParser &AsmParser;
890 struct RegIdxOp RegIdx;
893 struct RegListOp RegList;
896 SMLoc StartLoc, EndLoc;
899 static std::unique_ptr<MipsOperand> CreateReg(
unsigned Index,
StringRef Str,
903 MipsAsmParser &Parser) {
904 auto Op = std::make_unique<MipsOperand>(k_RegisterIndex, Parser);
907 Op->RegIdx.Kind = RegKind;
908 Op->RegIdx.Tok.Data = Str.data();
909 Op->RegIdx.Tok.Length = Str.size();
918 unsigned getGPR32Reg()
const {
919 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
920 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
921 unsigned ClassID = Mips::GPR32RegClassID;
922 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
927 unsigned getGPRMM16Reg()
const {
928 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
929 unsigned ClassID = Mips::GPR32RegClassID;
930 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
935 unsigned getGPR64Reg()
const {
936 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
937 unsigned ClassID = Mips::GPR64RegClassID;
938 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
944 unsigned getAFGR64Reg()
const {
945 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
946 if (RegIdx.Index % 2 != 0)
947 AsmParser.Warning(StartLoc,
"Float register should be even.");
948 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
949 .getRegister(RegIdx.Index / 2);
954 unsigned getFGR64Reg()
const {
955 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
956 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
957 .getRegister(RegIdx.Index);
962 unsigned getFGR32Reg()
const {
963 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
964 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
965 .getRegister(RegIdx.Index);
970 unsigned getFCCReg()
const {
971 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) &&
"Invalid access!");
972 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
973 .getRegister(RegIdx.Index);
978 unsigned getMSA128Reg()
const {
979 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) &&
"Invalid access!");
982 unsigned ClassID = Mips::MSA128BRegClassID;
983 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
988 unsigned getMSACtrlReg()
const {
989 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) &&
"Invalid access!");
990 unsigned ClassID = Mips::MSACtrlRegClassID;
991 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
996 unsigned getCOP0Reg()
const {
997 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) &&
"Invalid access!");
998 unsigned ClassID = Mips::COP0RegClassID;
999 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1004 unsigned getCOP2Reg()
const {
1005 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) &&
"Invalid access!");
1006 unsigned ClassID = Mips::COP2RegClassID;
1007 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1012 unsigned getCOP3Reg()
const {
1013 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) &&
"Invalid access!");
1014 unsigned ClassID = Mips::COP3RegClassID;
1015 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1020 unsigned getACC64DSPReg()
const {
1021 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
1022 unsigned ClassID = Mips::ACC64DSPRegClassID;
1023 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1028 unsigned getHI32DSPReg()
const {
1029 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
1030 unsigned ClassID = Mips::HI32DSPRegClassID;
1031 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1036 unsigned getLO32DSPReg()
const {
1037 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
1038 unsigned ClassID = Mips::LO32DSPRegClassID;
1039 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1044 unsigned getCCRReg()
const {
1045 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) &&
"Invalid access!");
1046 unsigned ClassID = Mips::CCRRegClassID;
1047 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1052 unsigned getHWRegsReg()
const {
1053 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) &&
"Invalid access!");
1054 unsigned ClassID = Mips::HWRegsRegClassID;
1055 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1063 else if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
1069 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
1076 void addGPR32ZeroAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1077 assert(
N == 1 &&
"Invalid number of operands!");
1081 void addGPR32NonZeroAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1082 assert(
N == 1 &&
"Invalid number of operands!");
1086 void addGPR32AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1087 assert(
N == 1 &&
"Invalid number of operands!");
1091 void addGPRMM16AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1092 assert(
N == 1 &&
"Invalid number of operands!");
1096 void addGPRMM16AsmRegZeroOperands(
MCInst &Inst,
unsigned N)
const {
1097 assert(
N == 1 &&
"Invalid number of operands!");
1101 void addGPRMM16AsmRegMovePOperands(
MCInst &Inst,
unsigned N)
const {
1102 assert(
N == 1 &&
"Invalid number of operands!");
1106 void addGPRMM16AsmRegMovePPairFirstOperands(
MCInst &Inst,
unsigned N)
const {
1107 assert(
N == 1 &&
"Invalid number of operands!");
1111 void addGPRMM16AsmRegMovePPairSecondOperands(
MCInst &Inst,
1113 assert(
N == 1 &&
"Invalid number of operands!");
1120 void addGPR64AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1121 assert(
N == 1 &&
"Invalid number of operands!");
1125 void addAFGR64AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1126 assert(
N == 1 &&
"Invalid number of operands!");
1130 void addStrictlyAFGR64AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1131 assert(
N == 1 &&
"Invalid number of operands!");
1135 void addStrictlyFGR64AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1136 assert(
N == 1 &&
"Invalid number of operands!");
1140 void addFGR64AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1141 assert(
N == 1 &&
"Invalid number of operands!");
1145 void addFGR32AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1146 assert(
N == 1 &&
"Invalid number of operands!");
1150 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1151 AsmParser.getParser().printError(
1152 StartLoc,
"-mno-odd-spreg prohibits the use of odd FPU "
1156 void addStrictlyFGR32AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1157 assert(
N == 1 &&
"Invalid number of operands!");
1160 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1161 AsmParser.Error(StartLoc,
"-mno-odd-spreg prohibits the use of odd FPU "
1165 void addFCCAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1166 assert(
N == 1 &&
"Invalid number of operands!");
1170 void addMSA128AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1171 assert(
N == 1 &&
"Invalid number of operands!");
1175 void addMSACtrlAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1176 assert(
N == 1 &&
"Invalid number of operands!");
1180 void addCOP0AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1181 assert(
N == 1 &&
"Invalid number of operands!");
1185 void addCOP2AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1186 assert(
N == 1 &&
"Invalid number of operands!");
1190 void addCOP3AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1191 assert(
N == 1 &&
"Invalid number of operands!");
1195 void addACC64DSPAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1196 assert(
N == 1 &&
"Invalid number of operands!");
1200 void addHI32DSPAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1201 assert(
N == 1 &&
"Invalid number of operands!");
1205 void addLO32DSPAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1206 assert(
N == 1 &&
"Invalid number of operands!");
1210 void addCCRAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1211 assert(
N == 1 &&
"Invalid number of operands!");
1215 void addHWRegsAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1216 assert(
N == 1 &&
"Invalid number of operands!");
1220 template <
unsigned Bits,
int Offset = 0,
int AdjustOffset = 0>
1221 void addConstantUImmOperands(
MCInst &Inst,
unsigned N)
const {
1222 assert(
N == 1 &&
"Invalid number of operands!");
1226 Imm += AdjustOffset;
1230 template <
unsigned Bits>
1231 void addSImmOperands(
MCInst &Inst,
unsigned N)
const {
1232 if (
isImm() && !isConstantImm()) {
1233 addExpr(Inst, getImm());
1236 addConstantSImmOperands<Bits, 0, 0>(Inst,
N);
1239 template <
unsigned Bits>
1240 void addUImmOperands(
MCInst &Inst,
unsigned N)
const {
1241 if (
isImm() && !isConstantImm()) {
1242 addExpr(Inst, getImm());
1245 addConstantUImmOperands<Bits, 0, 0>(Inst,
N);
1248 template <
unsigned Bits,
int Offset = 0,
int AdjustOffset = 0>
1249 void addConstantSImmOperands(
MCInst &Inst,
unsigned N)
const {
1250 assert(
N == 1 &&
"Invalid number of operands!");
1251 int64_t
Imm = getConstantImm() -
Offset;
1252 Imm = SignExtend64<Bits>(Imm);
1254 Imm += AdjustOffset;
1258 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
1259 assert(
N == 1 &&
"Invalid number of operands!");
1260 const MCExpr *Expr = getImm();
1261 addExpr(Inst, Expr);
1264 void addMemOperands(
MCInst &Inst,
unsigned N)
const {
1265 assert(
N == 2 &&
"Invalid number of operands!");
1268 ? getMemBase()->getGPR64Reg()
1269 : getMemBase()->getGPR32Reg()));
1271 const MCExpr *Expr = getMemOff();
1272 addExpr(Inst, Expr);
1275 void addMicroMipsMemOperands(
MCInst &Inst,
unsigned N)
const {
1276 assert(
N == 2 &&
"Invalid number of operands!");
1280 const MCExpr *Expr = getMemOff();
1281 addExpr(Inst, Expr);
1284 void addRegListOperands(
MCInst &Inst,
unsigned N)
const {
1285 assert(
N == 1 &&
"Invalid number of operands!");
1287 for (
auto RegNo : getRegList())
1291 bool isReg()
const override {
1294 return isGPRAsmReg() && RegIdx.Index == 0;
1297 bool isRegIdx()
const {
return Kind == k_RegisterIndex; }
1298 bool isImm()
const override {
return Kind == k_Immediate; }
1300 bool isConstantImm()
const {
1302 return isImm() && getImm()->evaluateAsAbsolute(Res);
1305 bool isConstantImmz()
const {
1306 return isConstantImm() && getConstantImm() == 0;
1309 template <
unsigned Bits,
int Offset = 0>
bool isConstantUImm()
const {
1310 return isConstantImm() && isUInt<Bits>(getConstantImm() -
Offset);
1313 template <
unsigned Bits>
bool isSImm()
const {
1314 return isConstantImm() ? isInt<Bits>(getConstantImm()) :
isImm();
1317 template <
unsigned Bits>
bool isUImm()
const {
1318 return isConstantImm() ? isUInt<Bits>(getConstantImm()) :
isImm();
1321 template <
unsigned Bits>
bool isAnyImm()
const {
1322 return isConstantImm() ? (isInt<Bits>(getConstantImm()) ||
1323 isUInt<Bits>(getConstantImm()))
1327 template <
unsigned Bits,
int Offset = 0>
bool isConstantSImm()
const {
1328 return isConstantImm() && isInt<Bits>(getConstantImm() -
Offset);
1331 template <
unsigned Bottom,
unsigned Top>
bool isConstantUImmRange()
const {
1332 return isConstantImm() && getConstantImm() >= Bottom &&
1333 getConstantImm() <= Top;
1336 bool isToken()
const override {
1339 return Kind == k_Token;
1342 bool isMem()
const override {
return Kind == k_Memory; }
1344 bool isConstantMemOff()
const {
1345 return isMem() && isa<MCConstantExpr>(getMemOff());
1349 template <
unsigned Bits,
unsigned ShiftAmount = 0>
1350 bool isMemWithSimmOffset()
const {
1353 if (!getMemBase()->isGPRAsmReg())
1355 if (isa<MCTargetExpr>(getMemOff()) ||
1356 (isConstantMemOff() &&
1357 isShiftedInt<Bits, ShiftAmount>(getConstantMemOff())))
1360 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res,
nullptr,
nullptr);
1361 return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.
getConstant());
1364 bool isMemWithPtrSizeOffset()
const {
1367 if (!getMemBase()->isGPRAsmReg())
1369 const unsigned PtrBits = AsmParser.getABI().ArePtrs64bit() ? 64 : 32;
1370 if (isa<MCTargetExpr>(getMemOff()) ||
1371 (isConstantMemOff() &&
isIntN(PtrBits, getConstantMemOff())))
1374 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res,
nullptr,
nullptr);
1378 bool isMemWithGRPMM16Base()
const {
1379 return isMem() && getMemBase()->isMM16AsmReg();
1382 template <
unsigned Bits>
bool isMemWithUimmOffsetSP()
const {
1383 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1384 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1387 template <
unsigned Bits>
bool isMemWithUimmWordAlignedOffsetSP()
const {
1388 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1389 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1390 && (getMemBase()->getGPR32Reg() == Mips::SP);
1393 template <
unsigned Bits>
bool isMemWithSimmWordAlignedOffsetGP()
const {
1394 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
1395 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1396 && (getMemBase()->getGPR32Reg() == Mips::GP);
1399 template <
unsigned Bits,
unsigned ShiftLeftAmount>
1400 bool isScaledUImm()
const {
1401 return isConstantImm() &&
1402 isShiftedUInt<Bits, ShiftLeftAmount>(getConstantImm());
1405 template <
unsigned Bits,
unsigned ShiftLeftAmount>
1406 bool isScaledSImm()
const {
1407 if (isConstantImm() &&
1408 isShiftedInt<Bits, ShiftLeftAmount>(getConstantImm()))
1412 if (Kind != k_Immediate)
1415 bool Success = getImm()->evaluateAsRelocatable(Res,
nullptr,
nullptr);
1419 bool isRegList16()
const {
1423 int Size = RegList.List->size();
1424 if (Size < 2 || Size > 5)
1427 unsigned R0 = RegList.List->front();
1428 unsigned R1 = RegList.List->back();
1429 if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1430 (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1433 int PrevReg = *RegList.List->begin();
1434 for (
int i = 1; i <
Size - 1; i++) {
1435 int Reg = (*(RegList.List))[i];
1436 if (
Reg != PrevReg + 1)
1444 bool isInvNum()
const {
return Kind == k_Immediate; }
1446 bool isLSAImm()
const {
1447 if (!isConstantImm())
1449 int64_t Val = getConstantImm();
1450 return 1 <= Val && Val <= 4;
1453 bool isRegList()
const {
return Kind == k_RegList; }
1456 assert(Kind == k_Token &&
"Invalid access!");
1463 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1464 RegIdx.Kind & RegKind_GPR)
1465 return getGPR32Reg();
1471 const MCExpr *getImm()
const {
1472 assert((Kind == k_Immediate) &&
"Invalid access!");
1476 int64_t getConstantImm()
const {
1477 const MCExpr *Val = getImm();
1479 (void)Val->evaluateAsAbsolute(
Value);
1483 MipsOperand *getMemBase()
const {
1484 assert((Kind == k_Memory) &&
"Invalid access!");
1488 const MCExpr *getMemOff()
const {
1489 assert((Kind == k_Memory) &&
"Invalid access!");
1493 int64_t getConstantMemOff()
const {
1494 return static_cast<const MCConstantExpr *
>(getMemOff())->getValue();
1498 assert((Kind == k_RegList) &&
"Invalid access!");
1499 return *(RegList.List);
1502 static std::unique_ptr<MipsOperand> CreateToken(
StringRef Str,
SMLoc S,
1503 MipsAsmParser &Parser) {
1504 auto Op = std::make_unique<MipsOperand>(k_Token, Parser);
1505 Op->Tok.Data = Str.data();
1506 Op->Tok.Length = Str.size();
1514 static std::unique_ptr<MipsOperand>
1518 return CreateReg(
Index, Str, RegKind_Numeric,
RegInfo, S,
E, Parser);
1523 static std::unique_ptr<MipsOperand>
1526 return CreateReg(
Index, Str, RegKind_GPR,
RegInfo, S,
E, Parser);
1531 static std::unique_ptr<MipsOperand>
1534 return CreateReg(
Index, Str, RegKind_FGR,
RegInfo, S,
E, Parser);
1539 static std::unique_ptr<MipsOperand>
1542 return CreateReg(
Index, Str, RegKind_HWRegs,
RegInfo, S,
E, Parser);
1547 static std::unique_ptr<MipsOperand>
1550 return CreateReg(
Index, Str, RegKind_FCC,
RegInfo, S,
E, Parser);
1555 static std::unique_ptr<MipsOperand>
1558 return CreateReg(
Index, Str, RegKind_ACC,
RegInfo, S,
E, Parser);
1563 static std::unique_ptr<MipsOperand>
1566 return CreateReg(
Index, Str, RegKind_MSA128,
RegInfo, S,
E, Parser);
1571 static std::unique_ptr<MipsOperand>
1574 return CreateReg(
Index, Str, RegKind_MSACtrl,
RegInfo, S,
E, Parser);
1577 static std::unique_ptr<MipsOperand>
1579 auto Op = std::make_unique<MipsOperand>(k_Immediate, Parser);
1586 static std::unique_ptr<MipsOperand>
1587 CreateMem(std::unique_ptr<MipsOperand>
Base,
const MCExpr *Off,
SMLoc S,
1588 SMLoc E, MipsAsmParser &Parser) {
1589 auto Op = std::make_unique<MipsOperand>(k_Memory, Parser);
1590 Op->Mem.Base =
Base.release();
1597 static std::unique_ptr<MipsOperand>
1599 MipsAsmParser &Parser) {
1600 assert(Regs.
size() > 0 &&
"Empty list not allowed");
1602 auto Op = std::make_unique<MipsOperand>(k_RegList, Parser);
1604 Op->StartLoc = StartLoc;
1605 Op->EndLoc = EndLoc;
1609 bool isGPRZeroAsmReg()
const {
1610 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
1613 bool isGPRNonZeroAsmReg()
const {
1614 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index > 0 &&
1618 bool isGPRAsmReg()
const {
1619 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1622 bool isMM16AsmReg()
const {
1623 if (!(isRegIdx() && RegIdx.Kind))
1625 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1626 || RegIdx.Index == 16 || RegIdx.Index == 17);
1629 bool isMM16AsmRegZero()
const {
1630 if (!(isRegIdx() && RegIdx.Kind))
1632 return (RegIdx.Index == 0 ||
1633 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1634 RegIdx.Index == 17);
1637 bool isMM16AsmRegMoveP()
const {
1638 if (!(isRegIdx() && RegIdx.Kind))
1640 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1641 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1644 bool isMM16AsmRegMovePPairFirst()
const {
1645 if (!(isRegIdx() && RegIdx.Kind))
1647 return RegIdx.Index >= 4 && RegIdx.Index <= 6;
1650 bool isMM16AsmRegMovePPairSecond()
const {
1651 if (!(isRegIdx() && RegIdx.Kind))
1653 return (RegIdx.Index == 21 || RegIdx.Index == 22 ||
1654 (RegIdx.Index >= 5 && RegIdx.Index <= 7));
1657 bool isFGRAsmReg()
const {
1659 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1662 bool isStrictlyFGRAsmReg()
const {
1664 return isRegIdx() && RegIdx.Kind == RegKind_FGR && RegIdx.Index <= 31;
1667 bool isHWRegsAsmReg()
const {
1668 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1671 bool isCCRAsmReg()
const {
1672 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1675 bool isFCCAsmReg()
const {
1676 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1678 return RegIdx.Index <= 7;
1681 bool isACCAsmReg()
const {
1682 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1685 bool isCOP0AsmReg()
const {
1686 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1689 bool isCOP2AsmReg()
const {
1690 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1693 bool isCOP3AsmReg()
const {
1694 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1697 bool isMSA128AsmReg()
const {
1698 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1701 bool isMSACtrlAsmReg()
const {
1702 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1706 SMLoc getStartLoc()
const override {
return StartLoc; }
1708 SMLoc getEndLoc()
const override {
return EndLoc; }
1719 Mem.Base->print(
OS);
1724 case k_RegisterIndex:
1725 OS <<
"RegIdx<" << RegIdx.Index <<
":" << RegIdx.Kind <<
", "
1726 <<
StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) <<
">";
1733 for (
auto Reg : (*RegList.List))
1740 bool isValidForTie(
const MipsOperand &
Other)
const {
1741 if (Kind !=
Other.Kind)
1748 case k_RegisterIndex: {
1749 StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length);
1751 return Token == OtherToken;
1767 case Mips::JRC16_MM:
1769 case Mips::JALRS_MM:
1770 case Mips::JALRS16_MM:
1771 case Mips::BGEZALS_MM:
1772 case Mips::BLTZALS_MM:
1782 if (
const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1783 return &SRExpr->getSymbol();
1786 if (
const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1799 if (
const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1806 if (isa<MCSymbolRefExpr>(Expr))
1809 if (
const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1813 if (
const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1832 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1841 if (NumOp != 3 && NumOp != 4)
1853 return !isInt<9>(
Op.getImm());
1855 return !isInt<16>(
Op.getImm());
1871bool MipsAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
1875 const unsigned Opcode = Inst.
getOpcode();
1877 bool ExpandedJalSym =
false;
1891 assert(hasCnMips() &&
"instruction only valid for octeon cpus");
1902 if (!
isIntN(inMicroMipsMode() ? 17 : 18,
Offset.getImm()))
1903 return Error(IDLoc,
"branch target out of range");
1906 return Error(IDLoc,
"branch to misaligned address");
1920 case Mips::BGEZAL_MM:
1921 case Mips::BLTZAL_MM:
1924 case Mips::BC1EQZC_MMR6:
1925 case Mips::BC1NEZC_MMR6:
1926 case Mips::BC2EQZC_MMR6:
1927 case Mips::BC2NEZC_MMR6:
1932 if (!
isIntN(inMicroMipsMode() ? 17 : 18,
Offset.getImm()))
1933 return Error(IDLoc,
"branch target out of range");
1936 return Error(IDLoc,
"branch to misaligned address");
1938 case Mips::BGEC:
case Mips::BGEC_MMR6:
1939 case Mips::BLTC:
case Mips::BLTC_MMR6:
1940 case Mips::BGEUC:
case Mips::BGEUC_MMR6:
1941 case Mips::BLTUC:
case Mips::BLTUC_MMR6:
1942 case Mips::BEQC:
case Mips::BEQC_MMR6:
1943 case Mips::BNEC:
case Mips::BNEC_MMR6:
1949 return Error(IDLoc,
"branch target out of range");
1951 return Error(IDLoc,
"branch to misaligned address");
1953 case Mips::BLEZC:
case Mips::BLEZC_MMR6:
1954 case Mips::BGEZC:
case Mips::BGEZC_MMR6:
1955 case Mips::BGTZC:
case Mips::BGTZC_MMR6:
1956 case Mips::BLTZC:
case Mips::BLTZC_MMR6:
1962 return Error(IDLoc,
"branch target out of range");
1964 return Error(IDLoc,
"branch to misaligned address");
1966 case Mips::BEQZC:
case Mips::BEQZC_MMR6:
1967 case Mips::BNEZC:
case Mips::BNEZC_MMR6:
1973 return Error(IDLoc,
"branch target out of range");
1975 return Error(IDLoc,
"branch to misaligned address");
1977 case Mips::BEQZ16_MM:
1978 case Mips::BEQZC16_MMR6:
1979 case Mips::BNEZ16_MM:
1980 case Mips::BNEZC16_MMR6:
1985 if (!isInt<8>(
Offset.getImm()))
1986 return Error(IDLoc,
"branch target out of range");
1988 return Error(IDLoc,
"branch to misaligned address");
1995 if (hasMips32r6() && Opcode == Mips::SSNOP) {
1996 std::string
ISA = hasMips64r6() ?
"MIPS64r6" :
"MIPS32r6";
1997 Warning(IDLoc,
"ssnop is deprecated for " + ISA +
" and is equivalent to a "
2017 return Error(IDLoc,
"expected immediate operand kind");
2019 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
2020 Opcode == Mips::BBIT1 ? 63 : 31))
2021 return Error(IDLoc,
"immediate operand value out of range");
2023 Inst.
setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
2034 return Error(IDLoc,
"expected immediate operand kind");
2036 if (!isInt<10>(Imm))
2037 return Error(IDLoc,
"immediate operand value out of range");
2049 unsigned FirstOp = 1;
2050 unsigned SecondOp = 2;
2054 case Mips::SDivIMacro:
2055 case Mips::UDivIMacro:
2056 case Mips::DSDivIMacro:
2057 case Mips::DUDivIMacro:
2061 Warning(IDLoc,
"dividing zero by zero");
2063 Warning(IDLoc,
"division by zero");
2075 case Mips::SDivMacro:
2076 case Mips::DSDivMacro:
2077 case Mips::UDivMacro:
2078 case Mips::DUDivMacro:
2083 case Mips::DIVU_MMR6:
2084 case Mips::DIV_MMR6:
2089 Warning(IDLoc,
"dividing zero by zero");
2091 Warning(IDLoc,
"division by zero");
2097 if ((Opcode == Mips::J || Opcode == Mips::J_MM) && inPicMode()) {
2099 BInst.
setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
2108 if ((Opcode == Mips::JAL || Opcode == Mips::JAL_MM) && inPicMode()) {
2109 warnIfNoMacro(IDLoc);
2112 return Error(IDLoc,
"unsupported constant in relocation");
2120 return Error(IDLoc,
"jal doesn't support multiple symbols in PIC mode");
2126 if (expandLoadAddress(Mips::T9, Mips::NoRegister, Inst.
getOperand(0),
2127 !isGP64bit(), IDLoc, Out, STI))
2131 if (inMicroMipsMode())
2132 JalrInst.
setOpcode(IsCpRestoreSet ? Mips::JALRS_MM : Mips::JALR_MM);
2138 if (isJalrRelocAvailable(JalExpr)) {
2142 MCSymbol *TmpLabel = getContext().createTempSymbol();
2144 const MCExpr *RelocJalrExpr =
2146 getContext(), IDLoc);
2149 *TmpExpr, inMicroMipsMode() ?
"R_MICROMIPS_JALR" :
"R_MIPS_JALR",
2150 RelocJalrExpr, IDLoc, *STI);
2155 ExpandedJalSym =
true;
2164 expandMem9Inst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2167 expandMem16Inst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2170 return getParser().hasPendingError();
2174 if (inMicroMipsMode()) {
2175 if (MCID.
mayLoad() && Opcode != Mips::LWP_MM) {
2183 int MemOffset =
Op.getImm();
2186 if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
2189 (BaseReg.
getReg() == Mips::GP ||
2190 BaseReg.
getReg() == Mips::GP_64)) {
2192 TOut.
emitRRI(Mips::LWGP_MM, DstReg.
getReg(), Mips::GP, MemOffset,
2209 case Mips::ADDIUSP_MM:
2212 return Error(IDLoc,
"expected immediate operand kind");
2214 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
2216 return Error(IDLoc,
"immediate operand value out of range");
2218 case Mips::SLL16_MM:
2219 case Mips::SRL16_MM:
2222 return Error(IDLoc,
"expected immediate operand kind");
2224 if (Imm < 1 || Imm > 8)
2225 return Error(IDLoc,
"immediate operand value out of range");
2230 return Error(IDLoc,
"expected immediate operand kind");
2232 if (Imm < -1 || Imm > 126)
2233 return Error(IDLoc,
"immediate operand value out of range");
2235 case Mips::ADDIUR2_MM:
2238 return Error(IDLoc,
"expected immediate operand kind");
2240 if (!(Imm == 1 || Imm == -1 ||
2241 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
2242 return Error(IDLoc,
"immediate operand value out of range");
2244 case Mips::ANDI16_MM:
2247 return Error(IDLoc,
"expected immediate operand kind");
2249 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
2250 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
2251 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
2252 return Error(IDLoc,
"immediate operand value out of range");
2254 case Mips::LBU16_MM:
2257 return Error(IDLoc,
"expected immediate operand kind");
2259 if (Imm < -1 || Imm > 14)
2260 return Error(IDLoc,
"immediate operand value out of range");
2263 case Mips::SB16_MMR6:
2266 return Error(IDLoc,
"expected immediate operand kind");
2268 if (Imm < 0 || Imm > 15)
2269 return Error(IDLoc,
"immediate operand value out of range");
2271 case Mips::LHU16_MM:
2273 case Mips::SH16_MMR6:
2276 return Error(IDLoc,
"expected immediate operand kind");
2278 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
2279 return Error(IDLoc,
"immediate operand value out of range");
2283 case Mips::SW16_MMR6:
2286 return Error(IDLoc,
"expected immediate operand kind");
2288 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
2289 return Error(IDLoc,
"immediate operand value out of range");
2291 case Mips::ADDIUPC_MM:
2294 return Error(IDLoc,
"expected immediate operand kind");
2296 if ((Imm % 4 != 0) || !isInt<25>(Imm))
2297 return Error(IDLoc,
"immediate operand value out of range");
2302 return Error(IDLoc,
"invalid operand for instruction");
2304 case Mips::MOVEP_MM:
2305 case Mips::MOVEP_MMR6: {
2308 bool RegPair = ((R0 == Mips::A1 && R1 == Mips::A2) ||
2309 (R0 == Mips::A1 && R1 == Mips::A3) ||
2310 (R0 == Mips::A2 && R1 == Mips::A3) ||
2311 (R0 == Mips::A0 && R1 == Mips::S5) ||
2312 (R0 == Mips::A0 && R1 == Mips::S6) ||
2313 (R0 == Mips::A0 && R1 == Mips::A1) ||
2314 (R0 == Mips::A0 && R1 == Mips::A2) ||
2315 (R0 == Mips::A0 && R1 == Mips::A3));
2317 return Error(IDLoc,
"invalid operand for instruction");
2323 bool FillDelaySlot =
2328 bool PrevForbiddenSlotAttr = CurForbiddenSlotAttr;
2331 bool SetReorderAfterNop =
false;
2336 if (PrevForbiddenSlotAttr && !SafeInForbiddenSlot(MCID)) {
2346 if (AssemblerOptions.
back()->isReorder() && !FillDelaySlot) {
2347 SetReorderAfterNop =
true;
2356 CurForbiddenSlotAttr =
2357 hasForbiddenSlot(MCID) && AssemblerOptions.
back()->isReorder();
2359 if (FillDelaySlot || CurForbiddenSlotAttr)
2362 MacroExpanderResultTy ExpandResult =
2363 tryExpandInstruction(Inst, IDLoc, Out, STI);
2364 switch (ExpandResult) {
2380 if (PrevForbiddenSlotAttr && !SetReorderAfterNop && !FillDelaySlot &&
2381 AssemblerOptions.
back()->isReorder()) {
2387 if (inMicroMipsMode()) {
2402 if (FillDelaySlot) {
2407 if ((Opcode == Mips::JalOneReg || Opcode == Mips::JalTwoReg ||
2409 isPicAndNotNxxAbi()) {
2410 if (IsCpRestoreSet) {
2414 if (!AssemblerOptions.
back()->isReorder())
2421 Warning(IDLoc,
"no .cprestore used in PIC mode");
2427void MipsAsmParser::onEndOfFile() {
2431 if (CurForbiddenSlotAttr) {
2433 if (AssemblerOptions.
back()->isReorder())
2438MipsAsmParser::MacroExpanderResultTy
2443 return MER_NotAMacro;
2444 case Mips::LoadImm32:
2445 return expandLoadImm(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2446 case Mips::LoadImm64:
2447 return expandLoadImm(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2448 case Mips::LoadAddrImm32:
2449 case Mips::LoadAddrImm64:
2452 "expected immediate operand kind");
2456 Inst.
getOpcode() == Mips::LoadAddrImm32, IDLoc,
2460 case Mips::LoadAddrReg32:
2461 case Mips::LoadAddrReg64:
2465 "expected immediate operand kind");
2469 Inst.
getOpcode() == Mips::LoadAddrReg32, IDLoc,
2473 case Mips::B_MM_Pseudo:
2474 case Mips::B_MMR6_Pseudo:
2475 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2479 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2481 case Mips::JalOneReg:
2482 case Mips::JalTwoReg:
2483 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2486 case Mips::BEQLImmMacro:
2487 case Mips::BNELImmMacro:
2488 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2505 case Mips::BLTImmMacro:
2506 case Mips::BLEImmMacro:
2507 case Mips::BGEImmMacro:
2508 case Mips::BGTImmMacro:
2509 case Mips::BLTUImmMacro:
2510 case Mips::BLEUImmMacro:
2511 case Mips::BGEUImmMacro:
2512 case Mips::BGTUImmMacro:
2513 case Mips::BLTLImmMacro:
2514 case Mips::BLELImmMacro:
2515 case Mips::BGELImmMacro:
2516 case Mips::BGTLImmMacro:
2517 case Mips::BLTULImmMacro:
2518 case Mips::BLEULImmMacro:
2519 case Mips::BGEULImmMacro:
2520 case Mips::BGTULImmMacro:
2521 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2522 case Mips::SDivMacro:
2523 case Mips::SDivIMacro:
2524 case Mips::SRemMacro:
2525 case Mips::SRemIMacro:
2526 return expandDivRem(Inst, IDLoc, Out, STI,
false,
true) ? MER_Fail
2528 case Mips::DSDivMacro:
2529 case Mips::DSDivIMacro:
2530 case Mips::DSRemMacro:
2531 case Mips::DSRemIMacro:
2532 return expandDivRem(Inst, IDLoc, Out, STI,
true,
true) ? MER_Fail
2534 case Mips::UDivMacro:
2535 case Mips::UDivIMacro:
2536 case Mips::URemMacro:
2537 case Mips::URemIMacro:
2538 return expandDivRem(Inst, IDLoc, Out, STI,
false,
false) ? MER_Fail
2540 case Mips::DUDivMacro:
2541 case Mips::DUDivIMacro:
2542 case Mips::DURemMacro:
2543 case Mips::DURemIMacro:
2544 return expandDivRem(Inst, IDLoc, Out, STI,
true,
false) ? MER_Fail
2546 case Mips::PseudoTRUNC_W_S:
2547 return expandTrunc(Inst,
false,
false, IDLoc, Out, STI) ? MER_Fail
2549 case Mips::PseudoTRUNC_W_D32:
2550 return expandTrunc(Inst,
true,
false, IDLoc, Out, STI) ? MER_Fail
2552 case Mips::PseudoTRUNC_W_D:
2553 return expandTrunc(Inst,
true,
true, IDLoc, Out, STI) ? MER_Fail
2556 case Mips::LoadImmSingleGPR:
2557 return expandLoadSingleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2559 case Mips::LoadImmSingleFGR:
2560 return expandLoadSingleImmToFPR(Inst, IDLoc, Out, STI) ? MER_Fail
2562 case Mips::LoadImmDoubleGPR:
2563 return expandLoadDoubleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2565 case Mips::LoadImmDoubleFGR:
2566 return expandLoadDoubleImmToFPR(Inst,
true, IDLoc, Out, STI) ? MER_Fail
2568 case Mips::LoadImmDoubleFGR_32:
2569 return expandLoadDoubleImmToFPR(Inst,
false, IDLoc, Out, STI) ? MER_Fail
2573 return expandUlh(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2575 return expandUlh(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2577 return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2580 return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2582 case Mips::NORImm64:
2583 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2586 return expandSge(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2589 case Mips::SGEImm64:
2590 case Mips::SGEUImm64:
2591 return expandSgeImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2594 case Mips::SGTImm64:
2595 case Mips::SGTUImm64:
2596 return expandSgtImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2599 return expandSle(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2602 case Mips::SLEImm64:
2603 case Mips::SLEUImm64:
2604 return expandSleImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2605 case Mips::SLTImm64:
2608 return MER_NotAMacro;
2610 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2611 case Mips::SLTUImm64:
2614 return MER_NotAMacro;
2616 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2617 case Mips::ADDi:
case Mips::ADDi_MM:
2618 case Mips::ADDiu:
case Mips::ADDiu_MM:
2619 case Mips::SLTi:
case Mips::SLTi_MM:
2620 case Mips::SLTiu:
case Mips::SLTiu_MM:
2624 if (isInt<16>(ImmValue))
2625 return MER_NotAMacro;
2626 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2629 return MER_NotAMacro;
2630 case Mips::ANDi:
case Mips::ANDi_MM:
case Mips::ANDi64:
2631 case Mips::ORi:
case Mips::ORi_MM:
case Mips::ORi64:
2632 case Mips::XORi:
case Mips::XORi_MM:
case Mips::XORi64:
2636 if (isUInt<16>(ImmValue))
2637 return MER_NotAMacro;
2638 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2641 return MER_NotAMacro;
2644 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2647 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2650 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2653 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2654 case Mips::ABSMacro:
2655 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2656 case Mips::MULImmMacro:
2657 case Mips::DMULImmMacro:
2658 return expandMulImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2659 case Mips::MULOMacro:
2660 case Mips::DMULOMacro:
2661 return expandMulO(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2662 case Mips::MULOUMacro:
2663 case Mips::DMULOUMacro:
2664 return expandMulOU(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2665 case Mips::DMULMacro:
2666 return expandDMULMacro(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2669 return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2674 return expandStoreDM1Macro(Inst, IDLoc, Out, STI)
2677 case Mips::SEQMacro:
2678 return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2679 case Mips::SEQIMacro:
2680 return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2681 case Mips::SNEMacro:
2682 return expandSne(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2683 case Mips::SNEIMacro:
2684 return expandSneI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2685 case Mips::MFTC0:
case Mips::MTTC0:
2686 case Mips::MFTGPR:
case Mips::MTTGPR:
2687 case Mips::MFTLO:
case Mips::MTTLO:
2688 case Mips::MFTHI:
case Mips::MTTHI:
2689 case Mips::MFTACX:
case Mips::MTTACX:
2690 case Mips::MFTDSP:
case Mips::MTTDSP:
2691 case Mips::MFTC1:
case Mips::MTTC1:
2692 case Mips::MFTHC1:
case Mips::MTTHC1:
2693 case Mips::CFTC1:
case Mips::CTTC1:
2694 return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2696 case Mips::SaadAddr:
2697 return expandSaaAddr(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2701bool MipsAsmParser::expandJalWithRegs(
MCInst &Inst,
SMLoc IDLoc,
2710 const unsigned Opcode = Inst.
getOpcode();
2712 if (Opcode == Mips::JalOneReg) {
2714 if (IsCpRestoreSet && inMicroMipsMode()) {
2717 }
else if (inMicroMipsMode()) {
2718 JalrInst.
setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2725 }
else if (Opcode == Mips::JalTwoReg) {
2727 if (IsCpRestoreSet && inMicroMipsMode())
2730 JalrInst.
setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2762bool MipsAsmParser::loadImmediate(int64_t ImmValue,
unsigned DstReg,
2763 unsigned SrcReg,
bool Is32BitImm,
2768 if (!Is32BitImm && !isGP64bit()) {
2769 Error(IDLoc,
"instruction requires a 64-bit architecture");
2774 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2778 ImmValue = SignExtend64<32>(ImmValue);
2780 Error(IDLoc,
"instruction requires a 32-bit immediate");
2785 unsigned ZeroReg = IsAddress ?
ABI.GetNullPtr() :
ABI.GetZeroReg();
2786 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2788 bool UseSrcReg =
false;
2789 if (SrcReg != Mips::NoRegister)
2792 unsigned TmpReg = DstReg;
2794 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2797 unsigned ATReg = getATReg(IDLoc);
2803 if (isInt<16>(ImmValue)) {
2810 if (IsAddress && !Is32BitImm) {
2811 TOut.
emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2815 TOut.
emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2819 if (isUInt<16>(ImmValue)) {
2820 unsigned TmpReg = DstReg;
2821 if (SrcReg == DstReg) {
2822 TmpReg = getATReg(IDLoc);
2827 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2829 TOut.
emitRRR(
ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2833 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2834 warnIfNoMacro(IDLoc);
2836 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2837 uint16_t Bits15To0 = ImmValue & 0xffff;
2838 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2841 if (ImmValue == 0xffffffff) {
2842 TOut.
emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2843 TOut.
emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2845 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2851 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2852 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2854 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2856 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2860 TOut.
emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2862 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2864 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2868 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2870 Error(IDLoc,
"instruction requires a 32-bit immediate");
2877 assert(
BitWidth >= 17 &&
"ImmValue must be at least 17-bit wide");
2881 unsigned ShiftAmount =
BitWidth - 16;
2883 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2884 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2887 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2892 warnIfNoMacro(IDLoc);
2899 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister,
true,
false,
2905 unsigned ShiftCarriedForwards = 16;
2906 for (
int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2907 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2909 if (ImmChunk != 0) {
2910 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2911 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2912 ShiftCarriedForwards = 0;
2915 ShiftCarriedForwards += 16;
2917 ShiftCarriedForwards -= 16;
2920 if (ShiftCarriedForwards)
2921 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2924 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2929bool MipsAsmParser::expandLoadImm(
MCInst &Inst,
bool Is32BitImm,
SMLoc IDLoc,
2932 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
2934 assert(DstRegOp.
isReg() &&
"expected register operand kind");
2936 if (loadImmediate(ImmOp.
getImm(), DstRegOp.
getReg(), Mips::NoRegister,
2937 Is32BitImm,
false, IDLoc, Out, STI))
2943bool MipsAsmParser::expandLoadAddress(
unsigned DstReg,
unsigned BaseReg,
2945 bool Is32BitAddress,
SMLoc IDLoc,
2949 if (Is32BitAddress &&
ABI.ArePtrs64bit()) {
2950 Warning(IDLoc,
"la used to load 64-bit address");
2952 Is32BitAddress =
false;
2956 if (!Is32BitAddress && !hasMips3()) {
2957 Error(IDLoc,
"instruction requires a 64-bit architecture");
2962 return loadAndAddSymbolAddress(
Offset.getExpr(), DstReg, BaseReg,
2963 Is32BitAddress, IDLoc, Out, STI);
2965 if (!
ABI.ArePtrs64bit()) {
2967 Is32BitAddress =
true;
2970 return loadImmediate(
Offset.getImm(), DstReg, BaseReg, Is32BitAddress,
true,
2974bool MipsAsmParser::loadAndAddSymbolAddress(
const MCExpr *SymExpr,
2975 unsigned DstReg,
unsigned SrcReg,
2976 bool Is32BitSym,
SMLoc IDLoc,
2980 bool UseSrcReg = SrcReg != Mips::NoRegister && SrcReg != Mips::ZERO &&
2981 SrcReg != Mips::ZERO_64;
2982 warnIfNoMacro(IDLoc);
2987 Error(IDLoc,
"expected relocatable expression");
2990 if (Res.
getSymB() !=
nullptr) {
2991 Error(IDLoc,
"expected relocatable expression with only one symbol");
2995 bool IsPtr64 =
ABI.ArePtrs64bit();
3007 bool UseXGOT = STI->
hasFeature(Mips::FeatureXGOT) && !IsLocalSym;
3013 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
3017 SymExpr, getContext());
3019 SymExpr, getContext());
3022 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, DstReg, GPReg,
3024 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, DstReg,
3029 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, GPReg,
3035 unsigned TmpReg = DstReg;
3037 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
3041 unsigned ATReg = getATReg(IDLoc);
3060 const MCExpr *CallHiExpr =
3067 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg, GPReg,
3069 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, TmpReg,
3073 TOut.
emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3079 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3085 const MCExpr *LoExpr =
nullptr;
3086 if (
ABI.IsN32() ||
ABI.IsN64()) {
3105 Error(IDLoc,
"macro instruction uses large offset, which is not "
3106 "currently supported");
3136 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, GPReg,
3140 TOut.
emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3144 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3156 if (
ABI.ArePtrs64bit() && isGP64bit()) {
3171 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
3173 if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
3174 unsigned ATReg = getATReg(IDLoc);
3186 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3188 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3191 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3194 TOut.
emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
3197 }
else if (canUseATReg() && !RdRegIsRsReg && DstReg != getATReg(IDLoc)) {
3198 unsigned ATReg = getATReg(IDLoc);
3214 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3218 TOut.
emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3219 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3221 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3224 }
else if ((!canUseATReg() && !RdRegIsRsReg) ||
3225 (canUseATReg() && DstReg == getATReg(IDLoc))) {
3236 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3238 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3239 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3241 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3242 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3245 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3251 assert(SrcReg == DstReg && !canUseATReg() &&
3252 "Could have expanded dla but didn't?");
3253 reportParseError(IDLoc,
3254 "pseudo-instruction requires $at, which is not available");
3268 unsigned TmpReg = DstReg;
3270 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
3273 unsigned ATReg = getATReg(IDLoc);
3284 TOut.
emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3287 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
3296 if (MipsMCRegisterClasses[Mips::FGR32RegClassID].
contains(
Reg))
3297 return Reg == (
unsigned)Mips::F31 ? (
unsigned)Mips::F0 :
Reg + 1;
3299 default:
llvm_unreachable(
"Unknown register in assembly macro expansion!");
3300 case Mips::ZERO:
return Mips::AT;
3301 case Mips::AT:
return Mips::V0;
3302 case Mips::V0:
return Mips::V1;
3303 case Mips::V1:
return Mips::A0;
3304 case Mips::A0:
return Mips::A1;
3305 case Mips::A1:
return Mips::A2;
3306 case Mips::A2:
return Mips::A3;
3307 case Mips::A3:
return Mips::T0;
3308 case Mips::T0:
return Mips::T1;
3309 case Mips::T1:
return Mips::T2;
3310 case Mips::T2:
return Mips::T3;
3311 case Mips::T3:
return Mips::T4;
3312 case Mips::T4:
return Mips::T5;
3313 case Mips::T5:
return Mips::T6;
3314 case Mips::T6:
return Mips::T7;
3315 case Mips::T7:
return Mips::S0;
3316 case Mips::S0:
return Mips::S1;
3317 case Mips::S1:
return Mips::S2;
3318 case Mips::S2:
return Mips::S3;
3319 case Mips::S3:
return Mips::S4;
3320 case Mips::S4:
return Mips::S5;
3321 case Mips::S5:
return Mips::S6;
3322 case Mips::S6:
return Mips::S7;
3323 case Mips::S7:
return Mips::T8;
3324 case Mips::T8:
return Mips::T9;
3325 case Mips::T9:
return Mips::K0;
3326 case Mips::K0:
return Mips::K1;
3327 case Mips::K1:
return Mips::GP;
3328 case Mips::GP:
return Mips::SP;
3329 case Mips::SP:
return Mips::FP;
3330 case Mips::FP:
return Mips::RA;
3331 case Mips::RA:
return Mips::ZERO;
3332 case Mips::D0:
return Mips::F1;
3333 case Mips::D1:
return Mips::F3;
3334 case Mips::D2:
return Mips::F5;
3335 case Mips::D3:
return Mips::F7;
3336 case Mips::D4:
return Mips::F9;
3337 case Mips::D5:
return Mips::F11;
3338 case Mips::D6:
return Mips::F13;
3339 case Mips::D7:
return Mips::F15;
3340 case Mips::D8:
return Mips::F17;
3341 case Mips::D9:
return Mips::F19;
3342 case Mips::D10:
return Mips::F21;
3343 case Mips::D11:
return Mips::F23;
3344 case Mips::D12:
return Mips::F25;
3345 case Mips::D13:
return Mips::F27;
3346 case Mips::D14:
return Mips::F29;
3347 case Mips::D15:
return Mips::F31;
3359 unsigned ATReg = getATReg(IDLoc);
3369 if(isABI_O32() || isABI_N32()) {
3388 if(isABI_O32() || isABI_N32()) {
3391 const MCExpr *HighestSym =
3395 const MCExpr *HigherSym =
3402 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3404 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3407 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3416 if ((
Hi_32(ImmOp64) & 0x7ff00000) == 0) {
3417 APFloat RealVal(APFloat::IEEEdouble(), ImmOp64);
3426 double DoubleImm = llvm::bit_cast<double>(ImmOp64);
3427 float TmpFloat =
static_cast<float>(DoubleImm);
3428 return llvm::bit_cast<uint32_t>(TmpFloat);
3431bool MipsAsmParser::expandLoadSingleImmToGPR(
MCInst &Inst,
SMLoc IDLoc,
3436 "Invalid instruction operand.");
3443 return loadImmediate(ImmOp32, FirstReg, Mips::NoRegister,
true,
false, IDLoc,
3447bool MipsAsmParser::expandLoadSingleImmToFPR(
MCInst &Inst,
SMLoc IDLoc,
3453 "Invalid instruction operand.");
3462 unsigned TmpReg = Mips::ZERO;
3464 TmpReg = getATReg(IDLoc);
3469 if (
Lo_32(ImmOp64) == 0) {
3470 if (TmpReg != Mips::ZERO && loadImmediate(ImmOp32, TmpReg, Mips::NoRegister,
3471 true,
false, IDLoc, Out, STI))
3473 TOut.
emitRR(Mips::MTC1, FirstReg, TmpReg, IDLoc, STI);
3477 MCSection *CS = getStreamer().getCurrentSectionOnly();
3489 getStreamer().switchSection(ReadOnlySection);
3490 getStreamer().emitLabel(
Sym, IDLoc);
3491 getStreamer().emitInt32(ImmOp32);
3492 getStreamer().switchSection(CS);
3494 if (emitPartialAddress(TOut, IDLoc,
Sym))
3501bool MipsAsmParser::expandLoadDoubleImmToGPR(
MCInst &Inst,
SMLoc IDLoc,
3507 "Invalid instruction operand.");
3514 if (
Lo_32(ImmOp64) == 0) {
3516 if (loadImmediate(ImmOp64, FirstReg, Mips::NoRegister,
false,
false,
3520 if (loadImmediate(
Hi_32(ImmOp64), FirstReg, Mips::NoRegister,
true,
false,
3524 if (loadImmediate(0,
nextReg(FirstReg), Mips::NoRegister,
true,
false,
3531 MCSection *CS = getStreamer().getCurrentSectionOnly();
3541 getStreamer().switchSection(ReadOnlySection);
3542 getStreamer().emitLabel(
Sym, IDLoc);
3543 getStreamer().emitValueToAlignment(
Align(8));
3544 getStreamer().emitIntValue(ImmOp64, 8);
3545 getStreamer().switchSection(CS);
3547 unsigned TmpReg = getATReg(IDLoc);
3551 if (emitPartialAddress(TOut, IDLoc,
Sym))
3554 TOut.
emitRRX(isABI_N64() ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3558 TOut.
emitRRI(Mips::LD, FirstReg, TmpReg, 0, IDLoc, STI);
3560 TOut.
emitRRI(Mips::LW, FirstReg, TmpReg, 0, IDLoc, STI);
3561 TOut.
emitRRI(Mips::LW,
nextReg(FirstReg), TmpReg, 4, IDLoc, STI);
3566bool MipsAsmParser::expandLoadDoubleImmToFPR(
MCInst &Inst,
bool Is64FPU,
3572 "Invalid instruction operand.");
3579 unsigned TmpReg = Mips::ZERO;
3581 TmpReg = getATReg(IDLoc);
3586 if ((
Lo_32(ImmOp64) == 0) &&
3587 !((
Hi_32(ImmOp64) & 0xffff0000) && (
Hi_32(ImmOp64) & 0x0000ffff))) {
3589 if (TmpReg != Mips::ZERO &&
3590 loadImmediate(ImmOp64, TmpReg, Mips::NoRegister,
false,
false, IDLoc,
3593 TOut.
emitRR(Mips::DMTC1, FirstReg, TmpReg, IDLoc, STI);
3597 if (TmpReg != Mips::ZERO &&
3598 loadImmediate(
Hi_32(ImmOp64), TmpReg, Mips::NoRegister,
true,
false,
3602 if (hasMips32r2()) {
3603 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3604 TOut.
emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, TmpReg, IDLoc, STI);
3606 TOut.
emitRR(Mips::MTC1,
nextReg(FirstReg), TmpReg, IDLoc, STI);
3607 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3612 MCSection *CS = getStreamer().getCurrentSectionOnly();
3624 getStreamer().switchSection(ReadOnlySection);
3625 getStreamer().emitLabel(
Sym, IDLoc);
3626 getStreamer().emitValueToAlignment(
Align(8));
3627 getStreamer().emitIntValue(ImmOp64, 8);
3628 getStreamer().switchSection(CS);
3630 if (emitPartialAddress(TOut, IDLoc,
Sym))
3633 TOut.
emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, TmpReg,
3639bool MipsAsmParser::expandUncondBranchMMPseudo(
MCInst &Inst,
SMLoc IDLoc,
3645 "unexpected number of operands");
3655 assert(
Offset.isImm() &&
"expected immediate operand kind");
3656 if (isInt<11>(
Offset.getImm())) {
3659 if (inMicroMipsMode())
3660 Inst.
setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3662 if (!isInt<17>(
Offset.getImm()))
3663 return Error(IDLoc,
"branch target out of range");
3665 return Error(IDLoc,
"branch to misaligned address");
3688 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3691 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
3695 "expected immediate or expression operand");
3697 bool IsLikely =
false;
3707 case Mips::BEQLImmMacro:
3711 case Mips::BNELImmMacro:
3720 int64_t ImmValue = ImmOp.
getImm();
3721 if (ImmValue == 0) {
3725 TOut.
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3727 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3730 warnIfNoMacro(IDLoc);
3732 unsigned ATReg = getATReg(IDLoc);
3736 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(),
true,
3743 TOut.
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3745 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3753 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3754 unsigned StartOp = NumOp == 3 ? 0 : 1;
3757 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3759 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3764 unsigned DstReg = DstRegOp.
getReg();
3765 unsigned BaseReg = BaseRegOp.
getReg();
3766 unsigned TmpReg = DstReg;
3769 int16_t DstRegClass =
Desc.operands()[StartOp].RegClass;
3770 unsigned DstRegClassID =
3771 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3772 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3773 (DstRegClassID == Mips::GPR64RegClassID);
3775 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3778 TmpReg = getATReg(IDLoc);
3785 TOut.
emitRRX(OpCode, DstReg, TmpReg, Off, IDLoc, STI);
3787 TOut.
emitRRRX(OpCode, DstReg, DstReg, TmpReg, Off, IDLoc, STI);
3790 if (OffsetOp.
isImm()) {
3791 int64_t LoOffset = OffsetOp.
getImm() & 0xffff;
3792 int64_t HiOffset = OffsetOp.
getImm() & ~0xffff;
3796 if (LoOffset & 0x8000)
3797 HiOffset += 0x10000;
3799 bool IsLargeOffset = HiOffset != 0;
3801 if (IsLargeOffset) {
3802 bool Is32BitImm = isInt<32>(OffsetOp.
getImm());
3803 if (loadImmediate(HiOffset, TmpReg, Mips::NoRegister, Is32BitImm,
true,
3808 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3809 TOut.
emitRRR(
ABI.ArePtrs64bit() ? Mips::DADDu : Mips::ADDu, TmpReg,
3810 TmpReg, BaseReg, IDLoc, STI);
3825 Error(IDLoc,
"expected relocatable expression");
3828 if (Res.
getSymB() !=
nullptr) {
3829 Error(IDLoc,
"expected relocatable expression with only one symbol");
3833 loadAndAddSymbolAddress(Res.
getSymA(), TmpReg, BaseReg,
3834 !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3854 TOut.
emitRX(Mips::LUi, TmpReg, HighestOperand, IDLoc, STI);
3855 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HigherOperand, IDLoc, STI);
3856 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3857 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HiOperand, IDLoc, STI);
3858 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3859 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3860 TOut.
emitRRR(Mips::DADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3861 emitInstWithOffset(LoOperand);
3864 TOut.
emitRX(Mips::LUi, TmpReg, HiOperand, IDLoc, STI);
3865 if (BaseReg != Mips::ZERO)
3866 TOut.
emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3868 emitInstWithOffset(LoOperand);
3880 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3881 unsigned StartOp = NumOp == 3 ? 0 : 1;
3884 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3886 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3891 unsigned DstReg = DstRegOp.
getReg();
3892 unsigned BaseReg = BaseRegOp.
getReg();
3893 unsigned TmpReg = DstReg;
3896 int16_t DstRegClass =
Desc.operands()[StartOp].RegClass;
3897 unsigned DstRegClassID =
3898 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3899 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3900 (DstRegClassID == Mips::GPR64RegClassID);
3902 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3905 TmpReg = getATReg(IDLoc);
3910 auto emitInst = [&]() {
3918 if (OffsetOp.
isImm()) {
3919 loadImmediate(OffsetOp.
getImm(), TmpReg, BaseReg, !
ABI.ArePtrs64bit(),
true,
3926 loadAndAddSymbolAddress(OffsetOp.
getExpr(), TmpReg, BaseReg,
3927 !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3935bool MipsAsmParser::expandLoadStoreMultiple(
MCInst &Inst,
SMLoc IDLoc,
3940 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3944 Inst.
getOperand(OpNum - 3).
isReg() &&
"Invalid instruction operand.");
3953 if (inMicroMipsMode() && hasMips32r6())
3954 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3956 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3964bool MipsAsmParser::expandCondBranches(
MCInst &Inst,
SMLoc IDLoc,
3968 bool EmittedNoMacroWarning =
false;
3969 unsigned PseudoOpcode = Inst.
getOpcode();
3974 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3975 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3980 else if (TrgOp.
isImm()) {
3981 warnIfNoMacro(IDLoc);
3982 EmittedNoMacroWarning =
true;
3984 TrgReg = getATReg(IDLoc);
3988 switch(PseudoOpcode) {
3991 case Mips::BLTImmMacro:
3992 PseudoOpcode = Mips::BLT;
3994 case Mips::BLEImmMacro:
3995 PseudoOpcode = Mips::BLE;
3997 case Mips::BGEImmMacro:
3998 PseudoOpcode = Mips::BGE;
4000 case Mips::BGTImmMacro:
4001 PseudoOpcode = Mips::BGT;
4003 case Mips::BLTUImmMacro:
4004 PseudoOpcode = Mips::BLTU;
4006 case Mips::BLEUImmMacro:
4007 PseudoOpcode = Mips::BLEU;
4009 case Mips::BGEUImmMacro:
4010 PseudoOpcode = Mips::BGEU;
4012 case Mips::BGTUImmMacro:
4013 PseudoOpcode = Mips::BGTU;
4015 case Mips::BLTLImmMacro:
4016 PseudoOpcode = Mips::BLTL;
4018 case Mips::BLELImmMacro:
4019 PseudoOpcode = Mips::BLEL;
4021 case Mips::BGELImmMacro:
4022 PseudoOpcode = Mips::BGEL;
4024 case Mips::BGTLImmMacro:
4025 PseudoOpcode = Mips::BGTL;
4027 case Mips::BLTULImmMacro:
4028 PseudoOpcode = Mips::BLTUL;
4030 case Mips::BLEULImmMacro:
4031 PseudoOpcode = Mips::BLEUL;
4033 case Mips::BGEULImmMacro:
4034 PseudoOpcode = Mips::BGEUL;
4036 case Mips::BGTULImmMacro:
4037 PseudoOpcode = Mips::BGTUL;
4041 if (loadImmediate(TrgOp.
getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
4042 false, IDLoc, Out, STI))
4046 switch (PseudoOpcode) {
4051 AcceptsEquality =
false;
4052 ReverseOrderSLT =
false;
4054 ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
4055 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
4056 ZeroSrcOpcode = Mips::BGTZ;
4057 ZeroTrgOpcode = Mips::BLTZ;
4063 AcceptsEquality =
true;
4064 ReverseOrderSLT =
true;
4066 ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
4067 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
4068 ZeroSrcOpcode = Mips::BGEZ;
4069 ZeroTrgOpcode = Mips::BLEZ;
4075 AcceptsEquality =
true;
4076 ReverseOrderSLT =
false;
4078 ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
4079 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
4080 ZeroSrcOpcode = Mips::BLEZ;
4081 ZeroTrgOpcode = Mips::BGEZ;
4087 AcceptsEquality =
false;
4088 ReverseOrderSLT =
true;
4090 ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
4091 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
4092 ZeroSrcOpcode = Mips::BLTZ;
4093 ZeroTrgOpcode = Mips::BGTZ;
4099 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
4100 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
4101 if (IsSrcRegZero && IsTrgRegZero) {
4105 if (PseudoOpcode == Mips::BLT) {
4110 if (PseudoOpcode == Mips::BLE) {
4113 Warning(IDLoc,
"branch is always taken");
4116 if (PseudoOpcode == Mips::BGE) {
4119 Warning(IDLoc,
"branch is always taken");
4122 if (PseudoOpcode == Mips::BGT) {
4127 if (PseudoOpcode == Mips::BGTU) {
4128 TOut.
emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
4132 if (AcceptsEquality) {
4135 TOut.
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4137 Warning(IDLoc,
"branch is always taken");
4144 if (IsSrcRegZero || IsTrgRegZero) {
4145 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
4146 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
4153 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
4154 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
4160 TOut.
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4162 Warning(IDLoc,
"branch is always taken");
4178 TOut.
emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
4179 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
4186 TOut.
emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
4187 IsSrcRegZero ? TrgReg : SrcReg,
4194 unsigned ATRegNum = getATReg(IDLoc);
4198 if (!EmittedNoMacroWarning)
4199 warnIfNoMacro(IDLoc);
4216 TOut.
emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
4217 ReverseOrderSLT ? TrgReg : SrcReg,
4218 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
4220 TOut.
emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
4221 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
4237 const bool IsMips64,
const bool Signed) {
4240 warnIfNoMacro(IDLoc);
4243 assert(RdRegOp.
isReg() &&
"expected register operand kind");
4244 unsigned RdReg = RdRegOp.
getReg();
4247 assert(RsRegOp.
isReg() &&
"expected register operand kind");
4248 unsigned RsReg = RsRegOp.
getReg();
4255 "expected register or immediate operand kind");
4259 ImmValue = RtOp.
getImm();
4266 DivOp =
Signed ? Mips::DSDIV : Mips::DUDIV;
4267 ZeroReg = Mips::ZERO_64;
4270 DivOp =
Signed ? Mips::SDIV : Mips::UDIV;
4271 ZeroReg = Mips::ZERO;
4275 bool UseTraps = useTraps();
4278 bool isDiv = Opcode == Mips::SDivMacro || Opcode == Mips::SDivIMacro ||
4279 Opcode == Mips::UDivMacro || Opcode == Mips::UDivIMacro ||
4280 Opcode == Mips::DSDivMacro || Opcode == Mips::DSDivIMacro ||
4281 Opcode == Mips::DUDivMacro || Opcode == Mips::DUDivIMacro;
4283 bool isRem = Opcode == Mips::SRemMacro || Opcode == Mips::SRemIMacro ||
4284 Opcode == Mips::URemMacro || Opcode == Mips::URemIMacro ||
4285 Opcode == Mips::DSRemMacro || Opcode == Mips::DSRemIMacro ||
4286 Opcode == Mips::DURemMacro || Opcode == Mips::DURemIMacro;
4289 unsigned ATReg = getATReg(IDLoc);
4293 if (ImmValue == 0) {
4295 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4297 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4301 if (isRem && (ImmValue == 1 || (
Signed && (ImmValue == -1)))) {
4302 TOut.
emitRRR(Mips::OR, RdReg, ZeroReg, ZeroReg, IDLoc, STI);
4304 }
else if (isDiv && ImmValue == 1) {
4305 TOut.
emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI);
4307 }
else if (isDiv &&
Signed && ImmValue == -1) {
4308 TOut.
emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
4311 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, isInt<32>(ImmValue),
4312 false, Inst.
getLoc(), Out, STI))
4314 TOut.
emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
4315 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4325 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
4327 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4330 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4336 if (isRem && (RdReg == Mips::ZERO || RdReg == Mips::ZERO_64)) {
4337 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4347 TOut.
emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4352 TOut.
emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4355 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4358 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4364 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4368 unsigned ATReg = getATReg(IDLoc);
4375 TOut.
emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
4383 TOut.
emitRRX(Mips::BNE, RtReg, ATReg, LabelOpEnd, IDLoc, STI);
4386 TOut.
emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
4387 TOut.
emitDSLL(ATReg, ATReg, 63, IDLoc, STI);
4393 TOut.
emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
4396 TOut.
emitRRX(Mips::BNE, RsReg, ATReg, LabelOpEnd, IDLoc, STI);
4398 TOut.
emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
4402 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4406bool MipsAsmParser::expandTrunc(
MCInst &Inst,
bool IsDouble,
bool Is64FPU,
4419 if (hasMips1() && !hasMips2()) {
4420 unsigned ATReg = getATReg(IDLoc);
4423 TOut.
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4424 TOut.
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4426 TOut.
emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4427 TOut.
emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4428 TOut.
emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4430 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4432 FirstReg, SecondReg, IDLoc, STI);
4433 TOut.
emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4438 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4440 FirstReg, SecondReg, IDLoc, STI);
4447 if (hasMips32r6() || hasMips64r6()) {
4448 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4452 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4454 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4456 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4459 unsigned DstReg = DstRegOp.
getReg();
4460 unsigned SrcReg = SrcRegOp.
getReg();
4461 int64_t OffsetValue = OffsetImmOp.
getImm();
4465 warnIfNoMacro(IDLoc);
4466 unsigned ATReg = getATReg(IDLoc);
4470 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4471 if (IsLargeOffset) {
4472 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4477 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4478 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4482 unsigned FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4483 unsigned SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4485 unsigned LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4486 unsigned SllReg = IsLargeOffset ? DstReg : ATReg;
4488 TOut.
emitRRI(
Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4489 FirstOffset, IDLoc, STI);
4490 TOut.
emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4491 TOut.
emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4492 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4499 if (hasMips32r6() || hasMips64r6()) {
4500 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4504 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4506 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4508 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4511 unsigned DstReg = DstRegOp.
getReg();
4512 unsigned SrcReg = SrcRegOp.
getReg();
4513 int64_t OffsetValue = OffsetImmOp.
getImm();
4515 warnIfNoMacro(IDLoc);
4516 unsigned ATReg = getATReg(IDLoc);
4520 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4521 if (IsLargeOffset) {
4522 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4527 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4528 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4532 if (IsLargeOffset) {
4533 TOut.
emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4534 TOut.
emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4535 TOut.
emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4536 TOut.
emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4537 TOut.
emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4538 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4540 TOut.
emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4541 TOut.
emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4542 TOut.
emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4550 if (hasMips32r6() || hasMips64r6()) {
4551 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4555 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4557 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4559 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4562 unsigned DstReg = DstRegOp.
getReg();
4563 unsigned SrcReg = SrcRegOp.
getReg();
4564 int64_t OffsetValue = OffsetImmOp.
getImm();
4567 bool IsLargeOffset = !(isInt<16>(OffsetValue + 3) && isInt<16>(OffsetValue));
4568 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4569 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4573 bool IsLoadInst = (Inst.
getOpcode() == Mips::Ulw);
4574 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4575 unsigned TmpReg = SrcReg;
4576 if (IsLargeOffset || DoMove) {
4577 warnIfNoMacro(IDLoc);
4578 TmpReg = getATReg(IDLoc);
4583 if (IsLargeOffset) {
4584 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4592 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4593 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4594 TOut.
emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4595 TOut.
emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4598 TOut.
emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4617 warnIfNoMacro(IDLoc);
4631 TOut.
emitRRR(OpCode, DstReg, SrcReg, OpReg, IDLoc, STI);
4632 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4649 unsigned OpRegCode, OpImmCode;
4651 warnIfNoMacro(IDLoc);
4655 case Mips::SGEImm64:
4656 OpRegCode = Mips::SLT;
4657 OpImmCode = Mips::SLTi;
4660 case Mips::SGEUImm64:
4661 OpRegCode = Mips::SLTu;
4662 OpImmCode = Mips::SLTiu;
4669 if (isInt<16>(ImmValue)) {
4671 TOut.
emitRRI(OpImmCode, DstReg, SrcReg, ImmValue, IDLoc, STI);
4672 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4674 unsigned ImmReg = DstReg;
4675 if (DstReg == SrcReg) {
4676 unsigned ATReg = getATReg(Inst.
getLoc());
4682 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4683 false, IDLoc, Out, STI))
4686 TOut.
emitRRR(OpRegCode, DstReg, SrcReg, ImmReg, IDLoc, STI);
4687 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4704 unsigned ImmReg = DstReg;
4708 warnIfNoMacro(IDLoc);
4712 case Mips::SGTImm64:
4716 case Mips::SGTUImm64:
4723 if (DstReg == SrcReg) {
4724 unsigned ATReg = getATReg(Inst.
getLoc());
4730 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4731 false, IDLoc, Out, STI))
4735 TOut.
emitRRR(OpCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4754 warnIfNoMacro(IDLoc);
4768 TOut.
emitRRR(OpCode, DstReg, OpReg, SrcReg, IDLoc, STI);
4769 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4788 warnIfNoMacro(IDLoc);
4792 case Mips::SLEImm64:
4793 OpRegCode = Mips::SLT;
4796 case Mips::SLEUImm64:
4797 OpRegCode = Mips::SLTu;
4804 unsigned ImmReg = DstReg;
4805 if (DstReg == SrcReg) {
4806 unsigned ATReg = getATReg(Inst.
getLoc());
4812 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4813 false, IDLoc, Out, STI))
4816 TOut.
emitRRR(OpRegCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4817 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4822bool MipsAsmParser::expandAliasImmediate(
MCInst &Inst,
SMLoc IDLoc,
4832 unsigned ATReg = Mips::NoRegister;
4833 unsigned FinalDstReg = Mips::NoRegister;
4838 bool Is32Bit = isInt<32>(ImmValue) || (!isGP64bit() && isUInt<32>(ImmValue));
4840 unsigned FinalOpcode = Inst.
getOpcode();
4842 if (DstReg == SrcReg) {
4843 ATReg = getATReg(Inst.
getLoc());
4846 FinalDstReg = DstReg;
4850 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit,
false,
4851 Inst.
getLoc(), Out, STI)) {
4852 switch (FinalOpcode) {
4856 FinalOpcode = Mips::ADD;
4859 FinalOpcode = Mips::ADDu;
4862 FinalOpcode = Mips::AND;
4865 FinalOpcode = Mips::NOR;
4868 FinalOpcode = Mips::OR;
4871 FinalOpcode = Mips::SLT;
4874 FinalOpcode = Mips::SLTu;
4877 FinalOpcode = Mips::XOR;
4880 FinalOpcode = Mips::ADD_MM;
4882 case Mips::ADDiu_MM:
4883 FinalOpcode = Mips::ADDu_MM;
4886 FinalOpcode = Mips::AND_MM;
4889 FinalOpcode = Mips::OR_MM;
4892 FinalOpcode = Mips::SLT_MM;
4894 case Mips::SLTiu_MM:
4895 FinalOpcode = Mips::SLTu_MM;
4898 FinalOpcode = Mips::XOR_MM;
4901 FinalOpcode = Mips::AND64;
4903 case Mips::NORImm64:
4904 FinalOpcode = Mips::NOR64;
4907 FinalOpcode = Mips::OR64;
4909 case Mips::SLTImm64:
4910 FinalOpcode = Mips::SLT64;
4912 case Mips::SLTUImm64:
4913 FinalOpcode = Mips::SLTu64;
4916 FinalOpcode = Mips::XOR64;
4920 if (FinalDstReg == Mips::NoRegister)
4921 TOut.
emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4923 TOut.
emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4932 unsigned ATReg = Mips::NoRegister;
4936 unsigned TmpReg =
DReg;
4938 unsigned FirstShift = Mips::NOP;
4939 unsigned SecondShift = Mips::NOP;
4941 if (hasMips32r2()) {
4943 TmpReg = getATReg(Inst.
getLoc());
4949 TOut.
emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4950 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
4955 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
4967 FirstShift = Mips::SRLV;
4968 SecondShift = Mips::SLLV;
4971 FirstShift = Mips::SLLV;
4972 SecondShift = Mips::SRLV;
4976 ATReg = getATReg(Inst.
getLoc());
4980 TOut.
emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4981 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
4982 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
4983 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
4991bool MipsAsmParser::expandRotationImm(
MCInst &Inst,
SMLoc IDLoc,
4995 unsigned ATReg = Mips::NoRegister;
5000 unsigned FirstShift = Mips::NOP;
5001 unsigned SecondShift = Mips::NOP;
5003 if (hasMips32r2()) {
5008 ShiftValue = MaxShift - ImmValue;
5009 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
5014 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.
getLoc(), STI);
5022 if (ImmValue == 0) {
5031 FirstShift = Mips::SLL;
5032 SecondShift = Mips::SRL;
5035 FirstShift = Mips::SRL;
5036 SecondShift = Mips::SLL;
5040 ATReg = getATReg(Inst.
getLoc());
5044 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.
getLoc(), STI);
5045 TOut.
emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.
getLoc(), STI);
5046 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5057 unsigned ATReg = Mips::NoRegister;
5061 unsigned TmpReg =
DReg;
5063 unsigned FirstShift = Mips::NOP;
5064 unsigned SecondShift = Mips::NOP;
5066 if (hasMips64r2()) {
5067 if (TmpReg == SReg) {
5068 TmpReg = getATReg(Inst.
getLoc());
5074 TOut.
emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
5075 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
5080 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
5092 FirstShift = Mips::DSRLV;
5093 SecondShift = Mips::DSLLV;
5096 FirstShift = Mips::DSLLV;
5097 SecondShift = Mips::DSRLV;
5101 ATReg = getATReg(Inst.
getLoc());
5105 TOut.
emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
5106 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
5107 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
5108 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5116bool MipsAsmParser::expandDRotationImm(
MCInst &Inst,
SMLoc IDLoc,
5120 unsigned ATReg = Mips::NoRegister;
5125 unsigned FirstShift = Mips::NOP;
5126 unsigned SecondShift = Mips::NOP;
5130 if (hasMips64r2()) {
5131 unsigned FinalOpcode = Mips::NOP;
5133 FinalOpcode = Mips::DROTR;
5134 else if (ImmValue % 32 == 0)
5135 FinalOpcode = Mips::DROTR32;
5136 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
5138 FinalOpcode = Mips::DROTR32;
5140 FinalOpcode = Mips::DROTR;
5141 }
else if (ImmValue >= 33) {
5143 FinalOpcode = Mips::DROTR;
5145 FinalOpcode = Mips::DROTR32;
5148 uint64_t ShiftValue = ImmValue % 32;
5150 ShiftValue = (32 - ImmValue % 32) % 32;
5152 TOut.
emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
5158 if (ImmValue == 0) {
5159 TOut.
emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.
getLoc(), STI);
5167 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5168 FirstShift = Mips::DSLL;
5169 SecondShift = Mips::DSRL32;
5171 if (ImmValue == 32) {
5172 FirstShift = Mips::DSLL32;
5173 SecondShift = Mips::DSRL32;
5175 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5176 FirstShift = Mips::DSLL32;
5177 SecondShift = Mips::DSRL;
5181 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5182 FirstShift = Mips::DSRL;
5183 SecondShift = Mips::DSLL32;
5185 if (ImmValue == 32) {
5186 FirstShift = Mips::DSRL32;
5187 SecondShift = Mips::DSLL32;
5189 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5190 FirstShift = Mips::DSRL32;
5191 SecondShift = Mips::DSLL;
5196 ATReg = getATReg(Inst.
getLoc());
5200 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.
getLoc(), STI);
5201 TOut.
emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
5203 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5217 TOut.
emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
5218 if (FirstRegOp != SecondRegOp)
5219 TOut.
emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
5222 TOut.
emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
5230 unsigned ATReg = Mips::NoRegister;
5235 ATReg = getATReg(IDLoc);
5239 loadImmediate(ImmValue, ATReg, Mips::NoRegister,
true,
false, IDLoc, Out,
5242 TOut.
emitRR(Inst.
getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
5243 SrcReg, ATReg, IDLoc, STI);