63#define DEBUG_TYPE "mips-asm-parser"
75class MipsAssemblerOptions {
77 MipsAssemblerOptions(
const FeatureBitset &Features_) : Features(Features_) {}
79 MipsAssemblerOptions(
const MipsAssemblerOptions *Opts) {
80 ATReg = Opts->getATRegIndex();
81 Reorder = Opts->isReorder();
82 Macro = Opts->isMacro();
83 Features = Opts->getFeatures();
86 unsigned getATRegIndex()
const {
return ATReg; }
87 bool setATRegIndex(
unsigned Reg) {
95 bool isReorder()
const {
return Reorder; }
96 void setReorder() { Reorder =
true; }
97 void setNoReorder() { Reorder =
false; }
99 bool isMacro()
const {
return Macro; }
100 void setMacro() {
Macro =
true; }
101 void setNoMacro() {
Macro =
false; }
104 void setFeatures(
const FeatureBitset &Features_) { Features = Features_; }
122const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
123 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
124 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
125 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
126 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
127 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
128 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
129 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
130 Mips::FeatureCnMipsP, Mips::FeatureFP64Bit, Mips::FeatureGP64Bit,
139 "do not have a target streamer");
153 bool CurForbiddenSlotAttr;
156 unsigned CpSaveLocation;
158 bool CpSaveLocationIsRegister;
164 void printWarningWithFixIt(
const Twine &Msg,
const Twine &FixMsg,
169#define GET_ASSEMBLER_HEADER
170#include "MipsGenAsmMatcher.inc"
180 bool MatchingInlineAsm)
override;
185 SMLoc &EndLoc)
override;
191 bool mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID);
214 enum MacroExpanderResultTy {
221 MacroExpanderResultTy tryExpandInstruction(
MCInst &Inst,
SMLoc IDLoc,
228 bool loadImmediate(int64_t ImmValue,
unsigned DstReg,
unsigned SrcReg,
229 bool Is32BitImm,
bool IsAddress,
SMLoc IDLoc,
232 bool loadAndAddSymbolAddress(
const MCExpr *SymExpr,
unsigned DstReg,
233 unsigned SrcReg,
bool Is32BitSym,
SMLoc IDLoc,
238 bool expandLoadImm(
MCInst &Inst,
bool Is32BitImm,
SMLoc IDLoc,
247 bool expandLoadDoubleImmToFPR(
MCInst &Inst,
bool Is64FPU,
SMLoc IDLoc,
250 bool expandLoadAddress(
unsigned DstReg,
unsigned BaseReg,
279 bool expandTrunc(
MCInst &Inst,
bool IsDouble,
bool Is64FPU,
SMLoc IDLoc,
354 bool reportParseError(
const Twine &ErrorMsg);
355 bool reportParseError(
SMLoc Loc,
const Twine &ErrorMsg);
357 bool parseMemOffset(
const MCExpr *&Res,
bool isParenExpr);
359 bool parseSetMips0Directive();
360 bool parseSetArchDirective();
361 bool parseSetFeature(
uint64_t Feature);
362 bool isPicAndNotNxxAbi();
363 bool parseDirectiveCpAdd(
SMLoc Loc);
364 bool parseDirectiveCpLoad(
SMLoc Loc);
365 bool parseDirectiveCpLocal(
SMLoc Loc);
366 bool parseDirectiveCpRestore(
SMLoc Loc);
367 bool parseDirectiveCPSetup();
368 bool parseDirectiveCPReturn();
369 bool parseDirectiveNaN();
370 bool parseDirectiveSet();
371 bool parseDirectiveOption();
372 bool parseInsnDirective();
373 bool parseRSectionDirective(
StringRef Section);
374 bool parseSSectionDirective(
StringRef Section,
unsigned Type);
376 bool parseSetAtDirective();
377 bool parseSetNoAtDirective();
378 bool parseSetMacroDirective();
379 bool parseSetNoMacroDirective();
380 bool parseSetMsaDirective();
381 bool parseSetNoMsaDirective();
382 bool parseSetNoDspDirective();
383 bool parseSetNoMips3DDirective();
384 bool parseSetReorderDirective();
385 bool parseSetNoReorderDirective();
386 bool parseSetMips16Directive();
387 bool parseSetNoMips16Directive();
388 bool parseSetFpDirective();
389 bool parseSetOddSPRegDirective();
390 bool parseSetNoOddSPRegDirective();
391 bool parseSetPopDirective();
392 bool parseSetPushDirective();
393 bool parseSetSoftFloatDirective();
394 bool parseSetHardFloatDirective();
395 bool parseSetMtDirective();
396 bool parseSetNoMtDirective();
397 bool parseSetNoCRCDirective();
398 bool parseSetNoVirtDirective();
399 bool parseSetNoGINVDirective();
401 bool parseSetAssignment();
403 bool parseDirectiveGpWord();
404 bool parseDirectiveGpDWord();
405 bool parseDirectiveDtpRelWord();
406 bool parseDirectiveDtpRelDWord();
407 bool parseDirectiveTpRelWord();
408 bool parseDirectiveTpRelDWord();
409 bool parseDirectiveModule();
410 bool parseDirectiveModuleFP();
414 bool parseInternalDirectiveReallowModule();
418 int matchCPURegisterName(
StringRef Symbol);
420 int matchHWRegsRegisterName(
StringRef Symbol);
432 unsigned getReg(
int RC,
int RegNo);
437 unsigned getATReg(
SMLoc Loc);
447 bool validateMSAIndex(
int Val,
int RegKind);
474 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
482 if (!(
getSTI().hasFeature(Feature))) {
491 if (
getSTI().hasFeature(Feature)) {
500 setFeatureBits(Feature, FeatureString);
501 AssemblerOptions.
front()->setFeatures(
getSTI().getFeatureBits());
505 clearFeatureBits(Feature, FeatureString);
506 AssemblerOptions.
front()->setFeatures(
getSTI().getFeatureBits());
510 enum MipsMatchResultTy {
512 Match_RequiresDifferentOperands,
513 Match_RequiresNoZeroRegister,
514 Match_RequiresSameSrcAndDst,
515 Match_NoFCCRegisterForCurrentISA,
516 Match_NonZeroOperandForSync,
517 Match_NonZeroOperandForMTCX,
518 Match_RequiresPosSizeRange0_32,
519 Match_RequiresPosSizeRange33_64,
520 Match_RequiresPosSizeUImm6,
521#define GET_OPERAND_DIAGNOSTIC_TYPES
522#include "MipsGenAsmMatcher.inc"
523#undef GET_OPERAND_DIAGNOSTIC_TYPES
543 std::make_unique<MipsAssemblerOptions>(
getSTI().getFeatureBits()));
547 std::make_unique<MipsAssemblerOptions>(
getSTI().getFeatureBits()));
549 getTargetStreamer().updateABIInfo(*
this);
551 if (!isABI_O32() && !useOddSPReg() != 0)
556 CurForbiddenSlotAttr =
false;
559 IsCpRestoreSet =
false;
560 CpRestoreOffset = -1;
561 GPReg =
ABI.GetGlobalPtr();
566 if (
getSTI().
getCPU() ==
"mips64r6" && inMicroMipsMode())
569 if (!isABI_O32() && inMicroMipsMode())
574 bool hasEightFccRegisters()
const {
return hasMips4() || hasMips32(); }
576 bool isGP64bit()
const {
580 bool isFP64bit()
const {
584 bool isJalrRelocAvailable(
const MCExpr *JalExpr) {
593 return ABI.IsN32() ||
ABI.IsN64();
598 bool isABI_N32()
const {
return ABI.IsN32(); }
599 bool isABI_N64()
const {
return ABI.IsN64(); }
600 bool isABI_O32()
const {
return ABI.IsO32(); }
601 bool isABI_FPXX()
const {
605 bool useOddSPReg()
const {
609 bool inMicroMipsMode()
const {
613 bool hasMips1()
const {
617 bool hasMips2()
const {
621 bool hasMips3()
const {
625 bool hasMips4()
const {
629 bool hasMips5()
const {
633 bool hasMips32()
const {
637 bool hasMips64()
const {
641 bool hasMips32r2()
const {
645 bool hasMips64r2()
const {
649 bool hasMips32r3()
const {
650 return (
getSTI().hasFeature(Mips::FeatureMips32r3));
653 bool hasMips64r3()
const {
654 return (
getSTI().hasFeature(Mips::FeatureMips64r3));
657 bool hasMips32r5()
const {
658 return (
getSTI().hasFeature(Mips::FeatureMips32r5));
661 bool hasMips64r5()
const {
662 return (
getSTI().hasFeature(Mips::FeatureMips64r5));
665 bool hasMips32r6()
const {
669 bool hasMips64r6()
const {
673 bool hasDSP()
const {
677 bool hasDSPR2()
const {
681 bool hasDSPR3()
const {
685 bool hasMSA()
const {
689 bool hasCnMips()
const {
690 return (
getSTI().hasFeature(Mips::FeatureCnMips));
693 bool hasCnMipsP()
const {
694 return (
getSTI().hasFeature(Mips::FeatureCnMipsP));
701 bool inMips16Mode()
const {
705 bool useTraps()
const {
709 bool useSoftFloat()
const {
716 bool hasCRC()
const {
720 bool hasVirt()
const {
724 bool hasGINV()
const {
728 bool hasForbiddenSlot(
const MCInstrDesc &MCID)
const {
732 bool SafeInForbiddenSlot(
const MCInstrDesc &MCID)
const {
739 void warnIfRegIndexIsAT(
unsigned RegIndex,
SMLoc Loc);
741 void warnIfNoMacro(
SMLoc Loc);
743 bool isLittle()
const {
return IsLittleEndian; }
748 switch(OperatorToken) {
819 RegKind_MSACtrl = 16,
824 RegKind_HWRegs = 256,
828 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
829 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
830 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
843 MipsOperand(KindTy K, MipsAsmParser &Parser) :
Kind(
K), AsmParser(Parser) {}
845 ~MipsOperand()
override {
854 case k_RegisterIndex:
862 MipsAsmParser &AsmParser;
891 struct RegIdxOp RegIdx;
894 struct RegListOp RegList;
897 SMLoc StartLoc, EndLoc;
900 static std::unique_ptr<MipsOperand> CreateReg(
unsigned Index,
StringRef Str,
904 MipsAsmParser &Parser) {
905 auto Op = std::make_unique<MipsOperand>(k_RegisterIndex, Parser);
908 Op->RegIdx.Kind = RegKind;
909 Op->RegIdx.Tok.Data = Str.data();
910 Op->RegIdx.Tok.Length = Str.size();
919 unsigned getGPR32Reg()
const {
920 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
921 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
922 unsigned ClassID = Mips::GPR32RegClassID;
923 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
928 unsigned getGPRMM16Reg()
const {
929 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
930 unsigned ClassID = Mips::GPR32RegClassID;
931 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
936 unsigned getGPR64Reg()
const {
937 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
938 unsigned ClassID = Mips::GPR64RegClassID;
939 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
945 unsigned getAFGR64Reg()
const {
946 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
947 if (RegIdx.Index % 2 != 0)
948 AsmParser.Warning(StartLoc,
"Float register should be even.");
949 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
950 .getRegister(RegIdx.Index / 2);
955 unsigned getFGR64Reg()
const {
956 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
957 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
958 .getRegister(RegIdx.Index);
963 unsigned getFGR32Reg()
const {
964 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
965 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
966 .getRegister(RegIdx.Index);
971 unsigned getFCCReg()
const {
972 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) &&
"Invalid access!");
973 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
974 .getRegister(RegIdx.Index);
979 unsigned getMSA128Reg()
const {
980 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) &&
"Invalid access!");
983 unsigned ClassID = Mips::MSA128BRegClassID;
984 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
989 unsigned getMSACtrlReg()
const {
990 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) &&
"Invalid access!");
991 unsigned ClassID = Mips::MSACtrlRegClassID;
992 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
997 unsigned getCOP0Reg()
const {
998 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) &&
"Invalid access!");
999 unsigned ClassID = Mips::COP0RegClassID;
1000 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1005 unsigned getCOP2Reg()
const {
1006 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) &&
"Invalid access!");
1007 unsigned ClassID = Mips::COP2RegClassID;
1008 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1013 unsigned getCOP3Reg()
const {
1014 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) &&
"Invalid access!");
1015 unsigned ClassID = Mips::COP3RegClassID;
1016 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1021 unsigned getACC64DSPReg()
const {
1022 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
1023 unsigned ClassID = Mips::ACC64DSPRegClassID;
1024 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1029 unsigned getHI32DSPReg()
const {
1030 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
1031 unsigned ClassID = Mips::HI32DSPRegClassID;
1032 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1037 unsigned getLO32DSPReg()
const {
1038 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
1039 unsigned ClassID = Mips::LO32DSPRegClassID;
1040 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1045 unsigned getCCRReg()
const {
1046 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) &&
"Invalid access!");
1047 unsigned ClassID = Mips::CCRRegClassID;
1048 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1053 unsigned getHWRegsReg()
const {
1054 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) &&
"Invalid access!");
1055 unsigned ClassID = Mips::HWRegsRegClassID;
1056 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1064 else if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
1070 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
1077 void addGPR32ZeroAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1078 assert(
N == 1 &&
"Invalid number of operands!");
1082 void addGPR32NonZeroAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1083 assert(
N == 1 &&
"Invalid number of operands!");
1087 void addGPR32AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1088 assert(
N == 1 &&
"Invalid number of operands!");
1092 void addGPRMM16AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1093 assert(
N == 1 &&
"Invalid number of operands!");
1097 void addGPRMM16AsmRegZeroOperands(
MCInst &Inst,
unsigned N)
const {
1098 assert(
N == 1 &&
"Invalid number of operands!");
1102 void addGPRMM16AsmRegMovePOperands(
MCInst &Inst,
unsigned N)
const {
1103 assert(
N == 1 &&
"Invalid number of operands!");
1107 void addGPRMM16AsmRegMovePPairFirstOperands(
MCInst &Inst,
unsigned N)
const {
1108 assert(
N == 1 &&
"Invalid number of operands!");
1112 void addGPRMM16AsmRegMovePPairSecondOperands(
MCInst &Inst,
1114 assert(
N == 1 &&
"Invalid number of operands!");
1121 void addGPR64AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1122 assert(
N == 1 &&
"Invalid number of operands!");
1126 void addAFGR64AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1127 assert(
N == 1 &&
"Invalid number of operands!");
1131 void addStrictlyAFGR64AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1132 assert(
N == 1 &&
"Invalid number of operands!");
1136 void addStrictlyFGR64AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1137 assert(
N == 1 &&
"Invalid number of operands!");
1141 void addFGR64AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1142 assert(
N == 1 &&
"Invalid number of operands!");
1146 void addFGR32AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1147 assert(
N == 1 &&
"Invalid number of operands!");
1151 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1152 AsmParser.getParser().printError(
1153 StartLoc,
"-mno-odd-spreg prohibits the use of odd FPU "
1157 void addStrictlyFGR32AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1158 assert(
N == 1 &&
"Invalid number of operands!");
1161 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1162 AsmParser.Error(StartLoc,
"-mno-odd-spreg prohibits the use of odd FPU "
1166 void addFCCAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1167 assert(
N == 1 &&
"Invalid number of operands!");
1171 void addMSA128AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1172 assert(
N == 1 &&
"Invalid number of operands!");
1176 void addMSACtrlAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1177 assert(
N == 1 &&
"Invalid number of operands!");
1181 void addCOP0AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1182 assert(
N == 1 &&
"Invalid number of operands!");
1186 void addCOP2AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1187 assert(
N == 1 &&
"Invalid number of operands!");
1191 void addCOP3AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1192 assert(
N == 1 &&
"Invalid number of operands!");
1196 void addACC64DSPAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1197 assert(
N == 1 &&
"Invalid number of operands!");
1201 void addHI32DSPAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1202 assert(
N == 1 &&
"Invalid number of operands!");
1206 void addLO32DSPAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1207 assert(
N == 1 &&
"Invalid number of operands!");
1211 void addCCRAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1212 assert(
N == 1 &&
"Invalid number of operands!");
1216 void addHWRegsAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1217 assert(
N == 1 &&
"Invalid number of operands!");
1221 template <
unsigned Bits,
int Offset = 0,
int AdjustOffset = 0>
1222 void addConstantUImmOperands(
MCInst &Inst,
unsigned N)
const {
1223 assert(
N == 1 &&
"Invalid number of operands!");
1227 Imm += AdjustOffset;
1231 template <
unsigned Bits>
1232 void addSImmOperands(
MCInst &Inst,
unsigned N)
const {
1233 if (
isImm() && !isConstantImm()) {
1234 addExpr(Inst, getImm());
1237 addConstantSImmOperands<Bits, 0, 0>(Inst,
N);
1240 template <
unsigned Bits>
1241 void addUImmOperands(
MCInst &Inst,
unsigned N)
const {
1242 if (
isImm() && !isConstantImm()) {
1243 addExpr(Inst, getImm());
1246 addConstantUImmOperands<Bits, 0, 0>(Inst,
N);
1249 template <
unsigned Bits,
int Offset = 0,
int AdjustOffset = 0>
1250 void addConstantSImmOperands(
MCInst &Inst,
unsigned N)
const {
1251 assert(
N == 1 &&
"Invalid number of operands!");
1252 int64_t
Imm = getConstantImm() -
Offset;
1253 Imm = SignExtend64<Bits>(Imm);
1255 Imm += AdjustOffset;
1259 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
1260 assert(
N == 1 &&
"Invalid number of operands!");
1261 const MCExpr *Expr = getImm();
1262 addExpr(Inst, Expr);
1265 void addMemOperands(
MCInst &Inst,
unsigned N)
const {
1266 assert(
N == 2 &&
"Invalid number of operands!");
1269 ? getMemBase()->getGPR64Reg()
1270 : getMemBase()->getGPR32Reg()));
1272 const MCExpr *Expr = getMemOff();
1273 addExpr(Inst, Expr);
1276 void addMicroMipsMemOperands(
MCInst &Inst,
unsigned N)
const {
1277 assert(
N == 2 &&
"Invalid number of operands!");
1281 const MCExpr *Expr = getMemOff();
1282 addExpr(Inst, Expr);
1285 void addRegListOperands(
MCInst &Inst,
unsigned N)
const {
1286 assert(
N == 1 &&
"Invalid number of operands!");
1288 for (
auto RegNo : getRegList())
1292 bool isReg()
const override {
1295 return isGPRAsmReg() && RegIdx.Index == 0;
1298 bool isRegIdx()
const {
return Kind == k_RegisterIndex; }
1299 bool isImm()
const override {
return Kind == k_Immediate; }
1301 bool isConstantImm()
const {
1303 return isImm() && getImm()->evaluateAsAbsolute(Res);
1306 bool isConstantImmz()
const {
1307 return isConstantImm() && getConstantImm() == 0;
1310 template <
unsigned Bits,
int Offset = 0>
bool isConstantUImm()
const {
1311 return isConstantImm() && isUInt<Bits>(getConstantImm() -
Offset);
1314 template <
unsigned Bits>
bool isSImm()
const {
1315 return isConstantImm() ? isInt<Bits>(getConstantImm()) :
isImm();
1318 template <
unsigned Bits>
bool isUImm()
const {
1319 return isConstantImm() ? isUInt<Bits>(getConstantImm()) :
isImm();
1322 template <
unsigned Bits>
bool isAnyImm()
const {
1323 return isConstantImm() ? (isInt<Bits>(getConstantImm()) ||
1324 isUInt<Bits>(getConstantImm()))
1328 template <
unsigned Bits,
int Offset = 0>
bool isConstantSImm()
const {
1329 return isConstantImm() && isInt<Bits>(getConstantImm() -
Offset);
1332 template <
unsigned Bottom,
unsigned Top>
bool isConstantUImmRange()
const {
1333 return isConstantImm() && getConstantImm() >= Bottom &&
1334 getConstantImm() <= Top;
1337 bool isToken()
const override {
1340 return Kind == k_Token;
1343 bool isMem()
const override {
return Kind == k_Memory; }
1345 bool isConstantMemOff()
const {
1346 return isMem() && isa<MCConstantExpr>(getMemOff());
1350 template <
unsigned Bits,
unsigned ShiftAmount = 0>
1351 bool isMemWithSimmOffset()
const {
1354 if (!getMemBase()->isGPRAsmReg())
1356 if (isa<MCTargetExpr>(getMemOff()) ||
1357 (isConstantMemOff() &&
1358 isShiftedInt<Bits, ShiftAmount>(getConstantMemOff())))
1361 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res,
nullptr,
nullptr);
1362 return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.
getConstant());
1365 bool isMemWithPtrSizeOffset()
const {
1368 if (!getMemBase()->isGPRAsmReg())
1370 const unsigned PtrBits = AsmParser.getABI().ArePtrs64bit() ? 64 : 32;
1371 if (isa<MCTargetExpr>(getMemOff()) ||
1372 (isConstantMemOff() &&
isIntN(PtrBits, getConstantMemOff())))
1375 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res,
nullptr,
nullptr);
1379 bool isMemWithGRPMM16Base()
const {
1380 return isMem() && getMemBase()->isMM16AsmReg();
1383 template <
unsigned Bits>
bool isMemWithUimmOffsetSP()
const {
1384 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1385 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1388 template <
unsigned Bits>
bool isMemWithUimmWordAlignedOffsetSP()
const {
1389 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1390 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1391 && (getMemBase()->getGPR32Reg() == Mips::SP);
1394 template <
unsigned Bits>
bool isMemWithSimmWordAlignedOffsetGP()
const {
1395 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
1396 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1397 && (getMemBase()->getGPR32Reg() == Mips::GP);
1400 template <
unsigned Bits,
unsigned ShiftLeftAmount>
1401 bool isScaledUImm()
const {
1402 return isConstantImm() &&
1403 isShiftedUInt<Bits, ShiftLeftAmount>(getConstantImm());
1406 template <
unsigned Bits,
unsigned ShiftLeftAmount>
1407 bool isScaledSImm()
const {
1408 if (isConstantImm() &&
1409 isShiftedInt<Bits, ShiftLeftAmount>(getConstantImm()))
1413 if (Kind != k_Immediate)
1416 bool Success = getImm()->evaluateAsRelocatable(Res,
nullptr,
nullptr);
1420 bool isRegList16()
const {
1424 int Size = RegList.List->size();
1425 if (Size < 2 || Size > 5)
1428 unsigned R0 = RegList.List->front();
1429 unsigned R1 = RegList.List->back();
1430 if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1431 (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1434 int PrevReg = *RegList.List->begin();
1435 for (
int i = 1; i <
Size - 1; i++) {
1436 int Reg = (*(RegList.List))[i];
1437 if (
Reg != PrevReg + 1)
1445 bool isInvNum()
const {
return Kind == k_Immediate; }
1447 bool isLSAImm()
const {
1448 if (!isConstantImm())
1450 int64_t Val = getConstantImm();
1451 return 1 <= Val && Val <= 4;
1454 bool isRegList()
const {
return Kind == k_RegList; }
1457 assert(Kind == k_Token &&
"Invalid access!");
1464 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1465 RegIdx.Kind & RegKind_GPR)
1466 return getGPR32Reg();
1472 const MCExpr *getImm()
const {
1473 assert((Kind == k_Immediate) &&
"Invalid access!");
1477 int64_t getConstantImm()
const {
1478 const MCExpr *Val = getImm();
1480 (void)Val->evaluateAsAbsolute(
Value);
1484 MipsOperand *getMemBase()
const {
1485 assert((Kind == k_Memory) &&
"Invalid access!");
1489 const MCExpr *getMemOff()
const {
1490 assert((Kind == k_Memory) &&
"Invalid access!");
1494 int64_t getConstantMemOff()
const {
1495 return static_cast<const MCConstantExpr *
>(getMemOff())->getValue();
1499 assert((Kind == k_RegList) &&
"Invalid access!");
1500 return *(RegList.List);
1503 static std::unique_ptr<MipsOperand> CreateToken(
StringRef Str,
SMLoc S,
1504 MipsAsmParser &Parser) {
1505 auto Op = std::make_unique<MipsOperand>(k_Token, Parser);
1506 Op->Tok.Data = Str.data();
1507 Op->Tok.Length = Str.size();
1515 static std::unique_ptr<MipsOperand>
1519 return CreateReg(
Index, Str, RegKind_Numeric,
RegInfo, S,
E, Parser);
1524 static std::unique_ptr<MipsOperand>
1527 return CreateReg(
Index, Str, RegKind_GPR,
RegInfo, S,
E, Parser);
1532 static std::unique_ptr<MipsOperand>
1535 return CreateReg(
Index, Str, RegKind_FGR,
RegInfo, S,
E, Parser);
1540 static std::unique_ptr<MipsOperand>
1543 return CreateReg(
Index, Str, RegKind_HWRegs,
RegInfo, S,
E, Parser);
1548 static std::unique_ptr<MipsOperand>
1551 return CreateReg(
Index, Str, RegKind_FCC,
RegInfo, S,
E, Parser);
1556 static std::unique_ptr<MipsOperand>
1559 return CreateReg(
Index, Str, RegKind_ACC,
RegInfo, S,
E, Parser);
1564 static std::unique_ptr<MipsOperand>
1567 return CreateReg(
Index, Str, RegKind_MSA128,
RegInfo, S,
E, Parser);
1572 static std::unique_ptr<MipsOperand>
1575 return CreateReg(
Index, Str, RegKind_MSACtrl,
RegInfo, S,
E, Parser);
1578 static std::unique_ptr<MipsOperand>
1580 auto Op = std::make_unique<MipsOperand>(k_Immediate, Parser);
1587 static std::unique_ptr<MipsOperand>
1588 CreateMem(std::unique_ptr<MipsOperand>
Base,
const MCExpr *Off,
SMLoc S,
1589 SMLoc E, MipsAsmParser &Parser) {
1590 auto Op = std::make_unique<MipsOperand>(k_Memory, Parser);
1591 Op->Mem.Base =
Base.release();
1598 static std::unique_ptr<MipsOperand>
1600 MipsAsmParser &Parser) {
1601 assert(Regs.
size() > 0 &&
"Empty list not allowed");
1603 auto Op = std::make_unique<MipsOperand>(k_RegList, Parser);
1605 Op->StartLoc = StartLoc;
1606 Op->EndLoc = EndLoc;
1610 bool isGPRZeroAsmReg()
const {
1611 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
1614 bool isGPRNonZeroAsmReg()
const {
1615 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index > 0 &&
1619 bool isGPRAsmReg()
const {
1620 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1623 bool isMM16AsmReg()
const {
1624 if (!(isRegIdx() && RegIdx.Kind))
1626 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1627 || RegIdx.Index == 16 || RegIdx.Index == 17);
1630 bool isMM16AsmRegZero()
const {
1631 if (!(isRegIdx() && RegIdx.Kind))
1633 return (RegIdx.Index == 0 ||
1634 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1635 RegIdx.Index == 17);
1638 bool isMM16AsmRegMoveP()
const {
1639 if (!(isRegIdx() && RegIdx.Kind))
1641 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1642 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1645 bool isMM16AsmRegMovePPairFirst()
const {
1646 if (!(isRegIdx() && RegIdx.Kind))
1648 return RegIdx.Index >= 4 && RegIdx.Index <= 6;
1651 bool isMM16AsmRegMovePPairSecond()
const {
1652 if (!(isRegIdx() && RegIdx.Kind))
1654 return (RegIdx.Index == 21 || RegIdx.Index == 22 ||
1655 (RegIdx.Index >= 5 && RegIdx.Index <= 7));
1658 bool isFGRAsmReg()
const {
1660 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1663 bool isStrictlyFGRAsmReg()
const {
1665 return isRegIdx() && RegIdx.Kind == RegKind_FGR && RegIdx.Index <= 31;
1668 bool isHWRegsAsmReg()
const {
1669 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1672 bool isCCRAsmReg()
const {
1673 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1676 bool isFCCAsmReg()
const {
1677 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1679 return RegIdx.Index <= 7;
1682 bool isACCAsmReg()
const {
1683 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1686 bool isCOP0AsmReg()
const {
1687 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1690 bool isCOP2AsmReg()
const {
1691 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1694 bool isCOP3AsmReg()
const {
1695 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1698 bool isMSA128AsmReg()
const {
1699 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1702 bool isMSACtrlAsmReg()
const {
1703 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1707 SMLoc getStartLoc()
const override {
return StartLoc; }
1709 SMLoc getEndLoc()
const override {
return EndLoc; }
1720 Mem.Base->print(
OS);
1725 case k_RegisterIndex:
1726 OS <<
"RegIdx<" << RegIdx.Index <<
":" << RegIdx.Kind <<
", "
1727 <<
StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) <<
">";
1734 for (
auto Reg : (*RegList.List))
1741 bool isValidForTie(
const MipsOperand &
Other)
const {
1742 if (Kind !=
Other.Kind)
1749 case k_RegisterIndex: {
1750 StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length);
1752 return Token == OtherToken;
1768 case Mips::JRC16_MM:
1770 case Mips::JALRS_MM:
1771 case Mips::JALRS16_MM:
1772 case Mips::BGEZALS_MM:
1773 case Mips::BLTZALS_MM:
1783 if (
const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1784 return &SRExpr->getSymbol();
1787 if (
const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1800 if (
const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1807 if (isa<MCSymbolRefExpr>(Expr))
1810 if (
const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1814 if (
const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1833 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1842 if (NumOp != 3 && NumOp != 4)
1854 return !isInt<9>(
Op.getImm());
1856 return !isInt<16>(
Op.getImm());
1872bool MipsAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
1876 const unsigned Opcode = Inst.
getOpcode();
1878 bool ExpandedJalSym =
false;
1892 assert(hasCnMips() &&
"instruction only valid for octeon cpus");
1903 if (!
isIntN(inMicroMipsMode() ? 17 : 18,
Offset.getImm()))
1904 return Error(IDLoc,
"branch target out of range");
1907 return Error(IDLoc,
"branch to misaligned address");
1921 case Mips::BGEZAL_MM:
1922 case Mips::BLTZAL_MM:
1925 case Mips::BC1EQZC_MMR6:
1926 case Mips::BC1NEZC_MMR6:
1927 case Mips::BC2EQZC_MMR6:
1928 case Mips::BC2NEZC_MMR6:
1933 if (!
isIntN(inMicroMipsMode() ? 17 : 18,
Offset.getImm()))
1934 return Error(IDLoc,
"branch target out of range");
1937 return Error(IDLoc,
"branch to misaligned address");
1939 case Mips::BGEC:
case Mips::BGEC_MMR6:
1940 case Mips::BLTC:
case Mips::BLTC_MMR6:
1941 case Mips::BGEUC:
case Mips::BGEUC_MMR6:
1942 case Mips::BLTUC:
case Mips::BLTUC_MMR6:
1943 case Mips::BEQC:
case Mips::BEQC_MMR6:
1944 case Mips::BNEC:
case Mips::BNEC_MMR6:
1950 return Error(IDLoc,
"branch target out of range");
1952 return Error(IDLoc,
"branch to misaligned address");
1954 case Mips::BLEZC:
case Mips::BLEZC_MMR6:
1955 case Mips::BGEZC:
case Mips::BGEZC_MMR6:
1956 case Mips::BGTZC:
case Mips::BGTZC_MMR6:
1957 case Mips::BLTZC:
case Mips::BLTZC_MMR6:
1963 return Error(IDLoc,
"branch target out of range");
1965 return Error(IDLoc,
"branch to misaligned address");
1967 case Mips::BEQZC:
case Mips::BEQZC_MMR6:
1968 case Mips::BNEZC:
case Mips::BNEZC_MMR6:
1974 return Error(IDLoc,
"branch target out of range");
1976 return Error(IDLoc,
"branch to misaligned address");
1978 case Mips::BEQZ16_MM:
1979 case Mips::BEQZC16_MMR6:
1980 case Mips::BNEZ16_MM:
1981 case Mips::BNEZC16_MMR6:
1986 if (!isInt<8>(
Offset.getImm()))
1987 return Error(IDLoc,
"branch target out of range");
1989 return Error(IDLoc,
"branch to misaligned address");
1996 if (hasMips32r6() && Opcode == Mips::SSNOP) {
1997 std::string
ISA = hasMips64r6() ?
"MIPS64r6" :
"MIPS32r6";
1998 Warning(IDLoc,
"ssnop is deprecated for " + ISA +
" and is equivalent to a "
2018 return Error(IDLoc,
"expected immediate operand kind");
2020 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
2021 Opcode == Mips::BBIT1 ? 63 : 31))
2022 return Error(IDLoc,
"immediate operand value out of range");
2024 Inst.
setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
2035 return Error(IDLoc,
"expected immediate operand kind");
2037 if (!isInt<10>(Imm))
2038 return Error(IDLoc,
"immediate operand value out of range");
2050 unsigned FirstOp = 1;
2051 unsigned SecondOp = 2;
2055 case Mips::SDivIMacro:
2056 case Mips::UDivIMacro:
2057 case Mips::DSDivIMacro:
2058 case Mips::DUDivIMacro:
2062 Warning(IDLoc,
"dividing zero by zero");
2064 Warning(IDLoc,
"division by zero");
2076 case Mips::SDivMacro:
2077 case Mips::DSDivMacro:
2078 case Mips::UDivMacro:
2079 case Mips::DUDivMacro:
2084 case Mips::DIVU_MMR6:
2085 case Mips::DIV_MMR6:
2090 Warning(IDLoc,
"dividing zero by zero");
2092 Warning(IDLoc,
"division by zero");
2098 if ((Opcode == Mips::J || Opcode == Mips::J_MM) && inPicMode()) {
2100 BInst.
setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
2109 if ((Opcode == Mips::JAL || Opcode == Mips::JAL_MM) && inPicMode()) {
2110 warnIfNoMacro(IDLoc);
2117 return Error(IDLoc,
"jal doesn't support multiple symbols in PIC mode");
2123 if (expandLoadAddress(Mips::T9, Mips::NoRegister, Inst.
getOperand(0),
2124 !isGP64bit(), IDLoc, Out, STI))
2128 if (inMicroMipsMode())
2129 JalrInst.
setOpcode(IsCpRestoreSet ? Mips::JALRS_MM : Mips::JALR_MM);
2135 if (isJalrRelocAvailable(JalExpr)) {
2139 MCSymbol *TmpLabel = getContext().createTempSymbol();
2141 const MCExpr *RelocJalrExpr =
2143 getContext(), IDLoc);
2146 *TmpExpr, inMicroMipsMode() ?
"R_MICROMIPS_JALR" :
"R_MIPS_JALR",
2147 RelocJalrExpr, IDLoc, *STI);
2152 ExpandedJalSym =
true;
2161 expandMem9Inst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2164 expandMem16Inst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2167 return getParser().hasPendingError();
2171 if (inMicroMipsMode()) {
2172 if (MCID.
mayLoad() && Opcode != Mips::LWP_MM) {
2180 int MemOffset =
Op.getImm();
2183 if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
2186 (BaseReg.
getReg() == Mips::GP ||
2187 BaseReg.
getReg() == Mips::GP_64)) {
2189 TOut.
emitRRI(Mips::LWGP_MM, DstReg.
getReg(), Mips::GP, MemOffset,
2206 case Mips::ADDIUSP_MM:
2209 return Error(IDLoc,
"expected immediate operand kind");
2211 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
2213 return Error(IDLoc,
"immediate operand value out of range");
2215 case Mips::SLL16_MM:
2216 case Mips::SRL16_MM:
2219 return Error(IDLoc,
"expected immediate operand kind");
2221 if (Imm < 1 || Imm > 8)
2222 return Error(IDLoc,
"immediate operand value out of range");
2227 return Error(IDLoc,
"expected immediate operand kind");
2229 if (Imm < -1 || Imm > 126)
2230 return Error(IDLoc,
"immediate operand value out of range");
2232 case Mips::ADDIUR2_MM:
2235 return Error(IDLoc,
"expected immediate operand kind");
2237 if (!(Imm == 1 || Imm == -1 ||
2238 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
2239 return Error(IDLoc,
"immediate operand value out of range");
2241 case Mips::ANDI16_MM:
2244 return Error(IDLoc,
"expected immediate operand kind");
2246 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
2247 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
2248 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
2249 return Error(IDLoc,
"immediate operand value out of range");
2251 case Mips::LBU16_MM:
2254 return Error(IDLoc,
"expected immediate operand kind");
2256 if (Imm < -1 || Imm > 14)
2257 return Error(IDLoc,
"immediate operand value out of range");
2260 case Mips::SB16_MMR6:
2263 return Error(IDLoc,
"expected immediate operand kind");
2265 if (Imm < 0 || Imm > 15)
2266 return Error(IDLoc,
"immediate operand value out of range");
2268 case Mips::LHU16_MM:
2270 case Mips::SH16_MMR6:
2273 return Error(IDLoc,
"expected immediate operand kind");
2275 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
2276 return Error(IDLoc,
"immediate operand value out of range");
2280 case Mips::SW16_MMR6:
2283 return Error(IDLoc,
"expected immediate operand kind");
2285 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
2286 return Error(IDLoc,
"immediate operand value out of range");
2288 case Mips::ADDIUPC_MM:
2291 return Error(IDLoc,
"expected immediate operand kind");
2293 if ((Imm % 4 != 0) || !isInt<25>(Imm))
2294 return Error(IDLoc,
"immediate operand value out of range");
2299 return Error(IDLoc,
"invalid operand for instruction");
2301 case Mips::MOVEP_MM:
2302 case Mips::MOVEP_MMR6: {
2305 bool RegPair = ((R0 == Mips::A1 && R1 == Mips::A2) ||
2306 (R0 == Mips::A1 && R1 == Mips::A3) ||
2307 (R0 == Mips::A2 && R1 == Mips::A3) ||
2308 (R0 == Mips::A0 && R1 == Mips::S5) ||
2309 (R0 == Mips::A0 && R1 == Mips::S6) ||
2310 (R0 == Mips::A0 && R1 == Mips::A1) ||
2311 (R0 == Mips::A0 && R1 == Mips::A2) ||
2312 (R0 == Mips::A0 && R1 == Mips::A3));
2314 return Error(IDLoc,
"invalid operand for instruction");
2320 bool FillDelaySlot =
2325 bool PrevForbiddenSlotAttr = CurForbiddenSlotAttr;
2328 bool SetReorderAfterNop =
false;
2333 if (PrevForbiddenSlotAttr && !SafeInForbiddenSlot(MCID)) {
2343 if (AssemblerOptions.
back()->isReorder() && !FillDelaySlot) {
2344 SetReorderAfterNop =
true;
2353 CurForbiddenSlotAttr =
2354 hasForbiddenSlot(MCID) && AssemblerOptions.
back()->isReorder();
2356 if (FillDelaySlot || CurForbiddenSlotAttr)
2359 MacroExpanderResultTy ExpandResult =
2360 tryExpandInstruction(Inst, IDLoc, Out, STI);
2361 switch (ExpandResult) {
2377 if (PrevForbiddenSlotAttr && !SetReorderAfterNop && !FillDelaySlot &&
2378 AssemblerOptions.
back()->isReorder()) {
2384 if (inMicroMipsMode()) {
2399 if (FillDelaySlot) {
2404 if ((Opcode == Mips::JalOneReg || Opcode == Mips::JalTwoReg ||
2406 isPicAndNotNxxAbi()) {
2407 if (IsCpRestoreSet) {
2411 if (!AssemblerOptions.
back()->isReorder())
2418 Warning(IDLoc,
"no .cprestore used in PIC mode");
2424void MipsAsmParser::onEndOfFile() {
2428 if (CurForbiddenSlotAttr) {
2430 if (AssemblerOptions.
back()->isReorder())
2435MipsAsmParser::MacroExpanderResultTy
2440 return MER_NotAMacro;
2441 case Mips::LoadImm32:
2442 return expandLoadImm(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2443 case Mips::LoadImm64:
2444 return expandLoadImm(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2445 case Mips::LoadAddrImm32:
2446 case Mips::LoadAddrImm64:
2449 "expected immediate operand kind");
2453 Inst.
getOpcode() == Mips::LoadAddrImm32, IDLoc,
2457 case Mips::LoadAddrReg32:
2458 case Mips::LoadAddrReg64:
2462 "expected immediate operand kind");
2466 Inst.
getOpcode() == Mips::LoadAddrReg32, IDLoc,
2470 case Mips::B_MM_Pseudo:
2471 case Mips::B_MMR6_Pseudo:
2472 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2476 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2478 case Mips::JalOneReg:
2479 case Mips::JalTwoReg:
2480 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2483 case Mips::BEQLImmMacro:
2484 case Mips::BNELImmMacro:
2485 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2502 case Mips::BLTImmMacro:
2503 case Mips::BLEImmMacro:
2504 case Mips::BGEImmMacro:
2505 case Mips::BGTImmMacro:
2506 case Mips::BLTUImmMacro:
2507 case Mips::BLEUImmMacro:
2508 case Mips::BGEUImmMacro:
2509 case Mips::BGTUImmMacro:
2510 case Mips::BLTLImmMacro:
2511 case Mips::BLELImmMacro:
2512 case Mips::BGELImmMacro:
2513 case Mips::BGTLImmMacro:
2514 case Mips::BLTULImmMacro:
2515 case Mips::BLEULImmMacro:
2516 case Mips::BGEULImmMacro:
2517 case Mips::BGTULImmMacro:
2518 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2519 case Mips::SDivMacro:
2520 case Mips::SDivIMacro:
2521 case Mips::SRemMacro:
2522 case Mips::SRemIMacro:
2523 return expandDivRem(Inst, IDLoc, Out, STI,
false,
true) ? MER_Fail
2525 case Mips::DSDivMacro:
2526 case Mips::DSDivIMacro:
2527 case Mips::DSRemMacro:
2528 case Mips::DSRemIMacro:
2529 return expandDivRem(Inst, IDLoc, Out, STI,
true,
true) ? MER_Fail
2531 case Mips::UDivMacro:
2532 case Mips::UDivIMacro:
2533 case Mips::URemMacro:
2534 case Mips::URemIMacro:
2535 return expandDivRem(Inst, IDLoc, Out, STI,
false,
false) ? MER_Fail
2537 case Mips::DUDivMacro:
2538 case Mips::DUDivIMacro:
2539 case Mips::DURemMacro:
2540 case Mips::DURemIMacro:
2541 return expandDivRem(Inst, IDLoc, Out, STI,
true,
false) ? MER_Fail
2543 case Mips::PseudoTRUNC_W_S:
2544 return expandTrunc(Inst,
false,
false, IDLoc, Out, STI) ? MER_Fail
2546 case Mips::PseudoTRUNC_W_D32:
2547 return expandTrunc(Inst,
true,
false, IDLoc, Out, STI) ? MER_Fail
2549 case Mips::PseudoTRUNC_W_D:
2550 return expandTrunc(Inst,
true,
true, IDLoc, Out, STI) ? MER_Fail
2553 case Mips::LoadImmSingleGPR:
2554 return expandLoadSingleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2556 case Mips::LoadImmSingleFGR:
2557 return expandLoadSingleImmToFPR(Inst, IDLoc, Out, STI) ? MER_Fail
2559 case Mips::LoadImmDoubleGPR:
2560 return expandLoadDoubleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2562 case Mips::LoadImmDoubleFGR:
2563 return expandLoadDoubleImmToFPR(Inst,
true, IDLoc, Out, STI) ? MER_Fail
2565 case Mips::LoadImmDoubleFGR_32:
2566 return expandLoadDoubleImmToFPR(Inst,
false, IDLoc, Out, STI) ? MER_Fail
2570 return expandUlh(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2572 return expandUlh(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2574 return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2577 return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2579 case Mips::NORImm64:
2580 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2583 return expandSge(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2586 case Mips::SGEImm64:
2587 case Mips::SGEUImm64:
2588 return expandSgeImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2591 case Mips::SGTImm64:
2592 case Mips::SGTUImm64:
2593 return expandSgtImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2596 return expandSle(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2599 case Mips::SLEImm64:
2600 case Mips::SLEUImm64:
2601 return expandSleImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2602 case Mips::SLTImm64:
2605 return MER_NotAMacro;
2607 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2608 case Mips::SLTUImm64:
2611 return MER_NotAMacro;
2613 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2614 case Mips::ADDi:
case Mips::ADDi_MM:
2615 case Mips::ADDiu:
case Mips::ADDiu_MM:
2616 case Mips::SLTi:
case Mips::SLTi_MM:
2617 case Mips::SLTiu:
case Mips::SLTiu_MM:
2621 if (isInt<16>(ImmValue))
2622 return MER_NotAMacro;
2623 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2626 return MER_NotAMacro;
2627 case Mips::ANDi:
case Mips::ANDi_MM:
case Mips::ANDi64:
2628 case Mips::ORi:
case Mips::ORi_MM:
case Mips::ORi64:
2629 case Mips::XORi:
case Mips::XORi_MM:
case Mips::XORi64:
2633 if (isUInt<16>(ImmValue))
2634 return MER_NotAMacro;
2635 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2638 return MER_NotAMacro;
2641 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2644 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2647 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2650 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2651 case Mips::ABSMacro:
2652 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2653 case Mips::MULImmMacro:
2654 case Mips::DMULImmMacro:
2655 return expandMulImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2656 case Mips::MULOMacro:
2657 case Mips::DMULOMacro:
2658 return expandMulO(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2659 case Mips::MULOUMacro:
2660 case Mips::DMULOUMacro:
2661 return expandMulOU(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2662 case Mips::DMULMacro:
2663 return expandDMULMacro(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2666 return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2671 return expandStoreDM1Macro(Inst, IDLoc, Out, STI)
2674 case Mips::SEQMacro:
2675 return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2676 case Mips::SEQIMacro:
2677 return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2678 case Mips::SNEMacro:
2679 return expandSne(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2680 case Mips::SNEIMacro:
2681 return expandSneI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2682 case Mips::MFTC0:
case Mips::MTTC0:
2683 case Mips::MFTGPR:
case Mips::MTTGPR:
2684 case Mips::MFTLO:
case Mips::MTTLO:
2685 case Mips::MFTHI:
case Mips::MTTHI:
2686 case Mips::MFTACX:
case Mips::MTTACX:
2687 case Mips::MFTDSP:
case Mips::MTTDSP:
2688 case Mips::MFTC1:
case Mips::MTTC1:
2689 case Mips::MFTHC1:
case Mips::MTTHC1:
2690 case Mips::CFTC1:
case Mips::CTTC1:
2691 return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2693 case Mips::SaadAddr:
2694 return expandSaaAddr(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2698bool MipsAsmParser::expandJalWithRegs(
MCInst &Inst,
SMLoc IDLoc,
2707 const unsigned Opcode = Inst.
getOpcode();
2709 if (Opcode == Mips::JalOneReg) {
2711 if (IsCpRestoreSet && inMicroMipsMode()) {
2714 }
else if (inMicroMipsMode()) {
2715 JalrInst.
setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2722 }
else if (Opcode == Mips::JalTwoReg) {
2724 if (IsCpRestoreSet && inMicroMipsMode())
2727 JalrInst.
setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2759bool MipsAsmParser::loadImmediate(int64_t ImmValue,
unsigned DstReg,
2760 unsigned SrcReg,
bool Is32BitImm,
2765 if (!Is32BitImm && !isGP64bit()) {
2766 Error(IDLoc,
"instruction requires a 64-bit architecture");
2771 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2775 ImmValue = SignExtend64<32>(ImmValue);
2777 Error(IDLoc,
"instruction requires a 32-bit immediate");
2782 unsigned ZeroReg = IsAddress ?
ABI.GetNullPtr() :
ABI.GetZeroReg();
2783 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2785 bool UseSrcReg =
false;
2786 if (SrcReg != Mips::NoRegister)
2789 unsigned TmpReg = DstReg;
2791 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2794 unsigned ATReg = getATReg(IDLoc);
2800 if (isInt<16>(ImmValue)) {
2807 if (IsAddress && !Is32BitImm) {
2808 TOut.
emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2812 TOut.
emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2816 if (isUInt<16>(ImmValue)) {
2817 unsigned TmpReg = DstReg;
2818 if (SrcReg == DstReg) {
2819 TmpReg = getATReg(IDLoc);
2824 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2826 TOut.
emitRRR(
ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2830 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2831 warnIfNoMacro(IDLoc);
2833 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2834 uint16_t Bits15To0 = ImmValue & 0xffff;
2835 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2838 if (ImmValue == 0xffffffff) {
2839 TOut.
emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2840 TOut.
emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2842 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2848 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2849 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2851 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2853 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2857 TOut.
emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2859 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2861 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2865 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2867 Error(IDLoc,
"instruction requires a 32-bit immediate");
2874 assert(
BitWidth >= 17 &&
"ImmValue must be at least 17-bit wide");
2878 unsigned ShiftAmount =
BitWidth - 16;
2880 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2881 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2884 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2889 warnIfNoMacro(IDLoc);
2896 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister,
true,
false,
2902 unsigned ShiftCarriedForwards = 16;
2903 for (
int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2904 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2906 if (ImmChunk != 0) {
2907 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2908 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2909 ShiftCarriedForwards = 0;
2912 ShiftCarriedForwards += 16;
2914 ShiftCarriedForwards -= 16;
2917 if (ShiftCarriedForwards)
2918 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2921 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2926bool MipsAsmParser::expandLoadImm(
MCInst &Inst,
bool Is32BitImm,
SMLoc IDLoc,
2929 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
2931 assert(DstRegOp.
isReg() &&
"expected register operand kind");
2933 if (loadImmediate(ImmOp.
getImm(), DstRegOp.
getReg(), Mips::NoRegister,
2934 Is32BitImm,
false, IDLoc, Out, STI))
2940bool MipsAsmParser::expandLoadAddress(
unsigned DstReg,
unsigned BaseReg,
2942 bool Is32BitAddress,
SMLoc IDLoc,
2946 if (Is32BitAddress &&
ABI.ArePtrs64bit()) {
2947 Warning(IDLoc,
"la used to load 64-bit address");
2949 Is32BitAddress =
false;
2953 if (!Is32BitAddress && !hasMips3()) {
2954 Error(IDLoc,
"instruction requires a 64-bit architecture");
2959 return loadAndAddSymbolAddress(
Offset.getExpr(), DstReg, BaseReg,
2960 Is32BitAddress, IDLoc, Out, STI);
2962 if (!
ABI.ArePtrs64bit()) {
2964 Is32BitAddress =
true;
2967 return loadImmediate(
Offset.getImm(), DstReg, BaseReg, Is32BitAddress,
true,
2971bool MipsAsmParser::loadAndAddSymbolAddress(
const MCExpr *SymExpr,
2972 unsigned DstReg,
unsigned SrcReg,
2973 bool Is32BitSym,
SMLoc IDLoc,
2977 bool UseSrcReg = SrcReg != Mips::NoRegister && SrcReg != Mips::ZERO &&
2978 SrcReg != Mips::ZERO_64;
2979 warnIfNoMacro(IDLoc);
2984 Error(IDLoc,
"expected relocatable expression");
2987 if (Res.
getSymB() !=
nullptr) {
2988 Error(IDLoc,
"expected relocatable expression with only one symbol");
2992 bool IsPtr64 =
ABI.ArePtrs64bit();
3004 bool UseXGOT = STI->
hasFeature(Mips::FeatureXGOT) && !IsLocalSym;
3010 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
3014 SymExpr, getContext());
3016 SymExpr, getContext());
3019 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, DstReg, GPReg,
3021 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, DstReg,
3026 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, GPReg,
3032 unsigned TmpReg = DstReg;
3034 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
3038 unsigned ATReg = getATReg(IDLoc);
3057 const MCExpr *CallHiExpr =
3064 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg, GPReg,
3066 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, TmpReg,
3070 TOut.
emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3076 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3082 const MCExpr *LoExpr =
nullptr;
3083 if (
ABI.IsN32() ||
ABI.IsN64()) {
3102 Error(IDLoc,
"macro instruction uses large offset, which is not "
3103 "currently supported");
3133 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, GPReg,
3137 TOut.
emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3141 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3153 if (
ABI.ArePtrs64bit() && isGP64bit()) {
3168 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
3170 if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
3171 unsigned ATReg = getATReg(IDLoc);
3183 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3185 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3188 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3191 TOut.
emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
3194 }
else if (canUseATReg() && !RdRegIsRsReg && DstReg != getATReg(IDLoc)) {
3195 unsigned ATReg = getATReg(IDLoc);
3211 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3215 TOut.
emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3216 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3218 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3221 }
else if ((!canUseATReg() && !RdRegIsRsReg) ||
3222 (canUseATReg() && DstReg == getATReg(IDLoc))) {
3233 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3235 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3236 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3238 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3239 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3242 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3248 assert(SrcReg == DstReg && !canUseATReg() &&
3249 "Could have expanded dla but didn't?");
3250 reportParseError(IDLoc,
3251 "pseudo-instruction requires $at, which is not available");
3265 unsigned TmpReg = DstReg;
3267 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
3270 unsigned ATReg = getATReg(IDLoc);
3281 TOut.
emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3284 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
3293 if (MipsMCRegisterClasses[Mips::FGR32RegClassID].
contains(
Reg))
3294 return Reg == (
unsigned)Mips::F31 ? (
unsigned)Mips::F0 :
Reg + 1;
3296 default:
llvm_unreachable(
"Unknown register in assembly macro expansion!");
3297 case Mips::ZERO:
return Mips::AT;
3298 case Mips::AT:
return Mips::V0;
3299 case Mips::V0:
return Mips::V1;
3300 case Mips::V1:
return Mips::A0;
3301 case Mips::A0:
return Mips::A1;
3302 case Mips::A1:
return Mips::A2;
3303 case Mips::A2:
return Mips::A3;
3304 case Mips::A3:
return Mips::T0;
3305 case Mips::T0:
return Mips::T1;
3306 case Mips::T1:
return Mips::T2;
3307 case Mips::T2:
return Mips::T3;
3308 case Mips::T3:
return Mips::T4;
3309 case Mips::T4:
return Mips::T5;
3310 case Mips::T5:
return Mips::T6;
3311 case Mips::T6:
return Mips::T7;
3312 case Mips::T7:
return Mips::S0;
3313 case Mips::S0:
return Mips::S1;
3314 case Mips::S1:
return Mips::S2;
3315 case Mips::S2:
return Mips::S3;
3316 case Mips::S3:
return Mips::S4;
3317 case Mips::S4:
return Mips::S5;
3318 case Mips::S5:
return Mips::S6;
3319 case Mips::S6:
return Mips::S7;
3320 case Mips::S7:
return Mips::T8;
3321 case Mips::T8:
return Mips::T9;
3322 case Mips::T9:
return Mips::K0;
3323 case Mips::K0:
return Mips::K1;
3324 case Mips::K1:
return Mips::GP;
3325 case Mips::GP:
return Mips::SP;
3326 case Mips::SP:
return Mips::FP;
3327 case Mips::FP:
return Mips::RA;
3328 case Mips::RA:
return Mips::ZERO;
3329 case Mips::D0:
return Mips::F1;
3330 case Mips::D1:
return Mips::F3;
3331 case Mips::D2:
return Mips::F5;
3332 case Mips::D3:
return Mips::F7;
3333 case Mips::D4:
return Mips::F9;
3334 case Mips::D5:
return Mips::F11;
3335 case Mips::D6:
return Mips::F13;
3336 case Mips::D7:
return Mips::F15;
3337 case Mips::D8:
return Mips::F17;
3338 case Mips::D9:
return Mips::F19;
3339 case Mips::D10:
return Mips::F21;
3340 case Mips::D11:
return Mips::F23;
3341 case Mips::D12:
return Mips::F25;
3342 case Mips::D13:
return Mips::F27;
3343 case Mips::D14:
return Mips::F29;
3344 case Mips::D15:
return Mips::F31;
3356 unsigned ATReg = getATReg(IDLoc);
3366 if(isABI_O32() || isABI_N32()) {
3385 if(isABI_O32() || isABI_N32()) {
3388 const MCExpr *HighestSym =
3392 const MCExpr *HigherSym =
3399 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3401 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3404 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3413 if ((
Hi_32(ImmOp64) & 0x7ff00000) == 0) {
3414 APFloat RealVal(APFloat::IEEEdouble(), ImmOp64);
3423 double DoubleImm = llvm::bit_cast<double>(ImmOp64);
3424 float TmpFloat =
static_cast<float>(DoubleImm);
3425 return llvm::bit_cast<uint32_t>(TmpFloat);
3428bool MipsAsmParser::expandLoadSingleImmToGPR(
MCInst &Inst,
SMLoc IDLoc,
3433 "Invalid instruction operand.");
3440 return loadImmediate(ImmOp32, FirstReg, Mips::NoRegister,
true,
false, IDLoc,
3444bool MipsAsmParser::expandLoadSingleImmToFPR(
MCInst &Inst,
SMLoc IDLoc,
3450 "Invalid instruction operand.");
3459 unsigned TmpReg = Mips::ZERO;
3461 TmpReg = getATReg(IDLoc);
3466 if (
Lo_32(ImmOp64) == 0) {
3467 if (TmpReg != Mips::ZERO && loadImmediate(ImmOp32, TmpReg, Mips::NoRegister,
3468 true,
false, IDLoc, Out, STI))
3470 TOut.
emitRR(Mips::MTC1, FirstReg, TmpReg, IDLoc, STI);
3474 MCSection *CS = getStreamer().getCurrentSectionOnly();
3486 getStreamer().switchSection(ReadOnlySection);
3487 getStreamer().emitLabel(
Sym, IDLoc);
3488 getStreamer().emitInt32(ImmOp32);
3489 getStreamer().switchSection(CS);
3491 if (emitPartialAddress(TOut, IDLoc,
Sym))
3498bool MipsAsmParser::expandLoadDoubleImmToGPR(
MCInst &Inst,
SMLoc IDLoc,
3504 "Invalid instruction operand.");
3511 if (
Lo_32(ImmOp64) == 0) {
3513 if (loadImmediate(ImmOp64, FirstReg, Mips::NoRegister,
false,
false,
3517 if (loadImmediate(
Hi_32(ImmOp64), FirstReg, Mips::NoRegister,
true,
false,
3521 if (loadImmediate(0,
nextReg(FirstReg), Mips::NoRegister,
true,
false,
3528 MCSection *CS = getStreamer().getCurrentSectionOnly();
3538 getStreamer().switchSection(ReadOnlySection);
3539 getStreamer().emitLabel(
Sym, IDLoc);
3540 getStreamer().emitValueToAlignment(
Align(8));
3541 getStreamer().emitIntValue(ImmOp64, 8);
3542 getStreamer().switchSection(CS);
3544 unsigned TmpReg = getATReg(IDLoc);
3548 if (emitPartialAddress(TOut, IDLoc,
Sym))
3551 TOut.
emitRRX(isABI_N64() ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3555 TOut.
emitRRI(Mips::LD, FirstReg, TmpReg, 0, IDLoc, STI);
3557 TOut.
emitRRI(Mips::LW, FirstReg, TmpReg, 0, IDLoc, STI);
3558 TOut.
emitRRI(Mips::LW,
nextReg(FirstReg), TmpReg, 4, IDLoc, STI);
3563bool MipsAsmParser::expandLoadDoubleImmToFPR(
MCInst &Inst,
bool Is64FPU,
3569 "Invalid instruction operand.");
3576 unsigned TmpReg = Mips::ZERO;
3578 TmpReg = getATReg(IDLoc);
3583 if ((
Lo_32(ImmOp64) == 0) &&
3584 !((
Hi_32(ImmOp64) & 0xffff0000) && (
Hi_32(ImmOp64) & 0x0000ffff))) {
3586 if (TmpReg != Mips::ZERO &&
3587 loadImmediate(ImmOp64, TmpReg, Mips::NoRegister,
false,
false, IDLoc,
3590 TOut.
emitRR(Mips::DMTC1, FirstReg, TmpReg, IDLoc, STI);
3594 if (TmpReg != Mips::ZERO &&
3595 loadImmediate(
Hi_32(ImmOp64), TmpReg, Mips::NoRegister,
true,
false,
3599 if (hasMips32r2()) {
3600 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3601 TOut.
emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, TmpReg, IDLoc, STI);
3603 TOut.
emitRR(Mips::MTC1,
nextReg(FirstReg), TmpReg, IDLoc, STI);
3604 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3609 MCSection *CS = getStreamer().getCurrentSectionOnly();
3621 getStreamer().switchSection(ReadOnlySection);
3622 getStreamer().emitLabel(
Sym, IDLoc);
3623 getStreamer().emitValueToAlignment(
Align(8));
3624 getStreamer().emitIntValue(ImmOp64, 8);
3625 getStreamer().switchSection(CS);
3627 if (emitPartialAddress(TOut, IDLoc,
Sym))
3630 TOut.
emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, TmpReg,
3636bool MipsAsmParser::expandUncondBranchMMPseudo(
MCInst &Inst,
SMLoc IDLoc,
3642 "unexpected number of operands");
3652 assert(
Offset.isImm() &&
"expected immediate operand kind");
3653 if (isInt<11>(
Offset.getImm())) {
3656 if (inMicroMipsMode())
3657 Inst.
setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3659 if (!isInt<17>(
Offset.getImm()))
3660 return Error(IDLoc,
"branch target out of range");
3662 return Error(IDLoc,
"branch to misaligned address");
3685 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3688 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
3692 "expected immediate or expression operand");
3694 bool IsLikely =
false;
3704 case Mips::BEQLImmMacro:
3708 case Mips::BNELImmMacro:
3717 int64_t ImmValue = ImmOp.
getImm();
3718 if (ImmValue == 0) {
3722 TOut.
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3724 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3727 warnIfNoMacro(IDLoc);
3729 unsigned ATReg = getATReg(IDLoc);
3733 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(),
true,
3740 TOut.
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3742 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3750 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3751 unsigned StartOp = NumOp == 3 ? 0 : 1;
3754 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3756 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3761 unsigned DstReg = DstRegOp.
getReg();
3762 unsigned BaseReg = BaseRegOp.
getReg();
3763 unsigned TmpReg = DstReg;
3766 int16_t DstRegClass =
Desc.operands()[StartOp].RegClass;
3767 unsigned DstRegClassID =
3768 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3769 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3770 (DstRegClassID == Mips::GPR64RegClassID);
3772 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3775 TmpReg = getATReg(IDLoc);
3782 TOut.
emitRRX(OpCode, DstReg, TmpReg, Off, IDLoc, STI);
3784 TOut.
emitRRRX(OpCode, DstReg, DstReg, TmpReg, Off, IDLoc, STI);
3787 if (OffsetOp.
isImm()) {
3788 int64_t LoOffset = OffsetOp.
getImm() & 0xffff;
3789 int64_t HiOffset = OffsetOp.
getImm() & ~0xffff;
3793 if (LoOffset & 0x8000)
3794 HiOffset += 0x10000;
3796 bool IsLargeOffset = HiOffset != 0;
3798 if (IsLargeOffset) {
3799 bool Is32BitImm = isInt<32>(OffsetOp.
getImm());
3800 if (loadImmediate(HiOffset, TmpReg, Mips::NoRegister, Is32BitImm,
true,
3805 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3806 TOut.
emitRRR(
ABI.ArePtrs64bit() ? Mips::DADDu : Mips::ADDu, TmpReg,
3807 TmpReg, BaseReg, IDLoc, STI);
3822 Error(IDLoc,
"expected relocatable expression");
3825 if (Res.
getSymB() !=
nullptr) {
3826 Error(IDLoc,
"expected relocatable expression with only one symbol");
3830 loadAndAddSymbolAddress(Res.
getSymA(), TmpReg, BaseReg,
3831 !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3851 TOut.
emitRX(Mips::LUi, TmpReg, HighestOperand, IDLoc, STI);
3852 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HigherOperand, IDLoc, STI);
3853 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3854 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HiOperand, IDLoc, STI);
3855 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3856 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3857 TOut.
emitRRR(Mips::DADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3858 emitInstWithOffset(LoOperand);
3861 TOut.
emitRX(Mips::LUi, TmpReg, HiOperand, IDLoc, STI);
3862 if (BaseReg != Mips::ZERO)
3863 TOut.
emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3865 emitInstWithOffset(LoOperand);
3877 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3878 unsigned StartOp = NumOp == 3 ? 0 : 1;
3881 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3883 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3888 unsigned DstReg = DstRegOp.
getReg();
3889 unsigned BaseReg = BaseRegOp.
getReg();
3890 unsigned TmpReg = DstReg;
3893 int16_t DstRegClass =
Desc.operands()[StartOp].RegClass;
3894 unsigned DstRegClassID =
3895 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3896 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3897 (DstRegClassID == Mips::GPR64RegClassID);
3899 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3902 TmpReg = getATReg(IDLoc);
3907 auto emitInst = [&]() {
3915 if (OffsetOp.
isImm()) {
3916 loadImmediate(OffsetOp.
getImm(), TmpReg, BaseReg, !
ABI.ArePtrs64bit(),
true,
3923 loadAndAddSymbolAddress(OffsetOp.
getExpr(), TmpReg, BaseReg,
3924 !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3932bool MipsAsmParser::expandLoadStoreMultiple(
MCInst &Inst,
SMLoc IDLoc,
3937 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3941 Inst.
getOperand(OpNum - 3).
isReg() &&
"Invalid instruction operand.");
3950 if (inMicroMipsMode() && hasMips32r6())
3951 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3953 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3961bool MipsAsmParser::expandCondBranches(
MCInst &Inst,
SMLoc IDLoc,
3965 bool EmittedNoMacroWarning =
false;
3966 unsigned PseudoOpcode = Inst.
getOpcode();
3971 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3972 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3977 else if (TrgOp.
isImm()) {
3978 warnIfNoMacro(IDLoc);
3979 EmittedNoMacroWarning =
true;
3981 TrgReg = getATReg(IDLoc);
3985 switch(PseudoOpcode) {
3988 case Mips::BLTImmMacro:
3989 PseudoOpcode = Mips::BLT;
3991 case Mips::BLEImmMacro:
3992 PseudoOpcode = Mips::BLE;
3994 case Mips::BGEImmMacro:
3995 PseudoOpcode = Mips::BGE;
3997 case Mips::BGTImmMacro:
3998 PseudoOpcode = Mips::BGT;
4000 case Mips::BLTUImmMacro:
4001 PseudoOpcode = Mips::BLTU;
4003 case Mips::BLEUImmMacro:
4004 PseudoOpcode = Mips::BLEU;
4006 case Mips::BGEUImmMacro:
4007 PseudoOpcode = Mips::BGEU;
4009 case Mips::BGTUImmMacro:
4010 PseudoOpcode = Mips::BGTU;
4012 case Mips::BLTLImmMacro:
4013 PseudoOpcode = Mips::BLTL;
4015 case Mips::BLELImmMacro:
4016 PseudoOpcode = Mips::BLEL;
4018 case Mips::BGELImmMacro:
4019 PseudoOpcode = Mips::BGEL;
4021 case Mips::BGTLImmMacro:
4022 PseudoOpcode = Mips::BGTL;
4024 case Mips::BLTULImmMacro:
4025 PseudoOpcode = Mips::BLTUL;
4027 case Mips::BLEULImmMacro:
4028 PseudoOpcode = Mips::BLEUL;
4030 case Mips::BGEULImmMacro:
4031 PseudoOpcode = Mips::BGEUL;
4033 case Mips::BGTULImmMacro:
4034 PseudoOpcode = Mips::BGTUL;
4038 if (loadImmediate(TrgOp.
getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
4039 false, IDLoc, Out, STI))
4043 switch (PseudoOpcode) {
4048 AcceptsEquality =
false;
4049 ReverseOrderSLT =
false;
4051 ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
4052 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
4053 ZeroSrcOpcode = Mips::BGTZ;
4054 ZeroTrgOpcode = Mips::BLTZ;
4060 AcceptsEquality =
true;
4061 ReverseOrderSLT =
true;
4063 ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
4064 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
4065 ZeroSrcOpcode = Mips::BGEZ;
4066 ZeroTrgOpcode = Mips::BLEZ;
4072 AcceptsEquality =
true;
4073 ReverseOrderSLT =
false;
4075 ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
4076 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
4077 ZeroSrcOpcode = Mips::BLEZ;
4078 ZeroTrgOpcode = Mips::BGEZ;
4084 AcceptsEquality =
false;
4085 ReverseOrderSLT =
true;
4087 ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
4088 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
4089 ZeroSrcOpcode = Mips::BLTZ;
4090 ZeroTrgOpcode = Mips::BGTZ;
4096 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
4097 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
4098 if (IsSrcRegZero && IsTrgRegZero) {
4102 if (PseudoOpcode == Mips::BLT) {
4107 if (PseudoOpcode == Mips::BLE) {
4110 Warning(IDLoc,
"branch is always taken");
4113 if (PseudoOpcode == Mips::BGE) {
4116 Warning(IDLoc,
"branch is always taken");
4119 if (PseudoOpcode == Mips::BGT) {
4124 if (PseudoOpcode == Mips::BGTU) {
4125 TOut.
emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
4129 if (AcceptsEquality) {
4132 TOut.
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4134 Warning(IDLoc,
"branch is always taken");
4141 if (IsSrcRegZero || IsTrgRegZero) {
4142 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
4143 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
4150 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
4151 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
4157 TOut.
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4159 Warning(IDLoc,
"branch is always taken");
4175 TOut.
emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
4176 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
4183 TOut.
emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
4184 IsSrcRegZero ? TrgReg : SrcReg,
4191 unsigned ATRegNum = getATReg(IDLoc);
4195 if (!EmittedNoMacroWarning)
4196 warnIfNoMacro(IDLoc);
4213 TOut.
emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
4214 ReverseOrderSLT ? TrgReg : SrcReg,
4215 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
4217 TOut.
emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
4218 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
4234 const bool IsMips64,
const bool Signed) {
4237 warnIfNoMacro(IDLoc);
4240 assert(RdRegOp.
isReg() &&
"expected register operand kind");
4241 unsigned RdReg = RdRegOp.
getReg();
4244 assert(RsRegOp.
isReg() &&
"expected register operand kind");
4245 unsigned RsReg = RsRegOp.
getReg();
4252 "expected register or immediate operand kind");
4256 ImmValue = RtOp.
getImm();
4263 DivOp =
Signed ? Mips::DSDIV : Mips::DUDIV;
4264 ZeroReg = Mips::ZERO_64;
4267 DivOp =
Signed ? Mips::SDIV : Mips::UDIV;
4268 ZeroReg = Mips::ZERO;
4272 bool UseTraps = useTraps();
4275 bool isDiv = Opcode == Mips::SDivMacro || Opcode == Mips::SDivIMacro ||
4276 Opcode == Mips::UDivMacro || Opcode == Mips::UDivIMacro ||
4277 Opcode == Mips::DSDivMacro || Opcode == Mips::DSDivIMacro ||
4278 Opcode == Mips::DUDivMacro || Opcode == Mips::DUDivIMacro;
4280 bool isRem = Opcode == Mips::SRemMacro || Opcode == Mips::SRemIMacro ||
4281 Opcode == Mips::URemMacro || Opcode == Mips::URemIMacro ||
4282 Opcode == Mips::DSRemMacro || Opcode == Mips::DSRemIMacro ||
4283 Opcode == Mips::DURemMacro || Opcode == Mips::DURemIMacro;
4286 unsigned ATReg = getATReg(IDLoc);
4290 if (ImmValue == 0) {
4292 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4294 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4298 if (isRem && (ImmValue == 1 || (
Signed && (ImmValue == -1)))) {
4299 TOut.
emitRRR(Mips::OR, RdReg, ZeroReg, ZeroReg, IDLoc, STI);
4301 }
else if (isDiv && ImmValue == 1) {
4302 TOut.
emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI);
4304 }
else if (isDiv &&
Signed && ImmValue == -1) {
4305 TOut.
emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
4308 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, isInt<32>(ImmValue),
4309 false, Inst.
getLoc(), Out, STI))
4311 TOut.
emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
4312 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4322 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
4324 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4327 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4333 if (isRem && (RdReg == Mips::ZERO || RdReg == Mips::ZERO_64)) {
4334 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4344 TOut.
emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4349 TOut.
emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4352 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4355 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4361 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4365 unsigned ATReg = getATReg(IDLoc);
4372 TOut.
emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
4380 TOut.
emitRRX(Mips::BNE, RtReg, ATReg, LabelOpEnd, IDLoc, STI);
4383 TOut.
emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
4384 TOut.
emitDSLL(ATReg, ATReg, 63, IDLoc, STI);
4390 TOut.
emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
4393 TOut.
emitRRX(Mips::BNE, RsReg, ATReg, LabelOpEnd, IDLoc, STI);
4395 TOut.
emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
4399 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4403bool MipsAsmParser::expandTrunc(
MCInst &Inst,
bool IsDouble,
bool Is64FPU,
4416 if (hasMips1() && !hasMips2()) {
4417 unsigned ATReg = getATReg(IDLoc);
4420 TOut.
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4421 TOut.
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4423 TOut.
emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4424 TOut.
emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4425 TOut.
emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4427 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4429 FirstReg, SecondReg, IDLoc, STI);
4430 TOut.
emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4435 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4437 FirstReg, SecondReg, IDLoc, STI);
4444 if (hasMips32r6() || hasMips64r6()) {
4445 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4449 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4451 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4453 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4456 unsigned DstReg = DstRegOp.
getReg();
4457 unsigned SrcReg = SrcRegOp.
getReg();
4458 int64_t OffsetValue = OffsetImmOp.
getImm();
4462 warnIfNoMacro(IDLoc);
4463 unsigned ATReg = getATReg(IDLoc);
4467 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4468 if (IsLargeOffset) {
4469 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4474 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4475 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4479 unsigned FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4480 unsigned SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4482 unsigned LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4483 unsigned SllReg = IsLargeOffset ? DstReg : ATReg;
4485 TOut.
emitRRI(
Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4486 FirstOffset, IDLoc, STI);
4487 TOut.
emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4488 TOut.
emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4489 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4496 if (hasMips32r6() || hasMips64r6()) {
4497 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4501 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4503 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4505 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4508 unsigned DstReg = DstRegOp.
getReg();
4509 unsigned SrcReg = SrcRegOp.
getReg();
4510 int64_t OffsetValue = OffsetImmOp.
getImm();
4512 warnIfNoMacro(IDLoc);
4513 unsigned ATReg = getATReg(IDLoc);
4517 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4518 if (IsLargeOffset) {
4519 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4524 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4525 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4529 if (IsLargeOffset) {
4530 TOut.
emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4531 TOut.
emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4532 TOut.
emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4533 TOut.
emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4534 TOut.
emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4535 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4537 TOut.
emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4538 TOut.
emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4539 TOut.
emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4547 if (hasMips32r6() || hasMips64r6()) {
4548 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4552 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4554 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4556 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4559 unsigned DstReg = DstRegOp.
getReg();
4560 unsigned SrcReg = SrcRegOp.
getReg();
4561 int64_t OffsetValue = OffsetImmOp.
getImm();
4564 bool IsLargeOffset = !(isInt<16>(OffsetValue + 3) && isInt<16>(OffsetValue));
4565 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4566 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4570 bool IsLoadInst = (Inst.
getOpcode() == Mips::Ulw);
4571 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4572 unsigned TmpReg = SrcReg;
4573 if (IsLargeOffset || DoMove) {
4574 warnIfNoMacro(IDLoc);
4575 TmpReg = getATReg(IDLoc);
4580 if (IsLargeOffset) {
4581 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4589 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4590 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4591 TOut.
emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4592 TOut.
emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4595 TOut.
emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4614 warnIfNoMacro(IDLoc);
4628 TOut.
emitRRR(OpCode, DstReg, SrcReg, OpReg, IDLoc, STI);
4629 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4646 unsigned OpRegCode, OpImmCode;
4648 warnIfNoMacro(IDLoc);
4652 case Mips::SGEImm64:
4653 OpRegCode = Mips::SLT;
4654 OpImmCode = Mips::SLTi;
4657 case Mips::SGEUImm64:
4658 OpRegCode = Mips::SLTu;
4659 OpImmCode = Mips::SLTiu;
4666 if (isInt<16>(ImmValue)) {
4668 TOut.
emitRRI(OpImmCode, DstReg, SrcReg, ImmValue, IDLoc, STI);
4669 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4671 unsigned ImmReg = DstReg;
4672 if (DstReg == SrcReg) {
4673 unsigned ATReg = getATReg(Inst.
getLoc());
4679 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4680 false, IDLoc, Out, STI))
4683 TOut.
emitRRR(OpRegCode, DstReg, SrcReg, ImmReg, IDLoc, STI);
4684 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4701 unsigned ImmReg = DstReg;
4705 warnIfNoMacro(IDLoc);
4709 case Mips::SGTImm64:
4713 case Mips::SGTUImm64:
4720 if (DstReg == SrcReg) {
4721 unsigned ATReg = getATReg(Inst.
getLoc());
4727 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4728 false, IDLoc, Out, STI))
4732 TOut.
emitRRR(OpCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4751 warnIfNoMacro(IDLoc);
4765 TOut.
emitRRR(OpCode, DstReg, OpReg, SrcReg, IDLoc, STI);
4766 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4785 warnIfNoMacro(IDLoc);
4789 case Mips::SLEImm64:
4790 OpRegCode = Mips::SLT;
4793 case Mips::SLEUImm64:
4794 OpRegCode = Mips::SLTu;
4801 unsigned ImmReg = DstReg;
4802 if (DstReg == SrcReg) {
4803 unsigned ATReg = getATReg(Inst.
getLoc());
4809 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4810 false, IDLoc, Out, STI))
4813 TOut.
emitRRR(OpRegCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4814 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4819bool MipsAsmParser::expandAliasImmediate(
MCInst &Inst,
SMLoc IDLoc,
4829 unsigned ATReg = Mips::NoRegister;
4830 unsigned FinalDstReg = Mips::NoRegister;
4835 bool Is32Bit = isInt<32>(ImmValue) || (!isGP64bit() && isUInt<32>(ImmValue));
4837 unsigned FinalOpcode = Inst.
getOpcode();
4839 if (DstReg == SrcReg) {
4840 ATReg = getATReg(Inst.
getLoc());
4843 FinalDstReg = DstReg;
4847 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit,
false,
4848 Inst.
getLoc(), Out, STI)) {
4849 switch (FinalOpcode) {
4853 FinalOpcode = Mips::ADD;
4856 FinalOpcode = Mips::ADDu;
4859 FinalOpcode = Mips::AND;
4862 FinalOpcode = Mips::NOR;
4865 FinalOpcode = Mips::OR;
4868 FinalOpcode = Mips::SLT;
4871 FinalOpcode = Mips::SLTu;
4874 FinalOpcode = Mips::XOR;
4877 FinalOpcode = Mips::ADD_MM;
4879 case Mips::ADDiu_MM:
4880 FinalOpcode = Mips::ADDu_MM;
4883 FinalOpcode = Mips::AND_MM;
4886 FinalOpcode = Mips::OR_MM;
4889 FinalOpcode = Mips::SLT_MM;
4891 case Mips::SLTiu_MM:
4892 FinalOpcode = Mips::SLTu_MM;
4895 FinalOpcode = Mips::XOR_MM;
4898 FinalOpcode = Mips::AND64;
4900 case Mips::NORImm64:
4901 FinalOpcode = Mips::NOR64;
4904 FinalOpcode = Mips::OR64;
4906 case Mips::SLTImm64:
4907 FinalOpcode = Mips::SLT64;
4909 case Mips::SLTUImm64:
4910 FinalOpcode = Mips::SLTu64;
4913 FinalOpcode = Mips::XOR64;
4917 if (FinalDstReg == Mips::NoRegister)
4918 TOut.
emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4920 TOut.
emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4929 unsigned ATReg = Mips::NoRegister;
4933 unsigned TmpReg =
DReg;
4935 unsigned FirstShift = Mips::NOP;
4936 unsigned SecondShift = Mips::NOP;
4938 if (hasMips32r2()) {
4940 TmpReg = getATReg(Inst.
getLoc());
4946 TOut.
emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4947 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
4952 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
4964 FirstShift = Mips::SRLV;
4965 SecondShift = Mips::SLLV;
4968 FirstShift = Mips::SLLV;
4969 SecondShift = Mips::SRLV;
4973 ATReg = getATReg(Inst.
getLoc());
4977 TOut.
emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4978 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
4979 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
4980 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
4988bool MipsAsmParser::expandRotationImm(
MCInst &Inst,
SMLoc IDLoc,
4992 unsigned ATReg = Mips::NoRegister;
4997 unsigned FirstShift = Mips::NOP;
4998 unsigned SecondShift = Mips::NOP;
5000 if (hasMips32r2()) {
5005 ShiftValue = MaxShift - ImmValue;
5006 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
5011 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.
getLoc(), STI);
5019 if (ImmValue == 0) {
5028 FirstShift = Mips::SLL;
5029 SecondShift = Mips::SRL;
5032 FirstShift = Mips::SRL;
5033 SecondShift = Mips::SLL;
5037 ATReg = getATReg(Inst.
getLoc());
5041 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.
getLoc(), STI);
5042 TOut.
emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.
getLoc(), STI);
5043 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5054 unsigned ATReg = Mips::NoRegister;
5058 unsigned TmpReg =
DReg;
5060 unsigned FirstShift = Mips::NOP;
5061 unsigned SecondShift = Mips::NOP;
5063 if (hasMips64r2()) {
5064 if (TmpReg == SReg) {
5065 TmpReg = getATReg(Inst.
getLoc());
5071 TOut.
emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
5072 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
5077 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
5089 FirstShift = Mips::DSRLV;
5090 SecondShift = Mips::DSLLV;
5093 FirstShift = Mips::DSLLV;
5094 SecondShift = Mips::DSRLV;
5098 ATReg = getATReg(Inst.
getLoc());
5102 TOut.
emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
5103 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
5104 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
5105 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5113bool MipsAsmParser::expandDRotationImm(
MCInst &Inst,
SMLoc IDLoc,
5117 unsigned ATReg = Mips::NoRegister;
5122 unsigned FirstShift = Mips::NOP;
5123 unsigned SecondShift = Mips::NOP;
5127 if (hasMips64r2()) {
5128 unsigned FinalOpcode = Mips::NOP;
5130 FinalOpcode = Mips::DROTR;
5131 else if (ImmValue % 32 == 0)
5132 FinalOpcode = Mips::DROTR32;
5133 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
5135 FinalOpcode = Mips::DROTR32;
5137 FinalOpcode = Mips::DROTR;
5138 }
else if (ImmValue >= 33) {
5140 FinalOpcode = Mips::DROTR;
5142 FinalOpcode = Mips::DROTR32;
5145 uint64_t ShiftValue = ImmValue % 32;
5147 ShiftValue = (32 - ImmValue % 32) % 32;
5149 TOut.
emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
5155 if (ImmValue == 0) {
5156 TOut.
emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.
getLoc(), STI);
5164 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5165 FirstShift = Mips::DSLL;
5166 SecondShift = Mips::DSRL32;
5168 if (ImmValue == 32) {
5169 FirstShift = Mips::DSLL32;
5170 SecondShift = Mips::DSRL32;
5172 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5173 FirstShift = Mips::DSLL32;
5174 SecondShift = Mips::DSRL;
5178 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5179 FirstShift = Mips::DSRL;
5180 SecondShift = Mips::DSLL32;
5182 if (ImmValue == 32) {
5183 FirstShift = Mips::DSRL32;
5184 SecondShift = Mips::DSLL32;
5186 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5187 FirstShift = Mips::DSRL32;
5188 SecondShift = Mips::DSLL;
5193 ATReg = getATReg(Inst.
getLoc());
5197 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.
getLoc(), STI);
5198 TOut.
emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
5200 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5214 TOut.
emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
5215 if (FirstRegOp != SecondRegOp)
5216 TOut.
emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
5219 TOut.
emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
5227 unsigned ATReg = Mips::NoRegister;
5232 ATReg = getATReg(IDLoc);
5236 loadImmediate(ImmValue, ATReg, Mips::NoRegister,
true,
false, IDLoc, Out,
5239 TOut.
emitRR(Inst.
getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
5240 SrcReg, ATReg, IDLoc, STI);
5242 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);