62#define DEBUG_TYPE "mips-asm-parser"
74class MipsAssemblerOptions {
76 MipsAssemblerOptions(
const FeatureBitset &Features_) : Features(Features_) {}
78 MipsAssemblerOptions(
const MipsAssemblerOptions *Opts) {
79 ATReg = Opts->getATRegIndex();
80 Reorder = Opts->isReorder();
81 Macro = Opts->isMacro();
82 Features = Opts->getFeatures();
85 unsigned getATRegIndex()
const {
return ATReg; }
86 bool setATRegIndex(
unsigned Reg) {
94 bool isReorder()
const {
return Reorder; }
95 void setReorder() { Reorder =
true; }
96 void setNoReorder() { Reorder =
false; }
98 bool isMacro()
const {
return Macro; }
99 void setMacro() {
Macro =
true; }
100 void setNoMacro() {
Macro =
false; }
103 void setFeatures(
const FeatureBitset &Features_) { Features = Features_; }
121const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
122 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
123 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
124 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
125 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
126 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
127 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
128 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
129 Mips::FeatureCnMipsP, Mips::FeatureFP64Bit, Mips::FeatureGP64Bit,
138 "do not have a target streamer");
152 bool CurForbiddenSlotAttr;
155 unsigned CpSaveLocation;
157 bool CpSaveLocationIsRegister;
163 void printWarningWithFixIt(
const Twine &Msg,
const Twine &FixMsg,
168#define GET_ASSEMBLER_HEADER
169#include "MipsGenAsmMatcher.inc"
179 bool MatchingInlineAsm)
override;
184 SMLoc &EndLoc)
override;
190 bool mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID);
213 enum MacroExpanderResultTy {
220 MacroExpanderResultTy tryExpandInstruction(
MCInst &Inst,
SMLoc IDLoc,
227 bool loadImmediate(int64_t ImmValue,
unsigned DstReg,
unsigned SrcReg,
228 bool Is32BitImm,
bool IsAddress,
SMLoc IDLoc,
231 bool loadAndAddSymbolAddress(
const MCExpr *SymExpr,
unsigned DstReg,
232 unsigned SrcReg,
bool Is32BitSym,
SMLoc IDLoc,
237 bool expandLoadImm(
MCInst &Inst,
bool Is32BitImm,
SMLoc IDLoc,
246 bool expandLoadDoubleImmToFPR(
MCInst &Inst,
bool Is64FPU,
SMLoc IDLoc,
249 bool expandLoadAddress(
unsigned DstReg,
unsigned BaseReg,
278 bool expandTrunc(
MCInst &Inst,
bool IsDouble,
bool Is64FPU,
SMLoc IDLoc,
353 bool reportParseError(
const Twine &ErrorMsg);
354 bool reportParseError(
SMLoc Loc,
const Twine &ErrorMsg);
356 bool parseMemOffset(
const MCExpr *&Res,
bool isParenExpr);
358 bool parseSetMips0Directive();
359 bool parseSetArchDirective();
360 bool parseSetFeature(
uint64_t Feature);
361 bool isPicAndNotNxxAbi();
362 bool parseDirectiveCpAdd(
SMLoc Loc);
363 bool parseDirectiveCpLoad(
SMLoc Loc);
364 bool parseDirectiveCpLocal(
SMLoc Loc);
365 bool parseDirectiveCpRestore(
SMLoc Loc);
366 bool parseDirectiveCPSetup();
367 bool parseDirectiveCPReturn();
368 bool parseDirectiveNaN();
369 bool parseDirectiveSet();
370 bool parseDirectiveOption();
371 bool parseInsnDirective();
372 bool parseRSectionDirective(
StringRef Section);
373 bool parseSSectionDirective(
StringRef Section,
unsigned Type);
375 bool parseSetAtDirective();
376 bool parseSetNoAtDirective();
377 bool parseSetMacroDirective();
378 bool parseSetNoMacroDirective();
379 bool parseSetMsaDirective();
380 bool parseSetNoMsaDirective();
381 bool parseSetNoDspDirective();
382 bool parseSetNoMips3DDirective();
383 bool parseSetReorderDirective();
384 bool parseSetNoReorderDirective();
385 bool parseSetMips16Directive();
386 bool parseSetNoMips16Directive();
387 bool parseSetFpDirective();
388 bool parseSetOddSPRegDirective();
389 bool parseSetNoOddSPRegDirective();
390 bool parseSetPopDirective();
391 bool parseSetPushDirective();
392 bool parseSetSoftFloatDirective();
393 bool parseSetHardFloatDirective();
394 bool parseSetMtDirective();
395 bool parseSetNoMtDirective();
396 bool parseSetNoCRCDirective();
397 bool parseSetNoVirtDirective();
398 bool parseSetNoGINVDirective();
400 bool parseSetAssignment();
402 bool parseDirectiveGpWord();
403 bool parseDirectiveGpDWord();
404 bool parseDirectiveDtpRelWord();
405 bool parseDirectiveDtpRelDWord();
406 bool parseDirectiveTpRelWord();
407 bool parseDirectiveTpRelDWord();
408 bool parseDirectiveModule();
409 bool parseDirectiveModuleFP();
413 bool parseInternalDirectiveReallowModule();
417 int matchCPURegisterName(
StringRef Symbol);
419 int matchHWRegsRegisterName(
StringRef Symbol);
431 unsigned getReg(
int RC,
int RegNo);
436 unsigned getATReg(
SMLoc Loc);
446 bool validateMSAIndex(
int Val,
int RegKind);
473 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
481 if (!(
getSTI().hasFeature(Feature))) {
490 if (
getSTI().hasFeature(Feature)) {
499 setFeatureBits(Feature, FeatureString);
500 AssemblerOptions.
front()->setFeatures(
getSTI().getFeatureBits());
504 clearFeatureBits(Feature, FeatureString);
505 AssemblerOptions.
front()->setFeatures(
getSTI().getFeatureBits());
509 enum MipsMatchResultTy {
511 Match_RequiresDifferentOperands,
512 Match_RequiresNoZeroRegister,
513 Match_RequiresSameSrcAndDst,
514 Match_NoFCCRegisterForCurrentISA,
515 Match_NonZeroOperandForSync,
516 Match_NonZeroOperandForMTCX,
517 Match_RequiresPosSizeRange0_32,
518 Match_RequiresPosSizeRange33_64,
519 Match_RequiresPosSizeUImm6,
520#define GET_OPERAND_DIAGNOSTIC_TYPES
521#include "MipsGenAsmMatcher.inc"
522#undef GET_OPERAND_DIAGNOSTIC_TYPES
542 std::make_unique<MipsAssemblerOptions>(
getSTI().getFeatureBits()));
546 std::make_unique<MipsAssemblerOptions>(
getSTI().getFeatureBits()));
548 getTargetStreamer().updateABIInfo(*
this);
550 if (!isABI_O32() && !useOddSPReg() != 0)
555 CurForbiddenSlotAttr =
false;
558 IsCpRestoreSet =
false;
559 CpRestoreOffset = -1;
560 GPReg =
ABI.GetGlobalPtr();
565 if (
getSTI().
getCPU() ==
"mips64r6" && inMicroMipsMode())
568 if (!isABI_O32() && inMicroMipsMode())
573 bool hasEightFccRegisters()
const {
return hasMips4() || hasMips32(); }
575 bool isGP64bit()
const {
579 bool isFP64bit()
const {
583 bool isJalrRelocAvailable(
const MCExpr *JalExpr) {
592 return ABI.IsN32() ||
ABI.IsN64();
597 bool isABI_N32()
const {
return ABI.IsN32(); }
598 bool isABI_N64()
const {
return ABI.IsN64(); }
599 bool isABI_O32()
const {
return ABI.IsO32(); }
600 bool isABI_FPXX()
const {
604 bool useOddSPReg()
const {
608 bool inMicroMipsMode()
const {
612 bool hasMips1()
const {
616 bool hasMips2()
const {
620 bool hasMips3()
const {
624 bool hasMips4()
const {
628 bool hasMips5()
const {
632 bool hasMips32()
const {
636 bool hasMips64()
const {
640 bool hasMips32r2()
const {
644 bool hasMips64r2()
const {
648 bool hasMips32r3()
const {
649 return (
getSTI().hasFeature(Mips::FeatureMips32r3));
652 bool hasMips64r3()
const {
653 return (
getSTI().hasFeature(Mips::FeatureMips64r3));
656 bool hasMips32r5()
const {
657 return (
getSTI().hasFeature(Mips::FeatureMips32r5));
660 bool hasMips64r5()
const {
661 return (
getSTI().hasFeature(Mips::FeatureMips64r5));
664 bool hasMips32r6()
const {
668 bool hasMips64r6()
const {
672 bool hasDSP()
const {
676 bool hasDSPR2()
const {
680 bool hasDSPR3()
const {
684 bool hasMSA()
const {
688 bool hasCnMips()
const {
689 return (
getSTI().hasFeature(Mips::FeatureCnMips));
692 bool hasCnMipsP()
const {
693 return (
getSTI().hasFeature(Mips::FeatureCnMipsP));
700 bool inMips16Mode()
const {
704 bool useTraps()
const {
708 bool useSoftFloat()
const {
715 bool hasCRC()
const {
719 bool hasVirt()
const {
723 bool hasGINV()
const {
727 bool hasForbiddenSlot(
const MCInstrDesc &MCID)
const {
731 bool SafeInForbiddenSlot(
const MCInstrDesc &MCID)
const {
738 void warnIfRegIndexIsAT(
unsigned RegIndex,
SMLoc Loc);
740 void warnIfNoMacro(
SMLoc Loc);
742 bool isLittle()
const {
return IsLittleEndian; }
747 switch(OperatorToken) {
818 RegKind_MSACtrl = 16,
823 RegKind_HWRegs = 256,
827 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
828 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
829 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
842 MipsOperand(KindTy K, MipsAsmParser &Parser) :
Kind(
K), AsmParser(Parser) {}
844 ~MipsOperand()
override {
853 case k_RegisterIndex:
861 MipsAsmParser &AsmParser;
890 struct RegIdxOp RegIdx;
893 struct RegListOp RegList;
896 SMLoc StartLoc, EndLoc;
899 static std::unique_ptr<MipsOperand> CreateReg(
unsigned Index,
StringRef Str,
903 MipsAsmParser &Parser) {
904 auto Op = std::make_unique<MipsOperand>(k_RegisterIndex, Parser);
907 Op->RegIdx.Kind = RegKind;
908 Op->RegIdx.Tok.Data = Str.data();
909 Op->RegIdx.Tok.Length = Str.size();
918 unsigned getGPR32Reg()
const {
919 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
920 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
921 unsigned ClassID = Mips::GPR32RegClassID;
922 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
927 unsigned getGPRMM16Reg()
const {
928 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
929 unsigned ClassID = Mips::GPR32RegClassID;
930 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
935 unsigned getGPR64Reg()
const {
936 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
937 unsigned ClassID = Mips::GPR64RegClassID;
938 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
944 unsigned getAFGR64Reg()
const {
945 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
946 if (RegIdx.Index % 2 != 0)
947 AsmParser.Warning(StartLoc,
"Float register should be even.");
948 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
949 .getRegister(RegIdx.Index / 2);
954 unsigned getFGR64Reg()
const {
955 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
956 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
957 .getRegister(RegIdx.Index);
962 unsigned getFGR32Reg()
const {
963 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
964 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
965 .getRegister(RegIdx.Index);
970 unsigned getFCCReg()
const {
971 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) &&
"Invalid access!");
972 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
973 .getRegister(RegIdx.Index);
978 unsigned getMSA128Reg()
const {
979 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) &&
"Invalid access!");
982 unsigned ClassID = Mips::MSA128BRegClassID;
983 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
988 unsigned getMSACtrlReg()
const {
989 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) &&
"Invalid access!");
990 unsigned ClassID = Mips::MSACtrlRegClassID;
991 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
996 unsigned getCOP0Reg()
const {
997 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) &&
"Invalid access!");
998 unsigned ClassID = Mips::COP0RegClassID;
999 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1004 unsigned getCOP2Reg()
const {
1005 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) &&
"Invalid access!");
1006 unsigned ClassID = Mips::COP2RegClassID;
1007 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1012 unsigned getCOP3Reg()
const {
1013 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) &&
"Invalid access!");
1014 unsigned ClassID = Mips::COP3RegClassID;
1015 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1020 unsigned getACC64DSPReg()
const {
1021 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
1022 unsigned ClassID = Mips::ACC64DSPRegClassID;
1023 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1028 unsigned getHI32DSPReg()
const {
1029 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
1030 unsigned ClassID = Mips::HI32DSPRegClassID;
1031 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1036 unsigned getLO32DSPReg()
const {
1037 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
1038 unsigned ClassID = Mips::LO32DSPRegClassID;
1039 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1044 unsigned getCCRReg()
const {
1045 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) &&
"Invalid access!");
1046 unsigned ClassID = Mips::CCRRegClassID;
1047 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1052 unsigned getHWRegsReg()
const {
1053 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) &&
"Invalid access!");
1054 unsigned ClassID = Mips::HWRegsRegClassID;
1055 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1063 else if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
1069 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
1076 void addGPR32ZeroAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1077 assert(
N == 1 &&
"Invalid number of operands!");
1081 void addGPR32NonZeroAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1082 assert(
N == 1 &&
"Invalid number of operands!");
1086 void addGPR32AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1087 assert(
N == 1 &&
"Invalid number of operands!");
1091 void addGPRMM16AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1092 assert(
N == 1 &&
"Invalid number of operands!");
1096 void addGPRMM16AsmRegZeroOperands(
MCInst &Inst,
unsigned N)
const {
1097 assert(
N == 1 &&
"Invalid number of operands!");
1101 void addGPRMM16AsmRegMovePOperands(
MCInst &Inst,
unsigned N)
const {
1102 assert(
N == 1 &&
"Invalid number of operands!");
1106 void addGPRMM16AsmRegMovePPairFirstOperands(
MCInst &Inst,
unsigned N)
const {
1107 assert(
N == 1 &&
"Invalid number of operands!");
1111 void addGPRMM16AsmRegMovePPairSecondOperands(
MCInst &Inst,
1113 assert(
N == 1 &&
"Invalid number of operands!");
1120 void addGPR64AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1121 assert(
N == 1 &&
"Invalid number of operands!");
1125 void addAFGR64AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1126 assert(
N == 1 &&
"Invalid number of operands!");
1130 void addStrictlyAFGR64AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1131 assert(
N == 1 &&
"Invalid number of operands!");
1135 void addStrictlyFGR64AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1136 assert(
N == 1 &&
"Invalid number of operands!");
1140 void addFGR64AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1141 assert(
N == 1 &&
"Invalid number of operands!");
1145 void addFGR32AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1146 assert(
N == 1 &&
"Invalid number of operands!");
1150 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1151 AsmParser.getParser().printError(
1152 StartLoc,
"-mno-odd-spreg prohibits the use of odd FPU "
1156 void addStrictlyFGR32AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1157 assert(
N == 1 &&
"Invalid number of operands!");
1160 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1161 AsmParser.Error(StartLoc,
"-mno-odd-spreg prohibits the use of odd FPU "
1165 void addFCCAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1166 assert(
N == 1 &&
"Invalid number of operands!");
1170 void addMSA128AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1171 assert(
N == 1 &&
"Invalid number of operands!");
1175 void addMSACtrlAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1176 assert(
N == 1 &&
"Invalid number of operands!");
1180 void addCOP0AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1181 assert(
N == 1 &&
"Invalid number of operands!");
1185 void addCOP2AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1186 assert(
N == 1 &&
"Invalid number of operands!");
1190 void addCOP3AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1191 assert(
N == 1 &&
"Invalid number of operands!");
1195 void addACC64DSPAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1196 assert(
N == 1 &&
"Invalid number of operands!");
1200 void addHI32DSPAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1201 assert(
N == 1 &&
"Invalid number of operands!");
1205 void addLO32DSPAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1206 assert(
N == 1 &&
"Invalid number of operands!");
1210 void addCCRAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1211 assert(
N == 1 &&
"Invalid number of operands!");
1215 void addHWRegsAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1216 assert(
N == 1 &&
"Invalid number of operands!");
1220 template <
unsigned Bits,
int Offset = 0,
int AdjustOffset = 0>
1221 void addConstantUImmOperands(
MCInst &Inst,
unsigned N)
const {
1222 assert(
N == 1 &&
"Invalid number of operands!");
1226 Imm += AdjustOffset;
1230 template <
unsigned Bits>
1231 void addSImmOperands(
MCInst &Inst,
unsigned N)
const {
1232 if (
isImm() && !isConstantImm()) {
1233 addExpr(Inst, getImm());
1236 addConstantSImmOperands<Bits, 0, 0>(Inst,
N);
1239 template <
unsigned Bits>
1240 void addUImmOperands(
MCInst &Inst,
unsigned N)
const {
1241 if (
isImm() && !isConstantImm()) {
1242 addExpr(Inst, getImm());
1245 addConstantUImmOperands<Bits, 0, 0>(Inst,
N);
1248 template <
unsigned Bits,
int Offset = 0,
int AdjustOffset = 0>
1249 void addConstantSImmOperands(
MCInst &Inst,
unsigned N)
const {
1250 assert(
N == 1 &&
"Invalid number of operands!");
1251 int64_t
Imm = getConstantImm() -
Offset;
1252 Imm = SignExtend64<Bits>(Imm);
1254 Imm += AdjustOffset;
1258 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
1259 assert(
N == 1 &&
"Invalid number of operands!");
1260 const MCExpr *Expr = getImm();
1261 addExpr(Inst, Expr);
1264 void addMemOperands(
MCInst &Inst,
unsigned N)
const {
1265 assert(
N == 2 &&
"Invalid number of operands!");
1268 ? getMemBase()->getGPR64Reg()
1269 : getMemBase()->getGPR32Reg()));
1271 const MCExpr *Expr = getMemOff();
1272 addExpr(Inst, Expr);
1275 void addMicroMipsMemOperands(
MCInst &Inst,
unsigned N)
const {
1276 assert(
N == 2 &&
"Invalid number of operands!");
1280 const MCExpr *Expr = getMemOff();
1281 addExpr(Inst, Expr);
1284 void addRegListOperands(
MCInst &Inst,
unsigned N)
const {
1285 assert(
N == 1 &&
"Invalid number of operands!");
1287 for (
auto RegNo : getRegList())
1291 bool isReg()
const override {
1294 return isGPRAsmReg() && RegIdx.Index == 0;
1297 bool isRegIdx()
const {
return Kind == k_RegisterIndex; }
1298 bool isImm()
const override {
return Kind == k_Immediate; }
1300 bool isConstantImm()
const {
1302 return isImm() && getImm()->evaluateAsAbsolute(Res);
1305 bool isConstantImmz()
const {
1306 return isConstantImm() && getConstantImm() == 0;
1309 template <
unsigned Bits,
int Offset = 0>
bool isConstantUImm()
const {
1310 return isConstantImm() && isUInt<Bits>(getConstantImm() -
Offset);
1313 template <
unsigned Bits>
bool isSImm()
const {
1314 return isConstantImm() ? isInt<Bits>(getConstantImm()) :
isImm();
1317 template <
unsigned Bits>
bool isUImm()
const {
1318 return isConstantImm() ? isUInt<Bits>(getConstantImm()) :
isImm();
1321 template <
unsigned Bits>
bool isAnyImm()
const {
1322 return isConstantImm() ? (isInt<Bits>(getConstantImm()) ||
1323 isUInt<Bits>(getConstantImm()))
1327 template <
unsigned Bits,
int Offset = 0>
bool isConstantSImm()
const {
1328 return isConstantImm() && isInt<Bits>(getConstantImm() -
Offset);
1331 template <
unsigned Bottom,
unsigned Top>
bool isConstantUImmRange()
const {
1332 return isConstantImm() && getConstantImm() >= Bottom &&
1333 getConstantImm() <= Top;
1336 bool isToken()
const override {
1339 return Kind == k_Token;
1342 bool isMem()
const override {
return Kind == k_Memory; }
1344 bool isConstantMemOff()
const {
1345 return isMem() && isa<MCConstantExpr>(getMemOff());
1349 template <
unsigned Bits,
unsigned ShiftAmount = 0>
1350 bool isMemWithSimmOffset()
const {
1353 if (!getMemBase()->isGPRAsmReg())
1355 if (isa<MCTargetExpr>(getMemOff()) ||
1356 (isConstantMemOff() &&
1357 isShiftedInt<Bits, ShiftAmount>(getConstantMemOff())))
1360 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res,
nullptr,
nullptr);
1361 return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.
getConstant());
1364 bool isMemWithPtrSizeOffset()
const {
1367 if (!getMemBase()->isGPRAsmReg())
1369 const unsigned PtrBits = AsmParser.getABI().ArePtrs64bit() ? 64 : 32;
1370 if (isa<MCTargetExpr>(getMemOff()) ||
1371 (isConstantMemOff() &&
isIntN(PtrBits, getConstantMemOff())))
1374 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res,
nullptr,
nullptr);
1378 bool isMemWithGRPMM16Base()
const {
1379 return isMem() && getMemBase()->isMM16AsmReg();
1382 template <
unsigned Bits>
bool isMemWithUimmOffsetSP()
const {
1383 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1384 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1387 template <
unsigned Bits>
bool isMemWithUimmWordAlignedOffsetSP()
const {
1388 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1389 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1390 && (getMemBase()->getGPR32Reg() == Mips::SP);
1393 template <
unsigned Bits>
bool isMemWithSimmWordAlignedOffsetGP()
const {
1394 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
1395 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1396 && (getMemBase()->getGPR32Reg() == Mips::GP);
1399 template <
unsigned Bits,
unsigned ShiftLeftAmount>
1400 bool isScaledUImm()
const {
1401 return isConstantImm() &&
1402 isShiftedUInt<Bits, ShiftLeftAmount>(getConstantImm());
1405 template <
unsigned Bits,
unsigned ShiftLeftAmount>
1406 bool isScaledSImm()
const {
1407 if (isConstantImm() &&
1408 isShiftedInt<Bits, ShiftLeftAmount>(getConstantImm()))
1412 if (Kind != k_Immediate)
1415 bool Success = getImm()->evaluateAsRelocatable(Res,
nullptr,
nullptr);
1419 bool isRegList16()
const {
1423 int Size = RegList.List->size();
1424 if (Size < 2 || Size > 5)
1427 unsigned R0 = RegList.List->front();
1428 unsigned R1 = RegList.List->back();
1429 if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1430 (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1433 int PrevReg = *RegList.List->begin();
1434 for (
int i = 1; i <
Size - 1; i++) {
1435 int Reg = (*(RegList.List))[i];
1436 if (
Reg != PrevReg + 1)
1444 bool isInvNum()
const {
return Kind == k_Immediate; }
1446 bool isLSAImm()
const {
1447 if (!isConstantImm())
1449 int64_t Val = getConstantImm();
1450 return 1 <= Val && Val <= 4;
1453 bool isRegList()
const {
return Kind == k_RegList; }
1456 assert(Kind == k_Token &&
"Invalid access!");
1463 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1464 RegIdx.Kind & RegKind_GPR)
1465 return getGPR32Reg();
1471 const MCExpr *getImm()
const {
1472 assert((Kind == k_Immediate) &&
"Invalid access!");
1476 int64_t getConstantImm()
const {
1477 const MCExpr *Val = getImm();
1479 (void)Val->evaluateAsAbsolute(
Value);
1483 MipsOperand *getMemBase()
const {
1484 assert((Kind == k_Memory) &&
"Invalid access!");
1488 const MCExpr *getMemOff()
const {
1489 assert((Kind == k_Memory) &&
"Invalid access!");
1493 int64_t getConstantMemOff()
const {
1494 return static_cast<const MCConstantExpr *
>(getMemOff())->getValue();
1498 assert((Kind == k_RegList) &&
"Invalid access!");
1499 return *(RegList.List);
1502 static std::unique_ptr<MipsOperand> CreateToken(
StringRef Str,
SMLoc S,
1503 MipsAsmParser &Parser) {
1504 auto Op = std::make_unique<MipsOperand>(k_Token, Parser);
1505 Op->Tok.Data = Str.data();
1506 Op->Tok.Length = Str.size();
1514 static std::unique_ptr<MipsOperand>
1518 return CreateReg(
Index, Str, RegKind_Numeric,
RegInfo, S,
E, Parser);
1523 static std::unique_ptr<MipsOperand>
1526 return CreateReg(
Index, Str, RegKind_GPR,
RegInfo, S,
E, Parser);
1531 static std::unique_ptr<MipsOperand>
1534 return CreateReg(
Index, Str, RegKind_FGR,
RegInfo, S,
E, Parser);
1539 static std::unique_ptr<MipsOperand>
1542 return CreateReg(
Index, Str, RegKind_HWRegs,
RegInfo, S,
E, Parser);
1547 static std::unique_ptr<MipsOperand>
1550 return CreateReg(
Index, Str, RegKind_FCC,
RegInfo, S,
E, Parser);
1555 static std::unique_ptr<MipsOperand>
1558 return CreateReg(
Index, Str, RegKind_ACC,
RegInfo, S,
E, Parser);
1563 static std::unique_ptr<MipsOperand>
1566 return CreateReg(
Index, Str, RegKind_MSA128,
RegInfo, S,
E, Parser);
1571 static std::unique_ptr<MipsOperand>
1574 return CreateReg(
Index, Str, RegKind_MSACtrl,
RegInfo, S,
E, Parser);
1577 static std::unique_ptr<MipsOperand>
1579 auto Op = std::make_unique<MipsOperand>(k_Immediate, Parser);
1586 static std::unique_ptr<MipsOperand>
1587 CreateMem(std::unique_ptr<MipsOperand>
Base,
const MCExpr *Off,
SMLoc S,
1588 SMLoc E, MipsAsmParser &Parser) {
1589 auto Op = std::make_unique<MipsOperand>(k_Memory, Parser);
1590 Op->Mem.Base =
Base.release();
1597 static std::unique_ptr<MipsOperand>
1599 MipsAsmParser &Parser) {
1600 assert(Regs.
size() > 0 &&
"Empty list not allowed");
1602 auto Op = std::make_unique<MipsOperand>(k_RegList, Parser);
1604 Op->StartLoc = StartLoc;
1605 Op->EndLoc = EndLoc;
1609 bool isGPRZeroAsmReg()
const {
1610 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
1613 bool isGPRNonZeroAsmReg()
const {
1614 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index > 0 &&
1618 bool isGPRAsmReg()
const {
1619 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1622 bool isMM16AsmReg()
const {
1623 if (!(isRegIdx() && RegIdx.Kind))
1625 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1626 || RegIdx.Index == 16 || RegIdx.Index == 17);
1629 bool isMM16AsmRegZero()
const {
1630 if (!(isRegIdx() && RegIdx.Kind))
1632 return (RegIdx.Index == 0 ||
1633 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1634 RegIdx.Index == 17);
1637 bool isMM16AsmRegMoveP()
const {
1638 if (!(isRegIdx() && RegIdx.Kind))
1640 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1641 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1644 bool isMM16AsmRegMovePPairFirst()
const {
1645 if (!(isRegIdx() && RegIdx.Kind))
1647 return RegIdx.Index >= 4 && RegIdx.Index <= 6;
1650 bool isMM16AsmRegMovePPairSecond()
const {
1651 if (!(isRegIdx() && RegIdx.Kind))
1653 return (RegIdx.Index == 21 || RegIdx.Index == 22 ||
1654 (RegIdx.Index >= 5 && RegIdx.Index <= 7));
1657 bool isFGRAsmReg()
const {
1659 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1662 bool isStrictlyFGRAsmReg()
const {
1664 return isRegIdx() && RegIdx.Kind == RegKind_FGR && RegIdx.Index <= 31;
1667 bool isHWRegsAsmReg()
const {
1668 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1671 bool isCCRAsmReg()
const {
1672 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1675 bool isFCCAsmReg()
const {
1676 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1678 return RegIdx.Index <= 7;
1681 bool isACCAsmReg()
const {
1682 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1685 bool isCOP0AsmReg()
const {
1686 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1689 bool isCOP2AsmReg()
const {
1690 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1693 bool isCOP3AsmReg()
const {
1694 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1697 bool isMSA128AsmReg()
const {
1698 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1701 bool isMSACtrlAsmReg()
const {
1702 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1706 SMLoc getStartLoc()
const override {
return StartLoc; }
1708 SMLoc getEndLoc()
const override {
return EndLoc; }
1719 Mem.Base->print(
OS);
1724 case k_RegisterIndex:
1725 OS <<
"RegIdx<" << RegIdx.Index <<
":" << RegIdx.Kind <<
", "
1726 <<
StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) <<
">";
1733 for (
auto Reg : (*RegList.List))
1740 bool isValidForTie(
const MipsOperand &
Other)
const {
1741 if (Kind !=
Other.Kind)
1748 case k_RegisterIndex: {
1749 StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length);
1751 return Token == OtherToken;
1767 case Mips::JRC16_MM:
1769 case Mips::JALRS_MM:
1770 case Mips::JALRS16_MM:
1771 case Mips::BGEZALS_MM:
1772 case Mips::BLTZALS_MM:
1782 if (
const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1783 return &SRExpr->getSymbol();
1786 if (
const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1799 if (
const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1806 if (isa<MCSymbolRefExpr>(Expr))
1809 if (
const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1813 if (
const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1832 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1841 if (NumOp != 3 && NumOp != 4)
1853 return !isInt<9>(
Op.getImm());
1855 return !isInt<16>(
Op.getImm());
1871bool MipsAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
1875 const unsigned Opcode = Inst.
getOpcode();
1877 bool ExpandedJalSym =
false;
1891 assert(hasCnMips() &&
"instruction only valid for octeon cpus");
1902 if (!
isIntN(inMicroMipsMode() ? 17 : 18,
Offset.getImm()))
1903 return Error(IDLoc,
"branch target out of range");
1906 return Error(IDLoc,
"branch to misaligned address");
1920 case Mips::BGEZAL_MM:
1921 case Mips::BLTZAL_MM:
1924 case Mips::BC1EQZC_MMR6:
1925 case Mips::BC1NEZC_MMR6:
1926 case Mips::BC2EQZC_MMR6:
1927 case Mips::BC2NEZC_MMR6:
1932 if (!
isIntN(inMicroMipsMode() ? 17 : 18,
Offset.getImm()))
1933 return Error(IDLoc,
"branch target out of range");
1936 return Error(IDLoc,
"branch to misaligned address");
1938 case Mips::BGEC:
case Mips::BGEC_MMR6:
1939 case Mips::BLTC:
case Mips::BLTC_MMR6:
1940 case Mips::BGEUC:
case Mips::BGEUC_MMR6:
1941 case Mips::BLTUC:
case Mips::BLTUC_MMR6:
1942 case Mips::BEQC:
case Mips::BEQC_MMR6:
1943 case Mips::BNEC:
case Mips::BNEC_MMR6:
1949 return Error(IDLoc,
"branch target out of range");
1951 return Error(IDLoc,
"branch to misaligned address");
1953 case Mips::BLEZC:
case Mips::BLEZC_MMR6:
1954 case Mips::BGEZC:
case Mips::BGEZC_MMR6:
1955 case Mips::BGTZC:
case Mips::BGTZC_MMR6:
1956 case Mips::BLTZC:
case Mips::BLTZC_MMR6:
1962 return Error(IDLoc,
"branch target out of range");
1964 return Error(IDLoc,
"branch to misaligned address");
1966 case Mips::BEQZC:
case Mips::BEQZC_MMR6:
1967 case Mips::BNEZC:
case Mips::BNEZC_MMR6:
1973 return Error(IDLoc,
"branch target out of range");
1975 return Error(IDLoc,
"branch to misaligned address");
1977 case Mips::BEQZ16_MM:
1978 case Mips::BEQZC16_MMR6:
1979 case Mips::BNEZ16_MM:
1980 case Mips::BNEZC16_MMR6:
1985 if (!isInt<8>(
Offset.getImm()))
1986 return Error(IDLoc,
"branch target out of range");
1988 return Error(IDLoc,
"branch to misaligned address");
1995 if (hasMips32r6() && Opcode == Mips::SSNOP) {
1996 std::string
ISA = hasMips64r6() ?
"MIPS64r6" :
"MIPS32r6";
1997 Warning(IDLoc,
"ssnop is deprecated for " + ISA +
" and is equivalent to a "
2017 return Error(IDLoc,
"expected immediate operand kind");
2019 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
2020 Opcode == Mips::BBIT1 ? 63 : 31))
2021 return Error(IDLoc,
"immediate operand value out of range");
2023 Inst.
setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
2034 return Error(IDLoc,
"expected immediate operand kind");
2036 if (!isInt<10>(Imm))
2037 return Error(IDLoc,
"immediate operand value out of range");
2049 unsigned FirstOp = 1;
2050 unsigned SecondOp = 2;
2054 case Mips::SDivIMacro:
2055 case Mips::UDivIMacro:
2056 case Mips::DSDivIMacro:
2057 case Mips::DUDivIMacro:
2061 Warning(IDLoc,
"dividing zero by zero");
2063 Warning(IDLoc,
"division by zero");
2075 case Mips::SDivMacro:
2076 case Mips::DSDivMacro:
2077 case Mips::UDivMacro:
2078 case Mips::DUDivMacro:
2083 case Mips::DIVU_MMR6:
2084 case Mips::DIV_MMR6:
2089 Warning(IDLoc,
"dividing zero by zero");
2091 Warning(IDLoc,
"division by zero");
2097 if ((Opcode == Mips::J || Opcode == Mips::J_MM) && inPicMode()) {
2099 BInst.
setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
2108 if ((Opcode == Mips::JAL || Opcode == Mips::JAL_MM) && inPicMode()) {
2109 warnIfNoMacro(IDLoc);
2112 return Error(IDLoc,
"unsupported constant in relocation");
2120 return Error(IDLoc,
"jal doesn't support multiple symbols in PIC mode");
2126 if (expandLoadAddress(Mips::T9, Mips::NoRegister, Inst.
getOperand(0),
2127 !isGP64bit(), IDLoc, Out, STI))
2131 if (inMicroMipsMode())
2132 JalrInst.
setOpcode(IsCpRestoreSet ? Mips::JALRS_MM : Mips::JALR_MM);
2138 if (isJalrRelocAvailable(JalExpr)) {
2142 MCSymbol *TmpLabel = getContext().createTempSymbol();
2144 const MCExpr *RelocJalrExpr =
2146 getContext(), IDLoc);
2149 *TmpExpr, inMicroMipsMode() ?
"R_MICROMIPS_JALR" :
"R_MIPS_JALR",
2150 RelocJalrExpr, IDLoc, *STI);
2155 ExpandedJalSym =
true;
2164 expandMem9Inst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2167 expandMem16Inst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2170 return getParser().hasPendingError();
2174 if (inMicroMipsMode()) {
2175 if (MCID.
mayLoad() && Opcode != Mips::LWP_MM) {
2183 int MemOffset =
Op.getImm();
2186 if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
2189 (BaseReg.
getReg() == Mips::GP ||
2190 BaseReg.
getReg() == Mips::GP_64)) {
2192 TOut.
emitRRI(Mips::LWGP_MM, DstReg.
getReg(), Mips::GP, MemOffset,
2209 case Mips::ADDIUSP_MM:
2212 return Error(IDLoc,
"expected immediate operand kind");
2214 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
2216 return Error(IDLoc,
"immediate operand value out of range");
2218 case Mips::SLL16_MM:
2219 case Mips::SRL16_MM:
2222 return Error(IDLoc,
"expected immediate operand kind");
2224 if (Imm < 1 || Imm > 8)
2225 return Error(IDLoc,
"immediate operand value out of range");
2230 return Error(IDLoc,
"expected immediate operand kind");
2232 if (Imm < -1 || Imm > 126)
2233 return Error(IDLoc,
"immediate operand value out of range");
2235 case Mips::ADDIUR2_MM:
2238 return Error(IDLoc,
"expected immediate operand kind");
2240 if (!(Imm == 1 || Imm == -1 ||
2241 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
2242 return Error(IDLoc,
"immediate operand value out of range");
2244 case Mips::ANDI16_MM:
2247 return Error(IDLoc,
"expected immediate operand kind");
2249 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
2250 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
2251 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
2252 return Error(IDLoc,
"immediate operand value out of range");
2254 case Mips::LBU16_MM:
2257 return Error(IDLoc,
"expected immediate operand kind");
2259 if (Imm < -1 || Imm > 14)
2260 return Error(IDLoc,
"immediate operand value out of range");
2263 case Mips::SB16_MMR6:
2266 return Error(IDLoc,
"expected immediate operand kind");
2268 if (Imm < 0 || Imm > 15)
2269 return Error(IDLoc,
"immediate operand value out of range");
2271 case Mips::LHU16_MM:
2273 case Mips::SH16_MMR6:
2276 return Error(IDLoc,
"expected immediate operand kind");
2278 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
2279 return Error(IDLoc,
"immediate operand value out of range");
2283 case Mips::SW16_MMR6:
2286 return Error(IDLoc,
"expected immediate operand kind");
2288 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
2289 return Error(IDLoc,
"immediate operand value out of range");
2291 case Mips::ADDIUPC_MM:
2294 return Error(IDLoc,
"expected immediate operand kind");
2296 if ((Imm % 4 != 0) || !isInt<25>(Imm))
2297 return Error(IDLoc,
"immediate operand value out of range");
2302 return Error(IDLoc,
"invalid operand for instruction");
2304 case Mips::MOVEP_MM:
2305 case Mips::MOVEP_MMR6: {
2308 bool RegPair = ((R0 == Mips::A1 && R1 == Mips::A2) ||
2309 (R0 == Mips::A1 && R1 == Mips::A3) ||
2310 (R0 == Mips::A2 && R1 == Mips::A3) ||
2311 (R0 == Mips::A0 && R1 == Mips::S5) ||
2312 (R0 == Mips::A0 && R1 == Mips::S6) ||
2313 (R0 == Mips::A0 && R1 == Mips::A1) ||
2314 (R0 == Mips::A0 && R1 == Mips::A2) ||
2315 (R0 == Mips::A0 && R1 == Mips::A3));
2317 return Error(IDLoc,
"invalid operand for instruction");
2323 bool FillDelaySlot =
2328 bool PrevForbiddenSlotAttr = CurForbiddenSlotAttr;
2331 bool SetReorderAfterNop =
false;
2336 if (PrevForbiddenSlotAttr && !SafeInForbiddenSlot(MCID)) {
2346 if (AssemblerOptions.
back()->isReorder() && !FillDelaySlot) {
2347 SetReorderAfterNop =
true;
2356 CurForbiddenSlotAttr =
2357 hasForbiddenSlot(MCID) && AssemblerOptions.
back()->isReorder();
2359 if (FillDelaySlot || CurForbiddenSlotAttr)
2362 MacroExpanderResultTy ExpandResult =
2363 tryExpandInstruction(Inst, IDLoc, Out, STI);
2364 switch (ExpandResult) {
2380 if (PrevForbiddenSlotAttr && !SetReorderAfterNop && !FillDelaySlot &&
2381 AssemblerOptions.
back()->isReorder()) {
2387 if (inMicroMipsMode()) {
2402 if (FillDelaySlot) {
2407 if ((Opcode == Mips::JalOneReg || Opcode == Mips::JalTwoReg ||
2409 isPicAndNotNxxAbi()) {
2410 if (IsCpRestoreSet) {
2414 if (!AssemblerOptions.
back()->isReorder())
2421 Warning(IDLoc,
"no .cprestore used in PIC mode");
2427void MipsAsmParser::onEndOfFile() {
2431 if (CurForbiddenSlotAttr) {
2433 if (AssemblerOptions.
back()->isReorder())
2438MipsAsmParser::MacroExpanderResultTy
2443 return MER_NotAMacro;
2444 case Mips::LoadImm32:
2445 return expandLoadImm(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2446 case Mips::LoadImm64:
2447 return expandLoadImm(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2448 case Mips::LoadAddrImm32:
2449 case Mips::LoadAddrImm64:
2452 "expected immediate operand kind");
2456 Inst.
getOpcode() == Mips::LoadAddrImm32, IDLoc,
2460 case Mips::LoadAddrReg32:
2461 case Mips::LoadAddrReg64:
2465 "expected immediate operand kind");
2469 Inst.
getOpcode() == Mips::LoadAddrReg32, IDLoc,
2473 case Mips::B_MM_Pseudo:
2474 case Mips::B_MMR6_Pseudo:
2475 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2479 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2481 case Mips::JalOneReg:
2482 case Mips::JalTwoReg:
2483 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2486 case Mips::BEQLImmMacro:
2487 case Mips::BNELImmMacro:
2488 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2505 case Mips::BLTImmMacro:
2506 case Mips::BLEImmMacro:
2507 case Mips::BGEImmMacro:
2508 case Mips::BGTImmMacro:
2509 case Mips::BLTUImmMacro:
2510 case Mips::BLEUImmMacro:
2511 case Mips::BGEUImmMacro:
2512 case Mips::BGTUImmMacro:
2513 case Mips::BLTLImmMacro:
2514 case Mips::BLELImmMacro:
2515 case Mips::BGELImmMacro:
2516 case Mips::BGTLImmMacro:
2517 case Mips::BLTULImmMacro:
2518 case Mips::BLEULImmMacro:
2519 case Mips::BGEULImmMacro:
2520 case Mips::BGTULImmMacro:
2521 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2522 case Mips::SDivMacro:
2523 case Mips::SDivIMacro:
2524 case Mips::SRemMacro:
2525 case Mips::SRemIMacro:
2526 return expandDivRem(Inst, IDLoc, Out, STI,
false,
true) ? MER_Fail
2528 case Mips::DSDivMacro:
2529 case Mips::DSDivIMacro:
2530 case Mips::DSRemMacro:
2531 case Mips::DSRemIMacro:
2532 return expandDivRem(Inst, IDLoc, Out, STI,
true,
true) ? MER_Fail
2534 case Mips::UDivMacro:
2535 case Mips::UDivIMacro:
2536 case Mips::URemMacro:
2537 case Mips::URemIMacro:
2538 return expandDivRem(Inst, IDLoc, Out, STI,
false,
false) ? MER_Fail
2540 case Mips::DUDivMacro:
2541 case Mips::DUDivIMacro:
2542 case Mips::DURemMacro:
2543 case Mips::DURemIMacro:
2544 return expandDivRem(Inst, IDLoc, Out, STI,
true,
false) ? MER_Fail
2546 case Mips::PseudoTRUNC_W_S:
2547 return expandTrunc(Inst,
false,
false, IDLoc, Out, STI) ? MER_Fail
2549 case Mips::PseudoTRUNC_W_D32:
2550 return expandTrunc(Inst,
true,
false, IDLoc, Out, STI) ? MER_Fail
2552 case Mips::PseudoTRUNC_W_D:
2553 return expandTrunc(Inst,
true,
true, IDLoc, Out, STI) ? MER_Fail
2556 case Mips::LoadImmSingleGPR:
2557 return expandLoadSingleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2559 case Mips::LoadImmSingleFGR:
2560 return expandLoadSingleImmToFPR(Inst, IDLoc, Out, STI) ? MER_Fail
2562 case Mips::LoadImmDoubleGPR:
2563 return expandLoadDoubleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2565 case Mips::LoadImmDoubleFGR:
2566 return expandLoadDoubleImmToFPR(Inst,
true, IDLoc, Out, STI) ? MER_Fail
2568 case Mips::LoadImmDoubleFGR_32:
2569 return expandLoadDoubleImmToFPR(Inst,
false, IDLoc, Out, STI) ? MER_Fail
2573 return expandUlh(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2575 return expandUlh(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2577 return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2580 return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2582 case Mips::NORImm64:
2583 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2586 return expandSge(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2589 case Mips::SGEImm64:
2590 case Mips::SGEUImm64:
2591 return expandSgeImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2594 case Mips::SGTImm64:
2595 case Mips::SGTUImm64:
2596 return expandSgtImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2599 return expandSle(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2602 case Mips::SLEImm64:
2603 case Mips::SLEUImm64:
2604 return expandSleImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2605 case Mips::SLTImm64:
2608 return MER_NotAMacro;
2610 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2611 case Mips::SLTUImm64:
2614 return MER_NotAMacro;
2616 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2617 case Mips::ADDi:
case Mips::ADDi_MM:
2618 case Mips::ADDiu:
case Mips::ADDiu_MM:
2619 case Mips::SLTi:
case Mips::SLTi_MM:
2620 case Mips::SLTiu:
case Mips::SLTiu_MM:
2624 if (isInt<16>(ImmValue))
2625 return MER_NotAMacro;
2626 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2629 return MER_NotAMacro;
2630 case Mips::ANDi:
case Mips::ANDi_MM:
case Mips::ANDi64:
2631 case Mips::ORi:
case Mips::ORi_MM:
case Mips::ORi64:
2632 case Mips::XORi:
case Mips::XORi_MM:
case Mips::XORi64:
2636 if (isUInt<16>(ImmValue))
2637 return MER_NotAMacro;
2638 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2641 return MER_NotAMacro;
2644 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2647 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2650 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2653 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2654 case Mips::ABSMacro:
2655 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2656 case Mips::MULImmMacro:
2657 case Mips::DMULImmMacro:
2658 return expandMulImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2659 case Mips::MULOMacro:
2660 case Mips::DMULOMacro:
2661 return expandMulO(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2662 case Mips::MULOUMacro:
2663 case Mips::DMULOUMacro:
2664 return expandMulOU(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2665 case Mips::DMULMacro:
2666 return expandDMULMacro(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2669 return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2674 return expandStoreDM1Macro(Inst, IDLoc, Out, STI)
2677 case Mips::SEQMacro:
2678 return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2679 case Mips::SEQIMacro:
2680 return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2681 case Mips::SNEMacro:
2682 return expandSne(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2683 case Mips::SNEIMacro:
2684 return expandSneI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2685 case Mips::MFTC0:
case Mips::MTTC0:
2686 case Mips::MFTGPR:
case Mips::MTTGPR:
2687 case Mips::MFTLO:
case Mips::MTTLO:
2688 case Mips::MFTHI:
case Mips::MTTHI:
2689 case Mips::MFTACX:
case Mips::MTTACX:
2690 case Mips::MFTDSP:
case Mips::MTTDSP:
2691 case Mips::MFTC1:
case Mips::MTTC1:
2692 case Mips::MFTHC1:
case Mips::MTTHC1:
2693 case Mips::CFTC1:
case Mips::CTTC1:
2694 return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2696 case Mips::SaadAddr:
2697 return expandSaaAddr(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2701bool MipsAsmParser::expandJalWithRegs(
MCInst &Inst,
SMLoc IDLoc,
2710 const unsigned Opcode = Inst.
getOpcode();
2712 if (Opcode == Mips::JalOneReg) {
2714 if (IsCpRestoreSet && inMicroMipsMode()) {
2717 }
else if (inMicroMipsMode()) {
2718 JalrInst.
setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2725 }
else if (Opcode == Mips::JalTwoReg) {
2727 if (IsCpRestoreSet && inMicroMipsMode())
2730 JalrInst.
setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2762bool MipsAsmParser::loadImmediate(int64_t ImmValue,
unsigned DstReg,
2763 unsigned SrcReg,
bool Is32BitImm,
2768 if (!Is32BitImm && !isGP64bit()) {
2769 Error(IDLoc,
"instruction requires a 64-bit architecture");
2774 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2778 ImmValue = SignExtend64<32>(ImmValue);
2780 Error(IDLoc,
"instruction requires a 32-bit immediate");
2785 unsigned ZeroReg = IsAddress ?
ABI.GetNullPtr() :
ABI.GetZeroReg();
2786 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2788 bool UseSrcReg =
false;
2789 if (SrcReg != Mips::NoRegister)
2792 unsigned TmpReg = DstReg;
2794 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2797 unsigned ATReg = getATReg(IDLoc);
2803 if (isInt<16>(ImmValue)) {
2810 if (IsAddress && !Is32BitImm) {
2811 TOut.
emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2815 TOut.
emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2819 if (isUInt<16>(ImmValue)) {
2820 unsigned TmpReg = DstReg;
2821 if (SrcReg == DstReg) {
2822 TmpReg = getATReg(IDLoc);
2827 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2829 TOut.
emitRRR(
ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2833 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2834 warnIfNoMacro(IDLoc);
2836 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2837 uint16_t Bits15To0 = ImmValue & 0xffff;
2838 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2841 if (ImmValue == 0xffffffff) {
2842 TOut.
emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2843 TOut.
emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2845 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2851 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2852 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2854 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2856 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2860 TOut.
emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2862 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2864 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2868 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2870 Error(IDLoc,
"instruction requires a 32-bit immediate");
2877 assert(
BitWidth >= 17 &&
"ImmValue must be at least 17-bit wide");
2881 unsigned ShiftAmount =
BitWidth - 16;
2883 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2884 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2887 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2892 warnIfNoMacro(IDLoc);
2899 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister,
true,
false,
2905 unsigned ShiftCarriedForwards = 16;
2906 for (
int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2907 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2909 if (ImmChunk != 0) {
2910 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2911 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2912 ShiftCarriedForwards = 0;
2915 ShiftCarriedForwards += 16;
2917 ShiftCarriedForwards -= 16;
2920 if (ShiftCarriedForwards)
2921 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2924 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2929bool MipsAsmParser::expandLoadImm(
MCInst &Inst,
bool Is32BitImm,
SMLoc IDLoc,
2932 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
2934 assert(DstRegOp.
isReg() &&
"expected register operand kind");
2936 if (loadImmediate(ImmOp.
getImm(), DstRegOp.
getReg(), Mips::NoRegister,
2937 Is32BitImm,
false, IDLoc, Out, STI))
2943bool MipsAsmParser::expandLoadAddress(
unsigned DstReg,
unsigned BaseReg,
2945 bool Is32BitAddress,
SMLoc IDLoc,
2949 if (Is32BitAddress &&
ABI.ArePtrs64bit()) {
2950 Warning(IDLoc,
"la used to load 64-bit address");
2952 Is32BitAddress =
false;
2956 if (!Is32BitAddress && !hasMips3()) {
2957 Error(IDLoc,
"instruction requires a 64-bit architecture");
2962 return loadAndAddSymbolAddress(
Offset.getExpr(), DstReg, BaseReg,
2963 Is32BitAddress, IDLoc, Out, STI);
2965 if (!
ABI.ArePtrs64bit()) {
2967 Is32BitAddress =
true;
2970 return loadImmediate(
Offset.getImm(), DstReg, BaseReg, Is32BitAddress,
true,
2974bool MipsAsmParser::loadAndAddSymbolAddress(
const MCExpr *SymExpr,
2975 unsigned DstReg,
unsigned SrcReg,
2976 bool Is32BitSym,
SMLoc IDLoc,
2980 bool UseSrcReg = SrcReg != Mips::NoRegister && SrcReg != Mips::ZERO &&
2981 SrcReg != Mips::ZERO_64;
2982 warnIfNoMacro(IDLoc);
2987 Error(IDLoc,
"expected relocatable expression");
2990 if (Res.
getSymB() !=
nullptr) {
2991 Error(IDLoc,
"expected relocatable expression with only one symbol");
2995 bool IsPtr64 =
ABI.ArePtrs64bit();
3007 bool UseXGOT = STI->
hasFeature(Mips::FeatureXGOT) && !IsLocalSym;
3013 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
3017 SymExpr, getContext());
3019 SymExpr, getContext());
3022 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, DstReg, GPReg,
3024 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, DstReg,
3029 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, GPReg,
3035 unsigned TmpReg = DstReg;
3037 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
3041 unsigned ATReg = getATReg(IDLoc);
3060 const MCExpr *CallHiExpr =
3067 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg, GPReg,
3069 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, TmpReg,
3073 TOut.
emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3079 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3085 const MCExpr *LoExpr =
nullptr;
3086 if (
ABI.IsN32() ||
ABI.IsN64()) {
3105 Error(IDLoc,
"macro instruction uses large offset, which is not "
3106 "currently supported");
3136 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, GPReg,
3140 TOut.
emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3144 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3156 if (
ABI.ArePtrs64bit() && isGP64bit()) {
3171 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
3173 if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
3174 unsigned ATReg = getATReg(IDLoc);
3186 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3188 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3191 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3194 TOut.
emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
3197 }
else if (canUseATReg() && !RdRegIsRsReg && DstReg != getATReg(IDLoc)) {
3198 unsigned ATReg = getATReg(IDLoc);
3214 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3218 TOut.
emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3219 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3221 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3224 }
else if ((!canUseATReg() && !RdRegIsRsReg) ||
3225 (canUseATReg() && DstReg == getATReg(IDLoc))) {
3236 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3238 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3239 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3241 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3242 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3245 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3251 assert(SrcReg == DstReg && !canUseATReg() &&
3252 "Could have expanded dla but didn't?");
3253 reportParseError(IDLoc,
3254 "pseudo-instruction requires $at, which is not available");
3268 unsigned TmpReg = DstReg;
3270 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
3273 unsigned ATReg = getATReg(IDLoc);
3284 TOut.
emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3287 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
3296 if (MipsMCRegisterClasses[Mips::FGR32RegClassID].
contains(
Reg))
3297 return Reg == (
unsigned)Mips::F31 ? (
unsigned)Mips::F0 :
Reg + 1;
3299 default:
llvm_unreachable(
"Unknown register in assembly macro expansion!");
3300 case Mips::ZERO:
return Mips::AT;
3301 case Mips::AT:
return Mips::V0;
3302 case Mips::V0:
return Mips::V1;
3303 case Mips::V1:
return Mips::A0;
3304 case Mips::A0:
return Mips::A1;
3305 case Mips::A1:
return Mips::A2;
3306 case Mips::A2:
return Mips::A3;
3307 case Mips::A3:
return Mips::T0;
3308 case Mips::T0:
return Mips::T1;
3309 case Mips::T1:
return Mips::T2;
3310 case Mips::T2:
return Mips::T3;
3311 case Mips::T3:
return Mips::T4;
3312 case Mips::T4:
return Mips::T5;
3313 case Mips::T5:
return Mips::T6;
3314 case Mips::T6:
return Mips::T7;
3315 case Mips::T7:
return Mips::S0;
3316 case Mips::S0:
return Mips::S1;
3317 case Mips::S1:
return Mips::S2;
3318 case Mips::S2:
return Mips::S3;
3319 case Mips::S3:
return Mips::S4;
3320 case Mips::S4:
return Mips::S5;
3321 case Mips::S5:
return Mips::S6;
3322 case Mips::S6:
return Mips::S7;
3323 case Mips::S7:
return Mips::T8;
3324 case Mips::T8:
return Mips::T9;
3325 case Mips::T9:
return Mips::K0;
3326 case Mips::K0:
return Mips::K1;
3327 case Mips::K1:
return Mips::GP;
3328 case Mips::GP:
return Mips::SP;
3329 case Mips::SP:
return Mips::FP;
3330 case Mips::FP:
return Mips::RA;
3331 case Mips::RA:
return Mips::ZERO;
3332 case Mips::D0:
return Mips::F1;
3333 case Mips::D1:
return Mips::F3;
3334 case Mips::D2:
return Mips::F5;
3335 case Mips::D3:
return Mips::F7;
3336 case Mips::D4:
return Mips::F9;
3337 case Mips::D5:
return Mips::F11;
3338 case Mips::D6:
return Mips::F13;
3339 case Mips::D7:
return Mips::F15;
3340 case Mips::D8:
return Mips::F17;
3341 case Mips::D9:
return Mips::F19;
3342 case Mips::D10:
return Mips::F21;
3343 case Mips::D11:
return Mips::F23;
3344 case Mips::D12:
return Mips::F25;
3345 case Mips::D13:
return Mips::F27;
3346 case Mips::D14:
return Mips::F29;
3347 case Mips::D15:
return Mips::F31;
3359 unsigned ATReg = getATReg(IDLoc);
3369 if(isABI_O32() || isABI_N32()) {
3388 if(isABI_O32() || isABI_N32()) {
3391 const MCExpr *HighestSym =
3395 const MCExpr *HigherSym =
3402 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3404 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3407 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3416 if ((
Hi_32(ImmOp64) & 0x7ff00000) == 0) {
3417 APFloat RealVal(APFloat::IEEEdouble(), ImmOp64);
3426 double DoubleImm = llvm::bit_cast<double>(ImmOp64);
3427 float TmpFloat =
static_cast<float>(DoubleImm);
3428 return llvm::bit_cast<uint32_t>(TmpFloat);
3431bool MipsAsmParser::expandLoadSingleImmToGPR(
MCInst &Inst,
SMLoc IDLoc,
3436 "Invalid instruction operand.");
3443 return loadImmediate(ImmOp32, FirstReg, Mips::NoRegister,
true,
false, IDLoc,
3447bool MipsAsmParser::expandLoadSingleImmToFPR(
MCInst &Inst,
SMLoc IDLoc,
3453 "Invalid instruction operand.");
3462 unsigned TmpReg = Mips::ZERO;
3464 TmpReg = getATReg(IDLoc);
3469 if (
Lo_32(ImmOp64) == 0) {
3470 if (TmpReg != Mips::ZERO && loadImmediate(ImmOp32, TmpReg, Mips::NoRegister,
3471 true,
false, IDLoc, Out, STI))
3473 TOut.
emitRR(Mips::MTC1, FirstReg, TmpReg, IDLoc, STI);
3477 MCSection *CS = getStreamer().getCurrentSectionOnly();
3489 getStreamer().switchSection(ReadOnlySection);
3490 getStreamer().emitLabel(
Sym, IDLoc);
3491 getStreamer().emitInt32(ImmOp32);
3492 getStreamer().switchSection(CS);
3494 if (emitPartialAddress(TOut, IDLoc,
Sym))
3501bool MipsAsmParser::expandLoadDoubleImmToGPR(
MCInst &Inst,
SMLoc IDLoc,
3507 "Invalid instruction operand.");
3514 if (
Lo_32(ImmOp64) == 0) {
3516 if (loadImmediate(ImmOp64, FirstReg, Mips::NoRegister,
false,
false,
3520 if (loadImmediate(
Hi_32(ImmOp64), FirstReg, Mips::NoRegister,
true,
false,
3524 if (loadImmediate(0,
nextReg(FirstReg), Mips::NoRegister,
true,
false,
3531 MCSection *CS = getStreamer().getCurrentSectionOnly();
3541 getStreamer().switchSection(ReadOnlySection);
3542 getStreamer().emitLabel(
Sym, IDLoc);
3543 getStreamer().emitValueToAlignment(
Align(8));
3544 getStreamer().emitIntValue(ImmOp64, 8);
3545 getStreamer().switchSection(CS);
3547 unsigned TmpReg = getATReg(IDLoc);
3551 if (emitPartialAddress(TOut, IDLoc,
Sym))
3554 TOut.
emitRRX(isABI_N64() ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3558 TOut.
emitRRI(Mips::LD, FirstReg, TmpReg, 0, IDLoc, STI);
3560 TOut.
emitRRI(Mips::LW, FirstReg, TmpReg, 0, IDLoc, STI);
3561 TOut.
emitRRI(Mips::LW,
nextReg(FirstReg), TmpReg, 4, IDLoc, STI);
3566bool MipsAsmParser::expandLoadDoubleImmToFPR(
MCInst &Inst,
bool Is64FPU,
3572 "Invalid instruction operand.");
3579 unsigned TmpReg = Mips::ZERO;
3581 TmpReg = getATReg(IDLoc);
3586 if ((
Lo_32(ImmOp64) == 0) &&
3587 !((
Hi_32(ImmOp64) & 0xffff0000) && (
Hi_32(ImmOp64) & 0x0000ffff))) {
3589 if (TmpReg != Mips::ZERO &&
3590 loadImmediate(ImmOp64, TmpReg, Mips::NoRegister,
false,
false, IDLoc,
3593 TOut.
emitRR(Mips::DMTC1, FirstReg, TmpReg, IDLoc, STI);
3597 if (TmpReg != Mips::ZERO &&
3598 loadImmediate(
Hi_32(ImmOp64), TmpReg, Mips::NoRegister,
true,
false,
3602 if (hasMips32r2()) {
3603 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3604 TOut.
emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, TmpReg, IDLoc, STI);
3606 TOut.
emitRR(Mips::MTC1,
nextReg(FirstReg), TmpReg, IDLoc, STI);
3607 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3612 MCSection *CS = getStreamer().getCurrentSectionOnly();
3624 getStreamer().switchSection(ReadOnlySection);
3625 getStreamer().emitLabel(
Sym, IDLoc);
3626 getStreamer().emitValueToAlignment(
Align(8));
3627 getStreamer().emitIntValue(ImmOp64, 8);
3628 getStreamer().switchSection(CS);
3630 if (emitPartialAddress(TOut, IDLoc,
Sym))
3633 TOut.
emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, TmpReg,
3639bool MipsAsmParser::expandUncondBranchMMPseudo(
MCInst &Inst,
SMLoc IDLoc,
3645 "unexpected number of operands");
3655 assert(
Offset.isImm() &&
"expected immediate operand kind");
3656 if (isInt<11>(
Offset.getImm())) {
3659 if (inMicroMipsMode())
3660 Inst.
setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3662 if (!isInt<17>(
Offset.getImm()))
3663 return Error(IDLoc,
"branch target out of range");
3665 return Error(IDLoc,
"branch to misaligned address");
3688 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3691 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
3695 "expected immediate or expression operand");
3697 bool IsLikely =
false;
3707 case Mips::BEQLImmMacro:
3711 case Mips::BNELImmMacro:
3720 int64_t ImmValue = ImmOp.
getImm();
3721 if (ImmValue == 0) {
3725 TOut.
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3727 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3730 warnIfNoMacro(IDLoc);
3732 unsigned ATReg = getATReg(IDLoc);
3736 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(),
true,
3743 TOut.
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3745 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3753 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3754 unsigned StartOp = NumOp == 3 ? 0 : 1;
3757 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3759 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3764 unsigned DstReg = DstRegOp.
getReg();
3765 unsigned BaseReg = BaseRegOp.
getReg();
3766 unsigned TmpReg = DstReg;
3769 int16_t DstRegClass =
Desc.operands()[StartOp].RegClass;
3770 unsigned DstRegClassID =
3771 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3772 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3773 (DstRegClassID == Mips::GPR64RegClassID);
3775 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3778 TmpReg = getATReg(IDLoc);
3785 TOut.
emitRRX(OpCode, DstReg, TmpReg, Off, IDLoc, STI);
3787 TOut.
emitRRRX(OpCode, DstReg, DstReg, TmpReg, Off, IDLoc, STI);
3790 if (OffsetOp.
isImm()) {
3791 int64_t LoOffset = OffsetOp.
getImm() & 0xffff;
3792 int64_t HiOffset = OffsetOp.
getImm() & ~0xffff;
3796 if (LoOffset & 0x8000)
3797 HiOffset += 0x10000;
3799 bool IsLargeOffset = HiOffset != 0;
3801 if (IsLargeOffset) {
3802 bool Is32BitImm = isInt<32>(OffsetOp.
getImm());
3803 if (loadImmediate(HiOffset, TmpReg, Mips::NoRegister, Is32BitImm,
true,
3808 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3809 TOut.
emitRRR(
ABI.ArePtrs64bit() ? Mips::DADDu : Mips::ADDu, TmpReg,
3810 TmpReg, BaseReg, IDLoc, STI);
3825 Error(IDLoc,
"expected relocatable expression");
3828 if (Res.
getSymB() !=
nullptr) {
3829 Error(IDLoc,
"expected relocatable expression with only one symbol");
3833 loadAndAddSymbolAddress(Res.
getSymA(), TmpReg, BaseReg,
3834 !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3854 TOut.
emitRX(Mips::LUi, TmpReg, HighestOperand, IDLoc, STI);
3855 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HigherOperand, IDLoc, STI);
3856 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3857 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HiOperand, IDLoc, STI);
3858 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3859 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3860 TOut.
emitRRR(Mips::DADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3861 emitInstWithOffset(LoOperand);
3864 TOut.
emitRX(Mips::LUi, TmpReg, HiOperand, IDLoc, STI);
3865 if (BaseReg != Mips::ZERO)
3866 TOut.
emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3868 emitInstWithOffset(LoOperand);
3880 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3881 unsigned StartOp = NumOp == 3 ? 0 : 1;
3884 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3886 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3891 unsigned DstReg = DstRegOp.
getReg();
3892 unsigned BaseReg = BaseRegOp.
getReg();
3893 unsigned TmpReg = DstReg;
3896 int16_t DstRegClass =
Desc.operands()[StartOp].RegClass;
3897 unsigned DstRegClassID =
3898 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3899 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3900 (DstRegClassID == Mips::GPR64RegClassID);
3902 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3905 TmpReg = getATReg(IDLoc);
3910 auto emitInst = [&]() {
3918 if (OffsetOp.
isImm()) {
3919 loadImmediate(OffsetOp.
getImm(), TmpReg, BaseReg, !
ABI.ArePtrs64bit(),
true,
3926 loadAndAddSymbolAddress(OffsetOp.
getExpr(), TmpReg, BaseReg,
3927 !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3935bool MipsAsmParser::expandLoadStoreMultiple(
MCInst &Inst,
SMLoc IDLoc,
3940 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3944 Inst.
getOperand(OpNum - 3).
isReg() &&
"Invalid instruction operand.");
3953 if (inMicroMipsMode() && hasMips32r6())
3954 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3956 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3964bool MipsAsmParser::expandCondBranches(
MCInst &Inst,
SMLoc IDLoc,
3968 bool EmittedNoMacroWarning =
false;
3969 unsigned PseudoOpcode = Inst.
getOpcode();
3974 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3975 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3980 else if (TrgOp.
isImm()) {
3981 warnIfNoMacro(IDLoc);
3982 EmittedNoMacroWarning =
true;
3984 TrgReg = getATReg(IDLoc);
3988 switch(PseudoOpcode) {
3991 case Mips::BLTImmMacro:
3992 PseudoOpcode = Mips::BLT;
3994 case Mips::BLEImmMacro:
3995 PseudoOpcode = Mips::BLE;
3997 case Mips::BGEImmMacro:
3998 PseudoOpcode = Mips::BGE;
4000 case Mips::BGTImmMacro:
4001 PseudoOpcode = Mips::BGT;
4003 case Mips::BLTUImmMacro:
4004 PseudoOpcode = Mips::BLTU;
4006 case Mips::BLEUImmMacro:
4007 PseudoOpcode = Mips::BLEU;
4009 case Mips::BGEUImmMacro:
4010 PseudoOpcode = Mips::BGEU;
4012 case Mips::BGTUImmMacro:
4013 PseudoOpcode = Mips::BGTU;
4015 case Mips::BLTLImmMacro:
4016 PseudoOpcode = Mips::BLTL;
4018 case Mips::BLELImmMacro:
4019 PseudoOpcode = Mips::BLEL;
4021 case Mips::BGELImmMacro:
4022 PseudoOpcode = Mips::BGEL;
4024 case Mips::BGTLImmMacro:
4025 PseudoOpcode = Mips::BGTL;
4027 case Mips::BLTULImmMacro:
4028 PseudoOpcode = Mips::BLTUL;
4030 case Mips::BLEULImmMacro:
4031 PseudoOpcode = Mips::BLEUL;
4033 case Mips::BGEULImmMacro:
4034 PseudoOpcode = Mips::BGEUL;
4036 case Mips::BGTULImmMacro:
4037 PseudoOpcode = Mips::BGTUL;
4041 if (loadImmediate(TrgOp.
getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
4042 false, IDLoc, Out, STI))
4046 switch (PseudoOpcode) {
4051 AcceptsEquality =
false;
4052 ReverseOrderSLT =
false;
4054 ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
4055 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
4056 ZeroSrcOpcode = Mips::BGTZ;
4057 ZeroTrgOpcode = Mips::BLTZ;
4063 AcceptsEquality =
true;
4064 ReverseOrderSLT =
true;
4066 ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
4067 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
4068 ZeroSrcOpcode = Mips::BGEZ;
4069 ZeroTrgOpcode = Mips::BLEZ;
4075 AcceptsEquality =
true;
4076 ReverseOrderSLT =
false;
4078 ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
4079 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
4080 ZeroSrcOpcode = Mips::BLEZ;
4081 ZeroTrgOpcode = Mips::BGEZ;
4087 AcceptsEquality =
false;
4088 ReverseOrderSLT =
true;
4090 ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
4091 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
4092 ZeroSrcOpcode = Mips::BLTZ;
4093 ZeroTrgOpcode = Mips::BGTZ;
4099 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
4100 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
4101 if (IsSrcRegZero && IsTrgRegZero) {
4105 if (PseudoOpcode == Mips::BLT) {
4110 if (PseudoOpcode == Mips::BLE) {
4113 Warning(IDLoc,
"branch is always taken");
4116 if (PseudoOpcode == Mips::BGE) {
4119 Warning(IDLoc,
"branch is always taken");
4122 if (PseudoOpcode == Mips::BGT) {
4127 if (PseudoOpcode == Mips::BGTU) {
4128 TOut.
emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
4132 if (AcceptsEquality) {
4135 TOut.
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4137 Warning(IDLoc,
"branch is always taken");
4144 if (IsSrcRegZero || IsTrgRegZero) {
4145 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
4146 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
4153 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
4154 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
4160 TOut.
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4162 Warning(IDLoc,
"branch is always taken");
4178 TOut.
emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
4179 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
4186 TOut.
emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
4187 IsSrcRegZero ? TrgReg : SrcReg,
4194 unsigned ATRegNum = getATReg(IDLoc);
4198 if (!EmittedNoMacroWarning)
4199 warnIfNoMacro(IDLoc);
4216 TOut.
emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
4217 ReverseOrderSLT ? TrgReg : SrcReg,
4218 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
4220 TOut.
emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
4221 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
4237 const bool IsMips64,
const bool Signed) {
4240 warnIfNoMacro(IDLoc);
4243 assert(RdRegOp.
isReg() &&
"expected register operand kind");
4244 unsigned RdReg = RdRegOp.
getReg();
4247 assert(RsRegOp.
isReg() &&
"expected register operand kind");
4248 unsigned RsReg = RsRegOp.
getReg();
4255 "expected register or immediate operand kind");
4259 ImmValue = RtOp.
getImm();
4266 DivOp =
Signed ? Mips::DSDIV : Mips::DUDIV;
4267 ZeroReg = Mips::ZERO_64;
4270 DivOp =
Signed ? Mips::SDIV : Mips::UDIV;
4271 ZeroReg = Mips::ZERO;
4275 bool UseTraps = useTraps();
4278 bool isDiv = Opcode == Mips::SDivMacro || Opcode == Mips::SDivIMacro ||
4279 Opcode == Mips::UDivMacro || Opcode == Mips::UDivIMacro ||
4280 Opcode == Mips::DSDivMacro || Opcode == Mips::DSDivIMacro ||
4281 Opcode == Mips::DUDivMacro || Opcode == Mips::DUDivIMacro;
4283 bool isRem = Opcode == Mips::SRemMacro || Opcode == Mips::SRemIMacro ||
4284 Opcode == Mips::URemMacro || Opcode == Mips::URemIMacro ||
4285 Opcode == Mips::DSRemMacro || Opcode == Mips::DSRemIMacro ||
4286 Opcode == Mips::DURemMacro || Opcode == Mips::DURemIMacro;
4289 unsigned ATReg = getATReg(IDLoc);
4293 if (ImmValue == 0) {
4295 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4297 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4301 if (isRem && (ImmValue == 1 || (
Signed && (ImmValue == -1)))) {
4302 TOut.
emitRRR(Mips::OR, RdReg, ZeroReg, ZeroReg, IDLoc, STI);
4304 }
else if (isDiv && ImmValue == 1) {
4305 TOut.
emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI);
4307 }
else if (isDiv &&
Signed && ImmValue == -1) {
4308 TOut.
emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
4311 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, isInt<32>(ImmValue),
4312 false, Inst.
getLoc(), Out, STI))
4314 TOut.
emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
4315 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4325 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
4327 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4330 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4336 if (isRem && (RdReg == Mips::ZERO || RdReg == Mips::ZERO_64)) {
4337 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4347 TOut.
emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4352 TOut.
emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4355 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4358 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4364 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4368 unsigned ATReg = getATReg(IDLoc);
4375 TOut.
emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
4383 TOut.
emitRRX(Mips::BNE, RtReg, ATReg, LabelOpEnd, IDLoc, STI);
4386 TOut.
emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
4387 TOut.
emitDSLL(ATReg, ATReg, 63, IDLoc, STI);
4393 TOut.
emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
4396 TOut.
emitRRX(Mips::BNE, RsReg, ATReg, LabelOpEnd, IDLoc, STI);
4398 TOut.
emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
4402 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4406bool MipsAsmParser::expandTrunc(
MCInst &Inst,
bool IsDouble,
bool Is64FPU,
4419 if (hasMips1() && !hasMips2()) {
4420 unsigned ATReg = getATReg(IDLoc);
4423 TOut.
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4424 TOut.
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4426 TOut.
emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4427 TOut.
emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4428 TOut.
emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4430 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4432 FirstReg, SecondReg, IDLoc, STI);
4433 TOut.
emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4438 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4440 FirstReg, SecondReg, IDLoc, STI);
4447 if (hasMips32r6() || hasMips64r6()) {
4448 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4452 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4454 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4456 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4459 unsigned DstReg = DstRegOp.
getReg();
4460 unsigned SrcReg = SrcRegOp.
getReg();
4461 int64_t OffsetValue = OffsetImmOp.
getImm();
4465 warnIfNoMacro(IDLoc);
4466 unsigned ATReg = getATReg(IDLoc);
4470 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4471 if (IsLargeOffset) {
4472 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4477 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4478 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4482 unsigned FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4483 unsigned SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4485 unsigned LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4486 unsigned SllReg = IsLargeOffset ? DstReg : ATReg;
4488 TOut.
emitRRI(
Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4489 FirstOffset, IDLoc, STI);
4490 TOut.
emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4491 TOut.
emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4492 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4499 if (hasMips32r6() || hasMips64r6()) {
4500 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4504 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4506 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4508 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4511 unsigned DstReg = DstRegOp.
getReg();
4512 unsigned SrcReg = SrcRegOp.
getReg();
4513 int64_t OffsetValue = OffsetImmOp.
getImm();
4515 warnIfNoMacro(IDLoc);
4516 unsigned ATReg = getATReg(IDLoc);
4520 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4521 if (IsLargeOffset) {
4522 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4527 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4528 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4532 if (IsLargeOffset) {
4533 TOut.
emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4534 TOut.
emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4535 TOut.
emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4536 TOut.
emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4537 TOut.
emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4538 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4540 TOut.
emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4541 TOut.
emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4542 TOut.
emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4550 if (hasMips32r6() || hasMips64r6()) {
4551 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4555 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4557 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4559 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4562 unsigned DstReg = DstRegOp.
getReg();
4563 unsigned SrcReg = SrcRegOp.
getReg();
4564 int64_t OffsetValue = OffsetImmOp.
getImm();
4567 bool IsLargeOffset = !(isInt<16>(OffsetValue + 3) && isInt<16>(OffsetValue));
4568 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4569 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4573 bool IsLoadInst = (Inst.
getOpcode() == Mips::Ulw);
4574 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4575 unsigned TmpReg = SrcReg;
4576 if (IsLargeOffset || DoMove) {
4577 warnIfNoMacro(IDLoc);
4578 TmpReg = getATReg(IDLoc);
4583 if (IsLargeOffset) {
4584 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4592 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4593 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4594 TOut.
emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4595 TOut.
emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4598 TOut.
emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4617 warnIfNoMacro(IDLoc);
4631 TOut.
emitRRR(OpCode, DstReg, SrcReg, OpReg, IDLoc, STI);
4632 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4649 unsigned OpRegCode, OpImmCode;
4651 warnIfNoMacro(IDLoc);
4655 case Mips::SGEImm64:
4656 OpRegCode = Mips::SLT;
4657 OpImmCode = Mips::SLTi;
4660 case Mips::SGEUImm64:
4661 OpRegCode = Mips::SLTu;
4662 OpImmCode = Mips::SLTiu;
4669 if (isInt<16>(ImmValue)) {
4671 TOut.
emitRRI(OpImmCode, DstReg, SrcReg, ImmValue, IDLoc, STI);
4672 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4674 unsigned ImmReg = DstReg;
4675 if (DstReg == SrcReg) {
4676 unsigned ATReg = getATReg(Inst.
getLoc());
4682 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4683 false, IDLoc, Out, STI))
4686 TOut.
emitRRR(OpRegCode, DstReg, SrcReg, ImmReg, IDLoc, STI);
4687 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4704 unsigned ImmReg = DstReg;
4708 warnIfNoMacro(IDLoc);
4712 case Mips::SGTImm64:
4716 case Mips::SGTUImm64:
4723 if (DstReg == SrcReg) {
4724 unsigned ATReg = getATReg(Inst.
getLoc());
4730 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4731 false, IDLoc, Out, STI))
4735 TOut.
emitRRR(OpCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4754 warnIfNoMacro(IDLoc);
4768 TOut.
emitRRR(OpCode, DstReg, OpReg, SrcReg, IDLoc, STI);
4769 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4788 warnIfNoMacro(IDLoc);
4792 case Mips::SLEImm64:
4793 OpRegCode = Mips::SLT;
4796 case Mips::SLEUImm64:
4797 OpRegCode = Mips::SLTu;
4804 unsigned ImmReg = DstReg;
4805 if (DstReg == SrcReg) {
4806 unsigned ATReg = getATReg(Inst.
getLoc());
4812 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4813 false, IDLoc, Out, STI))
4816 TOut.
emitRRR(OpRegCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4817 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4822bool MipsAsmParser::expandAliasImmediate(
MCInst &Inst,
SMLoc IDLoc,
4832 unsigned ATReg = Mips::NoRegister;
4833 unsigned FinalDstReg = Mips::NoRegister;
4838 bool Is32Bit = isInt<32>(ImmValue) || (!isGP64bit() && isUInt<32>(ImmValue));
4840 unsigned FinalOpcode = Inst.
getOpcode();
4842 if (DstReg == SrcReg) {
4843 ATReg = getATReg(Inst.
getLoc());
4846 FinalDstReg = DstReg;
4850 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit,
false,
4851 Inst.
getLoc(), Out, STI)) {
4852 switch (FinalOpcode) {
4856 FinalOpcode = Mips::ADD;
4859 FinalOpcode = Mips::ADDu;
4862 FinalOpcode = Mips::AND;
4865 FinalOpcode = Mips::NOR;
4868 FinalOpcode = Mips::OR;
4871 FinalOpcode = Mips::SLT;
4874 FinalOpcode = Mips::SLTu;
4877 FinalOpcode = Mips::XOR;
4880 FinalOpcode = Mips::ADD_MM;
4882 case Mips::ADDiu_MM:
4883 FinalOpcode = Mips::ADDu_MM;
4886 FinalOpcode = Mips::AND_MM;
4889 FinalOpcode = Mips::OR_MM;
4892 FinalOpcode = Mips::SLT_MM;
4894 case Mips::SLTiu_MM:
4895 FinalOpcode = Mips::SLTu_MM;
4898 FinalOpcode = Mips::XOR_MM;
4901 FinalOpcode = Mips::AND64;
4903 case Mips::NORImm64:
4904 FinalOpcode = Mips::NOR64;
4907 FinalOpcode = Mips::OR64;
4909 case Mips::SLTImm64:
4910 FinalOpcode = Mips::SLT64;
4912 case Mips::SLTUImm64:
4913 FinalOpcode = Mips::SLTu64;
4916 FinalOpcode = Mips::XOR64;
4920 if (FinalDstReg == Mips::NoRegister)
4921 TOut.
emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4923 TOut.
emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4932 unsigned ATReg = Mips::NoRegister;
4936 unsigned TmpReg =
DReg;
4938 unsigned FirstShift = Mips::NOP;
4939 unsigned SecondShift = Mips::NOP;
4941 if (hasMips32r2()) {
4943 TmpReg = getATReg(Inst.
getLoc());
4949 TOut.
emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4950 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
4955 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
4967 FirstShift = Mips::SRLV;
4968 SecondShift = Mips::SLLV;
4971 FirstShift = Mips::SLLV;
4972 SecondShift = Mips::SRLV;
4976 ATReg = getATReg(Inst.
getLoc());
4980 TOut.
emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4981 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
4982 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
4983 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
4991bool MipsAsmParser::expandRotationImm(
MCInst &Inst,
SMLoc IDLoc,
4995 unsigned ATReg = Mips::NoRegister;
5000 unsigned FirstShift = Mips::NOP;
5001 unsigned SecondShift = Mips::NOP;
5003 if (hasMips32r2()) {
5008 ShiftValue = MaxShift - ImmValue;
5009 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
5014 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.
getLoc(), STI);
5022 if (ImmValue == 0) {
5031 FirstShift = Mips::SLL;
5032 SecondShift = Mips::SRL;
5035 FirstShift = Mips::SRL;
5036 SecondShift = Mips::SLL;
5040 ATReg = getATReg(Inst.
getLoc());
5044 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.
getLoc(), STI);
5045 TOut.
emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.
getLoc(), STI);
5046 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5057 unsigned ATReg = Mips::NoRegister;
5061 unsigned TmpReg =
DReg;
5063 unsigned FirstShift = Mips::NOP;
5064 unsigned SecondShift = Mips::NOP;
5066 if (hasMips64r2()) {
5067 if (TmpReg == SReg) {
5068 TmpReg = getATReg(Inst.
getLoc());
5074 TOut.
emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
5075 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
5080 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
5092 FirstShift = Mips::DSRLV;
5093 SecondShift = Mips::DSLLV;
5096 FirstShift = Mips::DSLLV;
5097 SecondShift = Mips::DSRLV;
5101 ATReg = getATReg(Inst.
getLoc());
5105 TOut.
emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
5106 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
5107 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
5108 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5116bool MipsAsmParser::expandDRotationImm(
MCInst &Inst,
SMLoc IDLoc,
5120 unsigned ATReg = Mips::NoRegister;
5125 unsigned FirstShift = Mips::NOP;
5126 unsigned SecondShift = Mips::NOP;
5130 if (hasMips64r2()) {
5131 unsigned FinalOpcode = Mips::NOP;
5133 FinalOpcode = Mips::DROTR;
5134 else if (ImmValue % 32 == 0)
5135 FinalOpcode = Mips::DROTR32;
5136 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
5138 FinalOpcode = Mips::DROTR32;
5140 FinalOpcode = Mips::DROTR;
5141 }
else if (ImmValue >= 33) {
5143 FinalOpcode = Mips::DROTR;
5145 FinalOpcode = Mips::DROTR32;
5148 uint64_t ShiftValue = ImmValue % 32;
5150 ShiftValue = (32 - ImmValue % 32) % 32;
5152 TOut.
emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
5158 if (ImmValue == 0) {
5159 TOut.
emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.
getLoc(), STI);
5167 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5168 FirstShift = Mips::DSLL;
5169 SecondShift = Mips::DSRL32;
5171 if (ImmValue == 32) {
5172 FirstShift = Mips::DSLL32;
5173 SecondShift = Mips::DSRL32;
5175 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5176 FirstShift = Mips::DSLL32;
5177 SecondShift = Mips::DSRL;
5181 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5182 FirstShift = Mips::DSRL;
5183 SecondShift = Mips::DSLL32;
5185 if (ImmValue == 32) {
5186 FirstShift = Mips::DSRL32;
5187 SecondShift = Mips::DSLL32;
5189 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5190 FirstShift = Mips::DSRL32;
5191 SecondShift = Mips::DSLL;
5196 ATReg = getATReg(Inst.
getLoc());
5200 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.
getLoc(), STI);
5201 TOut.
emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
5203 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5217 TOut.
emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
5218 if (FirstRegOp != SecondRegOp)
5219 TOut.
emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
5222 TOut.
emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
5230 unsigned ATReg = Mips::NoRegister;
5235 ATReg = getATReg(IDLoc);
5239 loadImmediate(ImmValue, ATReg, Mips::NoRegister,
true,
false, IDLoc, Out,
5242 TOut.
emitRR(Inst.
getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
5243 SrcReg, ATReg, IDLoc, STI);
5245 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5253 unsigned ATReg = Mips::NoRegister;
5258 ATReg = getATReg(Inst.
getLoc());
5262 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
5263 SrcReg, TmpReg, IDLoc, STI);
5265 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5267 TOut.
emitRRI(Inst.
getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
5268 DstReg, DstReg, 0x1F, IDLoc, STI);
5270 TOut.
emitR(Mips::MFHI, ATReg, IDLoc, STI);
5273 TOut.
emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
5280 TOut.
emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
5281 if (AssemblerOptions.
back()->isReorder())
5283 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5287 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5295 unsigned ATReg = Mips::NoRegister;
5300 ATReg = getATReg(IDLoc);
5304 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
5305 SrcReg, TmpReg, IDLoc, STI);
5307 TOut.
emitR(Mips::MFHI, ATReg, IDLoc, STI);
5308 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5310 TOut.
emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);
5317 TOut.
emitRRX(Mips::BEQ, ATReg, Mips::ZERO, LabelOp, IDLoc, STI);
5318 if (AssemblerOptions.
back()->isReorder())
5320 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5335 TOut.
emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
5336 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5346bool MipsAsmParser::expandLoadStoreDMacro(
MCInst &Inst,
SMLoc IDLoc,
5353 warnIfNoMacro(IDLoc);
5356 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
5358 unsigned SecondReg =
nextReg(FirstReg);
5363 warnIfRegIndexIsAT(FirstReg, IDLoc);
5366 "Offset for load macro is not immediate!");
5369 signed NextOffset = FirstOffset.
getImm() + 4;
5372 if (!isInt<16>(FirstOffset.
getImm()) || !isInt<16>(NextOffset))
5377 if (FirstReg != BaseReg || !IsLoad) {
5378 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5379 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5381 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5382 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5394bool MipsAsmParser::expandStoreDM1Macro(
MCInst &Inst,
SMLoc IDLoc,
5400 warnIfNoMacro(IDLoc);
5403 unsigned Opcode = Mips::SWC1;
5405 unsigned SecondReg =
nextReg(FirstReg);
5410 warnIfRegIndexIsAT(FirstReg, IDLoc);
5413 "Offset for macro is not immediate!");
5416 signed NextOffset = FirstOffset.
getImm() + 4;
5419 if (!isInt<16>(FirstOffset.
getImm()) || !isInt<16>(NextOffset))
5422 if (!IsLittleEndian)
5425 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5426 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5444 warnIfNoMacro(IDLoc);
5446 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5447 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5448 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5452 unsigned Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5453 TOut.
emitRRI(Mips::SLTiu, DstReg,
Reg, 1, IDLoc, STI);
5470 warnIfNoMacro(IDLoc);
5473 TOut.
emitRRI(Mips::SLTiu, DstReg, SrcReg, 1, IDLoc, STI);
5477 if (SrcReg == Mips::ZERO) {
5478 Warning(IDLoc,
"comparison is always false");
5479 TOut.
emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
5480 DstReg, SrcReg, SrcReg, IDLoc, STI);
5485 if (Imm > -0x8000 && Imm < 0) {
5487 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5492 if (!isUInt<16>(Imm)) {
5493 unsigned ATReg = getATReg(IDLoc);
5497 if (loadImmediate(Imm, ATReg, Mips::NoRegister,
true, isGP64bit(), IDLoc,
5501 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5502 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5506 TOut.
emitRRI(Opc, DstReg, SrcReg, Imm, IDLoc, STI);
5507 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5525 warnIfNoMacro(IDLoc);
5527 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5528 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5529 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5533 unsigned Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5534 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO,
Reg, IDLoc, STI);
5551 warnIfNoMacro(IDLoc);
5553 if (ImmValue == 0) {
5554 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, SrcReg, IDLoc, STI);
5558 if (SrcReg == Mips::ZERO) {
5559 Warning(IDLoc,
"comparison is always true");
5560 if (loadImmediate(1, DstReg, Mips::NoRegister,
true,
false, IDLoc, Out,
5567 if (ImmValue > -0x8000 && ImmValue < 0) {
5568 ImmValue = -ImmValue;
5569 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5574 if (isUInt<16>(ImmValue)) {
5575 TOut.
emitRRI(Opc, DstReg, SrcReg, ImmValue, IDLoc, STI);
5576 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5580 unsigned ATReg = getATReg(IDLoc);
5584 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, isInt<32>(ImmValue),
5585 false, IDLoc, Out, STI))
5588 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5589 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5652 case Mips::F0:
return Mips::ZERO;
5653 case Mips::F1:
return Mips::AT;
5654 case Mips::F2:
return Mips::V0;
5655 case Mips::F3:
return Mips::V1;
5656 case Mips::F4:
return Mips::A0;
5657 case Mips::F5:
return Mips::A1;
5658 case Mips::F6:
return Mips::A2;
5659 case Mips::F7:
return Mips::A3;
5660 case Mips::F8:
return Mips::T0;
5661 case Mips::F9:
return Mips::T1;
5662 case Mips::F10:
return Mips::T2;
5663 case Mips::F11:
return Mips::T3;
5664 case Mips::F12:
return Mips::T4;
5665 case Mips::F13:
return Mips::T5;
5666 case Mips::F14:
return Mips::T6;
5667 case Mips::F15:
return Mips::T7;
5668 case Mips::F16:
return Mips::S0;
5669 case Mips::F17:
return Mips::S1;
5670 case Mips::F18:
return Mips::S2;
5671 case Mips::F19:
return Mips::S3;
5672 case Mips::F20:
return Mips::S4;
5673 case Mips::F21:
return Mips::S5;
5674 case Mips::F22:
return Mips::S6;
5675 case Mips::F23:
return Mips::S7;
5676 case Mips::F24:
return Mips::T8;
5677 case Mips::F25:
return Mips::T9;
5678 case Mips::F26:
return Mips::K0;
5679 case Mips::F27:
return Mips::K1;
5680 case Mips::F28:
return Mips::GP;
5681 case Mips::F29:
return Mips::SP;
5682 case Mips::F30:
return Mips::FP;
5683 case Mips::F31:
return Mips::RA;
5691 case Mips::COP00:
return Mips::ZERO;
5692 case Mips::COP01:
return Mips::AT;
5693 case Mips::COP02:
return Mips::V0;
5694 case Mips::COP03:
return Mips::V1;
5695 case Mips::COP04:
return Mips::A0;
5696 case Mips::COP05:
return Mips::A1;
5697 case Mips::COP06:
return Mips::A2;
5698 case Mips::COP07:
return Mips::A3;
5699 case Mips::COP08:
return Mips::T0;
5700 case Mips::COP09:
return Mips::T1;
5701 case Mips::COP010:
return Mips::T2;
5702 case Mips::COP011:
return Mips::T3;
5703 case Mips::COP012:
return Mips::T4;
5704 case Mips::COP013:
return Mips::T5;
5705 case Mips::COP014:
return Mips::T6;
5706 case Mips::COP015:
return Mips::T7;
5707 case Mips::COP016:
return Mips::S0;
5708 case Mips::COP017:
return Mips::S1;
5709 case Mips::COP018:
return Mips::S2;
5710 case Mips::COP019:
return Mips::S3;
5711 case Mips::COP020:
return Mips::S4;
5712 case Mips::COP021:
return Mips::S5;
5713 case Mips::COP022:
return Mips::S6;
5714 case Mips::COP023:
return Mips::S7;
5715 case Mips::COP024:
return Mips::T8;
5716 case Mips::COP025:
return Mips::T9;
5717 case Mips::COP026:
return Mips::K0;
5718 case Mips::COP027:
return Mips::K1;
5719 case Mips::COP028:
return Mips::GP;
5720 case Mips::COP029:
return Mips::SP;
5721 case Mips::COP030:
return Mips::FP;
5722 case Mips::COP031:
return Mips::RA;
5736 bool IsMFTR =
false;
5792 : Inst.getOperand(0).
getReg());
5794 TOut.
emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, u, sel, h, IDLoc,
5805 warnIfNoMacro(IDLoc);
5808 unsigned Opcode = Inst.
getOpcode() == Mips::SaaAddr ? Mips::SAA : Mips::SAAD;
5813 if (BaseOp.
isImm()) {
5814 int64_t ImmValue = BaseOp.
getImm();
5815 if (ImmValue == 0) {
5816 TOut.
emitRR(Opcode, RtReg, BaseReg, IDLoc, STI);
5821 unsigned ATReg = getATReg(IDLoc);
5825 if (expandLoadAddress(ATReg, BaseReg, BaseOp, !isGP64bit(), IDLoc, Out, STI))
5828 TOut.
emitRR(Opcode, RtReg, ATReg, IDLoc, STI);
5833MipsAsmParser::checkEarlyTargetMatchPredicate(
MCInst &Inst,
5837 return Match_Success;
5840 if (
static_cast<MipsOperand &
>(*
Operands[1])
5841 .isValidForTie(
static_cast<MipsOperand &
>(*
Operands[2])))
5842 return Match_Success;
5843 return Match_RequiresSameSrcAndDst;
5847unsigned MipsAsmParser::checkTargetMatchPredicate(
MCInst &Inst) {
5854 return Match_RequiresNoZeroRegister;
5855 return Match_Success;
5861 case Mips::JALR_HB64:
5862 case Mips::JALRC_HB_MMR6:
5863 case Mips::JALRC_MMR6:
5865 return Match_RequiresDifferentSrcAndDst;
5866 return Match_Success;
5869 return Match_RequiresDifferentSrcAndDst;
5870 return Match_Success;
5873 return Match_NonZeroOperandForSync;
5874 return Match_Success;
5880 return Match_NonZeroOperandForMTCX;
5881 return Match_Success;
5894 case Mips::BLEZC:
case Mips::BLEZC_MMR6:
5895 case Mips::BGEZC:
case Mips::BGEZC_MMR6:
5896 case Mips::BGTZC:
case Mips::BGTZC_MMR6:
5897 case Mips::BLTZC:
case Mips::BLTZC_MMR6:
5898 case Mips::BEQZC:
case Mips::BEQZC_MMR6:
5899 case Mips::BNEZC:
case Mips::BNEZC_MMR6:
5908 return Match_RequiresNoZeroRegister;
5909 return Match_Success;
5910 case Mips::BGEC:
case Mips::BGEC_MMR6:
5911 case Mips::BLTC:
case Mips::BLTC_MMR6:
5912 case Mips::BGEUC:
case Mips::BGEUC_MMR6:
5913 case Mips::BLTUC:
case Mips::BLTUC_MMR6:
5914 case Mips::BEQC:
case Mips::BEQC_MMR6:
5915 case Mips::BNEC:
case Mips::BNEC_MMR6:
5924 return Match_RequiresNoZeroRegister;
5927 return Match_RequiresNoZeroRegister;
5929 return Match_RequiresDifferentOperands;
5930 return Match_Success;
5933 "Operands must be immediates for dins!");
5936 if ((0 > (Pos +
Size)) || ((Pos +
Size) > 32))
5937 return Match_RequiresPosSizeRange0_32;
5938 return Match_Success;
5943 "Operands must be immediates for dinsm/dinsu!");
5946 if ((32 >= (Pos +
Size)) || ((Pos +
Size) > 64))
5947 return Match_RequiresPosSizeRange33_64;
5948 return Match_Success;
5952 "Operands must be immediates for DEXTM!");
5955 if ((1 > (Pos +
Size)) || ((Pos +
Size) > 63))
5956 return Match_RequiresPosSizeUImm6;
5957 return Match_Success;
5962 "Operands must be immediates for dextm/dextu!");
5965 if ((32 > (Pos +
Size)) || ((Pos +
Size) > 64))
5966 return Match_RequiresPosSizeRange33_64;
5967 return Match_Success;
5969 case Mips::CRC32B:
case Mips::CRC32CB:
5970 case Mips::CRC32H:
case Mips::CRC32CH:
5971 case Mips::CRC32W:
case Mips::CRC32CW:
5972 case Mips::CRC32D:
case Mips::CRC32CD:
5974 return Match_RequiresSameSrcAndDst;
5975 return Match_Success;
5981 return Match_NoFCCRegisterForCurrentISA;
5983 return Match_Success;
5991 if (ErrorLoc ==
SMLoc())
5998bool MipsAsmParser::matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
6002 bool MatchingInlineAsm) {
6004 unsigned MatchResult =
6007 switch (MatchResult) {
6009 if (processInstruction(Inst, IDLoc, Out, STI))
6012 case Match_MissingFeature:
6013 Error(IDLoc,
"instruction requires a CPU feature not currently enabled");
6015 case Match_InvalidTiedOperand:
6016 Error(IDLoc,
"operand must match destination register");
6018 case Match_InvalidOperand: {
6019 SMLoc ErrorLoc = IDLoc;
6022 return Error(IDLoc,
"too few operands for instruction");
6025 if (ErrorLoc ==
SMLoc())
6029 return Error(ErrorLoc,
"invalid operand for instruction");
6031 case Match_NonZeroOperandForSync:
6033 "s-type must be zero or unspecified for pre-MIPS32 ISAs");
6034 case Match_NonZeroOperandForMTCX:
6035 return Error(IDLoc,
"selector must be zero for pre-MIPS32 ISAs");
6036 case Match_MnemonicFail:
6037 return Error(IDLoc,
"invalid instruction");
6038 case Match_RequiresDifferentSrcAndDst:
6039 return Error(IDLoc,
"source and destination must be different");
6040 case Match_RequiresDifferentOperands:
6041 return Error(IDLoc,
"registers must be different");
6042 case Match_RequiresNoZeroRegister:
6043 return Error(IDLoc,
"invalid operand ($zero) for instruction");
6044 case Match_RequiresSameSrcAndDst:
6045 return Error(IDLoc,
"source and destination must match");
6046 case Match_NoFCCRegisterForCurrentISA:
6048 "non-zero fcc register doesn't exist in current ISA level");
6053 "expected 1-bit unsigned immediate");
6056 "expected 2-bit unsigned immediate");
6059 "expected immediate in range 1 .. 4");
6062 "expected 3-bit unsigned immediate");
6065 "expected 4-bit unsigned immediate");
6068 "expected 4-bit signed immediate");
6071 "expected 5-bit unsigned immediate");
6074 "expected 5-bit signed immediate");
6077 "expected immediate in range 1 .. 32");
6078 case Match_UImm5_32:
6080 "expected immediate in range 32 .. 63");
6081 case Match_UImm5_33:
6083 "expected immediate in range 33 .. 64");
6084 case Match_UImm5_0_Report_UImm6:
6088 "expected 6-bit unsigned immediate");
6089 case Match_UImm5_Lsl2:
6091 "expected both 7-bit unsigned immediate and multiple of 4");
6092 case Match_UImmRange2_64:
6094 "expected immediate in range 2 .. 64");
6097 "expected 6-bit unsigned immediate");
6098 case Match_UImm6_Lsl2:
6100 "expected both 8-bit unsigned immediate and multiple of 4");
6103 "expected 6-bit signed immediate");
6106 "expected 7-bit unsigned immediate");
6107 case Match_UImm7_N1:
6109 "expected immediate in range -1 .. 126");
6110 case Match_SImm7_Lsl2:
6112 "expected both 9-bit signed immediate and multiple of 4");
6115 "expected 8-bit unsigned immediate");
6116 case Match_UImm10_0:
6118 "expected 10-bit unsigned immediate");
6119 case Match_SImm10_0:
6121 "expected 10-bit signed immediate");
6122 case Match_SImm11_0:
6124 "expected 11-bit signed immediate");
6126 case Match_UImm16_Relaxed:
6127 case Match_UImm16_AltRelaxed:
6129 "expected 16-bit unsigned immediate");
6131 case Match_SImm16_Relaxed:
6133 "expected 16-bit signed immediate");
6134 case Match_SImm19_Lsl2:
6136 "expected both 19-bit signed immediate and multiple of 4");
6137 case Match_UImm20_0:
6139 "expected 20-bit unsigned immediate");
6140 case Match_UImm26_0:
6142 "expected 26-bit unsigned immediate");
6144 case Match_SImm32_Relaxed:
6146 "expected 32-bit signed immediate");
6147 case Match_UImm32_Coerced:
6149 "expected 32-bit immediate");
6150 case Match_MemSImm9:
6152 "expected memory with 9-bit signed offset");
6153 case Match_MemSImm10:
6155 "expected memory with 10-bit signed offset");
6156 case Match_MemSImm10Lsl1:
6158 "expected memory with 11-bit signed offset and multiple of 2");
6159 case Match_MemSImm10Lsl2:
6161 "expected memory with 12-bit signed offset and multiple of 4");
6162 case Match_MemSImm10Lsl3:
6164 "expected memory with 13-bit signed offset and multiple of 8");
6165 case Match_MemSImm11:
6167 "expected memory with 11-bit signed offset");
6168 case Match_MemSImm12:
6170 "expected memory with 12-bit signed offset");
6171 case Match_MemSImm16:
6173 "expected memory with 16-bit signed offset");
6174 case Match_MemSImmPtr:
6176 "expected memory with 32-bit signed offset");
6177 case Match_RequiresPosSizeRange0_32: {
6180 return Error(ErrorStart,
"size plus position are not in the range 0 .. 32",
6181 SMRange(ErrorStart, ErrorEnd));
6183 case Match_RequiresPosSizeUImm6: {
6186 return Error(ErrorStart,
"size plus position are not in the range 1 .. 63",
6187 SMRange(ErrorStart, ErrorEnd));
6189 case Match_RequiresPosSizeRange33_64: {
6192 return Error(ErrorStart,
"size plus position are not in the range 33 .. 64",
6193 SMRange(ErrorStart, ErrorEnd));
6200void MipsAsmParser::warnIfRegIndexIsAT(
unsigned RegIndex,
SMLoc Loc) {
6201 if (RegIndex != 0 && AssemblerOptions.
back()->getATRegIndex() == RegIndex)
6202 Warning(Loc,
"used $at (currently $" +
Twine(RegIndex) +
6203 ") without \".set noat\"");
6206void MipsAsmParser::warnIfNoMacro(
SMLoc Loc) {
6207 if (!AssemblerOptions.
back()->isMacro())
6208 Warning(Loc,
"macro instruction expanded into multiple instructions");
6211void MipsAsmParser::ConvertXWPOperands(
MCInst &Inst,
6215 "Unexpected instruction!");
6216 ((MipsOperand &)*
Operands[1]).addGPR32ZeroAsmRegOperands(Inst, 1);
6219 ((MipsOperand &)*
Operands[2]).addMemOperands(Inst, 2);
6223MipsAsmParser::printWarningWithFixIt(
const Twine &Msg,
const Twine &FixMsg,
6235 .
Cases(
"at",
"AT", 1)
6269 if (!(isABI_N32() || isABI_N64()))
6272 if (12 <=
CC &&
CC <= 15) {
6274 AsmToken RegTok = getLexer().peekTok();
6283 assert(FixedName !=
"" &&
"Register name is not one of t4-t7.");
6285 printWarningWithFixIt(
"register names $t4-$t7 are only available in O32.",
6286 "Did you mean $" + FixedName +
"?", RegRange);
6292 if (8 <=
CC &&
CC <= 11)
6312 .
Case(
"hwr_cpunum", 0)
6313 .
Case(
"hwr_synci_step", 1)
6315 .
Case(
"hwr_ccres", 3)
6316 .
Case(
"hwr_ulr", 29)
6323 if (
Name[0] ==
'f') {
6336 if (
Name.starts_with(
"fcc")) {
6349 if (
Name.starts_with(
"ac")) {
6364 if (
Name.front() !=
'w' ||
Name.drop_front(1).getAsInteger(10, IntVal))
6373int MipsAsmParser::matchMSA128CtrlRegisterName(
StringRef Name) {
6379 .
Case(
"msaaccess", 2)
6381 .
Case(
"msamodify", 4)
6382 .
Case(
"msarequest", 5)
6384 .
Case(
"msaunmap", 7)
6390bool MipsAsmParser::canUseATReg() {
6391 return AssemblerOptions.
back()->getATRegIndex() != 0;
6394unsigned MipsAsmParser::getATReg(
SMLoc Loc) {
6395 unsigned ATIndex = AssemblerOptions.
back()->getATRegIndex();
6397 reportParseError(Loc,
6398 "pseudo-instruction requires $at, which is not available");
6402 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
6406unsigned MipsAsmParser::getReg(
int RC,
int RegNo) {
6407 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
6432 switch (getLexer().getKind()) {
6442 if (!parseAnyRegister(
Operands).isNoMatch())
6451 MCSymbol *
Sym = getContext().getOrCreateSymbol(Identifier);
6456 Operands.push_back(MipsOperand::CreateImm(SymRef, S,
E, *
this));
6464 if (getParser().parseExpression(Expr))
6469 Operands.push_back(MipsOperand::CreateImm(Expr, S,
E, *
this));
6478 return !tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess();
6487 MipsOperand &Operand =
static_cast<MipsOperand &
>(*
Operands.front());
6488 StartLoc = Operand.getStartLoc();
6489 EndLoc = Operand.getEndLoc();
6495 if (Operand.isGPRAsmReg()) {
6497 Reg = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
6507bool MipsAsmParser::parseMemOffset(
const MCExpr *&Res,
bool isParenExpr) {
6511 return getParser().parseParenExprOfDepth(0, Res, S);
6512 return getParser().parseExpression(Res);
6518 const MCExpr *IdVal =
nullptr;
6520 bool isParenExpr =
false;
6531 if (parseMemOffset(IdVal, isParenExpr))
6536 MipsOperand &Mnemonic =
static_cast<MipsOperand &
>(*
Operands[0]);
6537 if (Mnemonic.getToken() ==
"la" || Mnemonic.getToken() ==
"dla") {
6540 Operands.push_back(MipsOperand::CreateImm(IdVal, S,
E, *
this));
6549 auto Base = MipsOperand::createGPRReg(
6550 0,
"0", getContext().getRegisterInfo(), S,
E, *
this);
6552 MipsOperand::CreateMem(std::move(
Base), IdVal, S,
E, *
this));
6605 if (getParser().parseExpression(NextExpr))
6628 std::unique_ptr<MipsOperand>
op(
6629 static_cast<MipsOperand *
>(
Operands.back().release()));
6634 if (
const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
6636 if (IdVal->evaluateAsAbsolute(Imm))
6643 Operands.push_back(MipsOperand::CreateMem(std::move(
op), IdVal, S,
E, *
this));
6654 if (
Sym->isVariable()) {
6655 const MCExpr *Expr =
Sym->getVariableValue();
6661 matchAnyRegisterNameWithoutDollar(
Operands, DefSymbol.
substr(1), S);
6670 }
else if (
Sym->isUnset()) {
6675 if (Entry != RegisterSets.
end()) {
6677 matchAnyRegisterWithoutDollar(
Operands,
Entry->getValue(), S);
6688ParseStatus MipsAsmParser::matchAnyRegisterNameWithoutDollar(
6690 int Index = matchCPURegisterName(Identifier);
6692 Operands.push_back(MipsOperand::createGPRReg(
6693 Index, Identifier, getContext().getRegisterInfo(), S,
6694 getLexer().getLoc(), *
this));
6698 Index = matchHWRegsRegisterName(Identifier);
6700 Operands.push_back(MipsOperand::createHWRegsReg(
6701 Index, Identifier, getContext().getRegisterInfo(), S,
6702 getLexer().getLoc(), *
this));
6706 Index = matchFPURegisterName(Identifier);
6708 Operands.push_back(MipsOperand::createFGRReg(
6709 Index, Identifier, getContext().getRegisterInfo(), S,
6710 getLexer().getLoc(), *
this));
6714 Index = matchFCCRegisterName(Identifier);
6716 Operands.push_back(MipsOperand::createFCCReg(
6717 Index, Identifier, getContext().getRegisterInfo(), S,
6718 getLexer().getLoc(), *
this));
6722 Index = matchACRegisterName(Identifier);
6724 Operands.push_back(MipsOperand::createACCReg(
6725 Index, Identifier, getContext().getRegisterInfo(), S,
6726 getLexer().getLoc(), *
this));
6730 Index = matchMSA128RegisterName(Identifier);
6732 Operands.push_back(MipsOperand::createMSA128Reg(
6733 Index, Identifier, getContext().getRegisterInfo(), S,
6734 getLexer().getLoc(), *
this));
6738 Index = matchMSA128CtrlRegisterName(Identifier);
6740 Operands.push_back(MipsOperand::createMSACtrlReg(
6741 Index, Identifier, getContext().getRegisterInfo(), S,
6742 getLexer().getLoc(), *
this));
6755 return matchAnyRegisterNameWithoutDollar(
Operands, Identifier, S);
6760 if (RegNum < 0 || RegNum > 31) {
6764 Error(getLexer().getLoc(),
"invalid register number");
6766 Operands.push_back(MipsOperand::createNumericReg(
6767 RegNum, Token.
getString(), getContext().getRegisterInfo(), S,
6779 auto Token = getLexer().peekTok(
false);
6780 return matchAnyRegisterWithoutDollar(
Operands, Token, S);
6787 auto Token = Parser.
getTok();
6814 SMLoc S = getLexer().getLoc();
6822 const MCExpr *Expr =
nullptr;
6828 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *
this));
6845 if (getParser().parseExpression(IdVal))
6852 Operands.push_back(MipsOperand::CreateImm(
6861 unsigned PrevReg = Mips::NoRegister;
6862 bool RegRange =
false;
6869 while (parseAnyRegister(TmpOperands).isSuccess()) {
6870 SMLoc E = getLexer().getLoc();
6871 MipsOperand &
Reg =
static_cast<MipsOperand &
>(*TmpOperands.
back());
6872 RegNo = isGP64bit() ?
Reg.getGPR64Reg() :
Reg.getGPR32Reg();
6876 if ((isGP64bit() && RegNo == Mips::RA_64) ||
6877 (!isGP64bit() && RegNo == Mips::RA)) {
6880 unsigned TmpReg = PrevReg + 1;
6881 while (TmpReg <= RegNo) {
6882 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
6883 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
6885 return Error(
E,
"invalid register operand");
6894 if ((PrevReg == Mips::NoRegister) &&
6895 ((isGP64bit() && (RegNo != Mips::S0_64) && (RegNo != Mips::RA_64)) ||
6896 (!isGP64bit() && (RegNo != Mips::S0) && (RegNo != Mips::RA))))
6897 return Error(
E,
"$16 or $31 expected");
6898 if (!(((RegNo == Mips::FP || RegNo == Mips::RA ||
6899 (RegNo >= Mips::S0 && RegNo <= Mips::S7)) &&
6901 ((RegNo == Mips::FP_64 || RegNo == Mips::RA_64 ||
6902 (RegNo >= Mips::S0_64 && RegNo <= Mips::S7_64)) &&
6904 return Error(
E,
"invalid register operand");
6905 if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
6906 ((RegNo != Mips::FP && RegNo != Mips::RA && !isGP64bit()) ||
6907 (RegNo != Mips::FP_64 && RegNo != Mips::RA_64 && isGP64bit())))
6908 return Error(
E,
"consecutive register numbers expected");
6918 return Error(
E,
"',' or '-' expected");
6928 Operands.push_back(MipsOperand::CreateRegList(Regs, S,
E, *
this));
6942 MipsOperand::CreateToken(
"(", getLexer().getLoc(), *
this));
6945 SMLoc Loc = getLexer().getLoc();
6946 return Error(Loc,
"unexpected token in argument list");
6949 SMLoc Loc = getLexer().getLoc();
6950 return Error(Loc,
"unexpected token, expected ')'");
6953 MipsOperand::CreateToken(
")", getLexer().getLoc(), *
this));
6970 MipsOperand::CreateToken(
"[", getLexer().getLoc(), *
this));
6973 SMLoc Loc = getLexer().getLoc();
6974 return Error(Loc,
"unexpected token in argument list");
6977 SMLoc Loc = getLexer().getLoc();
6978 return Error(Loc,
"unexpected token, expected ']'");
6981 MipsOperand::CreateToken(
"]", getLexer().getLoc(), *
this));
6988 unsigned VariantID = 0);
7009 getTargetStreamer().forbidModuleDirective();
7012 if (!mnemonicIsValid(
Name, 0)) {
7013 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
7015 return Error(NameLoc,
"unknown instruction" + Suggestion);
7018 Operands.push_back(MipsOperand::CreateToken(
Name, NameLoc, *
this));
7024 SMLoc Loc = getLexer().getLoc();
7025 return Error(Loc,
"unexpected token in argument list");
7035 SMLoc Loc = getLexer().getLoc();
7036 return Error(Loc,
"unexpected token in argument list");
7048 SMLoc Loc = getLexer().getLoc();
7049 return Error(Loc,
"unexpected token in argument list");
7057bool MipsAsmParser::reportParseError(
const Twine &ErrorMsg) {
7058 SMLoc Loc = getLexer().getLoc();
7059 return Error(Loc, ErrorMsg);
7062bool MipsAsmParser::reportParseError(
SMLoc Loc,
const Twine &ErrorMsg) {
7063 return Error(Loc, ErrorMsg);
7066bool MipsAsmParser::parseSetNoAtDirective() {
7071 AssemblerOptions.
back()->setATRegIndex(0);
7077 reportParseError(
"unexpected token, expected end of statement");
7081 getTargetStreamer().emitDirectiveSetNoAt();
7086bool MipsAsmParser::parseSetAtDirective() {
7094 AssemblerOptions.
back()->setATRegIndex(1);
7096 getTargetStreamer().emitDirectiveSetAt();
7102 reportParseError(
"unexpected token, expected equals sign");
7109 reportParseError(
"no register specified");
7112 reportParseError(
"unexpected token, expected dollar sign '$'");
7122 AtRegNo = matchCPURegisterName(
Reg.getIdentifier());
7124 AtRegNo =
Reg.getIntVal();
7126 reportParseError(
"unexpected token, expected identifier or integer");
7131 if (!AssemblerOptions.
back()->setATRegIndex(AtRegNo)) {
7132 reportParseError(
"invalid register");
7139 reportParseError(
"unexpected token, expected end of statement");
7143 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
7149bool MipsAsmParser::parseSetReorderDirective() {
7154 reportParseError(
"unexpected token, expected end of statement");
7157 AssemblerOptions.
back()->setReorder();
7158 getTargetStreamer().emitDirectiveSetReorder();
7163bool MipsAsmParser::parseSetNoReorderDirective() {
7168 reportParseError(
"unexpected token, expected end of statement");
7171 AssemblerOptions.
back()->setNoReorder();
7172 getTargetStreamer().emitDirectiveSetNoReorder();
7177bool MipsAsmParser::parseSetMacroDirective() {
7182 reportParseError(
"unexpected token, expected end of statement");
7185 AssemblerOptions.
back()->setMacro();
7186 getTargetStreamer().emitDirectiveSetMacro();
7191bool MipsAsmParser::parseSetNoMacroDirective() {
7196 reportParseError(
"unexpected token, expected end of statement");
7199 if (AssemblerOptions.
back()->isReorder()) {
7200 reportParseError(
"`noreorder' must be set before `nomacro'");
7203 AssemblerOptions.
back()->setNoMacro();
7204 getTargetStreamer().emitDirectiveSetNoMacro();
7209bool MipsAsmParser::parseSetMsaDirective() {
7215 return reportParseError(
"unexpected token, expected end of statement");
7217 setFeatureBits(Mips::FeatureMSA,
"msa");
7218 getTargetStreamer().emitDirectiveSetMsa();
7222bool MipsAsmParser::parseSetNoMsaDirective() {
7228 return reportParseError(
"unexpected token, expected end of statement");
7230 clearFeatureBits(Mips::FeatureMSA,
"msa");
7231 getTargetStreamer().emitDirectiveSetNoMsa();
7235bool MipsAsmParser::parseSetNoDspDirective() {
7241 reportParseError(
"unexpected token, expected end of statement");
7245 clearFeatureBits(Mips::FeatureDSP,
"dsp");
7246 getTargetStreamer().emitDirectiveSetNoDsp();
7250bool MipsAsmParser::parseSetNoMips3DDirective() {
7256 reportParseError(
"unexpected token, expected end of statement");
7260 clearFeatureBits(Mips::FeatureMips3D,
"mips3d");
7261 getTargetStreamer().emitDirectiveSetNoMips3D();
7265bool MipsAsmParser::parseSetMips16Directive() {
7271 reportParseError(
"unexpected token, expected end of statement");
7275 setFeatureBits(Mips::FeatureMips16,
"mips16");
7276 getTargetStreamer().emitDirectiveSetMips16();
7281bool MipsAsmParser::parseSetNoMips16Directive() {
7287 reportParseError(
"unexpected token, expected end of statement");
7291 clearFeatureBits(Mips::FeatureMips16,
"mips16");
7292 getTargetStreamer().emitDirectiveSetNoMips16();
7297bool MipsAsmParser::parseSetFpDirective() {
7306 reportParseError(
"unexpected token, expected equals sign '='");
7312 if (!parseFpABIValue(FpAbiVal,
".set"))
7316 reportParseError(
"unexpected token, expected end of statement");
7319 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
7324bool MipsAsmParser::parseSetOddSPRegDirective() {
7329 reportParseError(
"unexpected token, expected end of statement");
7333 clearFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
7334 getTargetStreamer().emitDirectiveSetOddSPReg();
7338bool MipsAsmParser::parseSetNoOddSPRegDirective() {
7343 reportParseError(
"unexpected token, expected end of statement");
7347 setFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
7348 getTargetStreamer().emitDirectiveSetNoOddSPReg();
7352bool MipsAsmParser::parseSetMtDirective() {
7358 reportParseError(
"unexpected token, expected end of statement");
7362 setFeatureBits(Mips::FeatureMT,
"mt");
7363 getTargetStreamer().emitDirectiveSetMt();
7368bool MipsAsmParser::parseSetNoMtDirective() {
7374 reportParseError(
"unexpected token, expected end of statement");
7378 clearFeatureBits(Mips::FeatureMT,
"mt");
7380 getTargetStreamer().emitDirectiveSetNoMt();
7385bool MipsAsmParser::parseSetNoCRCDirective() {
7391 reportParseError(
"unexpected token, expected end of statement");
7395 clearFeatureBits(Mips::FeatureCRC,
"crc");
7397 getTargetStreamer().emitDirectiveSetNoCRC();
7402bool MipsAsmParser::parseSetNoVirtDirective() {
7408 reportParseError(
"unexpected token, expected end of statement");
7412 clearFeatureBits(Mips::FeatureVirt,
"virt");
7414 getTargetStreamer().emitDirectiveSetNoVirt();
7419bool MipsAsmParser::parseSetNoGINVDirective() {
7425 reportParseError(
"unexpected token, expected end of statement");
7429 clearFeatureBits(Mips::FeatureGINV,
"ginv");
7431 getTargetStreamer().emitDirectiveSetNoGINV();
7436bool MipsAsmParser::parseSetPopDirective() {
7438 SMLoc Loc = getLexer().getLoc();
7442 return reportParseError(
"unexpected token, expected end of statement");
7446 if (AssemblerOptions.
size() == 2)
7447 return reportParseError(Loc,
".set pop with no .set push");
7451 setAvailableFeatures(
7452 ComputeAvailableFeatures(AssemblerOptions.
back()->getFeatures()));
7455 getTargetStreamer().emitDirectiveSetPop();
7459bool MipsAsmParser::parseSetPushDirective() {
7463 return reportParseError(
"unexpected token, expected end of statement");
7467 std::make_unique<MipsAssemblerOptions>(AssemblerOptions.
back().get()));
7469 getTargetStreamer().emitDirectiveSetPush();
7473bool MipsAsmParser::parseSetSoftFloatDirective() {
7477 return reportParseError(
"unexpected token, expected end of statement");
7479 setFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
7480 getTargetStreamer().emitDirectiveSetSoftFloat();
7484bool MipsAsmParser::parseSetHardFloatDirective() {
7488 return reportParseError(
"unexpected token, expected end of statement");
7490 clearFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
7491 getTargetStreamer().emitDirectiveSetHardFloat();
7495bool MipsAsmParser::parseSetAssignment() {
7500 return reportParseError(
"expected identifier after .set");
7503 return reportParseError(
"unexpected token, expected comma");
7513 getContext().getOrCreateSymbol(
Name);
7527bool MipsAsmParser::parseSetMips0Directive() {
7531 return reportParseError(
"unexpected token, expected end of statement");
7535 setAvailableFeatures(
7536 ComputeAvailableFeatures(AssemblerOptions.
front()->getFeatures()));
7538 AssemblerOptions.
back()->setFeatures(AssemblerOptions.
front()->getFeatures());
7540 getTargetStreamer().emitDirectiveSetMips0();
7544bool MipsAsmParser::parseSetArchDirective() {
7548 return reportParseError(
"unexpected token, expected equals sign");
7551 StringRef Arch = getParser().parseStringToEndOfStatement().
trim();
7553 return reportParseError(
"expected arch identifier");
7557 .
Case(
"mips1",
"mips1")
7558 .
Case(
"mips2",
"mips2")
7559 .
Case(
"mips3",
"mips3")
7560 .
Case(
"mips4",
"mips4")
7561 .
Case(
"mips5",
"mips5")
7562 .
Case(
"mips32",
"mips32")
7563 .
Case(
"mips32r2",
"mips32r2")
7564 .
Case(
"mips32r3",
"mips32r3")
7565 .
Case(
"mips32r5",
"mips32r5")
7566 .
Case(
"mips32r6",
"mips32r6")
7567 .
Case(
"mips64",
"mips64")
7568 .
Case(
"mips64r2",
"mips64r2")
7569 .
Case(
"mips64r3",
"mips64r3")
7570 .
Case(
"mips64r5",
"mips64r5")
7571 .
Case(
"mips64r6",
"mips64r6")
7572 .
Case(
"octeon",
"cnmips")
7573 .
Case(
"octeon+",
"cnmipsp")
7574 .
Case(
"r4000",
"mips3")
7577 if (ArchFeatureName.
empty())
7578 return reportParseError(
"unsupported architecture");
7580 if (ArchFeatureName ==
"mips64r6" && inMicroMipsMode())
7581 return reportParseError(
"mips64r6 does not support microMIPS");
7583 selectArch(ArchFeatureName);
7584 getTargetStreamer().emitDirectiveSetArch(Arch);
7588bool MipsAsmParser::parseSetFeature(
uint64_t Feature) {
7592 return reportParseError(
"unexpected token, expected end of statement");
7597 case Mips::FeatureMips3D:
7598 setFeatureBits(Mips::FeatureMips3D,
"mips3d");
7599 getTargetStreamer().emitDirectiveSetMips3D();
7601 case Mips::FeatureDSP:
7602 setFeatureBits(Mips::FeatureDSP,
"dsp");
7603 getTargetStreamer().emitDirectiveSetDsp();
7605 case Mips::FeatureDSPR2:
7606 setFeatureBits(Mips::FeatureDSPR2,
"dspr2");
7607 getTargetStreamer().emitDirectiveSetDspr2();
7609 case Mips::FeatureMicroMips:
7610 setFeatureBits(Mips::FeatureMicroMips,
"micromips");
7611 getTargetStreamer().emitDirectiveSetMicroMips();
7613 case Mips::FeatureMips1:
7614 selectArch(
"mips1");
7615 getTargetStreamer().emitDirectiveSetMips1();
7617 case Mips::FeatureMips2:
7618 selectArch(
"mips2");
7619 getTargetStreamer().emitDirectiveSetMips2();
7621 case Mips::FeatureMips3:
7622 selectArch(
"mips3");
7623 getTargetStreamer().emitDirectiveSetMips3();
7625 case Mips::FeatureMips4:
7626 selectArch(
"mips4");
7627 getTargetStreamer().emitDirectiveSetMips4();
7629 case Mips::FeatureMips5:
7630 selectArch(
"mips5");
7631 getTargetStreamer().emitDirectiveSetMips5();
7633 case Mips::FeatureMips32:
7634 selectArch(
"mips32");
7635 getTargetStreamer().emitDirectiveSetMips32();
7637 case Mips::FeatureMips32r2:
7638 selectArch(
"mips32r2");
7639 getTargetStreamer().emitDirectiveSetMips32R2();
7641 case Mips::FeatureMips32r3:
7642 selectArch(
"mips32r3");
7643 getTargetStreamer().emitDirectiveSetMips32R3();
7645 case Mips::FeatureMips32r5:
7646 selectArch(
"mips32r5");
7647 getTargetStreamer().emitDirectiveSetMips32R5();
7649 case Mips::FeatureMips32r6:
7650 selectArch(
"mips32r6");
7651 getTargetStreamer().emitDirectiveSetMips32R6();
7653 case Mips::FeatureMips64:
7654 selectArch(
"mips64");
7655 getTargetStreamer().emitDirectiveSetMips64();
7657 case Mips::FeatureMips64r2:
7658 selectArch(
"mips64r2");
7659 getTargetStreamer().emitDirectiveSetMips64R2();
7661 case Mips::FeatureMips64r3:
7662 selectArch(
"mips64r3");
7663 getTargetStreamer().emitDirectiveSetMips64R3();
7665 case Mips::FeatureMips64r5:
7666 selectArch(
"mips64r5");
7667 getTargetStreamer().emitDirectiveSetMips64R5();
7669 case Mips::FeatureMips64r6:
7670 selectArch(
"mips64r6");
7671 getTargetStreamer().emitDirectiveSetMips64R6();
7673 case Mips::FeatureCRC:
7674 setFeatureBits(Mips::FeatureCRC,
"crc");
7675 getTargetStreamer().emitDirectiveSetCRC();
7677 case Mips::FeatureVirt:
7678 setFeatureBits(Mips::FeatureVirt,
"virt");
7679 getTargetStreamer().emitDirectiveSetVirt();
7681 case Mips::FeatureGINV:
7682 setFeatureBits(Mips::FeatureGINV,
"ginv");
7683 getTargetStreamer().emitDirectiveSetGINV();
7689bool MipsAsmParser::eatComma(
StringRef ErrorStr) {
7692 SMLoc Loc = getLexer().getLoc();
7693 return Error(Loc, ErrorStr);
7704bool MipsAsmParser::isPicAndNotNxxAbi() {
7705 return inPicMode() && !(isABI_N32() || isABI_N64());
7708bool MipsAsmParser::parseDirectiveCpAdd(
SMLoc Loc) {
7712 reportParseError(
"expected register");
7716 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7717 if (!RegOpnd.isGPRAsmReg()) {
7718 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7724 reportParseError(
"unexpected token, expected end of statement");
7729 getTargetStreamer().emitDirectiveCpAdd(RegOpnd.getGPR32Reg());
7733bool MipsAsmParser::parseDirectiveCpLoad(
SMLoc Loc) {
7734 if (AssemblerOptions.
back()->isReorder())
7735 Warning(Loc,
".cpload should be inside a noreorder section");
7737 if (inMips16Mode()) {
7738 reportParseError(
".cpload is not supported in Mips16 mode");
7745 reportParseError(
"expected register containing function address");
7749 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7750 if (!RegOpnd.isGPRAsmReg()) {
7751 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7757 reportParseError(
"unexpected token, expected end of statement");
7761 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
7765bool MipsAsmParser::parseDirectiveCpLocal(
SMLoc Loc) {
7766 if (!isABI_N32() && !isABI_N64()) {
7767 reportParseError(
".cplocal is allowed only in N32 or N64 mode");
7774 reportParseError(
"expected register containing global pointer");
7778 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7779 if (!RegOpnd.isGPRAsmReg()) {
7780 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7786 reportParseError(
"unexpected token, expected end of statement");
7791 unsigned NewReg = RegOpnd.getGPR32Reg();
7795 getTargetStreamer().emitDirectiveCpLocal(NewReg);
7799bool MipsAsmParser::parseDirectiveCpRestore(
SMLoc Loc) {
7805 if (inMips16Mode()) {
7806 reportParseError(
".cprestore is not supported in Mips16 mode");
7812 int64_t StackOffsetVal;
7814 reportParseError(
"expected stack offset value");
7818 if (!
StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
7819 reportParseError(
"stack offset is not an absolute expression");
7823 if (StackOffsetVal < 0) {
7824 Warning(Loc,
".cprestore with negative stack offset has no effect");
7825 IsCpRestoreSet =
false;
7827 IsCpRestoreSet =
true;
7828 CpRestoreOffset = StackOffsetVal;
7833 reportParseError(
"unexpected token, expected end of statement");
7837 if (!getTargetStreamer().emitDirectiveCpRestore(
7838 CpRestoreOffset, [&]() {
return getATReg(Loc); }, Loc, STI))
7844bool MipsAsmParser::parseDirectiveCPSetup() {
7848 bool SaveIsReg =
true;
7853 reportParseError(
"expected register containing function address");
7857 MipsOperand &FuncRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7858 if (!FuncRegOpnd.isGPRAsmReg()) {
7859 reportParseError(FuncRegOpnd.getStartLoc(),
"invalid register");
7863 FuncReg = FuncRegOpnd.getGPR32Reg();
7866 if (!eatComma(
"unexpected token, expected comma"))
7869 Res = parseAnyRegister(TmpReg);
7871 const MCExpr *OffsetExpr;
7873 SMLoc ExprLoc = getLexer().getLoc();
7876 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
7877 reportParseError(ExprLoc,
"expected save register or stack offset");
7884 MipsOperand &SaveOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7885 if (!SaveOpnd.isGPRAsmReg()) {
7886 reportParseError(SaveOpnd.getStartLoc(),
"invalid register");
7889 Save = SaveOpnd.getGPR32Reg();
7892 if (!eatComma(
"unexpected token, expected comma"))
7897 reportParseError(
"expected expression");
7902 reportParseError(
"expected symbol");
7907 CpSaveLocation = Save;
7908 CpSaveLocationIsRegister = SaveIsReg;
7910 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save,
Ref->getSymbol(),
7915bool MipsAsmParser::parseDirectiveCPReturn() {
7916 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
7917 CpSaveLocationIsRegister);
7921bool MipsAsmParser::parseDirectiveNaN() {
7928 getTargetStreamer().emitDirectiveNaN2008();
7930 }
else if (Tok.
getString() ==
"legacy") {
7932 getTargetStreamer().emitDirectiveNaNLegacy();
7938 reportParseError(
"invalid option in .nan directive");
7942bool MipsAsmParser::parseDirectiveSet() {
7943 const AsmToken &Tok = getParser().getTok();
7947 if (IdVal ==
"noat")
7948 return parseSetNoAtDirective();
7950 return parseSetAtDirective();
7951 if (IdVal ==
"arch")
7952 return parseSetArchDirective();
7953 if (IdVal ==
"bopt") {
7954 Warning(Loc,
"'bopt' feature is unsupported");
7958 if (IdVal ==
"nobopt") {
7964 return parseSetFpDirective();
7965 if (IdVal ==
"oddspreg")
7966 return parseSetOddSPRegDirective();
7967 if (IdVal ==
"nooddspreg")
7968 return parseSetNoOddSPRegDirective();
7970 return parseSetPopDirective();
7971 if (IdVal ==
"push")
7972 return parseSetPushDirective();
7973 if (IdVal ==
"reorder")
7974 return parseSetReorderDirective();
7975 if (IdVal ==
"noreorder")
7976 return parseSetNoReorderDirective();
7977 if (IdVal ==
"macro")
7978 return parseSetMacroDirective();
7979 if (IdVal ==
"nomacro")
7980 return parseSetNoMacroDirective();
7981 if (IdVal ==
"mips16")
7982 return parseSetMips16Directive();
7983 if (IdVal ==
"nomips16")
7984 return parseSetNoMips16Directive();
7985 if (IdVal ==
"nomicromips") {
7986 clearFeatureBits(Mips::FeatureMicroMips,
"micromips");
7987 getTargetStreamer().emitDirectiveSetNoMicroMips();
7988 getParser().eatToEndOfStatement();
7991 if (IdVal ==
"micromips") {
7992 if (hasMips64r6()) {
7993 Error(Loc,
".set micromips directive is not supported with MIPS64R6");
7996 return parseSetFeature(Mips::FeatureMicroMips);
7998 if (IdVal ==
"mips0")
7999 return parseSetMips0Directive();
8000 if (IdVal ==
"mips1")
8001 return parseSetFeature(Mips::FeatureMips1);
8002 if (IdVal ==
"mips2")
8003 return parseSetFeature(Mips::FeatureMips2);
8004 if (IdVal ==
"mips3")
8005 return parseSetFeature(Mips::FeatureMips3);
8006 if (IdVal ==
"mips4")
8007 return parseSetFeature(Mips::FeatureMips4);
8008 if (IdVal ==
"mips5")
8009 return parseSetFeature(Mips::FeatureMips5);
8010 if (IdVal ==
"mips32")
8011 return parseSetFeature(Mips::FeatureMips32);
8012 if (IdVal ==
"mips32r2")
8013 return parseSetFeature(Mips::FeatureMips32r2);
8014 if (IdVal ==
"mips32r3")
8015 return parseSetFeature(Mips::FeatureMips32r3);
8016 if (IdVal ==
"mips32r5")
8017 return parseSetFeature(Mips::FeatureMips32r5);
8018 if (IdVal ==
"mips32r6")
8019 return parseSetFeature(Mips::FeatureMips32r6);
8020 if (IdVal ==
"mips64")
8021 return parseSetFeature(Mips::FeatureMips64);
8022 if (IdVal ==
"mips64r2")
8023 return parseSetFeature(Mips::FeatureMips64r2);
8024 if (IdVal ==
"mips64r3")
8025 return parseSetFeature(Mips::FeatureMips64r3);
8026 if (IdVal ==
"mips64r5")
8027 return parseSetFeature(Mips::FeatureMips64r5);
8028 if (IdVal ==
"mips64r6") {
8029 if (inMicroMipsMode()) {
8030 Error(Loc,
"MIPS64R6 is not supported with microMIPS");
8033 return parseSetFeature(Mips::FeatureMips64r6);
8036 return parseSetFeature(Mips::FeatureDSP);
8037 if (IdVal ==
"dspr2")
8038 return parseSetFeature(Mips::FeatureDSPR2);
8039 if (IdVal ==
"nodsp")
8040 return parseSetNoDspDirective();
8041 if (IdVal ==
"mips3d")
8042 return parseSetFeature(Mips::FeatureMips3D);
8043 if (IdVal ==
"nomips3d")
8044 return parseSetNoMips3DDirective();
8046 return parseSetMsaDirective();
8047 if (IdVal ==
"nomsa")
8048 return parseSetNoMsaDirective();
8050 return parseSetMtDirective();
8051 if (IdVal ==
"nomt")
8052 return parseSetNoMtDirective();
8053 if (IdVal ==
"softfloat")
8054 return parseSetSoftFloatDirective();
8055 if (IdVal ==
"hardfloat")
8056 return parseSetHardFloatDirective();
8058 return parseSetFeature(Mips::FeatureCRC);
8059 if (IdVal ==
"nocrc")
8060 return parseSetNoCRCDirective();
8061 if (IdVal ==
"virt")
8062 return parseSetFeature(Mips::FeatureVirt);
8063 if (IdVal ==
"novirt")
8064 return parseSetNoVirtDirective();
8065 if (IdVal ==
"ginv")
8066 return parseSetFeature(Mips::FeatureGINV);
8067 if (IdVal ==
"noginv")
8068 return parseSetNoGINVDirective();
8071 return parseSetAssignment();
8076bool MipsAsmParser::parseDirectiveGpWord() {
8081 if (getParser().parseExpression(
Value))
8083 getParser().getStreamer().emitGPRel32Value(
Value);
8086 return Error(getLexer().getLoc(),
8087 "unexpected token, expected end of statement");
8094bool MipsAsmParser::parseDirectiveGpDWord() {
8099 if (getParser().parseExpression(
Value))
8101 getParser().getStreamer().emitGPRel64Value(
Value);
8104 return Error(getLexer().getLoc(),
8105 "unexpected token, expected end of statement");
8112bool MipsAsmParser::parseDirectiveDtpRelWord() {
8117 if (getParser().parseExpression(
Value))
8119 getParser().getStreamer().emitDTPRel32Value(
Value);
8122 return Error(getLexer().getLoc(),
8123 "unexpected token, expected end of statement");
8130bool MipsAsmParser::parseDirectiveDtpRelDWord() {
8135 if (getParser().parseExpression(
Value))
8137 getParser().getStreamer().emitDTPRel64Value(
Value);
8140 return Error(getLexer().getLoc(),
8141 "unexpected token, expected end of statement");
8148bool MipsAsmParser::parseDirectiveTpRelWord() {
8153 if (getParser().parseExpression(
Value))
8155 getParser().getStreamer().emitTPRel32Value(
Value);
8158 return Error(getLexer().getLoc(),
8159 "unexpected token, expected end of statement");
8166bool MipsAsmParser::parseDirectiveTpRelDWord() {
8171 if (getParser().parseExpression(
Value))
8173 getParser().getStreamer().emitTPRel64Value(
Value);
8176 return Error(getLexer().getLoc(),
8177 "unexpected token, expected end of statement");
8182bool MipsAsmParser::parseDirectiveOption() {
8189 "unexpected token, expected identifier");
8194 if (Option ==
"pic0") {
8196 IsPicEnabled =
false;
8198 getTargetStreamer().emitDirectiveOptionPic0();
8202 "unexpected token, expected end of statement");
8207 if (Option ==
"pic2") {
8209 IsPicEnabled =
true;
8211 getTargetStreamer().emitDirectiveOptionPic2();
8215 "unexpected token, expected end of statement");
8222 "unknown option, expected 'pic0' or 'pic2'");
8229bool MipsAsmParser::parseInsnDirective() {
8232 reportParseError(
"unexpected token, expected end of statement");
8238 getTargetStreamer().emitDirectiveInsn();
8246bool MipsAsmParser::parseRSectionDirective(
StringRef Section) {
8249 reportParseError(
"unexpected token, expected end of statement");
8253 MCSection *ELFSection = getContext().getELFSection(
8255 getParser().getStreamer().switchSection(ELFSection);
8264bool MipsAsmParser::parseSSectionDirective(
StringRef Section,
unsigned Type) {
8267 reportParseError(
"unexpected token, expected end of statement");
8271 MCSection *ELFSection = getContext().getELFSection(
8273 getParser().getStreamer().switchSection(ELFSection);
8292bool MipsAsmParser::parseDirectiveModule() {
8297 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
8299 reportParseError(
".module directive must appear before any code");
8305 reportParseError(
"expected .module option identifier");
8309 if (Option ==
"oddspreg") {
8310 clearModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
8314 getTargetStreamer().updateABIInfo(*
this);
8319 getTargetStreamer().emitDirectiveModuleOddSPReg();
8323 reportParseError(
"unexpected token, expected end of statement");
8328 }
else if (Option ==
"nooddspreg") {
8330 return Error(L,
"'.module nooddspreg' requires the O32 ABI");
8333 setModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
8337 getTargetStreamer().updateABIInfo(*
this);
8342 getTargetStreamer().emitDirectiveModuleOddSPReg();
8346 reportParseError(
"unexpected token, expected end of statement");
8351 }
else if (Option ==
"fp") {
8352 return parseDirectiveModuleFP();
8353 }
else if (Option ==
"softfloat") {
8354 setModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
8358 getTargetStreamer().updateABIInfo(*
this);
8363 getTargetStreamer().emitDirectiveModuleSoftFloat();
8367 reportParseError(
"unexpected token, expected end of statement");
8372 }
else if (Option ==
"hardfloat") {
8373 clearModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
8377 getTargetStreamer().updateABIInfo(*
this);
8382 getTargetStreamer().emitDirectiveModuleHardFloat();
8386 reportParseError(
"unexpected token, expected end of statement");
8391 }
else if (Option ==
"mt") {
8392 setModuleFeatureBits(Mips::FeatureMT,
"mt");
8396 getTargetStreamer().updateABIInfo(*
this);
8401 getTargetStreamer().emitDirectiveModuleMT();
8405 reportParseError(
"unexpected token, expected end of statement");
8410 }
else if (Option ==
"crc") {
8411 setModuleFeatureBits(Mips::FeatureCRC,
"crc");
8415 getTargetStreamer().updateABIInfo(*
this);
8420 getTargetStreamer().emitDirectiveModuleCRC();
8424 reportParseError(
"unexpected token, expected end of statement");
8429 }
else if (Option ==
"nocrc") {
8430 clearModuleFeatureBits(Mips::FeatureCRC,
"crc");
8434 getTargetStreamer().updateABIInfo(*
this);
8439 getTargetStreamer().emitDirectiveModuleNoCRC();
8443 reportParseError(
"unexpected token, expected end of statement");
8448 }
else if (Option ==
"virt") {
8449 setModuleFeatureBits(Mips::FeatureVirt,
"virt");
8453 getTargetStreamer().updateABIInfo(*
this);
8458 getTargetStreamer().emitDirectiveModuleVirt();
8462 reportParseError(
"unexpected token, expected end of statement");
8467 }
else if (Option ==
"novirt") {
8468 clearModuleFeatureBits(Mips::FeatureVirt,
"virt");
8472 getTargetStreamer().updateABIInfo(*
this);
8477 getTargetStreamer().emitDirectiveModuleNoVirt();
8481 reportParseError(
"unexpected token, expected end of statement");
8486 }
else if (Option ==
"ginv") {
8487 setModuleFeatureBits(Mips::FeatureGINV,
"ginv");
8491 getTargetStreamer().updateABIInfo(*
this);
8496 getTargetStreamer().emitDirectiveModuleGINV();
8500 reportParseError(
"unexpected token, expected end of statement");
8505 }
else if (Option ==
"noginv") {
8506 clearModuleFeatureBits(Mips::FeatureGINV,
"ginv");
8510 getTargetStreamer().updateABIInfo(*
this);
8515 getTargetStreamer().emitDirectiveModuleNoGINV();
8519 reportParseError(
"unexpected token, expected end of statement");
8525 return Error(L,
"'" +
Twine(Option) +
"' is not a valid .module option.");
8533bool MipsAsmParser::parseDirectiveModuleFP() {
8538 reportParseError(
"unexpected token, expected equals sign '='");
8544 if (!parseFpABIValue(FpABI,
".module"))
8548 reportParseError(
"unexpected token, expected end of statement");
8554 getTargetStreamer().updateABIInfo(*
this);
8559 getTargetStreamer().emitDirectiveModuleFP();
8569 bool ModuleLevelOptions =
Directive ==
".module";
8575 if (
Value !=
"xx") {
8576 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
8581 reportParseError(
"'" +
Directive +
" fp=xx' requires the O32 ABI");
8585 FpABI = MipsABIFlagsSection::FpABIKind::XX;
8586 if (ModuleLevelOptions) {
8587 setModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8588 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8590 setFeatureBits(Mips::FeatureFPXX,
"fpxx");
8591 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8601 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
8607 reportParseError(
"'" +
Directive +
" fp=32' requires the O32 ABI");
8611 FpABI = MipsABIFlagsSection::FpABIKind::S32;
8612 if (ModuleLevelOptions) {
8613 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8614 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8616 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
8617 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8620 FpABI = MipsABIFlagsSection::FpABIKind::S64;
8621 if (ModuleLevelOptions) {
8622 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8623 setModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8625 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
8626 setFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8636bool MipsAsmParser::ParseDirective(
AsmToken DirectiveID) {
8645 if (IDVal ==
".cpadd") {
8646 parseDirectiveCpAdd(DirectiveID.
getLoc());
8649 if (IDVal ==
".cpload") {
8650 parseDirectiveCpLoad(DirectiveID.
getLoc());
8653 if (IDVal ==
".cprestore") {
8654 parseDirectiveCpRestore(DirectiveID.
getLoc());
8657 if (IDVal ==
".cplocal") {
8658 parseDirectiveCpLocal(DirectiveID.
getLoc());
8661 if (IDVal ==
".ent") {
8665 reportParseError(
"expected identifier after .ent");
8679 reportParseError(
"unexpected token, expected end of statement");
8683 const MCExpr *DummyNumber;
8684 int64_t DummyNumberVal;
8688 reportParseError(
"expected number after comma");
8691 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
8692 reportParseError(
"expected an absolute expression after comma");
8699 reportParseError(
"unexpected token, expected end of statement");
8703 MCSymbol *
Sym = getContext().getOrCreateSymbol(SymbolName);
8705 getTargetStreamer().emitDirectiveEnt(*
Sym);
8707 IsCpRestoreSet =
false;
8711 if (IDVal ==
".end") {
8715 reportParseError(
"expected identifier after .end");
8720 reportParseError(
"unexpected token, expected end of statement");
8724 if (CurrentFn ==
nullptr) {
8725 reportParseError(
".end used without .ent");
8729 if ((SymbolName != CurrentFn->
getName())) {
8730 reportParseError(
".end symbol does not match .ent symbol");
8734 getTargetStreamer().emitDirectiveEnd(SymbolName);
8735 CurrentFn =
nullptr;
8736 IsCpRestoreSet =
false;
8740 if (IDVal ==
".frame") {
8745 reportParseError(
"expected stack register");
8749 MipsOperand &StackRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
8750 if (!StackRegOpnd.isGPRAsmReg()) {
8751 reportParseError(StackRegOpnd.getStartLoc(),
8752 "expected general purpose register");
8755 unsigned StackReg = StackRegOpnd.getGPR32Reg();
8760 reportParseError(
"unexpected token, expected comma");
8766 int64_t FrameSizeVal;
8769 reportParseError(
"expected frame size value");
8773 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
8774 reportParseError(
"frame size not an absolute expression");
8781 reportParseError(
"unexpected token, expected comma");
8787 Res = parseAnyRegister(TmpReg);
8789 reportParseError(
"expected return register");
8793 MipsOperand &ReturnRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
8794 if (!ReturnRegOpnd.isGPRAsmReg()) {
8795 reportParseError(ReturnRegOpnd.getStartLoc(),
8796 "expected general purpose register");
8802 reportParseError(
"unexpected token, expected end of statement");
8806 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
8807 ReturnRegOpnd.getGPR32Reg());
8808 IsCpRestoreSet =
false;
8812 if (IDVal ==
".set") {
8813 parseDirectiveSet();
8817 if (IDVal ==
".mask" || IDVal ==
".fmask") {
8832 reportParseError(
"expected bitmask value");
8836 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
8837 reportParseError(
"bitmask not an absolute expression");
8844 reportParseError(
"unexpected token, expected comma");
8849 const MCExpr *FrameOffset;
8850 int64_t FrameOffsetVal;
8853 reportParseError(
"expected frame offset value");
8857 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
8858 reportParseError(
"frame offset not an absolute expression");
8864 reportParseError(
"unexpected token, expected end of statement");
8868 if (IDVal ==
".mask")
8869 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
8871 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
8875 if (IDVal ==
".nan")
8876 return parseDirectiveNaN();
8878 if (IDVal ==
".gpword") {
8879 parseDirectiveGpWord();
8883 if (IDVal ==
".gpdword") {
8884 parseDirectiveGpDWord();
8888 if (IDVal ==
".dtprelword") {
8889 parseDirectiveDtpRelWord();
8893 if (IDVal ==
".dtpreldword") {
8894 parseDirectiveDtpRelDWord();
8898 if (IDVal ==
".tprelword") {
8899 parseDirectiveTpRelWord();
8903 if (IDVal ==
".tpreldword") {
8904 parseDirectiveTpRelDWord();
8908 if (IDVal ==
".option") {
8909 parseDirectiveOption();
8913 if (IDVal ==
".abicalls") {
8914 getTargetStreamer().emitDirectiveAbiCalls();
8917 "unexpected token, expected end of statement");
8922 if (IDVal ==
".cpsetup") {
8923 parseDirectiveCPSetup();
8926 if (IDVal ==
".cpreturn") {
8927 parseDirectiveCPReturn();
8930 if (IDVal ==
".module") {
8931 parseDirectiveModule();
8934 if (IDVal ==
".llvm_internal_mips_reallow_module_directive") {
8935 parseInternalDirectiveReallowModule();
8938 if (IDVal ==
".insn") {
8939 parseInsnDirective();
8942 if (IDVal ==
".rdata") {
8943 parseRSectionDirective(
".rodata");
8946 if (IDVal ==
".sbss") {
8950 if (IDVal ==
".sdata") {
8958bool MipsAsmParser::parseInternalDirectiveReallowModule() {
8961 reportParseError(
"unexpected token, expected end of statement");
8965 getTargetStreamer().reallowModuleDirective();
8978#define GET_REGISTER_MATCHER
8979#define GET_MATCHER_IMPLEMENTATION
8980#define GET_MNEMONIC_SPELL_CHECKER
8981#include "MipsGenAsmMatcher.inc"
8983bool MipsAsmParser::mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID) {
8985 const MatchEntry *Start, *
End;
8986 switch (VariantID) {
8988 case 0: Start = std::begin(MatchTable0);
End = std::end(MatchTable0);
break;
8991 auto MnemonicRange = std::equal_range(Start,
End, Mnemonic, LessOpcode());
8992 return MnemonicRange.first != MnemonicRange.second;
static const TargetRegisterClass * getRegClass(const MachineInstr &MI, Register Reg)
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
This file declares a class to represent arbitrary precision floating point values and provide a varie...
static ARMBaseTargetMachine::ARMABI computeTargetABI(const Triple &TT, StringRef CPU, const TargetOptions &Options)
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Analysis containing CSE Info
#define LLVM_EXTERNAL_VISIBILITY
static Value * expandAbs(CallInst *Orig)
std::optional< std::vector< StOtherPiece > > Other
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
static FeatureBitset getFeatures(MCSubtargetInfo &STI, StringRef CPU, StringRef TuneCPU, StringRef FS, ArrayRef< StringRef > ProcNames, ArrayRef< SubtargetSubTypeKV > ProcDesc, ArrayRef< SubtargetFeatureKV > ProcFeatures)
mir Rename Register Operands
static unsigned countMCSymbolRefExpr(const MCExpr *Expr)
static std::string MipsMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, unsigned VariantID=0)
static uint64_t convertIntToDoubleImm(uint64_t ImmOp64)
static uint32_t covertDoubleImmToSingleImm(uint64_t ImmOp64)
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsAsmParser()
static unsigned getRegisterForMxtrDSP(MCInst &Inst, bool IsMFDSP)
static unsigned nextReg(unsigned Reg)
static bool hasShortDelaySlot(MCInst &Inst)
static bool needsExpandMemInst(MCInst &Inst, const MCInstrDesc &MCID)
cl::opt< bool > EmitJalrReloc
static bool isShiftedUIntAtAnyPosition(uint64_t x)
Can the value be represented by a unsigned N-bit value and a shift left?
static bool isEvaluated(const MCExpr *Expr)
static unsigned getRegisterForMxtrC0(MCInst &Inst, bool IsMFTC0)
static const MCSymbol * getSingleMCSymbol(const MCExpr *Expr)
static unsigned getRegisterForMxtrFP(MCInst &Inst, bool IsMFTC1)
static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands, uint64_t ErrorInfo)
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isImm(const MachineOperand &MO, MachineRegisterInfo *MRI)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
APInt bitcastToAPInt() const
uint64_t getZExtValue() const
Get zero extended value.
Target independent representation for an assembler token.
int64_t getIntVal() const
bool isNot(TokenKind K) const
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
bool is(TokenKind K) const
TokenKind getKind() const
SMRange getLocRange() const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
This class represents an Operation in the Expression.
Base class for user error types.
Lightweight error class with error context and mandatory checking.
Container class for subtarget features.
Generic assembler lexer interface, for use by target specific assembly lexers.
const AsmToken peekTok(bool ShouldSkipSpace=true)
Look ahead at the next token to be lexed.
bool isNot(AsmToken::TokenKind K) const
Check if the current token has kind K.
SMLoc getLoc() const
Get the current source location.
bool is(AsmToken::TokenKind K) const
Check if the current token has kind K.
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
MCStreamer & getStreamer()
MCAsmParser & getParser()
Generic assembler parser interface, for use by target specific assembly parsers.
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
virtual MCStreamer & getStreamer()=0
Return the output streamer for the assembler.
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
virtual MCAsmLexer & getLexer()=0
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
Binary assembler expressions.
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
static const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
@ LShr
Logical shift right.
@ Xor
Bitwise exclusive or.
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
const MCObjectFileInfo * getObjectFileInfo() const
MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
Base class for the full range of assembler expressions which are needed for parsing.
@ Unary
Unary expressions.
@ Constant
Constant expressions.
@ SymbolRef
References to labels and assigned expressions.
@ Target
Target specific expression.
@ Binary
Binary expressions.
bool evaluateAsRelocatable(MCValue &Res, const MCAssembler *Asm, const MCFixup *Fixup) const
Try to evaluate the expression to a relocatable value, i.e.
Instances of this class represent a single low-level machine instruction.
unsigned getNumOperands() const
unsigned getOpcode() const
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
const MCOperand & getOperand(unsigned i) const
Describe properties that are true of each instruction in the target description file.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
ArrayRef< MCOperandInfo > operands() const
bool mayStore() const
Return true if this instruction could possibly modify memory.
bool mayLoad() const
Return true if this instruction could possibly read memory.
bool isBranch() const
Returns true if this is a conditional, unconditional, or indirect branch.
bool isCall() const
Return true if the instruction is a call.
bool hasDelaySlot() const
Returns true if the specified instruction has a delay slot which must be filled by the code generator...
Interface to description of machine instruction set.
bool isPositionIndependent() const
This holds information about one operand of a machine instruction, indicating the register class for ...
uint8_t OperandType
Information about the type of the operand.
Instances of this class represent operands of the MCInst class.
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
MCRegister getReg() const
Returns the register number.
const MCExpr * getExpr() const
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual bool isReg() const =0
isReg - Is this a register operand?
virtual MCRegister getReg() const =0
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Wrapper class representing physical registers. Should be passed by value.
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Streaming machine code generation interface.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
MCContext & getContext() const
virtual std::optional< std::pair< bool, std::string > > emitRelocDirective(const MCExpr &Offset, StringRef Name, const MCExpr *Expr, SMLoc Loc, const MCSubtargetInfo &STI)
Record a relocation described by the .reloc directive.
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
MCTargetStreamer * getTargetStreamer()
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
void setFeatureBits(const FeatureBitset &FeatureBits_)
const Triple & getTargetTriple() const
const FeatureBitset & getFeatureBits() const
FeatureBitset ToggleFeature(uint64_t FB)
Toggle a feature and return the re-computed feature bits.
Represent a reference to a symbol from inside an expression.
const MCSymbol & getSymbol() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
VariantKind getKind() const
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
bool isInSection() const
isInSection - Check if this symbol is defined in some section (i.e., it is defined but not absolute).
StringRef getName() const
getName - Get the symbol name.
bool isTemporary() const
isTemporary - Check if this is an assembler temporary symbol.
MCTargetAsmParser - Generic interface to target specific assembly parsers.
virtual bool parseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands)=0
Parse one assembly instruction.
MCSubtargetInfo & copySTI()
Create a copy of STI and return a non-const reference to it.
@ FIRST_TARGET_MATCH_RESULT_TY
virtual bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
virtual bool ParseDirective(AsmToken DirectiveID)
ParseDirective - Parse a target specific assembler directive This method is deprecated,...
virtual unsigned checkEarlyTargetMatchPredicate(MCInst &Inst, const OperandVector &Operands)
Validate the instruction match against any complex target predicates before rendering any operands to...
virtual ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
tryParseRegister - parse one register if possible
virtual bool areEqualRegs(const MCParsedAsmOperand &Op1, const MCParsedAsmOperand &Op2) const
Returns whether two operands are registers and are equal.
virtual bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm)=0
Recognize a series of operands of a parsed instruction as an actual MCInst and emit it to the specifi...
virtual void onEndOfFile()
void setAvailableFeatures(const FeatureBitset &Value)
const MCSubtargetInfo & getSTI() const
virtual const MCExpr * createTargetUnaryExpr(const MCExpr *E, AsmToken::TokenKind OperatorToken, MCContext &Ctx)
virtual unsigned checkTargetMatchPredicate(MCInst &Inst)
checkTargetMatchPredicate - Validate the instruction match against any complex target predicates not ...
Target specific streamer interface.
MCStreamer & getStreamer()
Unary assembler expressions.
This represents an "assembler immediate".
int64_t getConstant() const
const MCSymbolRefExpr * getSymB() const
const MCSymbolRefExpr * getSymA() const
static const MipsMCExpr * create(MipsExprKind Kind, const MCExpr *Expr, MCContext &Ctx)
virtual void emitDirectiveSetReorder()
void emitRRIII(unsigned Opcode, unsigned Reg0, unsigned Reg1, int16_t Imm0, int16_t Imm1, int16_t Imm2, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1, int16_t Imm, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRX(unsigned Opcode, unsigned Reg0, MCOperand Op1, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitR(unsigned Opcode, unsigned Reg0, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void setUsesMicroMips()
void emitEmptyDelaySlot(bool hasShortDelaySlot, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1, MCOperand Op2, SMLoc IDLoc, const MCSubtargetInfo *STI)
void updateABIInfo(const PredicateLibrary &P)
void emitRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRI(unsigned Opcode, unsigned Reg0, int32_t Imm, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, unsigned Reg2, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1, unsigned Reg2, MCOperand Op3, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitGPRestore(int Offset, SMLoc IDLoc, const MCSubtargetInfo *STI)
Emit the $gp restore operation for .cprestore.
void emitNop(SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveSetNoReorder()
void emitDSLL(unsigned DstReg, unsigned SrcReg, int16_t ShiftAmount, SMLoc IDLoc, const MCSubtargetInfo *STI)
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
static constexpr StatusTy Failure
constexpr bool isSuccess() const
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
constexpr bool isNoMatch() const
Represents a single fixit, a replacement of one range of text with another.
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
Represents a range in source code.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StackOffset holds a fixed and a scalable offset in bytes.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
iterator find(StringRef Key)
StringRef - Represent a constant reference to a string, i.e.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
empty - Check if the string is empty.
StringRef trim(char Char) const
Return string with consecutive Char characters starting from the left and right removed.
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
StringSwitch & Cases(StringLiteral S0, StringLiteral S1, T Value)
Triple - Helper class for working with autoconf configuration names.
bool isLittleEndian() const
Tests whether the target triple is little endian.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
bool parseAssignmentExpression(StringRef Name, bool allow_redef, MCAsmParser &Parser, MCSymbol *&Symbol, const MCExpr *&Value)
Parse a value expression and return whether it can be assigned to a symbol with the given name.
@ IsCTI
IsCTI - Instruction is a Control Transfer Instruction.
@ HasFCCRegOperand
HasFCCRegOperand - Instruction uses an $fcc<x> register.
@ HasForbiddenSlot
HasForbiddenSlot - Instruction has a forbidden slot.
@ CE
Windows NT (Windows on ARM)
This is an optimization pass for GlobalISel generic memory operations.
Target & getTheMips64Target()
static bool isMem(const MachineInstr &MI, unsigned Op)
static StringRef getCPU(StringRef CPU)
Processes a CPU name.
int bit_width(T Value)
Returns the number of bits needed to represent Value if Value is nonzero.
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
Target & getTheMips64elTarget()
uint64_t offsetToAlignment(uint64_t Value, Align Alignment)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
@ Ref
The access may reference the value stored in memory.
bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
Target & getTheMipselTarget()
DWARFExpression::Operation Op
constexpr unsigned BitWidth
Target & getTheMipsTarget()
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Description of the encoding of one expression Op.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...