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);
2116 return Error(IDLoc,
"jal doesn't support multiple symbols in PIC mode");
2122 if (expandLoadAddress(Mips::T9, Mips::NoRegister, Inst.
getOperand(0),
2123 !isGP64bit(), IDLoc, Out, STI))
2127 if (inMicroMipsMode())
2128 JalrInst.
setOpcode(IsCpRestoreSet ? Mips::JALRS_MM : Mips::JALR_MM);
2134 if (isJalrRelocAvailable(JalExpr)) {
2138 MCSymbol *TmpLabel = getContext().createTempSymbol();
2140 const MCExpr *RelocJalrExpr =
2142 getContext(), IDLoc);
2145 *TmpExpr, inMicroMipsMode() ?
"R_MICROMIPS_JALR" :
"R_MIPS_JALR",
2146 RelocJalrExpr, IDLoc, *STI);
2151 ExpandedJalSym =
true;
2160 expandMem9Inst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2163 expandMem16Inst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2166 return getParser().hasPendingError();
2170 if (inMicroMipsMode()) {
2171 if (MCID.
mayLoad() && Opcode != Mips::LWP_MM) {
2179 int MemOffset =
Op.getImm();
2182 if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
2185 (BaseReg.
getReg() == Mips::GP ||
2186 BaseReg.
getReg() == Mips::GP_64)) {
2188 TOut.
emitRRI(Mips::LWGP_MM, DstReg.
getReg(), Mips::GP, MemOffset,
2205 case Mips::ADDIUSP_MM:
2208 return Error(IDLoc,
"expected immediate operand kind");
2210 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
2212 return Error(IDLoc,
"immediate operand value out of range");
2214 case Mips::SLL16_MM:
2215 case Mips::SRL16_MM:
2218 return Error(IDLoc,
"expected immediate operand kind");
2220 if (Imm < 1 || Imm > 8)
2221 return Error(IDLoc,
"immediate operand value out of range");
2226 return Error(IDLoc,
"expected immediate operand kind");
2228 if (Imm < -1 || Imm > 126)
2229 return Error(IDLoc,
"immediate operand value out of range");
2231 case Mips::ADDIUR2_MM:
2234 return Error(IDLoc,
"expected immediate operand kind");
2236 if (!(Imm == 1 || Imm == -1 ||
2237 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
2238 return Error(IDLoc,
"immediate operand value out of range");
2240 case Mips::ANDI16_MM:
2243 return Error(IDLoc,
"expected immediate operand kind");
2245 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
2246 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
2247 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
2248 return Error(IDLoc,
"immediate operand value out of range");
2250 case Mips::LBU16_MM:
2253 return Error(IDLoc,
"expected immediate operand kind");
2255 if (Imm < -1 || Imm > 14)
2256 return Error(IDLoc,
"immediate operand value out of range");
2259 case Mips::SB16_MMR6:
2262 return Error(IDLoc,
"expected immediate operand kind");
2264 if (Imm < 0 || Imm > 15)
2265 return Error(IDLoc,
"immediate operand value out of range");
2267 case Mips::LHU16_MM:
2269 case Mips::SH16_MMR6:
2272 return Error(IDLoc,
"expected immediate operand kind");
2274 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
2275 return Error(IDLoc,
"immediate operand value out of range");
2279 case Mips::SW16_MMR6:
2282 return Error(IDLoc,
"expected immediate operand kind");
2284 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
2285 return Error(IDLoc,
"immediate operand value out of range");
2287 case Mips::ADDIUPC_MM:
2290 return Error(IDLoc,
"expected immediate operand kind");
2292 if ((Imm % 4 != 0) || !isInt<25>(Imm))
2293 return Error(IDLoc,
"immediate operand value out of range");
2298 return Error(IDLoc,
"invalid operand for instruction");
2300 case Mips::MOVEP_MM:
2301 case Mips::MOVEP_MMR6: {
2304 bool RegPair = ((R0 == Mips::A1 && R1 == Mips::A2) ||
2305 (R0 == Mips::A1 && R1 == Mips::A3) ||
2306 (R0 == Mips::A2 && R1 == Mips::A3) ||
2307 (R0 == Mips::A0 && R1 == Mips::S5) ||
2308 (R0 == Mips::A0 && R1 == Mips::S6) ||
2309 (R0 == Mips::A0 && R1 == Mips::A1) ||
2310 (R0 == Mips::A0 && R1 == Mips::A2) ||
2311 (R0 == Mips::A0 && R1 == Mips::A3));
2313 return Error(IDLoc,
"invalid operand for instruction");
2319 bool FillDelaySlot =
2324 bool PrevForbiddenSlotAttr = CurForbiddenSlotAttr;
2327 bool SetReorderAfterNop =
false;
2332 if (PrevForbiddenSlotAttr && !SafeInForbiddenSlot(MCID)) {
2342 if (AssemblerOptions.
back()->isReorder() && !FillDelaySlot) {
2343 SetReorderAfterNop =
true;
2352 CurForbiddenSlotAttr =
2353 hasForbiddenSlot(MCID) && AssemblerOptions.
back()->isReorder();
2355 if (FillDelaySlot || CurForbiddenSlotAttr)
2358 MacroExpanderResultTy ExpandResult =
2359 tryExpandInstruction(Inst, IDLoc, Out, STI);
2360 switch (ExpandResult) {
2376 if (PrevForbiddenSlotAttr && !SetReorderAfterNop && !FillDelaySlot &&
2377 AssemblerOptions.
back()->isReorder()) {
2383 if (inMicroMipsMode()) {
2398 if (FillDelaySlot) {
2403 if ((Opcode == Mips::JalOneReg || Opcode == Mips::JalTwoReg ||
2405 isPicAndNotNxxAbi()) {
2406 if (IsCpRestoreSet) {
2410 if (!AssemblerOptions.
back()->isReorder())
2417 Warning(IDLoc,
"no .cprestore used in PIC mode");
2423void MipsAsmParser::onEndOfFile() {
2427 if (CurForbiddenSlotAttr) {
2429 if (AssemblerOptions.
back()->isReorder())
2434MipsAsmParser::MacroExpanderResultTy
2439 return MER_NotAMacro;
2440 case Mips::LoadImm32:
2441 return expandLoadImm(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2442 case Mips::LoadImm64:
2443 return expandLoadImm(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2444 case Mips::LoadAddrImm32:
2445 case Mips::LoadAddrImm64:
2448 "expected immediate operand kind");
2452 Inst.
getOpcode() == Mips::LoadAddrImm32, IDLoc,
2456 case Mips::LoadAddrReg32:
2457 case Mips::LoadAddrReg64:
2461 "expected immediate operand kind");
2465 Inst.
getOpcode() == Mips::LoadAddrReg32, IDLoc,
2469 case Mips::B_MM_Pseudo:
2470 case Mips::B_MMR6_Pseudo:
2471 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2475 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2477 case Mips::JalOneReg:
2478 case Mips::JalTwoReg:
2479 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2482 case Mips::BEQLImmMacro:
2483 case Mips::BNELImmMacro:
2484 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2501 case Mips::BLTImmMacro:
2502 case Mips::BLEImmMacro:
2503 case Mips::BGEImmMacro:
2504 case Mips::BGTImmMacro:
2505 case Mips::BLTUImmMacro:
2506 case Mips::BLEUImmMacro:
2507 case Mips::BGEUImmMacro:
2508 case Mips::BGTUImmMacro:
2509 case Mips::BLTLImmMacro:
2510 case Mips::BLELImmMacro:
2511 case Mips::BGELImmMacro:
2512 case Mips::BGTLImmMacro:
2513 case Mips::BLTULImmMacro:
2514 case Mips::BLEULImmMacro:
2515 case Mips::BGEULImmMacro:
2516 case Mips::BGTULImmMacro:
2517 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2518 case Mips::SDivMacro:
2519 case Mips::SDivIMacro:
2520 case Mips::SRemMacro:
2521 case Mips::SRemIMacro:
2522 return expandDivRem(Inst, IDLoc, Out, STI,
false,
true) ? MER_Fail
2524 case Mips::DSDivMacro:
2525 case Mips::DSDivIMacro:
2526 case Mips::DSRemMacro:
2527 case Mips::DSRemIMacro:
2528 return expandDivRem(Inst, IDLoc, Out, STI,
true,
true) ? MER_Fail
2530 case Mips::UDivMacro:
2531 case Mips::UDivIMacro:
2532 case Mips::URemMacro:
2533 case Mips::URemIMacro:
2534 return expandDivRem(Inst, IDLoc, Out, STI,
false,
false) ? MER_Fail
2536 case Mips::DUDivMacro:
2537 case Mips::DUDivIMacro:
2538 case Mips::DURemMacro:
2539 case Mips::DURemIMacro:
2540 return expandDivRem(Inst, IDLoc, Out, STI,
true,
false) ? MER_Fail
2542 case Mips::PseudoTRUNC_W_S:
2543 return expandTrunc(Inst,
false,
false, IDLoc, Out, STI) ? MER_Fail
2545 case Mips::PseudoTRUNC_W_D32:
2546 return expandTrunc(Inst,
true,
false, IDLoc, Out, STI) ? MER_Fail
2548 case Mips::PseudoTRUNC_W_D:
2549 return expandTrunc(Inst,
true,
true, IDLoc, Out, STI) ? MER_Fail
2552 case Mips::LoadImmSingleGPR:
2553 return expandLoadSingleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2555 case Mips::LoadImmSingleFGR:
2556 return expandLoadSingleImmToFPR(Inst, IDLoc, Out, STI) ? MER_Fail
2558 case Mips::LoadImmDoubleGPR:
2559 return expandLoadDoubleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2561 case Mips::LoadImmDoubleFGR:
2562 return expandLoadDoubleImmToFPR(Inst,
true, IDLoc, Out, STI) ? MER_Fail
2564 case Mips::LoadImmDoubleFGR_32:
2565 return expandLoadDoubleImmToFPR(Inst,
false, IDLoc, Out, STI) ? MER_Fail
2569 return expandUlh(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2571 return expandUlh(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2573 return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2576 return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2578 case Mips::NORImm64:
2579 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2582 return expandSge(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2585 case Mips::SGEImm64:
2586 case Mips::SGEUImm64:
2587 return expandSgeImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2590 case Mips::SGTImm64:
2591 case Mips::SGTUImm64:
2592 return expandSgtImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2595 return expandSle(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2598 case Mips::SLEImm64:
2599 case Mips::SLEUImm64:
2600 return expandSleImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2601 case Mips::SLTImm64:
2604 return MER_NotAMacro;
2606 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2607 case Mips::SLTUImm64:
2610 return MER_NotAMacro;
2612 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2613 case Mips::ADDi:
case Mips::ADDi_MM:
2614 case Mips::ADDiu:
case Mips::ADDiu_MM:
2615 case Mips::SLTi:
case Mips::SLTi_MM:
2616 case Mips::SLTiu:
case Mips::SLTiu_MM:
2620 if (isInt<16>(ImmValue))
2621 return MER_NotAMacro;
2622 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2625 return MER_NotAMacro;
2626 case Mips::ANDi:
case Mips::ANDi_MM:
case Mips::ANDi64:
2627 case Mips::ORi:
case Mips::ORi_MM:
case Mips::ORi64:
2628 case Mips::XORi:
case Mips::XORi_MM:
case Mips::XORi64:
2632 if (isUInt<16>(ImmValue))
2633 return MER_NotAMacro;
2634 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2637 return MER_NotAMacro;
2640 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2643 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2646 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2649 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2650 case Mips::ABSMacro:
2651 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2652 case Mips::MULImmMacro:
2653 case Mips::DMULImmMacro:
2654 return expandMulImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2655 case Mips::MULOMacro:
2656 case Mips::DMULOMacro:
2657 return expandMulO(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2658 case Mips::MULOUMacro:
2659 case Mips::DMULOUMacro:
2660 return expandMulOU(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2661 case Mips::DMULMacro:
2662 return expandDMULMacro(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2665 return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2670 return expandStoreDM1Macro(Inst, IDLoc, Out, STI)
2673 case Mips::SEQMacro:
2674 return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2675 case Mips::SEQIMacro:
2676 return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2677 case Mips::SNEMacro:
2678 return expandSne(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2679 case Mips::SNEIMacro:
2680 return expandSneI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2681 case Mips::MFTC0:
case Mips::MTTC0:
2682 case Mips::MFTGPR:
case Mips::MTTGPR:
2683 case Mips::MFTLO:
case Mips::MTTLO:
2684 case Mips::MFTHI:
case Mips::MTTHI:
2685 case Mips::MFTACX:
case Mips::MTTACX:
2686 case Mips::MFTDSP:
case Mips::MTTDSP:
2687 case Mips::MFTC1:
case Mips::MTTC1:
2688 case Mips::MFTHC1:
case Mips::MTTHC1:
2689 case Mips::CFTC1:
case Mips::CTTC1:
2690 return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2692 case Mips::SaadAddr:
2693 return expandSaaAddr(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2697bool MipsAsmParser::expandJalWithRegs(
MCInst &Inst,
SMLoc IDLoc,
2706 const unsigned Opcode = Inst.
getOpcode();
2708 if (Opcode == Mips::JalOneReg) {
2710 if (IsCpRestoreSet && inMicroMipsMode()) {
2713 }
else if (inMicroMipsMode()) {
2714 JalrInst.
setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2721 }
else if (Opcode == Mips::JalTwoReg) {
2723 if (IsCpRestoreSet && inMicroMipsMode())
2726 JalrInst.
setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2758bool MipsAsmParser::loadImmediate(int64_t ImmValue,
unsigned DstReg,
2759 unsigned SrcReg,
bool Is32BitImm,
2764 if (!Is32BitImm && !isGP64bit()) {
2765 Error(IDLoc,
"instruction requires a 64-bit architecture");
2770 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2774 ImmValue = SignExtend64<32>(ImmValue);
2776 Error(IDLoc,
"instruction requires a 32-bit immediate");
2781 unsigned ZeroReg = IsAddress ?
ABI.GetNullPtr() :
ABI.GetZeroReg();
2782 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2784 bool UseSrcReg =
false;
2785 if (SrcReg != Mips::NoRegister)
2788 unsigned TmpReg = DstReg;
2790 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2793 unsigned ATReg = getATReg(IDLoc);
2799 if (isInt<16>(ImmValue)) {
2806 if (IsAddress && !Is32BitImm) {
2807 TOut.
emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2811 TOut.
emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2815 if (isUInt<16>(ImmValue)) {
2816 unsigned TmpReg = DstReg;
2817 if (SrcReg == DstReg) {
2818 TmpReg = getATReg(IDLoc);
2823 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2825 TOut.
emitRRR(
ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2829 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2830 warnIfNoMacro(IDLoc);
2832 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2833 uint16_t Bits15To0 = ImmValue & 0xffff;
2834 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2837 if (ImmValue == 0xffffffff) {
2838 TOut.
emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2839 TOut.
emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2841 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2847 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2848 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2850 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2852 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2856 TOut.
emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2858 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2860 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2864 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2866 Error(IDLoc,
"instruction requires a 32-bit immediate");
2873 assert(
BitWidth >= 17 &&
"ImmValue must be at least 17-bit wide");
2877 unsigned ShiftAmount =
BitWidth - 16;
2879 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2880 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2883 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2888 warnIfNoMacro(IDLoc);
2895 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister,
true,
false,
2901 unsigned ShiftCarriedForwards = 16;
2902 for (
int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2903 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2905 if (ImmChunk != 0) {
2906 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2907 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2908 ShiftCarriedForwards = 0;
2911 ShiftCarriedForwards += 16;
2913 ShiftCarriedForwards -= 16;
2916 if (ShiftCarriedForwards)
2917 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2920 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2925bool MipsAsmParser::expandLoadImm(
MCInst &Inst,
bool Is32BitImm,
SMLoc IDLoc,
2928 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
2930 assert(DstRegOp.
isReg() &&
"expected register operand kind");
2932 if (loadImmediate(ImmOp.
getImm(), DstRegOp.
getReg(), Mips::NoRegister,
2933 Is32BitImm,
false, IDLoc, Out, STI))
2939bool MipsAsmParser::expandLoadAddress(
unsigned DstReg,
unsigned BaseReg,
2941 bool Is32BitAddress,
SMLoc IDLoc,
2945 if (Is32BitAddress &&
ABI.ArePtrs64bit()) {
2946 Warning(IDLoc,
"la used to load 64-bit address");
2948 Is32BitAddress =
false;
2952 if (!Is32BitAddress && !hasMips3()) {
2953 Error(IDLoc,
"instruction requires a 64-bit architecture");
2958 return loadAndAddSymbolAddress(
Offset.getExpr(), DstReg, BaseReg,
2959 Is32BitAddress, IDLoc, Out, STI);
2961 if (!
ABI.ArePtrs64bit()) {
2963 Is32BitAddress =
true;
2966 return loadImmediate(
Offset.getImm(), DstReg, BaseReg, Is32BitAddress,
true,
2970bool MipsAsmParser::loadAndAddSymbolAddress(
const MCExpr *SymExpr,
2971 unsigned DstReg,
unsigned SrcReg,
2972 bool Is32BitSym,
SMLoc IDLoc,
2976 bool UseSrcReg = SrcReg != Mips::NoRegister && SrcReg != Mips::ZERO &&
2977 SrcReg != Mips::ZERO_64;
2978 warnIfNoMacro(IDLoc);
2983 Error(IDLoc,
"expected relocatable expression");
2986 if (Res.
getSymB() !=
nullptr) {
2987 Error(IDLoc,
"expected relocatable expression with only one symbol");
2991 bool IsPtr64 =
ABI.ArePtrs64bit();
3003 bool UseXGOT = STI->
hasFeature(Mips::FeatureXGOT) && !IsLocalSym;
3009 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
3013 SymExpr, getContext());
3015 SymExpr, getContext());
3018 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, DstReg, GPReg,
3020 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, DstReg,
3025 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, GPReg,
3031 unsigned TmpReg = DstReg;
3033 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
3037 unsigned ATReg = getATReg(IDLoc);
3056 const MCExpr *CallHiExpr =
3063 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg, GPReg,
3065 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, TmpReg,
3069 TOut.
emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3075 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3081 const MCExpr *LoExpr =
nullptr;
3082 if (
ABI.IsN32() ||
ABI.IsN64()) {
3101 Error(IDLoc,
"macro instruction uses large offset, which is not "
3102 "currently supported");
3132 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, GPReg,
3136 TOut.
emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3140 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3152 if (
ABI.ArePtrs64bit() && isGP64bit()) {
3167 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
3169 if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
3170 unsigned ATReg = getATReg(IDLoc);
3182 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3184 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3187 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3190 TOut.
emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
3193 }
else if (canUseATReg() && !RdRegIsRsReg && DstReg != getATReg(IDLoc)) {
3194 unsigned ATReg = getATReg(IDLoc);
3210 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3214 TOut.
emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3215 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3217 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3220 }
else if ((!canUseATReg() && !RdRegIsRsReg) ||
3221 (canUseATReg() && DstReg == getATReg(IDLoc))) {
3232 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3234 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3235 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3237 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3238 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3241 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3247 assert(SrcReg == DstReg && !canUseATReg() &&
3248 "Could have expanded dla but didn't?");
3249 reportParseError(IDLoc,
3250 "pseudo-instruction requires $at, which is not available");
3264 unsigned TmpReg = DstReg;
3266 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
3269 unsigned ATReg = getATReg(IDLoc);
3280 TOut.
emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3283 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
3292 if (MipsMCRegisterClasses[Mips::FGR32RegClassID].
contains(
Reg))
3293 return Reg == (
unsigned)Mips::F31 ? (
unsigned)Mips::F0 :
Reg + 1;
3295 default:
llvm_unreachable(
"Unknown register in assembly macro expansion!");
3296 case Mips::ZERO:
return Mips::AT;
3297 case Mips::AT:
return Mips::V0;
3298 case Mips::V0:
return Mips::V1;
3299 case Mips::V1:
return Mips::A0;
3300 case Mips::A0:
return Mips::A1;
3301 case Mips::A1:
return Mips::A2;
3302 case Mips::A2:
return Mips::A3;
3303 case Mips::A3:
return Mips::T0;
3304 case Mips::T0:
return Mips::T1;
3305 case Mips::T1:
return Mips::T2;
3306 case Mips::T2:
return Mips::T3;
3307 case Mips::T3:
return Mips::T4;
3308 case Mips::T4:
return Mips::T5;
3309 case Mips::T5:
return Mips::T6;
3310 case Mips::T6:
return Mips::T7;
3311 case Mips::T7:
return Mips::S0;
3312 case Mips::S0:
return Mips::S1;
3313 case Mips::S1:
return Mips::S2;
3314 case Mips::S2:
return Mips::S3;
3315 case Mips::S3:
return Mips::S4;
3316 case Mips::S4:
return Mips::S5;
3317 case Mips::S5:
return Mips::S6;
3318 case Mips::S6:
return Mips::S7;
3319 case Mips::S7:
return Mips::T8;
3320 case Mips::T8:
return Mips::T9;
3321 case Mips::T9:
return Mips::K0;
3322 case Mips::K0:
return Mips::K1;
3323 case Mips::K1:
return Mips::GP;
3324 case Mips::GP:
return Mips::SP;
3325 case Mips::SP:
return Mips::FP;
3326 case Mips::FP:
return Mips::RA;
3327 case Mips::RA:
return Mips::ZERO;
3328 case Mips::D0:
return Mips::F1;
3329 case Mips::D1:
return Mips::F3;
3330 case Mips::D2:
return Mips::F5;
3331 case Mips::D3:
return Mips::F7;
3332 case Mips::D4:
return Mips::F9;
3333 case Mips::D5:
return Mips::F11;
3334 case Mips::D6:
return Mips::F13;
3335 case Mips::D7:
return Mips::F15;
3336 case Mips::D8:
return Mips::F17;
3337 case Mips::D9:
return Mips::F19;
3338 case Mips::D10:
return Mips::F21;
3339 case Mips::D11:
return Mips::F23;
3340 case Mips::D12:
return Mips::F25;
3341 case Mips::D13:
return Mips::F27;
3342 case Mips::D14:
return Mips::F29;
3343 case Mips::D15:
return Mips::F31;
3355 unsigned ATReg = getATReg(IDLoc);
3365 if(isABI_O32() || isABI_N32()) {
3384 if(isABI_O32() || isABI_N32()) {
3387 const MCExpr *HighestSym =
3391 const MCExpr *HigherSym =
3398 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3400 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3403 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3412 if ((
Hi_32(ImmOp64) & 0x7ff00000) == 0) {
3413 APFloat RealVal(APFloat::IEEEdouble(), ImmOp64);
3422 double DoubleImm = llvm::bit_cast<double>(ImmOp64);
3423 float TmpFloat =
static_cast<float>(DoubleImm);
3424 return llvm::bit_cast<uint32_t>(TmpFloat);
3427bool MipsAsmParser::expandLoadSingleImmToGPR(
MCInst &Inst,
SMLoc IDLoc,
3432 "Invalid instruction operand.");
3439 return loadImmediate(ImmOp32, FirstReg, Mips::NoRegister,
true,
false, IDLoc,
3443bool MipsAsmParser::expandLoadSingleImmToFPR(
MCInst &Inst,
SMLoc IDLoc,
3449 "Invalid instruction operand.");
3458 unsigned TmpReg = Mips::ZERO;
3460 TmpReg = getATReg(IDLoc);
3465 if (
Lo_32(ImmOp64) == 0) {
3466 if (TmpReg != Mips::ZERO && loadImmediate(ImmOp32, TmpReg, Mips::NoRegister,
3467 true,
false, IDLoc, Out, STI))
3469 TOut.
emitRR(Mips::MTC1, FirstReg, TmpReg, IDLoc, STI);
3473 MCSection *CS = getStreamer().getCurrentSectionOnly();
3485 getStreamer().switchSection(ReadOnlySection);
3486 getStreamer().emitLabel(
Sym, IDLoc);
3487 getStreamer().emitInt32(ImmOp32);
3488 getStreamer().switchSection(CS);
3490 if (emitPartialAddress(TOut, IDLoc,
Sym))
3497bool MipsAsmParser::expandLoadDoubleImmToGPR(
MCInst &Inst,
SMLoc IDLoc,
3503 "Invalid instruction operand.");
3510 if (
Lo_32(ImmOp64) == 0) {
3512 if (loadImmediate(ImmOp64, FirstReg, Mips::NoRegister,
false,
false,
3516 if (loadImmediate(
Hi_32(ImmOp64), FirstReg, Mips::NoRegister,
true,
false,
3520 if (loadImmediate(0,
nextReg(FirstReg), Mips::NoRegister,
true,
false,
3527 MCSection *CS = getStreamer().getCurrentSectionOnly();
3537 getStreamer().switchSection(ReadOnlySection);
3538 getStreamer().emitLabel(
Sym, IDLoc);
3539 getStreamer().emitValueToAlignment(
Align(8));
3540 getStreamer().emitIntValue(ImmOp64, 8);
3541 getStreamer().switchSection(CS);
3543 unsigned TmpReg = getATReg(IDLoc);
3547 if (emitPartialAddress(TOut, IDLoc,
Sym))
3550 TOut.
emitRRX(isABI_N64() ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3554 TOut.
emitRRI(Mips::LD, FirstReg, TmpReg, 0, IDLoc, STI);
3556 TOut.
emitRRI(Mips::LW, FirstReg, TmpReg, 0, IDLoc, STI);
3557 TOut.
emitRRI(Mips::LW,
nextReg(FirstReg), TmpReg, 4, IDLoc, STI);
3562bool MipsAsmParser::expandLoadDoubleImmToFPR(
MCInst &Inst,
bool Is64FPU,
3568 "Invalid instruction operand.");
3575 unsigned TmpReg = Mips::ZERO;
3577 TmpReg = getATReg(IDLoc);
3582 if ((
Lo_32(ImmOp64) == 0) &&
3583 !((
Hi_32(ImmOp64) & 0xffff0000) && (
Hi_32(ImmOp64) & 0x0000ffff))) {
3585 if (TmpReg != Mips::ZERO &&
3586 loadImmediate(ImmOp64, TmpReg, Mips::NoRegister,
false,
false, IDLoc,
3589 TOut.
emitRR(Mips::DMTC1, FirstReg, TmpReg, IDLoc, STI);
3593 if (TmpReg != Mips::ZERO &&
3594 loadImmediate(
Hi_32(ImmOp64), TmpReg, Mips::NoRegister,
true,
false,
3598 if (hasMips32r2()) {
3599 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3600 TOut.
emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, TmpReg, IDLoc, STI);
3602 TOut.
emitRR(Mips::MTC1,
nextReg(FirstReg), TmpReg, IDLoc, STI);
3603 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3608 MCSection *CS = getStreamer().getCurrentSectionOnly();
3620 getStreamer().switchSection(ReadOnlySection);
3621 getStreamer().emitLabel(
Sym, IDLoc);
3622 getStreamer().emitValueToAlignment(
Align(8));
3623 getStreamer().emitIntValue(ImmOp64, 8);
3624 getStreamer().switchSection(CS);
3626 if (emitPartialAddress(TOut, IDLoc,
Sym))
3629 TOut.
emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, TmpReg,
3635bool MipsAsmParser::expandUncondBranchMMPseudo(
MCInst &Inst,
SMLoc IDLoc,
3641 "unexpected number of operands");
3651 assert(
Offset.isImm() &&
"expected immediate operand kind");
3652 if (isInt<11>(
Offset.getImm())) {
3655 if (inMicroMipsMode())
3656 Inst.
setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3658 if (!isInt<17>(
Offset.getImm()))
3659 return Error(IDLoc,
"branch target out of range");
3661 return Error(IDLoc,
"branch to misaligned address");
3684 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3687 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
3691 "expected immediate or expression operand");
3693 bool IsLikely =
false;
3703 case Mips::BEQLImmMacro:
3707 case Mips::BNELImmMacro:
3716 int64_t ImmValue = ImmOp.
getImm();
3717 if (ImmValue == 0) {
3721 TOut.
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3723 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3726 warnIfNoMacro(IDLoc);
3728 unsigned ATReg = getATReg(IDLoc);
3732 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(),
true,
3739 TOut.
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3741 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3749 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3750 unsigned StartOp = NumOp == 3 ? 0 : 1;
3753 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3755 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3760 unsigned DstReg = DstRegOp.
getReg();
3761 unsigned BaseReg = BaseRegOp.
getReg();
3762 unsigned TmpReg = DstReg;
3765 int16_t DstRegClass =
Desc.operands()[StartOp].RegClass;
3766 unsigned DstRegClassID =
3767 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3768 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3769 (DstRegClassID == Mips::GPR64RegClassID);
3771 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3774 TmpReg = getATReg(IDLoc);
3781 TOut.
emitRRX(OpCode, DstReg, TmpReg, Off, IDLoc, STI);
3783 TOut.
emitRRRX(OpCode, DstReg, DstReg, TmpReg, Off, IDLoc, STI);
3786 if (OffsetOp.
isImm()) {
3787 int64_t LoOffset = OffsetOp.
getImm() & 0xffff;
3788 int64_t HiOffset = OffsetOp.
getImm() & ~0xffff;
3792 if (LoOffset & 0x8000)
3793 HiOffset += 0x10000;
3795 bool IsLargeOffset = HiOffset != 0;
3797 if (IsLargeOffset) {
3798 bool Is32BitImm = isInt<32>(OffsetOp.
getImm());
3799 if (loadImmediate(HiOffset, TmpReg, Mips::NoRegister, Is32BitImm,
true,
3804 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3805 TOut.
emitRRR(
ABI.ArePtrs64bit() ? Mips::DADDu : Mips::ADDu, TmpReg,
3806 TmpReg, BaseReg, IDLoc, STI);
3821 Error(IDLoc,
"expected relocatable expression");
3824 if (Res.
getSymB() !=
nullptr) {
3825 Error(IDLoc,
"expected relocatable expression with only one symbol");
3829 loadAndAddSymbolAddress(Res.
getSymA(), TmpReg, BaseReg,
3830 !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3850 TOut.
emitRX(Mips::LUi, TmpReg, HighestOperand, IDLoc, STI);
3851 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HigherOperand, IDLoc, STI);
3852 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3853 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HiOperand, IDLoc, STI);
3854 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3855 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3856 TOut.
emitRRR(Mips::DADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3857 emitInstWithOffset(LoOperand);
3860 TOut.
emitRX(Mips::LUi, TmpReg, HiOperand, IDLoc, STI);
3861 if (BaseReg != Mips::ZERO)
3862 TOut.
emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3864 emitInstWithOffset(LoOperand);
3876 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3877 unsigned StartOp = NumOp == 3 ? 0 : 1;
3880 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3882 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3887 unsigned DstReg = DstRegOp.
getReg();
3888 unsigned BaseReg = BaseRegOp.
getReg();
3889 unsigned TmpReg = DstReg;
3892 int16_t DstRegClass =
Desc.operands()[StartOp].RegClass;
3893 unsigned DstRegClassID =
3894 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3895 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3896 (DstRegClassID == Mips::GPR64RegClassID);
3898 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3901 TmpReg = getATReg(IDLoc);
3906 auto emitInst = [&]() {
3914 if (OffsetOp.
isImm()) {
3915 loadImmediate(OffsetOp.
getImm(), TmpReg, BaseReg, !
ABI.ArePtrs64bit(),
true,
3922 loadAndAddSymbolAddress(OffsetOp.
getExpr(), TmpReg, BaseReg,
3923 !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3931bool MipsAsmParser::expandLoadStoreMultiple(
MCInst &Inst,
SMLoc IDLoc,
3936 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3940 Inst.
getOperand(OpNum - 3).
isReg() &&
"Invalid instruction operand.");
3949 if (inMicroMipsMode() && hasMips32r6())
3950 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3952 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3960bool MipsAsmParser::expandCondBranches(
MCInst &Inst,
SMLoc IDLoc,
3964 bool EmittedNoMacroWarning =
false;
3965 unsigned PseudoOpcode = Inst.
getOpcode();
3970 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3971 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3976 else if (TrgOp.
isImm()) {
3977 warnIfNoMacro(IDLoc);
3978 EmittedNoMacroWarning =
true;
3980 TrgReg = getATReg(IDLoc);
3984 switch(PseudoOpcode) {
3987 case Mips::BLTImmMacro:
3988 PseudoOpcode = Mips::BLT;
3990 case Mips::BLEImmMacro:
3991 PseudoOpcode = Mips::BLE;
3993 case Mips::BGEImmMacro:
3994 PseudoOpcode = Mips::BGE;
3996 case Mips::BGTImmMacro:
3997 PseudoOpcode = Mips::BGT;
3999 case Mips::BLTUImmMacro:
4000 PseudoOpcode = Mips::BLTU;
4002 case Mips::BLEUImmMacro:
4003 PseudoOpcode = Mips::BLEU;
4005 case Mips::BGEUImmMacro:
4006 PseudoOpcode = Mips::BGEU;
4008 case Mips::BGTUImmMacro:
4009 PseudoOpcode = Mips::BGTU;
4011 case Mips::BLTLImmMacro:
4012 PseudoOpcode = Mips::BLTL;
4014 case Mips::BLELImmMacro:
4015 PseudoOpcode = Mips::BLEL;
4017 case Mips::BGELImmMacro:
4018 PseudoOpcode = Mips::BGEL;
4020 case Mips::BGTLImmMacro:
4021 PseudoOpcode = Mips::BGTL;
4023 case Mips::BLTULImmMacro:
4024 PseudoOpcode = Mips::BLTUL;
4026 case Mips::BLEULImmMacro:
4027 PseudoOpcode = Mips::BLEUL;
4029 case Mips::BGEULImmMacro:
4030 PseudoOpcode = Mips::BGEUL;
4032 case Mips::BGTULImmMacro:
4033 PseudoOpcode = Mips::BGTUL;
4037 if (loadImmediate(TrgOp.
getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
4038 false, IDLoc, Out, STI))
4042 switch (PseudoOpcode) {
4047 AcceptsEquality =
false;
4048 ReverseOrderSLT =
false;
4050 ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
4051 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
4052 ZeroSrcOpcode = Mips::BGTZ;
4053 ZeroTrgOpcode = Mips::BLTZ;
4059 AcceptsEquality =
true;
4060 ReverseOrderSLT =
true;
4062 ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
4063 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
4064 ZeroSrcOpcode = Mips::BGEZ;
4065 ZeroTrgOpcode = Mips::BLEZ;
4071 AcceptsEquality =
true;
4072 ReverseOrderSLT =
false;
4074 ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
4075 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
4076 ZeroSrcOpcode = Mips::BLEZ;
4077 ZeroTrgOpcode = Mips::BGEZ;
4083 AcceptsEquality =
false;
4084 ReverseOrderSLT =
true;
4086 ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
4087 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
4088 ZeroSrcOpcode = Mips::BLTZ;
4089 ZeroTrgOpcode = Mips::BGTZ;
4095 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
4096 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
4097 if (IsSrcRegZero && IsTrgRegZero) {
4101 if (PseudoOpcode == Mips::BLT) {
4106 if (PseudoOpcode == Mips::BLE) {
4109 Warning(IDLoc,
"branch is always taken");
4112 if (PseudoOpcode == Mips::BGE) {
4115 Warning(IDLoc,
"branch is always taken");
4118 if (PseudoOpcode == Mips::BGT) {
4123 if (PseudoOpcode == Mips::BGTU) {
4124 TOut.
emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
4128 if (AcceptsEquality) {
4131 TOut.
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4133 Warning(IDLoc,
"branch is always taken");
4140 if (IsSrcRegZero || IsTrgRegZero) {
4141 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
4142 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
4149 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
4150 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
4156 TOut.
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4158 Warning(IDLoc,
"branch is always taken");
4174 TOut.
emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
4175 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
4182 TOut.
emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
4183 IsSrcRegZero ? TrgReg : SrcReg,
4190 unsigned ATRegNum = getATReg(IDLoc);
4194 if (!EmittedNoMacroWarning)
4195 warnIfNoMacro(IDLoc);
4212 TOut.
emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
4213 ReverseOrderSLT ? TrgReg : SrcReg,
4214 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
4216 TOut.
emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
4217 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
4233 const bool IsMips64,
const bool Signed) {
4236 warnIfNoMacro(IDLoc);
4239 assert(RdRegOp.
isReg() &&
"expected register operand kind");
4240 unsigned RdReg = RdRegOp.
getReg();
4243 assert(RsRegOp.
isReg() &&
"expected register operand kind");
4244 unsigned RsReg = RsRegOp.
getReg();
4251 "expected register or immediate operand kind");
4255 ImmValue = RtOp.
getImm();
4262 DivOp =
Signed ? Mips::DSDIV : Mips::DUDIV;
4263 ZeroReg = Mips::ZERO_64;
4266 DivOp =
Signed ? Mips::SDIV : Mips::UDIV;
4267 ZeroReg = Mips::ZERO;
4271 bool UseTraps = useTraps();
4274 bool isDiv = Opcode == Mips::SDivMacro || Opcode == Mips::SDivIMacro ||
4275 Opcode == Mips::UDivMacro || Opcode == Mips::UDivIMacro ||
4276 Opcode == Mips::DSDivMacro || Opcode == Mips::DSDivIMacro ||
4277 Opcode == Mips::DUDivMacro || Opcode == Mips::DUDivIMacro;
4279 bool isRem = Opcode == Mips::SRemMacro || Opcode == Mips::SRemIMacro ||
4280 Opcode == Mips::URemMacro || Opcode == Mips::URemIMacro ||
4281 Opcode == Mips::DSRemMacro || Opcode == Mips::DSRemIMacro ||
4282 Opcode == Mips::DURemMacro || Opcode == Mips::DURemIMacro;
4285 unsigned ATReg = getATReg(IDLoc);
4289 if (ImmValue == 0) {
4291 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4293 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4297 if (isRem && (ImmValue == 1 || (
Signed && (ImmValue == -1)))) {
4298 TOut.
emitRRR(Mips::OR, RdReg, ZeroReg, ZeroReg, IDLoc, STI);
4300 }
else if (isDiv && ImmValue == 1) {
4301 TOut.
emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI);
4303 }
else if (isDiv &&
Signed && ImmValue == -1) {
4304 TOut.
emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
4307 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, isInt<32>(ImmValue),
4308 false, Inst.
getLoc(), Out, STI))
4310 TOut.
emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
4311 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4321 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
4323 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4326 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4332 if (isRem && (RdReg == Mips::ZERO || RdReg == Mips::ZERO_64)) {
4333 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4343 TOut.
emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4348 TOut.
emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4351 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4354 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4360 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4364 unsigned ATReg = getATReg(IDLoc);
4371 TOut.
emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
4379 TOut.
emitRRX(Mips::BNE, RtReg, ATReg, LabelOpEnd, IDLoc, STI);
4382 TOut.
emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
4383 TOut.
emitDSLL(ATReg, ATReg, 63, IDLoc, STI);
4389 TOut.
emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
4392 TOut.
emitRRX(Mips::BNE, RsReg, ATReg, LabelOpEnd, IDLoc, STI);
4394 TOut.
emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
4398 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4402bool MipsAsmParser::expandTrunc(
MCInst &Inst,
bool IsDouble,
bool Is64FPU,
4415 if (hasMips1() && !hasMips2()) {
4416 unsigned ATReg = getATReg(IDLoc);
4419 TOut.
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4420 TOut.
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4422 TOut.
emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4423 TOut.
emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4424 TOut.
emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4426 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4428 FirstReg, SecondReg, IDLoc, STI);
4429 TOut.
emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4434 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4436 FirstReg, SecondReg, IDLoc, STI);
4443 if (hasMips32r6() || hasMips64r6()) {
4444 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4448 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4450 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4452 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4455 unsigned DstReg = DstRegOp.
getReg();
4456 unsigned SrcReg = SrcRegOp.
getReg();
4457 int64_t OffsetValue = OffsetImmOp.
getImm();
4461 warnIfNoMacro(IDLoc);
4462 unsigned ATReg = getATReg(IDLoc);
4466 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4467 if (IsLargeOffset) {
4468 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4473 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4474 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4478 unsigned FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4479 unsigned SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4481 unsigned LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4482 unsigned SllReg = IsLargeOffset ? DstReg : ATReg;
4484 TOut.
emitRRI(
Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4485 FirstOffset, IDLoc, STI);
4486 TOut.
emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4487 TOut.
emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4488 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4495 if (hasMips32r6() || hasMips64r6()) {
4496 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4500 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4502 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4504 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4507 unsigned DstReg = DstRegOp.
getReg();
4508 unsigned SrcReg = SrcRegOp.
getReg();
4509 int64_t OffsetValue = OffsetImmOp.
getImm();
4511 warnIfNoMacro(IDLoc);
4512 unsigned ATReg = getATReg(IDLoc);
4516 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4517 if (IsLargeOffset) {
4518 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4523 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4524 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4528 if (IsLargeOffset) {
4529 TOut.
emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4530 TOut.
emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4531 TOut.
emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4532 TOut.
emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4533 TOut.
emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4534 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4536 TOut.
emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4537 TOut.
emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4538 TOut.
emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4546 if (hasMips32r6() || hasMips64r6()) {
4547 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4551 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4553 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4555 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4558 unsigned DstReg = DstRegOp.
getReg();
4559 unsigned SrcReg = SrcRegOp.
getReg();
4560 int64_t OffsetValue = OffsetImmOp.
getImm();
4563 bool IsLargeOffset = !(isInt<16>(OffsetValue + 3) && isInt<16>(OffsetValue));
4564 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4565 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4569 bool IsLoadInst = (Inst.
getOpcode() == Mips::Ulw);
4570 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4571 unsigned TmpReg = SrcReg;
4572 if (IsLargeOffset || DoMove) {
4573 warnIfNoMacro(IDLoc);
4574 TmpReg = getATReg(IDLoc);
4579 if (IsLargeOffset) {
4580 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4588 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4589 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4590 TOut.
emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4591 TOut.
emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4594 TOut.
emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4613 warnIfNoMacro(IDLoc);
4627 TOut.
emitRRR(OpCode, DstReg, SrcReg, OpReg, IDLoc, STI);
4628 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4645 unsigned OpRegCode, OpImmCode;
4647 warnIfNoMacro(IDLoc);
4651 case Mips::SGEImm64:
4652 OpRegCode = Mips::SLT;
4653 OpImmCode = Mips::SLTi;
4656 case Mips::SGEUImm64:
4657 OpRegCode = Mips::SLTu;
4658 OpImmCode = Mips::SLTiu;
4665 if (isInt<16>(ImmValue)) {
4667 TOut.
emitRRI(OpImmCode, DstReg, SrcReg, ImmValue, IDLoc, STI);
4668 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4670 unsigned ImmReg = DstReg;
4671 if (DstReg == SrcReg) {
4672 unsigned ATReg = getATReg(Inst.
getLoc());
4678 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4679 false, IDLoc, Out, STI))
4682 TOut.
emitRRR(OpRegCode, DstReg, SrcReg, ImmReg, IDLoc, STI);
4683 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4700 unsigned ImmReg = DstReg;
4704 warnIfNoMacro(IDLoc);
4708 case Mips::SGTImm64:
4712 case Mips::SGTUImm64:
4719 if (DstReg == SrcReg) {
4720 unsigned ATReg = getATReg(Inst.
getLoc());
4726 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4727 false, IDLoc, Out, STI))
4731 TOut.
emitRRR(OpCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4750 warnIfNoMacro(IDLoc);
4764 TOut.
emitRRR(OpCode, DstReg, OpReg, SrcReg, IDLoc, STI);
4765 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4784 warnIfNoMacro(IDLoc);
4788 case Mips::SLEImm64:
4789 OpRegCode = Mips::SLT;
4792 case Mips::SLEUImm64:
4793 OpRegCode = Mips::SLTu;
4800 unsigned ImmReg = DstReg;
4801 if (DstReg == SrcReg) {
4802 unsigned ATReg = getATReg(Inst.
getLoc());
4808 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4809 false, IDLoc, Out, STI))
4812 TOut.
emitRRR(OpRegCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4813 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4818bool MipsAsmParser::expandAliasImmediate(
MCInst &Inst,
SMLoc IDLoc,
4828 unsigned ATReg = Mips::NoRegister;
4829 unsigned FinalDstReg = Mips::NoRegister;
4834 bool Is32Bit = isInt<32>(ImmValue) || (!isGP64bit() && isUInt<32>(ImmValue));
4836 unsigned FinalOpcode = Inst.
getOpcode();
4838 if (DstReg == SrcReg) {
4839 ATReg = getATReg(Inst.
getLoc());
4842 FinalDstReg = DstReg;
4846 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit,
false,
4847 Inst.
getLoc(), Out, STI)) {
4848 switch (FinalOpcode) {
4852 FinalOpcode = Mips::ADD;
4855 FinalOpcode = Mips::ADDu;
4858 FinalOpcode = Mips::AND;
4861 FinalOpcode = Mips::NOR;
4864 FinalOpcode = Mips::OR;
4867 FinalOpcode = Mips::SLT;
4870 FinalOpcode = Mips::SLTu;
4873 FinalOpcode = Mips::XOR;
4876 FinalOpcode = Mips::ADD_MM;
4878 case Mips::ADDiu_MM:
4879 FinalOpcode = Mips::ADDu_MM;
4882 FinalOpcode = Mips::AND_MM;
4885 FinalOpcode = Mips::OR_MM;
4888 FinalOpcode = Mips::SLT_MM;
4890 case Mips::SLTiu_MM:
4891 FinalOpcode = Mips::SLTu_MM;
4894 FinalOpcode = Mips::XOR_MM;
4897 FinalOpcode = Mips::AND64;
4899 case Mips::NORImm64:
4900 FinalOpcode = Mips::NOR64;
4903 FinalOpcode = Mips::OR64;
4905 case Mips::SLTImm64:
4906 FinalOpcode = Mips::SLT64;
4908 case Mips::SLTUImm64:
4909 FinalOpcode = Mips::SLTu64;
4912 FinalOpcode = Mips::XOR64;
4916 if (FinalDstReg == Mips::NoRegister)
4917 TOut.
emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4919 TOut.
emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4928 unsigned ATReg = Mips::NoRegister;
4932 unsigned TmpReg =
DReg;
4934 unsigned FirstShift = Mips::NOP;
4935 unsigned SecondShift = Mips::NOP;
4937 if (hasMips32r2()) {
4939 TmpReg = getATReg(Inst.
getLoc());
4945 TOut.
emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4946 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
4951 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
4963 FirstShift = Mips::SRLV;
4964 SecondShift = Mips::SLLV;
4967 FirstShift = Mips::SLLV;
4968 SecondShift = Mips::SRLV;
4972 ATReg = getATReg(Inst.
getLoc());
4976 TOut.
emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4977 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
4978 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
4979 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
4987bool MipsAsmParser::expandRotationImm(
MCInst &Inst,
SMLoc IDLoc,
4991 unsigned ATReg = Mips::NoRegister;
4996 unsigned FirstShift = Mips::NOP;
4997 unsigned SecondShift = Mips::NOP;
4999 if (hasMips32r2()) {
5004 ShiftValue = MaxShift - ImmValue;
5005 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
5010 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.
getLoc(), STI);
5018 if (ImmValue == 0) {
5027 FirstShift = Mips::SLL;
5028 SecondShift = Mips::SRL;
5031 FirstShift = Mips::SRL;
5032 SecondShift = Mips::SLL;
5036 ATReg = getATReg(Inst.
getLoc());
5040 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.
getLoc(), STI);
5041 TOut.
emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.
getLoc(), STI);
5042 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5053 unsigned ATReg = Mips::NoRegister;
5057 unsigned TmpReg =
DReg;
5059 unsigned FirstShift = Mips::NOP;
5060 unsigned SecondShift = Mips::NOP;
5062 if (hasMips64r2()) {
5063 if (TmpReg == SReg) {
5064 TmpReg = getATReg(Inst.
getLoc());
5070 TOut.
emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
5071 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
5076 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
5088 FirstShift = Mips::DSRLV;
5089 SecondShift = Mips::DSLLV;
5092 FirstShift = Mips::DSLLV;
5093 SecondShift = Mips::DSRLV;
5097 ATReg = getATReg(Inst.
getLoc());
5101 TOut.
emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
5102 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
5103 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
5104 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5112bool MipsAsmParser::expandDRotationImm(
MCInst &Inst,
SMLoc IDLoc,
5116 unsigned ATReg = Mips::NoRegister;
5121 unsigned FirstShift = Mips::NOP;
5122 unsigned SecondShift = Mips::NOP;
5126 if (hasMips64r2()) {
5127 unsigned FinalOpcode = Mips::NOP;
5129 FinalOpcode = Mips::DROTR;
5130 else if (ImmValue % 32 == 0)
5131 FinalOpcode = Mips::DROTR32;
5132 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
5134 FinalOpcode = Mips::DROTR32;
5136 FinalOpcode = Mips::DROTR;
5137 }
else if (ImmValue >= 33) {
5139 FinalOpcode = Mips::DROTR;
5141 FinalOpcode = Mips::DROTR32;
5144 uint64_t ShiftValue = ImmValue % 32;
5146 ShiftValue = (32 - ImmValue % 32) % 32;
5148 TOut.
emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
5154 if (ImmValue == 0) {
5155 TOut.
emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.
getLoc(), STI);
5163 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5164 FirstShift = Mips::DSLL;
5165 SecondShift = Mips::DSRL32;
5167 if (ImmValue == 32) {
5168 FirstShift = Mips::DSLL32;
5169 SecondShift = Mips::DSRL32;
5171 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5172 FirstShift = Mips::DSLL32;
5173 SecondShift = Mips::DSRL;
5177 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5178 FirstShift = Mips::DSRL;
5179 SecondShift = Mips::DSLL32;
5181 if (ImmValue == 32) {
5182 FirstShift = Mips::DSRL32;
5183 SecondShift = Mips::DSLL32;
5185 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5186 FirstShift = Mips::DSRL32;
5187 SecondShift = Mips::DSLL;
5192 ATReg = getATReg(Inst.
getLoc());
5196 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.
getLoc(), STI);
5197 TOut.
emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
5199 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5213 TOut.
emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
5214 if (FirstRegOp != SecondRegOp)
5215 TOut.
emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
5218 TOut.
emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
5226 unsigned ATReg = Mips::NoRegister;
5231 ATReg = getATReg(IDLoc);
5235 loadImmediate(ImmValue, ATReg, Mips::NoRegister,
true,
false, IDLoc, Out,
5238 TOut.
emitRR(Inst.
getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
5239 SrcReg, ATReg, IDLoc, STI);
5241 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5249 unsigned ATReg = Mips::NoRegister;
5254 ATReg = getATReg(Inst.
getLoc());
5258 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
5259 SrcReg, TmpReg, IDLoc, STI);
5261 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5263 TOut.
emitRRI(Inst.
getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
5264 DstReg, DstReg, 0x1F, IDLoc, STI);
5266 TOut.
emitR(Mips::MFHI, ATReg, IDLoc, STI);
5269 TOut.
emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
5276 TOut.
emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
5277 if (AssemblerOptions.
back()->isReorder())
5279 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5283 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5291 unsigned ATReg = Mips::NoRegister;
5296 ATReg = getATReg(IDLoc);
5300 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
5301 SrcReg, TmpReg, IDLoc, STI);
5303 TOut.
emitR(Mips::MFHI, ATReg, IDLoc, STI);
5304 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5306 TOut.
emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);
5313 TOut.
emitRRX(Mips::BEQ, ATReg, Mips::ZERO, LabelOp, IDLoc, STI);
5314 if (AssemblerOptions.
back()->isReorder())
5316 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5331 TOut.
emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
5332 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5342bool MipsAsmParser::expandLoadStoreDMacro(
MCInst &Inst,
SMLoc IDLoc,
5349 warnIfNoMacro(IDLoc);
5352 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
5354 unsigned SecondReg =
nextReg(FirstReg);
5359 warnIfRegIndexIsAT(FirstReg, IDLoc);
5362 "Offset for load macro is not immediate!");
5365 signed NextOffset = FirstOffset.
getImm() + 4;
5368 if (!isInt<16>(FirstOffset.
getImm()) || !isInt<16>(NextOffset))
5373 if (FirstReg != BaseReg || !IsLoad) {
5374 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5375 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5377 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5378 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5390bool MipsAsmParser::expandStoreDM1Macro(
MCInst &Inst,
SMLoc IDLoc,
5396 warnIfNoMacro(IDLoc);
5399 unsigned Opcode = Mips::SWC1;
5401 unsigned SecondReg =
nextReg(FirstReg);
5406 warnIfRegIndexIsAT(FirstReg, IDLoc);
5409 "Offset for macro is not immediate!");
5412 signed NextOffset = FirstOffset.
getImm() + 4;
5415 if (!isInt<16>(FirstOffset.
getImm()) || !isInt<16>(NextOffset))
5418 if (!IsLittleEndian)
5421 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5422 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5440 warnIfNoMacro(IDLoc);
5442 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5443 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5444 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5448 unsigned Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5449 TOut.
emitRRI(Mips::SLTiu, DstReg,
Reg, 1, IDLoc, STI);
5466 warnIfNoMacro(IDLoc);
5469 TOut.
emitRRI(Mips::SLTiu, DstReg, SrcReg, 1, IDLoc, STI);
5473 if (SrcReg == Mips::ZERO) {
5474 Warning(IDLoc,
"comparison is always false");
5475 TOut.
emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
5476 DstReg, SrcReg, SrcReg, IDLoc, STI);
5481 if (Imm > -0x8000 && Imm < 0) {
5483 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5488 if (!isUInt<16>(Imm)) {
5489 unsigned ATReg = getATReg(IDLoc);
5493 if (loadImmediate(Imm, ATReg, Mips::NoRegister,
true, isGP64bit(), IDLoc,
5497 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5498 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5502 TOut.
emitRRI(Opc, DstReg, SrcReg, Imm, IDLoc, STI);
5503 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5521 warnIfNoMacro(IDLoc);
5523 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5524 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5525 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5529 unsigned Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5530 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO,
Reg, IDLoc, STI);
5547 warnIfNoMacro(IDLoc);
5549 if (ImmValue == 0) {
5550 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, SrcReg, IDLoc, STI);
5554 if (SrcReg == Mips::ZERO) {
5555 Warning(IDLoc,
"comparison is always true");
5556 if (loadImmediate(1, DstReg, Mips::NoRegister,
true,
false, IDLoc, Out,
5563 if (ImmValue > -0x8000 && ImmValue < 0) {
5564 ImmValue = -ImmValue;
5565 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5570 if (isUInt<16>(ImmValue)) {
5571 TOut.
emitRRI(Opc, DstReg, SrcReg, ImmValue, IDLoc, STI);
5572 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5576 unsigned ATReg = getATReg(IDLoc);
5580 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, isInt<32>(ImmValue),
5581 false, IDLoc, Out, STI))
5584 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5585 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5648 case Mips::F0:
return Mips::ZERO;
5649 case Mips::F1:
return Mips::AT;
5650 case Mips::F2:
return Mips::V0;
5651 case Mips::F3:
return Mips::V1;
5652 case Mips::F4:
return Mips::A0;
5653 case Mips::F5:
return Mips::A1;
5654 case Mips::F6:
return Mips::A2;
5655 case Mips::F7:
return Mips::A3;
5656 case Mips::F8:
return Mips::T0;
5657 case Mips::F9:
return Mips::T1;
5658 case Mips::F10:
return Mips::T2;
5659 case Mips::F11:
return Mips::T3;
5660 case Mips::F12:
return Mips::T4;
5661 case Mips::F13:
return Mips::T5;
5662 case Mips::F14:
return Mips::T6;
5663 case Mips::F15:
return Mips::T7;
5664 case Mips::F16:
return Mips::S0;
5665 case Mips::F17:
return Mips::S1;
5666 case Mips::F18:
return Mips::S2;
5667 case Mips::F19:
return Mips::S3;
5668 case Mips::F20:
return Mips::S4;
5669 case Mips::F21:
return Mips::S5;
5670 case Mips::F22:
return Mips::S6;
5671 case Mips::F23:
return Mips::S7;
5672 case Mips::F24:
return Mips::T8;
5673 case Mips::F25:
return Mips::T9;
5674 case Mips::F26:
return Mips::K0;
5675 case Mips::F27:
return Mips::K1;
5676 case Mips::F28:
return Mips::GP;
5677 case Mips::F29:
return Mips::SP;
5678 case Mips::F30:
return Mips::FP;
5679 case Mips::F31:
return Mips::RA;
5687 case Mips::COP00:
return Mips::ZERO;
5688 case Mips::COP01:
return Mips::AT;
5689 case Mips::COP02:
return Mips::V0;
5690 case Mips::COP03:
return Mips::V1;
5691 case Mips::COP04:
return Mips::A0;
5692 case Mips::COP05:
return Mips::A1;
5693 case Mips::COP06:
return Mips::A2;
5694 case Mips::COP07:
return Mips::A3;
5695 case Mips::COP08:
return Mips::T0;
5696 case Mips::COP09:
return Mips::T1;
5697 case Mips::COP010:
return Mips::T2;
5698 case Mips::COP011:
return Mips::T3;
5699 case Mips::COP012:
return Mips::T4;
5700 case Mips::COP013:
return Mips::T5;
5701 case Mips::COP014:
return Mips::T6;
5702 case Mips::COP015:
return Mips::T7;
5703 case Mips::COP016:
return Mips::S0;
5704 case Mips::COP017:
return Mips::S1;
5705 case Mips::COP018:
return Mips::S2;
5706 case Mips::COP019:
return Mips::S3;
5707 case Mips::COP020:
return Mips::S4;
5708 case Mips::COP021:
return Mips::S5;
5709 case Mips::COP022:
return Mips::S6;
5710 case Mips::COP023:
return Mips::S7;
5711 case Mips::COP024:
return Mips::T8;
5712 case Mips::COP025:
return Mips::T9;
5713 case Mips::COP026:
return Mips::K0;
5714 case Mips::COP027:
return Mips::K1;
5715 case Mips::COP028:
return Mips::GP;
5716 case Mips::COP029:
return Mips::SP;
5717 case Mips::COP030:
return Mips::FP;
5718 case Mips::COP031:
return Mips::RA;
5732 bool IsMFTR =
false;
5788 : Inst.getOperand(0).
getReg());
5790 TOut.
emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, u, sel, h, IDLoc,
5801 warnIfNoMacro(IDLoc);
5804 unsigned Opcode = Inst.
getOpcode() == Mips::SaaAddr ? Mips::SAA : Mips::SAAD;
5809 if (BaseOp.
isImm()) {
5810 int64_t ImmValue = BaseOp.
getImm();
5811 if (ImmValue == 0) {
5812 TOut.
emitRR(Opcode, RtReg, BaseReg, IDLoc, STI);
5817 unsigned ATReg = getATReg(IDLoc);
5821 if (expandLoadAddress(ATReg, BaseReg, BaseOp, !isGP64bit(), IDLoc, Out, STI))
5824 TOut.
emitRR(Opcode, RtReg, ATReg, IDLoc, STI);
5829MipsAsmParser::checkEarlyTargetMatchPredicate(
MCInst &Inst,
5833 return Match_Success;
5836 if (
static_cast<MipsOperand &
>(*
Operands[1])
5837 .isValidForTie(
static_cast<MipsOperand &
>(*
Operands[2])))
5838 return Match_Success;
5839 return Match_RequiresSameSrcAndDst;
5843unsigned MipsAsmParser::checkTargetMatchPredicate(
MCInst &Inst) {
5850 return Match_RequiresNoZeroRegister;
5851 return Match_Success;
5857 case Mips::JALR_HB64:
5858 case Mips::JALRC_HB_MMR6:
5859 case Mips::JALRC_MMR6:
5861 return Match_RequiresDifferentSrcAndDst;
5862 return Match_Success;
5865 return Match_RequiresDifferentSrcAndDst;
5866 return Match_Success;
5869 return Match_NonZeroOperandForSync;
5870 return Match_Success;
5876 return Match_NonZeroOperandForMTCX;
5877 return Match_Success;
5890 case Mips::BLEZC:
case Mips::BLEZC_MMR6:
5891 case Mips::BGEZC:
case Mips::BGEZC_MMR6:
5892 case Mips::BGTZC:
case Mips::BGTZC_MMR6:
5893 case Mips::BLTZC:
case Mips::BLTZC_MMR6:
5894 case Mips::BEQZC:
case Mips::BEQZC_MMR6:
5895 case Mips::BNEZC:
case Mips::BNEZC_MMR6:
5904 return Match_RequiresNoZeroRegister;
5905 return Match_Success;
5906 case Mips::BGEC:
case Mips::BGEC_MMR6:
5907 case Mips::BLTC:
case Mips::BLTC_MMR6:
5908 case Mips::BGEUC:
case Mips::BGEUC_MMR6:
5909 case Mips::BLTUC:
case Mips::BLTUC_MMR6:
5910 case Mips::BEQC:
case Mips::BEQC_MMR6:
5911 case Mips::BNEC:
case Mips::BNEC_MMR6:
5920 return Match_RequiresNoZeroRegister;
5923 return Match_RequiresNoZeroRegister;
5925 return Match_RequiresDifferentOperands;
5926 return Match_Success;
5929 "Operands must be immediates for dins!");
5932 if ((0 > (Pos +
Size)) || ((Pos +
Size) > 32))
5933 return Match_RequiresPosSizeRange0_32;
5934 return Match_Success;
5939 "Operands must be immediates for dinsm/dinsu!");
5942 if ((32 >= (Pos +
Size)) || ((Pos +
Size) > 64))
5943 return Match_RequiresPosSizeRange33_64;
5944 return Match_Success;
5948 "Operands must be immediates for DEXTM!");
5951 if ((1 > (Pos +
Size)) || ((Pos +
Size) > 63))
5952 return Match_RequiresPosSizeUImm6;
5953 return Match_Success;
5958 "Operands must be immediates for dextm/dextu!");
5961 if ((32 > (Pos +
Size)) || ((Pos +
Size) > 64))
5962 return Match_RequiresPosSizeRange33_64;
5963 return Match_Success;
5965 case Mips::CRC32B:
case Mips::CRC32CB:
5966 case Mips::CRC32H:
case Mips::CRC32CH:
5967 case Mips::CRC32W:
case Mips::CRC32CW:
5968 case Mips::CRC32D:
case Mips::CRC32CD:
5970 return Match_RequiresSameSrcAndDst;
5971 return Match_Success;
5977 return Match_NoFCCRegisterForCurrentISA;
5979 return Match_Success;
5987 if (ErrorLoc ==
SMLoc())
5994bool MipsAsmParser::matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
5998 bool MatchingInlineAsm) {
6000 unsigned MatchResult =
6003 switch (MatchResult) {
6005 if (processInstruction(Inst, IDLoc, Out, STI))
6008 case Match_MissingFeature:
6009 Error(IDLoc,
"instruction requires a CPU feature not currently enabled");
6011 case Match_InvalidTiedOperand:
6012 Error(IDLoc,
"operand must match destination register");
6014 case Match_InvalidOperand: {
6015 SMLoc ErrorLoc = IDLoc;
6018 return Error(IDLoc,
"too few operands for instruction");
6021 if (ErrorLoc ==
SMLoc())
6025 return Error(ErrorLoc,
"invalid operand for instruction");
6027 case Match_NonZeroOperandForSync:
6029 "s-type must be zero or unspecified for pre-MIPS32 ISAs");
6030 case Match_NonZeroOperandForMTCX:
6031 return Error(IDLoc,
"selector must be zero for pre-MIPS32 ISAs");
6032 case Match_MnemonicFail:
6033 return Error(IDLoc,
"invalid instruction");
6034 case Match_RequiresDifferentSrcAndDst:
6035 return Error(IDLoc,
"source and destination must be different");
6036 case Match_RequiresDifferentOperands:
6037 return Error(IDLoc,
"registers must be different");
6038 case Match_RequiresNoZeroRegister:
6039 return Error(IDLoc,
"invalid operand ($zero) for instruction");
6040 case Match_RequiresSameSrcAndDst:
6041 return Error(IDLoc,
"source and destination must match");
6042 case Match_NoFCCRegisterForCurrentISA:
6044 "non-zero fcc register doesn't exist in current ISA level");
6049 "expected 1-bit unsigned immediate");
6052 "expected 2-bit unsigned immediate");
6055 "expected immediate in range 1 .. 4");
6058 "expected 3-bit unsigned immediate");
6061 "expected 4-bit unsigned immediate");
6064 "expected 4-bit signed immediate");
6067 "expected 5-bit unsigned immediate");
6070 "expected 5-bit signed immediate");
6073 "expected immediate in range 1 .. 32");
6074 case Match_UImm5_32:
6076 "expected immediate in range 32 .. 63");
6077 case Match_UImm5_33:
6079 "expected immediate in range 33 .. 64");
6080 case Match_UImm5_0_Report_UImm6:
6084 "expected 6-bit unsigned immediate");
6085 case Match_UImm5_Lsl2:
6087 "expected both 7-bit unsigned immediate and multiple of 4");
6088 case Match_UImmRange2_64:
6090 "expected immediate in range 2 .. 64");
6093 "expected 6-bit unsigned immediate");
6094 case Match_UImm6_Lsl2:
6096 "expected both 8-bit unsigned immediate and multiple of 4");
6099 "expected 6-bit signed immediate");
6102 "expected 7-bit unsigned immediate");
6103 case Match_UImm7_N1:
6105 "expected immediate in range -1 .. 126");
6106 case Match_SImm7_Lsl2:
6108 "expected both 9-bit signed immediate and multiple of 4");
6111 "expected 8-bit unsigned immediate");
6112 case Match_UImm10_0:
6114 "expected 10-bit unsigned immediate");
6115 case Match_SImm10_0:
6117 "expected 10-bit signed immediate");
6118 case Match_SImm11_0:
6120 "expected 11-bit signed immediate");
6122 case Match_UImm16_Relaxed:
6123 case Match_UImm16_AltRelaxed:
6125 "expected 16-bit unsigned immediate");
6127 case Match_SImm16_Relaxed:
6129 "expected 16-bit signed immediate");
6130 case Match_SImm19_Lsl2:
6132 "expected both 19-bit signed immediate and multiple of 4");
6133 case Match_UImm20_0:
6135 "expected 20-bit unsigned immediate");
6136 case Match_UImm26_0:
6138 "expected 26-bit unsigned immediate");
6140 case Match_SImm32_Relaxed:
6142 "expected 32-bit signed immediate");
6143 case Match_UImm32_Coerced:
6145 "expected 32-bit immediate");
6146 case Match_MemSImm9:
6148 "expected memory with 9-bit signed offset");
6149 case Match_MemSImm10:
6151 "expected memory with 10-bit signed offset");
6152 case Match_MemSImm10Lsl1:
6154 "expected memory with 11-bit signed offset and multiple of 2");
6155 case Match_MemSImm10Lsl2:
6157 "expected memory with 12-bit signed offset and multiple of 4");
6158 case Match_MemSImm10Lsl3:
6160 "expected memory with 13-bit signed offset and multiple of 8");
6161 case Match_MemSImm11:
6163 "expected memory with 11-bit signed offset");
6164 case Match_MemSImm12:
6166 "expected memory with 12-bit signed offset");
6167 case Match_MemSImm16:
6169 "expected memory with 16-bit signed offset");
6170 case Match_MemSImmPtr:
6172 "expected memory with 32-bit signed offset");
6173 case Match_RequiresPosSizeRange0_32: {
6176 return Error(ErrorStart,
"size plus position are not in the range 0 .. 32",
6177 SMRange(ErrorStart, ErrorEnd));
6179 case Match_RequiresPosSizeUImm6: {
6182 return Error(ErrorStart,
"size plus position are not in the range 1 .. 63",
6183 SMRange(ErrorStart, ErrorEnd));
6185 case Match_RequiresPosSizeRange33_64: {
6188 return Error(ErrorStart,
"size plus position are not in the range 33 .. 64",
6189 SMRange(ErrorStart, ErrorEnd));
6196void MipsAsmParser::warnIfRegIndexIsAT(
unsigned RegIndex,
SMLoc Loc) {
6197 if (RegIndex != 0 && AssemblerOptions.
back()->getATRegIndex() == RegIndex)
6198 Warning(Loc,
"used $at (currently $" +
Twine(RegIndex) +
6199 ") without \".set noat\"");
6202void MipsAsmParser::warnIfNoMacro(
SMLoc Loc) {
6203 if (!AssemblerOptions.
back()->isMacro())
6204 Warning(Loc,
"macro instruction expanded into multiple instructions");
6207void MipsAsmParser::ConvertXWPOperands(
MCInst &Inst,
6211 "Unexpected instruction!");
6212 ((MipsOperand &)*
Operands[1]).addGPR32ZeroAsmRegOperands(Inst, 1);
6215 ((MipsOperand &)*
Operands[2]).addMemOperands(Inst, 2);
6219MipsAsmParser::printWarningWithFixIt(
const Twine &Msg,
const Twine &FixMsg,
6231 .
Cases(
"at",
"AT", 1)
6265 if (!(isABI_N32() || isABI_N64()))
6268 if (12 <=
CC &&
CC <= 15) {
6270 AsmToken RegTok = getLexer().peekTok();
6279 assert(FixedName !=
"" &&
"Register name is not one of t4-t7.");
6281 printWarningWithFixIt(
"register names $t4-$t7 are only available in O32.",
6282 "Did you mean $" + FixedName +
"?", RegRange);
6288 if (8 <=
CC &&
CC <= 11)
6308 .
Case(
"hwr_cpunum", 0)
6309 .
Case(
"hwr_synci_step", 1)
6311 .
Case(
"hwr_ccres", 3)
6312 .
Case(
"hwr_ulr", 29)
6319 if (
Name[0] ==
'f') {
6332 if (
Name.starts_with(
"fcc")) {
6345 if (
Name.starts_with(
"ac")) {
6360 if (
Name.front() !=
'w' ||
Name.drop_front(1).getAsInteger(10, IntVal))
6369int MipsAsmParser::matchMSA128CtrlRegisterName(
StringRef Name) {
6375 .
Case(
"msaaccess", 2)
6377 .
Case(
"msamodify", 4)
6378 .
Case(
"msarequest", 5)
6380 .
Case(
"msaunmap", 7)
6386bool MipsAsmParser::canUseATReg() {
6387 return AssemblerOptions.
back()->getATRegIndex() != 0;
6390unsigned MipsAsmParser::getATReg(
SMLoc Loc) {
6391 unsigned ATIndex = AssemblerOptions.
back()->getATRegIndex();
6393 reportParseError(Loc,
6394 "pseudo-instruction requires $at, which is not available");
6398 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
6402unsigned MipsAsmParser::getReg(
int RC,
int RegNo) {
6403 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
6428 switch (getLexer().getKind()) {
6438 if (!parseAnyRegister(
Operands).isNoMatch())
6447 MCSymbol *
Sym = getContext().getOrCreateSymbol(Identifier);
6452 Operands.push_back(MipsOperand::CreateImm(SymRef, S,
E, *
this));
6460 if (getParser().parseExpression(Expr))
6465 Operands.push_back(MipsOperand::CreateImm(Expr, S,
E, *
this));
6474 return !tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess();
6483 MipsOperand &Operand =
static_cast<MipsOperand &
>(*
Operands.front());
6484 StartLoc = Operand.getStartLoc();
6485 EndLoc = Operand.getEndLoc();
6491 if (Operand.isGPRAsmReg()) {
6493 Reg = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
6503bool MipsAsmParser::parseMemOffset(
const MCExpr *&Res,
bool isParenExpr) {
6507 return getParser().parseParenExprOfDepth(0, Res, S);
6508 return getParser().parseExpression(Res);
6514 const MCExpr *IdVal =
nullptr;
6516 bool isParenExpr =
false;
6527 if (parseMemOffset(IdVal, isParenExpr))
6532 MipsOperand &Mnemonic =
static_cast<MipsOperand &
>(*
Operands[0]);
6533 if (Mnemonic.getToken() ==
"la" || Mnemonic.getToken() ==
"dla") {
6536 Operands.push_back(MipsOperand::CreateImm(IdVal, S,
E, *
this));
6545 auto Base = MipsOperand::createGPRReg(
6546 0,
"0", getContext().getRegisterInfo(), S,
E, *
this);
6548 MipsOperand::CreateMem(std::move(
Base), IdVal, S,
E, *
this));
6601 if (getParser().parseExpression(NextExpr))
6624 std::unique_ptr<MipsOperand>
op(
6625 static_cast<MipsOperand *
>(
Operands.back().release()));
6630 if (
const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
6632 if (IdVal->evaluateAsAbsolute(Imm))
6639 Operands.push_back(MipsOperand::CreateMem(std::move(
op), IdVal, S,
E, *
this));
6650 if (
Sym->isVariable()) {
6651 const MCExpr *Expr =
Sym->getVariableValue();
6657 matchAnyRegisterNameWithoutDollar(
Operands, DefSymbol.
substr(1), S);
6666 }
else if (
Sym->isUnset()) {
6671 if (Entry != RegisterSets.
end()) {
6673 matchAnyRegisterWithoutDollar(
Operands,
Entry->getValue(), S);
6684ParseStatus MipsAsmParser::matchAnyRegisterNameWithoutDollar(
6686 int Index = matchCPURegisterName(Identifier);
6688 Operands.push_back(MipsOperand::createGPRReg(
6689 Index, Identifier, getContext().getRegisterInfo(), S,
6690 getLexer().getLoc(), *
this));
6694 Index = matchHWRegsRegisterName(Identifier);
6696 Operands.push_back(MipsOperand::createHWRegsReg(
6697 Index, Identifier, getContext().getRegisterInfo(), S,
6698 getLexer().getLoc(), *
this));
6702 Index = matchFPURegisterName(Identifier);
6704 Operands.push_back(MipsOperand::createFGRReg(
6705 Index, Identifier, getContext().getRegisterInfo(), S,
6706 getLexer().getLoc(), *
this));
6710 Index = matchFCCRegisterName(Identifier);
6712 Operands.push_back(MipsOperand::createFCCReg(
6713 Index, Identifier, getContext().getRegisterInfo(), S,
6714 getLexer().getLoc(), *
this));
6718 Index = matchACRegisterName(Identifier);
6720 Operands.push_back(MipsOperand::createACCReg(
6721 Index, Identifier, getContext().getRegisterInfo(), S,
6722 getLexer().getLoc(), *
this));
6726 Index = matchMSA128RegisterName(Identifier);
6728 Operands.push_back(MipsOperand::createMSA128Reg(
6729 Index, Identifier, getContext().getRegisterInfo(), S,
6730 getLexer().getLoc(), *
this));
6734 Index = matchMSA128CtrlRegisterName(Identifier);
6736 Operands.push_back(MipsOperand::createMSACtrlReg(
6737 Index, Identifier, getContext().getRegisterInfo(), S,
6738 getLexer().getLoc(), *
this));
6751 return matchAnyRegisterNameWithoutDollar(
Operands, Identifier, S);
6756 if (RegNum < 0 || RegNum > 31) {
6760 Error(getLexer().getLoc(),
"invalid register number");
6762 Operands.push_back(MipsOperand::createNumericReg(
6763 RegNum, Token.
getString(), getContext().getRegisterInfo(), S,
6775 auto Token = getLexer().peekTok(
false);
6776 return matchAnyRegisterWithoutDollar(
Operands, Token, S);
6783 auto Token = Parser.
getTok();
6810 SMLoc S = getLexer().getLoc();
6818 const MCExpr *Expr =
nullptr;
6824 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *
this));
6841 if (getParser().parseExpression(IdVal))
6848 Operands.push_back(MipsOperand::CreateImm(
6857 unsigned PrevReg = Mips::NoRegister;
6858 bool RegRange =
false;
6865 while (parseAnyRegister(TmpOperands).isSuccess()) {
6866 SMLoc E = getLexer().getLoc();
6867 MipsOperand &
Reg =
static_cast<MipsOperand &
>(*TmpOperands.
back());
6868 RegNo = isGP64bit() ?
Reg.getGPR64Reg() :
Reg.getGPR32Reg();
6872 if ((isGP64bit() && RegNo == Mips::RA_64) ||
6873 (!isGP64bit() && RegNo == Mips::RA)) {
6876 unsigned TmpReg = PrevReg + 1;
6877 while (TmpReg <= RegNo) {
6878 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
6879 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
6881 return Error(
E,
"invalid register operand");
6890 if ((PrevReg == Mips::NoRegister) &&
6891 ((isGP64bit() && (RegNo != Mips::S0_64) && (RegNo != Mips::RA_64)) ||
6892 (!isGP64bit() && (RegNo != Mips::S0) && (RegNo != Mips::RA))))
6893 return Error(
E,
"$16 or $31 expected");
6894 if (!(((RegNo == Mips::FP || RegNo == Mips::RA ||
6895 (RegNo >= Mips::S0 && RegNo <= Mips::S7)) &&
6897 ((RegNo == Mips::FP_64 || RegNo == Mips::RA_64 ||
6898 (RegNo >= Mips::S0_64 && RegNo <= Mips::S7_64)) &&
6900 return Error(
E,
"invalid register operand");
6901 if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
6902 ((RegNo != Mips::FP && RegNo != Mips::RA && !isGP64bit()) ||
6903 (RegNo != Mips::FP_64 && RegNo != Mips::RA_64 && isGP64bit())))
6904 return Error(
E,
"consecutive register numbers expected");
6914 return Error(
E,
"',' or '-' expected");
6924 Operands.push_back(MipsOperand::CreateRegList(Regs, S,
E, *
this));
6938 MipsOperand::CreateToken(
"(", getLexer().getLoc(), *
this));
6941 SMLoc Loc = getLexer().getLoc();
6942 return Error(Loc,
"unexpected token in argument list");
6945 SMLoc Loc = getLexer().getLoc();
6946 return Error(Loc,
"unexpected token, expected ')'");
6949 MipsOperand::CreateToken(
")", getLexer().getLoc(), *
this));
6966 MipsOperand::CreateToken(
"[", getLexer().getLoc(), *
this));
6969 SMLoc Loc = getLexer().getLoc();
6970 return Error(Loc,
"unexpected token in argument list");
6973 SMLoc Loc = getLexer().getLoc();
6974 return Error(Loc,
"unexpected token, expected ']'");
6977 MipsOperand::CreateToken(
"]", getLexer().getLoc(), *
this));
6984 unsigned VariantID = 0);
7005 getTargetStreamer().forbidModuleDirective();
7008 if (!mnemonicIsValid(
Name, 0)) {
7009 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
7011 return Error(NameLoc,
"unknown instruction" + Suggestion);
7014 Operands.push_back(MipsOperand::CreateToken(
Name, NameLoc, *
this));
7020 SMLoc Loc = getLexer().getLoc();
7021 return Error(Loc,
"unexpected token in argument list");
7031 SMLoc Loc = getLexer().getLoc();
7032 return Error(Loc,
"unexpected token in argument list");
7044 SMLoc Loc = getLexer().getLoc();
7045 return Error(Loc,
"unexpected token in argument list");
7053bool MipsAsmParser::reportParseError(
const Twine &ErrorMsg) {
7054 SMLoc Loc = getLexer().getLoc();
7055 return Error(Loc, ErrorMsg);
7058bool MipsAsmParser::reportParseError(
SMLoc Loc,
const Twine &ErrorMsg) {
7059 return Error(Loc, ErrorMsg);
7062bool MipsAsmParser::parseSetNoAtDirective() {
7067 AssemblerOptions.
back()->setATRegIndex(0);
7073 reportParseError(
"unexpected token, expected end of statement");
7077 getTargetStreamer().emitDirectiveSetNoAt();
7082bool MipsAsmParser::parseSetAtDirective() {
7090 AssemblerOptions.
back()->setATRegIndex(1);
7092 getTargetStreamer().emitDirectiveSetAt();
7098 reportParseError(
"unexpected token, expected equals sign");
7105 reportParseError(
"no register specified");
7108 reportParseError(
"unexpected token, expected dollar sign '$'");
7118 AtRegNo = matchCPURegisterName(
Reg.getIdentifier());
7120 AtRegNo =
Reg.getIntVal();
7122 reportParseError(
"unexpected token, expected identifier or integer");
7127 if (!AssemblerOptions.
back()->setATRegIndex(AtRegNo)) {
7128 reportParseError(
"invalid register");
7135 reportParseError(
"unexpected token, expected end of statement");
7139 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
7145bool MipsAsmParser::parseSetReorderDirective() {
7150 reportParseError(
"unexpected token, expected end of statement");
7153 AssemblerOptions.
back()->setReorder();
7154 getTargetStreamer().emitDirectiveSetReorder();
7159bool MipsAsmParser::parseSetNoReorderDirective() {
7164 reportParseError(
"unexpected token, expected end of statement");
7167 AssemblerOptions.
back()->setNoReorder();
7168 getTargetStreamer().emitDirectiveSetNoReorder();
7173bool MipsAsmParser::parseSetMacroDirective() {
7178 reportParseError(
"unexpected token, expected end of statement");
7181 AssemblerOptions.
back()->setMacro();
7182 getTargetStreamer().emitDirectiveSetMacro();
7187bool MipsAsmParser::parseSetNoMacroDirective() {
7192 reportParseError(
"unexpected token, expected end of statement");
7195 if (AssemblerOptions.
back()->isReorder()) {
7196 reportParseError(
"`noreorder' must be set before `nomacro'");
7199 AssemblerOptions.
back()->setNoMacro();
7200 getTargetStreamer().emitDirectiveSetNoMacro();
7205bool MipsAsmParser::parseSetMsaDirective() {
7211 return reportParseError(
"unexpected token, expected end of statement");
7213 setFeatureBits(Mips::FeatureMSA,
"msa");
7214 getTargetStreamer().emitDirectiveSetMsa();
7218bool MipsAsmParser::parseSetNoMsaDirective() {
7224 return reportParseError(
"unexpected token, expected end of statement");
7226 clearFeatureBits(Mips::FeatureMSA,
"msa");
7227 getTargetStreamer().emitDirectiveSetNoMsa();
7231bool MipsAsmParser::parseSetNoDspDirective() {
7237 reportParseError(
"unexpected token, expected end of statement");
7241 clearFeatureBits(Mips::FeatureDSP,
"dsp");
7242 getTargetStreamer().emitDirectiveSetNoDsp();
7246bool MipsAsmParser::parseSetNoMips3DDirective() {
7252 reportParseError(
"unexpected token, expected end of statement");
7256 clearFeatureBits(Mips::FeatureMips3D,
"mips3d");
7257 getTargetStreamer().emitDirectiveSetNoMips3D();
7261bool MipsAsmParser::parseSetMips16Directive() {
7267 reportParseError(
"unexpected token, expected end of statement");
7271 setFeatureBits(Mips::FeatureMips16,
"mips16");
7272 getTargetStreamer().emitDirectiveSetMips16();
7277bool MipsAsmParser::parseSetNoMips16Directive() {
7283 reportParseError(
"unexpected token, expected end of statement");
7287 clearFeatureBits(Mips::FeatureMips16,
"mips16");
7288 getTargetStreamer().emitDirectiveSetNoMips16();
7293bool MipsAsmParser::parseSetFpDirective() {
7302 reportParseError(
"unexpected token, expected equals sign '='");
7308 if (!parseFpABIValue(FpAbiVal,
".set"))
7312 reportParseError(
"unexpected token, expected end of statement");
7315 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
7320bool MipsAsmParser::parseSetOddSPRegDirective() {
7325 reportParseError(
"unexpected token, expected end of statement");
7329 clearFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
7330 getTargetStreamer().emitDirectiveSetOddSPReg();
7334bool MipsAsmParser::parseSetNoOddSPRegDirective() {
7339 reportParseError(
"unexpected token, expected end of statement");
7343 setFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
7344 getTargetStreamer().emitDirectiveSetNoOddSPReg();
7348bool MipsAsmParser::parseSetMtDirective() {
7354 reportParseError(
"unexpected token, expected end of statement");
7358 setFeatureBits(Mips::FeatureMT,
"mt");
7359 getTargetStreamer().emitDirectiveSetMt();
7364bool MipsAsmParser::parseSetNoMtDirective() {
7370 reportParseError(
"unexpected token, expected end of statement");
7374 clearFeatureBits(Mips::FeatureMT,
"mt");
7376 getTargetStreamer().emitDirectiveSetNoMt();
7381bool MipsAsmParser::parseSetNoCRCDirective() {
7387 reportParseError(
"unexpected token, expected end of statement");
7391 clearFeatureBits(Mips::FeatureCRC,
"crc");
7393 getTargetStreamer().emitDirectiveSetNoCRC();
7398bool MipsAsmParser::parseSetNoVirtDirective() {
7404 reportParseError(
"unexpected token, expected end of statement");
7408 clearFeatureBits(Mips::FeatureVirt,
"virt");
7410 getTargetStreamer().emitDirectiveSetNoVirt();
7415bool MipsAsmParser::parseSetNoGINVDirective() {
7421 reportParseError(
"unexpected token, expected end of statement");
7425 clearFeatureBits(Mips::FeatureGINV,
"ginv");
7427 getTargetStreamer().emitDirectiveSetNoGINV();
7432bool MipsAsmParser::parseSetPopDirective() {
7434 SMLoc Loc = getLexer().getLoc();
7438 return reportParseError(
"unexpected token, expected end of statement");
7442 if (AssemblerOptions.
size() == 2)
7443 return reportParseError(Loc,
".set pop with no .set push");
7447 setAvailableFeatures(
7448 ComputeAvailableFeatures(AssemblerOptions.
back()->getFeatures()));
7451 getTargetStreamer().emitDirectiveSetPop();
7455bool MipsAsmParser::parseSetPushDirective() {
7459 return reportParseError(
"unexpected token, expected end of statement");
7463 std::make_unique<MipsAssemblerOptions>(AssemblerOptions.
back().get()));
7465 getTargetStreamer().emitDirectiveSetPush();
7469bool MipsAsmParser::parseSetSoftFloatDirective() {
7473 return reportParseError(
"unexpected token, expected end of statement");
7475 setFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
7476 getTargetStreamer().emitDirectiveSetSoftFloat();
7480bool MipsAsmParser::parseSetHardFloatDirective() {
7484 return reportParseError(
"unexpected token, expected end of statement");
7486 clearFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
7487 getTargetStreamer().emitDirectiveSetHardFloat();
7491bool MipsAsmParser::parseSetAssignment() {
7496 return reportParseError(
"expected identifier after .set");
7499 return reportParseError(
"unexpected token, expected comma");
7509 getContext().getOrCreateSymbol(
Name);
7523bool MipsAsmParser::parseSetMips0Directive() {
7527 return reportParseError(
"unexpected token, expected end of statement");
7531 setAvailableFeatures(
7532 ComputeAvailableFeatures(AssemblerOptions.
front()->getFeatures()));
7534 AssemblerOptions.
back()->setFeatures(AssemblerOptions.
front()->getFeatures());
7536 getTargetStreamer().emitDirectiveSetMips0();
7540bool MipsAsmParser::parseSetArchDirective() {
7544 return reportParseError(
"unexpected token, expected equals sign");
7547 StringRef Arch = getParser().parseStringToEndOfStatement().
trim();
7549 return reportParseError(
"expected arch identifier");
7553 .
Case(
"mips1",
"mips1")
7554 .
Case(
"mips2",
"mips2")
7555 .
Case(
"mips3",
"mips3")
7556 .
Case(
"mips4",
"mips4")
7557 .
Case(
"mips5",
"mips5")
7558 .
Case(
"mips32",
"mips32")
7559 .
Case(
"mips32r2",
"mips32r2")
7560 .
Case(
"mips32r3",
"mips32r3")
7561 .
Case(
"mips32r5",
"mips32r5")
7562 .
Case(
"mips32r6",
"mips32r6")
7563 .
Case(
"mips64",
"mips64")
7564 .
Case(
"mips64r2",
"mips64r2")
7565 .
Case(
"mips64r3",
"mips64r3")
7566 .
Case(
"mips64r5",
"mips64r5")
7567 .
Case(
"mips64r6",
"mips64r6")
7568 .
Case(
"octeon",
"cnmips")
7569 .
Case(
"octeon+",
"cnmipsp")
7570 .
Case(
"r4000",
"mips3")
7573 if (ArchFeatureName.
empty())
7574 return reportParseError(
"unsupported architecture");
7576 if (ArchFeatureName ==
"mips64r6" && inMicroMipsMode())
7577 return reportParseError(
"mips64r6 does not support microMIPS");
7579 selectArch(ArchFeatureName);
7580 getTargetStreamer().emitDirectiveSetArch(Arch);
7584bool MipsAsmParser::parseSetFeature(
uint64_t Feature) {
7588 return reportParseError(
"unexpected token, expected end of statement");
7593 case Mips::FeatureMips3D:
7594 setFeatureBits(Mips::FeatureMips3D,
"mips3d");
7595 getTargetStreamer().emitDirectiveSetMips3D();
7597 case Mips::FeatureDSP:
7598 setFeatureBits(Mips::FeatureDSP,
"dsp");
7599 getTargetStreamer().emitDirectiveSetDsp();
7601 case Mips::FeatureDSPR2:
7602 setFeatureBits(Mips::FeatureDSPR2,
"dspr2");
7603 getTargetStreamer().emitDirectiveSetDspr2();
7605 case Mips::FeatureMicroMips:
7606 setFeatureBits(Mips::FeatureMicroMips,
"micromips");
7607 getTargetStreamer().emitDirectiveSetMicroMips();
7609 case Mips::FeatureMips1:
7610 selectArch(
"mips1");
7611 getTargetStreamer().emitDirectiveSetMips1();
7613 case Mips::FeatureMips2:
7614 selectArch(
"mips2");
7615 getTargetStreamer().emitDirectiveSetMips2();
7617 case Mips::FeatureMips3:
7618 selectArch(
"mips3");
7619 getTargetStreamer().emitDirectiveSetMips3();
7621 case Mips::FeatureMips4:
7622 selectArch(
"mips4");
7623 getTargetStreamer().emitDirectiveSetMips4();
7625 case Mips::FeatureMips5:
7626 selectArch(
"mips5");
7627 getTargetStreamer().emitDirectiveSetMips5();
7629 case Mips::FeatureMips32:
7630 selectArch(
"mips32");
7631 getTargetStreamer().emitDirectiveSetMips32();
7633 case Mips::FeatureMips32r2:
7634 selectArch(
"mips32r2");
7635 getTargetStreamer().emitDirectiveSetMips32R2();
7637 case Mips::FeatureMips32r3:
7638 selectArch(
"mips32r3");
7639 getTargetStreamer().emitDirectiveSetMips32R3();
7641 case Mips::FeatureMips32r5:
7642 selectArch(
"mips32r5");
7643 getTargetStreamer().emitDirectiveSetMips32R5();
7645 case Mips::FeatureMips32r6:
7646 selectArch(
"mips32r6");
7647 getTargetStreamer().emitDirectiveSetMips32R6();
7649 case Mips::FeatureMips64:
7650 selectArch(
"mips64");
7651 getTargetStreamer().emitDirectiveSetMips64();
7653 case Mips::FeatureMips64r2:
7654 selectArch(
"mips64r2");
7655 getTargetStreamer().emitDirectiveSetMips64R2();
7657 case Mips::FeatureMips64r3:
7658 selectArch(
"mips64r3");
7659 getTargetStreamer().emitDirectiveSetMips64R3();
7661 case Mips::FeatureMips64r5:
7662 selectArch(
"mips64r5");
7663 getTargetStreamer().emitDirectiveSetMips64R5();
7665 case Mips::FeatureMips64r6:
7666 selectArch(
"mips64r6");
7667 getTargetStreamer().emitDirectiveSetMips64R6();
7669 case Mips::FeatureCRC:
7670 setFeatureBits(Mips::FeatureCRC,
"crc");
7671 getTargetStreamer().emitDirectiveSetCRC();
7673 case Mips::FeatureVirt:
7674 setFeatureBits(Mips::FeatureVirt,
"virt");
7675 getTargetStreamer().emitDirectiveSetVirt();
7677 case Mips::FeatureGINV:
7678 setFeatureBits(Mips::FeatureGINV,
"ginv");
7679 getTargetStreamer().emitDirectiveSetGINV();
7685bool MipsAsmParser::eatComma(
StringRef ErrorStr) {
7688 SMLoc Loc = getLexer().getLoc();
7689 return Error(Loc, ErrorStr);
7700bool MipsAsmParser::isPicAndNotNxxAbi() {
7701 return inPicMode() && !(isABI_N32() || isABI_N64());
7704bool MipsAsmParser::parseDirectiveCpAdd(
SMLoc Loc) {
7708 reportParseError(
"expected register");
7712 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7713 if (!RegOpnd.isGPRAsmReg()) {
7714 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7720 reportParseError(
"unexpected token, expected end of statement");
7725 getTargetStreamer().emitDirectiveCpAdd(RegOpnd.getGPR32Reg());
7729bool MipsAsmParser::parseDirectiveCpLoad(
SMLoc Loc) {
7730 if (AssemblerOptions.
back()->isReorder())
7731 Warning(Loc,
".cpload should be inside a noreorder section");
7733 if (inMips16Mode()) {
7734 reportParseError(
".cpload is not supported in Mips16 mode");
7741 reportParseError(
"expected register containing function address");
7745 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7746 if (!RegOpnd.isGPRAsmReg()) {
7747 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7753 reportParseError(
"unexpected token, expected end of statement");
7757 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
7761bool MipsAsmParser::parseDirectiveCpLocal(
SMLoc Loc) {
7762 if (!isABI_N32() && !isABI_N64()) {
7763 reportParseError(
".cplocal is allowed only in N32 or N64 mode");
7770 reportParseError(
"expected register containing global pointer");
7774 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7775 if (!RegOpnd.isGPRAsmReg()) {
7776 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7782 reportParseError(
"unexpected token, expected end of statement");
7787 unsigned NewReg = RegOpnd.getGPR32Reg();
7791 getTargetStreamer().emitDirectiveCpLocal(NewReg);
7795bool MipsAsmParser::parseDirectiveCpRestore(
SMLoc Loc) {
7801 if (inMips16Mode()) {
7802 reportParseError(
".cprestore is not supported in Mips16 mode");
7808 int64_t StackOffsetVal;
7810 reportParseError(
"expected stack offset value");
7814 if (!
StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
7815 reportParseError(
"stack offset is not an absolute expression");
7819 if (StackOffsetVal < 0) {
7820 Warning(Loc,
".cprestore with negative stack offset has no effect");
7821 IsCpRestoreSet =
false;
7823 IsCpRestoreSet =
true;
7824 CpRestoreOffset = StackOffsetVal;
7829 reportParseError(
"unexpected token, expected end of statement");
7833 if (!getTargetStreamer().emitDirectiveCpRestore(
7834 CpRestoreOffset, [&]() {
return getATReg(Loc); }, Loc, STI))
7840bool MipsAsmParser::parseDirectiveCPSetup() {
7844 bool SaveIsReg =
true;
7849 reportParseError(
"expected register containing function address");
7853 MipsOperand &FuncRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7854 if (!FuncRegOpnd.isGPRAsmReg()) {
7855 reportParseError(FuncRegOpnd.getStartLoc(),
"invalid register");
7859 FuncReg = FuncRegOpnd.getGPR32Reg();
7862 if (!eatComma(
"unexpected token, expected comma"))
7865 Res = parseAnyRegister(TmpReg);
7867 const MCExpr *OffsetExpr;
7869 SMLoc ExprLoc = getLexer().getLoc();
7872 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
7873 reportParseError(ExprLoc,
"expected save register or stack offset");
7880 MipsOperand &SaveOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7881 if (!SaveOpnd.isGPRAsmReg()) {
7882 reportParseError(SaveOpnd.getStartLoc(),
"invalid register");
7885 Save = SaveOpnd.getGPR32Reg();
7888 if (!eatComma(
"unexpected token, expected comma"))
7893 reportParseError(
"expected expression");
7898 reportParseError(
"expected symbol");
7903 CpSaveLocation = Save;
7904 CpSaveLocationIsRegister = SaveIsReg;
7906 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save,
Ref->getSymbol(),
7911bool MipsAsmParser::parseDirectiveCPReturn() {
7912 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
7913 CpSaveLocationIsRegister);
7917bool MipsAsmParser::parseDirectiveNaN() {
7924 getTargetStreamer().emitDirectiveNaN2008();
7926 }
else if (Tok.
getString() ==
"legacy") {
7928 getTargetStreamer().emitDirectiveNaNLegacy();
7934 reportParseError(
"invalid option in .nan directive");
7938bool MipsAsmParser::parseDirectiveSet() {
7939 const AsmToken &Tok = getParser().getTok();
7943 if (IdVal ==
"noat")
7944 return parseSetNoAtDirective();
7946 return parseSetAtDirective();
7947 if (IdVal ==
"arch")
7948 return parseSetArchDirective();
7949 if (IdVal ==
"bopt") {
7950 Warning(Loc,
"'bopt' feature is unsupported");
7954 if (IdVal ==
"nobopt") {
7960 return parseSetFpDirective();
7961 if (IdVal ==
"oddspreg")
7962 return parseSetOddSPRegDirective();
7963 if (IdVal ==
"nooddspreg")
7964 return parseSetNoOddSPRegDirective();
7966 return parseSetPopDirective();
7967 if (IdVal ==
"push")
7968 return parseSetPushDirective();
7969 if (IdVal ==
"reorder")
7970 return parseSetReorderDirective();
7971 if (IdVal ==
"noreorder")
7972 return parseSetNoReorderDirective();
7973 if (IdVal ==
"macro")
7974 return parseSetMacroDirective();
7975 if (IdVal ==
"nomacro")
7976 return parseSetNoMacroDirective();
7977 if (IdVal ==
"mips16")
7978 return parseSetMips16Directive();
7979 if (IdVal ==
"nomips16")
7980 return parseSetNoMips16Directive();
7981 if (IdVal ==
"nomicromips") {
7982 clearFeatureBits(Mips::FeatureMicroMips,
"micromips");
7983 getTargetStreamer().emitDirectiveSetNoMicroMips();
7984 getParser().eatToEndOfStatement();
7987 if (IdVal ==
"micromips") {
7988 if (hasMips64r6()) {
7989 Error(Loc,
".set micromips directive is not supported with MIPS64R6");
7992 return parseSetFeature(Mips::FeatureMicroMips);
7994 if (IdVal ==
"mips0")
7995 return parseSetMips0Directive();
7996 if (IdVal ==
"mips1")
7997 return parseSetFeature(Mips::FeatureMips1);
7998 if (IdVal ==
"mips2")
7999 return parseSetFeature(Mips::FeatureMips2);
8000 if (IdVal ==
"mips3")
8001 return parseSetFeature(Mips::FeatureMips3);
8002 if (IdVal ==
"mips4")
8003 return parseSetFeature(Mips::FeatureMips4);
8004 if (IdVal ==
"mips5")
8005 return parseSetFeature(Mips::FeatureMips5);
8006 if (IdVal ==
"mips32")
8007 return parseSetFeature(Mips::FeatureMips32);
8008 if (IdVal ==
"mips32r2")
8009 return parseSetFeature(Mips::FeatureMips32r2);
8010 if (IdVal ==
"mips32r3")
8011 return parseSetFeature(Mips::FeatureMips32r3);
8012 if (IdVal ==
"mips32r5")
8013 return parseSetFeature(Mips::FeatureMips32r5);
8014 if (IdVal ==
"mips32r6")
8015 return parseSetFeature(Mips::FeatureMips32r6);
8016 if (IdVal ==
"mips64")
8017 return parseSetFeature(Mips::FeatureMips64);
8018 if (IdVal ==
"mips64r2")
8019 return parseSetFeature(Mips::FeatureMips64r2);
8020 if (IdVal ==
"mips64r3")
8021 return parseSetFeature(Mips::FeatureMips64r3);
8022 if (IdVal ==
"mips64r5")
8023 return parseSetFeature(Mips::FeatureMips64r5);
8024 if (IdVal ==
"mips64r6") {
8025 if (inMicroMipsMode()) {
8026 Error(Loc,
"MIPS64R6 is not supported with microMIPS");
8029 return parseSetFeature(Mips::FeatureMips64r6);
8032 return parseSetFeature(Mips::FeatureDSP);
8033 if (IdVal ==
"dspr2")
8034 return parseSetFeature(Mips::FeatureDSPR2);
8035 if (IdVal ==
"nodsp")
8036 return parseSetNoDspDirective();
8037 if (IdVal ==
"mips3d")
8038 return parseSetFeature(Mips::FeatureMips3D);
8039 if (IdVal ==
"nomips3d")
8040 return parseSetNoMips3DDirective();
8042 return parseSetMsaDirective();
8043 if (IdVal ==
"nomsa")
8044 return parseSetNoMsaDirective();
8046 return parseSetMtDirective();
8047 if (IdVal ==
"nomt")
8048 return parseSetNoMtDirective();
8049 if (IdVal ==
"softfloat")
8050 return parseSetSoftFloatDirective();
8051 if (IdVal ==
"hardfloat")
8052 return parseSetHardFloatDirective();
8054 return parseSetFeature(Mips::FeatureCRC);
8055 if (IdVal ==
"nocrc")
8056 return parseSetNoCRCDirective();
8057 if (IdVal ==
"virt")
8058 return parseSetFeature(Mips::FeatureVirt);
8059 if (IdVal ==
"novirt")
8060 return parseSetNoVirtDirective();
8061 if (IdVal ==
"ginv")
8062 return parseSetFeature(Mips::FeatureGINV);
8063 if (IdVal ==
"noginv")
8064 return parseSetNoGINVDirective();
8067 return parseSetAssignment();
8072bool MipsAsmParser::parseDirectiveGpWord() {
8077 if (getParser().parseExpression(
Value))
8079 getParser().getStreamer().emitGPRel32Value(
Value);
8082 return Error(getLexer().getLoc(),
8083 "unexpected token, expected end of statement");
8090bool MipsAsmParser::parseDirectiveGpDWord() {
8095 if (getParser().parseExpression(
Value))
8097 getParser().getStreamer().emitGPRel64Value(
Value);
8100 return Error(getLexer().getLoc(),
8101 "unexpected token, expected end of statement");
8108bool MipsAsmParser::parseDirectiveDtpRelWord() {
8113 if (getParser().parseExpression(
Value))
8115 getParser().getStreamer().emitDTPRel32Value(
Value);
8118 return Error(getLexer().getLoc(),
8119 "unexpected token, expected end of statement");
8126bool MipsAsmParser::parseDirectiveDtpRelDWord() {
8131 if (getParser().parseExpression(
Value))
8133 getParser().getStreamer().emitDTPRel64Value(
Value);
8136 return Error(getLexer().getLoc(),
8137 "unexpected token, expected end of statement");
8144bool MipsAsmParser::parseDirectiveTpRelWord() {
8149 if (getParser().parseExpression(
Value))
8151 getParser().getStreamer().emitTPRel32Value(
Value);
8154 return Error(getLexer().getLoc(),
8155 "unexpected token, expected end of statement");
8162bool MipsAsmParser::parseDirectiveTpRelDWord() {
8167 if (getParser().parseExpression(
Value))
8169 getParser().getStreamer().emitTPRel64Value(
Value);
8172 return Error(getLexer().getLoc(),
8173 "unexpected token, expected end of statement");
8178bool MipsAsmParser::parseDirectiveOption() {
8185 "unexpected token, expected identifier");
8190 if (Option ==
"pic0") {
8192 IsPicEnabled =
false;
8194 getTargetStreamer().emitDirectiveOptionPic0();
8198 "unexpected token, expected end of statement");
8203 if (Option ==
"pic2") {
8205 IsPicEnabled =
true;
8207 getTargetStreamer().emitDirectiveOptionPic2();
8211 "unexpected token, expected end of statement");
8218 "unknown option, expected 'pic0' or 'pic2'");
8225bool MipsAsmParser::parseInsnDirective() {
8228 reportParseError(
"unexpected token, expected end of statement");
8234 getTargetStreamer().emitDirectiveInsn();
8242bool MipsAsmParser::parseRSectionDirective(
StringRef Section) {
8245 reportParseError(
"unexpected token, expected end of statement");
8249 MCSection *ELFSection = getContext().getELFSection(
8251 getParser().getStreamer().switchSection(ELFSection);
8260bool MipsAsmParser::parseSSectionDirective(
StringRef Section,
unsigned Type) {
8263 reportParseError(
"unexpected token, expected end of statement");
8267 MCSection *ELFSection = getContext().getELFSection(
8269 getParser().getStreamer().switchSection(ELFSection);
8288bool MipsAsmParser::parseDirectiveModule() {
8293 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
8295 reportParseError(
".module directive must appear before any code");
8301 reportParseError(
"expected .module option identifier");
8305 if (Option ==
"oddspreg") {
8306 clearModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
8310 getTargetStreamer().updateABIInfo(*
this);
8315 getTargetStreamer().emitDirectiveModuleOddSPReg();
8319 reportParseError(
"unexpected token, expected end of statement");
8324 }
else if (Option ==
"nooddspreg") {
8326 return Error(L,
"'.module nooddspreg' requires the O32 ABI");
8329 setModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
8333 getTargetStreamer().updateABIInfo(*
this);
8338 getTargetStreamer().emitDirectiveModuleOddSPReg();
8342 reportParseError(
"unexpected token, expected end of statement");
8347 }
else if (Option ==
"fp") {
8348 return parseDirectiveModuleFP();
8349 }
else if (Option ==
"softfloat") {
8350 setModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
8354 getTargetStreamer().updateABIInfo(*
this);
8359 getTargetStreamer().emitDirectiveModuleSoftFloat();
8363 reportParseError(
"unexpected token, expected end of statement");
8368 }
else if (Option ==
"hardfloat") {
8369 clearModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
8373 getTargetStreamer().updateABIInfo(*
this);
8378 getTargetStreamer().emitDirectiveModuleHardFloat();
8382 reportParseError(
"unexpected token, expected end of statement");
8387 }
else if (Option ==
"mt") {
8388 setModuleFeatureBits(Mips::FeatureMT,
"mt");
8392 getTargetStreamer().updateABIInfo(*
this);
8397 getTargetStreamer().emitDirectiveModuleMT();
8401 reportParseError(
"unexpected token, expected end of statement");
8406 }
else if (Option ==
"crc") {
8407 setModuleFeatureBits(Mips::FeatureCRC,
"crc");
8411 getTargetStreamer().updateABIInfo(*
this);
8416 getTargetStreamer().emitDirectiveModuleCRC();
8420 reportParseError(
"unexpected token, expected end of statement");
8425 }
else if (Option ==
"nocrc") {
8426 clearModuleFeatureBits(Mips::FeatureCRC,
"crc");
8430 getTargetStreamer().updateABIInfo(*
this);
8435 getTargetStreamer().emitDirectiveModuleNoCRC();
8439 reportParseError(
"unexpected token, expected end of statement");
8444 }
else if (Option ==
"virt") {
8445 setModuleFeatureBits(Mips::FeatureVirt,
"virt");
8449 getTargetStreamer().updateABIInfo(*
this);
8454 getTargetStreamer().emitDirectiveModuleVirt();
8458 reportParseError(
"unexpected token, expected end of statement");
8463 }
else if (Option ==
"novirt") {
8464 clearModuleFeatureBits(Mips::FeatureVirt,
"virt");
8468 getTargetStreamer().updateABIInfo(*
this);
8473 getTargetStreamer().emitDirectiveModuleNoVirt();
8477 reportParseError(
"unexpected token, expected end of statement");
8482 }
else if (Option ==
"ginv") {
8483 setModuleFeatureBits(Mips::FeatureGINV,
"ginv");
8487 getTargetStreamer().updateABIInfo(*
this);
8492 getTargetStreamer().emitDirectiveModuleGINV();
8496 reportParseError(
"unexpected token, expected end of statement");
8501 }
else if (Option ==
"noginv") {
8502 clearModuleFeatureBits(Mips::FeatureGINV,
"ginv");
8506 getTargetStreamer().updateABIInfo(*
this);
8511 getTargetStreamer().emitDirectiveModuleNoGINV();
8515 reportParseError(
"unexpected token, expected end of statement");
8521 return Error(L,
"'" +
Twine(Option) +
"' is not a valid .module option.");
8529bool MipsAsmParser::parseDirectiveModuleFP() {
8534 reportParseError(
"unexpected token, expected equals sign '='");
8540 if (!parseFpABIValue(FpABI,
".module"))
8544 reportParseError(
"unexpected token, expected end of statement");
8550 getTargetStreamer().updateABIInfo(*
this);
8555 getTargetStreamer().emitDirectiveModuleFP();
8565 bool ModuleLevelOptions =
Directive ==
".module";
8571 if (
Value !=
"xx") {
8572 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
8577 reportParseError(
"'" +
Directive +
" fp=xx' requires the O32 ABI");
8581 FpABI = MipsABIFlagsSection::FpABIKind::XX;
8582 if (ModuleLevelOptions) {
8583 setModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8584 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8586 setFeatureBits(Mips::FeatureFPXX,
"fpxx");
8587 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8597 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
8603 reportParseError(
"'" +
Directive +
" fp=32' requires the O32 ABI");
8607 FpABI = MipsABIFlagsSection::FpABIKind::S32;
8608 if (ModuleLevelOptions) {
8609 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8610 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8612 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
8613 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8616 FpABI = MipsABIFlagsSection::FpABIKind::S64;
8617 if (ModuleLevelOptions) {
8618 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8619 setModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8621 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
8622 setFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8632bool MipsAsmParser::ParseDirective(
AsmToken DirectiveID) {
8641 if (IDVal ==
".cpadd") {
8642 parseDirectiveCpAdd(DirectiveID.
getLoc());
8645 if (IDVal ==
".cpload") {
8646 parseDirectiveCpLoad(DirectiveID.
getLoc());
8649 if (IDVal ==
".cprestore") {
8650 parseDirectiveCpRestore(DirectiveID.
getLoc());
8653 if (IDVal ==
".cplocal") {
8654 parseDirectiveCpLocal(DirectiveID.
getLoc());
8657 if (IDVal ==
".ent") {
8661 reportParseError(
"expected identifier after .ent");
8675 reportParseError(
"unexpected token, expected end of statement");
8679 const MCExpr *DummyNumber;
8680 int64_t DummyNumberVal;
8684 reportParseError(
"expected number after comma");
8687 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
8688 reportParseError(
"expected an absolute expression after comma");
8695 reportParseError(
"unexpected token, expected end of statement");
8699 MCSymbol *
Sym = getContext().getOrCreateSymbol(SymbolName);
8701 getTargetStreamer().emitDirectiveEnt(*
Sym);
8703 IsCpRestoreSet =
false;
8707 if (IDVal ==
".end") {
8711 reportParseError(
"expected identifier after .end");
8716 reportParseError(
"unexpected token, expected end of statement");
8720 if (CurrentFn ==
nullptr) {
8721 reportParseError(
".end used without .ent");
8725 if ((SymbolName != CurrentFn->
getName())) {
8726 reportParseError(
".end symbol does not match .ent symbol");
8730 getTargetStreamer().emitDirectiveEnd(SymbolName);
8731 CurrentFn =
nullptr;
8732 IsCpRestoreSet =
false;
8736 if (IDVal ==
".frame") {
8741 reportParseError(
"expected stack register");
8745 MipsOperand &StackRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
8746 if (!StackRegOpnd.isGPRAsmReg()) {
8747 reportParseError(StackRegOpnd.getStartLoc(),
8748 "expected general purpose register");
8751 unsigned StackReg = StackRegOpnd.getGPR32Reg();
8756 reportParseError(
"unexpected token, expected comma");
8762 int64_t FrameSizeVal;
8765 reportParseError(
"expected frame size value");
8769 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
8770 reportParseError(
"frame size not an absolute expression");
8777 reportParseError(
"unexpected token, expected comma");
8783 Res = parseAnyRegister(TmpReg);
8785 reportParseError(
"expected return register");
8789 MipsOperand &ReturnRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
8790 if (!ReturnRegOpnd.isGPRAsmReg()) {
8791 reportParseError(ReturnRegOpnd.getStartLoc(),
8792 "expected general purpose register");
8798 reportParseError(
"unexpected token, expected end of statement");
8802 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
8803 ReturnRegOpnd.getGPR32Reg());
8804 IsCpRestoreSet =
false;
8808 if (IDVal ==
".set") {
8809 parseDirectiveSet();
8813 if (IDVal ==
".mask" || IDVal ==
".fmask") {
8828 reportParseError(
"expected bitmask value");
8832 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
8833 reportParseError(
"bitmask not an absolute expression");
8840 reportParseError(
"unexpected token, expected comma");
8845 const MCExpr *FrameOffset;
8846 int64_t FrameOffsetVal;
8849 reportParseError(
"expected frame offset value");
8853 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
8854 reportParseError(
"frame offset not an absolute expression");
8860 reportParseError(
"unexpected token, expected end of statement");
8864 if (IDVal ==
".mask")
8865 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
8867 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
8871 if (IDVal ==
".nan")
8872 return parseDirectiveNaN();
8874 if (IDVal ==
".gpword") {
8875 parseDirectiveGpWord();
8879 if (IDVal ==
".gpdword") {
8880 parseDirectiveGpDWord();
8884 if (IDVal ==
".dtprelword") {
8885 parseDirectiveDtpRelWord();
8889 if (IDVal ==
".dtpreldword") {
8890 parseDirectiveDtpRelDWord();
8894 if (IDVal ==
".tprelword") {
8895 parseDirectiveTpRelWord();
8899 if (IDVal ==
".tpreldword") {
8900 parseDirectiveTpRelDWord();
8904 if (IDVal ==
".option") {
8905 parseDirectiveOption();
8909 if (IDVal ==
".abicalls") {
8910 getTargetStreamer().emitDirectiveAbiCalls();
8913 "unexpected token, expected end of statement");
8918 if (IDVal ==
".cpsetup") {
8919 parseDirectiveCPSetup();
8922 if (IDVal ==
".cpreturn") {
8923 parseDirectiveCPReturn();
8926 if (IDVal ==
".module") {
8927 parseDirectiveModule();
8930 if (IDVal ==
".llvm_internal_mips_reallow_module_directive") {
8931 parseInternalDirectiveReallowModule();
8934 if (IDVal ==
".insn") {
8935 parseInsnDirective();
8938 if (IDVal ==
".rdata") {
8939 parseRSectionDirective(
".rodata");
8942 if (IDVal ==
".sbss") {
8946 if (IDVal ==
".sdata") {
8954bool MipsAsmParser::parseInternalDirectiveReallowModule() {
8957 reportParseError(
"unexpected token, expected end of statement");
8961 getTargetStreamer().reallowModuleDirective();
8974#define GET_REGISTER_MATCHER
8975#define GET_MATCHER_IMPLEMENTATION
8976#define GET_MNEMONIC_SPELL_CHECKER
8977#include "MipsGenAsmMatcher.inc"
8979bool MipsAsmParser::mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID) {
8981 const MatchEntry *Start, *
End;
8982 switch (VariantID) {
8984 case 0: Start = std::begin(MatchTable0);
End = std::end(MatchTable0);
break;
8987 auto MnemonicRange = std::equal_range(Start,
End, Mnemonic, LessOpcode());
8988 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,...