63 #define DEBUG_TYPE "mips-asm-parser"
75 class 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_; }
122 const 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,
138 assert(getParser().getStreamer().getTargetStreamer() &&
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"
172 checkEarlyTargetMatchPredicate(
MCInst &Inst,
174 unsigned checkTargetMatchPredicate(
MCInst &Inst)
override;
176 bool MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
179 bool MatchingInlineAsm)
override;
182 bool ParseRegister(
unsigned &RegNo,
SMLoc &StartLoc,
SMLoc &EndLoc)
override;
184 SMLoc &EndLoc)
override;
190 bool mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID);
195 bool ParseDirective(
AsmToken DirectiveID)
override;
216 enum MacroExpanderResultTy {
223 MacroExpanderResultTy tryExpandInstruction(
MCInst &Inst,
SMLoc IDLoc,
230 bool loadImmediate(int64_t ImmValue,
unsigned DstReg,
unsigned SrcReg,
231 bool Is32BitImm,
bool IsAddress,
SMLoc IDLoc,
234 bool loadAndAddSymbolAddress(
const MCExpr *SymExpr,
unsigned DstReg,
235 unsigned SrcReg,
bool Is32BitSym,
SMLoc IDLoc,
240 bool expandLoadImm(
MCInst &Inst,
bool Is32BitImm,
SMLoc IDLoc,
249 bool expandLoadDoubleImmToFPR(
MCInst &Inst,
bool Is64FPU,
SMLoc IDLoc,
252 bool expandLoadAddress(
unsigned DstReg,
unsigned BaseReg,
253 const MCOperand &Offset,
bool Is32BitAddress,
281 bool expandTrunc(
MCInst &Inst,
bool IsDouble,
bool Is64FPU,
SMLoc IDLoc,
356 bool reportParseError(
const Twine &ErrorMsg);
357 bool reportParseError(
SMLoc Loc,
const Twine &ErrorMsg);
359 bool parseMemOffset(
const MCExpr *&Res,
bool isParenExpr);
361 bool parseSetMips0Directive();
362 bool parseSetArchDirective();
363 bool parseSetFeature(
uint64_t Feature);
364 bool isPicAndNotNxxAbi();
365 bool parseDirectiveCpAdd(
SMLoc Loc);
366 bool parseDirectiveCpLoad(
SMLoc Loc);
367 bool parseDirectiveCpLocal(
SMLoc Loc);
368 bool parseDirectiveCpRestore(
SMLoc Loc);
369 bool parseDirectiveCPSetup();
370 bool parseDirectiveCPReturn();
371 bool parseDirectiveNaN();
372 bool parseDirectiveSet();
373 bool parseDirectiveOption();
374 bool parseInsnDirective();
375 bool parseRSectionDirective(
StringRef Section);
376 bool parseSSectionDirective(
StringRef Section,
unsigned Type);
378 bool parseSetAtDirective();
379 bool parseSetNoAtDirective();
380 bool parseSetMacroDirective();
381 bool parseSetNoMacroDirective();
382 bool parseSetMsaDirective();
383 bool parseSetNoMsaDirective();
384 bool parseSetNoDspDirective();
385 bool parseSetNoMips3DDirective();
386 bool parseSetReorderDirective();
387 bool parseSetNoReorderDirective();
388 bool parseSetMips16Directive();
389 bool parseSetNoMips16Directive();
390 bool parseSetFpDirective();
391 bool parseSetOddSPRegDirective();
392 bool parseSetNoOddSPRegDirective();
393 bool parseSetPopDirective();
394 bool parseSetPushDirective();
395 bool parseSetSoftFloatDirective();
396 bool parseSetHardFloatDirective();
397 bool parseSetMtDirective();
398 bool parseSetNoMtDirective();
399 bool parseSetNoCRCDirective();
400 bool parseSetNoVirtDirective();
401 bool parseSetNoGINVDirective();
403 bool parseSetAssignment();
405 bool parseDirectiveGpWord();
406 bool parseDirectiveGpDWord();
407 bool parseDirectiveDtpRelWord();
408 bool parseDirectiveDtpRelDWord();
409 bool parseDirectiveTpRelWord();
410 bool parseDirectiveTpRelDWord();
411 bool parseDirectiveModule();
412 bool parseDirectiveModuleFP();
416 bool parseInternalDirectiveReallowModule();
434 unsigned getReg(
int RC,
int RegNo);
439 unsigned getATReg(
SMLoc Loc);
449 bool validateMSAIndex(
int Val,
int RegKind);
476 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
478 setAvailableFeatures(
484 if (!(getSTI().getFeatureBits()[Feature])) {
486 setAvailableFeatures(
493 if (getSTI().getFeatureBits()[Feature]) {
495 setAvailableFeatures(
502 setFeatureBits(Feature, FeatureString);
503 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
507 clearFeatureBits(Feature, FeatureString);
508 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
512 enum MipsMatchResultTy {
513 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
514 Match_RequiresDifferentOperands,
515 Match_RequiresNoZeroRegister,
516 Match_RequiresSameSrcAndDst,
517 Match_NoFCCRegisterForCurrentISA,
518 Match_NonZeroOperandForSync,
519 Match_NonZeroOperandForMTCX,
520 Match_RequiresPosSizeRange0_32,
521 Match_RequiresPosSizeRange33_64,
522 Match_RequiresPosSizeUImm6,
523 #define GET_OPERAND_DIAGNOSTIC_TYPES
524 #include "MipsGenAsmMatcher.inc"
525 #undef GET_OPERAND_DIAGNOSTIC_TYPES
541 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
544 AssemblerOptions.push_back(
545 std::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
548 AssemblerOptions.push_back(
549 std::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
551 getTargetStreamer().updateABIInfo(*
this);
553 if (!isABI_O32() && !useOddSPReg() != 0)
558 IsPicEnabled = getContext().getObjectFileInfo()->isPositionIndependent();
560 IsCpRestoreSet =
false;
561 CpRestoreOffset = -1;
562 GPReg =
ABI.GetGlobalPtr();
567 if (getSTI().
getCPU() ==
"mips64r6" && inMicroMipsMode())
570 if (!isABI_O32() && inMicroMipsMode())
575 bool hasEightFccRegisters()
const {
return hasMips4() || hasMips32(); }
577 bool isGP64bit()
const {
578 return getSTI().getFeatureBits()[Mips::FeatureGP64Bit];
581 bool isFP64bit()
const {
582 return getSTI().getFeatureBits()[Mips::FeatureFP64Bit];
585 bool isJalrRelocAvailable(
const MCExpr *JalExpr) {
594 return ABI.IsN32() ||
ABI.IsN64();
599 bool isABI_N32()
const {
return ABI.IsN32(); }
600 bool isABI_N64()
const {
return ABI.IsN64(); }
601 bool isABI_O32()
const {
return ABI.IsO32(); }
602 bool isABI_FPXX()
const {
603 return getSTI().getFeatureBits()[Mips::FeatureFPXX];
606 bool useOddSPReg()
const {
607 return !(getSTI().getFeatureBits()[Mips::FeatureNoOddSPReg]);
610 bool inMicroMipsMode()
const {
611 return getSTI().getFeatureBits()[Mips::FeatureMicroMips];
614 bool hasMips1()
const {
615 return getSTI().getFeatureBits()[Mips::FeatureMips1];
618 bool hasMips2()
const {
619 return getSTI().getFeatureBits()[Mips::FeatureMips2];
622 bool hasMips3()
const {
623 return getSTI().getFeatureBits()[Mips::FeatureMips3];
626 bool hasMips4()
const {
627 return getSTI().getFeatureBits()[Mips::FeatureMips4];
630 bool hasMips5()
const {
631 return getSTI().getFeatureBits()[Mips::FeatureMips5];
634 bool hasMips32()
const {
635 return getSTI().getFeatureBits()[Mips::FeatureMips32];
638 bool hasMips64()
const {
639 return getSTI().getFeatureBits()[Mips::FeatureMips64];
642 bool hasMips32r2()
const {
643 return getSTI().getFeatureBits()[Mips::FeatureMips32r2];
646 bool hasMips64r2()
const {
647 return getSTI().getFeatureBits()[Mips::FeatureMips64r2];
650 bool hasMips32r3()
const {
651 return (getSTI().getFeatureBits()[Mips::FeatureMips32r3]);
654 bool hasMips64r3()
const {
655 return (getSTI().getFeatureBits()[Mips::FeatureMips64r3]);
658 bool hasMips32r5()
const {
659 return (getSTI().getFeatureBits()[Mips::FeatureMips32r5]);
662 bool hasMips64r5()
const {
663 return (getSTI().getFeatureBits()[Mips::FeatureMips64r5]);
666 bool hasMips32r6()
const {
667 return getSTI().getFeatureBits()[Mips::FeatureMips32r6];
670 bool hasMips64r6()
const {
671 return getSTI().getFeatureBits()[Mips::FeatureMips64r6];
674 bool hasDSP()
const {
675 return getSTI().getFeatureBits()[Mips::FeatureDSP];
678 bool hasDSPR2()
const {
679 return getSTI().getFeatureBits()[Mips::FeatureDSPR2];
682 bool hasDSPR3()
const {
683 return getSTI().getFeatureBits()[Mips::FeatureDSPR3];
686 bool hasMSA()
const {
687 return getSTI().getFeatureBits()[Mips::FeatureMSA];
690 bool hasCnMips()
const {
691 return (getSTI().getFeatureBits()[Mips::FeatureCnMips]);
694 bool hasCnMipsP()
const {
695 return (getSTI().getFeatureBits()[Mips::FeatureCnMipsP]);
702 bool inMips16Mode()
const {
703 return getSTI().getFeatureBits()[Mips::FeatureMips16];
706 bool useTraps()
const {
707 return getSTI().getFeatureBits()[Mips::FeatureUseTCCInDIV];
710 bool useSoftFloat()
const {
711 return getSTI().getFeatureBits()[Mips::FeatureSoftFloat];
714 return getSTI().getFeatureBits()[Mips::FeatureMT];
717 bool hasCRC()
const {
718 return getSTI().getFeatureBits()[Mips::FeatureCRC];
721 bool hasVirt()
const {
722 return getSTI().getFeatureBits()[Mips::FeatureVirt];
725 bool hasGINV()
const {
726 return getSTI().getFeatureBits()[Mips::FeatureGINV];
730 void warnIfRegIndexIsAT(
unsigned RegIndex,
SMLoc Loc);
732 void warnIfNoMacro(
SMLoc Loc);
734 bool isLittle()
const {
return IsLittleEndian; }
739 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);
895 Op->RegIdx.RegInfo = RegInfo;
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>
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 {
1737 case k_RegisterIndex: {
1738 StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length);
1740 return Token == OtherToken;
1766 case Mips::JRC16_MM:
1768 case Mips::JALRS_MM:
1769 case Mips::JALRS16_MM:
1770 case Mips::BGEZALS_MM:
1771 case Mips::BLTZALS_MM:
1781 if (
const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1782 return &SRExpr->getSymbol();
1785 if (
const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1798 if (
const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1805 if (isa<MCSymbolRefExpr>(Expr))
1808 if (
const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1812 if (
const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1831 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1842 if (NumOp != 3 && NumOp != 4)
1854 return !isInt<9>(
Op.getImm());
1872 bool MipsAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
1876 const unsigned Opcode = Inst.
getOpcode();
1878 bool ExpandedJalSym =
false;
1892 assert(hasCnMips() &&
"instruction only valid for octeon cpus");
1903 if (!
isIntN(inMicroMipsMode() ? 17 : 18,
Offset.getImm()))
1904 return Error(IDLoc,
"branch target out of range");
1907 return Error(IDLoc,
"branch to misaligned address");
1921 case Mips::BGEZAL_MM:
1922 case Mips::BLTZAL_MM:
1925 case Mips::BC1EQZC_MMR6:
1926 case Mips::BC1NEZC_MMR6:
1927 case Mips::BC2EQZC_MMR6:
1928 case Mips::BC2NEZC_MMR6:
1933 if (!
isIntN(inMicroMipsMode() ? 17 : 18,
Offset.getImm()))
1934 return Error(IDLoc,
"branch target out of range");
1937 return Error(IDLoc,
"branch to misaligned address");
1939 case Mips::BGEC:
case Mips::BGEC_MMR6:
1940 case Mips::BLTC:
case Mips::BLTC_MMR6:
1941 case Mips::BGEUC:
case Mips::BGEUC_MMR6:
1942 case Mips::BLTUC:
case Mips::BLTUC_MMR6:
1943 case Mips::BEQC:
case Mips::BEQC_MMR6:
1944 case Mips::BNEC:
case Mips::BNEC_MMR6:
1950 return Error(IDLoc,
"branch target out of range");
1952 return Error(IDLoc,
"branch to misaligned address");
1954 case Mips::BLEZC:
case Mips::BLEZC_MMR6:
1955 case Mips::BGEZC:
case Mips::BGEZC_MMR6:
1956 case Mips::BGTZC:
case Mips::BGTZC_MMR6:
1957 case Mips::BLTZC:
case Mips::BLTZC_MMR6:
1963 return Error(IDLoc,
"branch target out of range");
1965 return Error(IDLoc,
"branch to misaligned address");
1967 case Mips::BEQZC:
case Mips::BEQZC_MMR6:
1968 case Mips::BNEZC:
case Mips::BNEZC_MMR6:
1974 return Error(IDLoc,
"branch target out of range");
1976 return Error(IDLoc,
"branch to misaligned address");
1978 case Mips::BEQZ16_MM:
1979 case Mips::BEQZC16_MMR6:
1980 case Mips::BNEZ16_MM:
1981 case Mips::BNEZC16_MMR6:
1987 return Error(IDLoc,
"branch target out of range");
1989 return Error(IDLoc,
"branch to misaligned address");
1996 if (hasMips32r6() && Opcode == Mips::SSNOP) {
1997 std::string
ISA = hasMips64r6() ?
"MIPS64r6" :
"MIPS32r6";
1998 Warning(IDLoc,
"ssnop is deprecated for " +
ISA +
" and is equivalent to a "
2018 return Error(IDLoc,
"expected immediate operand kind");
2020 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
2021 Opcode == Mips::BBIT1 ? 63 : 31))
2022 return Error(IDLoc,
"immediate operand value out of range");
2024 Inst.
setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
2035 return Error(IDLoc,
"expected immediate operand kind");
2037 if (!isInt<10>(
Imm))
2038 return Error(IDLoc,
"immediate operand value out of range");
2050 unsigned FirstOp = 1;
2051 unsigned SecondOp = 2;
2055 case Mips::SDivIMacro:
2056 case Mips::UDivIMacro:
2057 case Mips::DSDivIMacro:
2058 case Mips::DUDivIMacro:
2062 Warning(IDLoc,
"dividing zero by zero");
2064 Warning(IDLoc,
"division by zero");
2076 case Mips::SDivMacro:
2077 case Mips::DSDivMacro:
2078 case Mips::UDivMacro:
2079 case Mips::DUDivMacro:
2084 case Mips::DIVU_MMR6:
2085 case Mips::DIV_MMR6:
2090 Warning(IDLoc,
"dividing zero by zero");
2092 Warning(IDLoc,
"division by zero");
2098 if ((Opcode == Mips::J || Opcode == Mips::J_MM) && inPicMode()) {
2100 BInst.
setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
2109 if ((Opcode == Mips::JAL || Opcode == Mips::JAL_MM) && inPicMode()) {
2110 warnIfNoMacro(IDLoc);
2117 return Error(IDLoc,
"jal doesn't support multiple symbols in PIC mode");
2123 if (expandLoadAddress(Mips::T9, Mips::NoRegister, Inst.
getOperand(0),
2124 !isGP64bit(), IDLoc, Out, STI))
2128 if (inMicroMipsMode())
2129 JalrInst.
setOpcode(IsCpRestoreSet ? Mips::JALRS_MM : Mips::JALR_MM);
2135 if (isJalrRelocAvailable(JalExpr)) {
2139 MCSymbol *TmpLabel = getContext().createTempSymbol();
2141 const MCExpr *RelocJalrExpr =
2143 getContext(), IDLoc);
2146 *TmpExpr, inMicroMipsMode() ?
"R_MICROMIPS_JALR" :
"R_MIPS_JALR",
2147 RelocJalrExpr, IDLoc, *STI);
2152 ExpandedJalSym =
true;
2162 expandMem9Inst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2165 expandMem16Inst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2168 return getParser().hasPendingError();
2172 if (inMicroMipsMode()) {
2173 if (MCID.
mayLoad() && Opcode != Mips::LWP_MM) {
2181 int MemOffset =
Op.getImm();
2184 if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
2187 (BaseReg.
getReg() == Mips::GP ||
2188 BaseReg.
getReg() == Mips::GP_64)) {
2190 TOut.
emitRRI(Mips::LWGP_MM, DstReg.
getReg(), Mips::GP, MemOffset,
2207 case Mips::ADDIUSP_MM:
2210 return Error(IDLoc,
"expected immediate operand kind");
2212 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
2214 return Error(IDLoc,
"immediate operand value out of range");
2216 case Mips::SLL16_MM:
2217 case Mips::SRL16_MM:
2220 return Error(IDLoc,
"expected immediate operand kind");
2222 if (Imm < 1 || Imm > 8)
2223 return Error(IDLoc,
"immediate operand value out of range");
2228 return Error(IDLoc,
"expected immediate operand kind");
2230 if (Imm < -1 || Imm > 126)
2231 return Error(IDLoc,
"immediate operand value out of range");
2233 case Mips::ADDIUR2_MM:
2236 return Error(IDLoc,
"expected immediate operand kind");
2238 if (!(
Imm == 1 ||
Imm == -1 ||
2239 ((
Imm % 4 == 0) && Imm < 28 && Imm > 0)))
2240 return Error(IDLoc,
"immediate operand value out of range");
2242 case Mips::ANDI16_MM:
2245 return Error(IDLoc,
"expected immediate operand kind");
2249 Imm == 64 ||
Imm == 255 ||
Imm == 32768 ||
Imm == 65535))
2250 return Error(IDLoc,
"immediate operand value out of range");
2252 case Mips::LBU16_MM:
2255 return Error(IDLoc,
"expected immediate operand kind");
2257 if (Imm < -1 || Imm > 14)
2258 return Error(IDLoc,
"immediate operand value out of range");
2261 case Mips::SB16_MMR6:
2264 return Error(IDLoc,
"expected immediate operand kind");
2266 if (Imm < 0 || Imm > 15)
2267 return Error(IDLoc,
"immediate operand value out of range");
2269 case Mips::LHU16_MM:
2271 case Mips::SH16_MMR6:
2274 return Error(IDLoc,
"expected immediate operand kind");
2276 if (Imm < 0 || Imm > 30 || (
Imm % 2 != 0))
2277 return Error(IDLoc,
"immediate operand value out of range");
2281 case Mips::SW16_MMR6:
2284 return Error(IDLoc,
"expected immediate operand kind");
2286 if (Imm < 0 || Imm > 60 || (
Imm % 4 != 0))
2287 return Error(IDLoc,
"immediate operand value out of range");
2289 case Mips::ADDIUPC_MM:
2292 return Error(IDLoc,
"expected immediate operand kind");
2294 if ((
Imm % 4 != 0) || !isInt<25>(
Imm))
2295 return Error(IDLoc,
"immediate operand value out of range");
2300 return Error(IDLoc,
"invalid operand for instruction");
2302 case Mips::MOVEP_MM:
2303 case Mips::MOVEP_MMR6: {
2306 bool RegPair = ((R0 == Mips::A1 && R1 == Mips::A2) ||
2307 (R0 == Mips::A1 && R1 == Mips::A3) ||
2308 (R0 == Mips::A2 && R1 == Mips::A3) ||
2309 (R0 == Mips::A0 && R1 == Mips::S5) ||
2310 (R0 == Mips::A0 && R1 == Mips::S6) ||
2311 (R0 == Mips::A0 && R1 == Mips::A1) ||
2312 (R0 == Mips::A0 && R1 == Mips::A2) ||
2313 (R0 == Mips::A0 && R1 == Mips::A3));
2315 return Error(IDLoc,
"invalid operand for instruction");
2321 bool FillDelaySlot =
2322 MCID.
hasDelaySlot() && AssemblerOptions.back()->isReorder();
2326 MacroExpanderResultTy ExpandResult =
2327 tryExpandInstruction(Inst, IDLoc, Out, STI);
2328 switch (ExpandResult) {
2340 if (inMicroMipsMode()) {
2347 if (FillDelaySlot) {
2352 if ((Opcode == Mips::JalOneReg || Opcode == Mips::JalTwoReg ||
2354 isPicAndNotNxxAbi()) {
2355 if (IsCpRestoreSet) {
2359 if (!AssemblerOptions.back()->isReorder())
2366 Warning(IDLoc,
"no .cprestore used in PIC mode");
2372 MipsAsmParser::MacroExpanderResultTy
2377 return MER_NotAMacro;
2378 case Mips::LoadImm32:
2379 return expandLoadImm(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2380 case Mips::LoadImm64:
2381 return expandLoadImm(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2382 case Mips::LoadAddrImm32:
2383 case Mips::LoadAddrImm64:
2386 "expected immediate operand kind");
2390 Inst.
getOpcode() == Mips::LoadAddrImm32, IDLoc,
2394 case Mips::LoadAddrReg32:
2395 case Mips::LoadAddrReg64:
2399 "expected immediate operand kind");
2403 Inst.
getOpcode() == Mips::LoadAddrReg32, IDLoc,
2407 case Mips::B_MM_Pseudo:
2408 case Mips::B_MMR6_Pseudo:
2409 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2413 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2415 case Mips::JalOneReg:
2416 case Mips::JalTwoReg:
2417 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2420 case Mips::BEQLImmMacro:
2421 case Mips::BNELImmMacro:
2422 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2439 case Mips::BLTImmMacro:
2440 case Mips::BLEImmMacro:
2441 case Mips::BGEImmMacro:
2442 case Mips::BGTImmMacro:
2443 case Mips::BLTUImmMacro:
2444 case Mips::BLEUImmMacro:
2445 case Mips::BGEUImmMacro:
2446 case Mips::BGTUImmMacro:
2447 case Mips::BLTLImmMacro:
2448 case Mips::BLELImmMacro:
2449 case Mips::BGELImmMacro:
2450 case Mips::BGTLImmMacro:
2451 case Mips::BLTULImmMacro:
2452 case Mips::BLEULImmMacro:
2453 case Mips::BGEULImmMacro:
2454 case Mips::BGTULImmMacro:
2455 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2456 case Mips::SDivMacro:
2457 case Mips::SDivIMacro:
2458 case Mips::SRemMacro:
2459 case Mips::SRemIMacro:
2460 return expandDivRem(Inst, IDLoc, Out, STI,
false,
true) ? MER_Fail
2462 case Mips::DSDivMacro:
2463 case Mips::DSDivIMacro:
2464 case Mips::DSRemMacro:
2465 case Mips::DSRemIMacro:
2466 return expandDivRem(Inst, IDLoc, Out, STI,
true,
true) ? MER_Fail
2468 case Mips::UDivMacro:
2469 case Mips::UDivIMacro:
2470 case Mips::URemMacro:
2471 case Mips::URemIMacro:
2472 return expandDivRem(Inst, IDLoc, Out, STI,
false,
false) ? MER_Fail
2474 case Mips::DUDivMacro:
2475 case Mips::DUDivIMacro:
2476 case Mips::DURemMacro:
2477 case Mips::DURemIMacro:
2478 return expandDivRem(Inst, IDLoc, Out, STI,
true,
false) ? MER_Fail
2480 case Mips::PseudoTRUNC_W_S:
2481 return expandTrunc(Inst,
false,
false, IDLoc, Out, STI) ? MER_Fail
2483 case Mips::PseudoTRUNC_W_D32:
2484 return expandTrunc(Inst,
true,
false, IDLoc, Out, STI) ? MER_Fail
2486 case Mips::PseudoTRUNC_W_D:
2487 return expandTrunc(Inst,
true,
true, IDLoc, Out, STI) ? MER_Fail
2490 case Mips::LoadImmSingleGPR:
2491 return expandLoadSingleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2493 case Mips::LoadImmSingleFGR:
2494 return expandLoadSingleImmToFPR(Inst, IDLoc, Out, STI) ? MER_Fail
2496 case Mips::LoadImmDoubleGPR:
2497 return expandLoadDoubleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2499 case Mips::LoadImmDoubleFGR:
2500 return expandLoadDoubleImmToFPR(Inst,
true, IDLoc, Out, STI) ? MER_Fail
2502 case Mips::LoadImmDoubleFGR_32:
2503 return expandLoadDoubleImmToFPR(Inst,
false, IDLoc, Out, STI) ? MER_Fail
2507 return expandUlh(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2509 return expandUlh(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2511 return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2514 return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2516 case Mips::NORImm64:
2517 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2520 return expandSge(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2523 case Mips::SGEImm64:
2524 case Mips::SGEUImm64:
2525 return expandSgeImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2528 case Mips::SGTImm64:
2529 case Mips::SGTUImm64:
2530 return expandSgtImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2533 return expandSle(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2536 case Mips::SLEImm64:
2537 case Mips::SLEUImm64:
2538 return expandSleImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2539 case Mips::SLTImm64:
2542 return MER_NotAMacro;
2544 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2545 case Mips::SLTUImm64:
2548 return MER_NotAMacro;
2550 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2551 case Mips::ADDi:
case Mips::ADDi_MM:
2552 case Mips::ADDiu:
case Mips::ADDiu_MM:
2553 case Mips::SLTi:
case Mips::SLTi_MM:
2554 case Mips::SLTiu:
case Mips::SLTiu_MM:
2559 return MER_NotAMacro;
2560 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2563 return MER_NotAMacro;
2564 case Mips::ANDi:
case Mips::ANDi_MM:
case Mips::ANDi64:
2565 case Mips::ORi:
case Mips::ORi_MM:
case Mips::ORi64:
2566 case Mips::XORi:
case Mips::XORi_MM:
case Mips::XORi64:
2571 return MER_NotAMacro;
2572 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2575 return MER_NotAMacro;
2578 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2581 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2584 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2587 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2588 case Mips::ABSMacro:
2589 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2590 case Mips::MULImmMacro:
2591 case Mips::DMULImmMacro:
2592 return expandMulImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2593 case Mips::MULOMacro:
2594 case Mips::DMULOMacro:
2595 return expandMulO(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2596 case Mips::MULOUMacro:
2597 case Mips::DMULOUMacro:
2598 return expandMulOU(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2599 case Mips::DMULMacro:
2600 return expandDMULMacro(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2603 return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2608 return expandStoreDM1Macro(Inst, IDLoc, Out, STI)
2611 case Mips::SEQMacro:
2612 return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2613 case Mips::SEQIMacro:
2614 return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2615 case Mips::SNEMacro:
2616 return expandSne(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2617 case Mips::SNEIMacro:
2618 return expandSneI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2619 case Mips::MFTC0:
case Mips::MTTC0:
2620 case Mips::MFTGPR:
case Mips::MTTGPR:
2621 case Mips::MFTLO:
case Mips::MTTLO:
2622 case Mips::MFTHI:
case Mips::MTTHI:
2623 case Mips::MFTACX:
case Mips::MTTACX:
2624 case Mips::MFTDSP:
case Mips::MTTDSP:
2625 case Mips::MFTC1:
case Mips::MTTC1:
2626 case Mips::MFTHC1:
case Mips::MTTHC1:
2627 case Mips::CFTC1:
case Mips::CTTC1:
2628 return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2630 case Mips::SaadAddr:
2631 return expandSaaAddr(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2635 bool MipsAsmParser::expandJalWithRegs(
MCInst &Inst,
SMLoc IDLoc,
2644 const unsigned Opcode = Inst.
getOpcode();
2646 if (Opcode == Mips::JalOneReg) {
2648 if (IsCpRestoreSet && inMicroMipsMode()) {
2651 }
else if (inMicroMipsMode()) {
2652 JalrInst.
setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2659 }
else if (Opcode == Mips::JalTwoReg) {
2661 if (IsCpRestoreSet && inMicroMipsMode())
2664 JalrInst.
setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2674 if (MCID.
hasDelaySlot() && AssemblerOptions.back()->isReorder())
2685 return (
x ==
x >> BitNum << BitNum) && isUInt<N>(
x >> BitNum);
2698 bool MipsAsmParser::loadImmediate(int64_t ImmValue,
unsigned DstReg,
2699 unsigned SrcReg,
bool Is32BitImm,
2704 if (!Is32BitImm && !isGP64bit()) {
2705 Error(IDLoc,
"instruction requires a 64-bit architecture");
2714 ImmValue = SignExtend64<32>(ImmValue);
2716 Error(IDLoc,
"instruction requires a 32-bit immediate");
2721 unsigned ZeroReg = IsAddress ?
ABI.GetNullPtr() :
ABI.GetZeroReg();
2722 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2724 bool UseSrcReg =
false;
2725 if (SrcReg != Mips::NoRegister)
2728 unsigned TmpReg = DstReg;
2730 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2733 unsigned ATReg = getATReg(IDLoc);
2746 if (IsAddress && !Is32BitImm) {
2747 TOut.
emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2751 TOut.
emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2756 unsigned TmpReg = DstReg;
2757 if (SrcReg == DstReg) {
2758 TmpReg = getATReg(IDLoc);
2763 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2765 TOut.
emitRRR(
ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2770 warnIfNoMacro(IDLoc);
2772 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2773 uint16_t Bits15To0 = ImmValue & 0xffff;
2774 if (!Is32BitImm && !
isInt<32>(ImmValue)) {
2777 if (ImmValue == 0xffffffff) {
2778 TOut.
emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2779 TOut.
emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2781 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2787 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2788 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2790 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2792 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2796 TOut.
emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2798 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2800 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2804 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2806 Error(IDLoc,
"instruction requires a 32-bit immediate");
2814 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2816 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg,
Bits, IDLoc, STI);
2817 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2820 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2825 warnIfNoMacro(IDLoc);
2832 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister,
true,
false,
2838 unsigned ShiftCarriedForwards = 16;
2839 for (
int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2840 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2842 if (ImmChunk != 0) {
2843 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2844 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2845 ShiftCarriedForwards = 0;
2848 ShiftCarriedForwards += 16;
2850 ShiftCarriedForwards -= 16;
2853 if (ShiftCarriedForwards)
2854 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2857 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2862 bool MipsAsmParser::expandLoadImm(
MCInst &Inst,
bool Is32BitImm,
SMLoc IDLoc,
2865 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
2867 assert(DstRegOp.
isReg() &&
"expected register operand kind");
2869 if (loadImmediate(ImmOp.
getImm(), DstRegOp.
getReg(), Mips::NoRegister,
2870 Is32BitImm,
false, IDLoc, Out, STI))
2876 bool MipsAsmParser::expandLoadAddress(
unsigned DstReg,
unsigned BaseReg,
2878 bool Is32BitAddress,
SMLoc IDLoc,
2882 if (Is32BitAddress &&
ABI.ArePtrs64bit()) {
2883 Warning(IDLoc,
"la used to load 64-bit address");
2885 Is32BitAddress =
false;
2889 if (!Is32BitAddress && !hasMips3()) {
2890 Error(IDLoc,
"instruction requires a 64-bit architecture");
2895 return loadAndAddSymbolAddress(
Offset.getExpr(), DstReg, BaseReg,
2896 Is32BitAddress, IDLoc, Out, STI);
2898 if (!
ABI.ArePtrs64bit()) {
2900 Is32BitAddress =
true;
2903 return loadImmediate(
Offset.getImm(), DstReg, BaseReg, Is32BitAddress,
true,
2907 bool MipsAsmParser::loadAndAddSymbolAddress(
const MCExpr *SymExpr,
2908 unsigned DstReg,
unsigned SrcReg,
2909 bool Is32BitSym,
SMLoc IDLoc,
2913 bool UseSrcReg = SrcReg != Mips::NoRegister && SrcReg != Mips::ZERO &&
2914 SrcReg != Mips::ZERO_64;
2915 warnIfNoMacro(IDLoc);
2920 Error(IDLoc,
"expected relocatable expression");
2923 if (Res.
getSymB() !=
nullptr) {
2924 Error(IDLoc,
"expected relocatable expression with only one symbol");
2928 bool IsPtr64 =
ABI.ArePtrs64bit();
2935 bool UseXGOT = STI->
getFeatureBits()[Mips::FeatureXGOT] && !IsLocalSym;
2941 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2945 SymExpr, getContext());
2947 SymExpr, getContext());
2950 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, DstReg, GPReg,
2963 unsigned TmpReg = DstReg;
2965 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2969 unsigned ATReg = getATReg(IDLoc);
2988 const MCExpr *CallHiExpr =
2995 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg, GPReg,
3001 TOut.
emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3007 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3013 const MCExpr *LoExpr =
nullptr;
3014 if (
ABI.IsN32() ||
ABI.IsN64()) {
3033 Error(IDLoc,
"macro instruction uses large offset, which is not "
3034 "currently supported");
3068 TOut.
emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3072 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3084 if (
ABI.ArePtrs64bit() && isGP64bit()) {
3098 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
3100 if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
3101 unsigned ATReg = getATReg(IDLoc);
3113 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3115 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3118 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3121 TOut.
emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
3124 }
else if (canUseATReg() && !RdRegIsRsReg && DstReg != getATReg(IDLoc)) {
3125 unsigned ATReg = getATReg(IDLoc);
3141 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3145 TOut.
emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3146 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3148 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3151 }
else if ((!canUseATReg() && !RdRegIsRsReg) ||
3152 (canUseATReg() && DstReg == getATReg(IDLoc))) {
3163 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3165 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3166 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3168 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3169 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3172 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3178 assert(SrcReg == DstReg && !canUseATReg() &&
3179 "Could have expanded dla but didn't?");
3180 reportParseError(IDLoc,
3181 "pseudo-instruction requires $at, which is not available");
3195 unsigned TmpReg = DstReg;
3197 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
3200 unsigned ATReg = getATReg(IDLoc);
3211 TOut.
emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3214 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
3223 if (MipsMCRegisterClasses[Mips::FGR32RegClassID].
contains(
Reg))
3224 return Reg == (unsigned)Mips::F31 ? (
unsigned)Mips::F0 :
Reg + 1;
3226 default:
llvm_unreachable(
"Unknown register in assembly macro expansion!");
3227 case Mips::ZERO:
return Mips::AT;
3228 case Mips::AT:
return Mips::V0;
3229 case Mips::V0:
return Mips::V1;
3230 case Mips::V1:
return Mips::A0;
3231 case Mips::A0:
return Mips::A1;
3232 case Mips::A1:
return Mips::A2;
3233 case Mips::A2:
return Mips::A3;
3234 case Mips::A3:
return Mips::T0;
3237 case Mips::T2:
return Mips::T3;
3238 case Mips::T3:
return Mips::T4;
3239 case Mips::T4:
return Mips::T5;
3240 case Mips::T5:
return Mips::T6;
3241 case Mips::T6:
return Mips::T7;
3242 case Mips::T7:
return Mips::S0;
3243 case Mips::S0:
return Mips::S1;
3244 case Mips::S1:
return Mips::S2;
3245 case Mips::S2:
return Mips::S3;
3246 case Mips::S3:
return Mips::S4;
3247 case Mips::S4:
return Mips::S5;
3248 case Mips::S5:
return Mips::S6;
3249 case Mips::S6:
return Mips::S7;
3252 case Mips::T9:
return Mips::K0;
3253 case Mips::K0:
return Mips::K1;
3254 case Mips::K1:
return Mips::GP;
3255 case Mips::GP:
return Mips::SP;
3256 case Mips::SP:
return Mips::FP;
3257 case Mips::FP:
return Mips::RA;
3258 case Mips::RA:
return Mips::ZERO;
3259 case Mips::D0:
return Mips::F1;
3260 case Mips::D1:
return Mips::F3;
3261 case Mips::D2:
return Mips::F5;
3262 case Mips::D3:
return Mips::F7;
3263 case Mips::D4:
return Mips::F9;
3264 case Mips::D5:
return Mips::F11;
3265 case Mips::D6:
return Mips::F13;
3266 case Mips::D7:
return Mips::F15;
3267 case Mips::D8:
return Mips::F17;
3268 case Mips::D9:
return Mips::F19;
3269 case Mips::D10:
return Mips::F21;
3270 case Mips::D11:
return Mips::F23;
3271 case Mips::D12:
return Mips::F25;
3272 case Mips::D13:
return Mips::F27;
3273 case Mips::D14:
return Mips::F29;
3274 case Mips::D15:
return Mips::F31;
3286 unsigned ATReg = getATReg(IDLoc);
3296 if(isABI_O32() || isABI_N32()) {
3315 if(isABI_O32() || isABI_N32()) {
3318 const MCExpr *HighestSym =
3322 const MCExpr *HigherSym =
3329 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3331 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3334 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3343 if ((
Hi_32(ImmOp64) & 0x7ff00000) == 0) {
3354 float TmpFloat =
static_cast<float>(DoubleImm);
3358 bool MipsAsmParser::expandLoadSingleImmToGPR(
MCInst &Inst,
SMLoc IDLoc,
3363 "Invalid instruction operand.");
3370 return loadImmediate(ImmOp32, FirstReg, Mips::NoRegister,
true,
false, IDLoc,
3374 bool MipsAsmParser::expandLoadSingleImmToFPR(
MCInst &Inst,
SMLoc IDLoc,
3380 "Invalid instruction operand.");
3389 unsigned TmpReg = Mips::ZERO;
3391 TmpReg = getATReg(IDLoc);
3396 if (
Lo_32(ImmOp64) == 0) {
3397 if (TmpReg != Mips::ZERO && loadImmediate(ImmOp32, TmpReg, Mips::NoRegister,
3398 true,
false, IDLoc, Out, STI))
3400 TOut.
emitRR(Mips::MTC1, FirstReg, TmpReg, IDLoc, STI);
3404 MCSection *CS = getStreamer().getCurrentSectionOnly();
3410 MCSymbol *Sym = getContext().createTempSymbol();
3416 getStreamer().switchSection(ReadOnlySection);
3417 getStreamer().emitLabel(Sym, IDLoc);
3418 getStreamer().emitInt32(ImmOp32);
3419 getStreamer().switchSection(CS);
3421 if (emitPartialAddress(TOut, IDLoc, Sym))
3428 bool MipsAsmParser::expandLoadDoubleImmToGPR(
MCInst &Inst,
SMLoc IDLoc,
3434 "Invalid instruction operand.");
3441 if (
Lo_32(ImmOp64) == 0) {
3443 if (loadImmediate(ImmOp64, FirstReg, Mips::NoRegister,
false,
false,
3447 if (loadImmediate(
Hi_32(ImmOp64), FirstReg, Mips::NoRegister,
true,
false,
3451 if (loadImmediate(0,
nextReg(FirstReg), Mips::NoRegister,
true,
false,
3458 MCSection *CS = getStreamer().getCurrentSectionOnly();
3462 MCSymbol *Sym = getContext().createTempSymbol();
3468 getStreamer().switchSection(ReadOnlySection);
3469 getStreamer().emitLabel(Sym, IDLoc);
3470 getStreamer().emitValueToAlignment(8);
3471 getStreamer().emitIntValue(ImmOp64, 8);
3472 getStreamer().switchSection(CS);
3474 unsigned TmpReg = getATReg(IDLoc);
3478 if (emitPartialAddress(TOut, IDLoc, Sym))
3481 TOut.
emitRRX(isABI_N64() ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3487 TOut.
emitRRI(Mips::LW, FirstReg, TmpReg, 0, IDLoc, STI);
3488 TOut.
emitRRI(Mips::LW,
nextReg(FirstReg), TmpReg, 4, IDLoc, STI);
3493 bool MipsAsmParser::expandLoadDoubleImmToFPR(
MCInst &Inst,
bool Is64FPU,
3499 "Invalid instruction operand.");
3506 unsigned TmpReg = Mips::ZERO;
3508 TmpReg = getATReg(IDLoc);
3513 if ((
Lo_32(ImmOp64) == 0) &&
3514 !((
Hi_32(ImmOp64) & 0xffff0000) && (
Hi_32(ImmOp64) & 0x0000ffff))) {
3516 if (TmpReg != Mips::ZERO &&
3517 loadImmediate(ImmOp64, TmpReg, Mips::NoRegister,
false,
false, IDLoc,
3520 TOut.
emitRR(Mips::DMTC1, FirstReg, TmpReg, IDLoc, STI);
3524 if (TmpReg != Mips::ZERO &&
3525 loadImmediate(
Hi_32(ImmOp64), TmpReg, Mips::NoRegister,
true,
false,
3529 if (hasMips32r2()) {
3530 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3531 TOut.
emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, TmpReg, IDLoc, STI);
3533 TOut.
emitRR(Mips::MTC1,
nextReg(FirstReg), TmpReg, IDLoc, STI);
3534 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3539 MCSection *CS = getStreamer().getCurrentSectionOnly();
3545 MCSymbol *Sym = getContext().createTempSymbol();
3551 getStreamer().switchSection(ReadOnlySection);
3552 getStreamer().emitLabel(Sym, IDLoc);
3553 getStreamer().emitValueToAlignment(8);
3554 getStreamer().emitIntValue(ImmOp64, 8);
3555 getStreamer().switchSection(CS);
3557 if (emitPartialAddress(TOut, IDLoc, Sym))
3560 TOut.
emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, TmpReg,
3566 bool MipsAsmParser::expandUncondBranchMMPseudo(
MCInst &Inst,
SMLoc IDLoc,
3572 "unexpected number of operands");
3582 assert(
Offset.isImm() &&
"expected immediate operand kind");
3583 if (isInt<11>(
Offset.getImm())) {
3586 if (inMicroMipsMode())
3587 Inst.
setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3589 if (!isInt<17>(
Offset.getImm()))
3590 return Error(IDLoc,
"branch target out of range");
3592 return Error(IDLoc,
"branch to misaligned address");
3605 if (MCID.
hasDelaySlot() && AssemblerOptions.back()->isReorder())
3615 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3618 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
3622 "expected immediate or expression operand");
3624 bool IsLikely =
false;
3626 unsigned OpCode = 0;
3634 case Mips::BEQLImmMacro:
3635 OpCode = Mips::BEQL;
3638 case Mips::BNELImmMacro:
3639 OpCode = Mips::BNEL;
3647 int64_t ImmValue = ImmOp.
getImm();
3648 if (ImmValue == 0) {
3652 TOut.
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3654 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3657 warnIfNoMacro(IDLoc);
3659 unsigned ATReg = getATReg(IDLoc);
3663 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(),
true,
3670 TOut.
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3672 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3680 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3681 unsigned StartOp = NumOp == 3 ? 0 : 1;
3684 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3686 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3691 unsigned DstReg = DstRegOp.
getReg();
3692 unsigned BaseReg = BaseRegOp.
getReg();
3693 unsigned TmpReg = DstReg;
3697 unsigned DstRegClassID =
3698 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3699 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3700 (DstRegClassID == Mips::GPR64RegClassID);
3702 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3705 TmpReg = getATReg(IDLoc);
3712 TOut.
emitRRX(OpCode, DstReg, TmpReg, Off, IDLoc, STI);
3714 TOut.
emitRRRX(OpCode, DstReg, DstReg, TmpReg, Off, IDLoc, STI);
3717 if (OffsetOp.
isImm()) {
3718 int64_t LoOffset = OffsetOp.
getImm() & 0xffff;
3719 int64_t HiOffset = OffsetOp.
getImm() & ~0xffff;
3723 if (LoOffset & 0x8000)
3724 HiOffset += 0x10000;
3726 bool IsLargeOffset = HiOffset != 0;
3728 if (IsLargeOffset) {
3730 if (loadImmediate(HiOffset, TmpReg, Mips::NoRegister, Is32BitImm,
true,
3735 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3736 TOut.
emitRRR(
ABI.ArePtrs64bit() ? Mips::DADDu : Mips::ADDu, TmpReg,
3737 TmpReg, BaseReg, IDLoc, STI);
3752 Error(IDLoc,
"expected relocatable expression");
3755 if (Res.
getSymB() !=
nullptr) {
3756 Error(IDLoc,
"expected relocatable expression with only one symbol");
3760 loadAndAddSymbolAddress(Res.
getSymA(), TmpReg, BaseReg,
3761 !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3781 TOut.
emitRX(Mips::LUi, TmpReg, HighestOperand, IDLoc, STI);
3782 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HigherOperand, IDLoc, STI);
3783 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3784 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HiOperand, IDLoc, STI);
3785 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3786 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3787 TOut.
emitRRR(Mips::DADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3788 emitInstWithOffset(LoOperand);
3791 TOut.
emitRX(Mips::LUi, TmpReg, HiOperand, IDLoc, STI);
3792 if (BaseReg != Mips::ZERO)
3793 TOut.
emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3795 emitInstWithOffset(LoOperand);
3807 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3808 unsigned StartOp = NumOp == 3 ? 0 : 1;
3811 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3813 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3818 unsigned DstReg = DstRegOp.
getReg();
3819 unsigned BaseReg = BaseRegOp.
getReg();
3820 unsigned TmpReg = DstReg;
3824 unsigned DstRegClassID =
3825 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3826 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3827 (DstRegClassID == Mips::GPR64RegClassID);
3829 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3832 TmpReg = getATReg(IDLoc);
3837 auto emitInst = [&]() {
3845 if (OffsetOp.
isImm()) {
3846 loadImmediate(OffsetOp.
getImm(), TmpReg, BaseReg, !
ABI.ArePtrs64bit(),
true,
3853 loadAndAddSymbolAddress(OffsetOp.
getExpr(), TmpReg, BaseReg,
3854 !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3862 bool MipsAsmParser::expandLoadStoreMultiple(
MCInst &Inst,
SMLoc IDLoc,
3867 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3871 Inst.
getOperand(OpNum - 3).
isReg() &&
"Invalid instruction operand.");
3880 if (inMicroMipsMode() && hasMips32r6())
3881 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3883 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3891 bool MipsAsmParser::expandCondBranches(
MCInst &Inst,
SMLoc IDLoc,
3895 bool EmittedNoMacroWarning =
false;
3896 unsigned PseudoOpcode = Inst.
getOpcode();
3901 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3902 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3907 else if (TrgOp.
isImm()) {
3908 warnIfNoMacro(IDLoc);
3909 EmittedNoMacroWarning =
true;
3911 TrgReg = getATReg(IDLoc);
3915 switch(PseudoOpcode) {
3918 case Mips::BLTImmMacro:
3919 PseudoOpcode = Mips::BLT;
3921 case Mips::BLEImmMacro:
3922 PseudoOpcode = Mips::BLE;
3924 case Mips::BGEImmMacro:
3925 PseudoOpcode = Mips::BGE;
3927 case Mips::BGTImmMacro:
3928 PseudoOpcode = Mips::BGT;
3930 case Mips::BLTUImmMacro:
3931 PseudoOpcode = Mips::BLTU;
3933 case Mips::BLEUImmMacro:
3934 PseudoOpcode = Mips::BLEU;
3936 case Mips::BGEUImmMacro:
3937 PseudoOpcode = Mips::BGEU;
3939 case Mips::BGTUImmMacro:
3940 PseudoOpcode = Mips::BGTU;
3942 case Mips::BLTLImmMacro:
3943 PseudoOpcode = Mips::BLTL;
3945 case Mips::BLELImmMacro:
3946 PseudoOpcode = Mips::BLEL;
3948 case Mips::BGELImmMacro:
3949 PseudoOpcode = Mips::BGEL;
3951 case Mips::BGTLImmMacro:
3952 PseudoOpcode = Mips::BGTL;
3954 case Mips::BLTULImmMacro:
3955 PseudoOpcode = Mips::BLTUL;
3957 case Mips::BLEULImmMacro:
3958 PseudoOpcode = Mips::BLEUL;
3960 case Mips::BGEULImmMacro:
3961 PseudoOpcode = Mips::BGEUL;
3963 case Mips::BGTULImmMacro:
3964 PseudoOpcode = Mips::BGTUL;
3968 if (loadImmediate(TrgOp.
getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
3969 false, IDLoc, Out, STI))
3973 switch (PseudoOpcode) {
3978 AcceptsEquality =
false;
3979 ReverseOrderSLT =
false;
3981 ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
3982 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
3983 ZeroSrcOpcode = Mips::BGTZ;
3984 ZeroTrgOpcode = Mips::BLTZ;
3990 AcceptsEquality =
true;
3991 ReverseOrderSLT =
true;
3993 ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
3994 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
3995 ZeroSrcOpcode = Mips::BGEZ;
3996 ZeroTrgOpcode = Mips::BLEZ;
4002 AcceptsEquality =
true;
4003 ReverseOrderSLT =
false;
4005 ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
4006 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
4007 ZeroSrcOpcode = Mips::BLEZ;
4008 ZeroTrgOpcode = Mips::BGEZ;
4014 AcceptsEquality =
false;
4015 ReverseOrderSLT =
true;
4017 ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
4018 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
4019 ZeroSrcOpcode = Mips::BLTZ;
4020 ZeroTrgOpcode = Mips::BGTZ;
4026 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
4027 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
4028 if (IsSrcRegZero && IsTrgRegZero) {
4032 if (PseudoOpcode == Mips::BLT) {
4037 if (PseudoOpcode == Mips::BLE) {
4040 Warning(IDLoc,
"branch is always taken");
4043 if (PseudoOpcode == Mips::BGE) {
4046 Warning(IDLoc,
"branch is always taken");
4049 if (PseudoOpcode == Mips::BGT) {
4054 if (PseudoOpcode == Mips::BGTU) {
4055 TOut.
emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
4059 if (AcceptsEquality) {
4062 TOut.
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4064 Warning(IDLoc,
"branch is always taken");
4071 if (IsSrcRegZero || IsTrgRegZero) {
4072 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
4073 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
4080 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
4081 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
4087 TOut.
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4089 Warning(IDLoc,
"branch is always taken");
4105 TOut.
emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
4106 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
4113 TOut.
emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
4114 IsSrcRegZero ? TrgReg : SrcReg,
4121 unsigned ATRegNum = getATReg(IDLoc);
4125 if (!EmittedNoMacroWarning)
4126 warnIfNoMacro(IDLoc);
4143 TOut.
emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
4144 ReverseOrderSLT ? TrgReg : SrcReg,
4145 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
4147 TOut.
emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
4148 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
4164 const bool IsMips64,
const bool Signed) {
4167 warnIfNoMacro(IDLoc);
4170 assert(RdRegOp.
isReg() &&
"expected register operand kind");
4171 unsigned RdReg = RdRegOp.
getReg();
4174 assert(RsRegOp.
isReg() &&
"expected register operand kind");
4175 unsigned RsReg = RsRegOp.
getReg();
4182 "expected register or immediate operand kind");
4186 ImmValue = RtOp.
getImm();
4193 DivOp =
Signed ? Mips::DSDIV : Mips::DUDIV;
4194 ZeroReg = Mips::ZERO_64;
4198 ZeroReg = Mips::ZERO;
4202 bool UseTraps = useTraps();
4205 bool isDiv = Opcode == Mips::SDivMacro || Opcode == Mips::SDivIMacro ||
4206 Opcode == Mips::UDivMacro || Opcode == Mips::UDivIMacro ||
4207 Opcode == Mips::DSDivMacro || Opcode == Mips::DSDivIMacro ||
4208 Opcode == Mips::DUDivMacro || Opcode == Mips::DUDivIMacro;
4210 bool isRem = Opcode == Mips::SRemMacro || Opcode == Mips::SRemIMacro ||
4211 Opcode == Mips::URemMacro || Opcode == Mips::URemIMacro ||
4212 Opcode == Mips::DSRemMacro || Opcode == Mips::DSRemIMacro ||
4213 Opcode == Mips::DURemMacro || Opcode == Mips::DURemIMacro;
4216 unsigned ATReg = getATReg(IDLoc);
4220 if (ImmValue == 0) {
4222 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4224 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4228 if (isRem && (ImmValue == 1 || (
Signed && (ImmValue == -1)))) {
4231 }
else if (isDiv && ImmValue == 1) {
4234 }
else if (isDiv &&
Signed && ImmValue == -1) {
4235 TOut.
emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
4238 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister,
isInt<32>(ImmValue),
4239 false, Inst.
getLoc(), Out, STI))
4241 TOut.
emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
4252 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
4254 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4257 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4263 if (isRem && (RdReg == Mips::ZERO || RdReg == Mips::ZERO_64)) {
4264 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4274 TOut.
emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4277 BrTarget =
Context.createTempSymbol();
4279 TOut.
emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4282 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4285 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4295 unsigned ATReg = getATReg(IDLoc);
4302 TOut.
emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
4310 TOut.
emitRRX(Mips::BNE, RtReg, ATReg, LabelOpEnd, IDLoc, STI);
4313 TOut.
emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
4314 TOut.
emitDSLL(ATReg, ATReg, 63, IDLoc, STI);
4320 TOut.
emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
4323 TOut.
emitRRX(Mips::BNE, RsReg, ATReg, LabelOpEnd, IDLoc, STI);
4325 TOut.
emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
4333 bool MipsAsmParser::expandTrunc(
MCInst &Inst,
bool IsDouble,
bool Is64FPU,
4346 if (hasMips1() && !hasMips2()) {
4347 unsigned ATReg = getATReg(IDLoc);
4350 TOut.
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4351 TOut.
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4353 TOut.
emitRRI(Mips::ORi, ATReg, ThirdReg, 0
x3, IDLoc, STI);
4354 TOut.
emitRRI(Mips::XORi, ATReg, ATReg, 0
x2, IDLoc, STI);
4355 TOut.
emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4357 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4359 FirstReg, SecondReg, IDLoc, STI);
4360 TOut.
emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4365 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4367 FirstReg, SecondReg, IDLoc, STI);
4374 if (hasMips32r6() || hasMips64r6()) {
4375 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4379 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4381 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4383 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4386 unsigned DstReg = DstRegOp.
getReg();
4387 unsigned SrcReg = SrcRegOp.
getReg();
4388 int64_t OffsetValue = OffsetImmOp.
getImm();
4392 warnIfNoMacro(IDLoc);
4393 unsigned ATReg = getATReg(IDLoc);
4398 if (IsLargeOffset) {
4399 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4404 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4405 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4409 unsigned FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4410 unsigned SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4412 unsigned LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4413 unsigned SllReg = IsLargeOffset ? DstReg : ATReg;
4415 TOut.
emitRRI(
Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4416 FirstOffset, IDLoc, STI);
4417 TOut.
emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4418 TOut.
emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4426 if (hasMips32r6() || hasMips64r6()) {
4427 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4431 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4433 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4435 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4438 unsigned DstReg = DstRegOp.
getReg();
4439 unsigned SrcReg = SrcRegOp.
getReg();
4440 int64_t OffsetValue = OffsetImmOp.
getImm();
4442 warnIfNoMacro(IDLoc);
4443 unsigned ATReg = getATReg(IDLoc);
4448 if (IsLargeOffset) {
4449 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4454 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4455 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4459 if (IsLargeOffset) {
4460 TOut.
emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4462 TOut.
emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4463 TOut.
emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4464 TOut.
emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4467 TOut.
emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4469 TOut.
emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4477 if (hasMips32r6() || hasMips64r6()) {
4478 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4482 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4484 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4486 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4489 unsigned DstReg = DstRegOp.
getReg();
4490 unsigned SrcReg = SrcRegOp.
getReg();
4491 int64_t OffsetValue = OffsetImmOp.
getImm();
4495 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4496 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4500 bool IsLoadInst = (Inst.
getOpcode() == Mips::Ulw);
4501 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4502 unsigned TmpReg = SrcReg;
4503 if (IsLargeOffset || DoMove) {
4504 warnIfNoMacro(IDLoc);
4505 TmpReg = getATReg(IDLoc);
4510 if (IsLargeOffset) {
4511 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4521 TOut.
emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4522 TOut.
emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4544 warnIfNoMacro(IDLoc);
4551 OpCode = Mips::SLTu;
4558 TOut.
emitRRR(OpCode, DstReg, SrcReg, OpReg, IDLoc, STI);
4559 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4576 unsigned OpRegCode, OpImmCode;
4578 warnIfNoMacro(IDLoc);
4582 case Mips::SGEImm64:
4583 OpRegCode = Mips::SLT;
4584 OpImmCode = Mips::SLTi;
4587 case Mips::SGEUImm64:
4588 OpRegCode = Mips::SLTu;
4589 OpImmCode = Mips::SLTiu;
4598 TOut.
emitRRI(OpImmCode, DstReg, SrcReg, ImmValue, IDLoc, STI);
4599 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4601 unsigned ImmReg = DstReg;
4602 if (DstReg == SrcReg) {
4603 unsigned ATReg = getATReg(Inst.
getLoc());
4609 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister,
isInt<32>(ImmValue),
4610 false, IDLoc, Out, STI))
4613 TOut.
emitRRR(OpRegCode, DstReg, SrcReg, ImmReg, IDLoc, STI);
4614 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4631 unsigned ImmReg = DstReg;
4635 warnIfNoMacro(IDLoc);
4639 case Mips::SGTImm64:
4643 case Mips::SGTUImm64:
4644 OpCode = Mips::SLTu;
4650 if (DstReg == SrcReg) {
4651 unsigned ATReg = getATReg(Inst.
getLoc());
4657 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister,
isInt<32>(ImmValue),
4658 false, IDLoc, Out, STI))
4662 TOut.
emitRRR(OpCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4681 warnIfNoMacro(IDLoc);
4688 OpCode = Mips::SLTu;
4695 TOut.
emitRRR(OpCode, DstReg, OpReg, SrcReg, IDLoc, STI);
4696 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4715 warnIfNoMacro(IDLoc);
4719 case Mips::SLEImm64:
4720 OpRegCode = Mips::SLT;
4723 case Mips::SLEUImm64:
4724 OpRegCode = Mips::SLTu;
4731 unsigned ImmReg = DstReg;
4732 if (DstReg == SrcReg) {
4733 unsigned ATReg = getATReg(Inst.
getLoc());
4739 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister,
isInt<32>(ImmValue),
4740 false, IDLoc, Out, STI))
4743 TOut.
emitRRR(OpRegCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4744 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4749 bool MipsAsmParser::expandAliasImmediate(
MCInst &Inst,
SMLoc IDLoc,
4759 unsigned ATReg = Mips::NoRegister;
4760 unsigned FinalDstReg = Mips::NoRegister;
4767 unsigned FinalOpcode = Inst.
getOpcode();
4769 if (DstReg == SrcReg) {
4770 ATReg = getATReg(Inst.
getLoc());
4773 FinalDstReg = DstReg;
4777 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit,
false,
4778 Inst.
getLoc(), Out, STI)) {
4779 switch (FinalOpcode) {
4786 FinalOpcode = Mips::ADDu;
4792 FinalOpcode = Mips::NOR;
4798 FinalOpcode = Mips::SLT;
4801 FinalOpcode = Mips::SLTu;
4807 FinalOpcode = Mips::ADD_MM;
4809 case Mips::ADDiu_MM:
4810 FinalOpcode = Mips::ADDu_MM;
4813 FinalOpcode = Mips::AND_MM;
4816 FinalOpcode = Mips::OR_MM;
4819 FinalOpcode = Mips::SLT_MM;
4821 case Mips::SLTiu_MM:
4822 FinalOpcode = Mips::SLTu_MM;
4825 FinalOpcode = Mips::XOR_MM;
4828 FinalOpcode = Mips::AND64;
4830 case Mips::NORImm64:
4831 FinalOpcode = Mips::NOR64;
4834 FinalOpcode = Mips::OR64;
4836 case Mips::SLTImm64:
4837 FinalOpcode = Mips::SLT64;
4839 case Mips::SLTUImm64:
4840 FinalOpcode = Mips::SLTu64;
4843 FinalOpcode = Mips::XOR64;
4847 if (FinalDstReg == Mips::NoRegister)
4848 TOut.
emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4850 TOut.
emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4859 unsigned ATReg = Mips::NoRegister;
4863 unsigned TmpReg =
DReg;
4865 unsigned FirstShift = Mips::NOP;
4866 unsigned SecondShift = Mips::NOP;
4868 if (hasMips32r2()) {
4870 TmpReg = getATReg(Inst.
getLoc());
4876 TOut.
emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4894 FirstShift = Mips::SRLV;
4895 SecondShift = Mips::SLLV;
4898 FirstShift = Mips::SLLV;
4899 SecondShift = Mips::SRLV;
4903 ATReg = getATReg(Inst.
getLoc());
4907 TOut.
emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4908 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
4918 bool MipsAsmParser::expandRotationImm(
MCInst &Inst,
SMLoc IDLoc,
4922 unsigned ATReg = Mips::NoRegister;
4927 unsigned FirstShift = Mips::NOP;
4928 unsigned SecondShift = Mips::NOP;
4930 if (hasMips32r2()) {
4935 ShiftValue = MaxShift - ImmValue;
4949 if (ImmValue == 0) {
4958 FirstShift = Mips::SLL;
4963 SecondShift = Mips::SLL;
4967 ATReg = getATReg(Inst.
getLoc());
4971 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.
getLoc(), STI);
4984 unsigned ATReg = Mips::NoRegister;
4988 unsigned TmpReg =
DReg;
4990 unsigned FirstShift = Mips::NOP;
4991 unsigned SecondShift = Mips::NOP;
4993 if (hasMips64r2()) {
4994 if (TmpReg == SReg) {
4995 TmpReg = getATReg(Inst.
getLoc());
5001 TOut.
emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
5019 FirstShift = Mips::DSRLV;
5020 SecondShift = Mips::DSLLV;
5023 FirstShift = Mips::DSLLV;
5024 SecondShift = Mips::DSRLV;
5028 ATReg = getATReg(Inst.
getLoc());
5032 TOut.
emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
5033 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
5043 bool MipsAsmParser::expandDRotationImm(
MCInst &Inst,
SMLoc IDLoc,
5047 unsigned ATReg = Mips::NoRegister;
5052 unsigned FirstShift = Mips::NOP;
5053 unsigned SecondShift = Mips::NOP;
5057 if (hasMips64r2()) {
5058 unsigned FinalOpcode = Mips::NOP;
5060 FinalOpcode = Mips::DROTR;
5061 else if (ImmValue % 32 == 0)
5062 FinalOpcode = Mips::DROTR32;
5063 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
5065 FinalOpcode = Mips::DROTR32;
5067 FinalOpcode = Mips::DROTR;
5068 }
else if (ImmValue >= 33) {
5070 FinalOpcode = Mips::DROTR;
5072 FinalOpcode = Mips::DROTR32;
5075 uint64_t ShiftValue = ImmValue % 32;
5077 ShiftValue = (32 - ImmValue % 32) % 32;
5085 if (ImmValue == 0) {
5094 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5095 FirstShift = Mips::DSLL;
5096 SecondShift = Mips::DSRL32;
5098 if (ImmValue == 32) {
5099 FirstShift = Mips::DSLL32;
5100 SecondShift = Mips::DSRL32;
5102 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5103 FirstShift = Mips::DSLL32;
5104 SecondShift = Mips::DSRL;
5108 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5109 FirstShift = Mips::DSRL;
5110 SecondShift = Mips::DSLL32;
5112 if (ImmValue == 32) {
5113 FirstShift = Mips::DSRL32;
5114 SecondShift = Mips::DSLL32;
5116 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5117 FirstShift = Mips::DSRL32;
5118 SecondShift = Mips::DSLL;
5123 ATReg = getATReg(Inst.
getLoc());
5127 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.
getLoc(), STI);
5128 TOut.
emitRRI(SecondShift,
DReg, SReg, (32 - ImmValue % 32) % 32,
5144 TOut.
emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
5145 if (FirstRegOp != SecondRegOp)
5146 TOut.
emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
5157 unsigned ATReg = Mips::NoRegister;
5162 ATReg = getATReg(IDLoc);
5166 loadImmediate(ImmValue, ATReg, Mips::NoRegister,
true,
false, IDLoc, Out,
5170 SrcReg, ATReg, IDLoc, STI);
5180 unsigned ATReg = Mips::NoRegister;
5185 ATReg = getATReg(Inst.
getLoc());
5190 SrcReg, TmpReg, IDLoc, STI);
5195 DstReg, DstReg, 0x1F, IDLoc, STI);
5200 TOut.
emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
5207 TOut.
emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
5208 if (AssemblerOptions.back()->isReorder())
5210 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5222 unsigned ATReg = Mips::NoRegister;
5227 ATReg = getATReg(IDLoc);
5231 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
5232 SrcReg, TmpReg, IDLoc, STI);
5237 TOut.
emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);
5244 TOut.
emitRRX(Mips::BEQ, ATReg, Mips::ZERO, LabelOp, IDLoc, STI);
5245 if (AssemblerOptions.back()->isReorder())
5247 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5262 TOut.
emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
5273 bool MipsAsmParser::expandLoadStoreDMacro(
MCInst &Inst,
SMLoc IDLoc,
5280 warnIfNoMacro(IDLoc);
5283 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
5285 unsigned SecondReg =
nextReg(FirstReg);
5290 warnIfRegIndexIsAT(FirstReg, IDLoc);
5293 "Offset for load macro is not immediate!");
5296 signed NextOffset = FirstOffset.
getImm() + 4;
5304 if (FirstReg != BaseReg || !IsLoad) {
5305 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5306 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5308 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5309 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5321 bool MipsAsmParser::expandStoreDM1Macro(
MCInst &Inst,
SMLoc IDLoc,
5327 warnIfNoMacro(IDLoc);
5330 unsigned Opcode = Mips::SWC1;
5332 unsigned SecondReg =
nextReg(FirstReg);
5337 warnIfRegIndexIsAT(FirstReg, IDLoc);
5340 "Offset for macro is not immediate!");
5343 signed NextOffset = FirstOffset.
getImm() + 4;
5349 if (!IsLittleEndian)
5352 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5353 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5371 warnIfNoMacro(IDLoc);
5373 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5375 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5379 unsigned Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5380 TOut.
emitRRI(Mips::SLTiu, DstReg,
Reg, 1, IDLoc, STI);
5397 warnIfNoMacro(IDLoc);
5400 TOut.
emitRRI(Mips::SLTiu, DstReg, SrcReg, 1, IDLoc, STI);
5404 if (SrcReg == Mips::ZERO) {
5405 Warning(IDLoc,
"comparison is always false");
5406 TOut.
emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
5407 DstReg, SrcReg, SrcReg, IDLoc, STI);
5412 if (
Imm > -0x8000 &&
Imm < 0) {
5414 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5420 unsigned ATReg = getATReg(IDLoc);
5424 if (loadImmediate(
Imm, ATReg, Mips::NoRegister,
true, isGP64bit(), IDLoc,
5429 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5433 TOut.
emitRRI(Opc, DstReg, SrcReg,
Imm, IDLoc, STI);
5434 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5452 warnIfNoMacro(IDLoc);
5454 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5456 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5460 unsigned Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5461 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO,
Reg, IDLoc, STI);
5478 warnIfNoMacro(IDLoc);
5480 if (ImmValue == 0) {
5481 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, SrcReg, IDLoc, STI);
5485 if (SrcReg == Mips::ZERO) {
5486 Warning(IDLoc,
"comparison is always true");
5487 if (loadImmediate(1, DstReg, Mips::NoRegister,
true,
false, IDLoc, Out,