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; }
102 const FeatureBitset &
getFeatures()
const {
return Features; }
103 void setFeatures(
const FeatureBitset &Features_) { Features = Features_; }
110 static const FeatureBitset AllArchRelatedMask;
116 FeatureBitset 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,
136 MipsTargetStreamer &getTargetStreamer() {
137 assert(getParser().getStreamer().getTargetStreamer() &&
138 "do not have a target streamer");
139 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
140 return static_cast<MipsTargetStreamer &
>(TS);
152 bool CurForbiddenSlotAttr;
155 unsigned CpSaveLocation;
157 bool CpSaveLocationIsRegister;
160 StringMap<AsmToken> RegisterSets;
163 void printWarningWithFixIt(
const Twine &Msg,
const Twine &FixMsg,
164 SMRange
Range,
bool ShowColors =
true);
166 void ConvertXWPOperands(MCInst &Inst,
const OperandVector &Operands);
168#define GET_ASSEMBLER_HEADER
169#include "MipsGenAsmMatcher.inc"
172 checkEarlyTargetMatchPredicate(
MCInst &Inst,
174 unsigned checkTargetMatchPredicate(
MCInst &Inst)
override;
176 bool matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
179 bool MatchingInlineAsm)
override;
184 SMLoc &EndLoc)
override;
190 bool mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID);
195 bool ParseDirective(
AsmToken DirectiveID)
override;
208 const MCExpr *parseRelocExpr();
214 enum MacroExpanderResultTy {
221 MacroExpanderResultTy tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
223 const MCSubtargetInfo *STI);
225 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
226 const MCSubtargetInfo *STI);
228 bool loadImmediate(int64_t ImmValue, MCRegister DstReg, MCRegister SrcReg,
229 bool Is32BitImm,
bool IsAddress, SMLoc IDLoc,
230 MCStreamer &Out,
const MCSubtargetInfo *STI);
232 bool loadAndAddSymbolAddress(
const MCExpr *SymExpr, MCRegister DstReg,
233 MCRegister SrcReg,
bool Is32BitSym, SMLoc IDLoc,
234 MCStreamer &Out,
const MCSubtargetInfo *STI);
236 bool emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc, MCSymbol *Sym);
238 bool expandLoadImm(MCInst &Inst,
bool Is32BitImm, SMLoc IDLoc,
239 MCStreamer &Out,
const MCSubtargetInfo *STI);
241 bool expandLoadSingleImmToGPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
242 const MCSubtargetInfo *STI);
243 bool expandLoadSingleImmToFPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
244 const MCSubtargetInfo *STI);
245 bool expandLoadDoubleImmToGPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
246 const MCSubtargetInfo *STI);
247 bool expandLoadDoubleImmToFPR(MCInst &Inst,
bool Is64FPU, SMLoc IDLoc,
248 MCStreamer &Out,
const MCSubtargetInfo *STI);
250 bool expandLoadAddress(MCRegister DstReg, MCRegister BaseReg,
251 const MCOperand &
Offset,
bool Is32BitAddress,
252 SMLoc IDLoc, MCStreamer &Out,
253 const MCSubtargetInfo *STI);
255 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
256 const MCSubtargetInfo *STI);
258 void expandMem16Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
259 const MCSubtargetInfo *STI,
bool IsLoad);
260 void expandMem9Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
261 const MCSubtargetInfo *STI,
bool IsLoad);
263 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
264 const MCSubtargetInfo *STI);
266 bool expandAliasImmediate(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
267 const MCSubtargetInfo *STI);
269 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
270 const MCSubtargetInfo *STI);
272 bool expandCondBranches(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
273 const MCSubtargetInfo *STI);
275 bool expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
276 const MCSubtargetInfo *STI,
const bool IsMips64,
279 bool expandTrunc(MCInst &Inst,
bool IsDouble,
bool Is64FPU, SMLoc IDLoc,
280 MCStreamer &Out,
const MCSubtargetInfo *STI);
282 bool expandUlh(MCInst &Inst,
bool Signed, SMLoc IDLoc, MCStreamer &Out,
283 const MCSubtargetInfo *STI);
285 bool expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
286 const MCSubtargetInfo *STI);
288 bool expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
289 const MCSubtargetInfo *STI);
291 bool expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
292 const MCSubtargetInfo *STI);
294 bool expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
295 const MCSubtargetInfo *STI);
297 bool expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
298 const MCSubtargetInfo *STI);
300 bool expandSle(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
301 const MCSubtargetInfo *STI);
303 bool expandSleImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
304 const MCSubtargetInfo *STI);
306 bool expandRotation(MCInst &Inst, SMLoc IDLoc,
307 MCStreamer &Out,
const MCSubtargetInfo *STI);
308 bool expandRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
309 const MCSubtargetInfo *STI);
310 bool expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
311 const MCSubtargetInfo *STI);
312 bool expandDRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
313 const MCSubtargetInfo *STI);
315 bool expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
316 const MCSubtargetInfo *STI);
318 bool expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
319 const MCSubtargetInfo *STI);
321 bool expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
322 const MCSubtargetInfo *STI);
324 bool expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
325 const MCSubtargetInfo *STI);
327 bool expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
328 const MCSubtargetInfo *STI);
330 bool expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
331 const MCSubtargetInfo *STI,
bool IsLoad);
333 bool expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
334 const MCSubtargetInfo *STI);
336 bool expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
337 const MCSubtargetInfo *STI);
339 bool expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
340 const MCSubtargetInfo *STI);
342 bool expandSne(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
343 const MCSubtargetInfo *STI);
345 bool expandSneI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
346 const MCSubtargetInfo *STI);
348 bool expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
349 const MCSubtargetInfo *STI);
351 bool expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
352 const MCSubtargetInfo *STI);
354 bool reportParseError(
const Twine &ErrorMsg);
355 bool reportParseError(SMLoc Loc,
const Twine &ErrorMsg);
357 bool parseSetMips0Directive();
358 bool parseSetArchDirective();
359 bool parseSetFeature(uint64_t Feature);
360 bool isPicAndNotNxxAbi();
361 bool parseDirectiveCpAdd(SMLoc Loc);
362 bool parseDirectiveCpLoad(SMLoc Loc);
363 bool parseDirectiveCpLocal(SMLoc Loc);
364 bool parseDirectiveCpRestore(SMLoc Loc);
365 bool parseDirectiveCPSetup();
366 bool parseDirectiveCPReturn();
367 bool parseDirectiveNaN();
368 bool parseDirectiveSet();
369 bool parseDirectiveOption();
370 bool parseInsnDirective();
371 bool parseRSectionDirective(StringRef Section);
372 bool parseSSectionDirective(StringRef Section,
unsigned Type);
374 bool parseSetAtDirective();
375 bool parseSetNoAtDirective();
376 bool parseSetMacroDirective();
377 bool parseSetNoMacroDirective();
378 bool parseSetMsaDirective();
379 bool parseSetNoMsaDirective();
380 bool parseSetNoDspDirective();
381 bool parseSetNoMips3DDirective();
382 bool parseSetReorderDirective();
383 bool parseSetNoReorderDirective();
384 bool parseSetMips16Directive();
385 bool parseSetNoMips16Directive();
386 bool parseSetFpDirective();
387 bool parseSetOddSPRegDirective();
388 bool parseSetNoOddSPRegDirective();
389 bool parseSetPopDirective();
390 bool parseSetPushDirective();
391 bool parseSetSoftFloatDirective();
392 bool parseSetHardFloatDirective();
393 bool parseSetMtDirective();
394 bool parseSetNoMtDirective();
395 bool parseSetNoCRCDirective();
396 bool parseSetNoVirtDirective();
397 bool parseSetNoGINVDirective();
399 bool parseSetAssignment();
401 bool parseDirectiveGpWord();
402 bool parseDirectiveGpDWord();
403 bool parseDirectiveDtpRelWord();
404 bool parseDirectiveDtpRelDWord();
405 bool parseDirectiveTpRelWord();
406 bool parseDirectiveTpRelDWord();
407 bool parseDirectiveModule();
408 bool parseDirectiveModuleFP();
410 StringRef Directive);
412 bool parseInternalDirectiveReallowModule();
414 bool eatComma(StringRef ErrorStr);
416 int matchCPURegisterName(StringRef Symbol);
418 int matchHWRegsRegisterName(StringRef Symbol);
420 int matchFPURegisterName(StringRef Name);
422 int matchFCCRegisterName(StringRef Name);
424 int matchACRegisterName(StringRef Name);
426 int matchMSA128RegisterName(StringRef Name);
428 int matchMSA128CtrlRegisterName(StringRef Name);
430 MCRegister
getReg(
int RC,
int RegNo);
435 MCRegister getATReg(SMLoc Loc);
439 bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
440 const MCSubtargetInfo *STI);
445 bool validateMSAIndex(
int Val,
int RegKind);
469 void selectArch(StringRef ArchFeature) {
470 MCSubtargetInfo &STI = copySTI();
472 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
474 setAvailableFeatures(
479 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
480 if (!(getSTI().hasFeature(Feature))) {
481 MCSubtargetInfo &STI = copySTI();
482 setAvailableFeatures(
488 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
489 if (getSTI().hasFeature(Feature)) {
490 MCSubtargetInfo &STI = copySTI();
491 setAvailableFeatures(
497 void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
498 setFeatureBits(Feature, FeatureString);
499 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
502 void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
503 clearFeatureBits(Feature, FeatureString);
504 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
508 enum MipsMatchResultTy {
509 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
510 Match_RequiresDifferentOperands,
511 Match_RequiresNoZeroRegister,
512 Match_RequiresSameSrcAndDst,
513 Match_NoFCCRegisterForCurrentISA,
514 Match_NonZeroOperandForSync,
515 Match_NonZeroOperandForMTCX,
516 Match_RequiresPosSizeRange0_32,
517 Match_RequiresPosSizeRange33_64,
518 Match_RequiresPosSizeUImm6,
519#define GET_OPERAND_DIAGNOSTIC_TYPES
520#include "MipsGenAsmMatcher.inc"
521#undef GET_OPERAND_DIAGNOSTIC_TYPES
524 MipsAsmParser(
const MCSubtargetInfo &sti, MCAsmParser &parser,
525 const MCInstrInfo &MII,
const MCTargetOptions &
Options)
526 : MCTargetAsmParser(
Options, sti, MII),
537 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
540 AssemblerOptions.push_back(
541 std::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
544 AssemblerOptions.push_back(
545 std::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
547 getTargetStreamer().updateABIInfo(*
this);
549 if (!isABI_O32() && !useOddSPReg() != 0)
554 CurForbiddenSlotAttr =
false;
555 IsPicEnabled =
getContext().getObjectFileInfo()->isPositionIndependent();
557 IsCpRestoreSet =
false;
558 CpRestoreOffset = -1;
559 GPReg = ABI.GetGlobalPtr();
564 if (getSTI().
getCPU() ==
"mips64r6" && inMicroMipsMode())
567 if (!isABI_O32() && inMicroMipsMode())
572 bool hasEightFccRegisters()
const {
return hasMips4() || hasMips32(); }
574 bool isGP64bit()
const {
575 return getSTI().hasFeature(Mips::FeatureGP64Bit);
578 bool isFP64bit()
const {
579 return getSTI().hasFeature(Mips::FeatureFP64Bit);
582 bool isJalrRelocAvailable(
const MCExpr *JalExpr) {
591 return ABI.IsN32() || ABI.IsN64();
595 const MipsABIInfo &getABI()
const {
return ABI; }
596 bool isABI_N32()
const {
return ABI.IsN32(); }
597 bool isABI_N64()
const {
return ABI.IsN64(); }
598 bool isABI_O32()
const {
return ABI.IsO32(); }
599 bool isABI_FPXX()
const {
600 return getSTI().hasFeature(Mips::FeatureFPXX);
603 bool useOddSPReg()
const {
604 return !(getSTI().hasFeature(Mips::FeatureNoOddSPReg));
607 bool inMicroMipsMode()
const {
608 return getSTI().hasFeature(Mips::FeatureMicroMips);
611 bool hasMips1()
const {
612 return getSTI().hasFeature(Mips::FeatureMips1);
615 bool hasMips2()
const {
616 return getSTI().hasFeature(Mips::FeatureMips2);
619 bool hasMips3()
const {
620 return getSTI().hasFeature(Mips::FeatureMips3);
623 bool hasMips4()
const {
624 return getSTI().hasFeature(Mips::FeatureMips4);
627 bool hasMips5()
const {
628 return getSTI().hasFeature(Mips::FeatureMips5);
631 bool hasMips32()
const {
632 return getSTI().hasFeature(Mips::FeatureMips32);
635 bool hasMips64()
const {
636 return getSTI().hasFeature(Mips::FeatureMips64);
639 bool hasMips32r2()
const {
640 return getSTI().hasFeature(Mips::FeatureMips32r2);
643 bool hasMips64r2()
const {
644 return getSTI().hasFeature(Mips::FeatureMips64r2);
647 bool hasMips32r3()
const {
648 return (getSTI().hasFeature(Mips::FeatureMips32r3));
651 bool hasMips64r3()
const {
652 return (getSTI().hasFeature(Mips::FeatureMips64r3));
655 bool hasMips32r5()
const {
656 return (getSTI().hasFeature(Mips::FeatureMips32r5));
659 bool hasMips64r5()
const {
660 return (getSTI().hasFeature(Mips::FeatureMips64r5));
663 bool hasMips32r6()
const {
664 return getSTI().hasFeature(Mips::FeatureMips32r6);
667 bool hasMips64r6()
const {
668 return getSTI().hasFeature(Mips::FeatureMips64r6);
671 bool hasDSP()
const {
672 return getSTI().hasFeature(Mips::FeatureDSP);
675 bool hasDSPR2()
const {
676 return getSTI().hasFeature(Mips::FeatureDSPR2);
679 bool hasDSPR3()
const {
680 return getSTI().hasFeature(Mips::FeatureDSPR3);
683 bool hasMSA()
const {
684 return getSTI().hasFeature(Mips::FeatureMSA);
687 bool hasCnMips()
const {
688 return (getSTI().hasFeature(Mips::FeatureCnMips));
691 bool hasCnMipsP()
const {
692 return (getSTI().hasFeature(Mips::FeatureCnMipsP));
699 bool inMips16Mode()
const {
700 return getSTI().hasFeature(Mips::FeatureMips16);
703 bool useTraps()
const {
704 return getSTI().hasFeature(Mips::FeatureUseTCCInDIV);
707 bool useSoftFloat()
const {
708 return getSTI().hasFeature(Mips::FeatureSoftFloat);
711 return getSTI().hasFeature(Mips::FeatureMT);
714 bool hasCRC()
const {
715 return getSTI().hasFeature(Mips::FeatureCRC);
718 bool hasVirt()
const {
719 return getSTI().hasFeature(Mips::FeatureVirt);
722 bool hasGINV()
const {
723 return getSTI().hasFeature(Mips::FeatureGINV);
726 bool hasForbiddenSlot(
const MCInstrDesc &MCID)
const {
730 bool SafeInForbiddenSlot(
const MCInstrDesc &MCID)
const {
734 void onEndOfFile()
override;
737 void warnIfRegIndexIsAT(MCRegister RegIndex, SMLoc Loc);
739 void warnIfNoMacro(SMLoc Loc);
741 bool isLittle()
const {
return IsLittleEndian; }
743 bool areEqualRegs(
const MCParsedAsmOperand &Op1,
744 const MCParsedAsmOperand &Op2)
const override;
759 RegKind_MSACtrl = 16,
764 RegKind_HWRegs = 256,
768 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
769 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
770 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
783 MipsOperand(KindTy K, MipsAsmParser &Parser) : Kind(
K), AsmParser(Parser) {}
785 ~MipsOperand()
override {
794 case k_RegisterIndex:
802 MipsAsmParser &AsmParser;
813 const MCRegisterInfo *RegInfo;
831 struct RegIdxOp RegIdx;
834 struct RegListOp RegList;
837 SMLoc StartLoc, EndLoc;
840 static std::unique_ptr<MipsOperand> CreateReg(
unsigned Index, StringRef Str,
842 const MCRegisterInfo *RegInfo,
844 MipsAsmParser &Parser) {
845 auto Op = std::make_unique<MipsOperand>(k_RegisterIndex, Parser);
847 Op->RegIdx.RegInfo = RegInfo;
848 Op->RegIdx.Kind = RegKind;
849 Op->RegIdx.Tok.Data = Str.data();
850 Op->RegIdx.Tok.Length = Str.size();
859 MCRegister getGPR32Reg()
const {
860 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
861 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
862 unsigned ClassID = Mips::GPR32RegClassID;
863 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
868 MCRegister getGPRMM16Reg()
const {
869 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
870 unsigned ClassID = Mips::GPR32RegClassID;
871 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
876 MCRegister getGPR64Reg()
const {
877 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
878 unsigned ClassID = Mips::GPR64RegClassID;
879 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
885 MCRegister getAFGR64Reg()
const {
886 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
887 if (RegIdx.Index % 2 != 0)
888 AsmParser.Warning(StartLoc,
"Float register should be even.");
889 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
890 .getRegister(RegIdx.Index / 2);
895 MCRegister getFGR64Reg()
const {
896 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
897 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
898 .getRegister(RegIdx.Index);
903 MCRegister getFGR32Reg()
const {
904 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
905 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
906 .getRegister(RegIdx.Index);
911 MCRegister getFCCReg()
const {
912 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) &&
"Invalid access!");
913 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
914 .getRegister(RegIdx.Index);
919 MCRegister getMSA128Reg()
const {
920 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) &&
"Invalid access!");
923 unsigned ClassID = Mips::MSA128BRegClassID;
924 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
929 MCRegister getMSACtrlReg()
const {
930 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) &&
"Invalid access!");
931 unsigned ClassID = Mips::MSACtrlRegClassID;
932 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
937 MCRegister getCOP0Reg()
const {
938 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) &&
"Invalid access!");
939 unsigned ClassID = Mips::COP0RegClassID;
940 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
945 MCRegister getCOP2Reg()
const {
946 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) &&
"Invalid access!");
947 unsigned ClassID = Mips::COP2RegClassID;
948 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
953 MCRegister getCOP3Reg()
const {
954 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) &&
"Invalid access!");
955 unsigned ClassID = Mips::COP3RegClassID;
956 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
961 MCRegister getACC64DSPReg()
const {
962 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
963 unsigned ClassID = Mips::ACC64DSPRegClassID;
964 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
969 MCRegister getHI32DSPReg()
const {
970 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
971 unsigned ClassID = Mips::HI32DSPRegClassID;
972 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
977 MCRegister getLO32DSPReg()
const {
978 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
979 unsigned ClassID = Mips::LO32DSPRegClassID;
980 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
985 MCRegister getCCRReg()
const {
986 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) &&
"Invalid access!");
987 unsigned ClassID = Mips::CCRRegClassID;
988 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
993 MCRegister getHWRegsReg()
const {
994 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) &&
"Invalid access!");
995 unsigned ClassID = Mips::HWRegsRegClassID;
996 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1000 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const {
1010 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1017 void addGPR32ZeroAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1018 assert(
N == 1 &&
"Invalid number of operands!");
1022 void addGPR32NonZeroAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1023 assert(
N == 1 &&
"Invalid number of operands!");
1027 void addGPR32AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1028 assert(
N == 1 &&
"Invalid number of operands!");
1032 void addGPRMM16AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1033 assert(
N == 1 &&
"Invalid number of operands!");
1037 void addGPRMM16AsmRegZeroOperands(MCInst &Inst,
unsigned N)
const {
1038 assert(
N == 1 &&
"Invalid number of operands!");
1042 void addGPRMM16AsmRegMovePOperands(MCInst &Inst,
unsigned N)
const {
1043 assert(
N == 1 &&
"Invalid number of operands!");
1047 void addGPRMM16AsmRegMovePPairFirstOperands(MCInst &Inst,
unsigned N)
const {
1048 assert(
N == 1 &&
"Invalid number of operands!");
1052 void addGPRMM16AsmRegMovePPairSecondOperands(MCInst &Inst,
1054 assert(
N == 1 &&
"Invalid number of operands!");
1061 void addGPR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1062 assert(
N == 1 &&
"Invalid number of operands!");
1066 void addAFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1067 assert(
N == 1 &&
"Invalid number of operands!");
1071 void addStrictlyAFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1072 assert(
N == 1 &&
"Invalid number of operands!");
1076 void addStrictlyFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1077 assert(
N == 1 &&
"Invalid number of operands!");
1081 void addFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1082 assert(
N == 1 &&
"Invalid number of operands!");
1086 void addFGR32AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1087 assert(
N == 1 &&
"Invalid number of operands!");
1091 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1092 AsmParser.getParser().printError(
1093 StartLoc,
"-mno-odd-spreg prohibits the use of odd FPU "
1097 void addStrictlyFGR32AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1098 assert(
N == 1 &&
"Invalid number of operands!");
1101 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1102 AsmParser.Error(StartLoc,
"-mno-odd-spreg prohibits the use of odd FPU "
1106 void addFCCAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1107 assert(
N == 1 &&
"Invalid number of operands!");
1111 void addMSA128AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1112 assert(
N == 1 &&
"Invalid number of operands!");
1116 void addMSACtrlAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1117 assert(
N == 1 &&
"Invalid number of operands!");
1121 void addCOP0AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1122 assert(
N == 1 &&
"Invalid number of operands!");
1126 void addCOP2AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1127 assert(
N == 1 &&
"Invalid number of operands!");
1131 void addCOP3AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1132 assert(
N == 1 &&
"Invalid number of operands!");
1136 void addACC64DSPAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1137 assert(
N == 1 &&
"Invalid number of operands!");
1141 void addHI32DSPAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1142 assert(
N == 1 &&
"Invalid number of operands!");
1146 void addLO32DSPAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1147 assert(
N == 1 &&
"Invalid number of operands!");
1151 void addCCRAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1152 assert(
N == 1 &&
"Invalid number of operands!");
1156 void addHWRegsAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1157 assert(
N == 1 &&
"Invalid number of operands!");
1161 template <
unsigned Bits,
int Offset = 0,
int AdjustOffset = 0>
1162 void addConstantUImmOperands(MCInst &Inst,
unsigned N)
const {
1163 assert(
N == 1 &&
"Invalid number of operands!");
1164 uint64_t
Imm = getConstantImm() -
Offset;
1167 Imm += AdjustOffset;
1171 template <
unsigned Bits>
1172 void addSImmOperands(MCInst &Inst,
unsigned N)
const {
1173 if (isImm() && !isConstantImm()) {
1177 addConstantSImmOperands<Bits, 0, 0>(Inst,
N);
1180 template <
unsigned Bits>
1181 void addUImmOperands(MCInst &Inst,
unsigned N)
const {
1182 if (isImm() && !isConstantImm()) {
1186 addConstantUImmOperands<Bits, 0, 0>(Inst,
N);
1189 template <
unsigned Bits,
int Offset = 0,
int AdjustOffset = 0>
1190 void addConstantSImmOperands(MCInst &Inst,
unsigned N)
const {
1191 assert(
N == 1 &&
"Invalid number of operands!");
1192 int64_t
Imm = getConstantImm() -
Offset;
1195 Imm += AdjustOffset;
1199 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1200 assert(
N == 1 &&
"Invalid number of operands!");
1201 const MCExpr *Expr =
getImm();
1202 addExpr(Inst, Expr);
1205 void addMemOperands(MCInst &Inst,
unsigned N)
const {
1206 assert(
N == 2 &&
"Invalid number of operands!");
1209 ? getMemBase()->getGPR64Reg()
1210 : getMemBase()->getGPR32Reg()));
1212 const MCExpr *Expr = getMemOff();
1213 addExpr(Inst, Expr);
1216 void addMicroMipsMemOperands(MCInst &Inst,
unsigned N)
const {
1217 assert(
N == 2 &&
"Invalid number of operands!");
1221 const MCExpr *Expr = getMemOff();
1222 addExpr(Inst, Expr);
1225 void addRegListOperands(MCInst &Inst,
unsigned N)
const {
1226 assert(
N == 1 &&
"Invalid number of operands!");
1228 for (
auto RegNo : getRegList())
1232 bool isReg()
const override {
1235 return isGPRAsmReg() && RegIdx.Index == 0;
1238 bool isRegIdx()
const {
return Kind == k_RegisterIndex; }
1239 bool isImm()
const override {
return Kind == k_Immediate; }
1241 bool isConstantImm()
const {
1243 return isImm() &&
getImm()->evaluateAsAbsolute(Res);
1246 bool isConstantImmz()
const {
1247 return isConstantImm() && getConstantImm() == 0;
1250 template <
unsigned Bits,
int Offset = 0>
bool isConstantUImm()
const {
1254 template <
unsigned Bits>
bool isSImm()
const {
1258 if (
getImm()->evaluateAsAbsolute(Res))
1264 template <
unsigned Bits>
bool isUImm()
const {
1268 if (
getImm()->evaluateAsAbsolute(Res))
1274 template <
unsigned Bits>
bool isAnyImm()
const {
1275 return isConstantImm() ? (
isInt<Bits>(getConstantImm()) ||
1280 template <
unsigned Bits,
int Offset = 0>
bool isConstantSImm()
const {
1284 template <
unsigned Bottom,
unsigned Top>
bool isConstantUImmRange()
const {
1285 return isConstantImm() && getConstantImm() >= Bottom &&
1286 getConstantImm() <= Top;
1289 bool isToken()
const override {
1292 return Kind == k_Token;
1295 bool isMem()
const override {
return Kind == k_Memory; }
1297 bool isConstantMemOff()
const {
1302 template <
unsigned Bits,
unsigned ShiftAmount = 0>
1303 bool isMemWithSimmOffset()
const {
1306 if (!getMemBase()->isGPRAsmReg())
1309 (isConstantMemOff() &&
1313 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res,
nullptr);
1317 bool isMemWithPtrSizeOffset()
const {
1320 if (!getMemBase()->isGPRAsmReg())
1322 const unsigned PtrBits = AsmParser.getABI().ArePtrs64bit() ? 64 : 32;
1324 (isConstantMemOff() &&
isIntN(PtrBits, getConstantMemOff())))
1327 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res,
nullptr);
1331 bool isMemWithGRPMM16Base()
const {
1332 return isMem() && getMemBase()->isMM16AsmReg();
1335 template <
unsigned Bits>
bool isMemWithUimmOffsetSP()
const {
1337 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1340 template <
unsigned Bits>
bool isMemWithUimmWordAlignedOffsetSP()
const {
1342 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1343 && (getMemBase()->getGPR32Reg() == Mips::SP);
1346 template <
unsigned Bits>
bool isMemWithSimmWordAlignedOffsetGP()
const {
1348 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1349 && (getMemBase()->getGPR32Reg() == Mips::GP);
1352 template <
unsigned Bits,
unsigned ShiftLeftAmount>
1353 bool isScaledUImm()
const {
1354 return isConstantImm() &&
1358 template <
unsigned Bits,
unsigned ShiftLeftAmount>
1359 bool isScaledSImm()
const {
1360 if (isConstantImm() &&
1365 if (Kind != k_Immediate)
1368 bool Success =
getImm()->evaluateAsRelocatable(Res,
nullptr);
1372 bool isRegList16()
const {
1376 int Size = RegList.List->size();
1380 MCRegister R0 = RegList.List->front();
1381 MCRegister R1 = RegList.List->back();
1382 if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1383 (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1386 MCRegister PrevReg = RegList.List->front();
1387 for (
int i = 1; i <
Size - 1; i++) {
1388 MCRegister
Reg = (*(RegList.List))[i];
1389 if (
Reg != PrevReg + 1)
1397 bool isInvNum()
const {
return Kind == k_Immediate; }
1399 bool isLSAImm()
const {
1400 if (!isConstantImm())
1402 int64_t Val = getConstantImm();
1403 return 1 <= Val && Val <= 4;
1406 bool isRegList()
const {
return Kind == k_RegList; }
1409 assert(Kind == k_Token &&
"Invalid access!");
1410 return StringRef(Tok.Data, Tok.Length);
1413 MCRegister
getReg()
const override {
1416 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1417 RegIdx.Kind & RegKind_GPR)
1418 return getGPR32Reg();
1424 const MCExpr *
getImm()
const {
1425 assert((Kind == k_Immediate) &&
"Invalid access!");
1429 int64_t getConstantImm()
const {
1430 const MCExpr *Val =
getImm();
1432 (void)Val->evaluateAsAbsolute(
Value);
1436 MipsOperand *getMemBase()
const {
1437 assert((Kind == k_Memory) &&
"Invalid access!");
1441 const MCExpr *getMemOff()
const {
1442 assert((Kind == k_Memory) &&
"Invalid access!");
1446 int64_t getConstantMemOff()
const {
1447 return static_cast<const MCConstantExpr *
>(getMemOff())->getValue();
1450 const SmallVectorImpl<MCRegister> &getRegList()
const {
1451 assert((Kind == k_RegList) &&
"Invalid access!");
1452 return *(RegList.List);
1455 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1456 MipsAsmParser &Parser) {
1457 auto Op = std::make_unique<MipsOperand>(k_Token, Parser);
1458 Op->Tok.Data = Str.data();
1459 Op->Tok.Length = Str.size();
1467 static std::unique_ptr<MipsOperand>
1468 createNumericReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1469 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1470 LLVM_DEBUG(
dbgs() <<
"createNumericReg(" << Index <<
", ...)\n");
1471 return CreateReg(Index, Str, RegKind_Numeric, RegInfo, S,
E, Parser);
1476 static std::unique_ptr<MipsOperand>
1477 createGPRReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1478 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1479 return CreateReg(Index, Str, RegKind_GPR, RegInfo, S,
E, Parser);
1484 static std::unique_ptr<MipsOperand>
1485 createFGRReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1486 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1487 return CreateReg(Index, Str, RegKind_FGR, RegInfo, S,
E, Parser);
1492 static std::unique_ptr<MipsOperand>
1493 createHWRegsReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1494 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1495 return CreateReg(Index, Str, RegKind_HWRegs, RegInfo, S,
E, Parser);
1500 static std::unique_ptr<MipsOperand>
1501 createFCCReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1502 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1503 return CreateReg(Index, Str, RegKind_FCC, RegInfo, S,
E, Parser);
1508 static std::unique_ptr<MipsOperand>
1509 createACCReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1510 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1511 return CreateReg(Index, Str, RegKind_ACC, RegInfo, S,
E, Parser);
1516 static std::unique_ptr<MipsOperand>
1517 createMSA128Reg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1518 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1519 return CreateReg(Index, Str, RegKind_MSA128, RegInfo, S,
E, Parser);
1524 static std::unique_ptr<MipsOperand>
1525 createMSACtrlReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1526 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1527 return CreateReg(Index, Str, RegKind_MSACtrl, RegInfo, S,
E, Parser);
1530 static std::unique_ptr<MipsOperand>
1531 CreateImm(
const MCExpr *Val, SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1532 auto Op = std::make_unique<MipsOperand>(k_Immediate, Parser);
1539 static std::unique_ptr<MipsOperand>
1540 CreateMem(std::unique_ptr<MipsOperand>
Base,
const MCExpr *Off, SMLoc S,
1541 SMLoc
E, MipsAsmParser &Parser) {
1542 auto Op = std::make_unique<MipsOperand>(k_Memory, Parser);
1543 Op->Mem.Base =
Base.release();
1550 static std::unique_ptr<MipsOperand>
1551 CreateRegList(SmallVectorImpl<MCRegister> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1552 MipsAsmParser &Parser) {
1553 assert(!Regs.
empty() &&
"Empty list not allowed");
1555 auto Op = std::make_unique<MipsOperand>(k_RegList, Parser);
1558 Op->StartLoc = StartLoc;
1559 Op->EndLoc = EndLoc;
1563 bool isGPRZeroAsmReg()
const {
1564 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
1567 bool isGPRNonZeroAsmReg()
const {
1568 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index > 0 &&
1572 bool isGPRAsmReg()
const {
1573 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1576 bool isMM16AsmReg()
const {
1577 if (!(isRegIdx() && RegIdx.Kind))
1579 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1580 || RegIdx.Index == 16 || RegIdx.Index == 17);
1583 bool isMM16AsmRegZero()
const {
1584 if (!(isRegIdx() && RegIdx.Kind))
1586 return (RegIdx.Index == 0 ||
1587 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1588 RegIdx.Index == 17);
1591 bool isMM16AsmRegMoveP()
const {
1592 if (!(isRegIdx() && RegIdx.Kind))
1594 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1595 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1598 bool isMM16AsmRegMovePPairFirst()
const {
1599 if (!(isRegIdx() && RegIdx.Kind))
1601 return RegIdx.Index >= 4 && RegIdx.Index <= 6;
1604 bool isMM16AsmRegMovePPairSecond()
const {
1605 if (!(isRegIdx() && RegIdx.Kind))
1607 return (RegIdx.Index == 21 || RegIdx.Index == 22 ||
1608 (RegIdx.Index >= 5 && RegIdx.Index <= 7));
1611 bool isFGRAsmReg()
const {
1613 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1616 bool isStrictlyFGRAsmReg()
const {
1618 return isRegIdx() && RegIdx.Kind == RegKind_FGR && RegIdx.Index <= 31;
1621 bool isHWRegsAsmReg()
const {
1622 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1625 bool isCCRAsmReg()
const {
1626 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1629 bool isFCCAsmReg()
const {
1630 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1632 return RegIdx.Index <= 7;
1635 bool isACCAsmReg()
const {
1636 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1639 bool isCOP0AsmReg()
const {
1640 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1643 bool isCOP2AsmReg()
const {
1644 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1647 bool isCOP3AsmReg()
const {
1648 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1651 bool isMSA128AsmReg()
const {
1652 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1655 bool isMSACtrlAsmReg()
const {
1656 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1660 SMLoc getStartLoc()
const override {
return StartLoc; }
1662 SMLoc getEndLoc()
const override {
return EndLoc; }
1664 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1673 Mem.Base->print(OS, MAI);
1678 case k_RegisterIndex:
1679 OS <<
"RegIdx<" << RegIdx.Index <<
":" << RegIdx.Kind <<
", "
1680 << StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) <<
">";
1687 for (
auto Reg : (*RegList.List))
1688 OS <<
Reg.
id() <<
" ";
1694 bool isValidForTie(
const MipsOperand &
Other)
const {
1695 if (Kind !=
Other.Kind)
1702 case k_RegisterIndex: {
1703 StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length);
1704 StringRef OtherToken(
Other.RegIdx.Tok.Data,
Other.RegIdx.Tok.Length);
1705 return Token == OtherToken;
1721 case Mips::JRC16_MM:
1723 case Mips::JALRS_MM:
1724 case Mips::JALRS16_MM:
1725 case Mips::BGEZALS_MM:
1726 case Mips::BLTZALS_MM:
1737 return &SRExpr->getSymbol();
1796 unsigned NumOp =
MCID.getNumOperands();
1797 if (NumOp != 3 && NumOp != 4)
1827bool MipsAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
1830 MipsTargetStreamer &TOut = getTargetStreamer();
1831 const unsigned Opcode = Inst.
getOpcode();
1832 const MCInstrDesc &MCID = MII.get(Opcode);
1833 bool ExpandedJalSym =
false;
1847 assert(hasCnMips() &&
"instruction only valid for octeon cpus");
1858 if (!
isIntN(inMicroMipsMode() ? 17 : 18,
Offset.getImm()))
1859 return Error(IDLoc,
"branch target out of range");
1862 return Error(IDLoc,
"branch to misaligned address");
1876 case Mips::BGEZAL_MM:
1877 case Mips::BLTZAL_MM:
1880 case Mips::BC1EQZC_MMR6:
1881 case Mips::BC1NEZC_MMR6:
1882 case Mips::BC2EQZC_MMR6:
1883 case Mips::BC2NEZC_MMR6:
1888 if (!
isIntN(inMicroMipsMode() ? 17 : 18,
Offset.getImm()))
1889 return Error(IDLoc,
"branch target out of range");
1892 return Error(IDLoc,
"branch to misaligned address");
1894 case Mips::BGEC:
case Mips::BGEC_MMR6:
1895 case Mips::BLTC:
case Mips::BLTC_MMR6:
1896 case Mips::BGEUC:
case Mips::BGEUC_MMR6:
1897 case Mips::BLTUC:
case Mips::BLTUC_MMR6:
1898 case Mips::BEQC:
case Mips::BEQC_MMR6:
1899 case Mips::BNEC:
case Mips::BNEC_MMR6:
1905 return Error(IDLoc,
"branch target out of range");
1907 return Error(IDLoc,
"branch to misaligned address");
1909 case Mips::BLEZC:
case Mips::BLEZC_MMR6:
1910 case Mips::BGEZC:
case Mips::BGEZC_MMR6:
1911 case Mips::BGTZC:
case Mips::BGTZC_MMR6:
1912 case Mips::BLTZC:
case Mips::BLTZC_MMR6:
1918 return Error(IDLoc,
"branch target out of range");
1920 return Error(IDLoc,
"branch to misaligned address");
1922 case Mips::BEQZC:
case Mips::BEQZC_MMR6:
1923 case Mips::BNEZC:
case Mips::BNEZC_MMR6:
1929 return Error(IDLoc,
"branch target out of range");
1931 return Error(IDLoc,
"branch to misaligned address");
1933 case Mips::BEQZ16_MM:
1934 case Mips::BEQZC16_MMR6:
1935 case Mips::BNEZ16_MM:
1936 case Mips::BNEZC16_MMR6:
1942 return Error(IDLoc,
"branch target out of range");
1944 return Error(IDLoc,
"branch to misaligned address");
1951 if (hasMips32r6() && Opcode == Mips::SSNOP) {
1952 std::string
ISA = hasMips64r6() ?
"MIPS64r6" :
"MIPS32r6";
1953 Warning(IDLoc,
"ssnop is deprecated for " + ISA +
" and is equivalent to a "
1973 return Error(IDLoc,
"expected immediate operand kind");
1975 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1976 Opcode == Mips::BBIT1 ? 63 : 31))
1977 return Error(IDLoc,
"immediate operand value out of range");
1979 Inst.
setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1990 return Error(IDLoc,
"expected immediate operand kind");
1993 return Error(IDLoc,
"immediate operand value out of range");
2005 unsigned FirstOp = 1;
2006 unsigned SecondOp = 2;
2010 case Mips::SDivIMacro:
2011 case Mips::UDivIMacro:
2012 case Mips::DSDivIMacro:
2013 case Mips::DUDivIMacro:
2017 Warning(IDLoc,
"dividing zero by zero");
2019 Warning(IDLoc,
"division by zero");
2031 case Mips::SDivMacro:
2032 case Mips::DSDivMacro:
2033 case Mips::UDivMacro:
2034 case Mips::DUDivMacro:
2039 case Mips::DIVU_MMR6:
2040 case Mips::DIV_MMR6:
2045 Warning(IDLoc,
"dividing zero by zero");
2047 Warning(IDLoc,
"division by zero");
2053 if ((Opcode == Mips::J || Opcode == Mips::J_MM) && inPicMode()) {
2055 BInst.
setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
2064 if ((Opcode == Mips::JAL || Opcode == Mips::JAL_MM) && inPicMode()) {
2065 warnIfNoMacro(IDLoc);
2068 return Error(IDLoc,
"unsupported constant in relocation");
2076 return Error(IDLoc,
"jal doesn't support multiple symbols in PIC mode");
2082 if (expandLoadAddress(Mips::T9, MCRegister(), Inst.
getOperand(0),
2083 !isGP64bit(), IDLoc, Out, STI))
2087 if (inMicroMipsMode())
2088 JalrInst.
setOpcode(IsCpRestoreSet ? Mips::JALRS_MM : Mips::JALR_MM);
2094 if (isJalrRelocAvailable(JalExpr)) {
2100 const MCExpr *RelocJalrExpr =
2104 *TmpExpr, inMicroMipsMode() ?
"R_MICROMIPS_JALR" :
"R_MIPS_JALR",
2110 ExpandedJalSym =
true;
2119 expandMem9Inst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2122 expandMem16Inst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2125 return getParser().hasPendingError();
2129 if (inMicroMipsMode()) {
2130 if (MCID.
mayLoad() && Opcode != Mips::LWP_MM) {
2133 const MCOperandInfo &OpInfo = MCID.
operands()[i];
2138 int MemOffset =
Op.getImm();
2141 if (
isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
2144 (
BaseReg.getReg() == Mips::GP ||
2145 BaseReg.getReg() == Mips::GP_64)) {
2147 TOut.
emitRRI(Mips::LWGP_MM, DstReg.
getReg(), Mips::GP, MemOffset,
2164 case Mips::ADDIUSP_MM:
2167 return Error(IDLoc,
"expected immediate operand kind");
2169 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
2171 return Error(IDLoc,
"immediate operand value out of range");
2173 case Mips::SLL16_MM:
2174 case Mips::SRL16_MM:
2177 return Error(IDLoc,
"expected immediate operand kind");
2179 if (Imm < 1 || Imm > 8)
2180 return Error(IDLoc,
"immediate operand value out of range");
2185 return Error(IDLoc,
"expected immediate operand kind");
2187 if (Imm < -1 || Imm > 126)
2188 return Error(IDLoc,
"immediate operand value out of range");
2190 case Mips::ADDIUR2_MM:
2193 return Error(IDLoc,
"expected immediate operand kind");
2195 if (!(Imm == 1 || Imm == -1 ||
2196 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
2197 return Error(IDLoc,
"immediate operand value out of range");
2199 case Mips::ANDI16_MM:
2202 return Error(IDLoc,
"expected immediate operand kind");
2204 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
2205 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
2206 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
2207 return Error(IDLoc,
"immediate operand value out of range");
2209 case Mips::LBU16_MM:
2212 return Error(IDLoc,
"expected immediate operand kind");
2214 if (Imm < -1 || Imm > 14)
2215 return Error(IDLoc,
"immediate operand value out of range");
2218 case Mips::SB16_MMR6:
2221 return Error(IDLoc,
"expected immediate operand kind");
2223 if (Imm < 0 || Imm > 15)
2224 return Error(IDLoc,
"immediate operand value out of range");
2226 case Mips::LHU16_MM:
2228 case Mips::SH16_MMR6:
2231 return Error(IDLoc,
"expected immediate operand kind");
2233 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
2234 return Error(IDLoc,
"immediate operand value out of range");
2238 case Mips::SW16_MMR6:
2241 return Error(IDLoc,
"expected immediate operand kind");
2243 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
2244 return Error(IDLoc,
"immediate operand value out of range");
2246 case Mips::ADDIUPC_MM:
2249 return Error(IDLoc,
"expected immediate operand kind");
2252 return Error(IDLoc,
"immediate operand value out of range");
2257 return Error(IDLoc,
"invalid operand for instruction");
2259 case Mips::MOVEP_MM:
2260 case Mips::MOVEP_MMR6: {
2263 bool RegPair = ((R0 == Mips::A1 && R1 == Mips::A2) ||
2264 (R0 == Mips::A1 && R1 == Mips::A3) ||
2265 (R0 == Mips::A2 && R1 == Mips::A3) ||
2266 (R0 == Mips::A0 && R1 == Mips::S5) ||
2267 (R0 == Mips::A0 && R1 == Mips::S6) ||
2268 (R0 == Mips::A0 && R1 == Mips::A1) ||
2269 (R0 == Mips::A0 && R1 == Mips::A2) ||
2270 (R0 == Mips::A0 && R1 == Mips::A3));
2272 return Error(IDLoc,
"invalid operand for instruction");
2278 bool FillDelaySlot =
2283 bool PrevForbiddenSlotAttr = CurForbiddenSlotAttr;
2286 bool SetReorderAfterNop =
false;
2291 if (PrevForbiddenSlotAttr && !SafeInForbiddenSlot(MCID)) {
2301 if (AssemblerOptions.
back()->isReorder() && !FillDelaySlot) {
2302 SetReorderAfterNop =
true;
2311 CurForbiddenSlotAttr =
2312 hasForbiddenSlot(MCID) && AssemblerOptions.
back()->isReorder();
2314 if (FillDelaySlot || CurForbiddenSlotAttr)
2317 MacroExpanderResultTy ExpandResult =
2318 tryExpandInstruction(Inst, IDLoc, Out, STI);
2319 switch (ExpandResult) {
2335 if (PrevForbiddenSlotAttr && !SetReorderAfterNop && !FillDelaySlot &&
2336 AssemblerOptions.
back()->isReorder()) {
2342 if (inMicroMipsMode()) {
2357 if (FillDelaySlot) {
2362 if ((Opcode == Mips::JalOneReg || Opcode == Mips::JalTwoReg ||
2364 isPicAndNotNxxAbi()) {
2365 if (IsCpRestoreSet) {
2369 if (!AssemblerOptions.
back()->isReorder())
2376 Warning(IDLoc,
"no .cprestore used in PIC mode");
2382void MipsAsmParser::onEndOfFile() {
2383 MipsTargetStreamer &TOut = getTargetStreamer();
2384 SMLoc IDLoc = SMLoc();
2386 if (CurForbiddenSlotAttr) {
2388 if (AssemblerOptions.
back()->isReorder())
2393MipsAsmParser::MacroExpanderResultTy
2394MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2395 const MCSubtargetInfo *STI) {
2398 return MER_NotAMacro;
2399 case Mips::LoadImm32:
2400 return expandLoadImm(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2401 case Mips::LoadImm64:
2402 return expandLoadImm(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2403 case Mips::LoadAddrImm32:
2404 case Mips::LoadAddrImm64:
2407 "expected immediate operand kind");
2409 return expandLoadAddress(
2411 Inst.
getOpcode() == Mips::LoadAddrImm32, IDLoc, Out, STI)
2414 case Mips::LoadAddrReg32:
2415 case Mips::LoadAddrReg64:
2419 "expected immediate operand kind");
2423 Inst.
getOpcode() == Mips::LoadAddrReg32, IDLoc,
2427 case Mips::B_MM_Pseudo:
2428 case Mips::B_MMR6_Pseudo:
2429 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2433 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2435 case Mips::JalOneReg:
2436 case Mips::JalTwoReg:
2437 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2440 case Mips::BEQLImmMacro:
2441 case Mips::BNELImmMacro:
2442 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2459 case Mips::BLTImmMacro:
2460 case Mips::BLEImmMacro:
2461 case Mips::BGEImmMacro:
2462 case Mips::BGTImmMacro:
2463 case Mips::BLTUImmMacro:
2464 case Mips::BLEUImmMacro:
2465 case Mips::BGEUImmMacro:
2466 case Mips::BGTUImmMacro:
2467 case Mips::BLTLImmMacro:
2468 case Mips::BLELImmMacro:
2469 case Mips::BGELImmMacro:
2470 case Mips::BGTLImmMacro:
2471 case Mips::BLTULImmMacro:
2472 case Mips::BLEULImmMacro:
2473 case Mips::BGEULImmMacro:
2474 case Mips::BGTULImmMacro:
2475 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2476 case Mips::SDivMacro:
2477 case Mips::SDivIMacro:
2478 case Mips::SRemMacro:
2479 case Mips::SRemIMacro:
2480 return expandDivRem(Inst, IDLoc, Out, STI,
false,
true) ? MER_Fail
2482 case Mips::DSDivMacro:
2483 case Mips::DSDivIMacro:
2484 case Mips::DSRemMacro:
2485 case Mips::DSRemIMacro:
2486 return expandDivRem(Inst, IDLoc, Out, STI,
true,
true) ? MER_Fail
2488 case Mips::UDivMacro:
2489 case Mips::UDivIMacro:
2490 case Mips::URemMacro:
2491 case Mips::URemIMacro:
2492 return expandDivRem(Inst, IDLoc, Out, STI,
false,
false) ? MER_Fail
2494 case Mips::DUDivMacro:
2495 case Mips::DUDivIMacro:
2496 case Mips::DURemMacro:
2497 case Mips::DURemIMacro:
2498 return expandDivRem(Inst, IDLoc, Out, STI,
true,
false) ? MER_Fail
2500 case Mips::PseudoTRUNC_W_S:
2501 return expandTrunc(Inst,
false,
false, IDLoc, Out, STI) ? MER_Fail
2503 case Mips::PseudoTRUNC_W_D32:
2504 return expandTrunc(Inst,
true,
false, IDLoc, Out, STI) ? MER_Fail
2506 case Mips::PseudoTRUNC_W_D:
2507 return expandTrunc(Inst,
true,
true, IDLoc, Out, STI) ? MER_Fail
2510 case Mips::LoadImmSingleGPR:
2511 return expandLoadSingleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2513 case Mips::LoadImmSingleFGR:
2514 return expandLoadSingleImmToFPR(Inst, IDLoc, Out, STI) ? MER_Fail
2516 case Mips::LoadImmDoubleGPR:
2517 return expandLoadDoubleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2519 case Mips::LoadImmDoubleFGR:
2520 return expandLoadDoubleImmToFPR(Inst,
true, IDLoc, Out, STI) ? MER_Fail
2522 case Mips::LoadImmDoubleFGR_32:
2523 return expandLoadDoubleImmToFPR(Inst,
false, IDLoc, Out, STI) ? MER_Fail
2527 return expandUlh(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2529 return expandUlh(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2531 return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2534 return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2536 case Mips::NORImm64:
2537 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2540 return expandSge(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2543 case Mips::SGEImm64:
2544 case Mips::SGEUImm64:
2545 return expandSgeImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2548 case Mips::SGTImm64:
2549 case Mips::SGTUImm64:
2550 return expandSgtImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2553 return expandSle(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2556 case Mips::SLEImm64:
2557 case Mips::SLEUImm64:
2558 return expandSleImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2559 case Mips::SLTImm64:
2562 return MER_NotAMacro;
2564 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2565 case Mips::SLTUImm64:
2568 return MER_NotAMacro;
2570 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2571 case Mips::ADDi:
case Mips::ADDi_MM:
2572 case Mips::ADDiu:
case Mips::ADDiu_MM:
2573 case Mips::SLTi:
case Mips::SLTi_MM:
2574 case Mips::SLTiu:
case Mips::SLTiu_MM:
2579 return MER_NotAMacro;
2580 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2583 return MER_NotAMacro;
2584 case Mips::ANDi:
case Mips::ANDi_MM:
case Mips::ANDi64:
2585 case Mips::ORi:
case Mips::ORi_MM:
case Mips::ORi64:
2586 case Mips::XORi:
case Mips::XORi_MM:
case Mips::XORi64:
2591 return MER_NotAMacro;
2592 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2595 return MER_NotAMacro;
2598 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2601 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2604 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2607 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2608 case Mips::ABSMacro:
2609 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2610 case Mips::MULImmMacro:
2611 case Mips::DMULImmMacro:
2612 return expandMulImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2613 case Mips::MULOMacro:
2614 case Mips::DMULOMacro:
2615 return expandMulO(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2616 case Mips::MULOUMacro:
2617 case Mips::DMULOUMacro:
2618 return expandMulOU(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2619 case Mips::DMULMacro:
2620 return expandDMULMacro(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2623 return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2628 return expandStoreDM1Macro(Inst, IDLoc, Out, STI)
2631 case Mips::SEQMacro:
2632 return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2633 case Mips::SEQIMacro:
2634 return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2635 case Mips::SNEMacro:
2636 return expandSne(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2637 case Mips::SNEIMacro:
2638 return expandSneI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2639 case Mips::MFTC0:
case Mips::MTTC0:
2640 case Mips::MFTGPR:
case Mips::MTTGPR:
2641 case Mips::MFTLO:
case Mips::MTTLO:
2642 case Mips::MFTHI:
case Mips::MTTHI:
2643 case Mips::MFTACX:
case Mips::MTTACX:
2644 case Mips::MFTDSP:
case Mips::MTTDSP:
2645 case Mips::MFTC1:
case Mips::MTTC1:
2646 case Mips::MFTHC1:
case Mips::MTTHC1:
2647 case Mips::CFTC1:
case Mips::CTTC1:
2648 return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2650 case Mips::SaadAddr:
2651 return expandSaaAddr(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2655bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2657 const MCSubtargetInfo *STI) {
2658 MipsTargetStreamer &TOut = getTargetStreamer();
2663 const MCOperand FirstRegOp = Inst.
getOperand(0);
2664 const unsigned Opcode = Inst.
getOpcode();
2666 if (Opcode == Mips::JalOneReg) {
2668 if (IsCpRestoreSet && inMicroMipsMode()) {
2671 }
else if (inMicroMipsMode()) {
2672 JalrInst.
setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2679 }
else if (Opcode == Mips::JalTwoReg) {
2681 if (IsCpRestoreSet && inMicroMipsMode())
2684 JalrInst.
setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2686 const MCOperand SecondRegOp = Inst.
getOperand(1);
2693 const MCInstrDesc &MCID = MII.get(JalrInst.
getOpcode());
2716bool MipsAsmParser::loadImmediate(int64_t ImmValue, MCRegister DstReg,
2717 MCRegister SrcReg,
bool Is32BitImm,
2718 bool IsAddress, SMLoc IDLoc, MCStreamer &Out,
2719 const MCSubtargetInfo *STI) {
2720 MipsTargetStreamer &TOut = getTargetStreamer();
2722 if (!Is32BitImm && !isGP64bit()) {
2723 Error(IDLoc,
"instruction requires a 64-bit architecture");
2734 Error(IDLoc,
"instruction requires a 32-bit immediate");
2739 MCRegister ZeroReg = IsAddress ?
ABI.GetNullPtr() :
ABI.GetZeroReg();
2740 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2742 bool UseSrcReg =
false;
2746 MCRegister TmpReg = DstReg;
2748 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2751 MCRegister ATReg = getATReg(IDLoc);
2764 if (IsAddress && !Is32BitImm) {
2765 TOut.
emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2769 TOut.
emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2774 MCRegister TmpReg = DstReg;
2775 if (SrcReg == DstReg) {
2776 TmpReg = getATReg(IDLoc);
2781 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2783 TOut.
emitRRR(
ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2788 warnIfNoMacro(IDLoc);
2790 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2791 uint16_t Bits15To0 = ImmValue & 0xffff;
2792 if (!Is32BitImm && !
isInt<32>(ImmValue)) {
2795 if (ImmValue == 0xffffffff) {
2796 TOut.
emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2797 TOut.
emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2799 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2805 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2806 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2808 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2810 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2814 TOut.
emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2816 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2818 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2824 Error(IDLoc,
"instruction requires a 32-bit immediate");
2831 assert(
BitWidth >= 17 &&
"ImmValue must be at least 17-bit wide");
2835 unsigned ShiftAmount =
BitWidth - 16;
2836 uint16_t
Bits = (ImmValue >> ShiftAmount) & 0xffff;
2837 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2838 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2841 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2846 warnIfNoMacro(IDLoc);
2853 if (loadImmediate(ImmValue >> 32, TmpReg, MCRegister(),
true,
false, IDLoc,
2859 unsigned ShiftCarriedForwards = 16;
2860 for (
int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2861 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2863 if (ImmChunk != 0) {
2864 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2865 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2866 ShiftCarriedForwards = 0;
2869 ShiftCarriedForwards += 16;
2871 ShiftCarriedForwards -= 16;
2874 if (ShiftCarriedForwards)
2875 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2878 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2883bool MipsAsmParser::expandLoadImm(MCInst &Inst,
bool Is32BitImm, SMLoc IDLoc,
2884 MCStreamer &Out,
const MCSubtargetInfo *STI) {
2886 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
2887 const MCOperand &DstRegOp = Inst.
getOperand(0);
2888 assert(DstRegOp.
isReg() &&
"expected register operand kind");
2890 if (loadImmediate(ImmOp.
getImm(), DstRegOp.
getReg(), MCRegister(), Is32BitImm,
2891 false, IDLoc, Out, STI))
2897bool MipsAsmParser::expandLoadAddress(MCRegister DstReg, MCRegister BaseReg,
2899 bool Is32BitAddress, SMLoc IDLoc,
2901 const MCSubtargetInfo *STI) {
2903 if (Is32BitAddress &&
ABI.ArePtrs64bit()) {
2904 Warning(IDLoc,
"la used to load 64-bit address");
2906 Is32BitAddress =
false;
2910 if (!Is32BitAddress && !hasMips3()) {
2911 Error(IDLoc,
"instruction requires a 64-bit architecture");
2916 return loadAndAddSymbolAddress(
Offset.getExpr(), DstReg, BaseReg,
2917 Is32BitAddress, IDLoc, Out, STI);
2919 if (!
ABI.ArePtrs64bit()) {
2921 Is32BitAddress =
true;
2924 return loadImmediate(
Offset.getImm(), DstReg, BaseReg, Is32BitAddress,
true,
2928bool MipsAsmParser::loadAndAddSymbolAddress(
const MCExpr *SymExpr,
2930 MCRegister SrcReg,
bool Is32BitSym,
2931 SMLoc IDLoc, MCStreamer &Out,
2932 const MCSubtargetInfo *STI) {
2933 MipsTargetStreamer &TOut = getTargetStreamer();
2935 SrcReg.
isValid() && SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64;
2936 warnIfNoMacro(IDLoc);
2941 Error(IDLoc,
"expected relocatable expression");
2945 Error(IDLoc,
"expected relocatable expression with only one symbol");
2949 bool IsPtr64 =
ABI.ArePtrs64bit();
2953 static_cast<const MCSymbolELF *
>(Res.
getAddSym())->getBinding() ==
2960 bool UseXGOT = STI->
hasFeature(Mips::FeatureXGOT) && !IsLocalSym;
2966 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2969 const MCExpr *CallHiExpr =
2971 const MCExpr *CallLoExpr =
2975 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, DstReg, GPReg,
2977 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, DstReg,
2980 const MCExpr *CallExpr =
2982 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, GPReg,
2988 MCRegister TmpReg = DstReg;
2990 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2994 MCRegister ATReg = getATReg(IDLoc);
3013 const MCExpr *CallHiExpr =
3020 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg, GPReg,
3022 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, TmpReg,
3026 TOut.
emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3032 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3037 const MCSpecifierExpr *GotExpr =
nullptr;
3038 const MCExpr *LoExpr =
nullptr;
3039 if (
ABI.IsN32() ||
ABI.IsN64()) {
3058 Error(IDLoc,
"macro instruction uses large offset, which is not "
3059 "currently supported");
3088 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, GPReg,
3092 TOut.
emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3096 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3102 const auto *HiExpr =
3104 const auto *LoExpr =
3108 if (
ABI.ArePtrs64bit() && isGP64bit()) {
3116 const auto *HighestExpr =
3118 const auto *HigherExpr =
3123 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
3125 if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
3126 MCRegister ATReg = getATReg(IDLoc);
3138 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3140 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3143 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3146 TOut.
emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
3149 }
else if (canUseATReg() && !RdRegIsRsReg && DstReg != getATReg(IDLoc)) {
3150 MCRegister ATReg = getATReg(IDLoc);
3166 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3170 TOut.
emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3171 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3173 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3176 }
else if ((!canUseATReg() && !RdRegIsRsReg) ||
3177 (canUseATReg() && DstReg == getATReg(IDLoc))) {
3188 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3190 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3191 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3193 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3194 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3197 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3203 assert(SrcReg == DstReg && !canUseATReg() &&
3204 "Could have expanded dla but didn't?");
3205 reportParseError(IDLoc,
3206 "pseudo-instruction requires $at, which is not available");
3220 MCRegister TmpReg = DstReg;
3222 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
3225 MCRegister ATReg = getATReg(IDLoc);
3236 TOut.
emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3239 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
3248 if (MipsMCRegisterClasses[Mips::FGR32RegClassID].
contains(
Reg))
3249 return Reg == (
unsigned)Mips::F31 ? (
unsigned)Mips::F0 :
Reg + 1;
3251 default:
llvm_unreachable(
"Unknown register in assembly macro expansion!");
3252 case Mips::ZERO:
return Mips::AT;
3253 case Mips::AT:
return Mips::V0;
3254 case Mips::V0:
return Mips::V1;
3255 case Mips::V1:
return Mips::A0;
3256 case Mips::A0:
return Mips::A1;
3257 case Mips::A1:
return Mips::A2;
3258 case Mips::A2:
return Mips::A3;
3259 case Mips::A3:
return Mips::T0;
3260 case Mips::T0:
return Mips::T1;
3261 case Mips::T1:
return Mips::T2;
3262 case Mips::T2:
return Mips::T3;
3263 case Mips::T3:
return Mips::T4;
3264 case Mips::T4:
return Mips::T5;
3265 case Mips::T5:
return Mips::T6;
3266 case Mips::T6:
return Mips::T7;
3267 case Mips::T7:
return Mips::S0;
3268 case Mips::S0:
return Mips::S1;
3269 case Mips::S1:
return Mips::S2;
3270 case Mips::S2:
return Mips::S3;
3271 case Mips::S3:
return Mips::S4;
3272 case Mips::S4:
return Mips::S5;
3273 case Mips::S5:
return Mips::S6;
3274 case Mips::S6:
return Mips::S7;
3275 case Mips::S7:
return Mips::T8;
3276 case Mips::T8:
return Mips::T9;
3277 case Mips::T9:
return Mips::K0;
3278 case Mips::K0:
return Mips::K1;
3279 case Mips::K1:
return Mips::GP;
3280 case Mips::GP:
return Mips::SP;
3281 case Mips::SP:
return Mips::FP;
3282 case Mips::FP:
return Mips::RA;
3283 case Mips::RA:
return Mips::ZERO;
3284 case Mips::D0:
return Mips::F1;
3285 case Mips::D1:
return Mips::F3;
3286 case Mips::D2:
return Mips::F5;
3287 case Mips::D3:
return Mips::F7;
3288 case Mips::D4:
return Mips::F9;
3289 case Mips::D5:
return Mips::F11;
3290 case Mips::D6:
return Mips::F13;
3291 case Mips::D7:
return Mips::F15;
3292 case Mips::D8:
return Mips::F17;
3293 case Mips::D9:
return Mips::F19;
3294 case Mips::D10:
return Mips::F21;
3295 case Mips::D11:
return Mips::F23;
3296 case Mips::D12:
return Mips::F25;
3297 case Mips::D13:
return Mips::F27;
3298 case Mips::D14:
return Mips::F29;
3299 case Mips::D15:
return Mips::F31;
3309bool MipsAsmParser::emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc,
3311 MCRegister ATReg = getATReg(IDLoc);
3317 const auto *GotExpr =
3320 if(isABI_O32() || isABI_N32()) {
3329 const auto *HiExpr =
3338 if(isABI_O32() || isABI_N32()) {
3342 const auto *HighestExpr =
3345 const auto *HigherExpr =
3350 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3352 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3355 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3364 if ((
Hi_32(ImmOp64) & 0x7ff00000) == 0) {
3375 float TmpFloat =
static_cast<float>(DoubleImm);
3379bool MipsAsmParser::expandLoadSingleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3381 const MCSubtargetInfo *STI) {
3384 "Invalid instruction operand.");
3391 return loadImmediate(ImmOp32, FirstReg, MCRegister(),
true,
false, IDLoc, Out,
3395bool MipsAsmParser::expandLoadSingleImmToFPR(MCInst &Inst, SMLoc IDLoc,
3397 const MCSubtargetInfo *STI) {
3398 MipsTargetStreamer &TOut = getTargetStreamer();
3401 "Invalid instruction operand.");
3410 MCRegister TmpReg = Mips::ZERO;
3412 TmpReg = getATReg(IDLoc);
3417 if (
Lo_32(ImmOp64) == 0) {
3418 if (TmpReg != Mips::ZERO && loadImmediate(ImmOp32, TmpReg, MCRegister(),
3419 true,
false, IDLoc, Out, STI))
3421 TOut.
emitRR(Mips::MTC1, FirstReg, TmpReg, IDLoc, STI);
3425 MCSection *CS = getStreamer().getCurrentSectionOnly();
3428 MCSection *ReadOnlySection =
3435 getStreamer().switchSection(ReadOnlySection);
3436 getStreamer().emitLabel(Sym, IDLoc);
3437 getStreamer().emitInt32(ImmOp32);
3438 getStreamer().switchSection(CS);
3440 if (emitPartialAddress(TOut, IDLoc, Sym))
3447bool MipsAsmParser::expandLoadDoubleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3449 const MCSubtargetInfo *STI) {
3450 MipsTargetStreamer &TOut = getTargetStreamer();
3453 "Invalid instruction operand.");
3460 if (
Lo_32(ImmOp64) == 0) {
3462 if (loadImmediate(ImmOp64, FirstReg, MCRegister(),
false,
false, IDLoc,
3466 if (loadImmediate(
Hi_32(ImmOp64), FirstReg, MCRegister(),
true,
false,
3470 if (loadImmediate(0,
nextReg(FirstReg), MCRegister(),
true,
false, IDLoc,
3477 MCSection *CS = getStreamer().getCurrentSectionOnly();
3478 MCSection *ReadOnlySection =
3485 getStreamer().switchSection(ReadOnlySection);
3486 getStreamer().emitLabel(Sym, IDLoc);
3487 getStreamer().emitValueToAlignment(
Align(8));
3488 getStreamer().emitIntValue(ImmOp64, 8);
3489 getStreamer().switchSection(CS);
3491 MCRegister TmpReg = getATReg(IDLoc);
3495 if (emitPartialAddress(TOut, IDLoc, Sym))
3498 TOut.
emitRRX(isABI_N64() ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3502 TOut.
emitRRI(Mips::LD, FirstReg, TmpReg, 0, IDLoc, STI);
3504 TOut.
emitRRI(Mips::LW, FirstReg, TmpReg, 0, IDLoc, STI);
3505 TOut.
emitRRI(Mips::LW,
nextReg(FirstReg), TmpReg, 4, IDLoc, STI);
3510bool MipsAsmParser::expandLoadDoubleImmToFPR(MCInst &Inst,
bool Is64FPU,
3511 SMLoc IDLoc, MCStreamer &Out,
3512 const MCSubtargetInfo *STI) {
3513 MipsTargetStreamer &TOut = getTargetStreamer();
3516 "Invalid instruction operand.");
3523 MCRegister TmpReg = Mips::ZERO;
3525 TmpReg = getATReg(IDLoc);
3530 if ((
Lo_32(ImmOp64) == 0) &&
3531 !((
Hi_32(ImmOp64) & 0xffff0000) && (
Hi_32(ImmOp64) & 0x0000ffff))) {
3533 if (TmpReg != Mips::ZERO && loadImmediate(ImmOp64, TmpReg, MCRegister(),
3534 false,
false, IDLoc, Out, STI))
3536 TOut.
emitRR(Mips::DMTC1, FirstReg, TmpReg, IDLoc, STI);
3540 if (TmpReg != Mips::ZERO &&
3541 loadImmediate(
Hi_32(ImmOp64), TmpReg, MCRegister(),
true,
false, IDLoc,
3545 if (hasMips32r2()) {
3546 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3547 TOut.
emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, TmpReg, IDLoc, STI);
3549 TOut.
emitRR(Mips::MTC1,
nextReg(FirstReg), TmpReg, IDLoc, STI);
3550 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3555 MCSection *CS = getStreamer().getCurrentSectionOnly();
3558 MCSection *ReadOnlySection =
3565 getStreamer().switchSection(ReadOnlySection);
3566 getStreamer().emitLabel(Sym, IDLoc);
3567 getStreamer().emitValueToAlignment(
Align(8));
3568 getStreamer().emitIntValue(ImmOp64, 8);
3569 getStreamer().switchSection(CS);
3571 if (emitPartialAddress(TOut, IDLoc, Sym))
3574 TOut.
emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, TmpReg,
3580bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
3582 const MCSubtargetInfo *STI) {
3583 MipsTargetStreamer &TOut = getTargetStreamer();
3586 "unexpected number of operands");
3596 assert(
Offset.isImm() &&
"expected immediate operand kind");
3600 if (inMicroMipsMode())
3601 Inst.
setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3604 return Error(IDLoc,
"branch target out of range");
3606 return Error(IDLoc,
"branch to misaligned address");
3618 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
3625bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3626 const MCSubtargetInfo *STI) {
3627 MipsTargetStreamer &TOut = getTargetStreamer();
3628 const MCOperand &DstRegOp = Inst.
getOperand(0);
3629 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3632 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
3634 const MCOperand &MemOffsetOp = Inst.
getOperand(2);
3636 "expected immediate or expression operand");
3638 bool IsLikely =
false;
3648 case Mips::BEQLImmMacro:
3652 case Mips::BNELImmMacro:
3661 int64_t ImmValue = ImmOp.
getImm();
3662 if (ImmValue == 0) {
3666 TOut.
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3668 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3671 warnIfNoMacro(IDLoc);
3673 MCRegister ATReg = getATReg(IDLoc);
3677 if (loadImmediate(ImmValue, ATReg, MCRegister(), !isGP64bit(),
true, IDLoc,
3681 if (IsLikely && MemOffsetOp.
isExpr()) {
3684 TOut.
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3686 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3691void MipsAsmParser::expandMem16Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3692 const MCSubtargetInfo *STI,
bool IsLoad) {
3694 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3695 unsigned StartOp = NumOp == 3 ? 0 : 1;
3697 const MCOperand &DstRegOp = Inst.
getOperand(StartOp);
3698 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3699 const MCOperand &BaseRegOp = Inst.
getOperand(StartOp + 1);
3700 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3703 MipsTargetStreamer &TOut = getTargetStreamer();
3705 MCRegister DstReg = DstRegOp.
getReg();
3707 MCRegister TmpReg = DstReg;
3709 const MCInstrDesc &
Desc = MII.get(OpCode);
3710 int16_t DstRegClass =
3711 MII.getOpRegClassID(
Desc.operands()[StartOp],
3713 unsigned DstRegClassID =
3714 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3715 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3716 (DstRegClassID == Mips::GPR64RegClassID);
3718 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3721 TmpReg = getATReg(IDLoc);
3726 auto emitInstWithOffset = [&](
const MCOperand &
Off) {
3728 TOut.
emitRRX(OpCode, DstReg, TmpReg, Off, IDLoc, STI);
3730 TOut.
emitRRRX(OpCode, DstReg, DstReg, TmpReg, Off, IDLoc, STI);
3734 int64_t LoOffset =
OffsetOp.getImm() & 0xffff;
3735 int64_t HiOffset =
OffsetOp.getImm() & ~0xffff;
3739 if (LoOffset & 0x8000)
3740 HiOffset += 0x10000;
3742 bool IsLargeOffset = HiOffset != 0;
3744 if (IsLargeOffset) {
3746 if (loadImmediate(HiOffset, TmpReg, MCRegister(), Is32BitImm,
true, IDLoc,
3751 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3752 TOut.
emitRRR(
ABI.ArePtrs64bit() ? Mips::DADDu : Mips::ADDu, TmpReg,
3753 TmpReg, BaseReg, IDLoc, STI);
3767 if (!
OffsetOp.getExpr()->evaluateAsRelocatable(Res,
nullptr)) {
3768 Error(IDLoc,
"expected relocatable expression");
3772 Error(IDLoc,
"expected relocatable expression with only one symbol");
3776 loadAndAddSymbolAddress(
3778 BaseReg, !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3786 const MCExpr *OffExpr =
OffsetOp.getExpr();
3798 TOut.
emitRX(Mips::LUi, TmpReg, HighestOperand, IDLoc, STI);
3799 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HigherOperand, IDLoc, STI);
3800 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3801 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HiOperand, IDLoc, STI);
3802 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3803 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3804 TOut.
emitRRR(Mips::DADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3805 emitInstWithOffset(LoOperand);
3808 TOut.
emitRX(Mips::LUi, TmpReg, HiOperand, IDLoc, STI);
3809 if (BaseReg != Mips::ZERO)
3810 TOut.
emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3812 emitInstWithOffset(LoOperand);
3821void MipsAsmParser::expandMem9Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3822 const MCSubtargetInfo *STI,
bool IsLoad) {
3824 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3825 unsigned StartOp = NumOp == 3 ? 0 : 1;
3827 const MCOperand &DstRegOp = Inst.
getOperand(StartOp);
3828 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3829 const MCOperand &BaseRegOp = Inst.
getOperand(StartOp + 1);
3830 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3833 MipsTargetStreamer &TOut = getTargetStreamer();
3835 MCRegister DstReg = DstRegOp.
getReg();
3837 MCRegister TmpReg = DstReg;
3839 const MCInstrDesc &
Desc = MII.get(OpCode);
3840 int16_t DstRegClass =
3841 MII.getOpRegClassID(
Desc.operands()[StartOp],
3844 unsigned DstRegClassID =
3845 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3846 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3847 (DstRegClassID == Mips::GPR64RegClassID);
3849 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3852 TmpReg = getATReg(IDLoc);
3857 auto emitInst = [&]() {
3866 loadImmediate(
OffsetOp.getImm(), TmpReg, BaseReg, !
ABI.ArePtrs64bit(),
true,
3873 loadAndAddSymbolAddress(
OffsetOp.getExpr(), TmpReg, BaseReg,
3874 !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3882bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
3884 const MCSubtargetInfo *STI) {
3887 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3891 Inst.
getOperand(OpNum - 3).
isReg() &&
"Invalid instruction operand.");
3900 if (inMicroMipsMode() && hasMips32r6())
3901 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3903 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3911bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
3913 const MCSubtargetInfo *STI) {
3914 MipsTargetStreamer &TOut = getTargetStreamer();
3915 bool EmittedNoMacroWarning =
false;
3916 unsigned PseudoOpcode = Inst.
getOpcode();
3921 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3922 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3927 else if (TrgOp.
isImm()) {
3928 warnIfNoMacro(IDLoc);
3929 EmittedNoMacroWarning =
true;
3931 TrgReg = getATReg(IDLoc);
3935 switch(PseudoOpcode) {
3938 case Mips::BLTImmMacro:
3939 PseudoOpcode = Mips::BLT;
3941 case Mips::BLEImmMacro:
3942 PseudoOpcode = Mips::BLE;
3944 case Mips::BGEImmMacro:
3945 PseudoOpcode = Mips::BGE;
3947 case Mips::BGTImmMacro:
3948 PseudoOpcode = Mips::BGT;
3950 case Mips::BLTUImmMacro:
3951 PseudoOpcode = Mips::BLTU;
3953 case Mips::BLEUImmMacro:
3954 PseudoOpcode = Mips::BLEU;
3956 case Mips::BGEUImmMacro:
3957 PseudoOpcode = Mips::BGEU;
3959 case Mips::BGTUImmMacro:
3960 PseudoOpcode = Mips::BGTU;
3962 case Mips::BLTLImmMacro:
3963 PseudoOpcode = Mips::BLTL;
3965 case Mips::BLELImmMacro:
3966 PseudoOpcode = Mips::BLEL;
3968 case Mips::BGELImmMacro:
3969 PseudoOpcode = Mips::BGEL;
3971 case Mips::BGTLImmMacro:
3972 PseudoOpcode = Mips::BGTL;
3974 case Mips::BLTULImmMacro:
3975 PseudoOpcode = Mips::BLTUL;
3977 case Mips::BLEULImmMacro:
3978 PseudoOpcode = Mips::BLEUL;
3980 case Mips::BGEULImmMacro:
3981 PseudoOpcode = Mips::BGEUL;
3983 case Mips::BGTULImmMacro:
3984 PseudoOpcode = Mips::BGTUL;
3988 if (loadImmediate(TrgOp.
getImm(), TrgReg, MCRegister(), !isGP64bit(),
false,
3993 switch (PseudoOpcode) {
3998 AcceptsEquality =
false;
3999 ReverseOrderSLT =
false;
4001 ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
4002 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
4003 ZeroSrcOpcode = Mips::BGTZ;
4004 ZeroTrgOpcode = Mips::BLTZ;
4010 AcceptsEquality =
true;
4011 ReverseOrderSLT =
true;
4013 ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
4014 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
4015 ZeroSrcOpcode = Mips::BGEZ;
4016 ZeroTrgOpcode = Mips::BLEZ;
4022 AcceptsEquality =
true;
4023 ReverseOrderSLT =
false;
4025 ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
4026 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
4027 ZeroSrcOpcode = Mips::BLEZ;
4028 ZeroTrgOpcode = Mips::BGEZ;
4034 AcceptsEquality =
false;
4035 ReverseOrderSLT =
true;
4037 ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
4038 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
4039 ZeroSrcOpcode = Mips::BLTZ;
4040 ZeroTrgOpcode = Mips::BGTZ;
4046 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
4047 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
4048 if (IsSrcRegZero && IsTrgRegZero) {
4052 if (PseudoOpcode == Mips::BLT) {
4057 if (PseudoOpcode == Mips::BLE) {
4060 Warning(IDLoc,
"branch is always taken");
4063 if (PseudoOpcode == Mips::BGE) {
4066 Warning(IDLoc,
"branch is always taken");
4069 if (PseudoOpcode == Mips::BGT) {
4074 if (PseudoOpcode == Mips::BGTU) {
4075 TOut.
emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
4079 if (AcceptsEquality) {
4082 TOut.
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4084 Warning(IDLoc,
"branch is always taken");
4091 if (IsSrcRegZero || IsTrgRegZero) {
4092 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
4093 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
4100 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
4101 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
4107 TOut.
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4109 Warning(IDLoc,
"branch is always taken");
4125 TOut.
emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
4126 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
4133 TOut.
emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
4134 IsSrcRegZero ? TrgReg : SrcReg,
4141 MCRegister ATRegNum = getATReg(IDLoc);
4145 if (!EmittedNoMacroWarning)
4146 warnIfNoMacro(IDLoc);
4163 TOut.
emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
4164 ReverseOrderSLT ? TrgReg : SrcReg,
4165 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
4167 TOut.
emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
4168 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
4182bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4183 const MCSubtargetInfo *STI,
4184 const bool IsMips64,
const bool Signed) {
4185 MipsTargetStreamer &TOut = getTargetStreamer();
4187 warnIfNoMacro(IDLoc);
4189 const MCOperand &RdRegOp = Inst.
getOperand(0);
4190 assert(RdRegOp.
isReg() &&
"expected register operand kind");
4191 MCRegister RdReg = RdRegOp.
getReg();
4193 const MCOperand &RsRegOp = Inst.
getOperand(1);
4194 assert(RsRegOp.
isReg() &&
"expected register operand kind");
4195 MCRegister RsReg = RsRegOp.
getReg();
4202 "expected register or immediate operand kind");
4206 ImmValue = RtOp.
getImm();
4213 DivOp =
Signed ? Mips::DSDIV : Mips::DUDIV;
4214 ZeroReg = Mips::ZERO_64;
4217 DivOp =
Signed ? Mips::SDIV : Mips::UDIV;
4218 ZeroReg = Mips::ZERO;
4222 bool UseTraps = useTraps();
4225 bool isDiv = Opcode == Mips::SDivMacro || Opcode == Mips::SDivIMacro ||
4226 Opcode == Mips::UDivMacro || Opcode == Mips::UDivIMacro ||
4227 Opcode == Mips::DSDivMacro || Opcode == Mips::DSDivIMacro ||
4228 Opcode == Mips::DUDivMacro || Opcode == Mips::DUDivIMacro;
4230 bool isRem = Opcode == Mips::SRemMacro || Opcode == Mips::SRemIMacro ||
4231 Opcode == Mips::URemMacro || Opcode == Mips::URemIMacro ||
4232 Opcode == Mips::DSRemMacro || Opcode == Mips::DSRemIMacro ||
4233 Opcode == Mips::DURemMacro || Opcode == Mips::DURemIMacro;
4236 MCRegister ATReg = getATReg(IDLoc);
4240 if (ImmValue == 0) {
4242 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4244 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4248 if (isRem && (ImmValue == 1 || (
Signed && (ImmValue == -1)))) {
4249 TOut.
emitRRR(Mips::OR, RdReg, ZeroReg, ZeroReg, IDLoc, STI);
4251 }
else if (isDiv && ImmValue == 1) {
4252 TOut.
emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI);
4254 }
else if (isDiv &&
Signed && ImmValue == -1) {
4255 TOut.
emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
4258 if (loadImmediate(ImmValue, ATReg, MCRegister(),
isInt<32>(ImmValue),
4259 false, Inst.
getLoc(), Out, STI))
4261 TOut.
emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
4262 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4272 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
4274 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4277 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4283 if (isRem && (RdReg == Mips::ZERO || RdReg == Mips::ZERO_64)) {
4284 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4294 TOut.
emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4297 BrTarget =
Context.createTempSymbol();
4299 TOut.
emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4302 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4305 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4311 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4315 MCRegister ATReg = getATReg(IDLoc);
4322 TOut.
emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
4326 MCOperand LabelOpEnd =
4330 TOut.
emitRRX(Mips::BNE, RtReg, ATReg, LabelOpEnd, IDLoc, STI);
4333 TOut.
emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
4334 TOut.
emitDSLL(ATReg, ATReg, 63, IDLoc, STI);
4336 TOut.
emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, STI);
4340 TOut.
emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
4343 TOut.
emitRRX(Mips::BNE, RsReg, ATReg, LabelOpEnd, IDLoc, STI);
4345 TOut.
emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
4349 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4353bool MipsAsmParser::expandTrunc(MCInst &Inst,
bool IsDouble,
bool Is64FPU,
4354 SMLoc IDLoc, MCStreamer &Out,
4355 const MCSubtargetInfo *STI) {
4356 MipsTargetStreamer &TOut = getTargetStreamer();
4366 if (hasMips1() && !hasMips2()) {
4367 MCRegister ATReg = getATReg(IDLoc);
4370 TOut.
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4371 TOut.
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4373 TOut.
emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4374 TOut.
emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4375 TOut.
emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4377 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4379 FirstReg, SecondReg, IDLoc, STI);
4380 TOut.
emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4385 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4387 FirstReg, SecondReg, IDLoc, STI);
4392bool MipsAsmParser::expandUlh(MCInst &Inst,
bool Signed, SMLoc IDLoc,
4393 MCStreamer &Out,
const MCSubtargetInfo *STI) {
4394 if (hasMips32r6() || hasMips64r6()) {
4395 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4398 const MCOperand &DstRegOp = Inst.
getOperand(0);
4399 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4400 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4401 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4402 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4403 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4405 MipsTargetStreamer &TOut = getTargetStreamer();
4406 MCRegister DstReg = DstRegOp.
getReg();
4407 MCRegister SrcReg = SrcRegOp.
getReg();
4408 int64_t OffsetValue = OffsetImmOp.
getImm();
4412 warnIfNoMacro(IDLoc);
4413 MCRegister ATReg = getATReg(IDLoc);
4418 if (IsLargeOffset) {
4419 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4424 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4425 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4429 MCRegister FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4430 MCRegister SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4432 MCRegister LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4433 MCRegister SllReg = IsLargeOffset ? DstReg : ATReg;
4435 TOut.
emitRRI(
Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4436 FirstOffset, IDLoc, STI);
4437 TOut.
emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4438 TOut.
emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4439 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4444bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4445 const MCSubtargetInfo *STI) {
4446 if (hasMips32r6() || hasMips64r6()) {
4447 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4450 const MCOperand &DstRegOp = Inst.
getOperand(0);
4451 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4452 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4453 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4454 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4455 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4457 MipsTargetStreamer &TOut = getTargetStreamer();
4458 MCRegister DstReg = DstRegOp.
getReg();
4459 MCRegister SrcReg = SrcRegOp.
getReg();
4460 int64_t OffsetValue = OffsetImmOp.
getImm();
4462 warnIfNoMacro(IDLoc);
4463 MCRegister ATReg = getATReg(IDLoc);
4468 if (IsLargeOffset) {
4469 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4474 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4475 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4479 if (IsLargeOffset) {
4480 TOut.
emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4481 TOut.
emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4482 TOut.
emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4483 TOut.
emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4484 TOut.
emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4485 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4487 TOut.
emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4488 TOut.
emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4489 TOut.
emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4495bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4496 const MCSubtargetInfo *STI) {
4497 if (hasMips32r6() || hasMips64r6()) {
4498 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4501 const MCOperand &DstRegOp = Inst.
getOperand(0);
4502 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4503 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4504 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4505 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4506 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4508 MipsTargetStreamer &TOut = getTargetStreamer();
4509 MCRegister DstReg = DstRegOp.
getReg();
4510 MCRegister SrcReg = SrcRegOp.
getReg();
4511 int64_t OffsetValue = OffsetImmOp.
getImm();
4515 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4516 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4520 bool IsLoadInst = (Inst.
getOpcode() == Mips::Ulw);
4521 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4522 MCRegister TmpReg = SrcReg;
4523 if (IsLargeOffset || DoMove) {
4524 warnIfNoMacro(IDLoc);
4525 TmpReg = getATReg(IDLoc);
4530 if (IsLargeOffset) {
4531 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4539 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4540 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4541 TOut.
emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4542 TOut.
emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4545 TOut.
emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4550bool MipsAsmParser::expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4551 const MCSubtargetInfo *STI) {
4552 MipsTargetStreamer &TOut = getTargetStreamer();
4564 warnIfNoMacro(IDLoc);
4578 TOut.
emitRRR(OpCode, DstReg, SrcReg, OpReg, IDLoc, STI);
4579 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4584bool MipsAsmParser::expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4585 const MCSubtargetInfo *STI) {
4586 MipsTargetStreamer &TOut = getTargetStreamer();
4596 unsigned OpRegCode, OpImmCode;
4598 warnIfNoMacro(IDLoc);
4602 case Mips::SGEImm64:
4603 OpRegCode = Mips::SLT;
4604 OpImmCode = Mips::SLTi;
4607 case Mips::SGEUImm64:
4608 OpRegCode = Mips::SLTu;
4609 OpImmCode = Mips::SLTiu;
4618 TOut.
emitRRI(OpImmCode, DstReg, SrcReg, ImmValue, IDLoc, STI);
4619 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4621 MCRegister ImmReg = DstReg;
4622 if (DstReg == SrcReg) {
4623 MCRegister ATReg = getATReg(Inst.
getLoc());
4629 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
4630 false, IDLoc, Out, STI))
4633 TOut.
emitRRR(OpRegCode, DstReg, SrcReg, ImmReg, IDLoc, STI);
4634 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4640bool MipsAsmParser::expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4641 const MCSubtargetInfo *STI) {
4642 MipsTargetStreamer &TOut = getTargetStreamer();
4651 MCRegister ImmReg = DstReg;
4655 warnIfNoMacro(IDLoc);
4659 case Mips::SGTImm64:
4663 case Mips::SGTUImm64:
4670 if (DstReg == SrcReg) {
4671 MCRegister ATReg = getATReg(Inst.
getLoc());
4677 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
false,
4682 TOut.
emitRRR(OpCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4687bool MipsAsmParser::expandSle(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4688 const MCSubtargetInfo *STI) {
4689 MipsTargetStreamer &TOut = getTargetStreamer();
4701 warnIfNoMacro(IDLoc);
4715 TOut.
emitRRR(OpCode, DstReg, OpReg, SrcReg, IDLoc, STI);
4716 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4721bool MipsAsmParser::expandSleImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4722 const MCSubtargetInfo *STI) {
4723 MipsTargetStreamer &TOut = getTargetStreamer();
4735 warnIfNoMacro(IDLoc);
4739 case Mips::SLEImm64:
4740 OpRegCode = Mips::SLT;
4743 case Mips::SLEUImm64:
4744 OpRegCode = Mips::SLTu;
4751 MCRegister ImmReg = DstReg;
4752 if (DstReg == SrcReg) {
4753 MCRegister ATReg = getATReg(Inst.
getLoc());
4759 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
false,
4763 TOut.
emitRRR(OpRegCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4764 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4769bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
4771 const MCSubtargetInfo *STI) {
4772 MipsTargetStreamer &TOut = getTargetStreamer();
4780 MCRegister FinalDstReg;
4787 unsigned FinalOpcode = Inst.
getOpcode();
4789 if (DstReg == SrcReg) {
4790 ATReg = getATReg(Inst.
getLoc());
4793 FinalDstReg = DstReg;
4797 if (!loadImmediate(ImmValue, DstReg, MCRegister(), Is32Bit,
false,
4798 Inst.
getLoc(), Out, STI)) {
4799 switch (FinalOpcode) {
4803 FinalOpcode = Mips::ADD;
4806 FinalOpcode = Mips::ADDu;
4809 FinalOpcode = Mips::AND;
4812 FinalOpcode = Mips::NOR;
4815 FinalOpcode = Mips::OR;
4818 FinalOpcode = Mips::SLT;
4821 FinalOpcode = Mips::SLTu;
4824 FinalOpcode = Mips::XOR;
4827 FinalOpcode = Mips::ADD_MM;
4829 case Mips::ADDiu_MM:
4830 FinalOpcode = Mips::ADDu_MM;
4833 FinalOpcode = Mips::AND_MM;
4836 FinalOpcode = Mips::OR_MM;
4839 FinalOpcode = Mips::SLT_MM;
4841 case Mips::SLTiu_MM:
4842 FinalOpcode = Mips::SLTu_MM;
4845 FinalOpcode = Mips::XOR_MM;
4848 FinalOpcode = Mips::AND64;
4850 case Mips::NORImm64:
4851 FinalOpcode = Mips::NOR64;
4854 FinalOpcode = Mips::OR64;
4856 case Mips::SLTImm64:
4857 FinalOpcode = Mips::SLT64;
4859 case Mips::SLTUImm64:
4860 FinalOpcode = Mips::SLTu64;
4863 FinalOpcode = Mips::XOR64;
4868 TOut.
emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4870 TOut.
emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4876bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4877 const MCSubtargetInfo *STI) {
4878 MipsTargetStreamer &TOut = getTargetStreamer();
4883 MCRegister TmpReg =
DReg;
4885 unsigned FirstShift = Mips::NOP;
4886 unsigned SecondShift = Mips::NOP;
4888 if (hasMips32r2()) {
4890 TmpReg = getATReg(Inst.
getLoc());
4896 TOut.
emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4897 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
4902 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
4914 FirstShift = Mips::SRLV;
4915 SecondShift = Mips::SLLV;
4918 FirstShift = Mips::SLLV;
4919 SecondShift = Mips::SRLV;
4923 ATReg = getATReg(Inst.
getLoc());
4927 TOut.
emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4928 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
4929 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
4930 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
4938bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
4940 const MCSubtargetInfo *STI) {
4941 MipsTargetStreamer &TOut = getTargetStreamer();
4947 unsigned FirstShift = Mips::NOP;
4948 unsigned SecondShift = Mips::NOP;
4950 if (hasMips32r2()) {
4952 uint64_t MaxShift = 32;
4953 uint64_t ShiftValue = ImmValue;
4955 ShiftValue = MaxShift - ImmValue;
4956 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
4961 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.
getLoc(), STI);
4969 if (ImmValue == 0) {
4978 FirstShift = Mips::SLL;
4979 SecondShift = Mips::SRL;
4982 FirstShift = Mips::SRL;
4983 SecondShift = Mips::SLL;
4987 ATReg = getATReg(Inst.
getLoc());
4991 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.
getLoc(), STI);
4992 TOut.
emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.
getLoc(), STI);
4993 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5001bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5002 const MCSubtargetInfo *STI) {
5003 MipsTargetStreamer &TOut = getTargetStreamer();
5008 MCRegister TmpReg =
DReg;
5010 unsigned FirstShift = Mips::NOP;
5011 unsigned SecondShift = Mips::NOP;
5013 if (hasMips64r2()) {
5014 if (TmpReg == SReg) {
5015 TmpReg = getATReg(Inst.
getLoc());
5021 TOut.
emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
5022 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
5027 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
5039 FirstShift = Mips::DSRLV;
5040 SecondShift = Mips::DSLLV;
5043 FirstShift = Mips::DSLLV;
5044 SecondShift = Mips::DSRLV;
5048 ATReg = getATReg(Inst.
getLoc());
5052 TOut.
emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
5053 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
5054 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
5055 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5063bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
5065 const MCSubtargetInfo *STI) {
5066 MipsTargetStreamer &TOut = getTargetStreamer();
5072 unsigned FirstShift = Mips::NOP;
5073 unsigned SecondShift = Mips::NOP;
5077 if (hasMips64r2()) {
5078 unsigned FinalOpcode = Mips::NOP;
5080 FinalOpcode = Mips::DROTR;
5081 else if (ImmValue % 32 == 0)
5082 FinalOpcode = Mips::DROTR32;
5083 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
5085 FinalOpcode = Mips::DROTR32;
5087 FinalOpcode = Mips::DROTR;
5088 }
else if (ImmValue >= 33) {
5090 FinalOpcode = Mips::DROTR;
5092 FinalOpcode = Mips::DROTR32;
5095 uint64_t ShiftValue = ImmValue % 32;
5097 ShiftValue = (32 - ImmValue % 32) % 32;
5099 TOut.
emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
5105 if (ImmValue == 0) {
5106 TOut.
emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.
getLoc(), STI);
5114 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5115 FirstShift = Mips::DSLL;
5116 SecondShift = Mips::DSRL32;
5118 if (ImmValue == 32) {
5119 FirstShift = Mips::DSLL32;
5120 SecondShift = Mips::DSRL32;
5122 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5123 FirstShift = Mips::DSLL32;
5124 SecondShift = Mips::DSRL;
5128 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5129 FirstShift = Mips::DSRL;
5130 SecondShift = Mips::DSLL32;
5132 if (ImmValue == 32) {
5133 FirstShift = Mips::DSRL32;
5134 SecondShift = Mips::DSLL32;
5136 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5137 FirstShift = Mips::DSRL32;
5138 SecondShift = Mips::DSLL;
5143 ATReg = getATReg(Inst.
getLoc());
5147 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.
getLoc(), STI);
5148 TOut.
emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
5150 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5158bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5159 const MCSubtargetInfo *STI) {
5160 MipsTargetStreamer &TOut = getTargetStreamer();
5164 TOut.
emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
5165 if (FirstRegOp != SecondRegOp)
5166 TOut.
emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
5169 TOut.
emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
5174bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5175 const MCSubtargetInfo *STI) {
5176 MipsTargetStreamer &TOut = getTargetStreamer();
5182 ATReg = getATReg(IDLoc);
5186 loadImmediate(ImmValue, ATReg, MCRegister(),
true,
false, IDLoc, Out, STI);
5188 TOut.
emitRR(Inst.
getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
5189 SrcReg, ATReg, IDLoc, STI);
5191 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5196bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5197 const MCSubtargetInfo *STI) {
5198 MipsTargetStreamer &TOut = getTargetStreamer();
5204 ATReg = getATReg(Inst.
getLoc());
5208 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
5209 SrcReg, TmpReg, IDLoc, STI);
5211 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5213 TOut.
emitRRI(Inst.
getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
5214 DstReg, DstReg, 0x1F, IDLoc, STI);
5216 TOut.
emitR(Mips::MFHI, ATReg, IDLoc, STI);
5219 TOut.
emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
5226 TOut.
emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
5227 if (AssemblerOptions.
back()->isReorder())
5229 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5233 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5238bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5239 const MCSubtargetInfo *STI) {
5240 MipsTargetStreamer &TOut = getTargetStreamer();
5246 ATReg = getATReg(IDLoc);
5250 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
5251 SrcReg, TmpReg, IDLoc, STI);
5253 TOut.
emitR(Mips::MFHI, ATReg, IDLoc, STI);
5254 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5256 TOut.
emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);
5263 TOut.
emitRRX(Mips::BEQ, ATReg, Mips::ZERO, LabelOp, IDLoc, STI);
5264 if (AssemblerOptions.
back()->isReorder())
5266 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5274bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5275 const MCSubtargetInfo *STI) {
5276 MipsTargetStreamer &TOut = getTargetStreamer();
5281 TOut.
emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
5282 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5292bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
5294 const MCSubtargetInfo *STI,
5299 warnIfNoMacro(IDLoc);
5301 MipsTargetStreamer &TOut = getTargetStreamer();
5302 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
5304 MCRegister SecondReg =
nextReg(FirstReg);
5309 warnIfRegIndexIsAT(FirstReg, IDLoc);
5312 "Offset for load macro is not immediate!");
5315 signed NextOffset = FirstOffset.
getImm() + 4;
5323 if (FirstReg != BaseReg || !IsLoad) {
5324 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5325 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5327 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5328 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5340bool MipsAsmParser::expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc,
5342 const MCSubtargetInfo *STI) {
5346 warnIfNoMacro(IDLoc);
5348 MipsTargetStreamer &TOut = getTargetStreamer();
5349 unsigned Opcode = Mips::SWC1;
5351 MCRegister SecondReg =
nextReg(FirstReg);
5356 warnIfRegIndexIsAT(FirstReg, IDLoc);
5359 "Offset for macro is not immediate!");
5362 signed NextOffset = FirstOffset.
getImm() + 4;
5368 if (!IsLittleEndian)
5371 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5372 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5377bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5378 const MCSubtargetInfo *STI) {
5379 MipsTargetStreamer &TOut = getTargetStreamer();
5390 warnIfNoMacro(IDLoc);
5392 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5393 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5394 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5398 MCRegister
Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5399 TOut.
emitRRI(Mips::SLTiu, DstReg,
Reg, 1, IDLoc, STI);
5403bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5404 const MCSubtargetInfo *STI) {
5405 MipsTargetStreamer &TOut = getTargetStreamer();
5416 warnIfNoMacro(IDLoc);
5419 TOut.
emitRRI(Mips::SLTiu, DstReg, SrcReg, 1, IDLoc, STI);
5423 if (SrcReg == Mips::ZERO) {
5424 Warning(IDLoc,
"comparison is always false");
5425 TOut.
emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
5426 DstReg, SrcReg, SrcReg, IDLoc, STI);
5431 if (Imm > -0x8000 && Imm < 0) {
5433 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5439 MCRegister ATReg = getATReg(IDLoc);
5443 if (loadImmediate(Imm, ATReg, MCRegister(),
true, isGP64bit(), IDLoc, Out,
5447 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5448 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5452 TOut.
emitRRI(
Opc, DstReg, SrcReg, Imm, IDLoc, STI);
5453 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5457bool MipsAsmParser::expandSne(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5458 const MCSubtargetInfo *STI) {
5460 MipsTargetStreamer &TOut = getTargetStreamer();
5471 warnIfNoMacro(IDLoc);
5473 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5474 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5475 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5479 MCRegister
Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5480 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO,
Reg, IDLoc, STI);
5484bool MipsAsmParser::expandSneI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5485 const MCSubtargetInfo *STI) {
5486 MipsTargetStreamer &TOut = getTargetStreamer();
5497 warnIfNoMacro(IDLoc);
5499 if (ImmValue == 0) {
5500 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, SrcReg, IDLoc, STI);
5504 if (SrcReg == Mips::ZERO) {
5505 Warning(IDLoc,
"comparison is always true");
5506 if (loadImmediate(1, DstReg, MCRegister(),
true,
false, IDLoc, Out, STI))
5512 if (ImmValue > -0x8000 && ImmValue < 0) {
5513 ImmValue = -ImmValue;
5514 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5520 TOut.
emitRRI(
Opc, DstReg, SrcReg, ImmValue, IDLoc, STI);
5521 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5525 MCRegister ATReg = getATReg(IDLoc);
5529 if (loadImmediate(ImmValue, ATReg, MCRegister(),
isInt<32>(ImmValue),
false,
5533 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5534 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5597 case Mips::F0:
return Mips::ZERO;
5598 case Mips::F1:
return Mips::AT;
5599 case Mips::F2:
return Mips::V0;
5600 case Mips::F3:
return Mips::V1;
5601 case Mips::F4:
return Mips::A0;
5602 case Mips::F5:
return Mips::A1;
5603 case Mips::F6:
return Mips::A2;
5604 case Mips::F7:
return Mips::A3;
5605 case Mips::F8:
return Mips::T0;
5606 case Mips::F9:
return Mips::T1;
5607 case Mips::F10:
return Mips::T2;
5608 case Mips::F11:
return Mips::T3;
5609 case Mips::F12:
return Mips::T4;
5610 case Mips::F13:
return Mips::T5;
5611 case Mips::F14:
return Mips::T6;
5612 case Mips::F15:
return Mips::T7;
5613 case Mips::F16:
return Mips::S0;
5614 case Mips::F17:
return Mips::S1;
5615 case Mips::F18:
return Mips::S2;
5616 case Mips::F19:
return Mips::S3;
5617 case Mips::F20:
return Mips::S4;
5618 case Mips::F21:
return Mips::S5;
5619 case Mips::F22:
return Mips::S6;
5620 case Mips::F23:
return Mips::S7;
5621 case Mips::F24:
return Mips::T8;
5622 case Mips::F25:
return Mips::T9;
5623 case Mips::F26:
return Mips::K0;
5624 case Mips::F27:
return Mips::K1;
5625 case Mips::F28:
return Mips::GP;
5626 case Mips::F29:
return Mips::SP;
5627 case Mips::F30:
return Mips::FP;
5628 case Mips::F31:
return Mips::RA;
5636 case Mips::COP00:
return Mips::ZERO;
5637 case Mips::COP01:
return Mips::AT;
5638 case Mips::COP02:
return Mips::V0;
5639 case Mips::COP03:
return Mips::V1;
5640 case Mips::COP04:
return Mips::A0;
5641 case Mips::COP05:
return Mips::A1;
5642 case Mips::COP06:
return Mips::A2;
5643 case Mips::COP07:
return Mips::A3;
5644 case Mips::COP08:
return Mips::T0;
5645 case Mips::COP09:
return Mips::T1;
5646 case Mips::COP010:
return Mips::T2;
5647 case Mips::COP011:
return Mips::T3;
5648 case Mips::COP012:
return Mips::T4;
5649 case Mips::COP013:
return Mips::T5;
5650 case Mips::COP014:
return Mips::T6;
5651 case Mips::COP015:
return Mips::T7;
5652 case Mips::COP016:
return Mips::S0;
5653 case Mips::COP017:
return Mips::S1;
5654 case Mips::COP018:
return Mips::S2;
5655 case Mips::COP019:
return Mips::S3;
5656 case Mips::COP020:
return Mips::S4;
5657 case Mips::COP021:
return Mips::S5;
5658 case Mips::COP022:
return Mips::S6;
5659 case Mips::COP023:
return Mips::S7;
5660 case Mips::COP024:
return Mips::T8;
5661 case Mips::COP025:
return Mips::T9;
5662 case Mips::COP026:
return Mips::K0;
5663 case Mips::COP027:
return Mips::K1;
5664 case Mips::COP028:
return Mips::GP;
5665 case Mips::COP029:
return Mips::SP;
5666 case Mips::COP030:
return Mips::FP;
5667 case Mips::COP031:
return Mips::RA;
5674bool MipsAsmParser::expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5675 const MCSubtargetInfo *STI) {
5676 MipsTargetStreamer &TOut = getTargetStreamer();
5681 bool IsMFTR =
false;
5735 IsMFTR ? MCRegister(rd)
5737 : Inst.getOperand(0).
getReg());
5739 TOut.
emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, u, sel, h, IDLoc,
5744bool MipsAsmParser::expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5745 const MCSubtargetInfo *STI) {
5750 warnIfNoMacro(IDLoc);
5752 MipsTargetStreamer &TOut = getTargetStreamer();
5753 unsigned Opcode = Inst.
getOpcode() == Mips::SaaAddr ? Mips::SAA : Mips::SAAD;
5756 const MCOperand &BaseOp = Inst.
getOperand(2);
5758 if (BaseOp.
isImm()) {
5759 int64_t ImmValue = BaseOp.
getImm();
5760 if (ImmValue == 0) {
5761 TOut.
emitRR(Opcode, RtReg, BaseReg, IDLoc, STI);
5766 MCRegister ATReg = getATReg(IDLoc);
5770 if (expandLoadAddress(ATReg, BaseReg, BaseOp, !isGP64bit(), IDLoc, Out, STI))
5773 TOut.
emitRR(Opcode, RtReg, ATReg, IDLoc, STI);
5778MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
5782 return Match_Success;
5785 if (
static_cast<MipsOperand &
>(*Operands[1])
5786 .isValidForTie(
static_cast<MipsOperand &
>(*Operands[2])))
5787 return Match_Success;
5788 return Match_RequiresSameSrcAndDst;
5792unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
5799 return Match_RequiresNoZeroRegister;
5800 return Match_Success;
5806 case Mips::JALR_HB64:
5807 case Mips::JALRC_HB_MMR6:
5808 case Mips::JALRC_MMR6:
5810 return Match_RequiresDifferentSrcAndDst;
5811 return Match_Success;
5814 return Match_RequiresDifferentSrcAndDst;
5815 return Match_Success;
5818 return Match_NonZeroOperandForSync;
5819 return Match_Success;
5825 return Match_NonZeroOperandForMTCX;
5826 return Match_Success;
5839 case Mips::BLEZC:
case Mips::BLEZC_MMR6:
5840 case Mips::BGEZC:
case Mips::BGEZC_MMR6:
5841 case Mips::BGTZC:
case Mips::BGTZC_MMR6:
5842 case Mips::BLTZC:
case Mips::BLTZC_MMR6:
5843 case Mips::BEQZC:
case Mips::BEQZC_MMR6:
5844 case Mips::BNEZC:
case Mips::BNEZC_MMR6:
5853 return Match_RequiresNoZeroRegister;
5854 return Match_Success;
5855 case Mips::BGEC:
case Mips::BGEC_MMR6:
5856 case Mips::BLTC:
case Mips::BLTC_MMR6:
5857 case Mips::BGEUC:
case Mips::BGEUC_MMR6:
5858 case Mips::BLTUC:
case Mips::BLTUC_MMR6:
5859 case Mips::BEQC:
case Mips::BEQC_MMR6:
5860 case Mips::BNEC:
case Mips::BNEC_MMR6:
5869 return Match_RequiresNoZeroRegister;
5872 return Match_RequiresNoZeroRegister;
5874 return Match_RequiresDifferentOperands;
5875 return Match_Success;
5878 "Operands must be immediates for dins!");
5881 if ((0 > (Pos +
Size)) || ((Pos +
Size) > 32))
5882 return Match_RequiresPosSizeRange0_32;
5883 return Match_Success;
5888 "Operands must be immediates for dinsm/dinsu!");
5891 if ((32 >= (Pos +
Size)) || ((Pos +
Size) > 64))
5892 return Match_RequiresPosSizeRange33_64;
5893 return Match_Success;
5897 "Operands must be immediates for DEXTM!");
5900 if ((1 > (Pos +
Size)) || ((Pos +
Size) > 63))
5901 return Match_RequiresPosSizeUImm6;
5902 return Match_Success;
5907 "Operands must be immediates for dextm/dextu!");
5910 if ((32 > (Pos +
Size)) || ((Pos +
Size) > 64))
5911 return Match_RequiresPosSizeRange33_64;
5912 return Match_Success;
5914 case Mips::CRC32B:
case Mips::CRC32CB:
5915 case Mips::CRC32H:
case Mips::CRC32CH:
5916 case Mips::CRC32W:
case Mips::CRC32CW:
5917 case Mips::CRC32D:
case Mips::CRC32CD:
5919 return Match_RequiresSameSrcAndDst;
5920 return Match_Success;
5923 uint64_t TSFlags = MII.get(Inst.
getOpcode()).TSFlags;
5926 return Match_NoFCCRegisterForCurrentISA;
5928 return Match_Success;
5936 if (ErrorLoc ==
SMLoc())
5943bool MipsAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
5946 uint64_t &ErrorInfo,
5947 bool MatchingInlineAsm) {
5949 unsigned MatchResult =
5950 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
5952 switch (MatchResult) {
5954 if (processInstruction(Inst, IDLoc, Out, STI))
5957 case Match_MissingFeature:
5958 Error(IDLoc,
"instruction requires a CPU feature not currently enabled");
5960 case Match_InvalidTiedOperand:
5961 Error(IDLoc,
"operand must match destination register");
5963 case Match_InvalidOperand: {
5964 SMLoc ErrorLoc = IDLoc;
5965 if (ErrorInfo != ~0ULL) {
5966 if (ErrorInfo >= Operands.
size())
5967 return Error(IDLoc,
"too few operands for instruction");
5969 ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5970 if (ErrorLoc == SMLoc())
5974 return Error(ErrorLoc,
"invalid operand for instruction");
5976 case Match_NonZeroOperandForSync:
5978 "s-type must be zero or unspecified for pre-MIPS32 ISAs");
5979 case Match_NonZeroOperandForMTCX:
5980 return Error(IDLoc,
"selector must be zero for pre-MIPS32 ISAs");
5981 case Match_MnemonicFail:
5982 return Error(IDLoc,
"invalid instruction");
5983 case Match_RequiresDifferentSrcAndDst:
5984 return Error(IDLoc,
"source and destination must be different");
5985 case Match_RequiresDifferentOperands:
5986 return Error(IDLoc,
"registers must be different");
5987 case Match_RequiresNoZeroRegister:
5988 return Error(IDLoc,
"invalid operand ($zero) for instruction");
5989 case Match_RequiresSameSrcAndDst:
5990 return Error(IDLoc,
"source and destination must match");
5991 case Match_NoFCCRegisterForCurrentISA:
5993 "non-zero fcc register doesn't exist in current ISA level");
5998 "expected 1-bit unsigned immediate");
6001 "expected 2-bit unsigned immediate");
6004 "expected immediate in range 1 .. 4");
6007 "expected 3-bit unsigned immediate");
6010 "expected 4-bit unsigned immediate");
6013 "expected 4-bit signed immediate");
6016 "expected 5-bit unsigned immediate");
6019 "expected 5-bit signed immediate");
6022 "expected immediate in range 1 .. 32");
6023 case Match_UImm5_32:
6025 "expected immediate in range 32 .. 63");
6026 case Match_UImm5_33:
6028 "expected immediate in range 33 .. 64");
6029 case Match_UImm5_0_Report_UImm6:
6033 "expected 6-bit unsigned immediate");
6034 case Match_UImm5_Lsl2:
6036 "expected both 7-bit unsigned immediate and multiple of 4");
6037 case Match_UImmRange2_64:
6039 "expected immediate in range 2 .. 64");
6042 "expected 6-bit unsigned immediate");
6043 case Match_UImm6_Lsl2:
6045 "expected both 8-bit unsigned immediate and multiple of 4");
6048 "expected 6-bit signed immediate");
6051 "expected 7-bit unsigned immediate");
6052 case Match_UImm7_N1:
6054 "expected immediate in range -1 .. 126");
6055 case Match_SImm7_Lsl2:
6057 "expected both 9-bit signed immediate and multiple of 4");
6060 "expected 8-bit unsigned immediate");
6061 case Match_UImm10_0:
6063 "expected 10-bit unsigned immediate");
6064 case Match_SImm10_0:
6066 "expected 10-bit signed immediate");
6067 case Match_SImm11_0:
6069 "expected 11-bit signed immediate");
6071 case Match_UImm16_Relaxed:
6072 case Match_UImm16_AltRelaxed:
6074 "expected 16-bit unsigned immediate");
6076 case Match_SImm16_Relaxed:
6078 "expected 16-bit signed immediate");
6079 case Match_SImm19_Lsl2:
6081 "expected both 19-bit signed immediate and multiple of 4");
6082 case Match_UImm20_0:
6084 "expected 20-bit unsigned immediate");
6085 case Match_UImm26_0:
6087 "expected 26-bit unsigned immediate");
6089 case Match_SImm32_Relaxed:
6091 "expected 32-bit signed immediate");
6092 case Match_UImm32_Coerced:
6094 "expected 32-bit immediate");
6095 case Match_MemSImm9:
6097 "expected memory with 9-bit signed offset");
6098 case Match_MemSImm10:
6100 "expected memory with 10-bit signed offset");
6101 case Match_MemSImm10Lsl1:
6103 "expected memory with 11-bit signed offset and multiple of 2");
6104 case Match_MemSImm10Lsl2:
6106 "expected memory with 12-bit signed offset and multiple of 4");
6107 case Match_MemSImm10Lsl3:
6109 "expected memory with 13-bit signed offset and multiple of 8");
6110 case Match_MemSImm11:
6112 "expected memory with 11-bit signed offset");
6113 case Match_MemSImm12:
6115 "expected memory with 12-bit signed offset");
6116 case Match_MemSImm16:
6118 "expected memory with 16-bit signed offset");
6119 case Match_MemSImmPtr:
6121 "expected memory with 32-bit signed offset");
6122 case Match_RequiresPosSizeRange0_32: {
6123 SMLoc ErrorStart = Operands[3]->getStartLoc();
6124 SMLoc ErrorEnd = Operands[4]->getEndLoc();
6125 return Error(ErrorStart,
"size plus position are not in the range 0 .. 32",
6126 SMRange(ErrorStart, ErrorEnd));
6128 case Match_RequiresPosSizeUImm6: {
6129 SMLoc ErrorStart = Operands[3]->getStartLoc();
6130 SMLoc ErrorEnd = Operands[4]->getEndLoc();
6131 return Error(ErrorStart,
"size plus position are not in the range 1 .. 63",
6132 SMRange(ErrorStart, ErrorEnd));
6134 case Match_RequiresPosSizeRange33_64: {
6135 SMLoc ErrorStart = Operands[3]->getStartLoc();
6136 SMLoc ErrorEnd = Operands[4]->getEndLoc();
6137 return Error(ErrorStart,
"size plus position are not in the range 33 .. 64",
6138 SMRange(ErrorStart, ErrorEnd));
6145void MipsAsmParser::warnIfRegIndexIsAT(MCRegister RegIndex, SMLoc Loc) {
6146 if (RegIndex && AssemblerOptions.
back()->getATRegIndex() == RegIndex)
6147 Warning(Loc,
"used $at (currently $" + Twine(RegIndex.
id()) +
6148 ") without \".set noat\"");
6151void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
6152 if (!AssemblerOptions.
back()->isMacro())
6153 Warning(Loc,
"macro instruction expanded into multiple instructions");
6156void MipsAsmParser::ConvertXWPOperands(MCInst &Inst,
6160 "Unexpected instruction!");
6161 ((MipsOperand &)*Operands[1]).addGPR32ZeroAsmRegOperands(Inst, 1);
6162 MCRegister NextReg =
nextReg(((MipsOperand &)*Operands[1]).getGPR32Reg());
6164 ((MipsOperand &)*Operands[2]).addMemOperands(Inst, 2);
6168MipsAsmParser::printWarningWithFixIt(
const Twine &Msg,
const Twine &FixMsg,
6169 SMRange
Range,
bool ShowColors) {
6175int MipsAsmParser::matchCPURegisterName(StringRef Name) {
6178 CC = StringSwitch<unsigned>(Name)
6180 .Cases({
"at",
"AT"}, 1)
6214 if (!(isABI_N32() || isABI_N64()))
6217 if (12 <= CC && CC <= 15) {
6219 AsmToken RegTok = getLexer().peekTok();
6222 StringRef FixedName = StringSwitch<StringRef>(Name)
6228 assert(FixedName !=
"" &&
"Register name is not one of t4-t7.");
6230 printWarningWithFixIt(
"register names $t4-$t7 are only available in O32.",
6231 "Did you mean $" + FixedName +
"?", RegRange);
6237 if (8 <= CC && CC <= 11)
6241 CC = StringSwitch<unsigned>(Name)
6253int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
6256 CC = StringSwitch<unsigned>(Name)
6257 .Case(
"hwr_cpunum", 0)
6258 .Case(
"hwr_synci_step", 1)
6260 .Case(
"hwr_ccres", 3)
6261 .Case(
"hwr_ulr", 29)
6267int MipsAsmParser::matchFPURegisterName(StringRef Name) {
6268 if (Name[0] ==
'f') {
6269 StringRef NumString =
Name.substr(1);
6280int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
6281 if (
Name.starts_with(
"fcc")) {
6282 StringRef NumString =
Name.substr(3);
6293int MipsAsmParser::matchACRegisterName(StringRef Name) {
6294 if (
Name.starts_with(
"ac")) {
6295 StringRef NumString =
Name.substr(2);
6306int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
6309 if (
Name.front() !=
'w' ||
Name.drop_front(1).getAsInteger(10, IntVal))
6318int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
6321 CC = StringSwitch<unsigned>(Name)
6324 .Case(
"msaaccess", 2)
6326 .Case(
"msamodify", 4)
6327 .Case(
"msarequest", 5)
6329 .Case(
"msaunmap", 7)
6335bool MipsAsmParser::canUseATReg() {
6336 return AssemblerOptions.
back()->getATRegIndex() != 0;
6339MCRegister MipsAsmParser::getATReg(SMLoc Loc) {
6340 unsigned ATIndex = AssemblerOptions.
back()->getATRegIndex();
6342 reportParseError(Loc,
6343 "pseudo-instruction requires $at, which is not available");
6347 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
6351MCRegister MipsAsmParser::getReg(
int RC,
int RegNo) {
6352 return getContext().getRegisterInfo()->getRegClass(RC).getRegister(RegNo);
6358const MCExpr *MipsAsmParser::parseRelocExpr() {
6359 auto getOp = [](StringRef
Op) {
6360 return StringSwitch<Mips::Specifier>(
Op)
6388 MCAsmParser &Parser = getParser();
6390 const MCExpr *Res =
nullptr;
6396 auto Op = getOp(Name);
6405 while (
Ops.size()) {
6413bool MipsAsmParser::parseOperand(
OperandVector &Operands, StringRef Mnemonic) {
6414 MCAsmParser &Parser = getParser();
6424 ParseStatus Res = MatchOperandParserImpl(Operands, Mnemonic,
true);
6435 switch (getLexer().getKind()) {
6445 if (!parseAnyRegister(Operands).isNoMatch())
6458 Operands.
push_back(MipsOperand::CreateImm(SymRef, S,
E, *
this));
6463 const MCExpr *Expr = parseRelocExpr();
6467 Operands.
push_back(MipsOperand::CreateImm(Expr, S,
E, *
this));
6474bool MipsAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
6476 return !tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess();
6479ParseStatus MipsAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
6482 ParseStatus Res = parseAnyRegister(Operands);
6485 MipsOperand &Operand =
static_cast<MipsOperand &
>(*Operands.
front());
6486 StartLoc = Operand.getStartLoc();
6487 EndLoc = Operand.getEndLoc();
6493 if (Operand.isGPRAsmReg()) {
6495 Reg = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
6505ParseStatus MipsAsmParser::parseMemOperand(
OperandVector &Operands) {
6506 MCAsmParser &Parser = getParser();
6508 const MCExpr *IdVal =
nullptr;
6510 bool isParenExpr =
false;
6521 IdVal = parseRelocExpr();
6527 const AsmToken &Tok = Parser.
getTok();
6529 MipsOperand &Mnemonic =
static_cast<MipsOperand &
>(*Operands[0]);
6530 if (Mnemonic.getToken() ==
"la" || Mnemonic.getToken() ==
"dla") {
6533 Operands.
push_back(MipsOperand::CreateImm(IdVal, S,
E, *
this));
6542 auto Base = MipsOperand::createGPRReg(
6543 0,
"0",
getContext().getRegisterInfo(), S,
E, *
this);
6545 MipsOperand::CreateMem(std::move(
Base), IdVal, S,
E, *
this));
6597 const MCExpr * NextExpr;
6598 if (getParser().parseExpression(NextExpr))
6606 Res = parseAnyRegister(Operands);
6621 std::unique_ptr<MipsOperand>
op(
6622 static_cast<MipsOperand *
>(Operands.
back().release()));
6629 if (IdVal->evaluateAsAbsolute(Imm))
6636 Operands.
push_back(MipsOperand::CreateMem(std::move(
op), IdVal, S,
E, *
this));
6640bool MipsAsmParser::searchSymbolAlias(
OperandVector &Operands) {
6641 MCAsmParser &Parser = getParser();
6650 const MCSymbolRefExpr *
Ref =
static_cast<const MCSymbolRefExpr *
>(Expr);
6651 StringRef DefSymbol =
Ref->getSymbol().getName();
6654 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.
substr(1), S);
6668 if (Entry != RegisterSets.
end()) {
6670 matchAnyRegisterWithoutDollar(Operands,
Entry->getValue(), S);
6681ParseStatus MipsAsmParser::matchAnyRegisterNameWithoutDollar(
6683 int Index = matchCPURegisterName(Identifier);
6685 Operands.
push_back(MipsOperand::createGPRReg(
6686 Index, Identifier,
getContext().getRegisterInfo(), S,
6687 getLexer().getLoc(), *
this));
6691 Index = matchHWRegsRegisterName(Identifier);
6693 Operands.
push_back(MipsOperand::createHWRegsReg(
6694 Index, Identifier,
getContext().getRegisterInfo(), S,
6695 getLexer().getLoc(), *
this));
6699 Index = matchFPURegisterName(Identifier);
6701 Operands.
push_back(MipsOperand::createFGRReg(
6702 Index, Identifier,
getContext().getRegisterInfo(), S,
6703 getLexer().getLoc(), *
this));
6707 Index = matchFCCRegisterName(Identifier);
6709 Operands.
push_back(MipsOperand::createFCCReg(
6710 Index, Identifier,
getContext().getRegisterInfo(), S,
6711 getLexer().getLoc(), *
this));
6715 Index = matchACRegisterName(Identifier);
6717 Operands.
push_back(MipsOperand::createACCReg(
6718 Index, Identifier,
getContext().getRegisterInfo(), S,
6719 getLexer().getLoc(), *
this));
6723 Index = matchMSA128RegisterName(Identifier);
6725 Operands.
push_back(MipsOperand::createMSA128Reg(
6726 Index, Identifier,
getContext().getRegisterInfo(), S,
6727 getLexer().getLoc(), *
this));
6731 Index = matchMSA128CtrlRegisterName(Identifier);
6733 Operands.
push_back(MipsOperand::createMSACtrlReg(
6734 Index, Identifier,
getContext().getRegisterInfo(), S,
6735 getLexer().getLoc(), *
this));
6743MipsAsmParser::matchAnyRegisterWithoutDollar(
OperandVector &Operands,
6744 const AsmToken &Token, SMLoc S) {
6748 return matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
6753 if (RegNum < 0 || RegNum > 31) {
6757 Error(getLexer().getLoc(),
"invalid register number");
6759 Operands.
push_back(MipsOperand::createNumericReg(
6771MipsAsmParser::matchAnyRegisterWithoutDollar(
OperandVector &Operands, SMLoc S) {
6772 auto Token = getLexer().peekTok(
false);
6773 return matchAnyRegisterWithoutDollar(Operands, Token, S);
6776ParseStatus MipsAsmParser::parseAnyRegister(
OperandVector &Operands) {
6777 MCAsmParser &Parser = getParser();
6780 auto Token = Parser.
getTok();
6782 SMLoc S = Token.
getLoc();
6787 if (searchSymbolAlias(Operands))
6795 ParseStatus Res = matchAnyRegisterWithoutDollar(Operands, S);
6803ParseStatus MipsAsmParser::parseJumpTarget(
OperandVector &Operands) {
6804 MCAsmParser &Parser = getParser();
6807 SMLoc S = getLexer().getLoc();
6810 ParseStatus Res = parseAnyRegister(Operands);
6815 const MCExpr *Expr =
nullptr;
6821 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *
this));
6825ParseStatus MipsAsmParser::parseInvNum(
OperandVector &Operands) {
6826 MCAsmParser &Parser = getParser();
6827 const MCExpr *IdVal;
6838 if (getParser().parseExpression(IdVal))
6845 Operands.
push_back(MipsOperand::CreateImm(
6850ParseStatus MipsAsmParser::parseRegisterList(
OperandVector &Operands) {
6851 MCAsmParser &Parser = getParser();
6855 bool RegRange =
false;
6862 while (parseAnyRegister(TmpOperands).isSuccess()) {
6863 SMLoc
E = getLexer().getLoc();
6864 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*TmpOperands.
back());
6865 Reg = isGP64bit() ? RegOpnd.getGPR64Reg() : RegOpnd.getGPR32Reg();
6869 if ((isGP64bit() &&
Reg == Mips::RA_64) ||
6870 (!isGP64bit() &&
Reg == Mips::RA)) {
6873 MCRegister TmpReg = PrevReg + 1;
6874 while (TmpReg <=
Reg) {
6875 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
6876 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
6878 return Error(
E,
"invalid register operand");
6882 TmpReg = TmpReg.
id() + 1;
6889 ((isGP64bit() && (
Reg != Mips::S0_64) && (
Reg != Mips::RA_64)) ||
6890 (!isGP64bit() && (
Reg != Mips::S0) && (
Reg != Mips::RA))))
6891 return Error(
E,
"$16 or $31 expected");
6892 if (!(((
Reg == Mips::FP ||
Reg == Mips::RA ||
6893 (
Reg >= Mips::S0 &&
Reg <= Mips::S7)) &&
6895 ((
Reg == Mips::FP_64 ||
Reg == Mips::RA_64 ||
6896 (
Reg >= Mips::S0_64 &&
Reg <= Mips::S7_64)) &&
6898 return Error(
E,
"invalid register operand");
6899 if (PrevReg.
isValid() && (
Reg != PrevReg + 1) &&
6900 ((
Reg != Mips::FP &&
Reg != Mips::RA && !isGP64bit()) ||
6901 (
Reg != Mips::FP_64 &&
Reg != Mips::RA_64 && isGP64bit())))
6902 return Error(
E,
"consecutive register numbers expected");
6912 return Error(
E,
"',' or '-' expected");
6922 Operands.
push_back(MipsOperand::CreateRegList(Regs, S,
E, *
this));
6923 parseMemOperand(Operands);
6932bool MipsAsmParser::parseParenSuffix(StringRef Name,
OperandVector &Operands) {
6933 MCAsmParser &Parser = getParser();
6936 MipsOperand::CreateToken(
"(", getLexer().getLoc(), *
this));
6938 if (parseOperand(Operands, Name)) {
6939 SMLoc Loc = getLexer().getLoc();
6940 return Error(Loc,
"unexpected token in argument list");
6943 SMLoc Loc = getLexer().getLoc();
6944 return Error(Loc,
"unexpected token, expected ')'");
6947 MipsOperand::CreateToken(
")", getLexer().getLoc(), *
this));
6959bool MipsAsmParser::parseBracketSuffix(StringRef Name,
6961 MCAsmParser &Parser = getParser();
6964 MipsOperand::CreateToken(
"[", getLexer().getLoc(), *
this));
6966 if (parseOperand(Operands, Name)) {
6967 SMLoc Loc = getLexer().getLoc();
6968 return Error(Loc,
"unexpected token in argument list");
6971 SMLoc Loc = getLexer().getLoc();
6972 return Error(Loc,
"unexpected token, expected ']'");
6975 MipsOperand::CreateToken(
"]", getLexer().getLoc(), *
this));
6982 unsigned VariantID = 0);
6997bool MipsAsmParser::parseInstruction(ParseInstructionInfo &
Info, StringRef Name,
6999 MCAsmParser &Parser = getParser();
7003 getTargetStreamer().forbidModuleDirective();
7006 if (!mnemonicIsValid(Name, 0)) {
7007 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
7009 return Error(NameLoc,
"unknown instruction" + Suggestion);
7012 Operands.
push_back(MipsOperand::CreateToken(Name, NameLoc, *
this));
7017 if (parseOperand(Operands, Name)) {
7018 SMLoc Loc = getLexer().getLoc();
7019 return Error(Loc,
"unexpected token in argument list");
7021 if (getLexer().is(
AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
7028 if (parseOperand(Operands, Name)) {
7029 SMLoc Loc = getLexer().getLoc();
7030 return Error(Loc,
"unexpected token in argument list");
7034 if (parseBracketSuffix(Name, Operands))
7037 parseParenSuffix(Name, Operands))
7042 SMLoc Loc = getLexer().getLoc();
7043 return Error(Loc,
"unexpected token in argument list");
7051bool MipsAsmParser::reportParseError(
const Twine &ErrorMsg) {
7052 SMLoc Loc = getLexer().getLoc();
7053 return Error(Loc, ErrorMsg);
7056bool MipsAsmParser::reportParseError(SMLoc Loc,
const Twine &ErrorMsg) {
7057 return Error(Loc, ErrorMsg);
7060bool MipsAsmParser::parseSetNoAtDirective() {
7061 MCAsmParser &Parser = getParser();
7065 AssemblerOptions.
back()->setATRegIndex(0);
7071 reportParseError(
"unexpected token, expected end of statement");
7075 getTargetStreamer().emitDirectiveSetNoAt();
7080bool MipsAsmParser::parseSetAtDirective() {
7083 MCAsmParser &Parser = getParser();
7088 AssemblerOptions.
back()->setATRegIndex(1);
7090 getTargetStreamer().emitDirectiveSetAt();
7096 reportParseError(
"unexpected token, expected equals sign");
7103 reportParseError(
"no register specified");
7106 reportParseError(
"unexpected token, expected dollar sign '$'");
7116 AtRegNo = matchCPURegisterName(
Reg.getIdentifier());
7118 AtRegNo =
Reg.getIntVal();
7120 reportParseError(
"unexpected token, expected identifier or integer");
7125 if (!AssemblerOptions.
back()->setATRegIndex(AtRegNo)) {
7126 reportParseError(
"invalid register");
7133 reportParseError(
"unexpected token, expected end of statement");
7137 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
7143bool MipsAsmParser::parseSetReorderDirective() {
7144 MCAsmParser &Parser = getParser();
7148 reportParseError(
"unexpected token, expected end of statement");
7151 AssemblerOptions.
back()->setReorder();
7152 getTargetStreamer().emitDirectiveSetReorder();
7157bool MipsAsmParser::parseSetNoReorderDirective() {
7158 MCAsmParser &Parser = getParser();
7162 reportParseError(
"unexpected token, expected end of statement");
7165 AssemblerOptions.
back()->setNoReorder();
7166 getTargetStreamer().emitDirectiveSetNoReorder();
7171bool MipsAsmParser::parseSetMacroDirective() {
7172 MCAsmParser &Parser = getParser();
7176 reportParseError(
"unexpected token, expected end of statement");
7179 AssemblerOptions.
back()->setMacro();
7180 getTargetStreamer().emitDirectiveSetMacro();
7185bool MipsAsmParser::parseSetNoMacroDirective() {
7186 MCAsmParser &Parser = getParser();
7190 reportParseError(
"unexpected token, expected end of statement");
7193 if (AssemblerOptions.
back()->isReorder()) {
7194 reportParseError(
"`noreorder' must be set before `nomacro'");
7197 AssemblerOptions.
back()->setNoMacro();
7198 getTargetStreamer().emitDirectiveSetNoMacro();
7203bool MipsAsmParser::parseSetMsaDirective() {
7204 MCAsmParser &Parser = getParser();
7209 return reportParseError(
"unexpected token, expected end of statement");
7211 setFeatureBits(Mips::FeatureMSA,
"msa");
7212 getTargetStreamer().emitDirectiveSetMsa();
7216bool MipsAsmParser::parseSetNoMsaDirective() {
7217 MCAsmParser &Parser = getParser();
7222 return reportParseError(
"unexpected token, expected end of statement");
7224 clearFeatureBits(Mips::FeatureMSA,
"msa");
7225 getTargetStreamer().emitDirectiveSetNoMsa();
7229bool MipsAsmParser::parseSetNoDspDirective() {
7230 MCAsmParser &Parser = getParser();
7235 reportParseError(
"unexpected token, expected end of statement");
7239 clearFeatureBits(Mips::FeatureDSP,
"dsp");
7240 getTargetStreamer().emitDirectiveSetNoDsp();
7244bool MipsAsmParser::parseSetNoMips3DDirective() {
7245 MCAsmParser &Parser = getParser();
7250 reportParseError(
"unexpected token, expected end of statement");
7254 clearFeatureBits(Mips::FeatureMips3D,
"mips3d");
7255 getTargetStreamer().emitDirectiveSetNoMips3D();
7259bool MipsAsmParser::parseSetMips16Directive() {
7260 MCAsmParser &Parser = getParser();
7265 reportParseError(
"unexpected token, expected end of statement");
7269 setFeatureBits(Mips::FeatureMips16,
"mips16");
7270 getTargetStreamer().emitDirectiveSetMips16();
7275bool MipsAsmParser::parseSetNoMips16Directive() {
7276 MCAsmParser &Parser = getParser();
7281 reportParseError(
"unexpected token, expected end of statement");
7285 clearFeatureBits(Mips::FeatureMips16,
"mips16");
7286 getTargetStreamer().emitDirectiveSetNoMips16();
7291bool MipsAsmParser::parseSetFpDirective() {
7292 MCAsmParser &Parser = getParser();
7298 AsmToken Tok = Parser.
getTok();
7300 reportParseError(
"unexpected token, expected equals sign '='");
7306 if (!parseFpABIValue(FpAbiVal,
".set"))
7310 reportParseError(
"unexpected token, expected end of statement");
7313 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
7318bool MipsAsmParser::parseSetOddSPRegDirective() {
7319 MCAsmParser &Parser = getParser();
7323 reportParseError(
"unexpected token, expected end of statement");
7327 clearFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
7328 getTargetStreamer().emitDirectiveSetOddSPReg();
7332bool MipsAsmParser::parseSetNoOddSPRegDirective() {
7333 MCAsmParser &Parser = getParser();
7337 reportParseError(
"unexpected token, expected end of statement");
7341 setFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
7342 getTargetStreamer().emitDirectiveSetNoOddSPReg();
7346bool MipsAsmParser::parseSetMtDirective() {
7347 MCAsmParser &Parser = getParser();
7352 reportParseError(
"unexpected token, expected end of statement");
7356 setFeatureBits(Mips::FeatureMT,
"mt");
7357 getTargetStreamer().emitDirectiveSetMt();
7362bool MipsAsmParser::parseSetNoMtDirective() {
7363 MCAsmParser &Parser = getParser();
7368 reportParseError(
"unexpected token, expected end of statement");
7372 clearFeatureBits(Mips::FeatureMT,
"mt");
7374 getTargetStreamer().emitDirectiveSetNoMt();
7379bool MipsAsmParser::parseSetNoCRCDirective() {
7380 MCAsmParser &Parser = getParser();
7385 reportParseError(
"unexpected token, expected end of statement");
7389 clearFeatureBits(Mips::FeatureCRC,
"crc");
7391 getTargetStreamer().emitDirectiveSetNoCRC();
7396bool MipsAsmParser::parseSetNoVirtDirective() {
7397 MCAsmParser &Parser = getParser();
7402 reportParseError(
"unexpected token, expected end of statement");
7406 clearFeatureBits(Mips::FeatureVirt,
"virt");
7408 getTargetStreamer().emitDirectiveSetNoVirt();
7413bool MipsAsmParser::parseSetNoGINVDirective() {
7414 MCAsmParser &Parser = getParser();
7419 reportParseError(
"unexpected token, expected end of statement");
7423 clearFeatureBits(Mips::FeatureGINV,
"ginv");
7425 getTargetStreamer().emitDirectiveSetNoGINV();
7430bool MipsAsmParser::parseSetPopDirective() {
7431 MCAsmParser &Parser = getParser();
7432 SMLoc Loc = getLexer().getLoc();
7436 return reportParseError(
"unexpected token, expected end of statement");
7440 if (AssemblerOptions.
size() == 2)
7441 return reportParseError(Loc,
".set pop with no .set push");
7443 MCSubtargetInfo &STI = copySTI();
7445 setAvailableFeatures(
7446 ComputeAvailableFeatures(AssemblerOptions.
back()->getFeatures()));
7449 getTargetStreamer().emitDirectiveSetPop();
7453bool MipsAsmParser::parseSetPushDirective() {
7454 MCAsmParser &Parser = getParser();
7457 return reportParseError(
"unexpected token, expected end of statement");
7461 std::make_unique<MipsAssemblerOptions>(AssemblerOptions.
back().get()));
7463 getTargetStreamer().emitDirectiveSetPush();
7467bool MipsAsmParser::parseSetSoftFloatDirective() {
7468 MCAsmParser &Parser = getParser();
7471 return reportParseError(
"unexpected token, expected end of statement");
7473 setFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
7474 getTargetStreamer().emitDirectiveSetSoftFloat();
7478bool MipsAsmParser::parseSetHardFloatDirective() {
7479 MCAsmParser &Parser = getParser();
7482 return reportParseError(
"unexpected token, expected end of statement");
7484 clearFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
7485 getTargetStreamer().emitDirectiveSetHardFloat();
7489bool MipsAsmParser::parseSetAssignment() {
7491 MCAsmParser &Parser = getParser();
7494 return reportParseError(
"expected identifier after .set");
7497 return reportParseError(
"unexpected token, expected comma");
7512 const MCExpr *
Value;
7514 Parser, Sym,
Value))
7516 getStreamer().emitAssignment(Sym,
Value);
7521bool MipsAsmParser::parseSetMips0Directive() {
7522 MCAsmParser &Parser = getParser();
7525 return reportParseError(
"unexpected token, expected end of statement");
7528 MCSubtargetInfo &STI = copySTI();
7529 setAvailableFeatures(
7530 ComputeAvailableFeatures(AssemblerOptions.
front()->getFeatures()));
7532 AssemblerOptions.
back()->setFeatures(AssemblerOptions.
front()->getFeatures());
7534 getTargetStreamer().emitDirectiveSetMips0();
7538bool MipsAsmParser::parseSetArchDirective() {
7539 MCAsmParser &Parser = getParser();
7542 return reportParseError(
"unexpected token, expected equals sign");
7545 StringRef Arch = getParser().parseStringToEndOfStatement().trim();
7547 return reportParseError(
"expected arch identifier");
7549 StringRef ArchFeatureName =
7550 StringSwitch<StringRef>(Arch)
7551 .Case(
"mips1",
"mips1")
7552 .Case(
"mips2",
"mips2")
7553 .Case(
"mips3",
"mips3")
7554 .Case(
"mips4",
"mips4")
7555 .Case(
"mips5",
"mips5")
7556 .Case(
"mips32",
"mips32")
7557 .Case(
"mips32r2",
"mips32r2")
7558 .Case(
"mips32r3",
"mips32r3")
7559 .Case(
"mips32r5",
"mips32r5")
7560 .Case(
"mips32r6",
"mips32r6")
7561 .Case(
"mips64",
"mips64")
7562 .Case(
"mips64r2",
"mips64r2")
7563 .Case(
"mips64r3",
"mips64r3")
7564 .Case(
"mips64r5",
"mips64r5")
7565 .Case(
"mips64r6",
"mips64r6")
7566 .Case(
"octeon",
"cnmips")
7567 .Case(
"octeon+",
"cnmipsp")
7568 .Case(
"r4000",
"mips3")
7571 if (ArchFeatureName.
empty())
7572 return reportParseError(
"unsupported architecture");
7574 if (ArchFeatureName ==
"mips64r6" && inMicroMipsMode())
7575 return reportParseError(
"mips64r6 does not support microMIPS");
7577 selectArch(ArchFeatureName);
7578 getTargetStreamer().emitDirectiveSetArch(Arch);
7582bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
7583 MCAsmParser &Parser = getParser();
7586 return reportParseError(
"unexpected token, expected end of statement");
7591 case Mips::FeatureMips3D:
7592 setFeatureBits(Mips::FeatureMips3D,
"mips3d");
7593 getTargetStreamer().emitDirectiveSetMips3D();
7595 case Mips::FeatureDSP:
7596 setFeatureBits(Mips::FeatureDSP,
"dsp");
7597 getTargetStreamer().emitDirectiveSetDsp();
7599 case Mips::FeatureDSPR2:
7600 setFeatureBits(Mips::FeatureDSPR2,
"dspr2");
7601 getTargetStreamer().emitDirectiveSetDspr2();
7603 case Mips::FeatureMicroMips:
7604 setFeatureBits(Mips::FeatureMicroMips,
"micromips");
7605 getTargetStreamer().emitDirectiveSetMicroMips();
7607 case Mips::FeatureMips1:
7608 selectArch(
"mips1");
7609 getTargetStreamer().emitDirectiveSetMips1();
7611 case Mips::FeatureMips2:
7612 selectArch(
"mips2");
7613 getTargetStreamer().emitDirectiveSetMips2();
7615 case Mips::FeatureMips3:
7616 selectArch(
"mips3");
7617 getTargetStreamer().emitDirectiveSetMips3();
7619 case Mips::FeatureMips4:
7620 selectArch(
"mips4");
7621 getTargetStreamer().emitDirectiveSetMips4();
7623 case Mips::FeatureMips5:
7624 selectArch(
"mips5");
7625 getTargetStreamer().emitDirectiveSetMips5();
7627 case Mips::FeatureMips32:
7628 selectArch(
"mips32");
7629 getTargetStreamer().emitDirectiveSetMips32();
7631 case Mips::FeatureMips32r2:
7632 selectArch(
"mips32r2");
7633 getTargetStreamer().emitDirectiveSetMips32R2();
7635 case Mips::FeatureMips32r3:
7636 selectArch(
"mips32r3");
7637 getTargetStreamer().emitDirectiveSetMips32R3();
7639 case Mips::FeatureMips32r5:
7640 selectArch(
"mips32r5");
7641 getTargetStreamer().emitDirectiveSetMips32R5();
7643 case Mips::FeatureMips32r6:
7644 selectArch(
"mips32r6");
7645 getTargetStreamer().emitDirectiveSetMips32R6();
7647 case Mips::FeatureMips64:
7648 selectArch(
"mips64");
7649 getTargetStreamer().emitDirectiveSetMips64();
7651 case Mips::FeatureMips64r2:
7652 selectArch(
"mips64r2");
7653 getTargetStreamer().emitDirectiveSetMips64R2();
7655 case Mips::FeatureMips64r3:
7656 selectArch(
"mips64r3");
7657 getTargetStreamer().emitDirectiveSetMips64R3();
7659 case Mips::FeatureMips64r5:
7660 selectArch(
"mips64r5");
7661 getTargetStreamer().emitDirectiveSetMips64R5();
7663 case Mips::FeatureMips64r6:
7664 selectArch(
"mips64r6");
7665 getTargetStreamer().emitDirectiveSetMips64R6();
7667 case Mips::FeatureCRC:
7668 setFeatureBits(Mips::FeatureCRC,
"crc");
7669 getTargetStreamer().emitDirectiveSetCRC();
7671 case Mips::FeatureVirt:
7672 setFeatureBits(Mips::FeatureVirt,
"virt");
7673 getTargetStreamer().emitDirectiveSetVirt();
7675 case Mips::FeatureGINV:
7676 setFeatureBits(Mips::FeatureGINV,
"ginv");
7677 getTargetStreamer().emitDirectiveSetGINV();
7683bool MipsAsmParser::eatComma(StringRef ErrorStr) {
7684 MCAsmParser &Parser = getParser();
7686 SMLoc Loc = getLexer().getLoc();
7687 return Error(Loc, ErrorStr);
7698bool MipsAsmParser::isPicAndNotNxxAbi() {
7699 return inPicMode() && !(isABI_N32() || isABI_N64());
7702bool MipsAsmParser::parseDirectiveCpAdd(SMLoc Loc) {
7704 ParseStatus Res = parseAnyRegister(
Reg);
7706 reportParseError(
"expected register");
7710 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7711 if (!RegOpnd.isGPRAsmReg()) {
7712 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7718 reportParseError(
"unexpected token, expected end of statement");
7723 getTargetStreamer().emitDirectiveCpAdd(RegOpnd.getGPR32Reg());
7727bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
7728 if (AssemblerOptions.
back()->isReorder())
7729 Warning(Loc,
".cpload should be inside a noreorder section");
7731 if (inMips16Mode()) {
7732 reportParseError(
".cpload is not supported in Mips16 mode");
7737 ParseStatus Res = parseAnyRegister(
Reg);
7739 reportParseError(
"expected register containing function address");
7743 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7744 if (!RegOpnd.isGPRAsmReg()) {
7745 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7751 reportParseError(
"unexpected token, expected end of statement");
7755 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
7759bool MipsAsmParser::parseDirectiveCpLocal(SMLoc Loc) {
7760 if (!isABI_N32() && !isABI_N64()) {
7761 reportParseError(
".cplocal is allowed only in N32 or N64 mode");
7766 ParseStatus Res = parseAnyRegister(
Reg);
7768 reportParseError(
"expected register containing global pointer");
7772 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7773 if (!RegOpnd.isGPRAsmReg()) {
7774 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7780 reportParseError(
"unexpected token, expected end of statement");
7785 MCRegister NewReg = RegOpnd.getGPR32Reg();
7789 getTargetStreamer().emitDirectiveCpLocal(NewReg);
7793bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
7794 MCAsmParser &Parser = getParser();
7799 if (inMips16Mode()) {
7800 reportParseError(
".cprestore is not supported in Mips16 mode");
7805 const MCExpr *StackOffset;
7806 int64_t StackOffsetVal;
7808 reportParseError(
"expected stack offset value");
7812 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
7813 reportParseError(
"stack offset is not an absolute expression");
7817 if (StackOffsetVal < 0) {
7818 Warning(Loc,
".cprestore with negative stack offset has no effect");
7819 IsCpRestoreSet =
false;
7821 IsCpRestoreSet =
true;
7822 CpRestoreOffset = StackOffsetVal;
7827 reportParseError(
"unexpected token, expected end of statement");
7831 if (!getTargetStreamer().emitDirectiveCpRestore(
7832 CpRestoreOffset, [&]() {
return getATReg(Loc); }, Loc, STI))
7838bool MipsAsmParser::parseDirectiveCPSetup() {
7839 MCAsmParser &Parser = getParser();
7841 bool SaveIsReg =
true;
7844 ParseStatus Res = parseAnyRegister(TmpReg);
7846 reportParseError(
"expected register containing function address");
7850 MipsOperand &FuncRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7851 if (!FuncRegOpnd.isGPRAsmReg()) {
7852 reportParseError(FuncRegOpnd.getStartLoc(),
"invalid register");
7856 MCRegister FuncReg = FuncRegOpnd.getGPR32Reg();
7859 if (!eatComma(
"unexpected token, expected comma"))
7862 Res = parseAnyRegister(TmpReg);
7864 const MCExpr *OffsetExpr;
7866 SMLoc ExprLoc = getLexer().
getLoc();
7869 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
7870 reportParseError(ExprLoc,
"expected save register or stack offset");
7877 MipsOperand &SaveOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7878 if (!SaveOpnd.isGPRAsmReg()) {
7879 reportParseError(SaveOpnd.getStartLoc(),
"invalid register");
7882 Save = SaveOpnd.getGPR32Reg().id();
7885 if (!eatComma(
"unexpected token, expected comma"))
7890 reportParseError(
"expected expression");
7895 reportParseError(
"expected symbol");
7898 const MCSymbolRefExpr *
Ref =
static_cast<const MCSymbolRefExpr *
>(Expr);
7900 CpSaveLocation = Save;
7901 CpSaveLocationIsRegister = SaveIsReg;
7903 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save,
Ref->getSymbol(),
7908bool MipsAsmParser::parseDirectiveCPReturn() {
7909 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
7910 CpSaveLocationIsRegister);
7914bool MipsAsmParser::parseDirectiveNaN() {
7915 MCAsmParser &Parser = getParser();
7917 const AsmToken &Tok = Parser.
getTok();
7921 getTargetStreamer().emitDirectiveNaN2008();
7923 }
else if (Tok.
getString() ==
"legacy") {
7925 getTargetStreamer().emitDirectiveNaNLegacy();
7931 reportParseError(
"invalid option in .nan directive");
7935bool MipsAsmParser::parseDirectiveSet() {
7936 const AsmToken &Tok = getParser().getTok();
7938 SMLoc Loc = Tok.
getLoc();
7940 if (IdVal ==
"noat")
7941 return parseSetNoAtDirective();
7943 return parseSetAtDirective();
7944 if (IdVal ==
"arch")
7945 return parseSetArchDirective();
7946 if (IdVal ==
"bopt") {
7947 Warning(Loc,
"'bopt' feature is unsupported");
7951 if (IdVal ==
"nobopt") {
7957 return parseSetFpDirective();
7958 if (IdVal ==
"oddspreg")
7959 return parseSetOddSPRegDirective();
7960 if (IdVal ==
"nooddspreg")
7961 return parseSetNoOddSPRegDirective();
7963 return parseSetPopDirective();
7964 if (IdVal ==
"push")
7965 return parseSetPushDirective();
7966 if (IdVal ==
"reorder")
7967 return parseSetReorderDirective();
7968 if (IdVal ==
"noreorder")
7969 return parseSetNoReorderDirective();
7970 if (IdVal ==
"macro")
7971 return parseSetMacroDirective();
7972 if (IdVal ==
"nomacro")
7973 return parseSetNoMacroDirective();
7974 if (IdVal ==
"mips16")
7975 return parseSetMips16Directive();
7976 if (IdVal ==
"nomips16")
7977 return parseSetNoMips16Directive();
7978 if (IdVal ==
"nomicromips") {
7979 clearFeatureBits(Mips::FeatureMicroMips,
"micromips");
7980 getTargetStreamer().emitDirectiveSetNoMicroMips();
7981 getParser().eatToEndOfStatement();
7984 if (IdVal ==
"micromips") {
7985 if (hasMips64r6()) {
7986 Error(Loc,
".set micromips directive is not supported with MIPS64R6");
7989 return parseSetFeature(Mips::FeatureMicroMips);
7991 if (IdVal ==
"mips0")
7992 return parseSetMips0Directive();
7993 if (IdVal ==
"mips1")
7994 return parseSetFeature(Mips::FeatureMips1);
7995 if (IdVal ==
"mips2")
7996 return parseSetFeature(Mips::FeatureMips2);
7997 if (IdVal ==
"mips3")
7998 return parseSetFeature(Mips::FeatureMips3);
7999 if (IdVal ==
"mips4")
8000 return parseSetFeature(Mips::FeatureMips4);
8001 if (IdVal ==
"mips5")
8002 return parseSetFeature(Mips::FeatureMips5);
8003 if (IdVal ==
"mips32")
8004 return parseSetFeature(Mips::FeatureMips32);
8005 if (IdVal ==
"mips32r2")
8006 return parseSetFeature(Mips::FeatureMips32r2);
8007 if (IdVal ==
"mips32r3")
8008 return parseSetFeature(Mips::FeatureMips32r3);
8009 if (IdVal ==
"mips32r5")
8010 return parseSetFeature(Mips::FeatureMips32r5);
8011 if (IdVal ==
"mips32r6")
8012 return parseSetFeature(Mips::FeatureMips32r6);
8013 if (IdVal ==
"mips64")
8014 return parseSetFeature(Mips::FeatureMips64);
8015 if (IdVal ==
"mips64r2")
8016 return parseSetFeature(Mips::FeatureMips64r2);
8017 if (IdVal ==
"mips64r3")
8018 return parseSetFeature(Mips::FeatureMips64r3);
8019 if (IdVal ==
"mips64r5")
8020 return parseSetFeature(Mips::FeatureMips64r5);
8021 if (IdVal ==
"mips64r6") {
8022 if (inMicroMipsMode()) {
8023 Error(Loc,
"MIPS64R6 is not supported with microMIPS");
8026 return parseSetFeature(Mips::FeatureMips64r6);
8029 return parseSetFeature(Mips::FeatureDSP);
8030 if (IdVal ==
"dspr2")
8031 return parseSetFeature(Mips::FeatureDSPR2);
8032 if (IdVal ==
"nodsp")
8033 return parseSetNoDspDirective();
8034 if (IdVal ==
"mips3d")
8035 return parseSetFeature(Mips::FeatureMips3D);
8036 if (IdVal ==
"nomips3d")
8037 return parseSetNoMips3DDirective();
8039 return parseSetMsaDirective();
8040 if (IdVal ==
"nomsa")
8041 return parseSetNoMsaDirective();
8043 return parseSetMtDirective();
8044 if (IdVal ==
"nomt")
8045 return parseSetNoMtDirective();
8046 if (IdVal ==
"softfloat")
8047 return parseSetSoftFloatDirective();
8048 if (IdVal ==
"hardfloat")
8049 return parseSetHardFloatDirective();
8051 return parseSetFeature(Mips::FeatureCRC);
8052 if (IdVal ==
"nocrc")
8053 return parseSetNoCRCDirective();
8054 if (IdVal ==
"virt")
8055 return parseSetFeature(Mips::FeatureVirt);
8056 if (IdVal ==
"novirt")
8057 return parseSetNoVirtDirective();
8058 if (IdVal ==
"ginv")
8059 return parseSetFeature(Mips::FeatureGINV);
8060 if (IdVal ==
"noginv")
8061 return parseSetNoGINVDirective();
8064 return parseSetAssignment();
8069bool MipsAsmParser::parseDirectiveGpWord() {
8070 const MCExpr *
Value;
8071 if (getParser().parseExpression(
Value))
8073 getTargetStreamer().emitGPRel32Value(
Value);
8079bool MipsAsmParser::parseDirectiveGpDWord() {
8080 const MCExpr *
Value;
8081 if (getParser().parseExpression(
Value))
8083 getTargetStreamer().emitGPRel64Value(
Value);
8089bool MipsAsmParser::parseDirectiveDtpRelWord() {
8090 const MCExpr *
Value;
8091 if (getParser().parseExpression(
Value))
8093 getTargetStreamer().emitDTPRel32Value(
Value);
8099bool MipsAsmParser::parseDirectiveDtpRelDWord() {
8100 const MCExpr *
Value;
8101 if (getParser().parseExpression(
Value))
8103 getTargetStreamer().emitDTPRel64Value(
Value);
8109bool MipsAsmParser::parseDirectiveTpRelWord() {
8110 const MCExpr *
Value;
8111 if (getParser().parseExpression(
Value))
8113 getTargetStreamer().emitTPRel32Value(
Value);
8119bool MipsAsmParser::parseDirectiveTpRelDWord() {
8120 const MCExpr *
Value;
8121 if (getParser().parseExpression(
Value))
8123 getTargetStreamer().emitTPRel64Value(
Value);
8127bool MipsAsmParser::parseDirectiveOption() {
8128 MCAsmParser &Parser = getParser();
8130 AsmToken Tok = Parser.
getTok();
8134 "unexpected token, expected identifier");
8139 if (Option ==
"pic0") {
8141 IsPicEnabled =
false;
8143 getTargetStreamer().emitDirectiveOptionPic0();
8147 "unexpected token, expected end of statement");
8152 if (Option ==
"pic2") {
8154 IsPicEnabled =
true;
8156 getTargetStreamer().emitDirectiveOptionPic2();
8160 "unexpected token, expected end of statement");
8167 "unknown option, expected 'pic0' or 'pic2'");
8174bool MipsAsmParser::parseInsnDirective() {
8177 reportParseError(
"unexpected token, expected end of statement");
8183 getTargetStreamer().emitDirectiveInsn();
8191bool MipsAsmParser::parseRSectionDirective(StringRef Section) {
8194 reportParseError(
"unexpected token, expected end of statement");
8198 MCSection *ELFSection =
getContext().getELFSection(
8200 getParser().getStreamer().switchSection(ELFSection);
8209bool MipsAsmParser::parseSSectionDirective(StringRef Section,
unsigned Type) {
8212 reportParseError(
"unexpected token, expected end of statement");
8216 MCSection *ELFSection =
getContext().getELFSection(
8218 getParser().getStreamer().switchSection(ELFSection);
8237bool MipsAsmParser::parseDirectiveModule() {
8238 MCAsmParser &Parser = getParser();
8239 AsmLexer &Lexer = getLexer();
8242 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
8244 reportParseError(
".module directive must appear before any code");
8250 reportParseError(
"expected .module option identifier");
8254 if (Option ==
"oddspreg") {
8255 clearModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
8259 getTargetStreamer().updateABIInfo(*
this);
8264 getTargetStreamer().emitDirectiveModuleOddSPReg();
8268 reportParseError(
"unexpected token, expected end of statement");
8273 }
else if (Option ==
"nooddspreg") {
8275 return Error(L,
"'.module nooddspreg' requires the O32 ABI");
8278 setModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
8282 getTargetStreamer().updateABIInfo(*
this);
8287 getTargetStreamer().emitDirectiveModuleOddSPReg();
8291 reportParseError(
"unexpected token, expected end of statement");
8296 }
else if (Option ==
"fp") {
8297 return parseDirectiveModuleFP();
8298 }
else if (Option ==
"softfloat") {
8299 setModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
8303 getTargetStreamer().updateABIInfo(*
this);
8308 getTargetStreamer().emitDirectiveModuleSoftFloat();
8312 reportParseError(
"unexpected token, expected end of statement");
8317 }
else if (Option ==
"hardfloat") {
8318 clearModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
8322 getTargetStreamer().updateABIInfo(*
this);
8327 getTargetStreamer().emitDirectiveModuleHardFloat();
8331 reportParseError(
"unexpected token, expected end of statement");
8336 }
else if (Option ==
"mt") {
8337 setModuleFeatureBits(Mips::FeatureMT,
"mt");
8341 getTargetStreamer().updateABIInfo(*
this);
8346 getTargetStreamer().emitDirectiveModuleMT();
8350 reportParseError(
"unexpected token, expected end of statement");
8355 }
else if (Option ==
"crc") {
8356 setModuleFeatureBits(Mips::FeatureCRC,
"crc");
8360 getTargetStreamer().updateABIInfo(*
this);
8365 getTargetStreamer().emitDirectiveModuleCRC();
8369 reportParseError(
"unexpected token, expected end of statement");
8374 }
else if (Option ==
"nocrc") {
8375 clearModuleFeatureBits(Mips::FeatureCRC,
"crc");
8379 getTargetStreamer().updateABIInfo(*
this);
8384 getTargetStreamer().emitDirectiveModuleNoCRC();
8388 reportParseError(
"unexpected token, expected end of statement");
8393 }
else if (Option ==
"virt") {
8394 setModuleFeatureBits(Mips::FeatureVirt,
"virt");
8398 getTargetStreamer().updateABIInfo(*
this);
8403 getTargetStreamer().emitDirectiveModuleVirt();
8407 reportParseError(
"unexpected token, expected end of statement");
8412 }
else if (Option ==
"novirt") {
8413 clearModuleFeatureBits(Mips::FeatureVirt,
"virt");
8417 getTargetStreamer().updateABIInfo(*
this);
8422 getTargetStreamer().emitDirectiveModuleNoVirt();
8426 reportParseError(
"unexpected token, expected end of statement");
8431 }
else if (Option ==
"ginv") {
8432 setModuleFeatureBits(Mips::FeatureGINV,
"ginv");
8436 getTargetStreamer().updateABIInfo(*
this);
8441 getTargetStreamer().emitDirectiveModuleGINV();
8445 reportParseError(
"unexpected token, expected end of statement");
8450 }
else if (Option ==
"noginv") {
8451 clearModuleFeatureBits(Mips::FeatureGINV,
"ginv");
8455 getTargetStreamer().updateABIInfo(*
this);
8460 getTargetStreamer().emitDirectiveModuleNoGINV();
8464 reportParseError(
"unexpected token, expected end of statement");
8470 return Error(L,
"'" + Twine(Option) +
"' is not a valid .module option.");
8478bool MipsAsmParser::parseDirectiveModuleFP() {
8479 MCAsmParser &Parser = getParser();
8480 AsmLexer &Lexer = getLexer();
8483 reportParseError(
"unexpected token, expected equals sign '='");
8489 if (!parseFpABIValue(FpABI,
".module"))
8493 reportParseError(
"unexpected token, expected end of statement");
8499 getTargetStreamer().updateABIInfo(*
this);
8504 getTargetStreamer().emitDirectiveModuleFP();
8511 StringRef Directive) {
8512 MCAsmParser &Parser = getParser();
8513 AsmLexer &Lexer = getLexer();
8514 bool ModuleLevelOptions = Directive ==
".module";
8520 if (
Value !=
"xx") {
8521 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
8526 reportParseError(
"'" + Directive +
" fp=xx' requires the O32 ABI");
8530 FpABI = MipsABIFlagsSection::FpABIKind::XX;
8531 if (ModuleLevelOptions) {
8532 setModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8533 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8535 setFeatureBits(Mips::FeatureFPXX,
"fpxx");
8536 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8546 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
8552 reportParseError(
"'" + Directive +
" fp=32' requires the O32 ABI");
8556 FpABI = MipsABIFlagsSection::FpABIKind::S32;
8557 if (ModuleLevelOptions) {
8558 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8559 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8561 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
8562 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8565 FpABI = MipsABIFlagsSection::FpABIKind::S64;
8566 if (ModuleLevelOptions) {
8567 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8568 setModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8570 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
8571 setFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8581bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
8587 MCAsmParser &Parser = getParser();
8588 StringRef IDVal = DirectiveID.
getString();
8590 if (IDVal ==
".cpadd") {
8591 parseDirectiveCpAdd(DirectiveID.
getLoc());
8594 if (IDVal ==
".cpload") {
8595 parseDirectiveCpLoad(DirectiveID.
getLoc());
8598 if (IDVal ==
".cprestore") {
8599 parseDirectiveCpRestore(DirectiveID.
getLoc());
8602 if (IDVal ==
".cplocal") {
8603 parseDirectiveCpLocal(DirectiveID.
getLoc());
8606 if (IDVal ==
".ent") {
8610 reportParseError(
"expected identifier after .ent");
8624 reportParseError(
"unexpected token, expected end of statement");
8628 const MCExpr *DummyNumber;
8629 int64_t DummyNumberVal;
8633 reportParseError(
"expected number after comma");
8636 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
8637 reportParseError(
"expected an absolute expression after comma");
8644 reportParseError(
"unexpected token, expected end of statement");
8650 getTargetStreamer().emitDirectiveEnt(*Sym);
8652 IsCpRestoreSet =
false;
8656 if (IDVal ==
".end") {
8660 reportParseError(
"expected identifier after .end");
8665 reportParseError(
"unexpected token, expected end of statement");
8669 if (CurrentFn ==
nullptr) {
8670 reportParseError(
".end used without .ent");
8674 if ((SymbolName != CurrentFn->
getName())) {
8675 reportParseError(
".end symbol does not match .ent symbol");
8679 getTargetStreamer().emitDirectiveEnd(SymbolName);
8680 CurrentFn =
nullptr;
8681 IsCpRestoreSet =
false;
8685 if (IDVal ==
".frame") {
8688 ParseStatus Res = parseAnyRegister(TmpReg);
8690 reportParseError(
"expected stack register");
8694 MipsOperand &StackRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
8695 if (!StackRegOpnd.isGPRAsmReg()) {
8696 reportParseError(StackRegOpnd.getStartLoc(),
8697 "expected general purpose register");
8700 MCRegister StackReg = StackRegOpnd.getGPR32Reg();
8705 reportParseError(
"unexpected token, expected comma");
8710 const MCExpr *FrameSize;
8711 int64_t FrameSizeVal;
8714 reportParseError(
"expected frame size value");
8718 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
8719 reportParseError(
"frame size not an absolute expression");
8726 reportParseError(
"unexpected token, expected comma");
8732 Res = parseAnyRegister(TmpReg);
8734 reportParseError(
"expected return register");
8738 MipsOperand &ReturnRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
8739 if (!ReturnRegOpnd.isGPRAsmReg()) {
8740 reportParseError(ReturnRegOpnd.getStartLoc(),
8741 "expected general purpose register");
8747 reportParseError(
"unexpected token, expected end of statement");
8751 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
8752 ReturnRegOpnd.getGPR32Reg());
8753 IsCpRestoreSet =
false;
8757 if (IDVal ==
".set") {
8758 parseDirectiveSet();
8762 if (IDVal ==
".mask" || IDVal ==
".fmask") {
8773 const MCExpr *BitMask;
8777 reportParseError(
"expected bitmask value");
8781 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
8782 reportParseError(
"bitmask not an absolute expression");
8789 reportParseError(
"unexpected token, expected comma");
8794 const MCExpr *FrameOffset;
8795 int64_t FrameOffsetVal;
8798 reportParseError(
"expected frame offset value");
8802 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
8803 reportParseError(
"frame offset not an absolute expression");
8809 reportParseError(
"unexpected token, expected end of statement");
8813 if (IDVal ==
".mask")
8814 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
8816 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
8820 if (IDVal ==
".nan")
8821 return parseDirectiveNaN();
8823 if (IDVal ==
".gpword") {
8824 parseDirectiveGpWord();
8828 if (IDVal ==
".gpdword") {
8829 parseDirectiveGpDWord();
8833 if (IDVal ==
".dtprelword") {
8834 parseDirectiveDtpRelWord();
8838 if (IDVal ==
".dtpreldword") {
8839 parseDirectiveDtpRelDWord();
8843 if (IDVal ==
".tprelword") {
8844 parseDirectiveTpRelWord();
8848 if (IDVal ==
".tpreldword") {
8849 parseDirectiveTpRelDWord();
8853 if (IDVal ==
".option") {
8854 parseDirectiveOption();
8858 if (IDVal ==
".abicalls") {
8859 getTargetStreamer().emitDirectiveAbiCalls();
8862 "unexpected token, expected end of statement");
8867 if (IDVal ==
".cpsetup") {
8868 parseDirectiveCPSetup();
8871 if (IDVal ==
".cpreturn") {
8872 parseDirectiveCPReturn();
8875 if (IDVal ==
".module") {
8876 parseDirectiveModule();
8879 if (IDVal ==
".llvm_internal_mips_reallow_module_directive") {
8880 parseInternalDirectiveReallowModule();
8883 if (IDVal ==
".insn") {
8884 parseInsnDirective();
8887 if (IDVal ==
".rdata") {
8888 parseRSectionDirective(
".rodata");
8891 if (IDVal ==
".sbss") {
8895 if (IDVal ==
".sdata") {
8903bool MipsAsmParser::parseInternalDirectiveReallowModule() {
8906 reportParseError(
"unexpected token, expected end of statement");
8910 getTargetStreamer().reallowModuleDirective();
8924#define GET_REGISTER_MATCHER
8925#define GET_MATCHER_IMPLEMENTATION
8926#define GET_MNEMONIC_SPELL_CHECKER
8927#include "MipsGenAsmMatcher.inc"
8929bool MipsAsmParser::mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID) {
8931 const MatchEntry *Start, *End;
8932 switch (VariantID) {
8934 case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0);
break;
8937 auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
8938 return MnemonicRange.first != MnemonicRange.second;
static const TargetRegisterClass * getRegClass(const MachineInstr &MI, Register Reg)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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 GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Analysis containing CSE Info
#define LLVM_EXTERNAL_VISIBILITY
static Value * expandAbs(CallInst *Orig)
std::pair< Instruction::BinaryOps, Value * > OffsetOp
Find all possible pairs (BinOp, RHS) that BinOp V, RHS can be simplified.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static FeatureBitset getFeatures(MCSubtargetInfo &STI, StringRef CPU, StringRef TuneCPU, StringRef FS, ArrayRef< StringRef > ProcNames, ArrayRef< SubtargetSubTypeKV > ProcDesc, ArrayRef< SubtargetFeatureKV > ProcFeatures)
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)
static unsigned getRegisterForMxtrDSP(MCInst &Inst, bool IsMFDSP)
static bool hasShortDelaySlot(MCInst &Inst)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsAsmParser()
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 MCRegister nextReg(MCRegister Reg)
static unsigned getRegisterForMxtrFP(MCInst &Inst, bool IsMFTC1)
static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands, uint64_t ErrorInfo)
static MCRegister 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 PPCTargetMachine::PPCABI computeTargetABI(const Triple &TT, const TargetOptions &Options)
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 TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
static const fltSemantics & IEEEdouble()
APInt bitcastToAPInt() const
uint64_t getZExtValue() const
Get zero extended value.
SMLoc getLoc() const
Get the current source location.
const AsmToken peekTok(bool ShouldSkipSpace=true)
Look ahead at the next token to be lexed.
bool is(AsmToken::TokenKind K) const
Check if the current token has kind K.
bool isNot(AsmToken::TokenKind K) const
Check if the current token has kind K.
Target independent representation for an assembler token.
LLVM_ABI SMLoc getLoc() const
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
LLVM_ABI SMRange getLocRange() const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
Base class for user error types.
Container class for subtarget features.
void printExpr(raw_ostream &, const MCExpr &) const
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
bool parseToken(AsmToken::TokenKind T, const Twine &Msg="unexpected token")
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 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 LLVM_ABI 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 LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Base class for the full range of assembler expressions which are needed for parsing.
LLVM_ABI bool evaluateAsRelocatable(MCValue &Res, const MCAssembler *Asm) const
Try to evaluate the expression to a relocatable value, i.e.
@ Unary
Unary expressions.
@ Constant
Constant expressions.
@ SymbolRef
References to labels and assigned expressions.
@ Target
Target specific expression.
@ Specifier
Expression with a relocation specifier.
@ Binary
Binary expressions.
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.
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
Wrapper class representing physical registers. Should be passed by value.
constexpr bool isValid() const
constexpr unsigned id() const
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
Streaming machine code generation interface.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
virtual void emitRelocDirective(const MCExpr &Offset, StringRef Name, const MCExpr *Expr, SMLoc Loc={})
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.
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.
virtual unsigned getHwMode(enum HwModeType type=HwMode_Default) const
HwMode ID corresponding to the 'type' parameter is retrieved from the HwMode bit set of the current s...
Represent a reference to a symbol from inside an expression.
uint16_t getSpecifier() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
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).
bool isUndefined() const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).
StringRef getName() const
getName - Get the symbol name.
bool isVariable() const
isVariable - Check if this is a variable symbol.
const MCExpr * getVariableValue() const
Get the expression of the variable symbol.
bool isTemporary() const
isTemporary - Check if this is an assembler temporary symbol.
MCTargetAsmParser - Generic interface to target specific assembly parsers.
MCStreamer & getStreamer()
Unary assembler expressions.
const MCSymbol * getAddSym() const
int64_t getConstant() const
const MCSymbol * getSubSym() const
void emitRRX(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, MCOperand Op2, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveSetReorder()
void emitRRRX(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, MCRegister Reg2, MCOperand Op3, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRX(unsigned Opcode, MCRegister Reg0, MCOperand Op1, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitR(unsigned Opcode, MCRegister Reg0, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void setUsesMicroMips()
void emitRRI(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, int16_t Imm, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitEmptyDelaySlot(bool hasShortDelaySlot, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRI(unsigned Opcode, MCRegister Reg0, int32_t Imm, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRR(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, SMLoc IDLoc, const MCSubtargetInfo *STI)
void updateABIInfo(const PredicateLibrary &P)
void emitRRIII(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, int16_t Imm0, int16_t Imm1, int16_t Imm2, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitDSLL(MCRegister DstReg, MCRegister SrcReg, int16_t ShiftAmount, 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)
void emitRRR(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, MCRegister Reg2, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveSetNoReorder()
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
constexpr unsigned id() const
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
void push_back(const T &Elt)
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.
LLVM_ABI bool isLittleEndian() const
Tests whether the target triple is little endian.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
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.
@ CE
Windows NT (Windows on ARM)
LLVM_ABI std::string getABIName()
Context & getContext() const
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Target & getTheMips64Target()
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
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.
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
@ Success
The lock was released successfully.
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.
To bit_cast(const From &from) noexcept
Target & getTheMipselTarget()
DWARFExpression::Operation Op
constexpr bool isShiftedInt(int64_t x)
Checks if a signed integer is an N bit number shifted left by S.
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
static uint16_t getSpecifier(const MCSymbolRefExpr *SRE)
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
Target & getTheMipsTarget()
constexpr bool isShiftedUInt(uint64_t x)
Checks if a unsigned integer is an N bit number shifted left by S.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...