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");
155 unsigned CpSaveLocation;
157 bool CpSaveLocationIsRegister;
163 void printWarningWithFixIt(
const Twine &Msg,
const Twine &FixMsg,
164 SMRange Range,
bool ShowColors =
true);
168#define GET_ASSEMBLER_HEADER
169#include "MipsGenAsmMatcher.inc"
179 bool MatchingInlineAsm)
override;
183 SMLoc &EndLoc)
override;
185 SMLoc &EndLoc)
override;
191 bool mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID);
217 enum MacroExpanderResultTy {
224 MacroExpanderResultTy tryExpandInstruction(
MCInst &Inst,
SMLoc IDLoc,
231 bool loadImmediate(int64_t ImmValue,
unsigned DstReg,
unsigned SrcReg,
232 bool Is32BitImm,
bool IsAddress,
SMLoc IDLoc,
235 bool loadAndAddSymbolAddress(
const MCExpr *SymExpr,
unsigned DstReg,
236 unsigned SrcReg,
bool Is32BitSym,
SMLoc IDLoc,
241 bool expandLoadImm(
MCInst &Inst,
bool Is32BitImm,
SMLoc IDLoc,
250 bool expandLoadDoubleImmToFPR(
MCInst &Inst,
bool Is64FPU,
SMLoc IDLoc,
253 bool expandLoadAddress(
unsigned DstReg,
unsigned BaseReg,
282 bool expandTrunc(
MCInst &Inst,
bool IsDouble,
bool Is64FPU,
SMLoc IDLoc,
357 bool reportParseError(
const Twine &ErrorMsg);
358 bool reportParseError(
SMLoc Loc,
const Twine &ErrorMsg);
360 bool parseMemOffset(
const MCExpr *&Res,
bool isParenExpr);
362 bool parseSetMips0Directive();
363 bool parseSetArchDirective();
364 bool parseSetFeature(
uint64_t Feature);
365 bool isPicAndNotNxxAbi();
366 bool parseDirectiveCpAdd(
SMLoc Loc);
367 bool parseDirectiveCpLoad(
SMLoc Loc);
368 bool parseDirectiveCpLocal(
SMLoc Loc);
369 bool parseDirectiveCpRestore(
SMLoc Loc);
370 bool parseDirectiveCPSetup();
371 bool parseDirectiveCPReturn();
372 bool parseDirectiveNaN();
373 bool parseDirectiveSet();
374 bool parseDirectiveOption();
375 bool parseInsnDirective();
376 bool parseRSectionDirective(
StringRef Section);
377 bool parseSSectionDirective(
StringRef Section,
unsigned Type);
379 bool parseSetAtDirective();
380 bool parseSetNoAtDirective();
381 bool parseSetMacroDirective();
382 bool parseSetNoMacroDirective();
383 bool parseSetMsaDirective();
384 bool parseSetNoMsaDirective();
385 bool parseSetNoDspDirective();
386 bool parseSetNoMips3DDirective();
387 bool parseSetReorderDirective();
388 bool parseSetNoReorderDirective();
389 bool parseSetMips16Directive();
390 bool parseSetNoMips16Directive();
391 bool parseSetFpDirective();
392 bool parseSetOddSPRegDirective();
393 bool parseSetNoOddSPRegDirective();
394 bool parseSetPopDirective();
395 bool parseSetPushDirective();
396 bool parseSetSoftFloatDirective();
397 bool parseSetHardFloatDirective();
398 bool parseSetMtDirective();
399 bool parseSetNoMtDirective();
400 bool parseSetNoCRCDirective();
401 bool parseSetNoVirtDirective();
402 bool parseSetNoGINVDirective();
404 bool parseSetAssignment();
406 bool parseDirectiveGpWord();
407 bool parseDirectiveGpDWord();
408 bool parseDirectiveDtpRelWord();
409 bool parseDirectiveDtpRelDWord();
410 bool parseDirectiveTpRelWord();
411 bool parseDirectiveTpRelDWord();
412 bool parseDirectiveModule();
413 bool parseDirectiveModuleFP();
417 bool parseInternalDirectiveReallowModule();
421 int matchCPURegisterName(
StringRef Symbol);
423 int matchHWRegsRegisterName(
StringRef Symbol);
435 unsigned getReg(
int RC,
int RegNo);
440 unsigned getATReg(
SMLoc Loc);
450 bool validateMSAIndex(
int Val,
int RegKind);
477 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
485 if (!(
getSTI().hasFeature(Feature))) {
494 if (
getSTI().hasFeature(Feature)) {
503 setFeatureBits(Feature, FeatureString);
504 AssemblerOptions.
front()->setFeatures(
getSTI().getFeatureBits());
508 clearFeatureBits(Feature, FeatureString);
509 AssemblerOptions.
front()->setFeatures(
getSTI().getFeatureBits());
513 enum MipsMatchResultTy {
515 Match_RequiresDifferentOperands,
516 Match_RequiresNoZeroRegister,
517 Match_RequiresSameSrcAndDst,
518 Match_NoFCCRegisterForCurrentISA,
519 Match_NonZeroOperandForSync,
520 Match_NonZeroOperandForMTCX,
521 Match_RequiresPosSizeRange0_32,
522 Match_RequiresPosSizeRange33_64,
523 Match_RequiresPosSizeUImm6,
524#define GET_OPERAND_DIAGNOSTIC_TYPES
525#include "MipsGenAsmMatcher.inc"
526#undef GET_OPERAND_DIAGNOSTIC_TYPES
546 std::make_unique<MipsAssemblerOptions>(
getSTI().getFeatureBits()));
550 std::make_unique<MipsAssemblerOptions>(
getSTI().getFeatureBits()));
552 getTargetStreamer().updateABIInfo(*
this);
554 if (!isABI_O32() && !useOddSPReg() != 0)
561 IsCpRestoreSet =
false;
562 CpRestoreOffset = -1;
563 GPReg =
ABI.GetGlobalPtr();
568 if (
getSTI().
getCPU() ==
"mips64r6" && inMicroMipsMode())
571 if (!isABI_O32() && inMicroMipsMode())
576 bool hasEightFccRegisters()
const {
return hasMips4() || hasMips32(); }
578 bool isGP64bit()
const {
582 bool isFP64bit()
const {
586 bool isJalrRelocAvailable(
const MCExpr *JalExpr) {
595 return ABI.IsN32() ||
ABI.IsN64();
600 bool isABI_N32()
const {
return ABI.IsN32(); }
601 bool isABI_N64()
const {
return ABI.IsN64(); }
602 bool isABI_O32()
const {
return ABI.IsO32(); }
603 bool isABI_FPXX()
const {
607 bool useOddSPReg()
const {
611 bool inMicroMipsMode()
const {
615 bool hasMips1()
const {
619 bool hasMips2()
const {
623 bool hasMips3()
const {
627 bool hasMips4()
const {
631 bool hasMips5()
const {
635 bool hasMips32()
const {
639 bool hasMips64()
const {
643 bool hasMips32r2()
const {
647 bool hasMips64r2()
const {
651 bool hasMips32r3()
const {
652 return (
getSTI().hasFeature(Mips::FeatureMips32r3));
655 bool hasMips64r3()
const {
656 return (
getSTI().hasFeature(Mips::FeatureMips64r3));
659 bool hasMips32r5()
const {
660 return (
getSTI().hasFeature(Mips::FeatureMips32r5));
663 bool hasMips64r5()
const {
664 return (
getSTI().hasFeature(Mips::FeatureMips64r5));
667 bool hasMips32r6()
const {
671 bool hasMips64r6()
const {
675 bool hasDSP()
const {
679 bool hasDSPR2()
const {
683 bool hasDSPR3()
const {
687 bool hasMSA()
const {
691 bool hasCnMips()
const {
692 return (
getSTI().hasFeature(Mips::FeatureCnMips));
695 bool hasCnMipsP()
const {
696 return (
getSTI().hasFeature(Mips::FeatureCnMipsP));
703 bool inMips16Mode()
const {
707 bool useTraps()
const {
711 bool useSoftFloat()
const {
718 bool hasCRC()
const {
722 bool hasVirt()
const {
726 bool hasGINV()
const {
731 void warnIfRegIndexIsAT(
unsigned RegIndex,
SMLoc Loc);
733 void warnIfNoMacro(
SMLoc Loc);
735 bool isLittle()
const {
return IsLittleEndian; }
740 switch(OperatorToken) {
811 RegKind_MSACtrl = 16,
816 RegKind_HWRegs = 256,
820 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
821 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
822 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
835 MipsOperand(KindTy K, MipsAsmParser &Parser) :
Kind(
K), AsmParser(Parser) {}
837 ~MipsOperand()
override {
846 case k_RegisterIndex:
854 MipsAsmParser &AsmParser;
883 struct RegIdxOp RegIdx;
886 struct RegListOp RegList;
889 SMLoc StartLoc, EndLoc;
892 static std::unique_ptr<MipsOperand> CreateReg(
unsigned Index,
StringRef Str,
896 MipsAsmParser &Parser) {
897 auto Op = std::make_unique<MipsOperand>(k_RegisterIndex, Parser);
900 Op->RegIdx.Kind = RegKind;
901 Op->RegIdx.Tok.Data = Str.data();
902 Op->RegIdx.Tok.Length = Str.size();
911 unsigned getGPR32Reg()
const {
912 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
913 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
914 unsigned ClassID = Mips::GPR32RegClassID;
915 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
920 unsigned getGPRMM16Reg()
const {
921 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
922 unsigned ClassID = Mips::GPR32RegClassID;
923 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
928 unsigned getGPR64Reg()
const {
929 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
930 unsigned ClassID = Mips::GPR64RegClassID;
931 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
937 unsigned getAFGR64Reg()
const {
938 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
939 if (RegIdx.Index % 2 != 0)
940 AsmParser.Warning(StartLoc,
"Float register should be even.");
941 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
942 .getRegister(RegIdx.Index / 2);
947 unsigned getFGR64Reg()
const {
948 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
949 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
950 .getRegister(RegIdx.Index);
955 unsigned getFGR32Reg()
const {
956 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
957 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
958 .getRegister(RegIdx.Index);
963 unsigned getFCCReg()
const {
964 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) &&
"Invalid access!");
965 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
966 .getRegister(RegIdx.Index);
971 unsigned getMSA128Reg()
const {
972 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) &&
"Invalid access!");
975 unsigned ClassID = Mips::MSA128BRegClassID;
976 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
981 unsigned getMSACtrlReg()
const {
982 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) &&
"Invalid access!");
983 unsigned ClassID = Mips::MSACtrlRegClassID;
984 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
989 unsigned getCOP0Reg()
const {
990 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) &&
"Invalid access!");
991 unsigned ClassID = Mips::COP0RegClassID;
992 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
997 unsigned getCOP2Reg()
const {
998 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) &&
"Invalid access!");
999 unsigned ClassID = Mips::COP2RegClassID;
1000 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1005 unsigned getCOP3Reg()
const {
1006 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) &&
"Invalid access!");
1007 unsigned ClassID = Mips::COP3RegClassID;
1008 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1013 unsigned getACC64DSPReg()
const {
1014 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
1015 unsigned ClassID = Mips::ACC64DSPRegClassID;
1016 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1021 unsigned getHI32DSPReg()
const {
1022 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
1023 unsigned ClassID = Mips::HI32DSPRegClassID;
1024 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1029 unsigned getLO32DSPReg()
const {
1030 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
1031 unsigned ClassID = Mips::LO32DSPRegClassID;
1032 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1037 unsigned getCCRReg()
const {
1038 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) &&
"Invalid access!");
1039 unsigned ClassID = Mips::CCRRegClassID;
1040 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1045 unsigned getHWRegsReg()
const {
1046 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) &&
"Invalid access!");
1047 unsigned ClassID = Mips::HWRegsRegClassID;
1048 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1056 else if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
1062 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
1069 void addGPR32ZeroAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1070 assert(
N == 1 &&
"Invalid number of operands!");
1074 void addGPR32NonZeroAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1075 assert(
N == 1 &&
"Invalid number of operands!");
1079 void addGPR32AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1080 assert(
N == 1 &&
"Invalid number of operands!");
1084 void addGPRMM16AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1085 assert(
N == 1 &&
"Invalid number of operands!");
1089 void addGPRMM16AsmRegZeroOperands(
MCInst &Inst,
unsigned N)
const {
1090 assert(
N == 1 &&
"Invalid number of operands!");
1094 void addGPRMM16AsmRegMovePOperands(
MCInst &Inst,
unsigned N)
const {
1095 assert(
N == 1 &&
"Invalid number of operands!");
1099 void addGPRMM16AsmRegMovePPairFirstOperands(
MCInst &Inst,
unsigned N)
const {
1100 assert(
N == 1 &&
"Invalid number of operands!");
1104 void addGPRMM16AsmRegMovePPairSecondOperands(
MCInst &Inst,
1106 assert(
N == 1 &&
"Invalid number of operands!");
1113 void addGPR64AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1114 assert(
N == 1 &&
"Invalid number of operands!");
1118 void addAFGR64AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1119 assert(
N == 1 &&
"Invalid number of operands!");
1123 void addStrictlyAFGR64AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1124 assert(
N == 1 &&
"Invalid number of operands!");
1128 void addStrictlyFGR64AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1129 assert(
N == 1 &&
"Invalid number of operands!");
1133 void addFGR64AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1134 assert(
N == 1 &&
"Invalid number of operands!");
1138 void addFGR32AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1139 assert(
N == 1 &&
"Invalid number of operands!");
1143 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1144 AsmParser.getParser().printError(
1145 StartLoc,
"-mno-odd-spreg prohibits the use of odd FPU "
1149 void addStrictlyFGR32AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1150 assert(
N == 1 &&
"Invalid number of operands!");
1153 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1154 AsmParser.Error(StartLoc,
"-mno-odd-spreg prohibits the use of odd FPU "
1158 void addFCCAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1159 assert(
N == 1 &&
"Invalid number of operands!");
1163 void addMSA128AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1164 assert(
N == 1 &&
"Invalid number of operands!");
1168 void addMSACtrlAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1169 assert(
N == 1 &&
"Invalid number of operands!");
1173 void addCOP0AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1174 assert(
N == 1 &&
"Invalid number of operands!");
1178 void addCOP2AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1179 assert(
N == 1 &&
"Invalid number of operands!");
1183 void addCOP3AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1184 assert(
N == 1 &&
"Invalid number of operands!");
1188 void addACC64DSPAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1189 assert(
N == 1 &&
"Invalid number of operands!");
1193 void addHI32DSPAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1194 assert(
N == 1 &&
"Invalid number of operands!");
1198 void addLO32DSPAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1199 assert(
N == 1 &&
"Invalid number of operands!");
1203 void addCCRAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1204 assert(
N == 1 &&
"Invalid number of operands!");
1208 void addHWRegsAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1209 assert(
N == 1 &&
"Invalid number of operands!");
1213 template <
unsigned Bits,
int Offset = 0,
int AdjustOffset = 0>
1214 void addConstantUImmOperands(
MCInst &Inst,
unsigned N)
const {
1215 assert(
N == 1 &&
"Invalid number of operands!");
1219 Imm += AdjustOffset;
1223 template <
unsigned Bits>
1224 void addSImmOperands(
MCInst &Inst,
unsigned N)
const {
1225 if (
isImm() && !isConstantImm()) {
1226 addExpr(Inst, getImm());
1229 addConstantSImmOperands<Bits, 0, 0>(Inst,
N);
1232 template <
unsigned Bits>
1233 void addUImmOperands(
MCInst &Inst,
unsigned N)
const {
1234 if (
isImm() && !isConstantImm()) {
1235 addExpr(Inst, getImm());
1238 addConstantUImmOperands<Bits, 0, 0>(Inst,
N);
1241 template <
unsigned Bits,
int Offset = 0,
int AdjustOffset = 0>
1242 void addConstantSImmOperands(
MCInst &Inst,
unsigned N)
const {
1243 assert(
N == 1 &&
"Invalid number of operands!");
1244 int64_t
Imm = getConstantImm() -
Offset;
1245 Imm = SignExtend64<Bits>(Imm);
1247 Imm += AdjustOffset;
1251 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
1252 assert(
N == 1 &&
"Invalid number of operands!");
1253 const MCExpr *Expr = getImm();
1254 addExpr(Inst, Expr);
1257 void addMemOperands(
MCInst &Inst,
unsigned N)
const {
1258 assert(
N == 2 &&
"Invalid number of operands!");
1261 ? getMemBase()->getGPR64Reg()
1262 : getMemBase()->getGPR32Reg()));
1264 const MCExpr *Expr = getMemOff();
1265 addExpr(Inst, Expr);
1268 void addMicroMipsMemOperands(
MCInst &Inst,
unsigned N)
const {
1269 assert(
N == 2 &&
"Invalid number of operands!");
1273 const MCExpr *Expr = getMemOff();
1274 addExpr(Inst, Expr);
1277 void addRegListOperands(
MCInst &Inst,
unsigned N)
const {
1278 assert(
N == 1 &&
"Invalid number of operands!");
1280 for (
auto RegNo : getRegList())
1284 bool isReg()
const override {
1287 return isGPRAsmReg() && RegIdx.Index == 0;
1290 bool isRegIdx()
const {
return Kind == k_RegisterIndex; }
1291 bool isImm()
const override {
return Kind == k_Immediate; }
1293 bool isConstantImm()
const {
1295 return isImm() && getImm()->evaluateAsAbsolute(Res);
1298 bool isConstantImmz()
const {
1299 return isConstantImm() && getConstantImm() == 0;
1302 template <
unsigned Bits,
int Offset = 0>
bool isConstantUImm()
const {
1303 return isConstantImm() && isUInt<Bits>(getConstantImm() -
Offset);
1306 template <
unsigned Bits>
bool isSImm()
const {
1307 return isConstantImm() ? isInt<Bits>(getConstantImm()) :
isImm();
1310 template <
unsigned Bits>
bool isUImm()
const {
1311 return isConstantImm() ? isUInt<Bits>(getConstantImm()) :
isImm();
1314 template <
unsigned Bits>
bool isAnyImm()
const {
1315 return isConstantImm() ? (isInt<Bits>(getConstantImm()) ||
1316 isUInt<Bits>(getConstantImm()))
1320 template <
unsigned Bits,
int Offset = 0>
bool isConstantSImm()
const {
1321 return isConstantImm() && isInt<Bits>(getConstantImm() -
Offset);
1324 template <
unsigned Bottom,
unsigned Top>
bool isConstantUImmRange()
const {
1325 return isConstantImm() && getConstantImm() >= Bottom &&
1326 getConstantImm() <= Top;
1329 bool isToken()
const override {
1332 return Kind == k_Token;
1335 bool isMem()
const override {
return Kind == k_Memory; }
1337 bool isConstantMemOff()
const {
1338 return isMem() && isa<MCConstantExpr>(getMemOff());
1342 template <
unsigned Bits,
unsigned ShiftAmount = 0>
1343 bool isMemWithSimmOffset()
const {
1346 if (!getMemBase()->isGPRAsmReg())
1348 if (isa<MCTargetExpr>(getMemOff()) ||
1349 (isConstantMemOff() &&
1350 isShiftedInt<Bits, ShiftAmount>(getConstantMemOff())))
1353 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res,
nullptr,
nullptr);
1354 return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.
getConstant());
1357 bool isMemWithPtrSizeOffset()
const {
1360 if (!getMemBase()->isGPRAsmReg())
1362 const unsigned PtrBits = AsmParser.getABI().ArePtrs64bit() ? 64 : 32;
1363 if (isa<MCTargetExpr>(getMemOff()) ||
1364 (isConstantMemOff() &&
isIntN(PtrBits, getConstantMemOff())))
1367 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res,
nullptr,
nullptr);
1371 bool isMemWithGRPMM16Base()
const {
1372 return isMem() && getMemBase()->isMM16AsmReg();
1375 template <
unsigned Bits>
bool isMemWithUimmOffsetSP()
const {
1376 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1377 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1380 template <
unsigned Bits>
bool isMemWithUimmWordAlignedOffsetSP()
const {
1381 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1382 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1383 && (getMemBase()->getGPR32Reg() == Mips::SP);
1386 template <
unsigned Bits>
bool isMemWithSimmWordAlignedOffsetGP()
const {
1387 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
1388 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1389 && (getMemBase()->getGPR32Reg() == Mips::GP);
1392 template <
unsigned Bits,
unsigned ShiftLeftAmount>
1393 bool isScaledUImm()
const {
1394 return isConstantImm() &&
1395 isShiftedUInt<Bits, ShiftLeftAmount>(getConstantImm());
1398 template <
unsigned Bits,
unsigned ShiftLeftAmount>
1399 bool isScaledSImm()
const {
1400 if (isConstantImm() &&
1401 isShiftedInt<Bits, ShiftLeftAmount>(getConstantImm()))
1405 if (Kind != k_Immediate)
1408 bool Success = getImm()->evaluateAsRelocatable(Res,
nullptr,
nullptr);
1412 bool isRegList16()
const {
1416 int Size = RegList.List->size();
1417 if (Size < 2 || Size > 5)
1420 unsigned R0 = RegList.List->front();
1421 unsigned R1 = RegList.List->back();
1422 if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1423 (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1426 int PrevReg = *RegList.List->begin();
1427 for (
int i = 1; i <
Size - 1; i++) {
1428 int Reg = (*(RegList.List))[i];
1429 if (
Reg != PrevReg + 1)
1437 bool isInvNum()
const {
return Kind == k_Immediate; }
1439 bool isLSAImm()
const {
1440 if (!isConstantImm())
1442 int64_t Val = getConstantImm();
1443 return 1 <= Val && Val <= 4;
1446 bool isRegList()
const {
return Kind == k_RegList; }
1449 assert(Kind == k_Token &&
"Invalid access!");
1453 unsigned getReg()
const override {
1456 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1457 RegIdx.Kind & RegKind_GPR)
1458 return getGPR32Reg();
1464 const MCExpr *getImm()
const {
1465 assert((Kind == k_Immediate) &&
"Invalid access!");
1469 int64_t getConstantImm()
const {
1470 const MCExpr *Val = getImm();
1472 (void)Val->evaluateAsAbsolute(
Value);
1476 MipsOperand *getMemBase()
const {
1477 assert((Kind == k_Memory) &&
"Invalid access!");
1481 const MCExpr *getMemOff()
const {
1482 assert((Kind == k_Memory) &&
"Invalid access!");
1486 int64_t getConstantMemOff()
const {
1487 return static_cast<const MCConstantExpr *
>(getMemOff())->getValue();
1491 assert((Kind == k_RegList) &&
"Invalid access!");
1492 return *(RegList.List);
1495 static std::unique_ptr<MipsOperand> CreateToken(
StringRef Str,
SMLoc S,
1496 MipsAsmParser &Parser) {
1497 auto Op = std::make_unique<MipsOperand>(k_Token, Parser);
1498 Op->Tok.Data = Str.data();
1499 Op->Tok.Length = Str.size();
1507 static std::unique_ptr<MipsOperand>
1511 return CreateReg(
Index, Str, RegKind_Numeric,
RegInfo, S,
E, Parser);
1516 static std::unique_ptr<MipsOperand>
1519 return CreateReg(
Index, Str, RegKind_GPR,
RegInfo, S,
E, Parser);
1524 static std::unique_ptr<MipsOperand>
1527 return CreateReg(
Index, Str, RegKind_FGR,
RegInfo, S,
E, Parser);
1532 static std::unique_ptr<MipsOperand>
1535 return CreateReg(
Index, Str, RegKind_HWRegs,
RegInfo, S,
E, Parser);
1540 static std::unique_ptr<MipsOperand>
1543 return CreateReg(
Index, Str, RegKind_FCC,
RegInfo, S,
E, Parser);
1548 static std::unique_ptr<MipsOperand>
1551 return CreateReg(
Index, Str, RegKind_ACC,
RegInfo, S,
E, Parser);
1556 static std::unique_ptr<MipsOperand>
1559 return CreateReg(
Index, Str, RegKind_MSA128,
RegInfo, S,
E, Parser);
1564 static std::unique_ptr<MipsOperand>
1567 return CreateReg(
Index, Str, RegKind_MSACtrl,
RegInfo, S,
E, Parser);
1570 static std::unique_ptr<MipsOperand>
1572 auto Op = std::make_unique<MipsOperand>(k_Immediate, Parser);
1579 static std::unique_ptr<MipsOperand>
1580 CreateMem(std::unique_ptr<MipsOperand>
Base,
const MCExpr *Off,
SMLoc S,
1581 SMLoc E, MipsAsmParser &Parser) {
1582 auto Op = std::make_unique<MipsOperand>(k_Memory, Parser);
1583 Op->Mem.Base =
Base.release();
1590 static std::unique_ptr<MipsOperand>
1592 MipsAsmParser &Parser) {
1593 assert(Regs.
size() > 0 &&
"Empty list not allowed");
1595 auto Op = std::make_unique<MipsOperand>(k_RegList, Parser);
1597 Op->StartLoc = StartLoc;
1598 Op->EndLoc = EndLoc;
1602 bool isGPRZeroAsmReg()
const {
1603 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
1606 bool isGPRNonZeroAsmReg()
const {
1607 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index > 0 &&
1611 bool isGPRAsmReg()
const {
1612 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1615 bool isMM16AsmReg()
const {
1616 if (!(isRegIdx() && RegIdx.Kind))
1618 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1619 || RegIdx.Index == 16 || RegIdx.Index == 17);
1622 bool isMM16AsmRegZero()
const {
1623 if (!(isRegIdx() && RegIdx.Kind))
1625 return (RegIdx.Index == 0 ||
1626 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1627 RegIdx.Index == 17);
1630 bool isMM16AsmRegMoveP()
const {
1631 if (!(isRegIdx() && RegIdx.Kind))
1633 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1634 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1637 bool isMM16AsmRegMovePPairFirst()
const {
1638 if (!(isRegIdx() && RegIdx.Kind))
1640 return RegIdx.Index >= 4 && RegIdx.Index <= 6;
1643 bool isMM16AsmRegMovePPairSecond()
const {
1644 if (!(isRegIdx() && RegIdx.Kind))
1646 return (RegIdx.Index == 21 || RegIdx.Index == 22 ||
1647 (RegIdx.Index >= 5 && RegIdx.Index <= 7));
1650 bool isFGRAsmReg()
const {
1652 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1655 bool isStrictlyFGRAsmReg()
const {
1657 return isRegIdx() && RegIdx.Kind == RegKind_FGR && RegIdx.Index <= 31;
1660 bool isHWRegsAsmReg()
const {
1661 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1664 bool isCCRAsmReg()
const {
1665 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1668 bool isFCCAsmReg()
const {
1669 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1671 return RegIdx.Index <= 7;
1674 bool isACCAsmReg()
const {
1675 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1678 bool isCOP0AsmReg()
const {
1679 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1682 bool isCOP2AsmReg()
const {
1683 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1686 bool isCOP3AsmReg()
const {
1687 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1690 bool isMSA128AsmReg()
const {
1691 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1694 bool isMSACtrlAsmReg()
const {
1695 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1699 SMLoc getStartLoc()
const override {
return StartLoc; }
1701 SMLoc getEndLoc()
const override {
return EndLoc; }
1712 Mem.Base->print(
OS);
1717 case k_RegisterIndex:
1718 OS <<
"RegIdx<" << RegIdx.Index <<
":" << RegIdx.Kind <<
", "
1719 <<
StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) <<
">";
1726 for (
auto Reg : (*RegList.List))
1733 bool isValidForTie(
const MipsOperand &
Other)
const {
1734 if (Kind !=
Other.Kind)
1741 case k_RegisterIndex: {
1742 StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length);
1744 return Token == OtherToken;
1760 case Mips::JRC16_MM:
1762 case Mips::JALRS_MM:
1763 case Mips::JALRS16_MM:
1764 case Mips::BGEZALS_MM:
1765 case Mips::BLTZALS_MM:
1775 if (
const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1776 return &SRExpr->getSymbol();
1779 if (
const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1792 if (
const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1799 if (isa<MCSymbolRefExpr>(Expr))
1802 if (
const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1806 if (
const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1825 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1834 if (NumOp != 3 && NumOp != 4)
1846 return !isInt<9>(Op.getImm());
1848 return !isInt<16>(Op.getImm());
1852 const MCExpr *Expr = Op.getExpr();
1864bool MipsAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
1868 const unsigned Opcode = Inst.
getOpcode();
1870 bool ExpandedJalSym =
false;
1884 assert(hasCnMips() &&
"instruction only valid for octeon cpus");
1895 if (!
isIntN(inMicroMipsMode() ? 17 : 18,
Offset.getImm()))
1896 return Error(IDLoc,
"branch target out of range");
1899 return Error(IDLoc,
"branch to misaligned address");
1913 case Mips::BGEZAL_MM:
1914 case Mips::BLTZAL_MM:
1917 case Mips::BC1EQZC_MMR6:
1918 case Mips::BC1NEZC_MMR6:
1919 case Mips::BC2EQZC_MMR6:
1920 case Mips::BC2NEZC_MMR6:
1925 if (!
isIntN(inMicroMipsMode() ? 17 : 18,
Offset.getImm()))
1926 return Error(IDLoc,
"branch target out of range");
1929 return Error(IDLoc,
"branch to misaligned address");
1931 case Mips::BGEC:
case Mips::BGEC_MMR6:
1932 case Mips::BLTC:
case Mips::BLTC_MMR6:
1933 case Mips::BGEUC:
case Mips::BGEUC_MMR6:
1934 case Mips::BLTUC:
case Mips::BLTUC_MMR6:
1935 case Mips::BEQC:
case Mips::BEQC_MMR6:
1936 case Mips::BNEC:
case Mips::BNEC_MMR6:
1942 return Error(IDLoc,
"branch target out of range");
1944 return Error(IDLoc,
"branch to misaligned address");
1946 case Mips::BLEZC:
case Mips::BLEZC_MMR6:
1947 case Mips::BGEZC:
case Mips::BGEZC_MMR6:
1948 case Mips::BGTZC:
case Mips::BGTZC_MMR6:
1949 case Mips::BLTZC:
case Mips::BLTZC_MMR6:
1955 return Error(IDLoc,
"branch target out of range");
1957 return Error(IDLoc,
"branch to misaligned address");
1959 case Mips::BEQZC:
case Mips::BEQZC_MMR6:
1960 case Mips::BNEZC:
case Mips::BNEZC_MMR6:
1966 return Error(IDLoc,
"branch target out of range");
1968 return Error(IDLoc,
"branch to misaligned address");
1970 case Mips::BEQZ16_MM:
1971 case Mips::BEQZC16_MMR6:
1972 case Mips::BNEZ16_MM:
1973 case Mips::BNEZC16_MMR6:
1978 if (!isInt<8>(
Offset.getImm()))
1979 return Error(IDLoc,
"branch target out of range");
1981 return Error(IDLoc,
"branch to misaligned address");
1988 if (hasMips32r6() && Opcode == Mips::SSNOP) {
1989 std::string
ISA = hasMips64r6() ?
"MIPS64r6" :
"MIPS32r6";
1990 Warning(IDLoc,
"ssnop is deprecated for " + ISA +
" and is equivalent to a "
2010 return Error(IDLoc,
"expected immediate operand kind");
2012 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
2013 Opcode == Mips::BBIT1 ? 63 : 31))
2014 return Error(IDLoc,
"immediate operand value out of range");
2016 Inst.
setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
2027 return Error(IDLoc,
"expected immediate operand kind");
2029 if (!isInt<10>(Imm))
2030 return Error(IDLoc,
"immediate operand value out of range");
2042 unsigned FirstOp = 1;
2043 unsigned SecondOp = 2;
2047 case Mips::SDivIMacro:
2048 case Mips::UDivIMacro:
2049 case Mips::DSDivIMacro:
2050 case Mips::DUDivIMacro:
2054 Warning(IDLoc,
"dividing zero by zero");
2056 Warning(IDLoc,
"division by zero");
2068 case Mips::SDivMacro:
2069 case Mips::DSDivMacro:
2070 case Mips::UDivMacro:
2071 case Mips::DUDivMacro:
2076 case Mips::DIVU_MMR6:
2077 case Mips::DIV_MMR6:
2082 Warning(IDLoc,
"dividing zero by zero");
2084 Warning(IDLoc,
"division by zero");
2090 if ((Opcode == Mips::J || Opcode == Mips::J_MM) && inPicMode()) {
2092 BInst.
setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
2101 if ((Opcode == Mips::JAL || Opcode == Mips::JAL_MM) && inPicMode()) {
2102 warnIfNoMacro(IDLoc);
2109 return Error(IDLoc,
"jal doesn't support multiple symbols in PIC mode");
2115 if (expandLoadAddress(Mips::T9, Mips::NoRegister, Inst.
getOperand(0),
2116 !isGP64bit(), IDLoc, Out, STI))
2120 if (inMicroMipsMode())
2121 JalrInst.
setOpcode(IsCpRestoreSet ? Mips::JALRS_MM : Mips::JALR_MM);
2127 if (isJalrRelocAvailable(JalExpr)) {
2131 MCSymbol *TmpLabel = getContext().createTempSymbol();
2133 const MCExpr *RelocJalrExpr =
2135 getContext(), IDLoc);
2138 *TmpExpr, inMicroMipsMode() ?
"R_MICROMIPS_JALR" :
"R_MIPS_JALR",
2139 RelocJalrExpr, IDLoc, *STI);
2144 ExpandedJalSym =
true;
2153 expandMem9Inst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2156 expandMem16Inst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2159 return getParser().hasPendingError();
2163 if (inMicroMipsMode()) {
2164 if (MCID.
mayLoad() && Opcode != Mips::LWP_MM) {
2172 int MemOffset =
Op.getImm();
2175 if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
2178 (BaseReg.
getReg() == Mips::GP ||
2179 BaseReg.
getReg() == Mips::GP_64)) {
2181 TOut.
emitRRI(Mips::LWGP_MM, DstReg.
getReg(), Mips::GP, MemOffset,
2198 case Mips::ADDIUSP_MM:
2201 return Error(IDLoc,
"expected immediate operand kind");
2203 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
2205 return Error(IDLoc,
"immediate operand value out of range");
2207 case Mips::SLL16_MM:
2208 case Mips::SRL16_MM:
2211 return Error(IDLoc,
"expected immediate operand kind");
2213 if (Imm < 1 || Imm > 8)
2214 return Error(IDLoc,
"immediate operand value out of range");
2219 return Error(IDLoc,
"expected immediate operand kind");
2221 if (Imm < -1 || Imm > 126)
2222 return Error(IDLoc,
"immediate operand value out of range");
2224 case Mips::ADDIUR2_MM:
2227 return Error(IDLoc,
"expected immediate operand kind");
2229 if (!(Imm == 1 || Imm == -1 ||
2230 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
2231 return Error(IDLoc,
"immediate operand value out of range");
2233 case Mips::ANDI16_MM:
2236 return Error(IDLoc,
"expected immediate operand kind");
2238 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
2239 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
2240 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
2241 return Error(IDLoc,
"immediate operand value out of range");
2243 case Mips::LBU16_MM:
2246 return Error(IDLoc,
"expected immediate operand kind");
2248 if (Imm < -1 || Imm > 14)
2249 return Error(IDLoc,
"immediate operand value out of range");
2252 case Mips::SB16_MMR6:
2255 return Error(IDLoc,
"expected immediate operand kind");
2257 if (Imm < 0 || Imm > 15)
2258 return Error(IDLoc,
"immediate operand value out of range");
2260 case Mips::LHU16_MM:
2262 case Mips::SH16_MMR6:
2265 return Error(IDLoc,
"expected immediate operand kind");
2267 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
2268 return Error(IDLoc,
"immediate operand value out of range");
2272 case Mips::SW16_MMR6:
2275 return Error(IDLoc,
"expected immediate operand kind");
2277 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
2278 return Error(IDLoc,
"immediate operand value out of range");
2280 case Mips::ADDIUPC_MM:
2283 return Error(IDLoc,
"expected immediate operand kind");
2285 if ((Imm % 4 != 0) || !isInt<25>(Imm))
2286 return Error(IDLoc,
"immediate operand value out of range");
2291 return Error(IDLoc,
"invalid operand for instruction");
2293 case Mips::MOVEP_MM:
2294 case Mips::MOVEP_MMR6: {
2297 bool RegPair = ((R0 == Mips::A1 && R1 == Mips::A2) ||
2298 (R0 == Mips::A1 && R1 == Mips::A3) ||
2299 (R0 == Mips::A2 && R1 == Mips::A3) ||
2300 (R0 == Mips::A0 && R1 == Mips::S5) ||
2301 (R0 == Mips::A0 && R1 == Mips::S6) ||
2302 (R0 == Mips::A0 && R1 == Mips::A1) ||
2303 (R0 == Mips::A0 && R1 == Mips::A2) ||
2304 (R0 == Mips::A0 && R1 == Mips::A3));
2306 return Error(IDLoc,
"invalid operand for instruction");
2312 bool FillDelaySlot =
2317 MacroExpanderResultTy ExpandResult =
2318 tryExpandInstruction(Inst, IDLoc, Out, STI);
2319 switch (ExpandResult) {
2331 if (inMicroMipsMode()) {
2338 if (FillDelaySlot) {
2343 if ((Opcode == Mips::JalOneReg || Opcode == Mips::JalTwoReg ||
2345 isPicAndNotNxxAbi()) {
2346 if (IsCpRestoreSet) {
2350 if (!AssemblerOptions.
back()->isReorder())
2357 Warning(IDLoc,
"no .cprestore used in PIC mode");
2363MipsAsmParser::MacroExpanderResultTy
2368 return MER_NotAMacro;
2369 case Mips::LoadImm32:
2370 return expandLoadImm(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2371 case Mips::LoadImm64:
2372 return expandLoadImm(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2373 case Mips::LoadAddrImm32:
2374 case Mips::LoadAddrImm64:
2377 "expected immediate operand kind");
2381 Inst.
getOpcode() == Mips::LoadAddrImm32, IDLoc,
2385 case Mips::LoadAddrReg32:
2386 case Mips::LoadAddrReg64:
2390 "expected immediate operand kind");
2394 Inst.
getOpcode() == Mips::LoadAddrReg32, IDLoc,
2398 case Mips::B_MM_Pseudo:
2399 case Mips::B_MMR6_Pseudo:
2400 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2404 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2406 case Mips::JalOneReg:
2407 case Mips::JalTwoReg:
2408 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2411 case Mips::BEQLImmMacro:
2412 case Mips::BNELImmMacro:
2413 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2430 case Mips::BLTImmMacro:
2431 case Mips::BLEImmMacro:
2432 case Mips::BGEImmMacro:
2433 case Mips::BGTImmMacro:
2434 case Mips::BLTUImmMacro:
2435 case Mips::BLEUImmMacro:
2436 case Mips::BGEUImmMacro:
2437 case Mips::BGTUImmMacro:
2438 case Mips::BLTLImmMacro:
2439 case Mips::BLELImmMacro:
2440 case Mips::BGELImmMacro:
2441 case Mips::BGTLImmMacro:
2442 case Mips::BLTULImmMacro:
2443 case Mips::BLEULImmMacro:
2444 case Mips::BGEULImmMacro:
2445 case Mips::BGTULImmMacro:
2446 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2447 case Mips::SDivMacro:
2448 case Mips::SDivIMacro:
2449 case Mips::SRemMacro:
2450 case Mips::SRemIMacro:
2451 return expandDivRem(Inst, IDLoc, Out, STI,
false,
true) ? MER_Fail
2453 case Mips::DSDivMacro:
2454 case Mips::DSDivIMacro:
2455 case Mips::DSRemMacro:
2456 case Mips::DSRemIMacro:
2457 return expandDivRem(Inst, IDLoc, Out, STI,
true,
true) ? MER_Fail
2459 case Mips::UDivMacro:
2460 case Mips::UDivIMacro:
2461 case Mips::URemMacro:
2462 case Mips::URemIMacro:
2463 return expandDivRem(Inst, IDLoc, Out, STI,
false,
false) ? MER_Fail
2465 case Mips::DUDivMacro:
2466 case Mips::DUDivIMacro:
2467 case Mips::DURemMacro:
2468 case Mips::DURemIMacro:
2469 return expandDivRem(Inst, IDLoc, Out, STI,
true,
false) ? MER_Fail
2471 case Mips::PseudoTRUNC_W_S:
2472 return expandTrunc(Inst,
false,
false, IDLoc, Out, STI) ? MER_Fail
2474 case Mips::PseudoTRUNC_W_D32:
2475 return expandTrunc(Inst,
true,
false, IDLoc, Out, STI) ? MER_Fail
2477 case Mips::PseudoTRUNC_W_D:
2478 return expandTrunc(Inst,
true,
true, IDLoc, Out, STI) ? MER_Fail
2481 case Mips::LoadImmSingleGPR:
2482 return expandLoadSingleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2484 case Mips::LoadImmSingleFGR:
2485 return expandLoadSingleImmToFPR(Inst, IDLoc, Out, STI) ? MER_Fail
2487 case Mips::LoadImmDoubleGPR:
2488 return expandLoadDoubleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2490 case Mips::LoadImmDoubleFGR:
2491 return expandLoadDoubleImmToFPR(Inst,
true, IDLoc, Out, STI) ? MER_Fail
2493 case Mips::LoadImmDoubleFGR_32:
2494 return expandLoadDoubleImmToFPR(Inst,
false, IDLoc, Out, STI) ? MER_Fail
2498 return expandUlh(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2500 return expandUlh(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2502 return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2505 return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2507 case Mips::NORImm64:
2508 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2511 return expandSge(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2514 case Mips::SGEImm64:
2515 case Mips::SGEUImm64:
2516 return expandSgeImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2519 case Mips::SGTImm64:
2520 case Mips::SGTUImm64:
2521 return expandSgtImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2524 return expandSle(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2527 case Mips::SLEImm64:
2528 case Mips::SLEUImm64:
2529 return expandSleImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2530 case Mips::SLTImm64:
2533 return MER_NotAMacro;
2535 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2536 case Mips::SLTUImm64:
2539 return MER_NotAMacro;
2541 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2542 case Mips::ADDi:
case Mips::ADDi_MM:
2543 case Mips::ADDiu:
case Mips::ADDiu_MM:
2544 case Mips::SLTi:
case Mips::SLTi_MM:
2545 case Mips::SLTiu:
case Mips::SLTiu_MM:
2549 if (isInt<16>(ImmValue))
2550 return MER_NotAMacro;
2551 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2554 return MER_NotAMacro;
2555 case Mips::ANDi:
case Mips::ANDi_MM:
case Mips::ANDi64:
2556 case Mips::ORi:
case Mips::ORi_MM:
case Mips::ORi64:
2557 case Mips::XORi:
case Mips::XORi_MM:
case Mips::XORi64:
2561 if (isUInt<16>(ImmValue))
2562 return MER_NotAMacro;
2563 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2566 return MER_NotAMacro;
2569 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2572 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2575 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2578 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2579 case Mips::ABSMacro:
2580 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2581 case Mips::MULImmMacro:
2582 case Mips::DMULImmMacro:
2583 return expandMulImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2584 case Mips::MULOMacro:
2585 case Mips::DMULOMacro:
2586 return expandMulO(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2587 case Mips::MULOUMacro:
2588 case Mips::DMULOUMacro:
2589 return expandMulOU(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2590 case Mips::DMULMacro:
2591 return expandDMULMacro(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2594 return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2599 return expandStoreDM1Macro(Inst, IDLoc, Out, STI)
2602 case Mips::SEQMacro:
2603 return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2604 case Mips::SEQIMacro:
2605 return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2606 case Mips::SNEMacro:
2607 return expandSne(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2608 case Mips::SNEIMacro:
2609 return expandSneI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2610 case Mips::MFTC0:
case Mips::MTTC0:
2611 case Mips::MFTGPR:
case Mips::MTTGPR:
2612 case Mips::MFTLO:
case Mips::MTTLO:
2613 case Mips::MFTHI:
case Mips::MTTHI:
2614 case Mips::MFTACX:
case Mips::MTTACX:
2615 case Mips::MFTDSP:
case Mips::MTTDSP:
2616 case Mips::MFTC1:
case Mips::MTTC1:
2617 case Mips::MFTHC1:
case Mips::MTTHC1:
2618 case Mips::CFTC1:
case Mips::CTTC1:
2619 return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2621 case Mips::SaadAddr:
2622 return expandSaaAddr(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2626bool MipsAsmParser::expandJalWithRegs(
MCInst &Inst,
SMLoc IDLoc,
2635 const unsigned Opcode = Inst.
getOpcode();
2637 if (Opcode == Mips::JalOneReg) {
2639 if (IsCpRestoreSet && inMicroMipsMode()) {
2642 }
else if (inMicroMipsMode()) {
2643 JalrInst.
setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2650 }
else if (Opcode == Mips::JalTwoReg) {
2652 if (IsCpRestoreSet && inMicroMipsMode())
2655 JalrInst.
setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2687bool MipsAsmParser::loadImmediate(int64_t ImmValue,
unsigned DstReg,
2688 unsigned SrcReg,
bool Is32BitImm,
2693 if (!Is32BitImm && !isGP64bit()) {
2694 Error(IDLoc,
"instruction requires a 64-bit architecture");
2699 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2703 ImmValue = SignExtend64<32>(ImmValue);
2705 Error(IDLoc,
"instruction requires a 32-bit immediate");
2710 unsigned ZeroReg = IsAddress ?
ABI.GetNullPtr() :
ABI.GetZeroReg();
2711 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2713 bool UseSrcReg =
false;
2714 if (SrcReg != Mips::NoRegister)
2717 unsigned TmpReg = DstReg;
2719 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2722 unsigned ATReg = getATReg(IDLoc);
2728 if (isInt<16>(ImmValue)) {
2735 if (IsAddress && !Is32BitImm) {
2736 TOut.
emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2740 TOut.
emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2744 if (isUInt<16>(ImmValue)) {
2745 unsigned TmpReg = DstReg;
2746 if (SrcReg == DstReg) {
2747 TmpReg = getATReg(IDLoc);
2752 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2754 TOut.
emitRRR(
ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2758 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2759 warnIfNoMacro(IDLoc);
2761 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2762 uint16_t Bits15To0 = ImmValue & 0xffff;
2763 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2766 if (ImmValue == 0xffffffff) {
2767 TOut.
emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2768 TOut.
emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2770 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2776 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2777 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2779 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2781 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2785 TOut.
emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2787 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2789 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2793 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2795 Error(IDLoc,
"instruction requires a 32-bit immediate");
2802 assert(
BitWidth >= 17 &&
"ImmValue must be at least 17-bit wide");
2806 unsigned ShiftAmount =
BitWidth - 16;
2808 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2809 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2812 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2817 warnIfNoMacro(IDLoc);
2824 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister,
true,
false,
2830 unsigned ShiftCarriedForwards = 16;
2831 for (
int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2832 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2834 if (ImmChunk != 0) {
2835 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2836 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2837 ShiftCarriedForwards = 0;
2840 ShiftCarriedForwards += 16;
2842 ShiftCarriedForwards -= 16;
2845 if (ShiftCarriedForwards)
2846 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2849 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2854bool MipsAsmParser::expandLoadImm(
MCInst &Inst,
bool Is32BitImm,
SMLoc IDLoc,
2857 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
2859 assert(DstRegOp.
isReg() &&
"expected register operand kind");
2861 if (loadImmediate(ImmOp.
getImm(), DstRegOp.
getReg(), Mips::NoRegister,
2862 Is32BitImm,
false, IDLoc, Out, STI))
2868bool MipsAsmParser::expandLoadAddress(
unsigned DstReg,
unsigned BaseReg,
2870 bool Is32BitAddress,
SMLoc IDLoc,
2874 if (Is32BitAddress &&
ABI.ArePtrs64bit()) {
2875 Warning(IDLoc,
"la used to load 64-bit address");
2877 Is32BitAddress =
false;
2881 if (!Is32BitAddress && !hasMips3()) {
2882 Error(IDLoc,
"instruction requires a 64-bit architecture");
2887 return loadAndAddSymbolAddress(
Offset.getExpr(), DstReg, BaseReg,
2888 Is32BitAddress, IDLoc, Out, STI);
2890 if (!
ABI.ArePtrs64bit()) {
2892 Is32BitAddress =
true;
2895 return loadImmediate(
Offset.getImm(), DstReg, BaseReg, Is32BitAddress,
true,
2899bool MipsAsmParser::loadAndAddSymbolAddress(
const MCExpr *SymExpr,
2900 unsigned DstReg,
unsigned SrcReg,
2901 bool Is32BitSym,
SMLoc IDLoc,
2905 bool UseSrcReg = SrcReg != Mips::NoRegister && SrcReg != Mips::ZERO &&
2906 SrcReg != Mips::ZERO_64;
2907 warnIfNoMacro(IDLoc);
2912 Error(IDLoc,
"expected relocatable expression");
2915 if (Res.
getSymB() !=
nullptr) {
2916 Error(IDLoc,
"expected relocatable expression with only one symbol");
2920 bool IsPtr64 =
ABI.ArePtrs64bit();
2927 bool UseXGOT = STI->
hasFeature(Mips::FeatureXGOT) && !IsLocalSym;
2933 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2937 SymExpr, getContext());
2939 SymExpr, getContext());
2942 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, DstReg, GPReg,
2944 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, DstReg,
2949 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, GPReg,
2955 unsigned TmpReg = DstReg;
2957 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2961 unsigned ATReg = getATReg(IDLoc);
2980 const MCExpr *CallHiExpr =
2987 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg, GPReg,
2989 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, TmpReg,
2993 TOut.
emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
2999 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3005 const MCExpr *LoExpr =
nullptr;
3006 if (
ABI.IsN32() ||
ABI.IsN64()) {
3025 Error(IDLoc,
"macro instruction uses large offset, which is not "
3026 "currently supported");
3056 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, GPReg,
3060 TOut.
emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3064 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3076 if (
ABI.ArePtrs64bit() && isGP64bit()) {
3090 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
3092 if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
3093 unsigned ATReg = getATReg(IDLoc);
3105 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3107 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3110 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3113 TOut.
emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
3116 }
else if (canUseATReg() && !RdRegIsRsReg && DstReg != getATReg(IDLoc)) {
3117 unsigned ATReg = getATReg(IDLoc);
3133 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3137 TOut.
emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3138 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3140 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3143 }
else if ((!canUseATReg() && !RdRegIsRsReg) ||
3144 (canUseATReg() && DstReg == getATReg(IDLoc))) {
3155 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3157 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3158 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3160 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3161 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3164 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3170 assert(SrcReg == DstReg && !canUseATReg() &&
3171 "Could have expanded dla but didn't?");
3172 reportParseError(IDLoc,
3173 "pseudo-instruction requires $at, which is not available");
3187 unsigned TmpReg = DstReg;
3189 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
3192 unsigned ATReg = getATReg(IDLoc);
3203 TOut.
emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3206 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
3215 if (MipsMCRegisterClasses[Mips::FGR32RegClassID].
contains(
Reg))
3216 return Reg == (
unsigned)Mips::F31 ? (
unsigned)Mips::F0 :
Reg + 1;
3218 default:
llvm_unreachable(
"Unknown register in assembly macro expansion!");
3219 case Mips::ZERO:
return Mips::AT;
3220 case Mips::AT:
return Mips::V0;
3221 case Mips::V0:
return Mips::V1;
3222 case Mips::V1:
return Mips::A0;
3223 case Mips::A0:
return Mips::A1;
3224 case Mips::A1:
return Mips::A2;
3225 case Mips::A2:
return Mips::A3;
3226 case Mips::A3:
return Mips::T0;
3227 case Mips::T0:
return Mips::T1;
3228 case Mips::T1:
return Mips::T2;
3229 case Mips::T2:
return Mips::T3;
3230 case Mips::T3:
return Mips::T4;
3231 case Mips::T4:
return Mips::T5;
3232 case Mips::T5:
return Mips::T6;
3233 case Mips::T6:
return Mips::T7;
3234 case Mips::T7:
return Mips::S0;
3235 case Mips::S0:
return Mips::S1;
3236 case Mips::S1:
return Mips::S2;
3237 case Mips::S2:
return Mips::S3;
3238 case Mips::S3:
return Mips::S4;
3239 case Mips::S4:
return Mips::S5;
3240 case Mips::S5:
return Mips::S6;
3241 case Mips::S6:
return Mips::S7;
3242 case Mips::S7:
return Mips::T8;
3243 case Mips::T8:
return Mips::T9;
3244 case Mips::T9:
return Mips::K0;
3245 case Mips::K0:
return Mips::K1;
3246 case Mips::K1:
return Mips::GP;
3247 case Mips::GP:
return Mips::SP;
3248 case Mips::SP:
return Mips::FP;
3249 case Mips::FP:
return Mips::RA;
3250 case Mips::RA:
return Mips::ZERO;
3251 case Mips::D0:
return Mips::F1;
3252 case Mips::D1:
return Mips::F3;
3253 case Mips::D2:
return Mips::F5;
3254 case Mips::D3:
return Mips::F7;
3255 case Mips::D4:
return Mips::F9;
3256 case Mips::D5:
return Mips::F11;
3257 case Mips::D6:
return Mips::F13;
3258 case Mips::D7:
return Mips::F15;
3259 case Mips::D8:
return Mips::F17;
3260 case Mips::D9:
return Mips::F19;
3261 case Mips::D10:
return Mips::F21;
3262 case Mips::D11:
return Mips::F23;
3263 case Mips::D12:
return Mips::F25;
3264 case Mips::D13:
return Mips::F27;
3265 case Mips::D14:
return Mips::F29;
3266 case Mips::D15:
return Mips::F31;
3278 unsigned ATReg = getATReg(IDLoc);
3288 if(isABI_O32() || isABI_N32()) {
3307 if(isABI_O32() || isABI_N32()) {
3310 const MCExpr *HighestSym =
3314 const MCExpr *HigherSym =
3321 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3323 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3326 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3335 if ((
Hi_32(ImmOp64) & 0x7ff00000) == 0) {
3336 APFloat RealVal(APFloat::IEEEdouble(), ImmOp64);
3345 double DoubleImm = llvm::bit_cast<double>(ImmOp64);
3346 float TmpFloat =
static_cast<float>(DoubleImm);
3347 return llvm::bit_cast<uint32_t>(TmpFloat);
3350bool MipsAsmParser::expandLoadSingleImmToGPR(
MCInst &Inst,
SMLoc IDLoc,
3355 "Invalid instruction operand.");
3362 return loadImmediate(ImmOp32, FirstReg, Mips::NoRegister,
true,
false, IDLoc,
3366bool MipsAsmParser::expandLoadSingleImmToFPR(
MCInst &Inst,
SMLoc IDLoc,
3372 "Invalid instruction operand.");
3381 unsigned TmpReg = Mips::ZERO;
3383 TmpReg = getATReg(IDLoc);
3388 if (
Lo_32(ImmOp64) == 0) {
3389 if (TmpReg != Mips::ZERO && loadImmediate(ImmOp32, TmpReg, Mips::NoRegister,
3390 true,
false, IDLoc, Out, STI))
3392 TOut.
emitRR(Mips::MTC1, FirstReg, TmpReg, IDLoc, STI);
3396 MCSection *CS = getStreamer().getCurrentSectionOnly();
3402 MCSymbol *Sym = getContext().createTempSymbol();
3408 getStreamer().switchSection(ReadOnlySection);
3409 getStreamer().emitLabel(Sym, IDLoc);
3410 getStreamer().emitInt32(ImmOp32);
3411 getStreamer().switchSection(CS);
3413 if (emitPartialAddress(TOut, IDLoc, Sym))
3420bool MipsAsmParser::expandLoadDoubleImmToGPR(
MCInst &Inst,
SMLoc IDLoc,
3426 "Invalid instruction operand.");
3433 if (
Lo_32(ImmOp64) == 0) {
3435 if (loadImmediate(ImmOp64, FirstReg, Mips::NoRegister,
false,
false,
3439 if (loadImmediate(
Hi_32(ImmOp64), FirstReg, Mips::NoRegister,
true,
false,
3443 if (loadImmediate(0,
nextReg(FirstReg), Mips::NoRegister,
true,
false,
3450 MCSection *CS = getStreamer().getCurrentSectionOnly();
3454 MCSymbol *Sym = getContext().createTempSymbol();
3460 getStreamer().switchSection(ReadOnlySection);
3461 getStreamer().emitLabel(Sym, IDLoc);
3462 getStreamer().emitValueToAlignment(
Align(8));
3463 getStreamer().emitIntValue(ImmOp64, 8);
3464 getStreamer().switchSection(CS);
3466 unsigned TmpReg = getATReg(IDLoc);
3470 if (emitPartialAddress(TOut, IDLoc, Sym))
3473 TOut.
emitRRX(isABI_N64() ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3477 TOut.
emitRRI(Mips::LD, FirstReg, TmpReg, 0, IDLoc, STI);
3479 TOut.
emitRRI(Mips::LW, FirstReg, TmpReg, 0, IDLoc, STI);
3480 TOut.
emitRRI(Mips::LW,
nextReg(FirstReg), TmpReg, 4, IDLoc, STI);
3485bool MipsAsmParser::expandLoadDoubleImmToFPR(
MCInst &Inst,
bool Is64FPU,
3491 "Invalid instruction operand.");
3498 unsigned TmpReg = Mips::ZERO;
3500 TmpReg = getATReg(IDLoc);
3505 if ((
Lo_32(ImmOp64) == 0) &&
3506 !((
Hi_32(ImmOp64) & 0xffff0000) && (
Hi_32(ImmOp64) & 0x0000ffff))) {
3508 if (TmpReg != Mips::ZERO &&
3509 loadImmediate(ImmOp64, TmpReg, Mips::NoRegister,
false,
false, IDLoc,
3512 TOut.
emitRR(Mips::DMTC1, FirstReg, TmpReg, IDLoc, STI);
3516 if (TmpReg != Mips::ZERO &&
3517 loadImmediate(
Hi_32(ImmOp64), TmpReg, Mips::NoRegister,
true,
false,
3521 if (hasMips32r2()) {
3522 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3523 TOut.
emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, TmpReg, IDLoc, STI);
3525 TOut.
emitRR(Mips::MTC1,
nextReg(FirstReg), TmpReg, IDLoc, STI);
3526 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3531 MCSection *CS = getStreamer().getCurrentSectionOnly();
3537 MCSymbol *Sym = getContext().createTempSymbol();
3543 getStreamer().switchSection(ReadOnlySection);
3544 getStreamer().emitLabel(Sym, IDLoc);
3545 getStreamer().emitValueToAlignment(
Align(8));
3546 getStreamer().emitIntValue(ImmOp64, 8);
3547 getStreamer().switchSection(CS);
3549 if (emitPartialAddress(TOut, IDLoc, Sym))
3552 TOut.
emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, TmpReg,
3558bool MipsAsmParser::expandUncondBranchMMPseudo(
MCInst &Inst,
SMLoc IDLoc,
3564 "unexpected number of operands");
3574 assert(
Offset.isImm() &&
"expected immediate operand kind");
3575 if (isInt<11>(
Offset.getImm())) {
3578 if (inMicroMipsMode())
3579 Inst.
setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3581 if (!isInt<17>(
Offset.getImm()))
3582 return Error(IDLoc,
"branch target out of range");
3584 return Error(IDLoc,
"branch to misaligned address");
3607 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3610 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
3614 "expected immediate or expression operand");
3616 bool IsLikely =
false;
3618 unsigned OpCode = 0;
3626 case Mips::BEQLImmMacro:
3627 OpCode = Mips::BEQL;
3630 case Mips::BNELImmMacro:
3631 OpCode = Mips::BNEL;
3639 int64_t ImmValue = ImmOp.
getImm();
3640 if (ImmValue == 0) {
3644 TOut.
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3646 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3649 warnIfNoMacro(IDLoc);
3651 unsigned ATReg = getATReg(IDLoc);
3655 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(),
true,
3662 TOut.
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3664 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3672 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3673 unsigned StartOp = NumOp == 3 ? 0 : 1;
3676 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3678 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3683 unsigned DstReg = DstRegOp.
getReg();
3684 unsigned BaseReg = BaseRegOp.
getReg();
3685 unsigned TmpReg = DstReg;
3688 int16_t DstRegClass = Desc.
operands()[StartOp].RegClass;
3689 unsigned DstRegClassID =
3690 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3691 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3692 (DstRegClassID == Mips::GPR64RegClassID);
3694 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3697 TmpReg = getATReg(IDLoc);
3704 TOut.
emitRRX(OpCode, DstReg, TmpReg, Off, IDLoc, STI);
3706 TOut.
emitRRRX(OpCode, DstReg, DstReg, TmpReg, Off, IDLoc, STI);
3709 if (OffsetOp.
isImm()) {
3710 int64_t LoOffset = OffsetOp.
getImm() & 0xffff;
3711 int64_t HiOffset = OffsetOp.
getImm() & ~0xffff;
3715 if (LoOffset & 0x8000)
3716 HiOffset += 0x10000;
3718 bool IsLargeOffset = HiOffset != 0;
3720 if (IsLargeOffset) {
3721 bool Is32BitImm = isInt<32>(OffsetOp.
getImm());
3722 if (loadImmediate(HiOffset, TmpReg, Mips::NoRegister, Is32BitImm,
true,
3727 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3728 TOut.
emitRRR(
ABI.ArePtrs64bit() ? Mips::DADDu : Mips::ADDu, TmpReg,
3729 TmpReg, BaseReg, IDLoc, STI);
3744 Error(IDLoc,
"expected relocatable expression");
3747 if (Res.
getSymB() !=
nullptr) {
3748 Error(IDLoc,
"expected relocatable expression with only one symbol");
3752 loadAndAddSymbolAddress(Res.
getSymA(), TmpReg, BaseReg,
3753 !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3773 TOut.
emitRX(Mips::LUi, TmpReg, HighestOperand, IDLoc, STI);
3774 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HigherOperand, IDLoc, STI);
3775 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3776 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HiOperand, IDLoc, STI);
3777 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3778 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3779 TOut.
emitRRR(Mips::DADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3780 emitInstWithOffset(LoOperand);
3783 TOut.
emitRX(Mips::LUi, TmpReg, HiOperand, IDLoc, STI);
3784 if (BaseReg != Mips::ZERO)
3785 TOut.
emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3787 emitInstWithOffset(LoOperand);
3799 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3800 unsigned StartOp = NumOp == 3 ? 0 : 1;
3803 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3805 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3810 unsigned DstReg = DstRegOp.
getReg();
3811 unsigned BaseReg = BaseRegOp.
getReg();
3812 unsigned TmpReg = DstReg;
3815 int16_t DstRegClass = Desc.
operands()[StartOp].RegClass;
3816 unsigned DstRegClassID =
3817 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3818 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3819 (DstRegClassID == Mips::GPR64RegClassID);
3821 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3824 TmpReg = getATReg(IDLoc);
3829 auto emitInst = [&]() {
3837 if (OffsetOp.
isImm()) {
3838 loadImmediate(OffsetOp.
getImm(), TmpReg, BaseReg, !
ABI.ArePtrs64bit(),
true,
3845 loadAndAddSymbolAddress(OffsetOp.
getExpr(), TmpReg, BaseReg,
3846 !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3854bool MipsAsmParser::expandLoadStoreMultiple(
MCInst &Inst,
SMLoc IDLoc,
3859 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3863 Inst.
getOperand(OpNum - 3).
isReg() &&
"Invalid instruction operand.");
3872 if (inMicroMipsMode() && hasMips32r6())
3873 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3875 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3883bool MipsAsmParser::expandCondBranches(
MCInst &Inst,
SMLoc IDLoc,
3887 bool EmittedNoMacroWarning =
false;
3888 unsigned PseudoOpcode = Inst.
getOpcode();
3893 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3894 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3899 else if (TrgOp.
isImm()) {
3900 warnIfNoMacro(IDLoc);
3901 EmittedNoMacroWarning =
true;
3903 TrgReg = getATReg(IDLoc);
3907 switch(PseudoOpcode) {
3910 case Mips::BLTImmMacro:
3911 PseudoOpcode = Mips::BLT;
3913 case Mips::BLEImmMacro:
3914 PseudoOpcode = Mips::BLE;
3916 case Mips::BGEImmMacro:
3917 PseudoOpcode = Mips::BGE;
3919 case Mips::BGTImmMacro:
3920 PseudoOpcode = Mips::BGT;
3922 case Mips::BLTUImmMacro:
3923 PseudoOpcode = Mips::BLTU;
3925 case Mips::BLEUImmMacro:
3926 PseudoOpcode = Mips::BLEU;
3928 case Mips::BGEUImmMacro:
3929 PseudoOpcode = Mips::BGEU;
3931 case Mips::BGTUImmMacro:
3932 PseudoOpcode = Mips::BGTU;
3934 case Mips::BLTLImmMacro:
3935 PseudoOpcode = Mips::BLTL;
3937 case Mips::BLELImmMacro:
3938 PseudoOpcode = Mips::BLEL;
3940 case Mips::BGELImmMacro:
3941 PseudoOpcode = Mips::BGEL;
3943 case Mips::BGTLImmMacro:
3944 PseudoOpcode = Mips::BGTL;
3946 case Mips::BLTULImmMacro:
3947 PseudoOpcode = Mips::BLTUL;
3949 case Mips::BLEULImmMacro:
3950 PseudoOpcode = Mips::BLEUL;
3952 case Mips::BGEULImmMacro:
3953 PseudoOpcode = Mips::BGEUL;
3955 case Mips::BGTULImmMacro:
3956 PseudoOpcode = Mips::BGTUL;
3960 if (loadImmediate(TrgOp.
getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
3961 false, IDLoc, Out, STI))
3965 switch (PseudoOpcode) {
3970 AcceptsEquality =
false;
3971 ReverseOrderSLT =
false;
3973 ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
3974 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
3975 ZeroSrcOpcode = Mips::BGTZ;
3976 ZeroTrgOpcode = Mips::BLTZ;
3982 AcceptsEquality =
true;
3983 ReverseOrderSLT =
true;
3985 ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
3986 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
3987 ZeroSrcOpcode = Mips::BGEZ;
3988 ZeroTrgOpcode = Mips::BLEZ;
3994 AcceptsEquality =
true;
3995 ReverseOrderSLT =
false;
3997 ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
3998 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
3999 ZeroSrcOpcode = Mips::BLEZ;
4000 ZeroTrgOpcode = Mips::BGEZ;
4006 AcceptsEquality =
false;
4007 ReverseOrderSLT =
true;
4009 ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
4010 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
4011 ZeroSrcOpcode = Mips::BLTZ;
4012 ZeroTrgOpcode = Mips::BGTZ;
4018 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
4019 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
4020 if (IsSrcRegZero && IsTrgRegZero) {
4024 if (PseudoOpcode == Mips::BLT) {
4029 if (PseudoOpcode == Mips::BLE) {
4032 Warning(IDLoc,
"branch is always taken");
4035 if (PseudoOpcode == Mips::BGE) {
4038 Warning(IDLoc,
"branch is always taken");
4041 if (PseudoOpcode == Mips::BGT) {
4046 if (PseudoOpcode == Mips::BGTU) {
4047 TOut.
emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
4051 if (AcceptsEquality) {
4054 TOut.
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4056 Warning(IDLoc,
"branch is always taken");
4063 if (IsSrcRegZero || IsTrgRegZero) {
4064 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
4065 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
4072 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
4073 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
4079 TOut.
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4081 Warning(IDLoc,
"branch is always taken");
4097 TOut.
emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
4098 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
4105 TOut.
emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
4106 IsSrcRegZero ? TrgReg : SrcReg,
4113 unsigned ATRegNum = getATReg(IDLoc);
4117 if (!EmittedNoMacroWarning)
4118 warnIfNoMacro(IDLoc);
4135 TOut.
emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
4136 ReverseOrderSLT ? TrgReg : SrcReg,
4137 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
4139 TOut.
emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
4140 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
4156 const bool IsMips64,
const bool Signed) {
4159 warnIfNoMacro(IDLoc);
4162 assert(RdRegOp.
isReg() &&
"expected register operand kind");
4163 unsigned RdReg = RdRegOp.
getReg();
4166 assert(RsRegOp.
isReg() &&
"expected register operand kind");
4167 unsigned RsReg = RsRegOp.
getReg();
4174 "expected register or immediate operand kind");
4178 ImmValue = RtOp.
getImm();
4185 DivOp =
Signed ? Mips::DSDIV : Mips::DUDIV;
4186 ZeroReg = Mips::ZERO_64;
4189 DivOp =
Signed ? Mips::SDIV : Mips::UDIV;
4190 ZeroReg = Mips::ZERO;
4194 bool UseTraps = useTraps();
4197 bool isDiv = Opcode == Mips::SDivMacro || Opcode == Mips::SDivIMacro ||
4198 Opcode == Mips::UDivMacro || Opcode == Mips::UDivIMacro ||
4199 Opcode == Mips::DSDivMacro || Opcode == Mips::DSDivIMacro ||
4200 Opcode == Mips::DUDivMacro || Opcode == Mips::DUDivIMacro;
4202 bool isRem = Opcode == Mips::SRemMacro || Opcode == Mips::SRemIMacro ||
4203 Opcode == Mips::URemMacro || Opcode == Mips::URemIMacro ||
4204 Opcode == Mips::DSRemMacro || Opcode == Mips::DSRemIMacro ||
4205 Opcode == Mips::DURemMacro || Opcode == Mips::DURemIMacro;
4208 unsigned ATReg = getATReg(IDLoc);
4212 if (ImmValue == 0) {
4214 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4216 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4220 if (isRem && (ImmValue == 1 || (
Signed && (ImmValue == -1)))) {
4221 TOut.
emitRRR(Mips::OR, RdReg, ZeroReg, ZeroReg, IDLoc, STI);
4223 }
else if (isDiv && ImmValue == 1) {
4224 TOut.
emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI);
4226 }
else if (isDiv &&
Signed && ImmValue == -1) {
4227 TOut.
emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
4230 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, isInt<32>(ImmValue),
4231 false, Inst.
getLoc(), Out, STI))
4233 TOut.
emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
4234 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4244 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
4246 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4249 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4255 if (isRem && (RdReg == Mips::ZERO || RdReg == Mips::ZERO_64)) {
4256 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4266 TOut.
emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4269 BrTarget =
Context.createTempSymbol();
4271 TOut.
emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4274 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4277 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4283 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4287 unsigned ATReg = getATReg(IDLoc);
4294 TOut.
emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
4302 TOut.
emitRRX(Mips::BNE, RtReg, ATReg, LabelOpEnd, IDLoc, STI);
4305 TOut.
emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
4306 TOut.
emitDSLL(ATReg, ATReg, 63, IDLoc, STI);
4312 TOut.
emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
4315 TOut.
emitRRX(Mips::BNE, RsReg, ATReg, LabelOpEnd, IDLoc, STI);
4317 TOut.
emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
4321 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4325bool MipsAsmParser::expandTrunc(
MCInst &Inst,
bool IsDouble,
bool Is64FPU,
4338 if (hasMips1() && !hasMips2()) {
4339 unsigned ATReg = getATReg(IDLoc);
4342 TOut.
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4343 TOut.
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4345 TOut.
emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4346 TOut.
emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4347 TOut.
emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4349 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4351 FirstReg, SecondReg, IDLoc, STI);
4352 TOut.
emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4357 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4359 FirstReg, SecondReg, IDLoc, STI);
4366 if (hasMips32r6() || hasMips64r6()) {
4367 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4371 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4373 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4375 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4378 unsigned DstReg = DstRegOp.
getReg();
4379 unsigned SrcReg = SrcRegOp.
getReg();
4380 int64_t OffsetValue = OffsetImmOp.
getImm();
4384 warnIfNoMacro(IDLoc);
4385 unsigned ATReg = getATReg(IDLoc);
4389 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4390 if (IsLargeOffset) {
4391 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4396 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4397 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4401 unsigned FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4402 unsigned SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4404 unsigned LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4405 unsigned SllReg = IsLargeOffset ? DstReg : ATReg;
4407 TOut.
emitRRI(
Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4408 FirstOffset, IDLoc, STI);
4409 TOut.
emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4410 TOut.
emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4411 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4418 if (hasMips32r6() || hasMips64r6()) {
4419 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4423 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4425 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4427 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4430 unsigned DstReg = DstRegOp.
getReg();
4431 unsigned SrcReg = SrcRegOp.
getReg();
4432 int64_t OffsetValue = OffsetImmOp.
getImm();
4434 warnIfNoMacro(IDLoc);
4435 unsigned ATReg = getATReg(IDLoc);
4439 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4440 if (IsLargeOffset) {
4441 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4446 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4447 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4451 if (IsLargeOffset) {
4452 TOut.
emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4453 TOut.
emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4454 TOut.
emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4455 TOut.
emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4456 TOut.
emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4457 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4459 TOut.
emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4460 TOut.
emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4461 TOut.
emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4469 if (hasMips32r6() || hasMips64r6()) {
4470 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4474 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4476 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4478 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4481 unsigned DstReg = DstRegOp.
getReg();
4482 unsigned SrcReg = SrcRegOp.
getReg();
4483 int64_t OffsetValue = OffsetImmOp.
getImm();
4486 bool IsLargeOffset = !(isInt<16>(OffsetValue + 3) && isInt<16>(OffsetValue));
4487 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4488 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4492 bool IsLoadInst = (Inst.
getOpcode() == Mips::Ulw);
4493 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4494 unsigned TmpReg = SrcReg;
4495 if (IsLargeOffset || DoMove) {
4496 warnIfNoMacro(IDLoc);
4497 TmpReg = getATReg(IDLoc);
4502 if (IsLargeOffset) {
4503 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4511 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4512 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4513 TOut.
emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4514 TOut.
emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4517 TOut.
emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4536 warnIfNoMacro(IDLoc);
4543 OpCode = Mips::SLTu;
4550 TOut.
emitRRR(OpCode, DstReg, SrcReg, OpReg, IDLoc, STI);
4551 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4568 unsigned OpRegCode, OpImmCode;
4570 warnIfNoMacro(IDLoc);
4574 case Mips::SGEImm64:
4575 OpRegCode = Mips::SLT;
4576 OpImmCode = Mips::SLTi;
4579 case Mips::SGEUImm64:
4580 OpRegCode = Mips::SLTu;
4581 OpImmCode = Mips::SLTiu;
4588 if (isInt<16>(ImmValue)) {
4590 TOut.
emitRRI(OpImmCode, DstReg, SrcReg, ImmValue, IDLoc, STI);
4591 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4593 unsigned ImmReg = DstReg;
4594 if (DstReg == SrcReg) {
4595 unsigned ATReg = getATReg(Inst.
getLoc());
4601 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4602 false, IDLoc, Out, STI))
4605 TOut.
emitRRR(OpRegCode, DstReg, SrcReg, ImmReg, IDLoc, STI);
4606 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4623 unsigned ImmReg = DstReg;
4627 warnIfNoMacro(IDLoc);
4631 case Mips::SGTImm64:
4635 case Mips::SGTUImm64:
4636 OpCode = Mips::SLTu;
4642 if (DstReg == SrcReg) {
4643 unsigned ATReg = getATReg(Inst.
getLoc());
4649 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4650 false, IDLoc, Out, STI))
4654 TOut.
emitRRR(OpCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4673 warnIfNoMacro(IDLoc);
4680 OpCode = Mips::SLTu;
4687 TOut.
emitRRR(OpCode, DstReg, OpReg, SrcReg, IDLoc, STI);
4688 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4707 warnIfNoMacro(IDLoc);
4711 case Mips::SLEImm64:
4712 OpRegCode = Mips::SLT;
4715 case Mips::SLEUImm64:
4716 OpRegCode = Mips::SLTu;
4723 unsigned ImmReg = DstReg;
4724 if (DstReg == SrcReg) {
4725 unsigned ATReg = getATReg(Inst.
getLoc());
4731 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4732 false, IDLoc, Out, STI))
4735 TOut.
emitRRR(OpRegCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4736 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4741bool MipsAsmParser::expandAliasImmediate(
MCInst &Inst,
SMLoc IDLoc,
4751 unsigned ATReg = Mips::NoRegister;
4752 unsigned FinalDstReg = Mips::NoRegister;
4757 bool Is32Bit = isInt<32>(ImmValue) || (!isGP64bit() && isUInt<32>(ImmValue));
4759 unsigned FinalOpcode = Inst.
getOpcode();
4761 if (DstReg == SrcReg) {
4762 ATReg = getATReg(Inst.
getLoc());
4765 FinalDstReg = DstReg;
4769 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit,
false,
4770 Inst.
getLoc(), Out, STI)) {
4771 switch (FinalOpcode) {
4775 FinalOpcode = Mips::ADD;
4778 FinalOpcode = Mips::ADDu;
4781 FinalOpcode = Mips::AND;
4784 FinalOpcode = Mips::NOR;
4787 FinalOpcode = Mips::OR;
4790 FinalOpcode = Mips::SLT;
4793 FinalOpcode = Mips::SLTu;
4796 FinalOpcode = Mips::XOR;
4799 FinalOpcode = Mips::ADD_MM;
4801 case Mips::ADDiu_MM:
4802 FinalOpcode = Mips::ADDu_MM;
4805 FinalOpcode = Mips::AND_MM;
4808 FinalOpcode = Mips::OR_MM;
4811 FinalOpcode = Mips::SLT_MM;
4813 case Mips::SLTiu_MM:
4814 FinalOpcode = Mips::SLTu_MM;
4817 FinalOpcode = Mips::XOR_MM;
4820 FinalOpcode = Mips::AND64;
4822 case Mips::NORImm64:
4823 FinalOpcode = Mips::NOR64;
4826 FinalOpcode = Mips::OR64;
4828 case Mips::SLTImm64:
4829 FinalOpcode = Mips::SLT64;
4831 case Mips::SLTUImm64:
4832 FinalOpcode = Mips::SLTu64;
4835 FinalOpcode = Mips::XOR64;
4839 if (FinalDstReg == Mips::NoRegister)
4840 TOut.
emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4842 TOut.
emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4851 unsigned ATReg = Mips::NoRegister;
4855 unsigned TmpReg =
DReg;
4857 unsigned FirstShift = Mips::NOP;
4858 unsigned SecondShift = Mips::NOP;
4860 if (hasMips32r2()) {
4862 TmpReg = getATReg(Inst.
getLoc());
4868 TOut.
emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4869 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
4874 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
4886 FirstShift = Mips::SRLV;
4887 SecondShift = Mips::SLLV;
4890 FirstShift = Mips::SLLV;
4891 SecondShift = Mips::SRLV;
4895 ATReg = getATReg(Inst.
getLoc());
4899 TOut.
emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4900 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
4901 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
4902 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
4910bool MipsAsmParser::expandRotationImm(
MCInst &Inst,
SMLoc IDLoc,
4914 unsigned ATReg = Mips::NoRegister;
4919 unsigned FirstShift = Mips::NOP;
4920 unsigned SecondShift = Mips::NOP;
4922 if (hasMips32r2()) {
4927 ShiftValue = MaxShift - ImmValue;
4928 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
4933 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.
getLoc(), STI);
4941 if (ImmValue == 0) {
4950 FirstShift = Mips::SLL;
4951 SecondShift = Mips::SRL;
4954 FirstShift = Mips::SRL;
4955 SecondShift = Mips::SLL;
4959 ATReg = getATReg(Inst.
getLoc());
4963 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.
getLoc(), STI);
4964 TOut.
emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.
getLoc(), STI);
4965 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
4976 unsigned ATReg = Mips::NoRegister;
4980 unsigned TmpReg =
DReg;
4982 unsigned FirstShift = Mips::NOP;
4983 unsigned SecondShift = Mips::NOP;
4985 if (hasMips64r2()) {
4986 if (TmpReg == SReg) {
4987 TmpReg = getATReg(Inst.
getLoc());
4993 TOut.
emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4994 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
4999 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
5011 FirstShift = Mips::DSRLV;
5012 SecondShift = Mips::DSLLV;
5015 FirstShift = Mips::DSLLV;
5016 SecondShift = Mips::DSRLV;
5020 ATReg = getATReg(Inst.
getLoc());
5024 TOut.
emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
5025 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
5026 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
5027 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5035bool MipsAsmParser::expandDRotationImm(
MCInst &Inst,
SMLoc IDLoc,
5039 unsigned ATReg = Mips::NoRegister;
5044 unsigned FirstShift = Mips::NOP;
5045 unsigned SecondShift = Mips::NOP;
5049 if (hasMips64r2()) {
5050 unsigned FinalOpcode = Mips::NOP;
5052 FinalOpcode = Mips::DROTR;
5053 else if (ImmValue % 32 == 0)
5054 FinalOpcode = Mips::DROTR32;
5055 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
5057 FinalOpcode = Mips::DROTR32;
5059 FinalOpcode = Mips::DROTR;
5060 }
else if (ImmValue >= 33) {
5062 FinalOpcode = Mips::DROTR;
5064 FinalOpcode = Mips::DROTR32;
5067 uint64_t ShiftValue = ImmValue % 32;
5069 ShiftValue = (32 - ImmValue % 32) % 32;
5071 TOut.
emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
5077 if (ImmValue == 0) {
5078 TOut.
emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.
getLoc(), STI);
5086 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5087 FirstShift = Mips::DSLL;
5088 SecondShift = Mips::DSRL32;
5090 if (ImmValue == 32) {
5091 FirstShift = Mips::DSLL32;
5092 SecondShift = Mips::DSRL32;
5094 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5095 FirstShift = Mips::DSLL32;
5096 SecondShift = Mips::DSRL;
5100 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5101 FirstShift = Mips::DSRL;
5102 SecondShift = Mips::DSLL32;
5104 if (ImmValue == 32) {
5105 FirstShift = Mips::DSRL32;
5106 SecondShift = Mips::DSLL32;
5108 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5109 FirstShift = Mips::DSRL32;
5110 SecondShift = Mips::DSLL;
5115 ATReg = getATReg(Inst.
getLoc());
5119 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.
getLoc(), STI);
5120 TOut.
emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
5122 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5136 TOut.
emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
5137 if (FirstRegOp != SecondRegOp)
5138 TOut.
emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
5141 TOut.
emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
5149 unsigned ATReg = Mips::NoRegister;
5154 ATReg = getATReg(IDLoc);
5158 loadImmediate(ImmValue, ATReg, Mips::NoRegister,
true,
false, IDLoc, Out,
5161 TOut.
emitRR(Inst.
getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
5162 SrcReg, ATReg, IDLoc, STI);
5164 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5172 unsigned ATReg = Mips::NoRegister;
5177 ATReg = getATReg(Inst.
getLoc());
5181 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
5182 SrcReg, TmpReg, IDLoc, STI);
5184 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5186 TOut.
emitRRI(Inst.
getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
5187 DstReg, DstReg, 0x1F, IDLoc, STI);
5189 TOut.
emitR(Mips::MFHI, ATReg, IDLoc, STI);
5192 TOut.
emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
5199 TOut.
emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
5200 if (AssemblerOptions.
back()->isReorder())
5202 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5206 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5214 unsigned ATReg = Mips::NoRegister;
5219 ATReg = getATReg(IDLoc);
5223 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
5224 SrcReg, TmpReg, IDLoc, STI);
5226 TOut.
emitR(Mips::MFHI, ATReg, IDLoc, STI);
5227 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5229 TOut.
emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);