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);
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 unsigned R0 = RegList.List->front();
1381 unsigned R1 = RegList.List->back();
1382 if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1383 (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1386 int PrevReg = *RegList.List->begin();
1387 for (
int i = 1; i <
Size - 1; i++) {
1388 int 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<unsigned> &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<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1552 MipsAsmParser &Parser) {
1553 assert(Regs.
size() > 0 &&
"Empty list not allowed");
1555 auto Op = std::make_unique<MipsOperand>(k_RegList, Parser);
1557 Op->StartLoc = StartLoc;
1558 Op->EndLoc = EndLoc;
1562 bool isGPRZeroAsmReg()
const {
1563 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
1566 bool isGPRNonZeroAsmReg()
const {
1567 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index > 0 &&
1571 bool isGPRAsmReg()
const {
1572 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1575 bool isMM16AsmReg()
const {
1576 if (!(isRegIdx() && RegIdx.Kind))
1578 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1579 || RegIdx.Index == 16 || RegIdx.Index == 17);
1582 bool isMM16AsmRegZero()
const {
1583 if (!(isRegIdx() && RegIdx.Kind))
1585 return (RegIdx.Index == 0 ||
1586 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1587 RegIdx.Index == 17);
1590 bool isMM16AsmRegMoveP()
const {
1591 if (!(isRegIdx() && RegIdx.Kind))
1593 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1594 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1597 bool isMM16AsmRegMovePPairFirst()
const {
1598 if (!(isRegIdx() && RegIdx.Kind))
1600 return RegIdx.Index >= 4 && RegIdx.Index <= 6;
1603 bool isMM16AsmRegMovePPairSecond()
const {
1604 if (!(isRegIdx() && RegIdx.Kind))
1606 return (RegIdx.Index == 21 || RegIdx.Index == 22 ||
1607 (RegIdx.Index >= 5 && RegIdx.Index <= 7));
1610 bool isFGRAsmReg()
const {
1612 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1615 bool isStrictlyFGRAsmReg()
const {
1617 return isRegIdx() && RegIdx.Kind == RegKind_FGR && RegIdx.Index <= 31;
1620 bool isHWRegsAsmReg()
const {
1621 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1624 bool isCCRAsmReg()
const {
1625 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1628 bool isFCCAsmReg()
const {
1629 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1631 return RegIdx.Index <= 7;
1634 bool isACCAsmReg()
const {
1635 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1638 bool isCOP0AsmReg()
const {
1639 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1642 bool isCOP2AsmReg()
const {
1643 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1646 bool isCOP3AsmReg()
const {
1647 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1650 bool isMSA128AsmReg()
const {
1651 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1654 bool isMSACtrlAsmReg()
const {
1655 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1659 SMLoc getStartLoc()
const override {
return StartLoc; }
1661 SMLoc getEndLoc()
const override {
return EndLoc; }
1663 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1672 Mem.Base->print(OS, MAI);
1677 case k_RegisterIndex:
1678 OS <<
"RegIdx<" << RegIdx.Index <<
":" << RegIdx.Kind <<
", "
1679 << StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) <<
">";
1686 for (
auto Reg : (*RegList.List))
1693 bool isValidForTie(
const MipsOperand &
Other)
const {
1694 if (Kind !=
Other.Kind)
1701 case k_RegisterIndex: {
1702 StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length);
1703 StringRef OtherToken(
Other.RegIdx.Tok.Data,
Other.RegIdx.Tok.Length);
1704 return Token == OtherToken;
1720 case Mips::JRC16_MM:
1722 case Mips::JALRS_MM:
1723 case Mips::JALRS16_MM:
1724 case Mips::BGEZALS_MM:
1725 case Mips::BLTZALS_MM:
1736 return &SRExpr->getSymbol();
1795 unsigned NumOp =
MCID.getNumOperands();
1796 if (NumOp != 3 && NumOp != 4)
1826bool MipsAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
1829 MipsTargetStreamer &TOut = getTargetStreamer();
1830 const unsigned Opcode = Inst.
getOpcode();
1831 const MCInstrDesc &MCID = MII.get(Opcode);
1832 bool ExpandedJalSym =
false;
1846 assert(hasCnMips() &&
"instruction only valid for octeon cpus");
1857 if (!
isIntN(inMicroMipsMode() ? 17 : 18,
Offset.getImm()))
1858 return Error(IDLoc,
"branch target out of range");
1861 return Error(IDLoc,
"branch to misaligned address");
1875 case Mips::BGEZAL_MM:
1876 case Mips::BLTZAL_MM:
1879 case Mips::BC1EQZC_MMR6:
1880 case Mips::BC1NEZC_MMR6:
1881 case Mips::BC2EQZC_MMR6:
1882 case Mips::BC2NEZC_MMR6:
1887 if (!
isIntN(inMicroMipsMode() ? 17 : 18,
Offset.getImm()))
1888 return Error(IDLoc,
"branch target out of range");
1891 return Error(IDLoc,
"branch to misaligned address");
1893 case Mips::BGEC:
case Mips::BGEC_MMR6:
1894 case Mips::BLTC:
case Mips::BLTC_MMR6:
1895 case Mips::BGEUC:
case Mips::BGEUC_MMR6:
1896 case Mips::BLTUC:
case Mips::BLTUC_MMR6:
1897 case Mips::BEQC:
case Mips::BEQC_MMR6:
1898 case Mips::BNEC:
case Mips::BNEC_MMR6:
1904 return Error(IDLoc,
"branch target out of range");
1906 return Error(IDLoc,
"branch to misaligned address");
1908 case Mips::BLEZC:
case Mips::BLEZC_MMR6:
1909 case Mips::BGEZC:
case Mips::BGEZC_MMR6:
1910 case Mips::BGTZC:
case Mips::BGTZC_MMR6:
1911 case Mips::BLTZC:
case Mips::BLTZC_MMR6:
1917 return Error(IDLoc,
"branch target out of range");
1919 return Error(IDLoc,
"branch to misaligned address");
1921 case Mips::BEQZC:
case Mips::BEQZC_MMR6:
1922 case Mips::BNEZC:
case Mips::BNEZC_MMR6:
1928 return Error(IDLoc,
"branch target out of range");
1930 return Error(IDLoc,
"branch to misaligned address");
1932 case Mips::BEQZ16_MM:
1933 case Mips::BEQZC16_MMR6:
1934 case Mips::BNEZ16_MM:
1935 case Mips::BNEZC16_MMR6:
1941 return Error(IDLoc,
"branch target out of range");
1943 return Error(IDLoc,
"branch to misaligned address");
1950 if (hasMips32r6() && Opcode == Mips::SSNOP) {
1951 std::string
ISA = hasMips64r6() ?
"MIPS64r6" :
"MIPS32r6";
1952 Warning(IDLoc,
"ssnop is deprecated for " + ISA +
" and is equivalent to a "
1972 return Error(IDLoc,
"expected immediate operand kind");
1974 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1975 Opcode == Mips::BBIT1 ? 63 : 31))
1976 return Error(IDLoc,
"immediate operand value out of range");
1978 Inst.
setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1989 return Error(IDLoc,
"expected immediate operand kind");
1992 return Error(IDLoc,
"immediate operand value out of range");
2004 unsigned FirstOp = 1;
2005 unsigned SecondOp = 2;
2009 case Mips::SDivIMacro:
2010 case Mips::UDivIMacro:
2011 case Mips::DSDivIMacro:
2012 case Mips::DUDivIMacro:
2016 Warning(IDLoc,
"dividing zero by zero");
2018 Warning(IDLoc,
"division by zero");
2030 case Mips::SDivMacro:
2031 case Mips::DSDivMacro:
2032 case Mips::UDivMacro:
2033 case Mips::DUDivMacro:
2038 case Mips::DIVU_MMR6:
2039 case Mips::DIV_MMR6:
2044 Warning(IDLoc,
"dividing zero by zero");
2046 Warning(IDLoc,
"division by zero");
2052 if ((Opcode == Mips::J || Opcode == Mips::J_MM) && inPicMode()) {
2054 BInst.
setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
2063 if ((Opcode == Mips::JAL || Opcode == Mips::JAL_MM) && inPicMode()) {
2064 warnIfNoMacro(IDLoc);
2067 return Error(IDLoc,
"unsupported constant in relocation");
2075 return Error(IDLoc,
"jal doesn't support multiple symbols in PIC mode");
2081 if (expandLoadAddress(Mips::T9, MCRegister(), Inst.
getOperand(0),
2082 !isGP64bit(), IDLoc, Out, STI))
2086 if (inMicroMipsMode())
2087 JalrInst.
setOpcode(IsCpRestoreSet ? Mips::JALRS_MM : Mips::JALR_MM);
2093 if (isJalrRelocAvailable(JalExpr)) {
2099 const MCExpr *RelocJalrExpr =
2103 *TmpExpr, inMicroMipsMode() ?
"R_MICROMIPS_JALR" :
"R_MIPS_JALR",
2109 ExpandedJalSym =
true;
2118 expandMem9Inst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2121 expandMem16Inst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2124 return getParser().hasPendingError();
2128 if (inMicroMipsMode()) {
2129 if (MCID.
mayLoad() && Opcode != Mips::LWP_MM) {
2132 const MCOperandInfo &OpInfo = MCID.
operands()[i];
2137 int MemOffset =
Op.getImm();
2140 if (
isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
2143 (
BaseReg.getReg() == Mips::GP ||
2144 BaseReg.getReg() == Mips::GP_64)) {
2146 TOut.
emitRRI(Mips::LWGP_MM, DstReg.
getReg(), Mips::GP, MemOffset,
2163 case Mips::ADDIUSP_MM:
2166 return Error(IDLoc,
"expected immediate operand kind");
2168 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
2170 return Error(IDLoc,
"immediate operand value out of range");
2172 case Mips::SLL16_MM:
2173 case Mips::SRL16_MM:
2176 return Error(IDLoc,
"expected immediate operand kind");
2178 if (Imm < 1 || Imm > 8)
2179 return Error(IDLoc,
"immediate operand value out of range");
2184 return Error(IDLoc,
"expected immediate operand kind");
2186 if (Imm < -1 || Imm > 126)
2187 return Error(IDLoc,
"immediate operand value out of range");
2189 case Mips::ADDIUR2_MM:
2192 return Error(IDLoc,
"expected immediate operand kind");
2194 if (!(Imm == 1 || Imm == -1 ||
2195 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
2196 return Error(IDLoc,
"immediate operand value out of range");
2198 case Mips::ANDI16_MM:
2201 return Error(IDLoc,
"expected immediate operand kind");
2203 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
2204 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
2205 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
2206 return Error(IDLoc,
"immediate operand value out of range");
2208 case Mips::LBU16_MM:
2211 return Error(IDLoc,
"expected immediate operand kind");
2213 if (Imm < -1 || Imm > 14)
2214 return Error(IDLoc,
"immediate operand value out of range");
2217 case Mips::SB16_MMR6:
2220 return Error(IDLoc,
"expected immediate operand kind");
2222 if (Imm < 0 || Imm > 15)
2223 return Error(IDLoc,
"immediate operand value out of range");
2225 case Mips::LHU16_MM:
2227 case Mips::SH16_MMR6:
2230 return Error(IDLoc,
"expected immediate operand kind");
2232 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
2233 return Error(IDLoc,
"immediate operand value out of range");
2237 case Mips::SW16_MMR6:
2240 return Error(IDLoc,
"expected immediate operand kind");
2242 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
2243 return Error(IDLoc,
"immediate operand value out of range");
2245 case Mips::ADDIUPC_MM:
2248 return Error(IDLoc,
"expected immediate operand kind");
2251 return Error(IDLoc,
"immediate operand value out of range");
2256 return Error(IDLoc,
"invalid operand for instruction");
2258 case Mips::MOVEP_MM:
2259 case Mips::MOVEP_MMR6: {
2262 bool RegPair = ((R0 == Mips::A1 && R1 == Mips::A2) ||
2263 (R0 == Mips::A1 && R1 == Mips::A3) ||
2264 (R0 == Mips::A2 && R1 == Mips::A3) ||
2265 (R0 == Mips::A0 && R1 == Mips::S5) ||
2266 (R0 == Mips::A0 && R1 == Mips::S6) ||
2267 (R0 == Mips::A0 && R1 == Mips::A1) ||
2268 (R0 == Mips::A0 && R1 == Mips::A2) ||
2269 (R0 == Mips::A0 && R1 == Mips::A3));
2271 return Error(IDLoc,
"invalid operand for instruction");
2277 bool FillDelaySlot =
2282 bool PrevForbiddenSlotAttr = CurForbiddenSlotAttr;
2285 bool SetReorderAfterNop =
false;
2290 if (PrevForbiddenSlotAttr && !SafeInForbiddenSlot(MCID)) {
2300 if (AssemblerOptions.
back()->isReorder() && !FillDelaySlot) {
2301 SetReorderAfterNop =
true;
2310 CurForbiddenSlotAttr =
2311 hasForbiddenSlot(MCID) && AssemblerOptions.
back()->isReorder();
2313 if (FillDelaySlot || CurForbiddenSlotAttr)
2316 MacroExpanderResultTy ExpandResult =
2317 tryExpandInstruction(Inst, IDLoc, Out, STI);
2318 switch (ExpandResult) {
2334 if (PrevForbiddenSlotAttr && !SetReorderAfterNop && !FillDelaySlot &&
2335 AssemblerOptions.
back()->isReorder()) {
2341 if (inMicroMipsMode()) {
2356 if (FillDelaySlot) {
2361 if ((Opcode == Mips::JalOneReg || Opcode == Mips::JalTwoReg ||
2363 isPicAndNotNxxAbi()) {
2364 if (IsCpRestoreSet) {
2368 if (!AssemblerOptions.
back()->isReorder())
2375 Warning(IDLoc,
"no .cprestore used in PIC mode");
2381void MipsAsmParser::onEndOfFile() {
2382 MipsTargetStreamer &TOut = getTargetStreamer();
2383 SMLoc IDLoc = SMLoc();
2385 if (CurForbiddenSlotAttr) {
2387 if (AssemblerOptions.
back()->isReorder())
2392MipsAsmParser::MacroExpanderResultTy
2393MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2394 const MCSubtargetInfo *STI) {
2397 return MER_NotAMacro;
2398 case Mips::LoadImm32:
2399 return expandLoadImm(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2400 case Mips::LoadImm64:
2401 return expandLoadImm(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2402 case Mips::LoadAddrImm32:
2403 case Mips::LoadAddrImm64:
2406 "expected immediate operand kind");
2408 return expandLoadAddress(
2410 Inst.
getOpcode() == Mips::LoadAddrImm32, IDLoc, Out, STI)
2413 case Mips::LoadAddrReg32:
2414 case Mips::LoadAddrReg64:
2418 "expected immediate operand kind");
2422 Inst.
getOpcode() == Mips::LoadAddrReg32, IDLoc,
2426 case Mips::B_MM_Pseudo:
2427 case Mips::B_MMR6_Pseudo:
2428 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2432 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2434 case Mips::JalOneReg:
2435 case Mips::JalTwoReg:
2436 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2439 case Mips::BEQLImmMacro:
2440 case Mips::BNELImmMacro:
2441 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2458 case Mips::BLTImmMacro:
2459 case Mips::BLEImmMacro:
2460 case Mips::BGEImmMacro:
2461 case Mips::BGTImmMacro:
2462 case Mips::BLTUImmMacro:
2463 case Mips::BLEUImmMacro:
2464 case Mips::BGEUImmMacro:
2465 case Mips::BGTUImmMacro:
2466 case Mips::BLTLImmMacro:
2467 case Mips::BLELImmMacro:
2468 case Mips::BGELImmMacro:
2469 case Mips::BGTLImmMacro:
2470 case Mips::BLTULImmMacro:
2471 case Mips::BLEULImmMacro:
2472 case Mips::BGEULImmMacro:
2473 case Mips::BGTULImmMacro:
2474 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2475 case Mips::SDivMacro:
2476 case Mips::SDivIMacro:
2477 case Mips::SRemMacro:
2478 case Mips::SRemIMacro:
2479 return expandDivRem(Inst, IDLoc, Out, STI,
false,
true) ? MER_Fail
2481 case Mips::DSDivMacro:
2482 case Mips::DSDivIMacro:
2483 case Mips::DSRemMacro:
2484 case Mips::DSRemIMacro:
2485 return expandDivRem(Inst, IDLoc, Out, STI,
true,
true) ? MER_Fail
2487 case Mips::UDivMacro:
2488 case Mips::UDivIMacro:
2489 case Mips::URemMacro:
2490 case Mips::URemIMacro:
2491 return expandDivRem(Inst, IDLoc, Out, STI,
false,
false) ? MER_Fail
2493 case Mips::DUDivMacro:
2494 case Mips::DUDivIMacro:
2495 case Mips::DURemMacro:
2496 case Mips::DURemIMacro:
2497 return expandDivRem(Inst, IDLoc, Out, STI,
true,
false) ? MER_Fail
2499 case Mips::PseudoTRUNC_W_S:
2500 return expandTrunc(Inst,
false,
false, IDLoc, Out, STI) ? MER_Fail
2502 case Mips::PseudoTRUNC_W_D32:
2503 return expandTrunc(Inst,
true,
false, IDLoc, Out, STI) ? MER_Fail
2505 case Mips::PseudoTRUNC_W_D:
2506 return expandTrunc(Inst,
true,
true, IDLoc, Out, STI) ? MER_Fail
2509 case Mips::LoadImmSingleGPR:
2510 return expandLoadSingleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2512 case Mips::LoadImmSingleFGR:
2513 return expandLoadSingleImmToFPR(Inst, IDLoc, Out, STI) ? MER_Fail
2515 case Mips::LoadImmDoubleGPR:
2516 return expandLoadDoubleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2518 case Mips::LoadImmDoubleFGR:
2519 return expandLoadDoubleImmToFPR(Inst,
true, IDLoc, Out, STI) ? MER_Fail
2521 case Mips::LoadImmDoubleFGR_32:
2522 return expandLoadDoubleImmToFPR(Inst,
false, IDLoc, Out, STI) ? MER_Fail
2526 return expandUlh(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2528 return expandUlh(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2530 return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2533 return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2535 case Mips::NORImm64:
2536 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2539 return expandSge(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2542 case Mips::SGEImm64:
2543 case Mips::SGEUImm64:
2544 return expandSgeImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2547 case Mips::SGTImm64:
2548 case Mips::SGTUImm64:
2549 return expandSgtImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2552 return expandSle(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2555 case Mips::SLEImm64:
2556 case Mips::SLEUImm64:
2557 return expandSleImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2558 case Mips::SLTImm64:
2561 return MER_NotAMacro;
2563 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2564 case Mips::SLTUImm64:
2567 return MER_NotAMacro;
2569 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2570 case Mips::ADDi:
case Mips::ADDi_MM:
2571 case Mips::ADDiu:
case Mips::ADDiu_MM:
2572 case Mips::SLTi:
case Mips::SLTi_MM:
2573 case Mips::SLTiu:
case Mips::SLTiu_MM:
2578 return MER_NotAMacro;
2579 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2582 return MER_NotAMacro;
2583 case Mips::ANDi:
case Mips::ANDi_MM:
case Mips::ANDi64:
2584 case Mips::ORi:
case Mips::ORi_MM:
case Mips::ORi64:
2585 case Mips::XORi:
case Mips::XORi_MM:
case Mips::XORi64:
2590 return MER_NotAMacro;
2591 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2594 return MER_NotAMacro;
2597 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2600 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2603 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2606 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2607 case Mips::ABSMacro:
2608 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2609 case Mips::MULImmMacro:
2610 case Mips::DMULImmMacro:
2611 return expandMulImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2612 case Mips::MULOMacro:
2613 case Mips::DMULOMacro:
2614 return expandMulO(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2615 case Mips::MULOUMacro:
2616 case Mips::DMULOUMacro:
2617 return expandMulOU(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2618 case Mips::DMULMacro:
2619 return expandDMULMacro(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2622 return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2627 return expandStoreDM1Macro(Inst, IDLoc, Out, STI)
2630 case Mips::SEQMacro:
2631 return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2632 case Mips::SEQIMacro:
2633 return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2634 case Mips::SNEMacro:
2635 return expandSne(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2636 case Mips::SNEIMacro:
2637 return expandSneI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2638 case Mips::MFTC0:
case Mips::MTTC0:
2639 case Mips::MFTGPR:
case Mips::MTTGPR:
2640 case Mips::MFTLO:
case Mips::MTTLO:
2641 case Mips::MFTHI:
case Mips::MTTHI:
2642 case Mips::MFTACX:
case Mips::MTTACX:
2643 case Mips::MFTDSP:
case Mips::MTTDSP:
2644 case Mips::MFTC1:
case Mips::MTTC1:
2645 case Mips::MFTHC1:
case Mips::MTTHC1:
2646 case Mips::CFTC1:
case Mips::CTTC1:
2647 return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2649 case Mips::SaadAddr:
2650 return expandSaaAddr(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2654bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2656 const MCSubtargetInfo *STI) {
2657 MipsTargetStreamer &TOut = getTargetStreamer();
2662 const MCOperand FirstRegOp = Inst.
getOperand(0);
2663 const unsigned Opcode = Inst.
getOpcode();
2665 if (Opcode == Mips::JalOneReg) {
2667 if (IsCpRestoreSet && inMicroMipsMode()) {
2670 }
else if (inMicroMipsMode()) {
2671 JalrInst.
setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2678 }
else if (Opcode == Mips::JalTwoReg) {
2680 if (IsCpRestoreSet && inMicroMipsMode())
2683 JalrInst.
setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2685 const MCOperand SecondRegOp = Inst.
getOperand(1);
2692 const MCInstrDesc &MCID = MII.get(JalrInst.
getOpcode());
2715bool MipsAsmParser::loadImmediate(int64_t ImmValue, MCRegister DstReg,
2716 MCRegister SrcReg,
bool Is32BitImm,
2717 bool IsAddress, SMLoc IDLoc, MCStreamer &Out,
2718 const MCSubtargetInfo *STI) {
2719 MipsTargetStreamer &TOut = getTargetStreamer();
2721 if (!Is32BitImm && !isGP64bit()) {
2722 Error(IDLoc,
"instruction requires a 64-bit architecture");
2733 Error(IDLoc,
"instruction requires a 32-bit immediate");
2738 MCRegister ZeroReg = IsAddress ?
ABI.GetNullPtr() :
ABI.GetZeroReg();
2739 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2741 bool UseSrcReg =
false;
2745 MCRegister TmpReg = DstReg;
2747 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2750 MCRegister ATReg = getATReg(IDLoc);
2763 if (IsAddress && !Is32BitImm) {
2764 TOut.
emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2768 TOut.
emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2773 MCRegister TmpReg = DstReg;
2774 if (SrcReg == DstReg) {
2775 TmpReg = getATReg(IDLoc);
2780 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2782 TOut.
emitRRR(
ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2787 warnIfNoMacro(IDLoc);
2789 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2790 uint16_t Bits15To0 = ImmValue & 0xffff;
2791 if (!Is32BitImm && !
isInt<32>(ImmValue)) {
2794 if (ImmValue == 0xffffffff) {
2795 TOut.
emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2796 TOut.
emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2798 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2804 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2805 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2807 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2809 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2813 TOut.
emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2815 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2817 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2823 Error(IDLoc,
"instruction requires a 32-bit immediate");
2830 assert(
BitWidth >= 17 &&
"ImmValue must be at least 17-bit wide");
2834 unsigned ShiftAmount =
BitWidth - 16;
2835 uint16_t
Bits = (ImmValue >> ShiftAmount) & 0xffff;
2836 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2837 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2840 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2845 warnIfNoMacro(IDLoc);
2852 if (loadImmediate(ImmValue >> 32, TmpReg, MCRegister(),
true,
false, IDLoc,
2858 unsigned ShiftCarriedForwards = 16;
2859 for (
int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2860 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2862 if (ImmChunk != 0) {
2863 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2864 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2865 ShiftCarriedForwards = 0;
2868 ShiftCarriedForwards += 16;
2870 ShiftCarriedForwards -= 16;
2873 if (ShiftCarriedForwards)
2874 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2877 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2882bool MipsAsmParser::expandLoadImm(MCInst &Inst,
bool Is32BitImm, SMLoc IDLoc,
2883 MCStreamer &Out,
const MCSubtargetInfo *STI) {
2885 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
2886 const MCOperand &DstRegOp = Inst.
getOperand(0);
2887 assert(DstRegOp.
isReg() &&
"expected register operand kind");
2889 if (loadImmediate(ImmOp.
getImm(), DstRegOp.
getReg(), MCRegister(), Is32BitImm,
2890 false, IDLoc, Out, STI))
2896bool MipsAsmParser::expandLoadAddress(MCRegister DstReg, MCRegister BaseReg,
2898 bool Is32BitAddress, SMLoc IDLoc,
2900 const MCSubtargetInfo *STI) {
2902 if (Is32BitAddress &&
ABI.ArePtrs64bit()) {
2903 Warning(IDLoc,
"la used to load 64-bit address");
2905 Is32BitAddress =
false;
2909 if (!Is32BitAddress && !hasMips3()) {
2910 Error(IDLoc,
"instruction requires a 64-bit architecture");
2915 return loadAndAddSymbolAddress(
Offset.getExpr(), DstReg, BaseReg,
2916 Is32BitAddress, IDLoc, Out, STI);
2918 if (!
ABI.ArePtrs64bit()) {
2920 Is32BitAddress =
true;
2923 return loadImmediate(
Offset.getImm(), DstReg, BaseReg, Is32BitAddress,
true,
2927bool MipsAsmParser::loadAndAddSymbolAddress(
const MCExpr *SymExpr,
2929 MCRegister SrcReg,
bool Is32BitSym,
2930 SMLoc IDLoc, MCStreamer &Out,
2931 const MCSubtargetInfo *STI) {
2932 MipsTargetStreamer &TOut = getTargetStreamer();
2934 SrcReg.
isValid() && SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64;
2935 warnIfNoMacro(IDLoc);
2940 Error(IDLoc,
"expected relocatable expression");
2944 Error(IDLoc,
"expected relocatable expression with only one symbol");
2948 bool IsPtr64 =
ABI.ArePtrs64bit();
2952 static_cast<const MCSymbolELF *
>(Res.
getAddSym())->getBinding() ==
2959 bool UseXGOT = STI->
hasFeature(Mips::FeatureXGOT) && !IsLocalSym;
2965 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2968 const MCExpr *CallHiExpr =
2970 const MCExpr *CallLoExpr =
2974 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, DstReg, GPReg,
2976 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, DstReg,
2979 const MCExpr *CallExpr =
2981 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, GPReg,
2987 MCRegister TmpReg = DstReg;
2989 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2993 MCRegister ATReg = getATReg(IDLoc);
3012 const MCExpr *CallHiExpr =
3019 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg, GPReg,
3021 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, TmpReg,
3025 TOut.
emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3031 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3036 const MCSpecifierExpr *GotExpr =
nullptr;
3037 const MCExpr *LoExpr =
nullptr;
3038 if (
ABI.IsN32() ||
ABI.IsN64()) {
3057 Error(IDLoc,
"macro instruction uses large offset, which is not "
3058 "currently supported");
3087 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, GPReg,
3091 TOut.
emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3095 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3101 const auto *HiExpr =
3103 const auto *LoExpr =
3107 if (
ABI.ArePtrs64bit() && isGP64bit()) {
3115 const auto *HighestExpr =
3117 const auto *HigherExpr =
3122 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
3124 if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
3125 MCRegister ATReg = getATReg(IDLoc);
3137 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3139 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3142 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3145 TOut.
emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
3148 }
else if (canUseATReg() && !RdRegIsRsReg && DstReg != getATReg(IDLoc)) {
3149 MCRegister ATReg = getATReg(IDLoc);
3165 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3169 TOut.
emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3170 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3172 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3175 }
else if ((!canUseATReg() && !RdRegIsRsReg) ||
3176 (canUseATReg() && DstReg == getATReg(IDLoc))) {
3187 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3189 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3190 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3192 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3193 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3196 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3202 assert(SrcReg == DstReg && !canUseATReg() &&
3203 "Could have expanded dla but didn't?");
3204 reportParseError(IDLoc,
3205 "pseudo-instruction requires $at, which is not available");
3219 MCRegister TmpReg = DstReg;
3221 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
3224 MCRegister ATReg = getATReg(IDLoc);
3235 TOut.
emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3238 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
3247 if (MipsMCRegisterClasses[Mips::FGR32RegClassID].
contains(
Reg))
3248 return Reg == (
unsigned)Mips::F31 ? (
unsigned)Mips::F0 :
Reg + 1;
3250 default:
llvm_unreachable(
"Unknown register in assembly macro expansion!");
3251 case Mips::ZERO:
return Mips::AT;
3252 case Mips::AT:
return Mips::V0;
3253 case Mips::V0:
return Mips::V1;
3254 case Mips::V1:
return Mips::A0;
3255 case Mips::A0:
return Mips::A1;
3256 case Mips::A1:
return Mips::A2;
3257 case Mips::A2:
return Mips::A3;
3258 case Mips::A3:
return Mips::T0;
3259 case Mips::T0:
return Mips::T1;
3260 case Mips::T1:
return Mips::T2;
3261 case Mips::T2:
return Mips::T3;
3262 case Mips::T3:
return Mips::T4;
3263 case Mips::T4:
return Mips::T5;
3264 case Mips::T5:
return Mips::T6;
3265 case Mips::T6:
return Mips::T7;
3266 case Mips::T7:
return Mips::S0;
3267 case Mips::S0:
return Mips::S1;
3268 case Mips::S1:
return Mips::S2;
3269 case Mips::S2:
return Mips::S3;
3270 case Mips::S3:
return Mips::S4;
3271 case Mips::S4:
return Mips::S5;
3272 case Mips::S5:
return Mips::S6;
3273 case Mips::S6:
return Mips::S7;
3274 case Mips::S7:
return Mips::T8;
3275 case Mips::T8:
return Mips::T9;
3276 case Mips::T9:
return Mips::K0;
3277 case Mips::K0:
return Mips::K1;
3278 case Mips::K1:
return Mips::GP;
3279 case Mips::GP:
return Mips::SP;
3280 case Mips::SP:
return Mips::FP;
3281 case Mips::FP:
return Mips::RA;
3282 case Mips::RA:
return Mips::ZERO;
3283 case Mips::D0:
return Mips::F1;
3284 case Mips::D1:
return Mips::F3;
3285 case Mips::D2:
return Mips::F5;
3286 case Mips::D3:
return Mips::F7;
3287 case Mips::D4:
return Mips::F9;
3288 case Mips::D5:
return Mips::F11;
3289 case Mips::D6:
return Mips::F13;
3290 case Mips::D7:
return Mips::F15;
3291 case Mips::D8:
return Mips::F17;
3292 case Mips::D9:
return Mips::F19;
3293 case Mips::D10:
return Mips::F21;
3294 case Mips::D11:
return Mips::F23;
3295 case Mips::D12:
return Mips::F25;
3296 case Mips::D13:
return Mips::F27;
3297 case Mips::D14:
return Mips::F29;
3298 case Mips::D15:
return Mips::F31;
3308bool MipsAsmParser::emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc,
3310 MCRegister ATReg = getATReg(IDLoc);
3316 const auto *GotExpr =
3319 if(isABI_O32() || isABI_N32()) {
3328 const auto *HiExpr =
3337 if(isABI_O32() || isABI_N32()) {
3341 const auto *HighestExpr =
3344 const auto *HigherExpr =
3349 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3351 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3354 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3363 if ((
Hi_32(ImmOp64) & 0x7ff00000) == 0) {
3374 float TmpFloat =
static_cast<float>(DoubleImm);
3378bool MipsAsmParser::expandLoadSingleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3380 const MCSubtargetInfo *STI) {
3383 "Invalid instruction operand.");
3390 return loadImmediate(ImmOp32, FirstReg, MCRegister(),
true,
false, IDLoc, Out,
3394bool MipsAsmParser::expandLoadSingleImmToFPR(MCInst &Inst, SMLoc IDLoc,
3396 const MCSubtargetInfo *STI) {
3397 MipsTargetStreamer &TOut = getTargetStreamer();
3400 "Invalid instruction operand.");
3409 MCRegister TmpReg = Mips::ZERO;
3411 TmpReg = getATReg(IDLoc);
3416 if (
Lo_32(ImmOp64) == 0) {
3417 if (TmpReg != Mips::ZERO && loadImmediate(ImmOp32, TmpReg, MCRegister(),
3418 true,
false, IDLoc, Out, STI))
3420 TOut.
emitRR(Mips::MTC1, FirstReg, TmpReg, IDLoc, STI);
3424 MCSection *CS = getStreamer().getCurrentSectionOnly();
3427 MCSection *ReadOnlySection =
3434 getStreamer().switchSection(ReadOnlySection);
3435 getStreamer().emitLabel(Sym, IDLoc);
3436 getStreamer().emitInt32(ImmOp32);
3437 getStreamer().switchSection(CS);
3439 if (emitPartialAddress(TOut, IDLoc, Sym))
3446bool MipsAsmParser::expandLoadDoubleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3448 const MCSubtargetInfo *STI) {
3449 MipsTargetStreamer &TOut = getTargetStreamer();
3452 "Invalid instruction operand.");
3459 if (
Lo_32(ImmOp64) == 0) {
3461 if (loadImmediate(ImmOp64, FirstReg, MCRegister(),
false,
false, IDLoc,
3465 if (loadImmediate(
Hi_32(ImmOp64), FirstReg, MCRegister(),
true,
false,
3469 if (loadImmediate(0,
nextReg(FirstReg), MCRegister(),
true,
false, IDLoc,
3476 MCSection *CS = getStreamer().getCurrentSectionOnly();
3477 MCSection *ReadOnlySection =
3484 getStreamer().switchSection(ReadOnlySection);
3485 getStreamer().emitLabel(Sym, IDLoc);
3486 getStreamer().emitValueToAlignment(
Align(8));
3487 getStreamer().emitIntValue(ImmOp64, 8);
3488 getStreamer().switchSection(CS);
3490 MCRegister TmpReg = getATReg(IDLoc);
3494 if (emitPartialAddress(TOut, IDLoc, Sym))
3497 TOut.
emitRRX(isABI_N64() ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3501 TOut.
emitRRI(Mips::LD, FirstReg, TmpReg, 0, IDLoc, STI);
3503 TOut.
emitRRI(Mips::LW, FirstReg, TmpReg, 0, IDLoc, STI);
3504 TOut.
emitRRI(Mips::LW,
nextReg(FirstReg), TmpReg, 4, IDLoc, STI);
3509bool MipsAsmParser::expandLoadDoubleImmToFPR(MCInst &Inst,
bool Is64FPU,
3510 SMLoc IDLoc, MCStreamer &Out,
3511 const MCSubtargetInfo *STI) {
3512 MipsTargetStreamer &TOut = getTargetStreamer();
3515 "Invalid instruction operand.");
3522 MCRegister TmpReg = Mips::ZERO;
3524 TmpReg = getATReg(IDLoc);
3529 if ((
Lo_32(ImmOp64) == 0) &&
3530 !((
Hi_32(ImmOp64) & 0xffff0000) && (
Hi_32(ImmOp64) & 0x0000ffff))) {
3532 if (TmpReg != Mips::ZERO && loadImmediate(ImmOp64, TmpReg, MCRegister(),
3533 false,
false, IDLoc, Out, STI))
3535 TOut.
emitRR(Mips::DMTC1, FirstReg, TmpReg, IDLoc, STI);
3539 if (TmpReg != Mips::ZERO &&
3540 loadImmediate(
Hi_32(ImmOp64), TmpReg, MCRegister(),
true,
false, IDLoc,
3544 if (hasMips32r2()) {
3545 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3546 TOut.
emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, TmpReg, IDLoc, STI);
3548 TOut.
emitRR(Mips::MTC1,
nextReg(FirstReg), TmpReg, IDLoc, STI);
3549 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3554 MCSection *CS = getStreamer().getCurrentSectionOnly();
3557 MCSection *ReadOnlySection =
3564 getStreamer().switchSection(ReadOnlySection);
3565 getStreamer().emitLabel(Sym, IDLoc);
3566 getStreamer().emitValueToAlignment(
Align(8));
3567 getStreamer().emitIntValue(ImmOp64, 8);
3568 getStreamer().switchSection(CS);
3570 if (emitPartialAddress(TOut, IDLoc, Sym))
3573 TOut.
emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, TmpReg,
3579bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
3581 const MCSubtargetInfo *STI) {
3582 MipsTargetStreamer &TOut = getTargetStreamer();
3585 "unexpected number of operands");
3595 assert(
Offset.isImm() &&
"expected immediate operand kind");
3599 if (inMicroMipsMode())
3600 Inst.
setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3603 return Error(IDLoc,
"branch target out of range");
3605 return Error(IDLoc,
"branch to misaligned address");
3617 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
3624bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3625 const MCSubtargetInfo *STI) {
3626 MipsTargetStreamer &TOut = getTargetStreamer();
3627 const MCOperand &DstRegOp = Inst.
getOperand(0);
3628 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3631 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
3633 const MCOperand &MemOffsetOp = Inst.
getOperand(2);
3635 "expected immediate or expression operand");
3637 bool IsLikely =
false;
3647 case Mips::BEQLImmMacro:
3651 case Mips::BNELImmMacro:
3660 int64_t ImmValue = ImmOp.
getImm();
3661 if (ImmValue == 0) {
3665 TOut.
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3667 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3670 warnIfNoMacro(IDLoc);
3672 MCRegister ATReg = getATReg(IDLoc);
3676 if (loadImmediate(ImmValue, ATReg, MCRegister(), !isGP64bit(),
true, IDLoc,
3683 TOut.
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3685 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3690void MipsAsmParser::expandMem16Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3691 const MCSubtargetInfo *STI,
bool IsLoad) {
3693 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3694 unsigned StartOp = NumOp == 3 ? 0 : 1;
3696 const MCOperand &DstRegOp = Inst.
getOperand(StartOp);
3697 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3698 const MCOperand &BaseRegOp = Inst.
getOperand(StartOp + 1);
3699 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3702 MipsTargetStreamer &TOut = getTargetStreamer();
3704 MCRegister DstReg = DstRegOp.
getReg();
3706 MCRegister TmpReg = DstReg;
3708 const MCInstrDesc &
Desc = MII.get(OpCode);
3709 int16_t DstRegClass =
Desc.operands()[StartOp].RegClass;
3710 unsigned DstRegClassID =
3711 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3712 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3713 (DstRegClassID == Mips::GPR64RegClassID);
3715 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3718 TmpReg = getATReg(IDLoc);
3723 auto emitInstWithOffset = [&](
const MCOperand &
Off) {
3725 TOut.
emitRRX(OpCode, DstReg, TmpReg, Off, IDLoc, STI);
3727 TOut.
emitRRRX(OpCode, DstReg, DstReg, TmpReg, Off, IDLoc, STI);
3731 int64_t LoOffset =
OffsetOp.getImm() & 0xffff;
3732 int64_t HiOffset =
OffsetOp.getImm() & ~0xffff;
3736 if (LoOffset & 0x8000)
3737 HiOffset += 0x10000;
3739 bool IsLargeOffset = HiOffset != 0;
3741 if (IsLargeOffset) {
3743 if (loadImmediate(HiOffset, TmpReg, MCRegister(), Is32BitImm,
true, IDLoc,
3748 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3749 TOut.
emitRRR(
ABI.ArePtrs64bit() ? Mips::DADDu : Mips::ADDu, TmpReg,
3750 TmpReg, BaseReg, IDLoc, STI);
3764 if (!
OffsetOp.getExpr()->evaluateAsRelocatable(Res,
nullptr)) {
3765 Error(IDLoc,
"expected relocatable expression");
3769 Error(IDLoc,
"expected relocatable expression with only one symbol");
3773 loadAndAddSymbolAddress(
3775 BaseReg, !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3783 const MCExpr *OffExpr =
OffsetOp.getExpr();
3795 TOut.
emitRX(Mips::LUi, TmpReg, HighestOperand, IDLoc, STI);
3796 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HigherOperand, IDLoc, STI);
3797 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3798 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HiOperand, IDLoc, STI);
3799 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3800 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3801 TOut.
emitRRR(Mips::DADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3802 emitInstWithOffset(LoOperand);
3805 TOut.
emitRX(Mips::LUi, TmpReg, HiOperand, IDLoc, STI);
3806 if (BaseReg != Mips::ZERO)
3807 TOut.
emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3809 emitInstWithOffset(LoOperand);
3818void MipsAsmParser::expandMem9Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3819 const MCSubtargetInfo *STI,
bool IsLoad) {
3821 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3822 unsigned StartOp = NumOp == 3 ? 0 : 1;
3824 const MCOperand &DstRegOp = Inst.
getOperand(StartOp);
3825 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3826 const MCOperand &BaseRegOp = Inst.
getOperand(StartOp + 1);
3827 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3830 MipsTargetStreamer &TOut = getTargetStreamer();
3832 MCRegister DstReg = DstRegOp.
getReg();
3834 MCRegister TmpReg = DstReg;
3836 const MCInstrDesc &
Desc = MII.get(OpCode);
3837 int16_t DstRegClass =
Desc.operands()[StartOp].RegClass;
3838 unsigned DstRegClassID =
3839 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3840 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3841 (DstRegClassID == Mips::GPR64RegClassID);
3843 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3846 TmpReg = getATReg(IDLoc);
3851 auto emitInst = [&]() {
3860 loadImmediate(
OffsetOp.getImm(), TmpReg, BaseReg, !
ABI.ArePtrs64bit(),
true,
3867 loadAndAddSymbolAddress(
OffsetOp.getExpr(), TmpReg, BaseReg,
3868 !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3876bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
3878 const MCSubtargetInfo *STI) {
3881 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3885 Inst.
getOperand(OpNum - 3).
isReg() &&
"Invalid instruction operand.");
3894 if (inMicroMipsMode() && hasMips32r6())
3895 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3897 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3905bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
3907 const MCSubtargetInfo *STI) {
3908 MipsTargetStreamer &TOut = getTargetStreamer();
3909 bool EmittedNoMacroWarning =
false;
3910 unsigned PseudoOpcode = Inst.
getOpcode();
3915 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3916 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3921 else if (TrgOp.
isImm()) {
3922 warnIfNoMacro(IDLoc);
3923 EmittedNoMacroWarning =
true;
3925 TrgReg = getATReg(IDLoc);
3929 switch(PseudoOpcode) {
3932 case Mips::BLTImmMacro:
3933 PseudoOpcode = Mips::BLT;
3935 case Mips::BLEImmMacro:
3936 PseudoOpcode = Mips::BLE;
3938 case Mips::BGEImmMacro:
3939 PseudoOpcode = Mips::BGE;
3941 case Mips::BGTImmMacro:
3942 PseudoOpcode = Mips::BGT;
3944 case Mips::BLTUImmMacro:
3945 PseudoOpcode = Mips::BLTU;
3947 case Mips::BLEUImmMacro:
3948 PseudoOpcode = Mips::BLEU;
3950 case Mips::BGEUImmMacro:
3951 PseudoOpcode = Mips::BGEU;
3953 case Mips::BGTUImmMacro:
3954 PseudoOpcode = Mips::BGTU;
3956 case Mips::BLTLImmMacro:
3957 PseudoOpcode = Mips::BLTL;
3959 case Mips::BLELImmMacro:
3960 PseudoOpcode = Mips::BLEL;
3962 case Mips::BGELImmMacro:
3963 PseudoOpcode = Mips::BGEL;
3965 case Mips::BGTLImmMacro:
3966 PseudoOpcode = Mips::BGTL;
3968 case Mips::BLTULImmMacro:
3969 PseudoOpcode = Mips::BLTUL;
3971 case Mips::BLEULImmMacro:
3972 PseudoOpcode = Mips::BLEUL;
3974 case Mips::BGEULImmMacro:
3975 PseudoOpcode = Mips::BGEUL;
3977 case Mips::BGTULImmMacro:
3978 PseudoOpcode = Mips::BGTUL;
3982 if (loadImmediate(TrgOp.
getImm(), TrgReg, MCRegister(), !isGP64bit(),
false,
3987 switch (PseudoOpcode) {
3992 AcceptsEquality =
false;
3993 ReverseOrderSLT =
false;
3995 ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
3996 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
3997 ZeroSrcOpcode = Mips::BGTZ;
3998 ZeroTrgOpcode = Mips::BLTZ;
4004 AcceptsEquality =
true;
4005 ReverseOrderSLT =
true;
4007 ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
4008 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
4009 ZeroSrcOpcode = Mips::BGEZ;
4010 ZeroTrgOpcode = Mips::BLEZ;
4016 AcceptsEquality =
true;
4017 ReverseOrderSLT =
false;
4019 ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
4020 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
4021 ZeroSrcOpcode = Mips::BLEZ;
4022 ZeroTrgOpcode = Mips::BGEZ;
4028 AcceptsEquality =
false;
4029 ReverseOrderSLT =
true;
4031 ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
4032 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
4033 ZeroSrcOpcode = Mips::BLTZ;
4034 ZeroTrgOpcode = Mips::BGTZ;
4040 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
4041 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
4042 if (IsSrcRegZero && IsTrgRegZero) {
4046 if (PseudoOpcode == Mips::BLT) {
4051 if (PseudoOpcode == Mips::BLE) {
4054 Warning(IDLoc,
"branch is always taken");
4057 if (PseudoOpcode == Mips::BGE) {
4060 Warning(IDLoc,
"branch is always taken");
4063 if (PseudoOpcode == Mips::BGT) {
4068 if (PseudoOpcode == Mips::BGTU) {
4069 TOut.
emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
4073 if (AcceptsEquality) {
4076 TOut.
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4078 Warning(IDLoc,
"branch is always taken");
4085 if (IsSrcRegZero || IsTrgRegZero) {
4086 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
4087 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
4094 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
4095 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
4101 TOut.
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4103 Warning(IDLoc,
"branch is always taken");
4119 TOut.
emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
4120 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
4127 TOut.
emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
4128 IsSrcRegZero ? TrgReg : SrcReg,
4135 MCRegister ATRegNum = getATReg(IDLoc);
4139 if (!EmittedNoMacroWarning)
4140 warnIfNoMacro(IDLoc);
4157 TOut.
emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
4158 ReverseOrderSLT ? TrgReg : SrcReg,
4159 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
4161 TOut.
emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
4162 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
4176bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4177 const MCSubtargetInfo *STI,
4178 const bool IsMips64,
const bool Signed) {
4179 MipsTargetStreamer &TOut = getTargetStreamer();
4181 warnIfNoMacro(IDLoc);
4183 const MCOperand &RdRegOp = Inst.
getOperand(0);
4184 assert(RdRegOp.
isReg() &&
"expected register operand kind");
4185 MCRegister RdReg = RdRegOp.
getReg();
4187 const MCOperand &RsRegOp = Inst.
getOperand(1);
4188 assert(RsRegOp.
isReg() &&
"expected register operand kind");
4189 MCRegister RsReg = RsRegOp.
getReg();
4196 "expected register or immediate operand kind");
4200 ImmValue = RtOp.
getImm();
4207 DivOp =
Signed ? Mips::DSDIV : Mips::DUDIV;
4208 ZeroReg = Mips::ZERO_64;
4211 DivOp =
Signed ? Mips::SDIV : Mips::UDIV;
4212 ZeroReg = Mips::ZERO;
4216 bool UseTraps = useTraps();
4219 bool isDiv = Opcode == Mips::SDivMacro || Opcode == Mips::SDivIMacro ||
4220 Opcode == Mips::UDivMacro || Opcode == Mips::UDivIMacro ||
4221 Opcode == Mips::DSDivMacro || Opcode == Mips::DSDivIMacro ||
4222 Opcode == Mips::DUDivMacro || Opcode == Mips::DUDivIMacro;
4224 bool isRem = Opcode == Mips::SRemMacro || Opcode == Mips::SRemIMacro ||
4225 Opcode == Mips::URemMacro || Opcode == Mips::URemIMacro ||
4226 Opcode == Mips::DSRemMacro || Opcode == Mips::DSRemIMacro ||
4227 Opcode == Mips::DURemMacro || Opcode == Mips::DURemIMacro;
4230 MCRegister ATReg = getATReg(IDLoc);
4234 if (ImmValue == 0) {
4236 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4238 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4242 if (isRem && (ImmValue == 1 || (
Signed && (ImmValue == -1)))) {
4243 TOut.
emitRRR(Mips::OR, RdReg, ZeroReg, ZeroReg, IDLoc, STI);
4245 }
else if (isDiv && ImmValue == 1) {
4246 TOut.
emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI);
4248 }
else if (isDiv &&
Signed && ImmValue == -1) {
4249 TOut.
emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
4252 if (loadImmediate(ImmValue, ATReg, MCRegister(),
isInt<32>(ImmValue),
4253 false, Inst.
getLoc(), Out, STI))
4255 TOut.
emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
4256 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4266 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
4268 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4271 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4277 if (isRem && (RdReg == Mips::ZERO || RdReg == Mips::ZERO_64)) {
4278 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4288 TOut.
emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4291 BrTarget =
Context.createTempSymbol();
4293 TOut.
emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4296 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4299 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4305 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4309 MCRegister ATReg = getATReg(IDLoc);
4316 TOut.
emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
4320 MCOperand LabelOpEnd =
4324 TOut.
emitRRX(Mips::BNE, RtReg, ATReg, LabelOpEnd, IDLoc, STI);
4327 TOut.
emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
4328 TOut.
emitDSLL(ATReg, ATReg, 63, IDLoc, STI);
4330 TOut.
emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, STI);
4334 TOut.
emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
4337 TOut.
emitRRX(Mips::BNE, RsReg, ATReg, LabelOpEnd, IDLoc, STI);
4339 TOut.
emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
4343 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4347bool MipsAsmParser::expandTrunc(MCInst &Inst,
bool IsDouble,
bool Is64FPU,
4348 SMLoc IDLoc, MCStreamer &Out,
4349 const MCSubtargetInfo *STI) {
4350 MipsTargetStreamer &TOut = getTargetStreamer();
4360 if (hasMips1() && !hasMips2()) {
4361 MCRegister ATReg = getATReg(IDLoc);
4364 TOut.
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4365 TOut.
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4367 TOut.
emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4368 TOut.
emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4369 TOut.
emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4371 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4373 FirstReg, SecondReg, IDLoc, STI);
4374 TOut.
emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4379 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4381 FirstReg, SecondReg, IDLoc, STI);
4386bool MipsAsmParser::expandUlh(MCInst &Inst,
bool Signed, SMLoc IDLoc,
4387 MCStreamer &Out,
const MCSubtargetInfo *STI) {
4388 if (hasMips32r6() || hasMips64r6()) {
4389 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4392 const MCOperand &DstRegOp = Inst.
getOperand(0);
4393 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4394 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4395 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4396 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4397 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4399 MipsTargetStreamer &TOut = getTargetStreamer();
4400 MCRegister DstReg = DstRegOp.
getReg();
4401 MCRegister SrcReg = SrcRegOp.
getReg();
4402 int64_t OffsetValue = OffsetImmOp.
getImm();
4406 warnIfNoMacro(IDLoc);
4407 MCRegister ATReg = getATReg(IDLoc);
4412 if (IsLargeOffset) {
4413 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4418 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4419 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4423 MCRegister FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4424 MCRegister SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4426 MCRegister LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4427 MCRegister SllReg = IsLargeOffset ? DstReg : ATReg;
4429 TOut.
emitRRI(
Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4430 FirstOffset, IDLoc, STI);
4431 TOut.
emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4432 TOut.
emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4433 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4438bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4439 const MCSubtargetInfo *STI) {
4440 if (hasMips32r6() || hasMips64r6()) {
4441 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4444 const MCOperand &DstRegOp = Inst.
getOperand(0);
4445 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4446 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4447 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4448 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4449 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4451 MipsTargetStreamer &TOut = getTargetStreamer();
4452 MCRegister DstReg = DstRegOp.
getReg();
4453 MCRegister SrcReg = SrcRegOp.
getReg();
4454 int64_t OffsetValue = OffsetImmOp.
getImm();
4456 warnIfNoMacro(IDLoc);
4457 MCRegister ATReg = getATReg(IDLoc);
4462 if (IsLargeOffset) {
4463 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4468 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4469 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4473 if (IsLargeOffset) {
4474 TOut.
emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4475 TOut.
emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4476 TOut.
emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4477 TOut.
emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4478 TOut.
emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4479 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4481 TOut.
emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4482 TOut.
emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4483 TOut.
emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4489bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4490 const MCSubtargetInfo *STI) {
4491 if (hasMips32r6() || hasMips64r6()) {
4492 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4495 const MCOperand &DstRegOp = Inst.
getOperand(0);
4496 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4497 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4498 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4499 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4500 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4502 MipsTargetStreamer &TOut = getTargetStreamer();
4503 MCRegister DstReg = DstRegOp.
getReg();
4504 MCRegister SrcReg = SrcRegOp.
getReg();
4505 int64_t OffsetValue = OffsetImmOp.
getImm();
4509 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4510 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4514 bool IsLoadInst = (Inst.
getOpcode() == Mips::Ulw);
4515 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4516 MCRegister TmpReg = SrcReg;
4517 if (IsLargeOffset || DoMove) {
4518 warnIfNoMacro(IDLoc);
4519 TmpReg = getATReg(IDLoc);
4524 if (IsLargeOffset) {
4525 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4533 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4534 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4535 TOut.
emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4536 TOut.
emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4539 TOut.
emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4544bool MipsAsmParser::expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4545 const MCSubtargetInfo *STI) {
4546 MipsTargetStreamer &TOut = getTargetStreamer();
4558 warnIfNoMacro(IDLoc);
4572 TOut.
emitRRR(OpCode, DstReg, SrcReg, OpReg, IDLoc, STI);
4573 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4578bool MipsAsmParser::expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4579 const MCSubtargetInfo *STI) {
4580 MipsTargetStreamer &TOut = getTargetStreamer();
4590 unsigned OpRegCode, OpImmCode;
4592 warnIfNoMacro(IDLoc);
4596 case Mips::SGEImm64:
4597 OpRegCode = Mips::SLT;
4598 OpImmCode = Mips::SLTi;
4601 case Mips::SGEUImm64:
4602 OpRegCode = Mips::SLTu;
4603 OpImmCode = Mips::SLTiu;
4612 TOut.
emitRRI(OpImmCode, DstReg, SrcReg, ImmValue, IDLoc, STI);
4613 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4615 MCRegister ImmReg = DstReg;
4616 if (DstReg == SrcReg) {
4617 MCRegister ATReg = getATReg(Inst.
getLoc());
4623 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
4624 false, IDLoc, Out, STI))
4627 TOut.
emitRRR(OpRegCode, DstReg, SrcReg, ImmReg, IDLoc, STI);
4628 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4634bool MipsAsmParser::expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4635 const MCSubtargetInfo *STI) {
4636 MipsTargetStreamer &TOut = getTargetStreamer();
4645 MCRegister ImmReg = DstReg;
4649 warnIfNoMacro(IDLoc);
4653 case Mips::SGTImm64:
4657 case Mips::SGTUImm64:
4664 if (DstReg == SrcReg) {
4665 MCRegister ATReg = getATReg(Inst.
getLoc());
4671 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
false,
4676 TOut.
emitRRR(OpCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4681bool MipsAsmParser::expandSle(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4682 const MCSubtargetInfo *STI) {
4683 MipsTargetStreamer &TOut = getTargetStreamer();
4695 warnIfNoMacro(IDLoc);
4709 TOut.
emitRRR(OpCode, DstReg, OpReg, SrcReg, IDLoc, STI);
4710 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4715bool MipsAsmParser::expandSleImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4716 const MCSubtargetInfo *STI) {
4717 MipsTargetStreamer &TOut = getTargetStreamer();
4729 warnIfNoMacro(IDLoc);
4733 case Mips::SLEImm64:
4734 OpRegCode = Mips::SLT;
4737 case Mips::SLEUImm64:
4738 OpRegCode = Mips::SLTu;
4745 MCRegister ImmReg = DstReg;
4746 if (DstReg == SrcReg) {
4747 MCRegister ATReg = getATReg(Inst.
getLoc());
4753 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
false,
4757 TOut.
emitRRR(OpRegCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4758 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4763bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
4765 const MCSubtargetInfo *STI) {
4766 MipsTargetStreamer &TOut = getTargetStreamer();
4774 MCRegister FinalDstReg;
4781 unsigned FinalOpcode = Inst.
getOpcode();
4783 if (DstReg == SrcReg) {
4784 ATReg = getATReg(Inst.
getLoc());
4787 FinalDstReg = DstReg;
4791 if (!loadImmediate(ImmValue, DstReg, MCRegister(), Is32Bit,
false,
4792 Inst.
getLoc(), Out, STI)) {
4793 switch (FinalOpcode) {
4797 FinalOpcode = Mips::ADD;
4800 FinalOpcode = Mips::ADDu;
4803 FinalOpcode = Mips::AND;
4806 FinalOpcode = Mips::NOR;
4809 FinalOpcode = Mips::OR;
4812 FinalOpcode = Mips::SLT;
4815 FinalOpcode = Mips::SLTu;
4818 FinalOpcode = Mips::XOR;
4821 FinalOpcode = Mips::ADD_MM;
4823 case Mips::ADDiu_MM:
4824 FinalOpcode = Mips::ADDu_MM;
4827 FinalOpcode = Mips::AND_MM;
4830 FinalOpcode = Mips::OR_MM;
4833 FinalOpcode = Mips::SLT_MM;
4835 case Mips::SLTiu_MM:
4836 FinalOpcode = Mips::SLTu_MM;
4839 FinalOpcode = Mips::XOR_MM;
4842 FinalOpcode = Mips::AND64;
4844 case Mips::NORImm64:
4845 FinalOpcode = Mips::NOR64;
4848 FinalOpcode = Mips::OR64;
4850 case Mips::SLTImm64:
4851 FinalOpcode = Mips::SLT64;
4853 case Mips::SLTUImm64:
4854 FinalOpcode = Mips::SLTu64;
4857 FinalOpcode = Mips::XOR64;
4862 TOut.
emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4864 TOut.
emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4870bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4871 const MCSubtargetInfo *STI) {
4872 MipsTargetStreamer &TOut = getTargetStreamer();
4877 MCRegister TmpReg =
DReg;
4879 unsigned FirstShift = Mips::NOP;
4880 unsigned SecondShift = Mips::NOP;
4882 if (hasMips32r2()) {
4884 TmpReg = getATReg(Inst.
getLoc());
4890 TOut.
emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4891 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
4896 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
4908 FirstShift = Mips::SRLV;
4909 SecondShift = Mips::SLLV;
4912 FirstShift = Mips::SLLV;
4913 SecondShift = Mips::SRLV;
4917 ATReg = getATReg(Inst.
getLoc());
4921 TOut.
emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4922 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
4923 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
4924 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
4932bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
4934 const MCSubtargetInfo *STI) {
4935 MipsTargetStreamer &TOut = getTargetStreamer();
4941 unsigned FirstShift = Mips::NOP;
4942 unsigned SecondShift = Mips::NOP;
4944 if (hasMips32r2()) {
4946 uint64_t MaxShift = 32;
4947 uint64_t ShiftValue = ImmValue;
4949 ShiftValue = MaxShift - ImmValue;
4950 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
4955 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.
getLoc(), STI);
4963 if (ImmValue == 0) {
4972 FirstShift = Mips::SLL;
4973 SecondShift = Mips::SRL;
4976 FirstShift = Mips::SRL;
4977 SecondShift = Mips::SLL;
4981 ATReg = getATReg(Inst.
getLoc());
4985 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.
getLoc(), STI);
4986 TOut.
emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.
getLoc(), STI);
4987 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
4995bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4996 const MCSubtargetInfo *STI) {
4997 MipsTargetStreamer &TOut = getTargetStreamer();
5002 MCRegister TmpReg =
DReg;
5004 unsigned FirstShift = Mips::NOP;
5005 unsigned SecondShift = Mips::NOP;
5007 if (hasMips64r2()) {
5008 if (TmpReg == SReg) {
5009 TmpReg = getATReg(Inst.
getLoc());
5015 TOut.
emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
5016 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
5021 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
5033 FirstShift = Mips::DSRLV;
5034 SecondShift = Mips::DSLLV;
5037 FirstShift = Mips::DSLLV;
5038 SecondShift = Mips::DSRLV;
5042 ATReg = getATReg(Inst.
getLoc());
5046 TOut.
emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
5047 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
5048 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
5049 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5057bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
5059 const MCSubtargetInfo *STI) {
5060 MipsTargetStreamer &TOut = getTargetStreamer();
5066 unsigned FirstShift = Mips::NOP;
5067 unsigned SecondShift = Mips::NOP;
5071 if (hasMips64r2()) {
5072 unsigned FinalOpcode = Mips::NOP;
5074 FinalOpcode = Mips::DROTR;
5075 else if (ImmValue % 32 == 0)
5076 FinalOpcode = Mips::DROTR32;
5077 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
5079 FinalOpcode = Mips::DROTR32;
5081 FinalOpcode = Mips::DROTR;
5082 }
else if (ImmValue >= 33) {
5084 FinalOpcode = Mips::DROTR;
5086 FinalOpcode = Mips::DROTR32;
5089 uint64_t ShiftValue = ImmValue % 32;
5091 ShiftValue = (32 - ImmValue % 32) % 32;
5093 TOut.
emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
5099 if (ImmValue == 0) {
5100 TOut.
emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.
getLoc(), STI);
5108 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5109 FirstShift = Mips::DSLL;
5110 SecondShift = Mips::DSRL32;
5112 if (ImmValue == 32) {
5113 FirstShift = Mips::DSLL32;
5114 SecondShift = Mips::DSRL32;
5116 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5117 FirstShift = Mips::DSLL32;
5118 SecondShift = Mips::DSRL;
5122 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5123 FirstShift = Mips::DSRL;
5124 SecondShift = Mips::DSLL32;
5126 if (ImmValue == 32) {
5127 FirstShift = Mips::DSRL32;
5128 SecondShift = Mips::DSLL32;
5130 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5131 FirstShift = Mips::DSRL32;
5132 SecondShift = Mips::DSLL;
5137 ATReg = getATReg(Inst.
getLoc());
5141 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.
getLoc(), STI);
5142 TOut.
emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
5144 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5152bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5153 const MCSubtargetInfo *STI) {
5154 MipsTargetStreamer &TOut = getTargetStreamer();
5158 TOut.
emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
5159 if (FirstRegOp != SecondRegOp)
5160 TOut.
emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
5163 TOut.
emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
5168bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5169 const MCSubtargetInfo *STI) {
5170 MipsTargetStreamer &TOut = getTargetStreamer();
5176 ATReg = getATReg(IDLoc);
5180 loadImmediate(ImmValue, ATReg, MCRegister(),
true,
false, IDLoc, Out, STI);
5182 TOut.
emitRR(Inst.
getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
5183 SrcReg, ATReg, IDLoc, STI);
5185 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5190bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5191 const MCSubtargetInfo *STI) {
5192 MipsTargetStreamer &TOut = getTargetStreamer();
5198 ATReg = getATReg(Inst.
getLoc());
5202 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
5203 SrcReg, TmpReg, IDLoc, STI);
5205 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5207 TOut.
emitRRI(Inst.
getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
5208 DstReg, DstReg, 0x1F, IDLoc, STI);
5210 TOut.
emitR(Mips::MFHI, ATReg, IDLoc, STI);
5213 TOut.
emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
5220 TOut.
emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
5221 if (AssemblerOptions.
back()->isReorder())
5223 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5227 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5232bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5233 const MCSubtargetInfo *STI) {
5234 MipsTargetStreamer &TOut = getTargetStreamer();
5240 ATReg = getATReg(IDLoc);
5244 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
5245 SrcReg, TmpReg, IDLoc, STI);
5247 TOut.
emitR(Mips::MFHI, ATReg, IDLoc, STI);
5248 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5250 TOut.
emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);
5257 TOut.
emitRRX(Mips::BEQ, ATReg, Mips::ZERO, LabelOp, IDLoc, STI);
5258 if (AssemblerOptions.
back()->isReorder())
5260 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5268bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5269 const MCSubtargetInfo *STI) {
5270 MipsTargetStreamer &TOut = getTargetStreamer();
5275 TOut.
emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
5276 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5286bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
5288 const MCSubtargetInfo *STI,
5293 warnIfNoMacro(IDLoc);
5295 MipsTargetStreamer &TOut = getTargetStreamer();
5296 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
5298 MCRegister SecondReg =
nextReg(FirstReg);
5303 warnIfRegIndexIsAT(FirstReg, IDLoc);
5306 "Offset for load macro is not immediate!");
5309 signed NextOffset = FirstOffset.
getImm() + 4;
5317 if (FirstReg != BaseReg || !IsLoad) {
5318 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5319 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5321 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5322 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5334bool MipsAsmParser::expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc,
5336 const MCSubtargetInfo *STI) {
5340 warnIfNoMacro(IDLoc);
5342 MipsTargetStreamer &TOut = getTargetStreamer();
5343 unsigned Opcode = Mips::SWC1;
5345 MCRegister SecondReg =
nextReg(FirstReg);
5350 warnIfRegIndexIsAT(FirstReg, IDLoc);
5353 "Offset for macro is not immediate!");
5356 signed NextOffset = FirstOffset.
getImm() + 4;
5362 if (!IsLittleEndian)
5365 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5366 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5371bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5372 const MCSubtargetInfo *STI) {
5373 MipsTargetStreamer &TOut = getTargetStreamer();
5384 warnIfNoMacro(IDLoc);
5386 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5387 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5388 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5392 MCRegister
Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5393 TOut.
emitRRI(Mips::SLTiu, DstReg,
Reg, 1, IDLoc, STI);
5397bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5398 const MCSubtargetInfo *STI) {
5399 MipsTargetStreamer &TOut = getTargetStreamer();
5410 warnIfNoMacro(IDLoc);
5413 TOut.
emitRRI(Mips::SLTiu, DstReg, SrcReg, 1, IDLoc, STI);
5417 if (SrcReg == Mips::ZERO) {
5418 Warning(IDLoc,
"comparison is always false");
5419 TOut.
emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
5420 DstReg, SrcReg, SrcReg, IDLoc, STI);
5425 if (Imm > -0x8000 && Imm < 0) {
5427 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5433 MCRegister ATReg = getATReg(IDLoc);
5437 if (loadImmediate(Imm, ATReg, MCRegister(),
true, isGP64bit(), IDLoc, Out,
5441 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5442 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5446 TOut.
emitRRI(
Opc, DstReg, SrcReg, Imm, IDLoc, STI);
5447 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5451bool MipsAsmParser::expandSne(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5452 const MCSubtargetInfo *STI) {
5454 MipsTargetStreamer &TOut = getTargetStreamer();
5465 warnIfNoMacro(IDLoc);
5467 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5468 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5469 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5473 MCRegister
Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5474 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO,
Reg, IDLoc, STI);
5478bool MipsAsmParser::expandSneI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5479 const MCSubtargetInfo *STI) {
5480 MipsTargetStreamer &TOut = getTargetStreamer();
5491 warnIfNoMacro(IDLoc);
5493 if (ImmValue == 0) {
5494 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, SrcReg, IDLoc, STI);
5498 if (SrcReg == Mips::ZERO) {
5499 Warning(IDLoc,
"comparison is always true");
5500 if (loadImmediate(1, DstReg, MCRegister(),
true,
false, IDLoc, Out, STI))
5506 if (ImmValue > -0x8000 && ImmValue < 0) {
5507 ImmValue = -ImmValue;
5508 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5514 TOut.
emitRRI(
Opc, DstReg, SrcReg, ImmValue, IDLoc, STI);
5515 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5519 MCRegister ATReg = getATReg(IDLoc);
5523 if (loadImmediate(ImmValue, ATReg, MCRegister(),
isInt<32>(ImmValue),
false,
5527 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5528 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5591 case Mips::F0:
return Mips::ZERO;
5592 case Mips::F1:
return Mips::AT;
5593 case Mips::F2:
return Mips::V0;
5594 case Mips::F3:
return Mips::V1;
5595 case Mips::F4:
return Mips::A0;
5596 case Mips::F5:
return Mips::A1;
5597 case Mips::F6:
return Mips::A2;
5598 case Mips::F7:
return Mips::A3;
5599 case Mips::F8:
return Mips::T0;
5600 case Mips::F9:
return Mips::T1;
5601 case Mips::F10:
return Mips::T2;
5602 case Mips::F11:
return Mips::T3;
5603 case Mips::F12:
return Mips::T4;
5604 case Mips::F13:
return Mips::T5;
5605 case Mips::F14:
return Mips::T6;
5606 case Mips::F15:
return Mips::T7;
5607 case Mips::F16:
return Mips::S0;
5608 case Mips::F17:
return Mips::S1;
5609 case Mips::F18:
return Mips::S2;
5610 case Mips::F19:
return Mips::S3;
5611 case Mips::F20:
return Mips::S4;
5612 case Mips::F21:
return Mips::S5;
5613 case Mips::F22:
return Mips::S6;
5614 case Mips::F23:
return Mips::S7;
5615 case Mips::F24:
return Mips::T8;
5616 case Mips::F25:
return Mips::T9;
5617 case Mips::F26:
return Mips::K0;
5618 case Mips::F27:
return Mips::K1;
5619 case Mips::F28:
return Mips::GP;
5620 case Mips::F29:
return Mips::SP;
5621 case Mips::F30:
return Mips::FP;
5622 case Mips::F31:
return Mips::RA;
5630 case Mips::COP00:
return Mips::ZERO;
5631 case Mips::COP01:
return Mips::AT;
5632 case Mips::COP02:
return Mips::V0;
5633 case Mips::COP03:
return Mips::V1;
5634 case Mips::COP04:
return Mips::A0;
5635 case Mips::COP05:
return Mips::A1;
5636 case Mips::COP06:
return Mips::A2;
5637 case Mips::COP07:
return Mips::A3;
5638 case Mips::COP08:
return Mips::T0;
5639 case Mips::COP09:
return Mips::T1;
5640 case Mips::COP010:
return Mips::T2;
5641 case Mips::COP011:
return Mips::T3;
5642 case Mips::COP012:
return Mips::T4;
5643 case Mips::COP013:
return Mips::T5;
5644 case Mips::COP014:
return Mips::T6;
5645 case Mips::COP015:
return Mips::T7;
5646 case Mips::COP016:
return Mips::S0;
5647 case Mips::COP017:
return Mips::S1;
5648 case Mips::COP018:
return Mips::S2;
5649 case Mips::COP019:
return Mips::S3;
5650 case Mips::COP020:
return Mips::S4;
5651 case Mips::COP021:
return Mips::S5;
5652 case Mips::COP022:
return Mips::S6;
5653 case Mips::COP023:
return Mips::S7;
5654 case Mips::COP024:
return Mips::T8;
5655 case Mips::COP025:
return Mips::T9;
5656 case Mips::COP026:
return Mips::K0;
5657 case Mips::COP027:
return Mips::K1;
5658 case Mips::COP028:
return Mips::GP;
5659 case Mips::COP029:
return Mips::SP;
5660 case Mips::COP030:
return Mips::FP;
5661 case Mips::COP031:
return Mips::RA;
5668bool MipsAsmParser::expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5669 const MCSubtargetInfo *STI) {
5670 MipsTargetStreamer &TOut = getTargetStreamer();
5675 bool IsMFTR =
false;
5729 IsMFTR ? MCRegister(rd)
5731 : Inst.getOperand(0).
getReg());
5733 TOut.
emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, u, sel, h, IDLoc,
5738bool MipsAsmParser::expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5739 const MCSubtargetInfo *STI) {
5744 warnIfNoMacro(IDLoc);
5746 MipsTargetStreamer &TOut = getTargetStreamer();
5747 unsigned Opcode = Inst.
getOpcode() == Mips::SaaAddr ? Mips::SAA : Mips::SAAD;
5750 const MCOperand &BaseOp = Inst.
getOperand(2);
5752 if (BaseOp.
isImm()) {
5753 int64_t ImmValue = BaseOp.
getImm();
5754 if (ImmValue == 0) {
5755 TOut.
emitRR(Opcode, RtReg, BaseReg, IDLoc, STI);
5760 MCRegister ATReg = getATReg(IDLoc);
5764 if (expandLoadAddress(ATReg, BaseReg, BaseOp, !isGP64bit(), IDLoc, Out, STI))
5767 TOut.
emitRR(Opcode, RtReg, ATReg, IDLoc, STI);
5772MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
5776 return Match_Success;
5779 if (
static_cast<MipsOperand &
>(*
Operands[1])
5780 .isValidForTie(
static_cast<MipsOperand &
>(*
Operands[2])))
5781 return Match_Success;
5782 return Match_RequiresSameSrcAndDst;
5786unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
5793 return Match_RequiresNoZeroRegister;
5794 return Match_Success;
5800 case Mips::JALR_HB64:
5801 case Mips::JALRC_HB_MMR6:
5802 case Mips::JALRC_MMR6:
5804 return Match_RequiresDifferentSrcAndDst;
5805 return Match_Success;
5808 return Match_RequiresDifferentSrcAndDst;
5809 return Match_Success;
5812 return Match_NonZeroOperandForSync;
5813 return Match_Success;
5819 return Match_NonZeroOperandForMTCX;
5820 return Match_Success;
5833 case Mips::BLEZC:
case Mips::BLEZC_MMR6:
5834 case Mips::BGEZC:
case Mips::BGEZC_MMR6:
5835 case Mips::BGTZC:
case Mips::BGTZC_MMR6:
5836 case Mips::BLTZC:
case Mips::BLTZC_MMR6:
5837 case Mips::BEQZC:
case Mips::BEQZC_MMR6:
5838 case Mips::BNEZC:
case Mips::BNEZC_MMR6:
5847 return Match_RequiresNoZeroRegister;
5848 return Match_Success;
5849 case Mips::BGEC:
case Mips::BGEC_MMR6:
5850 case Mips::BLTC:
case Mips::BLTC_MMR6:
5851 case Mips::BGEUC:
case Mips::BGEUC_MMR6:
5852 case Mips::BLTUC:
case Mips::BLTUC_MMR6:
5853 case Mips::BEQC:
case Mips::BEQC_MMR6:
5854 case Mips::BNEC:
case Mips::BNEC_MMR6:
5863 return Match_RequiresNoZeroRegister;
5866 return Match_RequiresNoZeroRegister;
5868 return Match_RequiresDifferentOperands;
5869 return Match_Success;
5872 "Operands must be immediates for dins!");
5875 if ((0 > (Pos +
Size)) || ((Pos +
Size) > 32))
5876 return Match_RequiresPosSizeRange0_32;
5877 return Match_Success;
5882 "Operands must be immediates for dinsm/dinsu!");
5885 if ((32 >= (Pos +
Size)) || ((Pos +
Size) > 64))
5886 return Match_RequiresPosSizeRange33_64;
5887 return Match_Success;
5891 "Operands must be immediates for DEXTM!");
5894 if ((1 > (Pos +
Size)) || ((Pos +
Size) > 63))
5895 return Match_RequiresPosSizeUImm6;
5896 return Match_Success;
5901 "Operands must be immediates for dextm/dextu!");
5904 if ((32 > (Pos +
Size)) || ((Pos +
Size) > 64))
5905 return Match_RequiresPosSizeRange33_64;
5906 return Match_Success;
5908 case Mips::CRC32B:
case Mips::CRC32CB:
5909 case Mips::CRC32H:
case Mips::CRC32CH:
5910 case Mips::CRC32W:
case Mips::CRC32CW:
5911 case Mips::CRC32D:
case Mips::CRC32CD:
5913 return Match_RequiresSameSrcAndDst;
5914 return Match_Success;
5917 uint64_t TSFlags = MII.get(Inst.
getOpcode()).TSFlags;
5920 return Match_NoFCCRegisterForCurrentISA;
5922 return Match_Success;
5930 if (ErrorLoc ==
SMLoc())
5937bool MipsAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
5940 uint64_t &ErrorInfo,
5941 bool MatchingInlineAsm) {
5943 unsigned MatchResult =
5944 MatchInstructionImpl(
Operands, Inst, ErrorInfo, MatchingInlineAsm);
5946 switch (MatchResult) {
5948 if (processInstruction(Inst, IDLoc, Out, STI))
5951 case Match_MissingFeature:
5952 Error(IDLoc,
"instruction requires a CPU feature not currently enabled");
5954 case Match_InvalidTiedOperand:
5955 Error(IDLoc,
"operand must match destination register");
5957 case Match_InvalidOperand: {
5958 SMLoc ErrorLoc = IDLoc;
5959 if (ErrorInfo != ~0ULL) {
5961 return Error(IDLoc,
"too few operands for instruction");
5963 ErrorLoc =
Operands[ErrorInfo]->getStartLoc();
5964 if (ErrorLoc == SMLoc())
5968 return Error(ErrorLoc,
"invalid operand for instruction");
5970 case Match_NonZeroOperandForSync:
5972 "s-type must be zero or unspecified for pre-MIPS32 ISAs");
5973 case Match_NonZeroOperandForMTCX:
5974 return Error(IDLoc,
"selector must be zero for pre-MIPS32 ISAs");
5975 case Match_MnemonicFail:
5976 return Error(IDLoc,
"invalid instruction");
5977 case Match_RequiresDifferentSrcAndDst:
5978 return Error(IDLoc,
"source and destination must be different");
5979 case Match_RequiresDifferentOperands:
5980 return Error(IDLoc,
"registers must be different");
5981 case Match_RequiresNoZeroRegister:
5982 return Error(IDLoc,
"invalid operand ($zero) for instruction");
5983 case Match_RequiresSameSrcAndDst:
5984 return Error(IDLoc,
"source and destination must match");
5985 case Match_NoFCCRegisterForCurrentISA:
5987 "non-zero fcc register doesn't exist in current ISA level");
5992 "expected 1-bit unsigned immediate");
5995 "expected 2-bit unsigned immediate");
5998 "expected immediate in range 1 .. 4");
6001 "expected 3-bit unsigned immediate");
6004 "expected 4-bit unsigned immediate");
6007 "expected 4-bit signed immediate");
6010 "expected 5-bit unsigned immediate");
6013 "expected 5-bit signed immediate");
6016 "expected immediate in range 1 .. 32");
6017 case Match_UImm5_32:
6019 "expected immediate in range 32 .. 63");
6020 case Match_UImm5_33:
6022 "expected immediate in range 33 .. 64");
6023 case Match_UImm5_0_Report_UImm6:
6027 "expected 6-bit unsigned immediate");
6028 case Match_UImm5_Lsl2:
6030 "expected both 7-bit unsigned immediate and multiple of 4");
6031 case Match_UImmRange2_64:
6033 "expected immediate in range 2 .. 64");
6036 "expected 6-bit unsigned immediate");
6037 case Match_UImm6_Lsl2:
6039 "expected both 8-bit unsigned immediate and multiple of 4");
6042 "expected 6-bit signed immediate");
6045 "expected 7-bit unsigned immediate");
6046 case Match_UImm7_N1:
6048 "expected immediate in range -1 .. 126");
6049 case Match_SImm7_Lsl2:
6051 "expected both 9-bit signed immediate and multiple of 4");
6054 "expected 8-bit unsigned immediate");
6055 case Match_UImm10_0:
6057 "expected 10-bit unsigned immediate");
6058 case Match_SImm10_0:
6060 "expected 10-bit signed immediate");
6061 case Match_SImm11_0:
6063 "expected 11-bit signed immediate");
6065 case Match_UImm16_Relaxed:
6066 case Match_UImm16_AltRelaxed:
6068 "expected 16-bit unsigned immediate");
6070 case Match_SImm16_Relaxed:
6072 "expected 16-bit signed immediate");
6073 case Match_SImm19_Lsl2:
6075 "expected both 19-bit signed immediate and multiple of 4");
6076 case Match_UImm20_0:
6078 "expected 20-bit unsigned immediate");
6079 case Match_UImm26_0:
6081 "expected 26-bit unsigned immediate");
6083 case Match_SImm32_Relaxed:
6085 "expected 32-bit signed immediate");
6086 case Match_UImm32_Coerced:
6088 "expected 32-bit immediate");
6089 case Match_MemSImm9:
6091 "expected memory with 9-bit signed offset");
6092 case Match_MemSImm10:
6094 "expected memory with 10-bit signed offset");
6095 case Match_MemSImm10Lsl1:
6097 "expected memory with 11-bit signed offset and multiple of 2");
6098 case Match_MemSImm10Lsl2:
6100 "expected memory with 12-bit signed offset and multiple of 4");
6101 case Match_MemSImm10Lsl3:
6103 "expected memory with 13-bit signed offset and multiple of 8");
6104 case Match_MemSImm11:
6106 "expected memory with 11-bit signed offset");
6107 case Match_MemSImm12:
6109 "expected memory with 12-bit signed offset");
6110 case Match_MemSImm16:
6112 "expected memory with 16-bit signed offset");
6113 case Match_MemSImmPtr:
6115 "expected memory with 32-bit signed offset");
6116 case Match_RequiresPosSizeRange0_32: {
6117 SMLoc ErrorStart =
Operands[3]->getStartLoc();
6118 SMLoc ErrorEnd =
Operands[4]->getEndLoc();
6119 return Error(ErrorStart,
"size plus position are not in the range 0 .. 32",
6120 SMRange(ErrorStart, ErrorEnd));
6122 case Match_RequiresPosSizeUImm6: {
6123 SMLoc ErrorStart =
Operands[3]->getStartLoc();
6124 SMLoc ErrorEnd =
Operands[4]->getEndLoc();
6125 return Error(ErrorStart,
"size plus position are not in the range 1 .. 63",
6126 SMRange(ErrorStart, ErrorEnd));
6128 case Match_RequiresPosSizeRange33_64: {
6129 SMLoc ErrorStart =
Operands[3]->getStartLoc();
6130 SMLoc ErrorEnd =
Operands[4]->getEndLoc();
6131 return Error(ErrorStart,
"size plus position are not in the range 33 .. 64",
6132 SMRange(ErrorStart, ErrorEnd));
6139void MipsAsmParser::warnIfRegIndexIsAT(MCRegister RegIndex, SMLoc Loc) {
6140 if (RegIndex && AssemblerOptions.
back()->getATRegIndex() == RegIndex)
6141 Warning(Loc,
"used $at (currently $" + Twine(RegIndex.
id()) +
6142 ") without \".set noat\"");
6145void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
6146 if (!AssemblerOptions.
back()->isMacro())
6147 Warning(Loc,
"macro instruction expanded into multiple instructions");
6150void MipsAsmParser::ConvertXWPOperands(MCInst &Inst,
6154 "Unexpected instruction!");
6155 ((MipsOperand &)*
Operands[1]).addGPR32ZeroAsmRegOperands(Inst, 1);
6156 MCRegister NextReg =
nextReg(((MipsOperand &)*
Operands[1]).getGPR32Reg());
6158 ((MipsOperand &)*
Operands[2]).addMemOperands(Inst, 2);
6162MipsAsmParser::printWarningWithFixIt(
const Twine &Msg,
const Twine &FixMsg,
6163 SMRange
Range,
bool ShowColors) {
6169int MipsAsmParser::matchCPURegisterName(StringRef Name) {
6172 CC = StringSwitch<unsigned>(Name)
6174 .Cases(
"at",
"AT", 1)
6208 if (!(isABI_N32() || isABI_N64()))
6211 if (12 <= CC && CC <= 15) {
6213 AsmToken RegTok = getLexer().peekTok();
6216 StringRef FixedName = StringSwitch<StringRef>(Name)
6222 assert(FixedName !=
"" &&
"Register name is not one of t4-t7.");
6224 printWarningWithFixIt(
"register names $t4-$t7 are only available in O32.",
6225 "Did you mean $" + FixedName +
"?", RegRange);
6231 if (8 <= CC && CC <= 11)
6235 CC = StringSwitch<unsigned>(Name)
6247int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
6250 CC = StringSwitch<unsigned>(Name)
6251 .Case(
"hwr_cpunum", 0)
6252 .Case(
"hwr_synci_step", 1)
6254 .Case(
"hwr_ccres", 3)
6255 .Case(
"hwr_ulr", 29)
6261int MipsAsmParser::matchFPURegisterName(StringRef Name) {
6262 if (Name[0] ==
'f') {
6263 StringRef NumString =
Name.substr(1);
6274int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
6275 if (
Name.starts_with(
"fcc")) {
6276 StringRef NumString =
Name.substr(3);
6287int MipsAsmParser::matchACRegisterName(StringRef Name) {
6288 if (
Name.starts_with(
"ac")) {
6289 StringRef NumString =
Name.substr(2);
6300int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
6303 if (
Name.front() !=
'w' ||
Name.drop_front(1).getAsInteger(10, IntVal))
6312int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
6315 CC = StringSwitch<unsigned>(Name)
6318 .Case(
"msaaccess", 2)
6320 .Case(
"msamodify", 4)
6321 .Case(
"msarequest", 5)
6323 .Case(
"msaunmap", 7)
6329bool MipsAsmParser::canUseATReg() {
6330 return AssemblerOptions.
back()->getATRegIndex() != 0;
6333MCRegister MipsAsmParser::getATReg(SMLoc Loc) {
6334 unsigned ATIndex = AssemblerOptions.
back()->getATRegIndex();
6336 reportParseError(Loc,
6337 "pseudo-instruction requires $at, which is not available");
6341 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
6345MCRegister MipsAsmParser::getReg(
int RC,
int RegNo) {
6346 return getContext().getRegisterInfo()->getRegClass(RC).getRegister(RegNo);
6352const MCExpr *MipsAsmParser::parseRelocExpr() {
6353 auto getOp = [](StringRef
Op) {
6354 return StringSwitch<Mips::Specifier>(
Op)
6382 MCAsmParser &Parser = getParser();
6384 const MCExpr *Res =
nullptr;
6390 auto Op = getOp(Name);
6399 while (
Ops.size()) {
6408 MCAsmParser &Parser = getParser();
6418 ParseStatus Res = MatchOperandParserImpl(
Operands, Mnemonic,
true);
6429 switch (getLexer().getKind()) {
6439 if (!parseAnyRegister(
Operands).isNoMatch())
6452 Operands.push_back(MipsOperand::CreateImm(SymRef, S,
E, *
this));
6457 const MCExpr *Expr = parseRelocExpr();
6461 Operands.push_back(MipsOperand::CreateImm(Expr, S,
E, *
this));
6468bool MipsAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
6470 return !tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess();
6473ParseStatus MipsAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
6476 ParseStatus Res = parseAnyRegister(
Operands);
6479 MipsOperand &Operand =
static_cast<MipsOperand &
>(*
Operands.front());
6480 StartLoc = Operand.getStartLoc();
6481 EndLoc = Operand.getEndLoc();
6487 if (Operand.isGPRAsmReg()) {
6489 Reg = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
6500 MCAsmParser &Parser = getParser();
6502 const MCExpr *IdVal =
nullptr;
6504 bool isParenExpr =
false;
6515 IdVal = parseRelocExpr();
6521 const AsmToken &Tok = Parser.
getTok();
6523 MipsOperand &Mnemonic =
static_cast<MipsOperand &
>(*
Operands[0]);
6524 if (Mnemonic.getToken() ==
"la" || Mnemonic.getToken() ==
"dla") {
6527 Operands.push_back(MipsOperand::CreateImm(IdVal, S,
E, *
this));
6536 auto Base = MipsOperand::createGPRReg(
6537 0,
"0",
getContext().getRegisterInfo(), S,
E, *
this);
6539 MipsOperand::CreateMem(std::move(
Base), IdVal, S,
E, *
this));
6591 const MCExpr * NextExpr;
6592 if (getParser().parseExpression(NextExpr))
6615 std::unique_ptr<MipsOperand>
op(
6616 static_cast<MipsOperand *
>(
Operands.back().release()));
6623 if (IdVal->evaluateAsAbsolute(Imm))
6630 Operands.push_back(MipsOperand::CreateMem(std::move(
op), IdVal, S,
E, *
this));
6635 MCAsmParser &Parser = getParser();
6644 const MCSymbolRefExpr *
Ref =
static_cast<const MCSymbolRefExpr *
>(Expr);
6645 StringRef DefSymbol =
Ref->getSymbol().getName();
6648 matchAnyRegisterNameWithoutDollar(
Operands, DefSymbol.
substr(1), S);
6662 if (Entry != RegisterSets.
end()) {
6664 matchAnyRegisterWithoutDollar(
Operands,
Entry->getValue(), S);
6675ParseStatus MipsAsmParser::matchAnyRegisterNameWithoutDollar(
6677 int Index = matchCPURegisterName(Identifier);
6679 Operands.push_back(MipsOperand::createGPRReg(
6680 Index, Identifier,
getContext().getRegisterInfo(), S,
6681 getLexer().getLoc(), *
this));
6685 Index = matchHWRegsRegisterName(Identifier);
6687 Operands.push_back(MipsOperand::createHWRegsReg(
6688 Index, Identifier,
getContext().getRegisterInfo(), S,
6689 getLexer().getLoc(), *
this));
6693 Index = matchFPURegisterName(Identifier);
6695 Operands.push_back(MipsOperand::createFGRReg(
6696 Index, Identifier,
getContext().getRegisterInfo(), S,
6697 getLexer().getLoc(), *
this));
6701 Index = matchFCCRegisterName(Identifier);
6703 Operands.push_back(MipsOperand::createFCCReg(
6704 Index, Identifier,
getContext().getRegisterInfo(), S,
6705 getLexer().getLoc(), *
this));
6709 Index = matchACRegisterName(Identifier);
6711 Operands.push_back(MipsOperand::createACCReg(
6712 Index, Identifier,
getContext().getRegisterInfo(), S,
6713 getLexer().getLoc(), *
this));
6717 Index = matchMSA128RegisterName(Identifier);
6719 Operands.push_back(MipsOperand::createMSA128Reg(
6720 Index, Identifier,
getContext().getRegisterInfo(), S,
6721 getLexer().getLoc(), *
this));
6725 Index = matchMSA128CtrlRegisterName(Identifier);
6727 Operands.push_back(MipsOperand::createMSACtrlReg(
6728 Index, Identifier,
getContext().getRegisterInfo(), S,
6729 getLexer().getLoc(), *
this));
6738 const AsmToken &Token, SMLoc S) {
6742 return matchAnyRegisterNameWithoutDollar(
Operands, Identifier, S);
6747 if (RegNum < 0 || RegNum > 31) {
6751 Error(getLexer().getLoc(),
"invalid register number");
6753 Operands.push_back(MipsOperand::createNumericReg(
6766 auto Token = getLexer().peekTok(
false);
6767 return matchAnyRegisterWithoutDollar(
Operands, Token, S);
6771 MCAsmParser &Parser = getParser();
6774 auto Token = Parser.
getTok();
6776 SMLoc S = Token.
getLoc();
6789 ParseStatus Res = matchAnyRegisterWithoutDollar(
Operands, S);
6798 MCAsmParser &Parser = getParser();
6801 SMLoc S = getLexer().getLoc();
6804 ParseStatus Res = parseAnyRegister(
Operands);
6809 const MCExpr *Expr =
nullptr;
6815 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *
this));
6820 MCAsmParser &Parser = getParser();
6821 const MCExpr *IdVal;
6832 if (getParser().parseExpression(IdVal))
6839 Operands.push_back(MipsOperand::CreateImm(
6845 MCAsmParser &Parser = getParser();
6848 unsigned PrevReg = Mips::NoRegister;
6849 bool RegRange =
false;
6856 while (parseAnyRegister(TmpOperands).isSuccess()) {
6857 SMLoc
E = getLexer().getLoc();
6858 MipsOperand &
Reg =
static_cast<MipsOperand &
>(*TmpOperands.
back());
6859 RegNo = isGP64bit() ?
Reg.getGPR64Reg() :
Reg.getGPR32Reg();
6863 if ((isGP64bit() && RegNo == Mips::RA_64) ||
6864 (!isGP64bit() && RegNo == Mips::RA)) {
6867 unsigned TmpReg = PrevReg + 1;
6868 while (TmpReg <= RegNo) {
6869 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
6870 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
6872 return Error(
E,
"invalid register operand");
6881 if ((PrevReg == Mips::NoRegister) &&
6882 ((isGP64bit() && (RegNo != Mips::S0_64) && (RegNo != Mips::RA_64)) ||
6883 (!isGP64bit() && (RegNo != Mips::S0) && (RegNo != Mips::RA))))
6884 return Error(
E,
"$16 or $31 expected");
6885 if (!(((RegNo == Mips::FP || RegNo == Mips::RA ||
6886 (RegNo >= Mips::S0 && RegNo <= Mips::S7)) &&
6888 ((RegNo == Mips::FP_64 || RegNo == Mips::RA_64 ||
6889 (RegNo >= Mips::S0_64 && RegNo <= Mips::S7_64)) &&
6891 return Error(
E,
"invalid register operand");
6892 if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
6893 ((RegNo != Mips::FP && RegNo != Mips::RA && !isGP64bit()) ||
6894 (RegNo != Mips::FP_64 && RegNo != Mips::RA_64 && isGP64bit())))
6895 return Error(
E,
"consecutive register numbers expected");
6905 return Error(
E,
"',' or '-' expected");
6915 Operands.push_back(MipsOperand::CreateRegList(Regs, S,
E, *
this));
6926 MCAsmParser &Parser = getParser();
6929 MipsOperand::CreateToken(
"(", getLexer().getLoc(), *
this));
6931 if (parseOperand(
Operands, Name)) {
6932 SMLoc Loc = getLexer().getLoc();
6933 return Error(Loc,
"unexpected token in argument list");
6936 SMLoc Loc = getLexer().getLoc();
6937 return Error(Loc,
"unexpected token, expected ')'");
6940 MipsOperand::CreateToken(
")", getLexer().getLoc(), *
this));
6952bool MipsAsmParser::parseBracketSuffix(StringRef Name,
6954 MCAsmParser &Parser = getParser();
6957 MipsOperand::CreateToken(
"[", getLexer().getLoc(), *
this));
6959 if (parseOperand(
Operands, Name)) {
6960 SMLoc Loc = getLexer().getLoc();
6961 return Error(Loc,
"unexpected token in argument list");
6964 SMLoc Loc = getLexer().getLoc();
6965 return Error(Loc,
"unexpected token, expected ']'");
6968 MipsOperand::CreateToken(
"]", getLexer().getLoc(), *
this));
6975 unsigned VariantID = 0);
6990bool MipsAsmParser::parseInstruction(ParseInstructionInfo &
Info, StringRef Name,
6992 MCAsmParser &Parser = getParser();
6996 getTargetStreamer().forbidModuleDirective();
6999 if (!mnemonicIsValid(Name, 0)) {
7000 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
7002 return Error(NameLoc,
"unknown instruction" + Suggestion);
7005 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *
this));
7010 if (parseOperand(
Operands, Name)) {
7011 SMLoc Loc = getLexer().getLoc();
7012 return Error(Loc,
"unexpected token in argument list");
7021 if (parseOperand(
Operands, Name)) {
7022 SMLoc Loc = getLexer().getLoc();
7023 return Error(Loc,
"unexpected token in argument list");
7027 if (parseBracketSuffix(Name,
Operands))
7035 SMLoc Loc = getLexer().getLoc();
7036 return Error(Loc,
"unexpected token in argument list");
7044bool MipsAsmParser::reportParseError(
const Twine &ErrorMsg) {
7045 SMLoc Loc = getLexer().getLoc();
7046 return Error(Loc, ErrorMsg);
7049bool MipsAsmParser::reportParseError(SMLoc Loc,
const Twine &ErrorMsg) {
7050 return Error(Loc, ErrorMsg);
7053bool MipsAsmParser::parseSetNoAtDirective() {
7054 MCAsmParser &Parser = getParser();
7058 AssemblerOptions.
back()->setATRegIndex(0);
7064 reportParseError(
"unexpected token, expected end of statement");
7068 getTargetStreamer().emitDirectiveSetNoAt();
7073bool MipsAsmParser::parseSetAtDirective() {
7076 MCAsmParser &Parser = getParser();
7081 AssemblerOptions.
back()->setATRegIndex(1);
7083 getTargetStreamer().emitDirectiveSetAt();
7089 reportParseError(
"unexpected token, expected equals sign");
7096 reportParseError(
"no register specified");
7099 reportParseError(
"unexpected token, expected dollar sign '$'");
7109 AtRegNo = matchCPURegisterName(
Reg.getIdentifier());
7111 AtRegNo =
Reg.getIntVal();
7113 reportParseError(
"unexpected token, expected identifier or integer");
7118 if (!AssemblerOptions.
back()->setATRegIndex(AtRegNo)) {
7119 reportParseError(
"invalid register");
7126 reportParseError(
"unexpected token, expected end of statement");
7130 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
7136bool MipsAsmParser::parseSetReorderDirective() {
7137 MCAsmParser &Parser = getParser();
7141 reportParseError(
"unexpected token, expected end of statement");
7144 AssemblerOptions.
back()->setReorder();
7145 getTargetStreamer().emitDirectiveSetReorder();
7150bool MipsAsmParser::parseSetNoReorderDirective() {
7151 MCAsmParser &Parser = getParser();
7155 reportParseError(
"unexpected token, expected end of statement");
7158 AssemblerOptions.
back()->setNoReorder();
7159 getTargetStreamer().emitDirectiveSetNoReorder();
7164bool MipsAsmParser::parseSetMacroDirective() {
7165 MCAsmParser &Parser = getParser();
7169 reportParseError(
"unexpected token, expected end of statement");
7172 AssemblerOptions.
back()->setMacro();
7173 getTargetStreamer().emitDirectiveSetMacro();
7178bool MipsAsmParser::parseSetNoMacroDirective() {
7179 MCAsmParser &Parser = getParser();
7183 reportParseError(
"unexpected token, expected end of statement");
7186 if (AssemblerOptions.
back()->isReorder()) {
7187 reportParseError(
"`noreorder' must be set before `nomacro'");
7190 AssemblerOptions.
back()->setNoMacro();
7191 getTargetStreamer().emitDirectiveSetNoMacro();
7196bool MipsAsmParser::parseSetMsaDirective() {
7197 MCAsmParser &Parser = getParser();
7202 return reportParseError(
"unexpected token, expected end of statement");
7204 setFeatureBits(Mips::FeatureMSA,
"msa");
7205 getTargetStreamer().emitDirectiveSetMsa();
7209bool MipsAsmParser::parseSetNoMsaDirective() {
7210 MCAsmParser &Parser = getParser();
7215 return reportParseError(
"unexpected token, expected end of statement");
7217 clearFeatureBits(Mips::FeatureMSA,
"msa");
7218 getTargetStreamer().emitDirectiveSetNoMsa();
7222bool MipsAsmParser::parseSetNoDspDirective() {
7223 MCAsmParser &Parser = getParser();
7228 reportParseError(
"unexpected token, expected end of statement");
7232 clearFeatureBits(Mips::FeatureDSP,
"dsp");
7233 getTargetStreamer().emitDirectiveSetNoDsp();
7237bool MipsAsmParser::parseSetNoMips3DDirective() {
7238 MCAsmParser &Parser = getParser();
7243 reportParseError(
"unexpected token, expected end of statement");
7247 clearFeatureBits(Mips::FeatureMips3D,
"mips3d");
7248 getTargetStreamer().emitDirectiveSetNoMips3D();
7252bool MipsAsmParser::parseSetMips16Directive() {
7253 MCAsmParser &Parser = getParser();
7258 reportParseError(
"unexpected token, expected end of statement");
7262 setFeatureBits(Mips::FeatureMips16,
"mips16");
7263 getTargetStreamer().emitDirectiveSetMips16();
7268bool MipsAsmParser::parseSetNoMips16Directive() {
7269 MCAsmParser &Parser = getParser();
7274 reportParseError(
"unexpected token, expected end of statement");
7278 clearFeatureBits(Mips::FeatureMips16,
"mips16");
7279 getTargetStreamer().emitDirectiveSetNoMips16();
7284bool MipsAsmParser::parseSetFpDirective() {
7285 MCAsmParser &Parser = getParser();
7291 AsmToken Tok = Parser.
getTok();
7293 reportParseError(
"unexpected token, expected equals sign '='");
7299 if (!parseFpABIValue(FpAbiVal,
".set"))
7303 reportParseError(
"unexpected token, expected end of statement");
7306 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
7311bool MipsAsmParser::parseSetOddSPRegDirective() {
7312 MCAsmParser &Parser = getParser();
7316 reportParseError(
"unexpected token, expected end of statement");
7320 clearFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
7321 getTargetStreamer().emitDirectiveSetOddSPReg();
7325bool MipsAsmParser::parseSetNoOddSPRegDirective() {
7326 MCAsmParser &Parser = getParser();
7330 reportParseError(
"unexpected token, expected end of statement");
7334 setFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
7335 getTargetStreamer().emitDirectiveSetNoOddSPReg();
7339bool MipsAsmParser::parseSetMtDirective() {
7340 MCAsmParser &Parser = getParser();
7345 reportParseError(
"unexpected token, expected end of statement");
7349 setFeatureBits(Mips::FeatureMT,
"mt");
7350 getTargetStreamer().emitDirectiveSetMt();
7355bool MipsAsmParser::parseSetNoMtDirective() {
7356 MCAsmParser &Parser = getParser();
7361 reportParseError(
"unexpected token, expected end of statement");
7365 clearFeatureBits(Mips::FeatureMT,
"mt");
7367 getTargetStreamer().emitDirectiveSetNoMt();
7372bool MipsAsmParser::parseSetNoCRCDirective() {
7373 MCAsmParser &Parser = getParser();
7378 reportParseError(
"unexpected token, expected end of statement");
7382 clearFeatureBits(Mips::FeatureCRC,
"crc");
7384 getTargetStreamer().emitDirectiveSetNoCRC();
7389bool MipsAsmParser::parseSetNoVirtDirective() {
7390 MCAsmParser &Parser = getParser();
7395 reportParseError(
"unexpected token, expected end of statement");
7399 clearFeatureBits(Mips::FeatureVirt,
"virt");
7401 getTargetStreamer().emitDirectiveSetNoVirt();
7406bool MipsAsmParser::parseSetNoGINVDirective() {
7407 MCAsmParser &Parser = getParser();
7412 reportParseError(
"unexpected token, expected end of statement");
7416 clearFeatureBits(Mips::FeatureGINV,
"ginv");
7418 getTargetStreamer().emitDirectiveSetNoGINV();
7423bool MipsAsmParser::parseSetPopDirective() {
7424 MCAsmParser &Parser = getParser();
7425 SMLoc Loc = getLexer().getLoc();
7429 return reportParseError(
"unexpected token, expected end of statement");
7433 if (AssemblerOptions.
size() == 2)
7434 return reportParseError(Loc,
".set pop with no .set push");
7436 MCSubtargetInfo &STI = copySTI();
7438 setAvailableFeatures(
7439 ComputeAvailableFeatures(AssemblerOptions.
back()->getFeatures()));
7442 getTargetStreamer().emitDirectiveSetPop();
7446bool MipsAsmParser::parseSetPushDirective() {
7447 MCAsmParser &Parser = getParser();
7450 return reportParseError(
"unexpected token, expected end of statement");
7454 std::make_unique<MipsAssemblerOptions>(AssemblerOptions.
back().get()));
7456 getTargetStreamer().emitDirectiveSetPush();
7460bool MipsAsmParser::parseSetSoftFloatDirective() {
7461 MCAsmParser &Parser = getParser();
7464 return reportParseError(
"unexpected token, expected end of statement");
7466 setFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
7467 getTargetStreamer().emitDirectiveSetSoftFloat();
7471bool MipsAsmParser::parseSetHardFloatDirective() {
7472 MCAsmParser &Parser = getParser();
7475 return reportParseError(
"unexpected token, expected end of statement");
7477 clearFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
7478 getTargetStreamer().emitDirectiveSetHardFloat();
7482bool MipsAsmParser::parseSetAssignment() {
7484 MCAsmParser &Parser = getParser();
7487 return reportParseError(
"expected identifier after .set");
7490 return reportParseError(
"unexpected token, expected comma");
7505 const MCExpr *
Value;
7507 Parser, Sym,
Value))
7509 getStreamer().emitAssignment(Sym,
Value);
7514bool MipsAsmParser::parseSetMips0Directive() {
7515 MCAsmParser &Parser = getParser();
7518 return reportParseError(
"unexpected token, expected end of statement");
7521 MCSubtargetInfo &STI = copySTI();
7522 setAvailableFeatures(
7523 ComputeAvailableFeatures(AssemblerOptions.
front()->getFeatures()));
7525 AssemblerOptions.
back()->setFeatures(AssemblerOptions.
front()->getFeatures());
7527 getTargetStreamer().emitDirectiveSetMips0();
7531bool MipsAsmParser::parseSetArchDirective() {
7532 MCAsmParser &Parser = getParser();
7535 return reportParseError(
"unexpected token, expected equals sign");
7538 StringRef Arch = getParser().parseStringToEndOfStatement().trim();
7540 return reportParseError(
"expected arch identifier");
7542 StringRef ArchFeatureName =
7543 StringSwitch<StringRef>(Arch)
7544 .Case(
"mips1",
"mips1")
7545 .Case(
"mips2",
"mips2")
7546 .Case(
"mips3",
"mips3")
7547 .Case(
"mips4",
"mips4")
7548 .Case(
"mips5",
"mips5")
7549 .Case(
"mips32",
"mips32")
7550 .Case(
"mips32r2",
"mips32r2")
7551 .Case(
"mips32r3",
"mips32r3")
7552 .Case(
"mips32r5",
"mips32r5")
7553 .Case(
"mips32r6",
"mips32r6")
7554 .Case(
"mips64",
"mips64")
7555 .Case(
"mips64r2",
"mips64r2")
7556 .Case(
"mips64r3",
"mips64r3")
7557 .Case(
"mips64r5",
"mips64r5")
7558 .Case(
"mips64r6",
"mips64r6")
7559 .Case(
"octeon",
"cnmips")
7560 .Case(
"octeon+",
"cnmipsp")
7561 .Case(
"r4000",
"mips3")
7564 if (ArchFeatureName.
empty())
7565 return reportParseError(
"unsupported architecture");
7567 if (ArchFeatureName ==
"mips64r6" && inMicroMipsMode())
7568 return reportParseError(
"mips64r6 does not support microMIPS");
7570 selectArch(ArchFeatureName);
7571 getTargetStreamer().emitDirectiveSetArch(Arch);
7575bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
7576 MCAsmParser &Parser = getParser();
7579 return reportParseError(
"unexpected token, expected end of statement");
7584 case Mips::FeatureMips3D:
7585 setFeatureBits(Mips::FeatureMips3D,
"mips3d");
7586 getTargetStreamer().emitDirectiveSetMips3D();
7588 case Mips::FeatureDSP:
7589 setFeatureBits(Mips::FeatureDSP,
"dsp");
7590 getTargetStreamer().emitDirectiveSetDsp();
7592 case Mips::FeatureDSPR2:
7593 setFeatureBits(Mips::FeatureDSPR2,
"dspr2");
7594 getTargetStreamer().emitDirectiveSetDspr2();
7596 case Mips::FeatureMicroMips:
7597 setFeatureBits(Mips::FeatureMicroMips,
"micromips");
7598 getTargetStreamer().emitDirectiveSetMicroMips();
7600 case Mips::FeatureMips1:
7601 selectArch(
"mips1");
7602 getTargetStreamer().emitDirectiveSetMips1();
7604 case Mips::FeatureMips2:
7605 selectArch(
"mips2");
7606 getTargetStreamer().emitDirectiveSetMips2();
7608 case Mips::FeatureMips3:
7609 selectArch(
"mips3");
7610 getTargetStreamer().emitDirectiveSetMips3();
7612 case Mips::FeatureMips4:
7613 selectArch(
"mips4");
7614 getTargetStreamer().emitDirectiveSetMips4();
7616 case Mips::FeatureMips5:
7617 selectArch(
"mips5");
7618 getTargetStreamer().emitDirectiveSetMips5();
7620 case Mips::FeatureMips32:
7621 selectArch(
"mips32");
7622 getTargetStreamer().emitDirectiveSetMips32();
7624 case Mips::FeatureMips32r2:
7625 selectArch(
"mips32r2");
7626 getTargetStreamer().emitDirectiveSetMips32R2();
7628 case Mips::FeatureMips32r3:
7629 selectArch(
"mips32r3");
7630 getTargetStreamer().emitDirectiveSetMips32R3();
7632 case Mips::FeatureMips32r5:
7633 selectArch(
"mips32r5");
7634 getTargetStreamer().emitDirectiveSetMips32R5();
7636 case Mips::FeatureMips32r6:
7637 selectArch(
"mips32r6");
7638 getTargetStreamer().emitDirectiveSetMips32R6();
7640 case Mips::FeatureMips64:
7641 selectArch(
"mips64");
7642 getTargetStreamer().emitDirectiveSetMips64();
7644 case Mips::FeatureMips64r2:
7645 selectArch(
"mips64r2");
7646 getTargetStreamer().emitDirectiveSetMips64R2();
7648 case Mips::FeatureMips64r3:
7649 selectArch(
"mips64r3");
7650 getTargetStreamer().emitDirectiveSetMips64R3();
7652 case Mips::FeatureMips64r5:
7653 selectArch(
"mips64r5");
7654 getTargetStreamer().emitDirectiveSetMips64R5();
7656 case Mips::FeatureMips64r6:
7657 selectArch(
"mips64r6");
7658 getTargetStreamer().emitDirectiveSetMips64R6();
7660 case Mips::FeatureCRC:
7661 setFeatureBits(Mips::FeatureCRC,
"crc");
7662 getTargetStreamer().emitDirectiveSetCRC();
7664 case Mips::FeatureVirt:
7665 setFeatureBits(Mips::FeatureVirt,
"virt");
7666 getTargetStreamer().emitDirectiveSetVirt();
7668 case Mips::FeatureGINV:
7669 setFeatureBits(Mips::FeatureGINV,
"ginv");
7670 getTargetStreamer().emitDirectiveSetGINV();
7676bool MipsAsmParser::eatComma(StringRef ErrorStr) {
7677 MCAsmParser &Parser = getParser();
7679 SMLoc Loc = getLexer().getLoc();
7680 return Error(Loc, ErrorStr);
7691bool MipsAsmParser::isPicAndNotNxxAbi() {
7692 return inPicMode() && !(isABI_N32() || isABI_N64());
7695bool MipsAsmParser::parseDirectiveCpAdd(SMLoc Loc) {
7697 ParseStatus Res = parseAnyRegister(
Reg);
7699 reportParseError(
"expected register");
7703 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7704 if (!RegOpnd.isGPRAsmReg()) {
7705 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7711 reportParseError(
"unexpected token, expected end of statement");
7716 getTargetStreamer().emitDirectiveCpAdd(RegOpnd.getGPR32Reg());
7720bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
7721 if (AssemblerOptions.
back()->isReorder())
7722 Warning(Loc,
".cpload should be inside a noreorder section");
7724 if (inMips16Mode()) {
7725 reportParseError(
".cpload is not supported in Mips16 mode");
7730 ParseStatus Res = parseAnyRegister(
Reg);
7732 reportParseError(
"expected register containing function address");
7736 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7737 if (!RegOpnd.isGPRAsmReg()) {
7738 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7744 reportParseError(
"unexpected token, expected end of statement");
7748 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
7752bool MipsAsmParser::parseDirectiveCpLocal(SMLoc Loc) {
7753 if (!isABI_N32() && !isABI_N64()) {
7754 reportParseError(
".cplocal is allowed only in N32 or N64 mode");
7759 ParseStatus Res = parseAnyRegister(
Reg);
7761 reportParseError(
"expected register containing global pointer");
7765 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7766 if (!RegOpnd.isGPRAsmReg()) {
7767 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7773 reportParseError(
"unexpected token, expected end of statement");
7778 unsigned NewReg = RegOpnd.getGPR32Reg();
7782 getTargetStreamer().emitDirectiveCpLocal(NewReg);
7786bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
7787 MCAsmParser &Parser = getParser();
7792 if (inMips16Mode()) {
7793 reportParseError(
".cprestore is not supported in Mips16 mode");
7798 const MCExpr *StackOffset;
7799 int64_t StackOffsetVal;
7801 reportParseError(
"expected stack offset value");
7805 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
7806 reportParseError(
"stack offset is not an absolute expression");
7810 if (StackOffsetVal < 0) {
7811 Warning(Loc,
".cprestore with negative stack offset has no effect");
7812 IsCpRestoreSet =
false;
7814 IsCpRestoreSet =
true;
7815 CpRestoreOffset = StackOffsetVal;
7820 reportParseError(
"unexpected token, expected end of statement");
7824 if (!getTargetStreamer().emitDirectiveCpRestore(
7825 CpRestoreOffset, [&]() {
return getATReg(Loc); }, Loc, STI))
7831bool MipsAsmParser::parseDirectiveCPSetup() {
7832 MCAsmParser &Parser = getParser();
7835 bool SaveIsReg =
true;
7838 ParseStatus Res = parseAnyRegister(TmpReg);
7840 reportParseError(
"expected register containing function address");
7844 MipsOperand &FuncRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7845 if (!FuncRegOpnd.isGPRAsmReg()) {
7846 reportParseError(FuncRegOpnd.getStartLoc(),
"invalid register");
7850 FuncReg = FuncRegOpnd.getGPR32Reg();
7853 if (!eatComma(
"unexpected token, expected comma"))
7856 Res = parseAnyRegister(TmpReg);
7858 const MCExpr *OffsetExpr;
7860 SMLoc ExprLoc = getLexer().
getLoc();
7863 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
7864 reportParseError(ExprLoc,
"expected save register or stack offset");
7871 MipsOperand &SaveOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7872 if (!SaveOpnd.isGPRAsmReg()) {
7873 reportParseError(SaveOpnd.getStartLoc(),
"invalid register");
7876 Save = SaveOpnd.getGPR32Reg();
7879 if (!eatComma(
"unexpected token, expected comma"))
7884 reportParseError(
"expected expression");
7889 reportParseError(
"expected symbol");
7892 const MCSymbolRefExpr *
Ref =
static_cast<const MCSymbolRefExpr *
>(Expr);
7894 CpSaveLocation = Save;
7895 CpSaveLocationIsRegister = SaveIsReg;
7897 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save,
Ref->getSymbol(),
7902bool MipsAsmParser::parseDirectiveCPReturn() {
7903 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
7904 CpSaveLocationIsRegister);
7908bool MipsAsmParser::parseDirectiveNaN() {
7909 MCAsmParser &Parser = getParser();
7911 const AsmToken &Tok = Parser.
getTok();
7915 getTargetStreamer().emitDirectiveNaN2008();
7917 }
else if (Tok.
getString() ==
"legacy") {
7919 getTargetStreamer().emitDirectiveNaNLegacy();
7925 reportParseError(
"invalid option in .nan directive");
7929bool MipsAsmParser::parseDirectiveSet() {
7930 const AsmToken &Tok = getParser().getTok();
7932 SMLoc Loc = Tok.
getLoc();
7934 if (IdVal ==
"noat")
7935 return parseSetNoAtDirective();
7937 return parseSetAtDirective();
7938 if (IdVal ==
"arch")
7939 return parseSetArchDirective();
7940 if (IdVal ==
"bopt") {
7941 Warning(Loc,
"'bopt' feature is unsupported");
7945 if (IdVal ==
"nobopt") {
7951 return parseSetFpDirective();
7952 if (IdVal ==
"oddspreg")
7953 return parseSetOddSPRegDirective();
7954 if (IdVal ==
"nooddspreg")
7955 return parseSetNoOddSPRegDirective();
7957 return parseSetPopDirective();
7958 if (IdVal ==
"push")
7959 return parseSetPushDirective();
7960 if (IdVal ==
"reorder")
7961 return parseSetReorderDirective();
7962 if (IdVal ==
"noreorder")
7963 return parseSetNoReorderDirective();
7964 if (IdVal ==
"macro")
7965 return parseSetMacroDirective();
7966 if (IdVal ==
"nomacro")
7967 return parseSetNoMacroDirective();
7968 if (IdVal ==
"mips16")
7969 return parseSetMips16Directive();
7970 if (IdVal ==
"nomips16")
7971 return parseSetNoMips16Directive();
7972 if (IdVal ==
"nomicromips") {
7973 clearFeatureBits(Mips::FeatureMicroMips,
"micromips");
7974 getTargetStreamer().emitDirectiveSetNoMicroMips();
7975 getParser().eatToEndOfStatement();
7978 if (IdVal ==
"micromips") {
7979 if (hasMips64r6()) {
7980 Error(Loc,
".set micromips directive is not supported with MIPS64R6");
7983 return parseSetFeature(Mips::FeatureMicroMips);
7985 if (IdVal ==
"mips0")
7986 return parseSetMips0Directive();
7987 if (IdVal ==
"mips1")
7988 return parseSetFeature(Mips::FeatureMips1);
7989 if (IdVal ==
"mips2")
7990 return parseSetFeature(Mips::FeatureMips2);
7991 if (IdVal ==
"mips3")
7992 return parseSetFeature(Mips::FeatureMips3);
7993 if (IdVal ==
"mips4")
7994 return parseSetFeature(Mips::FeatureMips4);
7995 if (IdVal ==
"mips5")
7996 return parseSetFeature(Mips::FeatureMips5);
7997 if (IdVal ==
"mips32")
7998 return parseSetFeature(Mips::FeatureMips32);
7999 if (IdVal ==
"mips32r2")
8000 return parseSetFeature(Mips::FeatureMips32r2);
8001 if (IdVal ==
"mips32r3")
8002 return parseSetFeature(Mips::FeatureMips32r3);
8003 if (IdVal ==
"mips32r5")
8004 return parseSetFeature(Mips::FeatureMips32r5);
8005 if (IdVal ==
"mips32r6")
8006 return parseSetFeature(Mips::FeatureMips32r6);
8007 if (IdVal ==
"mips64")
8008 return parseSetFeature(Mips::FeatureMips64);
8009 if (IdVal ==
"mips64r2")
8010 return parseSetFeature(Mips::FeatureMips64r2);
8011 if (IdVal ==
"mips64r3")
8012 return parseSetFeature(Mips::FeatureMips64r3);
8013 if (IdVal ==
"mips64r5")
8014 return parseSetFeature(Mips::FeatureMips64r5);
8015 if (IdVal ==
"mips64r6") {
8016 if (inMicroMipsMode()) {
8017 Error(Loc,
"MIPS64R6 is not supported with microMIPS");
8020 return parseSetFeature(Mips::FeatureMips64r6);
8023 return parseSetFeature(Mips::FeatureDSP);
8024 if (IdVal ==
"dspr2")
8025 return parseSetFeature(Mips::FeatureDSPR2);
8026 if (IdVal ==
"nodsp")
8027 return parseSetNoDspDirective();
8028 if (IdVal ==
"mips3d")
8029 return parseSetFeature(Mips::FeatureMips3D);
8030 if (IdVal ==
"nomips3d")
8031 return parseSetNoMips3DDirective();
8033 return parseSetMsaDirective();
8034 if (IdVal ==
"nomsa")
8035 return parseSetNoMsaDirective();
8037 return parseSetMtDirective();
8038 if (IdVal ==
"nomt")
8039 return parseSetNoMtDirective();
8040 if (IdVal ==
"softfloat")
8041 return parseSetSoftFloatDirective();
8042 if (IdVal ==
"hardfloat")
8043 return parseSetHardFloatDirective();
8045 return parseSetFeature(Mips::FeatureCRC);
8046 if (IdVal ==
"nocrc")
8047 return parseSetNoCRCDirective();
8048 if (IdVal ==
"virt")
8049 return parseSetFeature(Mips::FeatureVirt);
8050 if (IdVal ==
"novirt")
8051 return parseSetNoVirtDirective();
8052 if (IdVal ==
"ginv")
8053 return parseSetFeature(Mips::FeatureGINV);
8054 if (IdVal ==
"noginv")
8055 return parseSetNoGINVDirective();
8058 return parseSetAssignment();
8063bool MipsAsmParser::parseDirectiveGpWord() {
8064 const MCExpr *
Value;
8065 if (getParser().parseExpression(
Value))
8067 getTargetStreamer().emitGPRel32Value(
Value);
8073bool MipsAsmParser::parseDirectiveGpDWord() {
8074 const MCExpr *
Value;
8075 if (getParser().parseExpression(
Value))
8077 getTargetStreamer().emitGPRel64Value(
Value);
8083bool MipsAsmParser::parseDirectiveDtpRelWord() {
8084 const MCExpr *
Value;
8085 if (getParser().parseExpression(
Value))
8087 getTargetStreamer().emitDTPRel32Value(
Value);
8093bool MipsAsmParser::parseDirectiveDtpRelDWord() {
8094 const MCExpr *
Value;
8095 if (getParser().parseExpression(
Value))
8097 getTargetStreamer().emitDTPRel64Value(
Value);
8103bool MipsAsmParser::parseDirectiveTpRelWord() {
8104 const MCExpr *
Value;
8105 if (getParser().parseExpression(
Value))
8107 getTargetStreamer().emitTPRel32Value(
Value);
8113bool MipsAsmParser::parseDirectiveTpRelDWord() {
8114 const MCExpr *
Value;
8115 if (getParser().parseExpression(
Value))
8117 getTargetStreamer().emitTPRel64Value(
Value);
8121bool MipsAsmParser::parseDirectiveOption() {
8122 MCAsmParser &Parser = getParser();
8124 AsmToken Tok = Parser.
getTok();
8128 "unexpected token, expected identifier");
8133 if (Option ==
"pic0") {
8135 IsPicEnabled =
false;
8137 getTargetStreamer().emitDirectiveOptionPic0();
8141 "unexpected token, expected end of statement");
8146 if (Option ==
"pic2") {
8148 IsPicEnabled =
true;
8150 getTargetStreamer().emitDirectiveOptionPic2();
8154 "unexpected token, expected end of statement");
8161 "unknown option, expected 'pic0' or 'pic2'");
8168bool MipsAsmParser::parseInsnDirective() {
8171 reportParseError(
"unexpected token, expected end of statement");
8177 getTargetStreamer().emitDirectiveInsn();
8185bool MipsAsmParser::parseRSectionDirective(StringRef Section) {
8188 reportParseError(
"unexpected token, expected end of statement");
8192 MCSection *ELFSection =
getContext().getELFSection(
8194 getParser().getStreamer().switchSection(ELFSection);
8203bool MipsAsmParser::parseSSectionDirective(StringRef Section,
unsigned Type) {
8206 reportParseError(
"unexpected token, expected end of statement");
8210 MCSection *ELFSection =
getContext().getELFSection(
8212 getParser().getStreamer().switchSection(ELFSection);
8231bool MipsAsmParser::parseDirectiveModule() {
8232 MCAsmParser &Parser = getParser();
8233 AsmLexer &Lexer = getLexer();
8236 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
8238 reportParseError(
".module directive must appear before any code");
8244 reportParseError(
"expected .module option identifier");
8248 if (Option ==
"oddspreg") {
8249 clearModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
8253 getTargetStreamer().updateABIInfo(*
this);
8258 getTargetStreamer().emitDirectiveModuleOddSPReg();
8262 reportParseError(
"unexpected token, expected end of statement");
8267 }
else if (Option ==
"nooddspreg") {
8269 return Error(L,
"'.module nooddspreg' requires the O32 ABI");
8272 setModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
8276 getTargetStreamer().updateABIInfo(*
this);
8281 getTargetStreamer().emitDirectiveModuleOddSPReg();
8285 reportParseError(
"unexpected token, expected end of statement");
8290 }
else if (Option ==
"fp") {
8291 return parseDirectiveModuleFP();
8292 }
else if (Option ==
"softfloat") {
8293 setModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
8297 getTargetStreamer().updateABIInfo(*
this);
8302 getTargetStreamer().emitDirectiveModuleSoftFloat();
8306 reportParseError(
"unexpected token, expected end of statement");
8311 }
else if (Option ==
"hardfloat") {
8312 clearModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
8316 getTargetStreamer().updateABIInfo(*
this);
8321 getTargetStreamer().emitDirectiveModuleHardFloat();
8325 reportParseError(
"unexpected token, expected end of statement");
8330 }
else if (Option ==
"mt") {
8331 setModuleFeatureBits(Mips::FeatureMT,
"mt");
8335 getTargetStreamer().updateABIInfo(*
this);
8340 getTargetStreamer().emitDirectiveModuleMT();
8344 reportParseError(
"unexpected token, expected end of statement");
8349 }
else if (Option ==
"crc") {
8350 setModuleFeatureBits(Mips::FeatureCRC,
"crc");
8354 getTargetStreamer().updateABIInfo(*
this);
8359 getTargetStreamer().emitDirectiveModuleCRC();
8363 reportParseError(
"unexpected token, expected end of statement");
8368 }
else if (Option ==
"nocrc") {
8369 clearModuleFeatureBits(Mips::FeatureCRC,
"crc");
8373 getTargetStreamer().updateABIInfo(*
this);
8378 getTargetStreamer().emitDirectiveModuleNoCRC();
8382 reportParseError(
"unexpected token, expected end of statement");
8387 }
else if (Option ==
"virt") {
8388 setModuleFeatureBits(Mips::FeatureVirt,
"virt");
8392 getTargetStreamer().updateABIInfo(*
this);
8397 getTargetStreamer().emitDirectiveModuleVirt();
8401 reportParseError(
"unexpected token, expected end of statement");
8406 }
else if (Option ==
"novirt") {
8407 clearModuleFeatureBits(Mips::FeatureVirt,
"virt");
8411 getTargetStreamer().updateABIInfo(*
this);
8416 getTargetStreamer().emitDirectiveModuleNoVirt();
8420 reportParseError(
"unexpected token, expected end of statement");
8425 }
else if (Option ==
"ginv") {
8426 setModuleFeatureBits(Mips::FeatureGINV,
"ginv");
8430 getTargetStreamer().updateABIInfo(*
this);
8435 getTargetStreamer().emitDirectiveModuleGINV();
8439 reportParseError(
"unexpected token, expected end of statement");
8444 }
else if (Option ==
"noginv") {
8445 clearModuleFeatureBits(Mips::FeatureGINV,
"ginv");
8449 getTargetStreamer().updateABIInfo(*
this);
8454 getTargetStreamer().emitDirectiveModuleNoGINV();
8458 reportParseError(
"unexpected token, expected end of statement");
8464 return Error(L,
"'" + Twine(Option) +
"' is not a valid .module option.");
8472bool MipsAsmParser::parseDirectiveModuleFP() {
8473 MCAsmParser &Parser = getParser();
8474 AsmLexer &Lexer = getLexer();
8477 reportParseError(
"unexpected token, expected equals sign '='");
8483 if (!parseFpABIValue(FpABI,
".module"))
8487 reportParseError(
"unexpected token, expected end of statement");
8493 getTargetStreamer().updateABIInfo(*
this);
8498 getTargetStreamer().emitDirectiveModuleFP();
8505 StringRef Directive) {
8506 MCAsmParser &Parser = getParser();
8507 AsmLexer &Lexer = getLexer();
8508 bool ModuleLevelOptions = Directive ==
".module";
8514 if (
Value !=
"xx") {
8515 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
8520 reportParseError(
"'" + Directive +
" fp=xx' requires the O32 ABI");
8524 FpABI = MipsABIFlagsSection::FpABIKind::XX;
8525 if (ModuleLevelOptions) {
8526 setModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8527 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8529 setFeatureBits(Mips::FeatureFPXX,
"fpxx");
8530 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8540 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
8546 reportParseError(
"'" + Directive +
" fp=32' requires the O32 ABI");
8550 FpABI = MipsABIFlagsSection::FpABIKind::S32;
8551 if (ModuleLevelOptions) {
8552 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8553 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8555 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
8556 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8559 FpABI = MipsABIFlagsSection::FpABIKind::S64;
8560 if (ModuleLevelOptions) {
8561 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8562 setModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8564 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
8565 setFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8575bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
8581 MCAsmParser &Parser = getParser();
8582 StringRef IDVal = DirectiveID.
getString();
8584 if (IDVal ==
".cpadd") {
8585 parseDirectiveCpAdd(DirectiveID.
getLoc());
8588 if (IDVal ==
".cpload") {
8589 parseDirectiveCpLoad(DirectiveID.
getLoc());
8592 if (IDVal ==
".cprestore") {
8593 parseDirectiveCpRestore(DirectiveID.
getLoc());
8596 if (IDVal ==
".cplocal") {
8597 parseDirectiveCpLocal(DirectiveID.
getLoc());
8600 if (IDVal ==
".ent") {
8604 reportParseError(
"expected identifier after .ent");
8618 reportParseError(
"unexpected token, expected end of statement");
8622 const MCExpr *DummyNumber;
8623 int64_t DummyNumberVal;
8627 reportParseError(
"expected number after comma");
8630 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
8631 reportParseError(
"expected an absolute expression after comma");
8638 reportParseError(
"unexpected token, expected end of statement");
8644 getTargetStreamer().emitDirectiveEnt(*Sym);
8646 IsCpRestoreSet =
false;
8650 if (IDVal ==
".end") {
8654 reportParseError(
"expected identifier after .end");
8659 reportParseError(
"unexpected token, expected end of statement");
8663 if (CurrentFn ==
nullptr) {
8664 reportParseError(
".end used without .ent");
8668 if ((SymbolName != CurrentFn->
getName())) {
8669 reportParseError(
".end symbol does not match .ent symbol");
8673 getTargetStreamer().emitDirectiveEnd(SymbolName);
8674 CurrentFn =
nullptr;
8675 IsCpRestoreSet =
false;
8679 if (IDVal ==
".frame") {
8682 ParseStatus Res = parseAnyRegister(TmpReg);
8684 reportParseError(
"expected stack register");
8688 MipsOperand &StackRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
8689 if (!StackRegOpnd.isGPRAsmReg()) {
8690 reportParseError(StackRegOpnd.getStartLoc(),
8691 "expected general purpose register");
8694 unsigned StackReg = StackRegOpnd.getGPR32Reg();
8699 reportParseError(
"unexpected token, expected comma");
8704 const MCExpr *FrameSize;
8705 int64_t FrameSizeVal;
8708 reportParseError(
"expected frame size value");
8712 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
8713 reportParseError(
"frame size not an absolute expression");
8720 reportParseError(
"unexpected token, expected comma");
8726 Res = parseAnyRegister(TmpReg);
8728 reportParseError(
"expected return register");
8732 MipsOperand &ReturnRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
8733 if (!ReturnRegOpnd.isGPRAsmReg()) {
8734 reportParseError(ReturnRegOpnd.getStartLoc(),
8735 "expected general purpose register");
8741 reportParseError(
"unexpected token, expected end of statement");
8745 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
8746 ReturnRegOpnd.getGPR32Reg());
8747 IsCpRestoreSet =
false;
8751 if (IDVal ==
".set") {
8752 parseDirectiveSet();
8756 if (IDVal ==
".mask" || IDVal ==
".fmask") {
8767 const MCExpr *BitMask;
8771 reportParseError(
"expected bitmask value");
8775 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
8776 reportParseError(
"bitmask not an absolute expression");
8783 reportParseError(
"unexpected token, expected comma");
8788 const MCExpr *FrameOffset;
8789 int64_t FrameOffsetVal;
8792 reportParseError(
"expected frame offset value");
8796 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
8797 reportParseError(
"frame offset not an absolute expression");
8803 reportParseError(
"unexpected token, expected end of statement");
8807 if (IDVal ==
".mask")
8808 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
8810 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
8814 if (IDVal ==
".nan")
8815 return parseDirectiveNaN();
8817 if (IDVal ==
".gpword") {
8818 parseDirectiveGpWord();
8822 if (IDVal ==
".gpdword") {
8823 parseDirectiveGpDWord();
8827 if (IDVal ==
".dtprelword") {
8828 parseDirectiveDtpRelWord();
8832 if (IDVal ==
".dtpreldword") {
8833 parseDirectiveDtpRelDWord();
8837 if (IDVal ==
".tprelword") {
8838 parseDirectiveTpRelWord();
8842 if (IDVal ==
".tpreldword") {
8843 parseDirectiveTpRelDWord();
8847 if (IDVal ==
".option") {
8848 parseDirectiveOption();
8852 if (IDVal ==
".abicalls") {
8853 getTargetStreamer().emitDirectiveAbiCalls();
8856 "unexpected token, expected end of statement");
8861 if (IDVal ==
".cpsetup") {
8862 parseDirectiveCPSetup();
8865 if (IDVal ==
".cpreturn") {
8866 parseDirectiveCPReturn();
8869 if (IDVal ==
".module") {
8870 parseDirectiveModule();
8873 if (IDVal ==
".llvm_internal_mips_reallow_module_directive") {
8874 parseInternalDirectiveReallowModule();
8877 if (IDVal ==
".insn") {
8878 parseInsnDirective();
8881 if (IDVal ==
".rdata") {
8882 parseRSectionDirective(
".rodata");
8885 if (IDVal ==
".sbss") {
8889 if (IDVal ==
".sdata") {
8897bool MipsAsmParser::parseInternalDirectiveReallowModule() {
8900 reportParseError(
"unexpected token, expected end of statement");
8904 getTargetStreamer().reallowModuleDirective();
8918#define GET_REGISTER_MATCHER
8919#define GET_MATCHER_IMPLEMENTATION
8920#define GET_MNEMONIC_SPELL_CHECKER
8921#include "MipsGenAsmMatcher.inc"
8923bool MipsAsmParser::mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID) {
8925 const MatchEntry *Start, *End;
8926 switch (VariantID) {
8928 case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0);
break;
8931 auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
8932 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)
mir Rename Register Operands
static unsigned countMCSymbolRefExpr(const MCExpr *Expr)
static std::string MipsMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, unsigned VariantID=0)
static uint64_t convertIntToDoubleImm(uint64_t ImmOp64)
static uint32_t covertDoubleImmToSingleImm(uint64_t ImmOp64)
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 unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
static 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.
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.
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
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)
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.
static LLVM_ABI const fltSemantics & IEEEdouble() LLVM_READNONE
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...