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;
184 SMLoc &EndLoc)
override;
190 bool mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID);
213 enum MacroExpanderResultTy {
220 MacroExpanderResultTy tryExpandInstruction(
MCInst &Inst,
SMLoc IDLoc,
227 bool loadImmediate(int64_t ImmValue,
unsigned DstReg,
unsigned SrcReg,
228 bool Is32BitImm,
bool IsAddress,
SMLoc IDLoc,
231 bool loadAndAddSymbolAddress(
const MCExpr *SymExpr,
unsigned DstReg,
232 unsigned SrcReg,
bool Is32BitSym,
SMLoc IDLoc,
237 bool expandLoadImm(
MCInst &Inst,
bool Is32BitImm,
SMLoc IDLoc,
246 bool expandLoadDoubleImmToFPR(
MCInst &Inst,
bool Is64FPU,
SMLoc IDLoc,
249 bool expandLoadAddress(
unsigned DstReg,
unsigned BaseReg,
278 bool expandTrunc(
MCInst &Inst,
bool IsDouble,
bool Is64FPU,
SMLoc IDLoc,
353 bool reportParseError(
const Twine &ErrorMsg);
354 bool reportParseError(
SMLoc Loc,
const Twine &ErrorMsg);
356 bool parseMemOffset(
const MCExpr *&Res,
bool isParenExpr);
358 bool parseSetMips0Directive();
359 bool parseSetArchDirective();
360 bool parseSetFeature(
uint64_t Feature);
361 bool isPicAndNotNxxAbi();
362 bool parseDirectiveCpAdd(
SMLoc Loc);
363 bool parseDirectiveCpLoad(
SMLoc Loc);
364 bool parseDirectiveCpLocal(
SMLoc Loc);
365 bool parseDirectiveCpRestore(
SMLoc Loc);
366 bool parseDirectiveCPSetup();
367 bool parseDirectiveCPReturn();
368 bool parseDirectiveNaN();
369 bool parseDirectiveSet();
370 bool parseDirectiveOption();
371 bool parseInsnDirective();
372 bool parseRSectionDirective(
StringRef Section);
373 bool parseSSectionDirective(
StringRef Section,
unsigned Type);
375 bool parseSetAtDirective();
376 bool parseSetNoAtDirective();
377 bool parseSetMacroDirective();
378 bool parseSetNoMacroDirective();
379 bool parseSetMsaDirective();
380 bool parseSetNoMsaDirective();
381 bool parseSetNoDspDirective();
382 bool parseSetNoMips3DDirective();
383 bool parseSetReorderDirective();
384 bool parseSetNoReorderDirective();
385 bool parseSetMips16Directive();
386 bool parseSetNoMips16Directive();
387 bool parseSetFpDirective();
388 bool parseSetOddSPRegDirective();
389 bool parseSetNoOddSPRegDirective();
390 bool parseSetPopDirective();
391 bool parseSetPushDirective();
392 bool parseSetSoftFloatDirective();
393 bool parseSetHardFloatDirective();
394 bool parseSetMtDirective();
395 bool parseSetNoMtDirective();
396 bool parseSetNoCRCDirective();
397 bool parseSetNoVirtDirective();
398 bool parseSetNoGINVDirective();
400 bool parseSetAssignment();
402 bool parseDirectiveGpWord();
403 bool parseDirectiveGpDWord();
404 bool parseDirectiveDtpRelWord();
405 bool parseDirectiveDtpRelDWord();
406 bool parseDirectiveTpRelWord();
407 bool parseDirectiveTpRelDWord();
408 bool parseDirectiveModule();
409 bool parseDirectiveModuleFP();
413 bool parseInternalDirectiveReallowModule();
417 int matchCPURegisterName(
StringRef Symbol);
419 int matchHWRegsRegisterName(
StringRef Symbol);
431 unsigned getReg(
int RC,
int RegNo);
436 unsigned getATReg(
SMLoc Loc);
446 bool validateMSAIndex(
int Val,
int RegKind);
473 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
481 if (!(
getSTI().hasFeature(Feature))) {
490 if (
getSTI().hasFeature(Feature)) {
499 setFeatureBits(Feature, FeatureString);
500 AssemblerOptions.
front()->setFeatures(
getSTI().getFeatureBits());
504 clearFeatureBits(Feature, FeatureString);
505 AssemblerOptions.
front()->setFeatures(
getSTI().getFeatureBits());
509 enum MipsMatchResultTy {
511 Match_RequiresDifferentOperands,
512 Match_RequiresNoZeroRegister,
513 Match_RequiresSameSrcAndDst,
514 Match_NoFCCRegisterForCurrentISA,
515 Match_NonZeroOperandForSync,
516 Match_NonZeroOperandForMTCX,
517 Match_RequiresPosSizeRange0_32,
518 Match_RequiresPosSizeRange33_64,
519 Match_RequiresPosSizeUImm6,
520#define GET_OPERAND_DIAGNOSTIC_TYPES
521#include "MipsGenAsmMatcher.inc"
522#undef GET_OPERAND_DIAGNOSTIC_TYPES
542 std::make_unique<MipsAssemblerOptions>(
getSTI().getFeatureBits()));
546 std::make_unique<MipsAssemblerOptions>(
getSTI().getFeatureBits()));
548 getTargetStreamer().updateABIInfo(*
this);
550 if (!isABI_O32() && !useOddSPReg() != 0)
557 IsCpRestoreSet =
false;
558 CpRestoreOffset = -1;
559 GPReg =
ABI.GetGlobalPtr();
564 if (
getSTI().
getCPU() ==
"mips64r6" && inMicroMipsMode())
567 if (!isABI_O32() && inMicroMipsMode())
572 bool hasEightFccRegisters()
const {
return hasMips4() || hasMips32(); }
574 bool isGP64bit()
const {
578 bool isFP64bit()
const {
582 bool isJalrRelocAvailable(
const MCExpr *JalExpr) {
591 return ABI.IsN32() ||
ABI.IsN64();
596 bool isABI_N32()
const {
return ABI.IsN32(); }
597 bool isABI_N64()
const {
return ABI.IsN64(); }
598 bool isABI_O32()
const {
return ABI.IsO32(); }
599 bool isABI_FPXX()
const {
603 bool useOddSPReg()
const {
607 bool inMicroMipsMode()
const {
611 bool hasMips1()
const {
615 bool hasMips2()
const {
619 bool hasMips3()
const {
623 bool hasMips4()
const {
627 bool hasMips5()
const {
631 bool hasMips32()
const {
635 bool hasMips64()
const {
639 bool hasMips32r2()
const {
643 bool hasMips64r2()
const {
647 bool hasMips32r3()
const {
648 return (
getSTI().hasFeature(Mips::FeatureMips32r3));
651 bool hasMips64r3()
const {
652 return (
getSTI().hasFeature(Mips::FeatureMips64r3));
655 bool hasMips32r5()
const {
656 return (
getSTI().hasFeature(Mips::FeatureMips32r5));
659 bool hasMips64r5()
const {
660 return (
getSTI().hasFeature(Mips::FeatureMips64r5));
663 bool hasMips32r6()
const {
667 bool hasMips64r6()
const {
671 bool hasDSP()
const {
675 bool hasDSPR2()
const {
679 bool hasDSPR3()
const {
683 bool hasMSA()
const {
687 bool hasCnMips()
const {
688 return (
getSTI().hasFeature(Mips::FeatureCnMips));
691 bool hasCnMipsP()
const {
692 return (
getSTI().hasFeature(Mips::FeatureCnMipsP));
699 bool inMips16Mode()
const {
703 bool useTraps()
const {
707 bool useSoftFloat()
const {
714 bool hasCRC()
const {
718 bool hasVirt()
const {
722 bool hasGINV()
const {
727 void warnIfRegIndexIsAT(
unsigned RegIndex,
SMLoc Loc);
729 void warnIfNoMacro(
SMLoc Loc);
731 bool isLittle()
const {
return IsLittleEndian; }
736 switch(OperatorToken) {
807 RegKind_MSACtrl = 16,
812 RegKind_HWRegs = 256,
816 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
817 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
818 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
831 MipsOperand(KindTy K, MipsAsmParser &Parser) :
Kind(
K), AsmParser(Parser) {}
833 ~MipsOperand()
override {
842 case k_RegisterIndex:
850 MipsAsmParser &AsmParser;
879 struct RegIdxOp RegIdx;
882 struct RegListOp RegList;
885 SMLoc StartLoc, EndLoc;
888 static std::unique_ptr<MipsOperand> CreateReg(
unsigned Index,
StringRef Str,
892 MipsAsmParser &Parser) {
893 auto Op = std::make_unique<MipsOperand>(k_RegisterIndex, Parser);
896 Op->RegIdx.Kind = RegKind;
897 Op->RegIdx.Tok.Data = Str.data();
898 Op->RegIdx.Tok.Length = Str.size();
907 unsigned getGPR32Reg()
const {
908 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
909 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
910 unsigned ClassID = Mips::GPR32RegClassID;
911 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
916 unsigned getGPRMM16Reg()
const {
917 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
918 unsigned ClassID = Mips::GPR32RegClassID;
919 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
924 unsigned getGPR64Reg()
const {
925 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
926 unsigned ClassID = Mips::GPR64RegClassID;
927 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
933 unsigned getAFGR64Reg()
const {
934 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
935 if (RegIdx.Index % 2 != 0)
936 AsmParser.Warning(StartLoc,
"Float register should be even.");
937 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
938 .getRegister(RegIdx.Index / 2);
943 unsigned getFGR64Reg()
const {
944 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
945 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
946 .getRegister(RegIdx.Index);
951 unsigned getFGR32Reg()
const {
952 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
953 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
954 .getRegister(RegIdx.Index);
959 unsigned getFCCReg()
const {
960 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) &&
"Invalid access!");
961 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
962 .getRegister(RegIdx.Index);
967 unsigned getMSA128Reg()
const {
968 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) &&
"Invalid access!");
971 unsigned ClassID = Mips::MSA128BRegClassID;
972 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
977 unsigned getMSACtrlReg()
const {
978 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) &&
"Invalid access!");
979 unsigned ClassID = Mips::MSACtrlRegClassID;
980 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
985 unsigned getCOP0Reg()
const {
986 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) &&
"Invalid access!");
987 unsigned ClassID = Mips::COP0RegClassID;
988 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
993 unsigned getCOP2Reg()
const {
994 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) &&
"Invalid access!");
995 unsigned ClassID = Mips::COP2RegClassID;
996 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1001 unsigned getCOP3Reg()
const {
1002 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) &&
"Invalid access!");
1003 unsigned ClassID = Mips::COP3RegClassID;
1004 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1009 unsigned getACC64DSPReg()
const {
1010 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
1011 unsigned ClassID = Mips::ACC64DSPRegClassID;
1012 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1017 unsigned getHI32DSPReg()
const {
1018 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
1019 unsigned ClassID = Mips::HI32DSPRegClassID;
1020 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1025 unsigned getLO32DSPReg()
const {
1026 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
1027 unsigned ClassID = Mips::LO32DSPRegClassID;
1028 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1033 unsigned getCCRReg()
const {
1034 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) &&
"Invalid access!");
1035 unsigned ClassID = Mips::CCRRegClassID;
1036 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1041 unsigned getHWRegsReg()
const {
1042 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) &&
"Invalid access!");
1043 unsigned ClassID = Mips::HWRegsRegClassID;
1044 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1052 else if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
1058 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
1065 void addGPR32ZeroAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1066 assert(
N == 1 &&
"Invalid number of operands!");
1070 void addGPR32NonZeroAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1071 assert(
N == 1 &&
"Invalid number of operands!");
1075 void addGPR32AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1076 assert(
N == 1 &&
"Invalid number of operands!");
1080 void addGPRMM16AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1081 assert(
N == 1 &&
"Invalid number of operands!");
1085 void addGPRMM16AsmRegZeroOperands(
MCInst &Inst,
unsigned N)
const {
1086 assert(
N == 1 &&
"Invalid number of operands!");
1090 void addGPRMM16AsmRegMovePOperands(
MCInst &Inst,
unsigned N)
const {
1091 assert(
N == 1 &&
"Invalid number of operands!");
1095 void addGPRMM16AsmRegMovePPairFirstOperands(
MCInst &Inst,
unsigned N)
const {
1096 assert(
N == 1 &&
"Invalid number of operands!");
1100 void addGPRMM16AsmRegMovePPairSecondOperands(
MCInst &Inst,
1102 assert(
N == 1 &&
"Invalid number of operands!");
1109 void addGPR64AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1110 assert(
N == 1 &&
"Invalid number of operands!");
1114 void addAFGR64AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1115 assert(
N == 1 &&
"Invalid number of operands!");
1119 void addStrictlyAFGR64AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1120 assert(
N == 1 &&
"Invalid number of operands!");
1124 void addStrictlyFGR64AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1125 assert(
N == 1 &&
"Invalid number of operands!");
1129 void addFGR64AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1130 assert(
N == 1 &&
"Invalid number of operands!");
1134 void addFGR32AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1135 assert(
N == 1 &&
"Invalid number of operands!");
1139 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1140 AsmParser.getParser().printError(
1141 StartLoc,
"-mno-odd-spreg prohibits the use of odd FPU "
1145 void addStrictlyFGR32AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1146 assert(
N == 1 &&
"Invalid number of operands!");
1149 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1150 AsmParser.Error(StartLoc,
"-mno-odd-spreg prohibits the use of odd FPU "
1154 void addFCCAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1155 assert(
N == 1 &&
"Invalid number of operands!");
1159 void addMSA128AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1160 assert(
N == 1 &&
"Invalid number of operands!");
1164 void addMSACtrlAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1165 assert(
N == 1 &&
"Invalid number of operands!");
1169 void addCOP0AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1170 assert(
N == 1 &&
"Invalid number of operands!");
1174 void addCOP2AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1175 assert(
N == 1 &&
"Invalid number of operands!");
1179 void addCOP3AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1180 assert(
N == 1 &&
"Invalid number of operands!");
1184 void addACC64DSPAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1185 assert(
N == 1 &&
"Invalid number of operands!");
1189 void addHI32DSPAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1190 assert(
N == 1 &&
"Invalid number of operands!");
1194 void addLO32DSPAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1195 assert(
N == 1 &&
"Invalid number of operands!");
1199 void addCCRAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1200 assert(
N == 1 &&
"Invalid number of operands!");
1204 void addHWRegsAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1205 assert(
N == 1 &&
"Invalid number of operands!");
1209 template <
unsigned Bits,
int Offset = 0,
int AdjustOffset = 0>
1210 void addConstantUImmOperands(
MCInst &Inst,
unsigned N)
const {
1211 assert(
N == 1 &&
"Invalid number of operands!");
1215 Imm += AdjustOffset;
1219 template <
unsigned Bits>
1220 void addSImmOperands(
MCInst &Inst,
unsigned N)
const {
1221 if (
isImm() && !isConstantImm()) {
1222 addExpr(Inst, getImm());
1225 addConstantSImmOperands<Bits, 0, 0>(Inst,
N);
1228 template <
unsigned Bits>
1229 void addUImmOperands(
MCInst &Inst,
unsigned N)
const {
1230 if (
isImm() && !isConstantImm()) {
1231 addExpr(Inst, getImm());
1234 addConstantUImmOperands<Bits, 0, 0>(Inst,
N);
1237 template <
unsigned Bits,
int Offset = 0,
int AdjustOffset = 0>
1238 void addConstantSImmOperands(
MCInst &Inst,
unsigned N)
const {
1239 assert(
N == 1 &&
"Invalid number of operands!");
1240 int64_t
Imm = getConstantImm() -
Offset;
1241 Imm = SignExtend64<Bits>(Imm);
1243 Imm += AdjustOffset;
1247 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
1248 assert(
N == 1 &&
"Invalid number of operands!");
1249 const MCExpr *Expr = getImm();
1250 addExpr(Inst, Expr);
1253 void addMemOperands(
MCInst &Inst,
unsigned N)
const {
1254 assert(
N == 2 &&
"Invalid number of operands!");
1257 ? getMemBase()->getGPR64Reg()
1258 : getMemBase()->getGPR32Reg()));
1260 const MCExpr *Expr = getMemOff();
1261 addExpr(Inst, Expr);
1264 void addMicroMipsMemOperands(
MCInst &Inst,
unsigned N)
const {
1265 assert(
N == 2 &&
"Invalid number of operands!");
1269 const MCExpr *Expr = getMemOff();
1270 addExpr(Inst, Expr);
1273 void addRegListOperands(
MCInst &Inst,
unsigned N)
const {
1274 assert(
N == 1 &&
"Invalid number of operands!");
1276 for (
auto RegNo : getRegList())
1280 bool isReg()
const override {
1283 return isGPRAsmReg() && RegIdx.Index == 0;
1286 bool isRegIdx()
const {
return Kind == k_RegisterIndex; }
1287 bool isImm()
const override {
return Kind == k_Immediate; }
1289 bool isConstantImm()
const {
1291 return isImm() && getImm()->evaluateAsAbsolute(Res);
1294 bool isConstantImmz()
const {
1295 return isConstantImm() && getConstantImm() == 0;
1298 template <
unsigned Bits,
int Offset = 0>
bool isConstantUImm()
const {
1299 return isConstantImm() && isUInt<Bits>(getConstantImm() -
Offset);
1302 template <
unsigned Bits>
bool isSImm()
const {
1303 return isConstantImm() ? isInt<Bits>(getConstantImm()) :
isImm();
1306 template <
unsigned Bits>
bool isUImm()
const {
1307 return isConstantImm() ? isUInt<Bits>(getConstantImm()) :
isImm();
1310 template <
unsigned Bits>
bool isAnyImm()
const {
1311 return isConstantImm() ? (isInt<Bits>(getConstantImm()) ||
1312 isUInt<Bits>(getConstantImm()))
1316 template <
unsigned Bits,
int Offset = 0>
bool isConstantSImm()
const {
1317 return isConstantImm() && isInt<Bits>(getConstantImm() -
Offset);
1320 template <
unsigned Bottom,
unsigned Top>
bool isConstantUImmRange()
const {
1321 return isConstantImm() && getConstantImm() >= Bottom &&
1322 getConstantImm() <= Top;
1325 bool isToken()
const override {
1328 return Kind == k_Token;
1331 bool isMem()
const override {
return Kind == k_Memory; }
1333 bool isConstantMemOff()
const {
1334 return isMem() && isa<MCConstantExpr>(getMemOff());
1338 template <
unsigned Bits,
unsigned ShiftAmount = 0>
1339 bool isMemWithSimmOffset()
const {
1342 if (!getMemBase()->isGPRAsmReg())
1344 if (isa<MCTargetExpr>(getMemOff()) ||
1345 (isConstantMemOff() &&
1346 isShiftedInt<Bits, ShiftAmount>(getConstantMemOff())))
1349 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res,
nullptr,
nullptr);
1350 return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.
getConstant());
1353 bool isMemWithPtrSizeOffset()
const {
1356 if (!getMemBase()->isGPRAsmReg())
1358 const unsigned PtrBits = AsmParser.getABI().ArePtrs64bit() ? 64 : 32;
1359 if (isa<MCTargetExpr>(getMemOff()) ||
1360 (isConstantMemOff() &&
isIntN(PtrBits, getConstantMemOff())))
1363 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res,
nullptr,
nullptr);
1367 bool isMemWithGRPMM16Base()
const {
1368 return isMem() && getMemBase()->isMM16AsmReg();
1371 template <
unsigned Bits>
bool isMemWithUimmOffsetSP()
const {
1372 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1373 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1376 template <
unsigned Bits>
bool isMemWithUimmWordAlignedOffsetSP()
const {
1377 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1378 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1379 && (getMemBase()->getGPR32Reg() == Mips::SP);
1382 template <
unsigned Bits>
bool isMemWithSimmWordAlignedOffsetGP()
const {
1383 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
1384 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1385 && (getMemBase()->getGPR32Reg() == Mips::GP);
1388 template <
unsigned Bits,
unsigned ShiftLeftAmount>
1389 bool isScaledUImm()
const {
1390 return isConstantImm() &&
1391 isShiftedUInt<Bits, ShiftLeftAmount>(getConstantImm());
1394 template <
unsigned Bits,
unsigned ShiftLeftAmount>
1395 bool isScaledSImm()
const {
1396 if (isConstantImm() &&
1397 isShiftedInt<Bits, ShiftLeftAmount>(getConstantImm()))
1401 if (Kind != k_Immediate)
1404 bool Success = getImm()->evaluateAsRelocatable(Res,
nullptr,
nullptr);
1408 bool isRegList16()
const {
1412 int Size = RegList.List->size();
1413 if (Size < 2 || Size > 5)
1416 unsigned R0 = RegList.List->front();
1417 unsigned R1 = RegList.List->back();
1418 if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1419 (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1422 int PrevReg = *RegList.List->begin();
1423 for (
int i = 1; i <
Size - 1; i++) {
1424 int Reg = (*(RegList.List))[i];
1425 if (
Reg != PrevReg + 1)
1433 bool isInvNum()
const {
return Kind == k_Immediate; }
1435 bool isLSAImm()
const {
1436 if (!isConstantImm())
1438 int64_t Val = getConstantImm();
1439 return 1 <= Val && Val <= 4;
1442 bool isRegList()
const {
return Kind == k_RegList; }
1445 assert(Kind == k_Token &&
"Invalid access!");
1449 unsigned getReg()
const override {
1452 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1453 RegIdx.Kind & RegKind_GPR)
1454 return getGPR32Reg();
1460 const MCExpr *getImm()
const {
1461 assert((Kind == k_Immediate) &&
"Invalid access!");
1465 int64_t getConstantImm()
const {
1466 const MCExpr *Val = getImm();
1468 (void)Val->evaluateAsAbsolute(
Value);
1472 MipsOperand *getMemBase()
const {
1473 assert((Kind == k_Memory) &&
"Invalid access!");
1477 const MCExpr *getMemOff()
const {
1478 assert((Kind == k_Memory) &&
"Invalid access!");
1482 int64_t getConstantMemOff()
const {
1483 return static_cast<const MCConstantExpr *
>(getMemOff())->getValue();
1487 assert((Kind == k_RegList) &&
"Invalid access!");
1488 return *(RegList.List);
1491 static std::unique_ptr<MipsOperand> CreateToken(
StringRef Str,
SMLoc S,
1492 MipsAsmParser &Parser) {
1493 auto Op = std::make_unique<MipsOperand>(k_Token, Parser);
1494 Op->Tok.Data = Str.data();
1495 Op->Tok.Length = Str.size();
1503 static std::unique_ptr<MipsOperand>
1507 return CreateReg(
Index, Str, RegKind_Numeric,
RegInfo, S,
E, Parser);
1512 static std::unique_ptr<MipsOperand>
1515 return CreateReg(
Index, Str, RegKind_GPR,
RegInfo, S,
E, Parser);
1520 static std::unique_ptr<MipsOperand>
1523 return CreateReg(
Index, Str, RegKind_FGR,
RegInfo, S,
E, Parser);
1528 static std::unique_ptr<MipsOperand>
1531 return CreateReg(
Index, Str, RegKind_HWRegs,
RegInfo, S,
E, Parser);
1536 static std::unique_ptr<MipsOperand>
1539 return CreateReg(
Index, Str, RegKind_FCC,
RegInfo, S,
E, Parser);
1544 static std::unique_ptr<MipsOperand>
1547 return CreateReg(
Index, Str, RegKind_ACC,
RegInfo, S,
E, Parser);
1552 static std::unique_ptr<MipsOperand>
1555 return CreateReg(
Index, Str, RegKind_MSA128,
RegInfo, S,
E, Parser);
1560 static std::unique_ptr<MipsOperand>
1563 return CreateReg(
Index, Str, RegKind_MSACtrl,
RegInfo, S,
E, Parser);
1566 static std::unique_ptr<MipsOperand>
1568 auto Op = std::make_unique<MipsOperand>(k_Immediate, Parser);
1575 static std::unique_ptr<MipsOperand>
1576 CreateMem(std::unique_ptr<MipsOperand>
Base,
const MCExpr *Off,
SMLoc S,
1577 SMLoc E, MipsAsmParser &Parser) {
1578 auto Op = std::make_unique<MipsOperand>(k_Memory, Parser);
1579 Op->Mem.Base =
Base.release();
1586 static std::unique_ptr<MipsOperand>
1588 MipsAsmParser &Parser) {
1589 assert(Regs.
size() > 0 &&
"Empty list not allowed");
1591 auto Op = std::make_unique<MipsOperand>(k_RegList, Parser);
1593 Op->StartLoc = StartLoc;
1594 Op->EndLoc = EndLoc;
1598 bool isGPRZeroAsmReg()
const {
1599 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
1602 bool isGPRNonZeroAsmReg()
const {
1603 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index > 0 &&
1607 bool isGPRAsmReg()
const {
1608 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1611 bool isMM16AsmReg()
const {
1612 if (!(isRegIdx() && RegIdx.Kind))
1614 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1615 || RegIdx.Index == 16 || RegIdx.Index == 17);
1618 bool isMM16AsmRegZero()
const {
1619 if (!(isRegIdx() && RegIdx.Kind))
1621 return (RegIdx.Index == 0 ||
1622 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1623 RegIdx.Index == 17);
1626 bool isMM16AsmRegMoveP()
const {
1627 if (!(isRegIdx() && RegIdx.Kind))
1629 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1630 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1633 bool isMM16AsmRegMovePPairFirst()
const {
1634 if (!(isRegIdx() && RegIdx.Kind))
1636 return RegIdx.Index >= 4 && RegIdx.Index <= 6;
1639 bool isMM16AsmRegMovePPairSecond()
const {
1640 if (!(isRegIdx() && RegIdx.Kind))
1642 return (RegIdx.Index == 21 || RegIdx.Index == 22 ||
1643 (RegIdx.Index >= 5 && RegIdx.Index <= 7));
1646 bool isFGRAsmReg()
const {
1648 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1651 bool isStrictlyFGRAsmReg()
const {
1653 return isRegIdx() && RegIdx.Kind == RegKind_FGR && RegIdx.Index <= 31;
1656 bool isHWRegsAsmReg()
const {
1657 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1660 bool isCCRAsmReg()
const {
1661 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1664 bool isFCCAsmReg()
const {
1665 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1667 return RegIdx.Index <= 7;
1670 bool isACCAsmReg()
const {
1671 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1674 bool isCOP0AsmReg()
const {
1675 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1678 bool isCOP2AsmReg()
const {
1679 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1682 bool isCOP3AsmReg()
const {
1683 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1686 bool isMSA128AsmReg()
const {
1687 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1690 bool isMSACtrlAsmReg()
const {
1691 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1695 SMLoc getStartLoc()
const override {
return StartLoc; }
1697 SMLoc getEndLoc()
const override {
return EndLoc; }
1708 Mem.Base->print(
OS);
1713 case k_RegisterIndex:
1714 OS <<
"RegIdx<" << RegIdx.Index <<
":" << RegIdx.Kind <<
", "
1715 <<
StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) <<
">";
1722 for (
auto Reg : (*RegList.List))
1729 bool isValidForTie(
const MipsOperand &
Other)
const {
1730 if (Kind !=
Other.Kind)
1737 case k_RegisterIndex: {
1738 StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length);
1740 return Token == OtherToken;
1756 case Mips::JRC16_MM:
1758 case Mips::JALRS_MM:
1759 case Mips::JALRS16_MM:
1760 case Mips::BGEZALS_MM:
1761 case Mips::BLTZALS_MM:
1771 if (
const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1772 return &SRExpr->getSymbol();
1775 if (
const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1788 if (
const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1795 if (isa<MCSymbolRefExpr>(Expr))
1798 if (
const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1802 if (
const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1821 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1830 if (NumOp != 3 && NumOp != 4)
1842 return !isInt<9>(
Op.getImm());
1844 return !isInt<16>(
Op.getImm());
1860bool MipsAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
1864 const unsigned Opcode = Inst.
getOpcode();
1866 bool ExpandedJalSym =
false;
1880 assert(hasCnMips() &&
"instruction only valid for octeon cpus");
1891 if (!
isIntN(inMicroMipsMode() ? 17 : 18,
Offset.getImm()))
1892 return Error(IDLoc,
"branch target out of range");
1895 return Error(IDLoc,
"branch to misaligned address");
1909 case Mips::BGEZAL_MM:
1910 case Mips::BLTZAL_MM:
1913 case Mips::BC1EQZC_MMR6:
1914 case Mips::BC1NEZC_MMR6:
1915 case Mips::BC2EQZC_MMR6:
1916 case Mips::BC2NEZC_MMR6:
1921 if (!
isIntN(inMicroMipsMode() ? 17 : 18,
Offset.getImm()))
1922 return Error(IDLoc,
"branch target out of range");
1925 return Error(IDLoc,
"branch to misaligned address");
1927 case Mips::BGEC:
case Mips::BGEC_MMR6:
1928 case Mips::BLTC:
case Mips::BLTC_MMR6:
1929 case Mips::BGEUC:
case Mips::BGEUC_MMR6:
1930 case Mips::BLTUC:
case Mips::BLTUC_MMR6:
1931 case Mips::BEQC:
case Mips::BEQC_MMR6:
1932 case Mips::BNEC:
case Mips::BNEC_MMR6:
1938 return Error(IDLoc,
"branch target out of range");
1940 return Error(IDLoc,
"branch to misaligned address");
1942 case Mips::BLEZC:
case Mips::BLEZC_MMR6:
1943 case Mips::BGEZC:
case Mips::BGEZC_MMR6:
1944 case Mips::BGTZC:
case Mips::BGTZC_MMR6:
1945 case Mips::BLTZC:
case Mips::BLTZC_MMR6:
1951 return Error(IDLoc,
"branch target out of range");
1953 return Error(IDLoc,
"branch to misaligned address");
1955 case Mips::BEQZC:
case Mips::BEQZC_MMR6:
1956 case Mips::BNEZC:
case Mips::BNEZC_MMR6:
1962 return Error(IDLoc,
"branch target out of range");
1964 return Error(IDLoc,
"branch to misaligned address");
1966 case Mips::BEQZ16_MM:
1967 case Mips::BEQZC16_MMR6:
1968 case Mips::BNEZ16_MM:
1969 case Mips::BNEZC16_MMR6:
1974 if (!isInt<8>(
Offset.getImm()))
1975 return Error(IDLoc,
"branch target out of range");
1977 return Error(IDLoc,
"branch to misaligned address");
1984 if (hasMips32r6() && Opcode == Mips::SSNOP) {
1985 std::string
ISA = hasMips64r6() ?
"MIPS64r6" :
"MIPS32r6";
1986 Warning(IDLoc,
"ssnop is deprecated for " + ISA +
" and is equivalent to a "
2006 return Error(IDLoc,
"expected immediate operand kind");
2008 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
2009 Opcode == Mips::BBIT1 ? 63 : 31))
2010 return Error(IDLoc,
"immediate operand value out of range");
2012 Inst.
setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
2023 return Error(IDLoc,
"expected immediate operand kind");
2025 if (!isInt<10>(Imm))
2026 return Error(IDLoc,
"immediate operand value out of range");
2038 unsigned FirstOp = 1;
2039 unsigned SecondOp = 2;
2043 case Mips::SDivIMacro:
2044 case Mips::UDivIMacro:
2045 case Mips::DSDivIMacro:
2046 case Mips::DUDivIMacro:
2050 Warning(IDLoc,
"dividing zero by zero");
2052 Warning(IDLoc,
"division by zero");
2064 case Mips::SDivMacro:
2065 case Mips::DSDivMacro:
2066 case Mips::UDivMacro:
2067 case Mips::DUDivMacro:
2072 case Mips::DIVU_MMR6:
2073 case Mips::DIV_MMR6:
2078 Warning(IDLoc,
"dividing zero by zero");
2080 Warning(IDLoc,
"division by zero");
2086 if ((Opcode == Mips::J || Opcode == Mips::J_MM) && inPicMode()) {
2088 BInst.
setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
2097 if ((Opcode == Mips::JAL || Opcode == Mips::JAL_MM) && inPicMode()) {
2098 warnIfNoMacro(IDLoc);
2105 return Error(IDLoc,
"jal doesn't support multiple symbols in PIC mode");
2111 if (expandLoadAddress(Mips::T9, Mips::NoRegister, Inst.
getOperand(0),
2112 !isGP64bit(), IDLoc, Out, STI))
2116 if (inMicroMipsMode())
2117 JalrInst.
setOpcode(IsCpRestoreSet ? Mips::JALRS_MM : Mips::JALR_MM);
2123 if (isJalrRelocAvailable(JalExpr)) {
2127 MCSymbol *TmpLabel = getContext().createTempSymbol();
2129 const MCExpr *RelocJalrExpr =
2131 getContext(), IDLoc);
2134 *TmpExpr, inMicroMipsMode() ?
"R_MICROMIPS_JALR" :
"R_MIPS_JALR",
2135 RelocJalrExpr, IDLoc, *STI);
2140 ExpandedJalSym =
true;
2149 expandMem9Inst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2152 expandMem16Inst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2155 return getParser().hasPendingError();
2159 if (inMicroMipsMode()) {
2160 if (MCID.
mayLoad() && Opcode != Mips::LWP_MM) {
2168 int MemOffset =
Op.getImm();
2171 if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
2174 (BaseReg.
getReg() == Mips::GP ||
2175 BaseReg.
getReg() == Mips::GP_64)) {
2177 TOut.
emitRRI(Mips::LWGP_MM, DstReg.
getReg(), Mips::GP, MemOffset,
2194 case Mips::ADDIUSP_MM:
2197 return Error(IDLoc,
"expected immediate operand kind");
2199 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
2201 return Error(IDLoc,
"immediate operand value out of range");
2203 case Mips::SLL16_MM:
2204 case Mips::SRL16_MM:
2207 return Error(IDLoc,
"expected immediate operand kind");
2209 if (Imm < 1 || Imm > 8)
2210 return Error(IDLoc,
"immediate operand value out of range");
2215 return Error(IDLoc,
"expected immediate operand kind");
2217 if (Imm < -1 || Imm > 126)
2218 return Error(IDLoc,
"immediate operand value out of range");
2220 case Mips::ADDIUR2_MM:
2223 return Error(IDLoc,
"expected immediate operand kind");
2225 if (!(Imm == 1 || Imm == -1 ||
2226 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
2227 return Error(IDLoc,
"immediate operand value out of range");
2229 case Mips::ANDI16_MM:
2232 return Error(IDLoc,
"expected immediate operand kind");
2234 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
2235 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
2236 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
2237 return Error(IDLoc,
"immediate operand value out of range");
2239 case Mips::LBU16_MM:
2242 return Error(IDLoc,
"expected immediate operand kind");
2244 if (Imm < -1 || Imm > 14)
2245 return Error(IDLoc,
"immediate operand value out of range");
2248 case Mips::SB16_MMR6:
2251 return Error(IDLoc,
"expected immediate operand kind");
2253 if (Imm < 0 || Imm > 15)
2254 return Error(IDLoc,
"immediate operand value out of range");
2256 case Mips::LHU16_MM:
2258 case Mips::SH16_MMR6:
2261 return Error(IDLoc,
"expected immediate operand kind");
2263 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
2264 return Error(IDLoc,
"immediate operand value out of range");
2268 case Mips::SW16_MMR6:
2271 return Error(IDLoc,
"expected immediate operand kind");
2273 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
2274 return Error(IDLoc,
"immediate operand value out of range");
2276 case Mips::ADDIUPC_MM:
2279 return Error(IDLoc,
"expected immediate operand kind");
2281 if ((Imm % 4 != 0) || !isInt<25>(Imm))
2282 return Error(IDLoc,
"immediate operand value out of range");
2287 return Error(IDLoc,
"invalid operand for instruction");
2289 case Mips::MOVEP_MM:
2290 case Mips::MOVEP_MMR6: {
2293 bool RegPair = ((R0 == Mips::A1 && R1 == Mips::A2) ||
2294 (R0 == Mips::A1 && R1 == Mips::A3) ||
2295 (R0 == Mips::A2 && R1 == Mips::A3) ||
2296 (R0 == Mips::A0 && R1 == Mips::S5) ||
2297 (R0 == Mips::A0 && R1 == Mips::S6) ||
2298 (R0 == Mips::A0 && R1 == Mips::A1) ||
2299 (R0 == Mips::A0 && R1 == Mips::A2) ||
2300 (R0 == Mips::A0 && R1 == Mips::A3));
2302 return Error(IDLoc,
"invalid operand for instruction");
2308 bool FillDelaySlot =
2313 MacroExpanderResultTy ExpandResult =
2314 tryExpandInstruction(Inst, IDLoc, Out, STI);
2315 switch (ExpandResult) {
2327 if (inMicroMipsMode()) {
2334 if (FillDelaySlot) {
2339 if ((Opcode == Mips::JalOneReg || Opcode == Mips::JalTwoReg ||
2341 isPicAndNotNxxAbi()) {
2342 if (IsCpRestoreSet) {
2346 if (!AssemblerOptions.
back()->isReorder())
2353 Warning(IDLoc,
"no .cprestore used in PIC mode");
2359MipsAsmParser::MacroExpanderResultTy
2364 return MER_NotAMacro;
2365 case Mips::LoadImm32:
2366 return expandLoadImm(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2367 case Mips::LoadImm64:
2368 return expandLoadImm(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2369 case Mips::LoadAddrImm32:
2370 case Mips::LoadAddrImm64:
2373 "expected immediate operand kind");
2377 Inst.
getOpcode() == Mips::LoadAddrImm32, IDLoc,
2381 case Mips::LoadAddrReg32:
2382 case Mips::LoadAddrReg64:
2386 "expected immediate operand kind");
2390 Inst.
getOpcode() == Mips::LoadAddrReg32, IDLoc,
2394 case Mips::B_MM_Pseudo:
2395 case Mips::B_MMR6_Pseudo:
2396 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2400 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2402 case Mips::JalOneReg:
2403 case Mips::JalTwoReg:
2404 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2407 case Mips::BEQLImmMacro:
2408 case Mips::BNELImmMacro:
2409 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2426 case Mips::BLTImmMacro:
2427 case Mips::BLEImmMacro:
2428 case Mips::BGEImmMacro:
2429 case Mips::BGTImmMacro:
2430 case Mips::BLTUImmMacro:
2431 case Mips::BLEUImmMacro:
2432 case Mips::BGEUImmMacro:
2433 case Mips::BGTUImmMacro:
2434 case Mips::BLTLImmMacro:
2435 case Mips::BLELImmMacro:
2436 case Mips::BGELImmMacro:
2437 case Mips::BGTLImmMacro:
2438 case Mips::BLTULImmMacro:
2439 case Mips::BLEULImmMacro:
2440 case Mips::BGEULImmMacro:
2441 case Mips::BGTULImmMacro:
2442 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2443 case Mips::SDivMacro:
2444 case Mips::SDivIMacro:
2445 case Mips::SRemMacro:
2446 case Mips::SRemIMacro:
2447 return expandDivRem(Inst, IDLoc, Out, STI,
false,
true) ? MER_Fail
2449 case Mips::DSDivMacro:
2450 case Mips::DSDivIMacro:
2451 case Mips::DSRemMacro:
2452 case Mips::DSRemIMacro:
2453 return expandDivRem(Inst, IDLoc, Out, STI,
true,
true) ? MER_Fail
2455 case Mips::UDivMacro:
2456 case Mips::UDivIMacro:
2457 case Mips::URemMacro:
2458 case Mips::URemIMacro:
2459 return expandDivRem(Inst, IDLoc, Out, STI,
false,
false) ? MER_Fail
2461 case Mips::DUDivMacro:
2462 case Mips::DUDivIMacro:
2463 case Mips::DURemMacro:
2464 case Mips::DURemIMacro:
2465 return expandDivRem(Inst, IDLoc, Out, STI,
true,
false) ? MER_Fail
2467 case Mips::PseudoTRUNC_W_S:
2468 return expandTrunc(Inst,
false,
false, IDLoc, Out, STI) ? MER_Fail
2470 case Mips::PseudoTRUNC_W_D32:
2471 return expandTrunc(Inst,
true,
false, IDLoc, Out, STI) ? MER_Fail
2473 case Mips::PseudoTRUNC_W_D:
2474 return expandTrunc(Inst,
true,
true, IDLoc, Out, STI) ? MER_Fail
2477 case Mips::LoadImmSingleGPR:
2478 return expandLoadSingleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2480 case Mips::LoadImmSingleFGR:
2481 return expandLoadSingleImmToFPR(Inst, IDLoc, Out, STI) ? MER_Fail
2483 case Mips::LoadImmDoubleGPR:
2484 return expandLoadDoubleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2486 case Mips::LoadImmDoubleFGR:
2487 return expandLoadDoubleImmToFPR(Inst,
true, IDLoc, Out, STI) ? MER_Fail
2489 case Mips::LoadImmDoubleFGR_32:
2490 return expandLoadDoubleImmToFPR(Inst,
false, IDLoc, Out, STI) ? MER_Fail
2494 return expandUlh(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2496 return expandUlh(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2498 return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2501 return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2503 case Mips::NORImm64:
2504 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2507 return expandSge(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2510 case Mips::SGEImm64:
2511 case Mips::SGEUImm64:
2512 return expandSgeImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2515 case Mips::SGTImm64:
2516 case Mips::SGTUImm64:
2517 return expandSgtImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2520 return expandSle(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2523 case Mips::SLEImm64:
2524 case Mips::SLEUImm64:
2525 return expandSleImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2526 case Mips::SLTImm64:
2529 return MER_NotAMacro;
2531 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2532 case Mips::SLTUImm64:
2535 return MER_NotAMacro;
2537 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2538 case Mips::ADDi:
case Mips::ADDi_MM:
2539 case Mips::ADDiu:
case Mips::ADDiu_MM:
2540 case Mips::SLTi:
case Mips::SLTi_MM:
2541 case Mips::SLTiu:
case Mips::SLTiu_MM:
2545 if (isInt<16>(ImmValue))
2546 return MER_NotAMacro;
2547 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2550 return MER_NotAMacro;
2551 case Mips::ANDi:
case Mips::ANDi_MM:
case Mips::ANDi64:
2552 case Mips::ORi:
case Mips::ORi_MM:
case Mips::ORi64:
2553 case Mips::XORi:
case Mips::XORi_MM:
case Mips::XORi64:
2557 if (isUInt<16>(ImmValue))
2558 return MER_NotAMacro;
2559 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2562 return MER_NotAMacro;
2565 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2568 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2571 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2574 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2575 case Mips::ABSMacro:
2576 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2577 case Mips::MULImmMacro:
2578 case Mips::DMULImmMacro:
2579 return expandMulImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2580 case Mips::MULOMacro:
2581 case Mips::DMULOMacro:
2582 return expandMulO(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2583 case Mips::MULOUMacro:
2584 case Mips::DMULOUMacro:
2585 return expandMulOU(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2586 case Mips::DMULMacro:
2587 return expandDMULMacro(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2590 return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2595 return expandStoreDM1Macro(Inst, IDLoc, Out, STI)
2598 case Mips::SEQMacro:
2599 return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2600 case Mips::SEQIMacro:
2601 return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2602 case Mips::SNEMacro:
2603 return expandSne(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2604 case Mips::SNEIMacro:
2605 return expandSneI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2606 case Mips::MFTC0:
case Mips::MTTC0:
2607 case Mips::MFTGPR:
case Mips::MTTGPR:
2608 case Mips::MFTLO:
case Mips::MTTLO:
2609 case Mips::MFTHI:
case Mips::MTTHI:
2610 case Mips::MFTACX:
case Mips::MTTACX:
2611 case Mips::MFTDSP:
case Mips::MTTDSP:
2612 case Mips::MFTC1:
case Mips::MTTC1:
2613 case Mips::MFTHC1:
case Mips::MTTHC1:
2614 case Mips::CFTC1:
case Mips::CTTC1:
2615 return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2617 case Mips::SaadAddr:
2618 return expandSaaAddr(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2622bool MipsAsmParser::expandJalWithRegs(
MCInst &Inst,
SMLoc IDLoc,
2631 const unsigned Opcode = Inst.
getOpcode();
2633 if (Opcode == Mips::JalOneReg) {
2635 if (IsCpRestoreSet && inMicroMipsMode()) {
2638 }
else if (inMicroMipsMode()) {
2639 JalrInst.
setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2646 }
else if (Opcode == Mips::JalTwoReg) {
2648 if (IsCpRestoreSet && inMicroMipsMode())
2651 JalrInst.
setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2683bool MipsAsmParser::loadImmediate(int64_t ImmValue,
unsigned DstReg,
2684 unsigned SrcReg,
bool Is32BitImm,
2689 if (!Is32BitImm && !isGP64bit()) {
2690 Error(IDLoc,
"instruction requires a 64-bit architecture");
2695 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2699 ImmValue = SignExtend64<32>(ImmValue);
2701 Error(IDLoc,
"instruction requires a 32-bit immediate");
2706 unsigned ZeroReg = IsAddress ?
ABI.GetNullPtr() :
ABI.GetZeroReg();
2707 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2709 bool UseSrcReg =
false;
2710 if (SrcReg != Mips::NoRegister)
2713 unsigned TmpReg = DstReg;
2715 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2718 unsigned ATReg = getATReg(IDLoc);
2724 if (isInt<16>(ImmValue)) {
2731 if (IsAddress && !Is32BitImm) {
2732 TOut.
emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2736 TOut.
emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2740 if (isUInt<16>(ImmValue)) {
2741 unsigned TmpReg = DstReg;
2742 if (SrcReg == DstReg) {
2743 TmpReg = getATReg(IDLoc);
2748 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2750 TOut.
emitRRR(
ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2754 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2755 warnIfNoMacro(IDLoc);
2757 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2758 uint16_t Bits15To0 = ImmValue & 0xffff;
2759 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2762 if (ImmValue == 0xffffffff) {
2763 TOut.
emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2764 TOut.
emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2766 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2772 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2773 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2775 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2777 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2781 TOut.
emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2783 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2785 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2789 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2791 Error(IDLoc,
"instruction requires a 32-bit immediate");
2798 assert(
BitWidth >= 17 &&
"ImmValue must be at least 17-bit wide");
2802 unsigned ShiftAmount =
BitWidth - 16;
2804 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2805 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2808 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2813 warnIfNoMacro(IDLoc);
2820 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister,
true,
false,
2826 unsigned ShiftCarriedForwards = 16;
2827 for (
int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2828 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2830 if (ImmChunk != 0) {
2831 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2832 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2833 ShiftCarriedForwards = 0;
2836 ShiftCarriedForwards += 16;
2838 ShiftCarriedForwards -= 16;
2841 if (ShiftCarriedForwards)
2842 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2845 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2850bool MipsAsmParser::expandLoadImm(
MCInst &Inst,
bool Is32BitImm,
SMLoc IDLoc,
2853 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
2855 assert(DstRegOp.
isReg() &&
"expected register operand kind");
2857 if (loadImmediate(ImmOp.
getImm(), DstRegOp.
getReg(), Mips::NoRegister,
2858 Is32BitImm,
false, IDLoc, Out, STI))
2864bool MipsAsmParser::expandLoadAddress(
unsigned DstReg,
unsigned BaseReg,
2866 bool Is32BitAddress,
SMLoc IDLoc,
2870 if (Is32BitAddress &&
ABI.ArePtrs64bit()) {
2871 Warning(IDLoc,
"la used to load 64-bit address");
2873 Is32BitAddress =
false;
2877 if (!Is32BitAddress && !hasMips3()) {
2878 Error(IDLoc,
"instruction requires a 64-bit architecture");
2883 return loadAndAddSymbolAddress(
Offset.getExpr(), DstReg, BaseReg,
2884 Is32BitAddress, IDLoc, Out, STI);
2886 if (!
ABI.ArePtrs64bit()) {
2888 Is32BitAddress =
true;
2891 return loadImmediate(
Offset.getImm(), DstReg, BaseReg, Is32BitAddress,
true,
2895bool MipsAsmParser::loadAndAddSymbolAddress(
const MCExpr *SymExpr,
2896 unsigned DstReg,
unsigned SrcReg,
2897 bool Is32BitSym,
SMLoc IDLoc,
2901 bool UseSrcReg = SrcReg != Mips::NoRegister && SrcReg != Mips::ZERO &&
2902 SrcReg != Mips::ZERO_64;
2903 warnIfNoMacro(IDLoc);
2908 Error(IDLoc,
"expected relocatable expression");
2911 if (Res.
getSymB() !=
nullptr) {
2912 Error(IDLoc,
"expected relocatable expression with only one symbol");
2916 bool IsPtr64 =
ABI.ArePtrs64bit();
2923 bool UseXGOT = STI->
hasFeature(Mips::FeatureXGOT) && !IsLocalSym;
2929 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2933 SymExpr, getContext());
2935 SymExpr, getContext());
2938 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, DstReg, GPReg,
2940 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, DstReg,
2945 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, GPReg,
2951 unsigned TmpReg = DstReg;
2953 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2957 unsigned ATReg = getATReg(IDLoc);
2976 const MCExpr *CallHiExpr =
2983 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg, GPReg,
2985 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, TmpReg,
2989 TOut.
emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
2995 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3001 const MCExpr *LoExpr =
nullptr;
3002 if (
ABI.IsN32() ||
ABI.IsN64()) {
3021 Error(IDLoc,
"macro instruction uses large offset, which is not "
3022 "currently supported");
3052 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, GPReg,
3056 TOut.
emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3060 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3072 if (
ABI.ArePtrs64bit() && isGP64bit()) {
3087 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
3089 if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
3090 unsigned ATReg = getATReg(IDLoc);
3102 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3104 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3107 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3110 TOut.
emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
3113 }
else if (canUseATReg() && !RdRegIsRsReg && DstReg != getATReg(IDLoc)) {
3114 unsigned ATReg = getATReg(IDLoc);
3130 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3134 TOut.
emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3135 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3137 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3140 }
else if ((!canUseATReg() && !RdRegIsRsReg) ||
3141 (canUseATReg() && DstReg == getATReg(IDLoc))) {
3152 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3154 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3155 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3157 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3158 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3161 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3167 assert(SrcReg == DstReg && !canUseATReg() &&
3168 "Could have expanded dla but didn't?");
3169 reportParseError(IDLoc,
3170 "pseudo-instruction requires $at, which is not available");
3184 unsigned TmpReg = DstReg;
3186 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
3189 unsigned ATReg = getATReg(IDLoc);
3200 TOut.
emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3203 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
3212 if (MipsMCRegisterClasses[Mips::FGR32RegClassID].
contains(
Reg))
3213 return Reg == (
unsigned)Mips::F31 ? (
unsigned)Mips::F0 :
Reg + 1;
3215 default:
llvm_unreachable(
"Unknown register in assembly macro expansion!");
3216 case Mips::ZERO:
return Mips::AT;
3217 case Mips::AT:
return Mips::V0;
3218 case Mips::V0:
return Mips::V1;
3219 case Mips::V1:
return Mips::A0;
3220 case Mips::A0:
return Mips::A1;
3221 case Mips::A1:
return Mips::A2;
3222 case Mips::A2:
return Mips::A3;
3223 case Mips::A3:
return Mips::T0;
3224 case Mips::T0:
return Mips::T1;
3225 case Mips::T1:
return Mips::T2;
3226 case Mips::T2:
return Mips::T3;
3227 case Mips::T3:
return Mips::T4;
3228 case Mips::T4:
return Mips::T5;
3229 case Mips::T5:
return Mips::T6;
3230 case Mips::T6:
return Mips::T7;
3231 case Mips::T7:
return Mips::S0;
3232 case Mips::S0:
return Mips::S1;
3233 case Mips::S1:
return Mips::S2;
3234 case Mips::S2:
return Mips::S3;
3235 case Mips::S3:
return Mips::S4;
3236 case Mips::S4:
return Mips::S5;
3237 case Mips::S5:
return Mips::S6;
3238 case Mips::S6:
return Mips::S7;
3239 case Mips::S7:
return Mips::T8;
3240 case Mips::T8:
return Mips::T9;
3241 case Mips::T9:
return Mips::K0;
3242 case Mips::K0:
return Mips::K1;
3243 case Mips::K1:
return Mips::GP;
3244 case Mips::GP:
return Mips::SP;
3245 case Mips::SP:
return Mips::FP;
3246 case Mips::FP:
return Mips::RA;
3247 case Mips::RA:
return Mips::ZERO;
3248 case Mips::D0:
return Mips::F1;
3249 case Mips::D1:
return Mips::F3;
3250 case Mips::D2:
return Mips::F5;
3251 case Mips::D3:
return Mips::F7;
3252 case Mips::D4:
return Mips::F9;
3253 case Mips::D5:
return Mips::F11;
3254 case Mips::D6:
return Mips::F13;
3255 case Mips::D7:
return Mips::F15;
3256 case Mips::D8:
return Mips::F17;
3257 case Mips::D9:
return Mips::F19;
3258 case Mips::D10:
return Mips::F21;
3259 case Mips::D11:
return Mips::F23;
3260 case Mips::D12:
return Mips::F25;
3261 case Mips::D13:
return Mips::F27;
3262 case Mips::D14:
return Mips::F29;
3263 case Mips::D15:
return Mips::F31;
3275 unsigned ATReg = getATReg(IDLoc);
3285 if(isABI_O32() || isABI_N32()) {
3304 if(isABI_O32() || isABI_N32()) {
3307 const MCExpr *HighestSym =
3311 const MCExpr *HigherSym =
3318 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3320 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3323 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3332 if ((
Hi_32(ImmOp64) & 0x7ff00000) == 0) {
3333 APFloat RealVal(APFloat::IEEEdouble(), ImmOp64);
3342 double DoubleImm = llvm::bit_cast<double>(ImmOp64);
3343 float TmpFloat =
static_cast<float>(DoubleImm);
3344 return llvm::bit_cast<uint32_t>(TmpFloat);
3347bool MipsAsmParser::expandLoadSingleImmToGPR(
MCInst &Inst,
SMLoc IDLoc,
3352 "Invalid instruction operand.");
3359 return loadImmediate(ImmOp32, FirstReg, Mips::NoRegister,
true,
false, IDLoc,
3363bool MipsAsmParser::expandLoadSingleImmToFPR(
MCInst &Inst,
SMLoc IDLoc,
3369 "Invalid instruction operand.");
3378 unsigned TmpReg = Mips::ZERO;
3380 TmpReg = getATReg(IDLoc);
3385 if (
Lo_32(ImmOp64) == 0) {
3386 if (TmpReg != Mips::ZERO && loadImmediate(ImmOp32, TmpReg, Mips::NoRegister,
3387 true,
false, IDLoc, Out, STI))
3389 TOut.
emitRR(Mips::MTC1, FirstReg, TmpReg, IDLoc, STI);
3393 MCSection *CS = getStreamer().getCurrentSectionOnly();
3405 getStreamer().switchSection(ReadOnlySection);
3406 getStreamer().emitLabel(
Sym, IDLoc);
3407 getStreamer().emitInt32(ImmOp32);
3408 getStreamer().switchSection(CS);
3410 if (emitPartialAddress(TOut, IDLoc,
Sym))
3417bool MipsAsmParser::expandLoadDoubleImmToGPR(
MCInst &Inst,
SMLoc IDLoc,
3423 "Invalid instruction operand.");
3430 if (
Lo_32(ImmOp64) == 0) {
3432 if (loadImmediate(ImmOp64, FirstReg, Mips::NoRegister,
false,
false,
3436 if (loadImmediate(
Hi_32(ImmOp64), FirstReg, Mips::NoRegister,
true,
false,
3440 if (loadImmediate(0,
nextReg(FirstReg), Mips::NoRegister,
true,
false,
3447 MCSection *CS = getStreamer().getCurrentSectionOnly();
3457 getStreamer().switchSection(ReadOnlySection);
3458 getStreamer().emitLabel(
Sym, IDLoc);
3459 getStreamer().emitValueToAlignment(
Align(8));
3460 getStreamer().emitIntValue(ImmOp64, 8);
3461 getStreamer().switchSection(CS);
3463 unsigned TmpReg = getATReg(IDLoc);
3467 if (emitPartialAddress(TOut, IDLoc,
Sym))
3470 TOut.
emitRRX(isABI_N64() ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3474 TOut.
emitRRI(Mips::LD, FirstReg, TmpReg, 0, IDLoc, STI);
3476 TOut.
emitRRI(Mips::LW, FirstReg, TmpReg, 0, IDLoc, STI);
3477 TOut.
emitRRI(Mips::LW,
nextReg(FirstReg), TmpReg, 4, IDLoc, STI);
3482bool MipsAsmParser::expandLoadDoubleImmToFPR(
MCInst &Inst,
bool Is64FPU,
3488 "Invalid instruction operand.");
3495 unsigned TmpReg = Mips::ZERO;
3497 TmpReg = getATReg(IDLoc);
3502 if ((
Lo_32(ImmOp64) == 0) &&
3503 !((
Hi_32(ImmOp64) & 0xffff0000) && (
Hi_32(ImmOp64) & 0x0000ffff))) {
3505 if (TmpReg != Mips::ZERO &&
3506 loadImmediate(ImmOp64, TmpReg, Mips::NoRegister,
false,
false, IDLoc,
3509 TOut.
emitRR(Mips::DMTC1, FirstReg, TmpReg, IDLoc, STI);
3513 if (TmpReg != Mips::ZERO &&
3514 loadImmediate(
Hi_32(ImmOp64), TmpReg, Mips::NoRegister,
true,
false,
3518 if (hasMips32r2()) {
3519 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3520 TOut.
emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, TmpReg, IDLoc, STI);
3522 TOut.
emitRR(Mips::MTC1,
nextReg(FirstReg), TmpReg, IDLoc, STI);
3523 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3528 MCSection *CS = getStreamer().getCurrentSectionOnly();
3540 getStreamer().switchSection(ReadOnlySection);
3541 getStreamer().emitLabel(
Sym, IDLoc);
3542 getStreamer().emitValueToAlignment(
Align(8));
3543 getStreamer().emitIntValue(ImmOp64, 8);
3544 getStreamer().switchSection(CS);
3546 if (emitPartialAddress(TOut, IDLoc,
Sym))
3549 TOut.
emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, TmpReg,
3555bool MipsAsmParser::expandUncondBranchMMPseudo(
MCInst &Inst,
SMLoc IDLoc,
3561 "unexpected number of operands");
3571 assert(
Offset.isImm() &&
"expected immediate operand kind");
3572 if (isInt<11>(
Offset.getImm())) {
3575 if (inMicroMipsMode())
3576 Inst.
setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3578 if (!isInt<17>(
Offset.getImm()))
3579 return Error(IDLoc,
"branch target out of range");
3581 return Error(IDLoc,
"branch to misaligned address");
3604 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3607 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
3611 "expected immediate or expression operand");
3613 bool IsLikely =
false;
3615 unsigned OpCode = 0;
3623 case Mips::BEQLImmMacro:
3624 OpCode = Mips::BEQL;
3627 case Mips::BNELImmMacro:
3628 OpCode = Mips::BNEL;
3636 int64_t ImmValue = ImmOp.
getImm();
3637 if (ImmValue == 0) {
3641 TOut.
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3643 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3646 warnIfNoMacro(IDLoc);
3648 unsigned ATReg = getATReg(IDLoc);
3652 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(),
true,
3659 TOut.
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3661 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3669 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3670 unsigned StartOp = NumOp == 3 ? 0 : 1;
3673 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3675 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3680 unsigned DstReg = DstRegOp.
getReg();
3681 unsigned BaseReg = BaseRegOp.
getReg();
3682 unsigned TmpReg = DstReg;
3685 int16_t DstRegClass =
Desc.operands()[StartOp].RegClass;
3686 unsigned DstRegClassID =
3687 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3688 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3689 (DstRegClassID == Mips::GPR64RegClassID);
3691 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3694 TmpReg = getATReg(IDLoc);
3701 TOut.
emitRRX(OpCode, DstReg, TmpReg, Off, IDLoc, STI);
3703 TOut.
emitRRRX(OpCode, DstReg, DstReg, TmpReg, Off, IDLoc, STI);
3706 if (OffsetOp.
isImm()) {
3707 int64_t LoOffset = OffsetOp.
getImm() & 0xffff;
3708 int64_t HiOffset = OffsetOp.
getImm() & ~0xffff;
3712 if (LoOffset & 0x8000)
3713 HiOffset += 0x10000;
3715 bool IsLargeOffset = HiOffset != 0;
3717 if (IsLargeOffset) {
3718 bool Is32BitImm = isInt<32>(OffsetOp.
getImm());
3719 if (loadImmediate(HiOffset, TmpReg, Mips::NoRegister, Is32BitImm,
true,
3724 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3725 TOut.
emitRRR(
ABI.ArePtrs64bit() ? Mips::DADDu : Mips::ADDu, TmpReg,
3726 TmpReg, BaseReg, IDLoc, STI);
3741 Error(IDLoc,
"expected relocatable expression");
3744 if (Res.
getSymB() !=
nullptr) {
3745 Error(IDLoc,
"expected relocatable expression with only one symbol");
3749 loadAndAddSymbolAddress(Res.
getSymA(), TmpReg, BaseReg,
3750 !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3770 TOut.
emitRX(Mips::LUi, TmpReg, HighestOperand, IDLoc, STI);
3771 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HigherOperand, IDLoc, STI);
3772 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3773 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HiOperand, IDLoc, STI);
3774 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3775 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3776 TOut.
emitRRR(Mips::DADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3777 emitInstWithOffset(LoOperand);
3780 TOut.
emitRX(Mips::LUi, TmpReg, HiOperand, IDLoc, STI);
3781 if (BaseReg != Mips::ZERO)
3782 TOut.
emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3784 emitInstWithOffset(LoOperand);
3796 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3797 unsigned StartOp = NumOp == 3 ? 0 : 1;
3800 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3802 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3807 unsigned DstReg = DstRegOp.
getReg();
3808 unsigned BaseReg = BaseRegOp.
getReg();
3809 unsigned TmpReg = DstReg;
3812 int16_t DstRegClass =
Desc.operands()[StartOp].RegClass;
3813 unsigned DstRegClassID =
3814 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3815 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3816 (DstRegClassID == Mips::GPR64RegClassID);
3818 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3821 TmpReg = getATReg(IDLoc);
3826 auto emitInst = [&]() {
3834 if (OffsetOp.
isImm()) {
3835 loadImmediate(OffsetOp.
getImm(), TmpReg, BaseReg, !
ABI.ArePtrs64bit(),
true,
3842 loadAndAddSymbolAddress(OffsetOp.
getExpr(), TmpReg, BaseReg,
3843 !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3851bool MipsAsmParser::expandLoadStoreMultiple(
MCInst &Inst,
SMLoc IDLoc,
3856 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3860 Inst.
getOperand(OpNum - 3).
isReg() &&
"Invalid instruction operand.");
3869 if (inMicroMipsMode() && hasMips32r6())
3870 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3872 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3880bool MipsAsmParser::expandCondBranches(
MCInst &Inst,
SMLoc IDLoc,
3884 bool EmittedNoMacroWarning =
false;
3885 unsigned PseudoOpcode = Inst.
getOpcode();
3890 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3891 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3896 else if (TrgOp.
isImm()) {
3897 warnIfNoMacro(IDLoc);
3898 EmittedNoMacroWarning =
true;
3900 TrgReg = getATReg(IDLoc);
3904 switch(PseudoOpcode) {
3907 case Mips::BLTImmMacro:
3908 PseudoOpcode = Mips::BLT;
3910 case Mips::BLEImmMacro:
3911 PseudoOpcode = Mips::BLE;
3913 case Mips::BGEImmMacro:
3914 PseudoOpcode = Mips::BGE;
3916 case Mips::BGTImmMacro:
3917 PseudoOpcode = Mips::BGT;
3919 case Mips::BLTUImmMacro:
3920 PseudoOpcode = Mips::BLTU;
3922 case Mips::BLEUImmMacro:
3923 PseudoOpcode = Mips::BLEU;
3925 case Mips::BGEUImmMacro:
3926 PseudoOpcode = Mips::BGEU;
3928 case Mips::BGTUImmMacro:
3929 PseudoOpcode = Mips::BGTU;
3931 case Mips::BLTLImmMacro:
3932 PseudoOpcode = Mips::BLTL;
3934 case Mips::BLELImmMacro:
3935 PseudoOpcode = Mips::BLEL;
3937 case Mips::BGELImmMacro:
3938 PseudoOpcode = Mips::BGEL;
3940 case Mips::BGTLImmMacro:
3941 PseudoOpcode = Mips::BGTL;
3943 case Mips::BLTULImmMacro:
3944 PseudoOpcode = Mips::BLTUL;
3946 case Mips::BLEULImmMacro:
3947 PseudoOpcode = Mips::BLEUL;
3949 case Mips::BGEULImmMacro:
3950 PseudoOpcode = Mips::BGEUL;
3952 case Mips::BGTULImmMacro:
3953 PseudoOpcode = Mips::BGTUL;
3957 if (loadImmediate(TrgOp.
getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
3958 false, IDLoc, Out, STI))
3962 switch (PseudoOpcode) {
3967 AcceptsEquality =
false;
3968 ReverseOrderSLT =
false;
3970 ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
3971 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
3972 ZeroSrcOpcode = Mips::BGTZ;
3973 ZeroTrgOpcode = Mips::BLTZ;
3979 AcceptsEquality =
true;
3980 ReverseOrderSLT =
true;
3982 ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
3983 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
3984 ZeroSrcOpcode = Mips::BGEZ;
3985 ZeroTrgOpcode = Mips::BLEZ;
3991 AcceptsEquality =
true;
3992 ReverseOrderSLT =
false;
3994 ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
3995 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
3996 ZeroSrcOpcode = Mips::BLEZ;
3997 ZeroTrgOpcode = Mips::BGEZ;
4003 AcceptsEquality =
false;
4004 ReverseOrderSLT =
true;
4006 ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
4007 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
4008 ZeroSrcOpcode = Mips::BLTZ;
4009 ZeroTrgOpcode = Mips::BGTZ;
4015 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
4016 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
4017 if (IsSrcRegZero && IsTrgRegZero) {
4021 if (PseudoOpcode == Mips::BLT) {
4026 if (PseudoOpcode == Mips::BLE) {
4029 Warning(IDLoc,
"branch is always taken");
4032 if (PseudoOpcode == Mips::BGE) {
4035 Warning(IDLoc,
"branch is always taken");
4038 if (PseudoOpcode == Mips::BGT) {
4043 if (PseudoOpcode == Mips::BGTU) {
4044 TOut.
emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
4048 if (AcceptsEquality) {
4051 TOut.
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4053 Warning(IDLoc,
"branch is always taken");
4060 if (IsSrcRegZero || IsTrgRegZero) {
4061 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
4062 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
4069 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
4070 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
4076 TOut.
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4078 Warning(IDLoc,
"branch is always taken");
4094 TOut.
emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
4095 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
4102 TOut.
emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
4103 IsSrcRegZero ? TrgReg : SrcReg,
4110 unsigned ATRegNum = getATReg(IDLoc);
4114 if (!EmittedNoMacroWarning)
4115 warnIfNoMacro(IDLoc);
4132 TOut.
emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
4133 ReverseOrderSLT ? TrgReg : SrcReg,
4134 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
4136 TOut.
emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
4137 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
4153 const bool IsMips64,
const bool Signed) {
4156 warnIfNoMacro(IDLoc);
4159 assert(RdRegOp.
isReg() &&
"expected register operand kind");
4160 unsigned RdReg = RdRegOp.
getReg();
4163 assert(RsRegOp.
isReg() &&
"expected register operand kind");
4164 unsigned RsReg = RsRegOp.
getReg();
4171 "expected register or immediate operand kind");
4175 ImmValue = RtOp.
getImm();
4182 DivOp =
Signed ? Mips::DSDIV : Mips::DUDIV;
4183 ZeroReg = Mips::ZERO_64;
4186 DivOp =
Signed ? Mips::SDIV : Mips::UDIV;
4187 ZeroReg = Mips::ZERO;
4191 bool UseTraps = useTraps();
4194 bool isDiv = Opcode == Mips::SDivMacro || Opcode == Mips::SDivIMacro ||
4195 Opcode == Mips::UDivMacro || Opcode == Mips::UDivIMacro ||
4196 Opcode == Mips::DSDivMacro || Opcode == Mips::DSDivIMacro ||
4197 Opcode == Mips::DUDivMacro || Opcode == Mips::DUDivIMacro;
4199 bool isRem = Opcode == Mips::SRemMacro || Opcode == Mips::SRemIMacro ||
4200 Opcode == Mips::URemMacro || Opcode == Mips::URemIMacro ||
4201 Opcode == Mips::DSRemMacro || Opcode == Mips::DSRemIMacro ||
4202 Opcode == Mips::DURemMacro || Opcode == Mips::DURemIMacro;
4205 unsigned ATReg = getATReg(IDLoc);
4209 if (ImmValue == 0) {
4211 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4213 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4217 if (isRem && (ImmValue == 1 || (
Signed && (ImmValue == -1)))) {
4218 TOut.
emitRRR(Mips::OR, RdReg, ZeroReg, ZeroReg, IDLoc, STI);
4220 }
else if (isDiv && ImmValue == 1) {
4221 TOut.
emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI);
4223 }
else if (isDiv &&
Signed && ImmValue == -1) {
4224 TOut.
emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
4227 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, isInt<32>(ImmValue),
4228 false, Inst.
getLoc(), Out, STI))
4230 TOut.
emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
4231 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4241 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
4243 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4246 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4252 if (isRem && (RdReg == Mips::ZERO || RdReg == Mips::ZERO_64)) {
4253 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4263 TOut.
emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4266 BrTarget =
Context.createTempSymbol();
4268 TOut.
emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4271 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4274 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4280 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4284 unsigned ATReg = getATReg(IDLoc);
4291 TOut.
emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
4299 TOut.
emitRRX(Mips::BNE, RtReg, ATReg, LabelOpEnd, IDLoc, STI);
4302 TOut.
emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
4303 TOut.
emitDSLL(ATReg, ATReg, 63, IDLoc, STI);
4309 TOut.
emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
4312 TOut.
emitRRX(Mips::BNE, RsReg, ATReg, LabelOpEnd, IDLoc, STI);
4314 TOut.
emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
4318 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4322bool MipsAsmParser::expandTrunc(
MCInst &Inst,
bool IsDouble,
bool Is64FPU,
4335 if (hasMips1() && !hasMips2()) {
4336 unsigned ATReg = getATReg(IDLoc);
4339 TOut.
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4340 TOut.
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4342 TOut.
emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4343 TOut.
emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4344 TOut.
emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4346 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4348 FirstReg, SecondReg, IDLoc, STI);
4349 TOut.
emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4354 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4356 FirstReg, SecondReg, IDLoc, STI);
4363 if (hasMips32r6() || hasMips64r6()) {
4364 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4368 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4370 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4372 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4375 unsigned DstReg = DstRegOp.
getReg();
4376 unsigned SrcReg = SrcRegOp.
getReg();
4377 int64_t OffsetValue = OffsetImmOp.
getImm();
4381 warnIfNoMacro(IDLoc);
4382 unsigned ATReg = getATReg(IDLoc);
4386 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4387 if (IsLargeOffset) {
4388 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4393 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4394 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4398 unsigned FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4399 unsigned SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4401 unsigned LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4402 unsigned SllReg = IsLargeOffset ? DstReg : ATReg;
4404 TOut.
emitRRI(
Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4405 FirstOffset, IDLoc, STI);
4406 TOut.
emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4407 TOut.
emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4408 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4415 if (hasMips32r6() || hasMips64r6()) {
4416 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4420 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4422 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4424 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4427 unsigned DstReg = DstRegOp.
getReg();
4428 unsigned SrcReg = SrcRegOp.
getReg();
4429 int64_t OffsetValue = OffsetImmOp.
getImm();
4431 warnIfNoMacro(IDLoc);
4432 unsigned ATReg = getATReg(IDLoc);
4436 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4437 if (IsLargeOffset) {
4438 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4443 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4444 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4448 if (IsLargeOffset) {
4449 TOut.
emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4450 TOut.
emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4451 TOut.
emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4452 TOut.
emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4453 TOut.
emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4454 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4456 TOut.
emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4457 TOut.
emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4458 TOut.
emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4466 if (hasMips32r6() || hasMips64r6()) {
4467 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4471 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4473 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4475 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4478 unsigned DstReg = DstRegOp.
getReg();
4479 unsigned SrcReg = SrcRegOp.
getReg();
4480 int64_t OffsetValue = OffsetImmOp.
getImm();
4483 bool IsLargeOffset = !(isInt<16>(OffsetValue + 3) && isInt<16>(OffsetValue));
4484 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4485 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4489 bool IsLoadInst = (Inst.
getOpcode() == Mips::Ulw);
4490 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4491 unsigned TmpReg = SrcReg;
4492 if (IsLargeOffset || DoMove) {
4493 warnIfNoMacro(IDLoc);
4494 TmpReg = getATReg(IDLoc);
4499 if (IsLargeOffset) {
4500 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4508 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4509 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4510 TOut.
emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4511 TOut.
emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4514 TOut.
emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4533 warnIfNoMacro(IDLoc);
4540 OpCode = Mips::SLTu;
4547 TOut.
emitRRR(OpCode, DstReg, SrcReg, OpReg, IDLoc, STI);
4548 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4565 unsigned OpRegCode, OpImmCode;
4567 warnIfNoMacro(IDLoc);
4571 case Mips::SGEImm64:
4572 OpRegCode = Mips::SLT;
4573 OpImmCode = Mips::SLTi;
4576 case Mips::SGEUImm64:
4577 OpRegCode = Mips::SLTu;
4578 OpImmCode = Mips::SLTiu;
4585 if (isInt<16>(ImmValue)) {
4587 TOut.
emitRRI(OpImmCode, DstReg, SrcReg, ImmValue, IDLoc, STI);
4588 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4590 unsigned ImmReg = DstReg;
4591 if (DstReg == SrcReg) {
4592 unsigned ATReg = getATReg(Inst.
getLoc());
4598 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4599 false, IDLoc, Out, STI))
4602 TOut.
emitRRR(OpRegCode, DstReg, SrcReg, ImmReg, IDLoc, STI);
4603 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4620 unsigned ImmReg = DstReg;
4624 warnIfNoMacro(IDLoc);
4628 case Mips::SGTImm64:
4632 case Mips::SGTUImm64:
4633 OpCode = Mips::SLTu;
4639 if (DstReg == SrcReg) {
4640 unsigned ATReg = getATReg(Inst.
getLoc());
4646 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4647 false, IDLoc, Out, STI))
4651 TOut.
emitRRR(OpCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4670 warnIfNoMacro(IDLoc);
4677 OpCode = Mips::SLTu;
4684 TOut.
emitRRR(OpCode, DstReg, OpReg, SrcReg, IDLoc, STI);
4685 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4704 warnIfNoMacro(IDLoc);
4708 case Mips::SLEImm64:
4709 OpRegCode = Mips::SLT;
4712 case Mips::SLEUImm64:
4713 OpRegCode = Mips::SLTu;
4720 unsigned ImmReg = DstReg;
4721 if (DstReg == SrcReg) {
4722 unsigned ATReg = getATReg(Inst.
getLoc());
4728 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4729 false, IDLoc, Out, STI))
4732 TOut.
emitRRR(OpRegCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4733 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4738bool MipsAsmParser::expandAliasImmediate(
MCInst &Inst,
SMLoc IDLoc,
4748 unsigned ATReg = Mips::NoRegister;
4749 unsigned FinalDstReg = Mips::NoRegister;
4754 bool Is32Bit = isInt<32>(ImmValue) || (!isGP64bit() && isUInt<32>(ImmValue));
4756 unsigned FinalOpcode = Inst.
getOpcode();
4758 if (DstReg == SrcReg) {
4759 ATReg = getATReg(Inst.
getLoc());
4762 FinalDstReg = DstReg;
4766 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit,
false,
4767 Inst.
getLoc(), Out, STI)) {
4768 switch (FinalOpcode) {
4772 FinalOpcode = Mips::ADD;
4775 FinalOpcode = Mips::ADDu;
4778 FinalOpcode = Mips::AND;
4781 FinalOpcode = Mips::NOR;
4784 FinalOpcode = Mips::OR;
4787 FinalOpcode = Mips::SLT;
4790 FinalOpcode = Mips::SLTu;
4793 FinalOpcode = Mips::XOR;
4796 FinalOpcode = Mips::ADD_MM;
4798 case Mips::ADDiu_MM:
4799 FinalOpcode = Mips::ADDu_MM;
4802 FinalOpcode = Mips::AND_MM;
4805 FinalOpcode = Mips::OR_MM;
4808 FinalOpcode = Mips::SLT_MM;
4810 case Mips::SLTiu_MM:
4811 FinalOpcode = Mips::SLTu_MM;
4814 FinalOpcode = Mips::XOR_MM;
4817 FinalOpcode = Mips::AND64;
4819 case Mips::NORImm64:
4820 FinalOpcode = Mips::NOR64;
4823 FinalOpcode = Mips::OR64;
4825 case Mips::SLTImm64:
4826 FinalOpcode = Mips::SLT64;
4828 case Mips::SLTUImm64:
4829 FinalOpcode = Mips::SLTu64;
4832 FinalOpcode = Mips::XOR64;
4836 if (FinalDstReg == Mips::NoRegister)
4837 TOut.
emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4839 TOut.
emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4848 unsigned ATReg = Mips::NoRegister;
4852 unsigned TmpReg =
DReg;
4854 unsigned FirstShift = Mips::NOP;
4855 unsigned SecondShift = Mips::NOP;
4857 if (hasMips32r2()) {
4859 TmpReg = getATReg(Inst.
getLoc());
4865 TOut.
emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4866 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
4871 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
4883 FirstShift = Mips::SRLV;
4884 SecondShift = Mips::SLLV;
4887 FirstShift = Mips::SLLV;
4888 SecondShift = Mips::SRLV;
4892 ATReg = getATReg(Inst.
getLoc());
4896 TOut.
emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4897 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
4898 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
4899 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
4907bool MipsAsmParser::expandRotationImm(
MCInst &Inst,
SMLoc IDLoc,
4911 unsigned ATReg = Mips::NoRegister;
4916 unsigned FirstShift = Mips::NOP;
4917 unsigned SecondShift = Mips::NOP;
4919 if (hasMips32r2()) {
4924 ShiftValue = MaxShift - ImmValue;
4925 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
4930 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.
getLoc(), STI);
4938 if (ImmValue == 0) {
4947 FirstShift = Mips::SLL;
4948 SecondShift = Mips::SRL;
4951 FirstShift = Mips::SRL;
4952 SecondShift = Mips::SLL;
4956 ATReg = getATReg(Inst.
getLoc());
4960 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.
getLoc(), STI);
4961 TOut.
emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.
getLoc(), STI);
4962 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
4973 unsigned ATReg = Mips::NoRegister;
4977 unsigned TmpReg =
DReg;
4979 unsigned FirstShift = Mips::NOP;
4980 unsigned SecondShift = Mips::NOP;
4982 if (hasMips64r2()) {
4983 if (TmpReg == SReg) {
4984 TmpReg = getATReg(Inst.
getLoc());
4990 TOut.
emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4991 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
4996 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
5008 FirstShift = Mips::DSRLV;
5009 SecondShift = Mips::DSLLV;
5012 FirstShift = Mips::DSLLV;
5013 SecondShift = Mips::DSRLV;
5017 ATReg = getATReg(Inst.
getLoc());
5021 TOut.
emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
5022 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
5023 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
5024 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5032bool MipsAsmParser::expandDRotationImm(
MCInst &Inst,
SMLoc IDLoc,
5036 unsigned ATReg = Mips::NoRegister;
5041 unsigned FirstShift = Mips::NOP;
5042 unsigned SecondShift = Mips::NOP;
5046 if (hasMips64r2()) {
5047 unsigned FinalOpcode = Mips::NOP;
5049 FinalOpcode = Mips::DROTR;
5050 else if (ImmValue % 32 == 0)
5051 FinalOpcode = Mips::DROTR32;
5052 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
5054 FinalOpcode = Mips::DROTR32;
5056 FinalOpcode = Mips::DROTR;
5057 }
else if (ImmValue >= 33) {
5059 FinalOpcode = Mips::DROTR;
5061 FinalOpcode = Mips::DROTR32;
5064 uint64_t ShiftValue = ImmValue % 32;
5066 ShiftValue = (32 - ImmValue % 32) % 32;
5068 TOut.
emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
5074 if (ImmValue == 0) {
5075 TOut.
emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.
getLoc(), STI);
5083 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5084 FirstShift = Mips::DSLL;
5085 SecondShift = Mips::DSRL32;
5087 if (ImmValue == 32) {
5088 FirstShift = Mips::DSLL32;
5089 SecondShift = Mips::DSRL32;
5091 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5092 FirstShift = Mips::DSLL32;
5093 SecondShift = Mips::DSRL;
5097 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5098 FirstShift = Mips::DSRL;
5099 SecondShift = Mips::DSLL32;
5101 if (ImmValue == 32) {
5102 FirstShift = Mips::DSRL32;
5103 SecondShift = Mips::DSLL32;
5105 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5106 FirstShift = Mips::DSRL32;
5107 SecondShift = Mips::DSLL;
5112 ATReg = getATReg(Inst.
getLoc());
5116 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.
getLoc(), STI);
5117 TOut.
emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
5119 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5133 TOut.
emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
5134 if (FirstRegOp != SecondRegOp)
5135 TOut.
emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
5138 TOut.
emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
5146 unsigned ATReg = Mips::NoRegister;
5151 ATReg = getATReg(IDLoc);
5155 loadImmediate(ImmValue, ATReg, Mips::NoRegister,
true,
false, IDLoc, Out,
5158 TOut.
emitRR(Inst.
getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
5159 SrcReg, ATReg, IDLoc, STI);
5161 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5169 unsigned ATReg = Mips::NoRegister;
5174 ATReg = getATReg(Inst.
getLoc());
5178 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
5179 SrcReg, TmpReg, IDLoc, STI);
5181 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5183 TOut.
emitRRI(Inst.
getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
5184 DstReg, DstReg, 0x1F, IDLoc, STI);
5186 TOut.
emitR(Mips::MFHI, ATReg, IDLoc, STI);
5189 TOut.
emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
5196 TOut.
emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
5197 if (AssemblerOptions.
back()->isReorder())
5199 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5203 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5211 unsigned ATReg = Mips::NoRegister;
5216 ATReg = getATReg(IDLoc);
5220 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
5221 SrcReg, TmpReg, IDLoc, STI);
5223 TOut.
emitR(Mips::MFHI, ATReg, IDLoc, STI);
5224 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5226 TOut.
emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);