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 =
3710 MII.getOpRegClassID(
Desc.operands()[StartOp],
3712 unsigned DstRegClassID =
3713 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3714 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3715 (DstRegClassID == Mips::GPR64RegClassID);
3717 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3720 TmpReg = getATReg(IDLoc);
3725 auto emitInstWithOffset = [&](
const MCOperand &
Off) {
3727 TOut.
emitRRX(OpCode, DstReg, TmpReg, Off, IDLoc, STI);
3729 TOut.
emitRRRX(OpCode, DstReg, DstReg, TmpReg, Off, IDLoc, STI);
3733 int64_t LoOffset =
OffsetOp.getImm() & 0xffff;
3734 int64_t HiOffset =
OffsetOp.getImm() & ~0xffff;
3738 if (LoOffset & 0x8000)
3739 HiOffset += 0x10000;
3741 bool IsLargeOffset = HiOffset != 0;
3743 if (IsLargeOffset) {
3745 if (loadImmediate(HiOffset, TmpReg, MCRegister(), Is32BitImm,
true, IDLoc,
3750 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3751 TOut.
emitRRR(
ABI.ArePtrs64bit() ? Mips::DADDu : Mips::ADDu, TmpReg,
3752 TmpReg, BaseReg, IDLoc, STI);
3766 if (!
OffsetOp.getExpr()->evaluateAsRelocatable(Res,
nullptr)) {
3767 Error(IDLoc,
"expected relocatable expression");
3771 Error(IDLoc,
"expected relocatable expression with only one symbol");
3775 loadAndAddSymbolAddress(
3777 BaseReg, !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3785 const MCExpr *OffExpr =
OffsetOp.getExpr();
3797 TOut.
emitRX(Mips::LUi, TmpReg, HighestOperand, IDLoc, STI);
3798 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HigherOperand, IDLoc, STI);
3799 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3800 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HiOperand, IDLoc, STI);
3801 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3802 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3803 TOut.
emitRRR(Mips::DADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3804 emitInstWithOffset(LoOperand);
3807 TOut.
emitRX(Mips::LUi, TmpReg, HiOperand, IDLoc, STI);
3808 if (BaseReg != Mips::ZERO)
3809 TOut.
emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3811 emitInstWithOffset(LoOperand);
3820void MipsAsmParser::expandMem9Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3821 const MCSubtargetInfo *STI,
bool IsLoad) {
3823 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3824 unsigned StartOp = NumOp == 3 ? 0 : 1;
3826 const MCOperand &DstRegOp = Inst.
getOperand(StartOp);
3827 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3828 const MCOperand &BaseRegOp = Inst.
getOperand(StartOp + 1);
3829 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3832 MipsTargetStreamer &TOut = getTargetStreamer();
3834 MCRegister DstReg = DstRegOp.
getReg();
3836 MCRegister TmpReg = DstReg;
3838 const MCInstrDesc &
Desc = MII.get(OpCode);
3839 int16_t DstRegClass =
3840 MII.getOpRegClassID(
Desc.operands()[StartOp],
3843 unsigned DstRegClassID =
3844 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3845 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3846 (DstRegClassID == Mips::GPR64RegClassID);
3848 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3851 TmpReg = getATReg(IDLoc);
3856 auto emitInst = [&]() {
3865 loadImmediate(
OffsetOp.getImm(), TmpReg, BaseReg, !
ABI.ArePtrs64bit(),
true,
3872 loadAndAddSymbolAddress(
OffsetOp.getExpr(), TmpReg, BaseReg,
3873 !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3881bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
3883 const MCSubtargetInfo *STI) {
3886 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3890 Inst.
getOperand(OpNum - 3).
isReg() &&
"Invalid instruction operand.");
3899 if (inMicroMipsMode() && hasMips32r6())
3900 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3902 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3910bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
3912 const MCSubtargetInfo *STI) {
3913 MipsTargetStreamer &TOut = getTargetStreamer();
3914 bool EmittedNoMacroWarning =
false;
3915 unsigned PseudoOpcode = Inst.
getOpcode();
3920 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3921 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3926 else if (TrgOp.
isImm()) {
3927 warnIfNoMacro(IDLoc);
3928 EmittedNoMacroWarning =
true;
3930 TrgReg = getATReg(IDLoc);
3934 switch(PseudoOpcode) {
3937 case Mips::BLTImmMacro:
3938 PseudoOpcode = Mips::BLT;
3940 case Mips::BLEImmMacro:
3941 PseudoOpcode = Mips::BLE;
3943 case Mips::BGEImmMacro:
3944 PseudoOpcode = Mips::BGE;
3946 case Mips::BGTImmMacro:
3947 PseudoOpcode = Mips::BGT;
3949 case Mips::BLTUImmMacro:
3950 PseudoOpcode = Mips::BLTU;
3952 case Mips::BLEUImmMacro:
3953 PseudoOpcode = Mips::BLEU;
3955 case Mips::BGEUImmMacro:
3956 PseudoOpcode = Mips::BGEU;
3958 case Mips::BGTUImmMacro:
3959 PseudoOpcode = Mips::BGTU;
3961 case Mips::BLTLImmMacro:
3962 PseudoOpcode = Mips::BLTL;
3964 case Mips::BLELImmMacro:
3965 PseudoOpcode = Mips::BLEL;
3967 case Mips::BGELImmMacro:
3968 PseudoOpcode = Mips::BGEL;
3970 case Mips::BGTLImmMacro:
3971 PseudoOpcode = Mips::BGTL;
3973 case Mips::BLTULImmMacro:
3974 PseudoOpcode = Mips::BLTUL;
3976 case Mips::BLEULImmMacro:
3977 PseudoOpcode = Mips::BLEUL;
3979 case Mips::BGEULImmMacro:
3980 PseudoOpcode = Mips::BGEUL;
3982 case Mips::BGTULImmMacro:
3983 PseudoOpcode = Mips::BGTUL;
3987 if (loadImmediate(TrgOp.
getImm(), TrgReg, MCRegister(), !isGP64bit(),
false,
3992 switch (PseudoOpcode) {
3997 AcceptsEquality =
false;
3998 ReverseOrderSLT =
false;
4000 ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
4001 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
4002 ZeroSrcOpcode = Mips::BGTZ;
4003 ZeroTrgOpcode = Mips::BLTZ;
4009 AcceptsEquality =
true;
4010 ReverseOrderSLT =
true;
4012 ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
4013 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
4014 ZeroSrcOpcode = Mips::BGEZ;
4015 ZeroTrgOpcode = Mips::BLEZ;
4021 AcceptsEquality =
true;
4022 ReverseOrderSLT =
false;
4024 ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
4025 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
4026 ZeroSrcOpcode = Mips::BLEZ;
4027 ZeroTrgOpcode = Mips::BGEZ;
4033 AcceptsEquality =
false;
4034 ReverseOrderSLT =
true;
4036 ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
4037 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
4038 ZeroSrcOpcode = Mips::BLTZ;
4039 ZeroTrgOpcode = Mips::BGTZ;
4045 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
4046 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
4047 if (IsSrcRegZero && IsTrgRegZero) {
4051 if (PseudoOpcode == Mips::BLT) {
4056 if (PseudoOpcode == Mips::BLE) {
4059 Warning(IDLoc,
"branch is always taken");
4062 if (PseudoOpcode == Mips::BGE) {
4065 Warning(IDLoc,
"branch is always taken");
4068 if (PseudoOpcode == Mips::BGT) {
4073 if (PseudoOpcode == Mips::BGTU) {
4074 TOut.
emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
4078 if (AcceptsEquality) {
4081 TOut.
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4083 Warning(IDLoc,
"branch is always taken");
4090 if (IsSrcRegZero || IsTrgRegZero) {
4091 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
4092 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
4099 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
4100 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
4106 TOut.
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4108 Warning(IDLoc,
"branch is always taken");
4124 TOut.
emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
4125 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
4132 TOut.
emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
4133 IsSrcRegZero ? TrgReg : SrcReg,
4140 MCRegister ATRegNum = getATReg(IDLoc);
4144 if (!EmittedNoMacroWarning)
4145 warnIfNoMacro(IDLoc);
4162 TOut.
emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
4163 ReverseOrderSLT ? TrgReg : SrcReg,
4164 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
4166 TOut.
emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
4167 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
4181bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4182 const MCSubtargetInfo *STI,
4183 const bool IsMips64,
const bool Signed) {
4184 MipsTargetStreamer &TOut = getTargetStreamer();
4186 warnIfNoMacro(IDLoc);
4188 const MCOperand &RdRegOp = Inst.
getOperand(0);
4189 assert(RdRegOp.
isReg() &&
"expected register operand kind");
4190 MCRegister RdReg = RdRegOp.
getReg();
4192 const MCOperand &RsRegOp = Inst.
getOperand(1);
4193 assert(RsRegOp.
isReg() &&
"expected register operand kind");
4194 MCRegister RsReg = RsRegOp.
getReg();
4201 "expected register or immediate operand kind");
4205 ImmValue = RtOp.
getImm();
4212 DivOp =
Signed ? Mips::DSDIV : Mips::DUDIV;
4213 ZeroReg = Mips::ZERO_64;
4216 DivOp =
Signed ? Mips::SDIV : Mips::UDIV;
4217 ZeroReg = Mips::ZERO;
4221 bool UseTraps = useTraps();
4224 bool isDiv = Opcode == Mips::SDivMacro || Opcode == Mips::SDivIMacro ||
4225 Opcode == Mips::UDivMacro || Opcode == Mips::UDivIMacro ||
4226 Opcode == Mips::DSDivMacro || Opcode == Mips::DSDivIMacro ||
4227 Opcode == Mips::DUDivMacro || Opcode == Mips::DUDivIMacro;
4229 bool isRem = Opcode == Mips::SRemMacro || Opcode == Mips::SRemIMacro ||
4230 Opcode == Mips::URemMacro || Opcode == Mips::URemIMacro ||
4231 Opcode == Mips::DSRemMacro || Opcode == Mips::DSRemIMacro ||
4232 Opcode == Mips::DURemMacro || Opcode == Mips::DURemIMacro;
4235 MCRegister ATReg = getATReg(IDLoc);
4239 if (ImmValue == 0) {
4241 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4243 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4247 if (isRem && (ImmValue == 1 || (
Signed && (ImmValue == -1)))) {
4248 TOut.
emitRRR(Mips::OR, RdReg, ZeroReg, ZeroReg, IDLoc, STI);
4250 }
else if (isDiv && ImmValue == 1) {
4251 TOut.
emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI);
4253 }
else if (isDiv &&
Signed && ImmValue == -1) {
4254 TOut.
emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
4257 if (loadImmediate(ImmValue, ATReg, MCRegister(),
isInt<32>(ImmValue),
4258 false, Inst.
getLoc(), Out, STI))
4260 TOut.
emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
4261 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4271 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
4273 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4276 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4282 if (isRem && (RdReg == Mips::ZERO || RdReg == Mips::ZERO_64)) {
4283 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4293 TOut.
emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4296 BrTarget =
Context.createTempSymbol();
4298 TOut.
emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4301 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4304 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4310 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4314 MCRegister ATReg = getATReg(IDLoc);
4321 TOut.
emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
4325 MCOperand LabelOpEnd =
4329 TOut.
emitRRX(Mips::BNE, RtReg, ATReg, LabelOpEnd, IDLoc, STI);
4332 TOut.
emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
4333 TOut.
emitDSLL(ATReg, ATReg, 63, IDLoc, STI);
4335 TOut.
emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, STI);
4339 TOut.
emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
4342 TOut.
emitRRX(Mips::BNE, RsReg, ATReg, LabelOpEnd, IDLoc, STI);
4344 TOut.
emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
4348 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4352bool MipsAsmParser::expandTrunc(MCInst &Inst,
bool IsDouble,
bool Is64FPU,
4353 SMLoc IDLoc, MCStreamer &Out,
4354 const MCSubtargetInfo *STI) {
4355 MipsTargetStreamer &TOut = getTargetStreamer();
4365 if (hasMips1() && !hasMips2()) {
4366 MCRegister ATReg = getATReg(IDLoc);
4369 TOut.
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4370 TOut.
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4372 TOut.
emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4373 TOut.
emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4374 TOut.
emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4376 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4378 FirstReg, SecondReg, IDLoc, STI);
4379 TOut.
emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4384 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4386 FirstReg, SecondReg, IDLoc, STI);
4391bool MipsAsmParser::expandUlh(MCInst &Inst,
bool Signed, SMLoc IDLoc,
4392 MCStreamer &Out,
const MCSubtargetInfo *STI) {
4393 if (hasMips32r6() || hasMips64r6()) {
4394 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4397 const MCOperand &DstRegOp = Inst.
getOperand(0);
4398 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4399 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4400 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4401 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4402 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4404 MipsTargetStreamer &TOut = getTargetStreamer();
4405 MCRegister DstReg = DstRegOp.
getReg();
4406 MCRegister SrcReg = SrcRegOp.
getReg();
4407 int64_t OffsetValue = OffsetImmOp.
getImm();
4411 warnIfNoMacro(IDLoc);
4412 MCRegister ATReg = getATReg(IDLoc);
4417 if (IsLargeOffset) {
4418 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4423 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4424 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4428 MCRegister FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4429 MCRegister SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4431 MCRegister LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4432 MCRegister SllReg = IsLargeOffset ? DstReg : ATReg;
4434 TOut.
emitRRI(
Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4435 FirstOffset, IDLoc, STI);
4436 TOut.
emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4437 TOut.
emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4438 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4443bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4444 const MCSubtargetInfo *STI) {
4445 if (hasMips32r6() || hasMips64r6()) {
4446 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4449 const MCOperand &DstRegOp = Inst.
getOperand(0);
4450 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4451 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4452 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4453 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4454 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4456 MipsTargetStreamer &TOut = getTargetStreamer();
4457 MCRegister DstReg = DstRegOp.
getReg();
4458 MCRegister SrcReg = SrcRegOp.
getReg();
4459 int64_t OffsetValue = OffsetImmOp.
getImm();
4461 warnIfNoMacro(IDLoc);
4462 MCRegister ATReg = getATReg(IDLoc);
4467 if (IsLargeOffset) {
4468 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4473 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4474 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4478 if (IsLargeOffset) {
4479 TOut.
emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4480 TOut.
emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4481 TOut.
emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4482 TOut.
emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4483 TOut.
emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4484 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4486 TOut.
emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4487 TOut.
emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4488 TOut.
emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4494bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4495 const MCSubtargetInfo *STI) {
4496 if (hasMips32r6() || hasMips64r6()) {
4497 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4500 const MCOperand &DstRegOp = Inst.
getOperand(0);
4501 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4502 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4503 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4504 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4505 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4507 MipsTargetStreamer &TOut = getTargetStreamer();
4508 MCRegister DstReg = DstRegOp.
getReg();
4509 MCRegister SrcReg = SrcRegOp.
getReg();
4510 int64_t OffsetValue = OffsetImmOp.
getImm();
4514 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4515 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4519 bool IsLoadInst = (Inst.
getOpcode() == Mips::Ulw);
4520 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4521 MCRegister TmpReg = SrcReg;
4522 if (IsLargeOffset || DoMove) {
4523 warnIfNoMacro(IDLoc);
4524 TmpReg = getATReg(IDLoc);
4529 if (IsLargeOffset) {
4530 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4538 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4539 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4540 TOut.
emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4541 TOut.
emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4544 TOut.
emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4549bool MipsAsmParser::expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4550 const MCSubtargetInfo *STI) {
4551 MipsTargetStreamer &TOut = getTargetStreamer();
4563 warnIfNoMacro(IDLoc);
4577 TOut.
emitRRR(OpCode, DstReg, SrcReg, OpReg, IDLoc, STI);
4578 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4583bool MipsAsmParser::expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4584 const MCSubtargetInfo *STI) {
4585 MipsTargetStreamer &TOut = getTargetStreamer();
4595 unsigned OpRegCode, OpImmCode;
4597 warnIfNoMacro(IDLoc);
4601 case Mips::SGEImm64:
4602 OpRegCode = Mips::SLT;
4603 OpImmCode = Mips::SLTi;
4606 case Mips::SGEUImm64:
4607 OpRegCode = Mips::SLTu;
4608 OpImmCode = Mips::SLTiu;
4617 TOut.
emitRRI(OpImmCode, DstReg, SrcReg, ImmValue, IDLoc, STI);
4618 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4620 MCRegister ImmReg = DstReg;
4621 if (DstReg == SrcReg) {
4622 MCRegister ATReg = getATReg(Inst.
getLoc());
4628 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
4629 false, IDLoc, Out, STI))
4632 TOut.
emitRRR(OpRegCode, DstReg, SrcReg, ImmReg, IDLoc, STI);
4633 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4639bool MipsAsmParser::expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4640 const MCSubtargetInfo *STI) {
4641 MipsTargetStreamer &TOut = getTargetStreamer();
4650 MCRegister ImmReg = DstReg;
4654 warnIfNoMacro(IDLoc);
4658 case Mips::SGTImm64:
4662 case Mips::SGTUImm64:
4669 if (DstReg == SrcReg) {
4670 MCRegister ATReg = getATReg(Inst.
getLoc());
4676 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
false,
4681 TOut.
emitRRR(OpCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4686bool MipsAsmParser::expandSle(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4687 const MCSubtargetInfo *STI) {
4688 MipsTargetStreamer &TOut = getTargetStreamer();
4700 warnIfNoMacro(IDLoc);
4714 TOut.
emitRRR(OpCode, DstReg, OpReg, SrcReg, IDLoc, STI);
4715 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4720bool MipsAsmParser::expandSleImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4721 const MCSubtargetInfo *STI) {
4722 MipsTargetStreamer &TOut = getTargetStreamer();
4734 warnIfNoMacro(IDLoc);
4738 case Mips::SLEImm64:
4739 OpRegCode = Mips::SLT;
4742 case Mips::SLEUImm64:
4743 OpRegCode = Mips::SLTu;
4750 MCRegister ImmReg = DstReg;
4751 if (DstReg == SrcReg) {
4752 MCRegister ATReg = getATReg(Inst.
getLoc());
4758 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
false,
4762 TOut.
emitRRR(OpRegCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4763 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4768bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
4770 const MCSubtargetInfo *STI) {
4771 MipsTargetStreamer &TOut = getTargetStreamer();
4779 MCRegister FinalDstReg;
4786 unsigned FinalOpcode = Inst.
getOpcode();
4788 if (DstReg == SrcReg) {
4789 ATReg = getATReg(Inst.
getLoc());
4792 FinalDstReg = DstReg;
4796 if (!loadImmediate(ImmValue, DstReg, MCRegister(), Is32Bit,
false,
4797 Inst.
getLoc(), Out, STI)) {
4798 switch (FinalOpcode) {
4802 FinalOpcode = Mips::ADD;
4805 FinalOpcode = Mips::ADDu;
4808 FinalOpcode = Mips::AND;
4811 FinalOpcode = Mips::NOR;
4814 FinalOpcode = Mips::OR;
4817 FinalOpcode = Mips::SLT;
4820 FinalOpcode = Mips::SLTu;
4823 FinalOpcode = Mips::XOR;
4826 FinalOpcode = Mips::ADD_MM;
4828 case Mips::ADDiu_MM:
4829 FinalOpcode = Mips::ADDu_MM;
4832 FinalOpcode = Mips::AND_MM;
4835 FinalOpcode = Mips::OR_MM;
4838 FinalOpcode = Mips::SLT_MM;
4840 case Mips::SLTiu_MM:
4841 FinalOpcode = Mips::SLTu_MM;
4844 FinalOpcode = Mips::XOR_MM;
4847 FinalOpcode = Mips::AND64;
4849 case Mips::NORImm64:
4850 FinalOpcode = Mips::NOR64;
4853 FinalOpcode = Mips::OR64;
4855 case Mips::SLTImm64:
4856 FinalOpcode = Mips::SLT64;
4858 case Mips::SLTUImm64:
4859 FinalOpcode = Mips::SLTu64;
4862 FinalOpcode = Mips::XOR64;
4867 TOut.
emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4869 TOut.
emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4875bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4876 const MCSubtargetInfo *STI) {
4877 MipsTargetStreamer &TOut = getTargetStreamer();
4882 MCRegister TmpReg =
DReg;
4884 unsigned FirstShift = Mips::NOP;
4885 unsigned SecondShift = Mips::NOP;
4887 if (hasMips32r2()) {
4889 TmpReg = getATReg(Inst.
getLoc());
4895 TOut.
emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4896 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
4901 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
4913 FirstShift = Mips::SRLV;
4914 SecondShift = Mips::SLLV;
4917 FirstShift = Mips::SLLV;
4918 SecondShift = Mips::SRLV;
4922 ATReg = getATReg(Inst.
getLoc());
4926 TOut.
emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4927 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
4928 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
4929 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
4937bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
4939 const MCSubtargetInfo *STI) {
4940 MipsTargetStreamer &TOut = getTargetStreamer();
4946 unsigned FirstShift = Mips::NOP;
4947 unsigned SecondShift = Mips::NOP;
4949 if (hasMips32r2()) {
4951 uint64_t MaxShift = 32;
4952 uint64_t ShiftValue = ImmValue;
4954 ShiftValue = MaxShift - ImmValue;
4955 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
4960 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.
getLoc(), STI);
4968 if (ImmValue == 0) {
4977 FirstShift = Mips::SLL;
4978 SecondShift = Mips::SRL;
4981 FirstShift = Mips::SRL;
4982 SecondShift = Mips::SLL;
4986 ATReg = getATReg(Inst.
getLoc());
4990 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.
getLoc(), STI);
4991 TOut.
emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.
getLoc(), STI);
4992 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5000bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5001 const MCSubtargetInfo *STI) {
5002 MipsTargetStreamer &TOut = getTargetStreamer();
5007 MCRegister TmpReg =
DReg;
5009 unsigned FirstShift = Mips::NOP;
5010 unsigned SecondShift = Mips::NOP;
5012 if (hasMips64r2()) {
5013 if (TmpReg == SReg) {
5014 TmpReg = getATReg(Inst.
getLoc());
5020 TOut.
emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
5021 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
5026 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
5038 FirstShift = Mips::DSRLV;
5039 SecondShift = Mips::DSLLV;
5042 FirstShift = Mips::DSLLV;
5043 SecondShift = Mips::DSRLV;
5047 ATReg = getATReg(Inst.
getLoc());
5051 TOut.
emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
5052 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
5053 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
5054 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5062bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
5064 const MCSubtargetInfo *STI) {
5065 MipsTargetStreamer &TOut = getTargetStreamer();
5071 unsigned FirstShift = Mips::NOP;
5072 unsigned SecondShift = Mips::NOP;
5076 if (hasMips64r2()) {
5077 unsigned FinalOpcode = Mips::NOP;
5079 FinalOpcode = Mips::DROTR;
5080 else if (ImmValue % 32 == 0)
5081 FinalOpcode = Mips::DROTR32;
5082 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
5084 FinalOpcode = Mips::DROTR32;
5086 FinalOpcode = Mips::DROTR;
5087 }
else if (ImmValue >= 33) {
5089 FinalOpcode = Mips::DROTR;
5091 FinalOpcode = Mips::DROTR32;
5094 uint64_t ShiftValue = ImmValue % 32;
5096 ShiftValue = (32 - ImmValue % 32) % 32;
5098 TOut.
emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
5104 if (ImmValue == 0) {
5105 TOut.
emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.
getLoc(), STI);
5113 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5114 FirstShift = Mips::DSLL;
5115 SecondShift = Mips::DSRL32;
5117 if (ImmValue == 32) {
5118 FirstShift = Mips::DSLL32;
5119 SecondShift = Mips::DSRL32;
5121 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5122 FirstShift = Mips::DSLL32;
5123 SecondShift = Mips::DSRL;
5127 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5128 FirstShift = Mips::DSRL;
5129 SecondShift = Mips::DSLL32;
5131 if (ImmValue == 32) {
5132 FirstShift = Mips::DSRL32;
5133 SecondShift = Mips::DSLL32;
5135 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5136 FirstShift = Mips::DSRL32;
5137 SecondShift = Mips::DSLL;
5142 ATReg = getATReg(Inst.
getLoc());
5146 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.
getLoc(), STI);
5147 TOut.
emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
5149 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5157bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5158 const MCSubtargetInfo *STI) {
5159 MipsTargetStreamer &TOut = getTargetStreamer();
5163 TOut.
emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
5164 if (FirstRegOp != SecondRegOp)
5165 TOut.
emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
5168 TOut.
emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
5173bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5174 const MCSubtargetInfo *STI) {
5175 MipsTargetStreamer &TOut = getTargetStreamer();
5181 ATReg = getATReg(IDLoc);
5185 loadImmediate(ImmValue, ATReg, MCRegister(),
true,
false, IDLoc, Out, STI);
5187 TOut.
emitRR(Inst.
getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
5188 SrcReg, ATReg, IDLoc, STI);
5190 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5195bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5196 const MCSubtargetInfo *STI) {
5197 MipsTargetStreamer &TOut = getTargetStreamer();
5203 ATReg = getATReg(Inst.
getLoc());
5207 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
5208 SrcReg, TmpReg, IDLoc, STI);
5210 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5212 TOut.
emitRRI(Inst.
getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
5213 DstReg, DstReg, 0x1F, IDLoc, STI);
5215 TOut.
emitR(Mips::MFHI, ATReg, IDLoc, STI);
5218 TOut.
emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
5225 TOut.
emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
5226 if (AssemblerOptions.
back()->isReorder())
5228 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5232 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5237bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5238 const MCSubtargetInfo *STI) {
5239 MipsTargetStreamer &TOut = getTargetStreamer();
5245 ATReg = getATReg(IDLoc);
5249 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
5250 SrcReg, TmpReg, IDLoc, STI);
5252 TOut.
emitR(Mips::MFHI, ATReg, IDLoc, STI);
5253 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5255 TOut.
emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);
5262 TOut.
emitRRX(Mips::BEQ, ATReg, Mips::ZERO, LabelOp, IDLoc, STI);
5263 if (AssemblerOptions.
back()->isReorder())
5265 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5273bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5274 const MCSubtargetInfo *STI) {
5275 MipsTargetStreamer &TOut = getTargetStreamer();
5280 TOut.
emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
5281 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5291bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
5293 const MCSubtargetInfo *STI,
5298 warnIfNoMacro(IDLoc);
5300 MipsTargetStreamer &TOut = getTargetStreamer();
5301 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
5303 MCRegister SecondReg =
nextReg(FirstReg);
5308 warnIfRegIndexIsAT(FirstReg, IDLoc);
5311 "Offset for load macro is not immediate!");
5314 signed NextOffset = FirstOffset.
getImm() + 4;
5322 if (FirstReg != BaseReg || !IsLoad) {
5323 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5324 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5326 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5327 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5339bool MipsAsmParser::expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc,
5341 const MCSubtargetInfo *STI) {
5345 warnIfNoMacro(IDLoc);
5347 MipsTargetStreamer &TOut = getTargetStreamer();
5348 unsigned Opcode = Mips::SWC1;
5350 MCRegister SecondReg =
nextReg(FirstReg);
5355 warnIfRegIndexIsAT(FirstReg, IDLoc);
5358 "Offset for macro is not immediate!");
5361 signed NextOffset = FirstOffset.
getImm() + 4;
5367 if (!IsLittleEndian)
5370 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5371 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5376bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5377 const MCSubtargetInfo *STI) {
5378 MipsTargetStreamer &TOut = getTargetStreamer();
5389 warnIfNoMacro(IDLoc);
5391 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5392 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5393 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5397 MCRegister
Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5398 TOut.
emitRRI(Mips::SLTiu, DstReg,
Reg, 1, IDLoc, STI);
5402bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5403 const MCSubtargetInfo *STI) {
5404 MipsTargetStreamer &TOut = getTargetStreamer();
5415 warnIfNoMacro(IDLoc);
5418 TOut.
emitRRI(Mips::SLTiu, DstReg, SrcReg, 1, IDLoc, STI);
5422 if (SrcReg == Mips::ZERO) {
5423 Warning(IDLoc,
"comparison is always false");
5424 TOut.
emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
5425 DstReg, SrcReg, SrcReg, IDLoc, STI);
5430 if (Imm > -0x8000 && Imm < 0) {
5432 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5438 MCRegister ATReg = getATReg(IDLoc);
5442 if (loadImmediate(Imm, ATReg, MCRegister(),
true, isGP64bit(), IDLoc, Out,
5446 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5447 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5451 TOut.
emitRRI(
Opc, DstReg, SrcReg, Imm, IDLoc, STI);
5452 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5456bool MipsAsmParser::expandSne(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5457 const MCSubtargetInfo *STI) {
5459 MipsTargetStreamer &TOut = getTargetStreamer();
5470 warnIfNoMacro(IDLoc);
5472 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5473 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5474 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5478 MCRegister
Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5479 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO,
Reg, IDLoc, STI);
5483bool MipsAsmParser::expandSneI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5484 const MCSubtargetInfo *STI) {
5485 MipsTargetStreamer &TOut = getTargetStreamer();
5496 warnIfNoMacro(IDLoc);
5498 if (ImmValue == 0) {
5499 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, SrcReg, IDLoc, STI);
5503 if (SrcReg == Mips::ZERO) {
5504 Warning(IDLoc,
"comparison is always true");
5505 if (loadImmediate(1, DstReg, MCRegister(),
true,
false, IDLoc, Out, STI))
5511 if (ImmValue > -0x8000 && ImmValue < 0) {
5512 ImmValue = -ImmValue;
5513 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5519 TOut.
emitRRI(
Opc, DstReg, SrcReg, ImmValue, IDLoc, STI);
5520 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5524 MCRegister ATReg = getATReg(IDLoc);
5528 if (loadImmediate(ImmValue, ATReg, MCRegister(),
isInt<32>(ImmValue),
false,
5532 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5533 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5596 case Mips::F0:
return Mips::ZERO;
5597 case Mips::F1:
return Mips::AT;
5598 case Mips::F2:
return Mips::V0;
5599 case Mips::F3:
return Mips::V1;
5600 case Mips::F4:
return Mips::A0;
5601 case Mips::F5:
return Mips::A1;
5602 case Mips::F6:
return Mips::A2;
5603 case Mips::F7:
return Mips::A3;
5604 case Mips::F8:
return Mips::T0;
5605 case Mips::F9:
return Mips::T1;
5606 case Mips::F10:
return Mips::T2;
5607 case Mips::F11:
return Mips::T3;
5608 case Mips::F12:
return Mips::T4;
5609 case Mips::F13:
return Mips::T5;
5610 case Mips::F14:
return Mips::T6;
5611 case Mips::F15:
return Mips::T7;
5612 case Mips::F16:
return Mips::S0;
5613 case Mips::F17:
return Mips::S1;
5614 case Mips::F18:
return Mips::S2;
5615 case Mips::F19:
return Mips::S3;
5616 case Mips::F20:
return Mips::S4;
5617 case Mips::F21:
return Mips::S5;
5618 case Mips::F22:
return Mips::S6;
5619 case Mips::F23:
return Mips::S7;
5620 case Mips::F24:
return Mips::T8;
5621 case Mips::F25:
return Mips::T9;
5622 case Mips::F26:
return Mips::K0;
5623 case Mips::F27:
return Mips::K1;
5624 case Mips::F28:
return Mips::GP;
5625 case Mips::F29:
return Mips::SP;
5626 case Mips::F30:
return Mips::FP;
5627 case Mips::F31:
return Mips::RA;
5635 case Mips::COP00:
return Mips::ZERO;
5636 case Mips::COP01:
return Mips::AT;
5637 case Mips::COP02:
return Mips::V0;
5638 case Mips::COP03:
return Mips::V1;
5639 case Mips::COP04:
return Mips::A0;
5640 case Mips::COP05:
return Mips::A1;
5641 case Mips::COP06:
return Mips::A2;
5642 case Mips::COP07:
return Mips::A3;
5643 case Mips::COP08:
return Mips::T0;
5644 case Mips::COP09:
return Mips::T1;
5645 case Mips::COP010:
return Mips::T2;
5646 case Mips::COP011:
return Mips::T3;
5647 case Mips::COP012:
return Mips::T4;
5648 case Mips::COP013:
return Mips::T5;
5649 case Mips::COP014:
return Mips::T6;
5650 case Mips::COP015:
return Mips::T7;
5651 case Mips::COP016:
return Mips::S0;
5652 case Mips::COP017:
return Mips::S1;
5653 case Mips::COP018:
return Mips::S2;
5654 case Mips::COP019:
return Mips::S3;
5655 case Mips::COP020:
return Mips::S4;
5656 case Mips::COP021:
return Mips::S5;
5657 case Mips::COP022:
return Mips::S6;
5658 case Mips::COP023:
return Mips::S7;
5659 case Mips::COP024:
return Mips::T8;
5660 case Mips::COP025:
return Mips::T9;
5661 case Mips::COP026:
return Mips::K0;
5662 case Mips::COP027:
return Mips::K1;
5663 case Mips::COP028:
return Mips::GP;
5664 case Mips::COP029:
return Mips::SP;
5665 case Mips::COP030:
return Mips::FP;
5666 case Mips::COP031:
return Mips::RA;
5673bool MipsAsmParser::expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5674 const MCSubtargetInfo *STI) {
5675 MipsTargetStreamer &TOut = getTargetStreamer();
5680 bool IsMFTR =
false;
5734 IsMFTR ? MCRegister(rd)
5736 : Inst.getOperand(0).
getReg());
5738 TOut.
emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, u, sel, h, IDLoc,
5743bool MipsAsmParser::expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5744 const MCSubtargetInfo *STI) {
5749 warnIfNoMacro(IDLoc);
5751 MipsTargetStreamer &TOut = getTargetStreamer();
5752 unsigned Opcode = Inst.
getOpcode() == Mips::SaaAddr ? Mips::SAA : Mips::SAAD;
5755 const MCOperand &BaseOp = Inst.
getOperand(2);
5757 if (BaseOp.
isImm()) {
5758 int64_t ImmValue = BaseOp.
getImm();
5759 if (ImmValue == 0) {
5760 TOut.
emitRR(Opcode, RtReg, BaseReg, IDLoc, STI);
5765 MCRegister ATReg = getATReg(IDLoc);
5769 if (expandLoadAddress(ATReg, BaseReg, BaseOp, !isGP64bit(), IDLoc, Out, STI))
5772 TOut.
emitRR(Opcode, RtReg, ATReg, IDLoc, STI);
5777MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
5781 return Match_Success;
5784 if (
static_cast<MipsOperand &
>(*
Operands[1])
5785 .isValidForTie(
static_cast<MipsOperand &
>(*
Operands[2])))
5786 return Match_Success;
5787 return Match_RequiresSameSrcAndDst;
5791unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
5798 return Match_RequiresNoZeroRegister;
5799 return Match_Success;
5805 case Mips::JALR_HB64:
5806 case Mips::JALRC_HB_MMR6:
5807 case Mips::JALRC_MMR6:
5809 return Match_RequiresDifferentSrcAndDst;
5810 return Match_Success;
5813 return Match_RequiresDifferentSrcAndDst;
5814 return Match_Success;
5817 return Match_NonZeroOperandForSync;
5818 return Match_Success;
5824 return Match_NonZeroOperandForMTCX;
5825 return Match_Success;
5838 case Mips::BLEZC:
case Mips::BLEZC_MMR6:
5839 case Mips::BGEZC:
case Mips::BGEZC_MMR6:
5840 case Mips::BGTZC:
case Mips::BGTZC_MMR6:
5841 case Mips::BLTZC:
case Mips::BLTZC_MMR6:
5842 case Mips::BEQZC:
case Mips::BEQZC_MMR6:
5843 case Mips::BNEZC:
case Mips::BNEZC_MMR6:
5852 return Match_RequiresNoZeroRegister;
5853 return Match_Success;
5854 case Mips::BGEC:
case Mips::BGEC_MMR6:
5855 case Mips::BLTC:
case Mips::BLTC_MMR6:
5856 case Mips::BGEUC:
case Mips::BGEUC_MMR6:
5857 case Mips::BLTUC:
case Mips::BLTUC_MMR6:
5858 case Mips::BEQC:
case Mips::BEQC_MMR6:
5859 case Mips::BNEC:
case Mips::BNEC_MMR6:
5868 return Match_RequiresNoZeroRegister;
5871 return Match_RequiresNoZeroRegister;
5873 return Match_RequiresDifferentOperands;
5874 return Match_Success;
5877 "Operands must be immediates for dins!");
5880 if ((0 > (Pos +
Size)) || ((Pos +
Size) > 32))
5881 return Match_RequiresPosSizeRange0_32;
5882 return Match_Success;
5887 "Operands must be immediates for dinsm/dinsu!");
5890 if ((32 >= (Pos +
Size)) || ((Pos +
Size) > 64))
5891 return Match_RequiresPosSizeRange33_64;
5892 return Match_Success;
5896 "Operands must be immediates for DEXTM!");
5899 if ((1 > (Pos +
Size)) || ((Pos +
Size) > 63))
5900 return Match_RequiresPosSizeUImm6;
5901 return Match_Success;
5906 "Operands must be immediates for dextm/dextu!");
5909 if ((32 > (Pos +
Size)) || ((Pos +
Size) > 64))
5910 return Match_RequiresPosSizeRange33_64;
5911 return Match_Success;
5913 case Mips::CRC32B:
case Mips::CRC32CB:
5914 case Mips::CRC32H:
case Mips::CRC32CH:
5915 case Mips::CRC32W:
case Mips::CRC32CW:
5916 case Mips::CRC32D:
case Mips::CRC32CD:
5918 return Match_RequiresSameSrcAndDst;
5919 return Match_Success;
5922 uint64_t TSFlags = MII.get(Inst.
getOpcode()).TSFlags;
5925 return Match_NoFCCRegisterForCurrentISA;
5927 return Match_Success;
5935 if (ErrorLoc ==
SMLoc())
5942bool MipsAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
5945 uint64_t &ErrorInfo,
5946 bool MatchingInlineAsm) {
5948 unsigned MatchResult =
5949 MatchInstructionImpl(
Operands, Inst, ErrorInfo, MatchingInlineAsm);
5951 switch (MatchResult) {
5953 if (processInstruction(Inst, IDLoc, Out, STI))
5956 case Match_MissingFeature:
5957 Error(IDLoc,
"instruction requires a CPU feature not currently enabled");
5959 case Match_InvalidTiedOperand:
5960 Error(IDLoc,
"operand must match destination register");
5962 case Match_InvalidOperand: {
5963 SMLoc ErrorLoc = IDLoc;
5964 if (ErrorInfo != ~0ULL) {
5966 return Error(IDLoc,
"too few operands for instruction");
5968 ErrorLoc =
Operands[ErrorInfo]->getStartLoc();
5969 if (ErrorLoc == SMLoc())
5973 return Error(ErrorLoc,
"invalid operand for instruction");
5975 case Match_NonZeroOperandForSync:
5977 "s-type must be zero or unspecified for pre-MIPS32 ISAs");
5978 case Match_NonZeroOperandForMTCX:
5979 return Error(IDLoc,
"selector must be zero for pre-MIPS32 ISAs");
5980 case Match_MnemonicFail:
5981 return Error(IDLoc,
"invalid instruction");
5982 case Match_RequiresDifferentSrcAndDst:
5983 return Error(IDLoc,
"source and destination must be different");
5984 case Match_RequiresDifferentOperands:
5985 return Error(IDLoc,
"registers must be different");
5986 case Match_RequiresNoZeroRegister:
5987 return Error(IDLoc,
"invalid operand ($zero) for instruction");
5988 case Match_RequiresSameSrcAndDst:
5989 return Error(IDLoc,
"source and destination must match");
5990 case Match_NoFCCRegisterForCurrentISA:
5992 "non-zero fcc register doesn't exist in current ISA level");
5997 "expected 1-bit unsigned immediate");
6000 "expected 2-bit unsigned immediate");
6003 "expected immediate in range 1 .. 4");
6006 "expected 3-bit unsigned immediate");
6009 "expected 4-bit unsigned immediate");
6012 "expected 4-bit signed immediate");
6015 "expected 5-bit unsigned immediate");
6018 "expected 5-bit signed immediate");
6021 "expected immediate in range 1 .. 32");
6022 case Match_UImm5_32:
6024 "expected immediate in range 32 .. 63");
6025 case Match_UImm5_33:
6027 "expected immediate in range 33 .. 64");
6028 case Match_UImm5_0_Report_UImm6:
6032 "expected 6-bit unsigned immediate");
6033 case Match_UImm5_Lsl2:
6035 "expected both 7-bit unsigned immediate and multiple of 4");
6036 case Match_UImmRange2_64:
6038 "expected immediate in range 2 .. 64");
6041 "expected 6-bit unsigned immediate");
6042 case Match_UImm6_Lsl2:
6044 "expected both 8-bit unsigned immediate and multiple of 4");
6047 "expected 6-bit signed immediate");
6050 "expected 7-bit unsigned immediate");
6051 case Match_UImm7_N1:
6053 "expected immediate in range -1 .. 126");
6054 case Match_SImm7_Lsl2:
6056 "expected both 9-bit signed immediate and multiple of 4");
6059 "expected 8-bit unsigned immediate");
6060 case Match_UImm10_0:
6062 "expected 10-bit unsigned immediate");
6063 case Match_SImm10_0:
6065 "expected 10-bit signed immediate");
6066 case Match_SImm11_0:
6068 "expected 11-bit signed immediate");
6070 case Match_UImm16_Relaxed:
6071 case Match_UImm16_AltRelaxed:
6073 "expected 16-bit unsigned immediate");
6075 case Match_SImm16_Relaxed:
6077 "expected 16-bit signed immediate");
6078 case Match_SImm19_Lsl2:
6080 "expected both 19-bit signed immediate and multiple of 4");
6081 case Match_UImm20_0:
6083 "expected 20-bit unsigned immediate");
6084 case Match_UImm26_0:
6086 "expected 26-bit unsigned immediate");
6088 case Match_SImm32_Relaxed:
6090 "expected 32-bit signed immediate");
6091 case Match_UImm32_Coerced:
6093 "expected 32-bit immediate");
6094 case Match_MemSImm9:
6096 "expected memory with 9-bit signed offset");
6097 case Match_MemSImm10:
6099 "expected memory with 10-bit signed offset");
6100 case Match_MemSImm10Lsl1:
6102 "expected memory with 11-bit signed offset and multiple of 2");
6103 case Match_MemSImm10Lsl2:
6105 "expected memory with 12-bit signed offset and multiple of 4");
6106 case Match_MemSImm10Lsl3:
6108 "expected memory with 13-bit signed offset and multiple of 8");
6109 case Match_MemSImm11:
6111 "expected memory with 11-bit signed offset");
6112 case Match_MemSImm12:
6114 "expected memory with 12-bit signed offset");
6115 case Match_MemSImm16:
6117 "expected memory with 16-bit signed offset");
6118 case Match_MemSImmPtr:
6120 "expected memory with 32-bit signed offset");
6121 case Match_RequiresPosSizeRange0_32: {
6122 SMLoc ErrorStart =
Operands[3]->getStartLoc();
6123 SMLoc ErrorEnd =
Operands[4]->getEndLoc();
6124 return Error(ErrorStart,
"size plus position are not in the range 0 .. 32",
6125 SMRange(ErrorStart, ErrorEnd));
6127 case Match_RequiresPosSizeUImm6: {
6128 SMLoc ErrorStart =
Operands[3]->getStartLoc();
6129 SMLoc ErrorEnd =
Operands[4]->getEndLoc();
6130 return Error(ErrorStart,
"size plus position are not in the range 1 .. 63",
6131 SMRange(ErrorStart, ErrorEnd));
6133 case Match_RequiresPosSizeRange33_64: {
6134 SMLoc ErrorStart =
Operands[3]->getStartLoc();
6135 SMLoc ErrorEnd =
Operands[4]->getEndLoc();
6136 return Error(ErrorStart,
"size plus position are not in the range 33 .. 64",
6137 SMRange(ErrorStart, ErrorEnd));
6144void MipsAsmParser::warnIfRegIndexIsAT(MCRegister RegIndex, SMLoc Loc) {
6145 if (RegIndex && AssemblerOptions.
back()->getATRegIndex() == RegIndex)
6146 Warning(Loc,
"used $at (currently $" + Twine(RegIndex.
id()) +
6147 ") without \".set noat\"");
6150void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
6151 if (!AssemblerOptions.
back()->isMacro())
6152 Warning(Loc,
"macro instruction expanded into multiple instructions");
6155void MipsAsmParser::ConvertXWPOperands(MCInst &Inst,
6159 "Unexpected instruction!");
6160 ((MipsOperand &)*
Operands[1]).addGPR32ZeroAsmRegOperands(Inst, 1);
6161 MCRegister NextReg =
nextReg(((MipsOperand &)*
Operands[1]).getGPR32Reg());
6163 ((MipsOperand &)*
Operands[2]).addMemOperands(Inst, 2);
6167MipsAsmParser::printWarningWithFixIt(
const Twine &Msg,
const Twine &FixMsg,
6168 SMRange
Range,
bool ShowColors) {
6174int MipsAsmParser::matchCPURegisterName(StringRef Name) {
6177 CC = StringSwitch<unsigned>(Name)
6179 .Cases(
"at",
"AT", 1)
6213 if (!(isABI_N32() || isABI_N64()))
6216 if (12 <= CC && CC <= 15) {
6218 AsmToken RegTok = getLexer().peekTok();
6221 StringRef FixedName = StringSwitch<StringRef>(Name)
6227 assert(FixedName !=
"" &&
"Register name is not one of t4-t7.");
6229 printWarningWithFixIt(
"register names $t4-$t7 are only available in O32.",
6230 "Did you mean $" + FixedName +
"?", RegRange);
6236 if (8 <= CC && CC <= 11)
6240 CC = StringSwitch<unsigned>(Name)
6252int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
6255 CC = StringSwitch<unsigned>(Name)
6256 .Case(
"hwr_cpunum", 0)
6257 .Case(
"hwr_synci_step", 1)
6259 .Case(
"hwr_ccres", 3)
6260 .Case(
"hwr_ulr", 29)
6266int MipsAsmParser::matchFPURegisterName(StringRef Name) {
6267 if (Name[0] ==
'f') {
6268 StringRef NumString =
Name.substr(1);
6279int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
6280 if (
Name.starts_with(
"fcc")) {
6281 StringRef NumString =
Name.substr(3);
6292int MipsAsmParser::matchACRegisterName(StringRef Name) {
6293 if (
Name.starts_with(
"ac")) {
6294 StringRef NumString =
Name.substr(2);
6305int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
6308 if (
Name.front() !=
'w' ||
Name.drop_front(1).getAsInteger(10, IntVal))
6317int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
6320 CC = StringSwitch<unsigned>(Name)
6323 .Case(
"msaaccess", 2)
6325 .Case(
"msamodify", 4)
6326 .Case(
"msarequest", 5)
6328 .Case(
"msaunmap", 7)
6334bool MipsAsmParser::canUseATReg() {
6335 return AssemblerOptions.
back()->getATRegIndex() != 0;
6338MCRegister MipsAsmParser::getATReg(SMLoc Loc) {
6339 unsigned ATIndex = AssemblerOptions.
back()->getATRegIndex();
6341 reportParseError(Loc,
6342 "pseudo-instruction requires $at, which is not available");
6346 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
6350MCRegister MipsAsmParser::getReg(
int RC,
int RegNo) {
6351 return getContext().getRegisterInfo()->getRegClass(RC).getRegister(RegNo);
6357const MCExpr *MipsAsmParser::parseRelocExpr() {
6358 auto getOp = [](StringRef
Op) {
6359 return StringSwitch<Mips::Specifier>(
Op)
6387 MCAsmParser &Parser = getParser();
6389 const MCExpr *Res =
nullptr;
6395 auto Op = getOp(Name);
6404 while (
Ops.size()) {
6413 MCAsmParser &Parser = getParser();
6423 ParseStatus Res = MatchOperandParserImpl(
Operands, Mnemonic,
true);
6434 switch (getLexer().getKind()) {
6444 if (!parseAnyRegister(
Operands).isNoMatch())
6457 Operands.push_back(MipsOperand::CreateImm(SymRef, S,
E, *
this));
6462 const MCExpr *Expr = parseRelocExpr();
6466 Operands.push_back(MipsOperand::CreateImm(Expr, S,
E, *
this));
6473bool MipsAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
6475 return !tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess();
6478ParseStatus MipsAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
6481 ParseStatus Res = parseAnyRegister(
Operands);
6484 MipsOperand &Operand =
static_cast<MipsOperand &
>(*
Operands.front());
6485 StartLoc = Operand.getStartLoc();
6486 EndLoc = Operand.getEndLoc();
6492 if (Operand.isGPRAsmReg()) {
6494 Reg = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
6505 MCAsmParser &Parser = getParser();
6507 const MCExpr *IdVal =
nullptr;
6509 bool isParenExpr =
false;
6520 IdVal = parseRelocExpr();
6526 const AsmToken &Tok = Parser.
getTok();
6528 MipsOperand &Mnemonic =
static_cast<MipsOperand &
>(*
Operands[0]);
6529 if (Mnemonic.getToken() ==
"la" || Mnemonic.getToken() ==
"dla") {
6532 Operands.push_back(MipsOperand::CreateImm(IdVal, S,
E, *
this));
6541 auto Base = MipsOperand::createGPRReg(
6542 0,
"0",
getContext().getRegisterInfo(), S,
E, *
this);
6544 MipsOperand::CreateMem(std::move(
Base), IdVal, S,
E, *
this));
6596 const MCExpr * NextExpr;
6597 if (getParser().parseExpression(NextExpr))
6620 std::unique_ptr<MipsOperand>
op(
6621 static_cast<MipsOperand *
>(
Operands.back().release()));
6628 if (IdVal->evaluateAsAbsolute(Imm))
6635 Operands.push_back(MipsOperand::CreateMem(std::move(
op), IdVal, S,
E, *
this));
6640 MCAsmParser &Parser = getParser();
6649 const MCSymbolRefExpr *
Ref =
static_cast<const MCSymbolRefExpr *
>(Expr);
6650 StringRef DefSymbol =
Ref->getSymbol().getName();
6653 matchAnyRegisterNameWithoutDollar(
Operands, DefSymbol.
substr(1), S);
6667 if (Entry != RegisterSets.
end()) {
6669 matchAnyRegisterWithoutDollar(
Operands,
Entry->getValue(), S);
6680ParseStatus MipsAsmParser::matchAnyRegisterNameWithoutDollar(
6682 int Index = matchCPURegisterName(Identifier);
6684 Operands.push_back(MipsOperand::createGPRReg(
6685 Index, Identifier,
getContext().getRegisterInfo(), S,
6686 getLexer().getLoc(), *
this));
6690 Index = matchHWRegsRegisterName(Identifier);
6692 Operands.push_back(MipsOperand::createHWRegsReg(
6693 Index, Identifier,
getContext().getRegisterInfo(), S,
6694 getLexer().getLoc(), *
this));
6698 Index = matchFPURegisterName(Identifier);
6700 Operands.push_back(MipsOperand::createFGRReg(
6701 Index, Identifier,
getContext().getRegisterInfo(), S,
6702 getLexer().getLoc(), *
this));
6706 Index = matchFCCRegisterName(Identifier);
6708 Operands.push_back(MipsOperand::createFCCReg(
6709 Index, Identifier,
getContext().getRegisterInfo(), S,
6710 getLexer().getLoc(), *
this));
6714 Index = matchACRegisterName(Identifier);
6716 Operands.push_back(MipsOperand::createACCReg(
6717 Index, Identifier,
getContext().getRegisterInfo(), S,
6718 getLexer().getLoc(), *
this));
6722 Index = matchMSA128RegisterName(Identifier);
6724 Operands.push_back(MipsOperand::createMSA128Reg(
6725 Index, Identifier,
getContext().getRegisterInfo(), S,
6726 getLexer().getLoc(), *
this));
6730 Index = matchMSA128CtrlRegisterName(Identifier);
6732 Operands.push_back(MipsOperand::createMSACtrlReg(
6733 Index, Identifier,
getContext().getRegisterInfo(), S,
6734 getLexer().getLoc(), *
this));
6743 const AsmToken &Token, SMLoc S) {
6747 return matchAnyRegisterNameWithoutDollar(
Operands, Identifier, S);
6752 if (RegNum < 0 || RegNum > 31) {
6756 Error(getLexer().getLoc(),
"invalid register number");
6758 Operands.push_back(MipsOperand::createNumericReg(
6771 auto Token = getLexer().peekTok(
false);
6772 return matchAnyRegisterWithoutDollar(
Operands, Token, S);
6776 MCAsmParser &Parser = getParser();
6779 auto Token = Parser.
getTok();
6781 SMLoc S = Token.
getLoc();
6794 ParseStatus Res = matchAnyRegisterWithoutDollar(
Operands, S);
6803 MCAsmParser &Parser = getParser();
6806 SMLoc S = getLexer().getLoc();
6809 ParseStatus Res = parseAnyRegister(
Operands);
6814 const MCExpr *Expr =
nullptr;
6820 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *
this));
6825 MCAsmParser &Parser = getParser();
6826 const MCExpr *IdVal;
6837 if (getParser().parseExpression(IdVal))
6844 Operands.push_back(MipsOperand::CreateImm(
6850 MCAsmParser &Parser = getParser();
6853 unsigned PrevReg = Mips::NoRegister;
6854 bool RegRange =
false;
6861 while (parseAnyRegister(TmpOperands).isSuccess()) {
6862 SMLoc
E = getLexer().getLoc();
6863 MipsOperand &
Reg =
static_cast<MipsOperand &
>(*TmpOperands.
back());
6864 RegNo = isGP64bit() ?
Reg.getGPR64Reg() :
Reg.getGPR32Reg();
6868 if ((isGP64bit() && RegNo == Mips::RA_64) ||
6869 (!isGP64bit() && RegNo == Mips::RA)) {
6872 unsigned TmpReg = PrevReg + 1;
6873 while (TmpReg <= RegNo) {
6874 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
6875 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
6877 return Error(
E,
"invalid register operand");
6886 if ((PrevReg == Mips::NoRegister) &&
6887 ((isGP64bit() && (RegNo != Mips::S0_64) && (RegNo != Mips::RA_64)) ||
6888 (!isGP64bit() && (RegNo != Mips::S0) && (RegNo != Mips::RA))))
6889 return Error(
E,
"$16 or $31 expected");
6890 if (!(((RegNo == Mips::FP || RegNo == Mips::RA ||
6891 (RegNo >= Mips::S0 && RegNo <= Mips::S7)) &&
6893 ((RegNo == Mips::FP_64 || RegNo == Mips::RA_64 ||
6894 (RegNo >= Mips::S0_64 && RegNo <= Mips::S7_64)) &&
6896 return Error(
E,
"invalid register operand");
6897 if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
6898 ((RegNo != Mips::FP && RegNo != Mips::RA && !isGP64bit()) ||
6899 (RegNo != Mips::FP_64 && RegNo != Mips::RA_64 && isGP64bit())))
6900 return Error(
E,
"consecutive register numbers expected");
6910 return Error(
E,
"',' or '-' expected");
6920 Operands.push_back(MipsOperand::CreateRegList(Regs, S,
E, *
this));
6931 MCAsmParser &Parser = getParser();
6934 MipsOperand::CreateToken(
"(", getLexer().getLoc(), *
this));
6936 if (parseOperand(
Operands, Name)) {
6937 SMLoc Loc = getLexer().getLoc();
6938 return Error(Loc,
"unexpected token in argument list");
6941 SMLoc Loc = getLexer().getLoc();
6942 return Error(Loc,
"unexpected token, expected ')'");
6945 MipsOperand::CreateToken(
")", getLexer().getLoc(), *
this));
6957bool MipsAsmParser::parseBracketSuffix(StringRef Name,
6959 MCAsmParser &Parser = getParser();
6962 MipsOperand::CreateToken(
"[", getLexer().getLoc(), *
this));
6964 if (parseOperand(
Operands, Name)) {
6965 SMLoc Loc = getLexer().getLoc();
6966 return Error(Loc,
"unexpected token in argument list");
6969 SMLoc Loc = getLexer().getLoc();
6970 return Error(Loc,
"unexpected token, expected ']'");
6973 MipsOperand::CreateToken(
"]", getLexer().getLoc(), *
this));
6980 unsigned VariantID = 0);
6995bool MipsAsmParser::parseInstruction(ParseInstructionInfo &
Info, StringRef Name,
6997 MCAsmParser &Parser = getParser();
7001 getTargetStreamer().forbidModuleDirective();
7004 if (!mnemonicIsValid(Name, 0)) {
7005 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
7007 return Error(NameLoc,
"unknown instruction" + Suggestion);
7010 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *
this));
7015 if (parseOperand(
Operands, Name)) {
7016 SMLoc Loc = getLexer().getLoc();
7017 return Error(Loc,
"unexpected token in argument list");
7026 if (parseOperand(
Operands, Name)) {
7027 SMLoc Loc = getLexer().getLoc();
7028 return Error(Loc,
"unexpected token in argument list");
7032 if (parseBracketSuffix(Name,
Operands))
7040 SMLoc Loc = getLexer().getLoc();
7041 return Error(Loc,
"unexpected token in argument list");
7049bool MipsAsmParser::reportParseError(
const Twine &ErrorMsg) {
7050 SMLoc Loc = getLexer().getLoc();
7051 return Error(Loc, ErrorMsg);
7054bool MipsAsmParser::reportParseError(SMLoc Loc,
const Twine &ErrorMsg) {
7055 return Error(Loc, ErrorMsg);
7058bool MipsAsmParser::parseSetNoAtDirective() {
7059 MCAsmParser &Parser = getParser();
7063 AssemblerOptions.
back()->setATRegIndex(0);
7069 reportParseError(
"unexpected token, expected end of statement");
7073 getTargetStreamer().emitDirectiveSetNoAt();
7078bool MipsAsmParser::parseSetAtDirective() {
7081 MCAsmParser &Parser = getParser();
7086 AssemblerOptions.
back()->setATRegIndex(1);
7088 getTargetStreamer().emitDirectiveSetAt();
7094 reportParseError(
"unexpected token, expected equals sign");
7101 reportParseError(
"no register specified");
7104 reportParseError(
"unexpected token, expected dollar sign '$'");
7114 AtRegNo = matchCPURegisterName(
Reg.getIdentifier());
7116 AtRegNo =
Reg.getIntVal();
7118 reportParseError(
"unexpected token, expected identifier or integer");
7123 if (!AssemblerOptions.
back()->setATRegIndex(AtRegNo)) {
7124 reportParseError(
"invalid register");
7131 reportParseError(
"unexpected token, expected end of statement");
7135 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
7141bool MipsAsmParser::parseSetReorderDirective() {
7142 MCAsmParser &Parser = getParser();
7146 reportParseError(
"unexpected token, expected end of statement");
7149 AssemblerOptions.
back()->setReorder();
7150 getTargetStreamer().emitDirectiveSetReorder();
7155bool MipsAsmParser::parseSetNoReorderDirective() {
7156 MCAsmParser &Parser = getParser();
7160 reportParseError(
"unexpected token, expected end of statement");
7163 AssemblerOptions.
back()->setNoReorder();
7164 getTargetStreamer().emitDirectiveSetNoReorder();
7169bool MipsAsmParser::parseSetMacroDirective() {
7170 MCAsmParser &Parser = getParser();
7174 reportParseError(
"unexpected token, expected end of statement");
7177 AssemblerOptions.
back()->setMacro();
7178 getTargetStreamer().emitDirectiveSetMacro();
7183bool MipsAsmParser::parseSetNoMacroDirective() {
7184 MCAsmParser &Parser = getParser();
7188 reportParseError(
"unexpected token, expected end of statement");
7191 if (AssemblerOptions.
back()->isReorder()) {
7192 reportParseError(
"`noreorder' must be set before `nomacro'");
7195 AssemblerOptions.
back()->setNoMacro();
7196 getTargetStreamer().emitDirectiveSetNoMacro();
7201bool MipsAsmParser::parseSetMsaDirective() {
7202 MCAsmParser &Parser = getParser();
7207 return reportParseError(
"unexpected token, expected end of statement");
7209 setFeatureBits(Mips::FeatureMSA,
"msa");
7210 getTargetStreamer().emitDirectiveSetMsa();
7214bool MipsAsmParser::parseSetNoMsaDirective() {
7215 MCAsmParser &Parser = getParser();
7220 return reportParseError(
"unexpected token, expected end of statement");
7222 clearFeatureBits(Mips::FeatureMSA,
"msa");
7223 getTargetStreamer().emitDirectiveSetNoMsa();
7227bool MipsAsmParser::parseSetNoDspDirective() {
7228 MCAsmParser &Parser = getParser();
7233 reportParseError(
"unexpected token, expected end of statement");
7237 clearFeatureBits(Mips::FeatureDSP,
"dsp");
7238 getTargetStreamer().emitDirectiveSetNoDsp();
7242bool MipsAsmParser::parseSetNoMips3DDirective() {
7243 MCAsmParser &Parser = getParser();
7248 reportParseError(
"unexpected token, expected end of statement");
7252 clearFeatureBits(Mips::FeatureMips3D,
"mips3d");
7253 getTargetStreamer().emitDirectiveSetNoMips3D();
7257bool MipsAsmParser::parseSetMips16Directive() {
7258 MCAsmParser &Parser = getParser();
7263 reportParseError(
"unexpected token, expected end of statement");
7267 setFeatureBits(Mips::FeatureMips16,
"mips16");
7268 getTargetStreamer().emitDirectiveSetMips16();
7273bool MipsAsmParser::parseSetNoMips16Directive() {
7274 MCAsmParser &Parser = getParser();
7279 reportParseError(
"unexpected token, expected end of statement");
7283 clearFeatureBits(Mips::FeatureMips16,
"mips16");
7284 getTargetStreamer().emitDirectiveSetNoMips16();
7289bool MipsAsmParser::parseSetFpDirective() {
7290 MCAsmParser &Parser = getParser();
7296 AsmToken Tok = Parser.
getTok();
7298 reportParseError(
"unexpected token, expected equals sign '='");
7304 if (!parseFpABIValue(FpAbiVal,
".set"))
7308 reportParseError(
"unexpected token, expected end of statement");
7311 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
7316bool MipsAsmParser::parseSetOddSPRegDirective() {
7317 MCAsmParser &Parser = getParser();
7321 reportParseError(
"unexpected token, expected end of statement");
7325 clearFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
7326 getTargetStreamer().emitDirectiveSetOddSPReg();
7330bool MipsAsmParser::parseSetNoOddSPRegDirective() {
7331 MCAsmParser &Parser = getParser();
7335 reportParseError(
"unexpected token, expected end of statement");
7339 setFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
7340 getTargetStreamer().emitDirectiveSetNoOddSPReg();
7344bool MipsAsmParser::parseSetMtDirective() {
7345 MCAsmParser &Parser = getParser();
7350 reportParseError(
"unexpected token, expected end of statement");
7354 setFeatureBits(Mips::FeatureMT,
"mt");
7355 getTargetStreamer().emitDirectiveSetMt();
7360bool MipsAsmParser::parseSetNoMtDirective() {
7361 MCAsmParser &Parser = getParser();
7366 reportParseError(
"unexpected token, expected end of statement");
7370 clearFeatureBits(Mips::FeatureMT,
"mt");
7372 getTargetStreamer().emitDirectiveSetNoMt();
7377bool MipsAsmParser::parseSetNoCRCDirective() {
7378 MCAsmParser &Parser = getParser();
7383 reportParseError(
"unexpected token, expected end of statement");
7387 clearFeatureBits(Mips::FeatureCRC,
"crc");
7389 getTargetStreamer().emitDirectiveSetNoCRC();
7394bool MipsAsmParser::parseSetNoVirtDirective() {
7395 MCAsmParser &Parser = getParser();
7400 reportParseError(
"unexpected token, expected end of statement");
7404 clearFeatureBits(Mips::FeatureVirt,
"virt");
7406 getTargetStreamer().emitDirectiveSetNoVirt();
7411bool MipsAsmParser::parseSetNoGINVDirective() {
7412 MCAsmParser &Parser = getParser();
7417 reportParseError(
"unexpected token, expected end of statement");
7421 clearFeatureBits(Mips::FeatureGINV,
"ginv");
7423 getTargetStreamer().emitDirectiveSetNoGINV();
7428bool MipsAsmParser::parseSetPopDirective() {
7429 MCAsmParser &Parser = getParser();
7430 SMLoc Loc = getLexer().getLoc();
7434 return reportParseError(
"unexpected token, expected end of statement");
7438 if (AssemblerOptions.
size() == 2)
7439 return reportParseError(Loc,
".set pop with no .set push");
7441 MCSubtargetInfo &STI = copySTI();
7443 setAvailableFeatures(
7444 ComputeAvailableFeatures(AssemblerOptions.
back()->getFeatures()));
7447 getTargetStreamer().emitDirectiveSetPop();
7451bool MipsAsmParser::parseSetPushDirective() {
7452 MCAsmParser &Parser = getParser();
7455 return reportParseError(
"unexpected token, expected end of statement");
7459 std::make_unique<MipsAssemblerOptions>(AssemblerOptions.
back().get()));
7461 getTargetStreamer().emitDirectiveSetPush();
7465bool MipsAsmParser::parseSetSoftFloatDirective() {
7466 MCAsmParser &Parser = getParser();
7469 return reportParseError(
"unexpected token, expected end of statement");
7471 setFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
7472 getTargetStreamer().emitDirectiveSetSoftFloat();
7476bool MipsAsmParser::parseSetHardFloatDirective() {
7477 MCAsmParser &Parser = getParser();
7480 return reportParseError(
"unexpected token, expected end of statement");
7482 clearFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
7483 getTargetStreamer().emitDirectiveSetHardFloat();
7487bool MipsAsmParser::parseSetAssignment() {
7489 MCAsmParser &Parser = getParser();
7492 return reportParseError(
"expected identifier after .set");
7495 return reportParseError(
"unexpected token, expected comma");
7510 const MCExpr *
Value;
7512 Parser, Sym,
Value))
7514 getStreamer().emitAssignment(Sym,
Value);
7519bool MipsAsmParser::parseSetMips0Directive() {
7520 MCAsmParser &Parser = getParser();
7523 return reportParseError(
"unexpected token, expected end of statement");
7526 MCSubtargetInfo &STI = copySTI();
7527 setAvailableFeatures(
7528 ComputeAvailableFeatures(AssemblerOptions.
front()->getFeatures()));
7530 AssemblerOptions.
back()->setFeatures(AssemblerOptions.
front()->getFeatures());
7532 getTargetStreamer().emitDirectiveSetMips0();
7536bool MipsAsmParser::parseSetArchDirective() {
7537 MCAsmParser &Parser = getParser();
7540 return reportParseError(
"unexpected token, expected equals sign");
7543 StringRef Arch = getParser().parseStringToEndOfStatement().trim();
7545 return reportParseError(
"expected arch identifier");
7547 StringRef ArchFeatureName =
7548 StringSwitch<StringRef>(Arch)
7549 .Case(
"mips1",
"mips1")
7550 .Case(
"mips2",
"mips2")
7551 .Case(
"mips3",
"mips3")
7552 .Case(
"mips4",
"mips4")
7553 .Case(
"mips5",
"mips5")
7554 .Case(
"mips32",
"mips32")
7555 .Case(
"mips32r2",
"mips32r2")
7556 .Case(
"mips32r3",
"mips32r3")
7557 .Case(
"mips32r5",
"mips32r5")
7558 .Case(
"mips32r6",
"mips32r6")
7559 .Case(
"mips64",
"mips64")
7560 .Case(
"mips64r2",
"mips64r2")
7561 .Case(
"mips64r3",
"mips64r3")
7562 .Case(
"mips64r5",
"mips64r5")
7563 .Case(
"mips64r6",
"mips64r6")
7564 .Case(
"octeon",
"cnmips")
7565 .Case(
"octeon+",
"cnmipsp")
7566 .Case(
"r4000",
"mips3")
7569 if (ArchFeatureName.
empty())
7570 return reportParseError(
"unsupported architecture");
7572 if (ArchFeatureName ==
"mips64r6" && inMicroMipsMode())
7573 return reportParseError(
"mips64r6 does not support microMIPS");
7575 selectArch(ArchFeatureName);
7576 getTargetStreamer().emitDirectiveSetArch(Arch);
7580bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
7581 MCAsmParser &Parser = getParser();
7584 return reportParseError(
"unexpected token, expected end of statement");
7589 case Mips::FeatureMips3D:
7590 setFeatureBits(Mips::FeatureMips3D,
"mips3d");
7591 getTargetStreamer().emitDirectiveSetMips3D();
7593 case Mips::FeatureDSP:
7594 setFeatureBits(Mips::FeatureDSP,
"dsp");
7595 getTargetStreamer().emitDirectiveSetDsp();
7597 case Mips::FeatureDSPR2:
7598 setFeatureBits(Mips::FeatureDSPR2,
"dspr2");
7599 getTargetStreamer().emitDirectiveSetDspr2();
7601 case Mips::FeatureMicroMips:
7602 setFeatureBits(Mips::FeatureMicroMips,
"micromips");
7603 getTargetStreamer().emitDirectiveSetMicroMips();
7605 case Mips::FeatureMips1:
7606 selectArch(
"mips1");
7607 getTargetStreamer().emitDirectiveSetMips1();
7609 case Mips::FeatureMips2:
7610 selectArch(
"mips2");
7611 getTargetStreamer().emitDirectiveSetMips2();
7613 case Mips::FeatureMips3:
7614 selectArch(
"mips3");
7615 getTargetStreamer().emitDirectiveSetMips3();
7617 case Mips::FeatureMips4:
7618 selectArch(
"mips4");
7619 getTargetStreamer().emitDirectiveSetMips4();
7621 case Mips::FeatureMips5:
7622 selectArch(
"mips5");
7623 getTargetStreamer().emitDirectiveSetMips5();
7625 case Mips::FeatureMips32:
7626 selectArch(
"mips32");
7627 getTargetStreamer().emitDirectiveSetMips32();
7629 case Mips::FeatureMips32r2:
7630 selectArch(
"mips32r2");
7631 getTargetStreamer().emitDirectiveSetMips32R2();
7633 case Mips::FeatureMips32r3:
7634 selectArch(
"mips32r3");
7635 getTargetStreamer().emitDirectiveSetMips32R3();
7637 case Mips::FeatureMips32r5:
7638 selectArch(
"mips32r5");
7639 getTargetStreamer().emitDirectiveSetMips32R5();
7641 case Mips::FeatureMips32r6:
7642 selectArch(
"mips32r6");
7643 getTargetStreamer().emitDirectiveSetMips32R6();
7645 case Mips::FeatureMips64:
7646 selectArch(
"mips64");
7647 getTargetStreamer().emitDirectiveSetMips64();
7649 case Mips::FeatureMips64r2:
7650 selectArch(
"mips64r2");
7651 getTargetStreamer().emitDirectiveSetMips64R2();
7653 case Mips::FeatureMips64r3:
7654 selectArch(
"mips64r3");
7655 getTargetStreamer().emitDirectiveSetMips64R3();
7657 case Mips::FeatureMips64r5:
7658 selectArch(
"mips64r5");
7659 getTargetStreamer().emitDirectiveSetMips64R5();
7661 case Mips::FeatureMips64r6:
7662 selectArch(
"mips64r6");
7663 getTargetStreamer().emitDirectiveSetMips64R6();
7665 case Mips::FeatureCRC:
7666 setFeatureBits(Mips::FeatureCRC,
"crc");
7667 getTargetStreamer().emitDirectiveSetCRC();
7669 case Mips::FeatureVirt:
7670 setFeatureBits(Mips::FeatureVirt,
"virt");
7671 getTargetStreamer().emitDirectiveSetVirt();
7673 case Mips::FeatureGINV:
7674 setFeatureBits(Mips::FeatureGINV,
"ginv");
7675 getTargetStreamer().emitDirectiveSetGINV();
7681bool MipsAsmParser::eatComma(StringRef ErrorStr) {
7682 MCAsmParser &Parser = getParser();
7684 SMLoc Loc = getLexer().getLoc();
7685 return Error(Loc, ErrorStr);
7696bool MipsAsmParser::isPicAndNotNxxAbi() {
7697 return inPicMode() && !(isABI_N32() || isABI_N64());
7700bool MipsAsmParser::parseDirectiveCpAdd(SMLoc Loc) {
7702 ParseStatus Res = parseAnyRegister(
Reg);
7704 reportParseError(
"expected register");
7708 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7709 if (!RegOpnd.isGPRAsmReg()) {
7710 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7716 reportParseError(
"unexpected token, expected end of statement");
7721 getTargetStreamer().emitDirectiveCpAdd(RegOpnd.getGPR32Reg());
7725bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
7726 if (AssemblerOptions.
back()->isReorder())
7727 Warning(Loc,
".cpload should be inside a noreorder section");
7729 if (inMips16Mode()) {
7730 reportParseError(
".cpload is not supported in Mips16 mode");
7735 ParseStatus Res = parseAnyRegister(
Reg);
7737 reportParseError(
"expected register containing function address");
7741 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7742 if (!RegOpnd.isGPRAsmReg()) {
7743 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7749 reportParseError(
"unexpected token, expected end of statement");
7753 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
7757bool MipsAsmParser::parseDirectiveCpLocal(SMLoc Loc) {
7758 if (!isABI_N32() && !isABI_N64()) {
7759 reportParseError(
".cplocal is allowed only in N32 or N64 mode");
7764 ParseStatus Res = parseAnyRegister(
Reg);
7766 reportParseError(
"expected register containing global pointer");
7770 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7771 if (!RegOpnd.isGPRAsmReg()) {
7772 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7778 reportParseError(
"unexpected token, expected end of statement");
7783 unsigned NewReg = RegOpnd.getGPR32Reg();
7787 getTargetStreamer().emitDirectiveCpLocal(NewReg);
7791bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
7792 MCAsmParser &Parser = getParser();
7797 if (inMips16Mode()) {
7798 reportParseError(
".cprestore is not supported in Mips16 mode");
7803 const MCExpr *StackOffset;
7804 int64_t StackOffsetVal;
7806 reportParseError(
"expected stack offset value");
7810 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
7811 reportParseError(
"stack offset is not an absolute expression");
7815 if (StackOffsetVal < 0) {
7816 Warning(Loc,
".cprestore with negative stack offset has no effect");
7817 IsCpRestoreSet =
false;
7819 IsCpRestoreSet =
true;
7820 CpRestoreOffset = StackOffsetVal;
7825 reportParseError(
"unexpected token, expected end of statement");
7829 if (!getTargetStreamer().emitDirectiveCpRestore(
7830 CpRestoreOffset, [&]() {
return getATReg(Loc); }, Loc, STI))
7836bool MipsAsmParser::parseDirectiveCPSetup() {
7837 MCAsmParser &Parser = getParser();
7840 bool SaveIsReg =
true;
7843 ParseStatus Res = parseAnyRegister(TmpReg);
7845 reportParseError(
"expected register containing function address");
7849 MipsOperand &FuncRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7850 if (!FuncRegOpnd.isGPRAsmReg()) {
7851 reportParseError(FuncRegOpnd.getStartLoc(),
"invalid register");
7855 FuncReg = FuncRegOpnd.getGPR32Reg();
7858 if (!eatComma(
"unexpected token, expected comma"))
7861 Res = parseAnyRegister(TmpReg);
7863 const MCExpr *OffsetExpr;
7865 SMLoc ExprLoc = getLexer().
getLoc();
7868 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
7869 reportParseError(ExprLoc,
"expected save register or stack offset");
7876 MipsOperand &SaveOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7877 if (!SaveOpnd.isGPRAsmReg()) {
7878 reportParseError(SaveOpnd.getStartLoc(),
"invalid register");
7881 Save = SaveOpnd.getGPR32Reg();
7884 if (!eatComma(
"unexpected token, expected comma"))
7889 reportParseError(
"expected expression");
7894 reportParseError(
"expected symbol");
7897 const MCSymbolRefExpr *
Ref =
static_cast<const MCSymbolRefExpr *
>(Expr);
7899 CpSaveLocation = Save;
7900 CpSaveLocationIsRegister = SaveIsReg;
7902 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save,
Ref->getSymbol(),
7907bool MipsAsmParser::parseDirectiveCPReturn() {
7908 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
7909 CpSaveLocationIsRegister);
7913bool MipsAsmParser::parseDirectiveNaN() {
7914 MCAsmParser &Parser = getParser();
7916 const AsmToken &Tok = Parser.
getTok();
7920 getTargetStreamer().emitDirectiveNaN2008();
7922 }
else if (Tok.
getString() ==
"legacy") {
7924 getTargetStreamer().emitDirectiveNaNLegacy();
7930 reportParseError(
"invalid option in .nan directive");
7934bool MipsAsmParser::parseDirectiveSet() {
7935 const AsmToken &Tok = getParser().getTok();
7937 SMLoc Loc = Tok.
getLoc();
7939 if (IdVal ==
"noat")
7940 return parseSetNoAtDirective();
7942 return parseSetAtDirective();
7943 if (IdVal ==
"arch")
7944 return parseSetArchDirective();
7945 if (IdVal ==
"bopt") {
7946 Warning(Loc,
"'bopt' feature is unsupported");
7950 if (IdVal ==
"nobopt") {
7956 return parseSetFpDirective();
7957 if (IdVal ==
"oddspreg")
7958 return parseSetOddSPRegDirective();
7959 if (IdVal ==
"nooddspreg")
7960 return parseSetNoOddSPRegDirective();
7962 return parseSetPopDirective();
7963 if (IdVal ==
"push")
7964 return parseSetPushDirective();
7965 if (IdVal ==
"reorder")
7966 return parseSetReorderDirective();
7967 if (IdVal ==
"noreorder")
7968 return parseSetNoReorderDirective();
7969 if (IdVal ==
"macro")
7970 return parseSetMacroDirective();
7971 if (IdVal ==
"nomacro")
7972 return parseSetNoMacroDirective();
7973 if (IdVal ==
"mips16")
7974 return parseSetMips16Directive();
7975 if (IdVal ==
"nomips16")
7976 return parseSetNoMips16Directive();
7977 if (IdVal ==
"nomicromips") {
7978 clearFeatureBits(Mips::FeatureMicroMips,
"micromips");
7979 getTargetStreamer().emitDirectiveSetNoMicroMips();
7980 getParser().eatToEndOfStatement();
7983 if (IdVal ==
"micromips") {
7984 if (hasMips64r6()) {
7985 Error(Loc,
".set micromips directive is not supported with MIPS64R6");
7988 return parseSetFeature(Mips::FeatureMicroMips);
7990 if (IdVal ==
"mips0")
7991 return parseSetMips0Directive();
7992 if (IdVal ==
"mips1")
7993 return parseSetFeature(Mips::FeatureMips1);
7994 if (IdVal ==
"mips2")
7995 return parseSetFeature(Mips::FeatureMips2);
7996 if (IdVal ==
"mips3")
7997 return parseSetFeature(Mips::FeatureMips3);
7998 if (IdVal ==
"mips4")
7999 return parseSetFeature(Mips::FeatureMips4);
8000 if (IdVal ==
"mips5")
8001 return parseSetFeature(Mips::FeatureMips5);
8002 if (IdVal ==
"mips32")
8003 return parseSetFeature(Mips::FeatureMips32);
8004 if (IdVal ==
"mips32r2")
8005 return parseSetFeature(Mips::FeatureMips32r2);
8006 if (IdVal ==
"mips32r3")
8007 return parseSetFeature(Mips::FeatureMips32r3);
8008 if (IdVal ==
"mips32r5")
8009 return parseSetFeature(Mips::FeatureMips32r5);
8010 if (IdVal ==
"mips32r6")
8011 return parseSetFeature(Mips::FeatureMips32r6);
8012 if (IdVal ==
"mips64")
8013 return parseSetFeature(Mips::FeatureMips64);
8014 if (IdVal ==
"mips64r2")
8015 return parseSetFeature(Mips::FeatureMips64r2);
8016 if (IdVal ==
"mips64r3")
8017 return parseSetFeature(Mips::FeatureMips64r3);
8018 if (IdVal ==
"mips64r5")
8019 return parseSetFeature(Mips::FeatureMips64r5);
8020 if (IdVal ==
"mips64r6") {
8021 if (inMicroMipsMode()) {
8022 Error(Loc,
"MIPS64R6 is not supported with microMIPS");
8025 return parseSetFeature(Mips::FeatureMips64r6);
8028 return parseSetFeature(Mips::FeatureDSP);
8029 if (IdVal ==
"dspr2")
8030 return parseSetFeature(Mips::FeatureDSPR2);
8031 if (IdVal ==
"nodsp")
8032 return parseSetNoDspDirective();
8033 if (IdVal ==
"mips3d")
8034 return parseSetFeature(Mips::FeatureMips3D);
8035 if (IdVal ==
"nomips3d")
8036 return parseSetNoMips3DDirective();
8038 return parseSetMsaDirective();
8039 if (IdVal ==
"nomsa")
8040 return parseSetNoMsaDirective();
8042 return parseSetMtDirective();
8043 if (IdVal ==
"nomt")
8044 return parseSetNoMtDirective();
8045 if (IdVal ==
"softfloat")
8046 return parseSetSoftFloatDirective();
8047 if (IdVal ==
"hardfloat")
8048 return parseSetHardFloatDirective();
8050 return parseSetFeature(Mips::FeatureCRC);
8051 if (IdVal ==
"nocrc")
8052 return parseSetNoCRCDirective();
8053 if (IdVal ==
"virt")
8054 return parseSetFeature(Mips::FeatureVirt);
8055 if (IdVal ==
"novirt")
8056 return parseSetNoVirtDirective();
8057 if (IdVal ==
"ginv")
8058 return parseSetFeature(Mips::FeatureGINV);
8059 if (IdVal ==
"noginv")
8060 return parseSetNoGINVDirective();
8063 return parseSetAssignment();
8068bool MipsAsmParser::parseDirectiveGpWord() {
8069 const MCExpr *
Value;
8070 if (getParser().parseExpression(
Value))
8072 getTargetStreamer().emitGPRel32Value(
Value);
8078bool MipsAsmParser::parseDirectiveGpDWord() {
8079 const MCExpr *
Value;
8080 if (getParser().parseExpression(
Value))
8082 getTargetStreamer().emitGPRel64Value(
Value);
8088bool MipsAsmParser::parseDirectiveDtpRelWord() {
8089 const MCExpr *
Value;
8090 if (getParser().parseExpression(
Value))
8092 getTargetStreamer().emitDTPRel32Value(
Value);
8098bool MipsAsmParser::parseDirectiveDtpRelDWord() {
8099 const MCExpr *
Value;
8100 if (getParser().parseExpression(
Value))
8102 getTargetStreamer().emitDTPRel64Value(
Value);
8108bool MipsAsmParser::parseDirectiveTpRelWord() {
8109 const MCExpr *
Value;
8110 if (getParser().parseExpression(
Value))
8112 getTargetStreamer().emitTPRel32Value(
Value);
8118bool MipsAsmParser::parseDirectiveTpRelDWord() {
8119 const MCExpr *
Value;
8120 if (getParser().parseExpression(
Value))
8122 getTargetStreamer().emitTPRel64Value(
Value);
8126bool MipsAsmParser::parseDirectiveOption() {
8127 MCAsmParser &Parser = getParser();
8129 AsmToken Tok = Parser.
getTok();
8133 "unexpected token, expected identifier");
8138 if (Option ==
"pic0") {
8140 IsPicEnabled =
false;
8142 getTargetStreamer().emitDirectiveOptionPic0();
8146 "unexpected token, expected end of statement");
8151 if (Option ==
"pic2") {
8153 IsPicEnabled =
true;
8155 getTargetStreamer().emitDirectiveOptionPic2();
8159 "unexpected token, expected end of statement");
8166 "unknown option, expected 'pic0' or 'pic2'");
8173bool MipsAsmParser::parseInsnDirective() {
8176 reportParseError(
"unexpected token, expected end of statement");
8182 getTargetStreamer().emitDirectiveInsn();
8190bool MipsAsmParser::parseRSectionDirective(StringRef Section) {
8193 reportParseError(
"unexpected token, expected end of statement");
8197 MCSection *ELFSection =
getContext().getELFSection(
8199 getParser().getStreamer().switchSection(ELFSection);
8208bool MipsAsmParser::parseSSectionDirective(StringRef Section,
unsigned Type) {
8211 reportParseError(
"unexpected token, expected end of statement");
8215 MCSection *ELFSection =
getContext().getELFSection(
8217 getParser().getStreamer().switchSection(ELFSection);
8236bool MipsAsmParser::parseDirectiveModule() {
8237 MCAsmParser &Parser = getParser();
8238 AsmLexer &Lexer = getLexer();
8241 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
8243 reportParseError(
".module directive must appear before any code");
8249 reportParseError(
"expected .module option identifier");
8253 if (Option ==
"oddspreg") {
8254 clearModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
8258 getTargetStreamer().updateABIInfo(*
this);
8263 getTargetStreamer().emitDirectiveModuleOddSPReg();
8267 reportParseError(
"unexpected token, expected end of statement");
8272 }
else if (Option ==
"nooddspreg") {
8274 return Error(L,
"'.module nooddspreg' requires the O32 ABI");
8277 setModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
8281 getTargetStreamer().updateABIInfo(*
this);
8286 getTargetStreamer().emitDirectiveModuleOddSPReg();
8290 reportParseError(
"unexpected token, expected end of statement");
8295 }
else if (Option ==
"fp") {
8296 return parseDirectiveModuleFP();
8297 }
else if (Option ==
"softfloat") {
8298 setModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
8302 getTargetStreamer().updateABIInfo(*
this);
8307 getTargetStreamer().emitDirectiveModuleSoftFloat();
8311 reportParseError(
"unexpected token, expected end of statement");
8316 }
else if (Option ==
"hardfloat") {
8317 clearModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
8321 getTargetStreamer().updateABIInfo(*
this);
8326 getTargetStreamer().emitDirectiveModuleHardFloat();
8330 reportParseError(
"unexpected token, expected end of statement");
8335 }
else if (Option ==
"mt") {
8336 setModuleFeatureBits(Mips::FeatureMT,
"mt");
8340 getTargetStreamer().updateABIInfo(*
this);
8345 getTargetStreamer().emitDirectiveModuleMT();
8349 reportParseError(
"unexpected token, expected end of statement");
8354 }
else if (Option ==
"crc") {
8355 setModuleFeatureBits(Mips::FeatureCRC,
"crc");
8359 getTargetStreamer().updateABIInfo(*
this);
8364 getTargetStreamer().emitDirectiveModuleCRC();
8368 reportParseError(
"unexpected token, expected end of statement");
8373 }
else if (Option ==
"nocrc") {
8374 clearModuleFeatureBits(Mips::FeatureCRC,
"crc");
8378 getTargetStreamer().updateABIInfo(*
this);
8383 getTargetStreamer().emitDirectiveModuleNoCRC();
8387 reportParseError(
"unexpected token, expected end of statement");
8392 }
else if (Option ==
"virt") {
8393 setModuleFeatureBits(Mips::FeatureVirt,
"virt");
8397 getTargetStreamer().updateABIInfo(*
this);
8402 getTargetStreamer().emitDirectiveModuleVirt();
8406 reportParseError(
"unexpected token, expected end of statement");
8411 }
else if (Option ==
"novirt") {
8412 clearModuleFeatureBits(Mips::FeatureVirt,
"virt");
8416 getTargetStreamer().updateABIInfo(*
this);
8421 getTargetStreamer().emitDirectiveModuleNoVirt();
8425 reportParseError(
"unexpected token, expected end of statement");
8430 }
else if (Option ==
"ginv") {
8431 setModuleFeatureBits(Mips::FeatureGINV,
"ginv");
8435 getTargetStreamer().updateABIInfo(*
this);
8440 getTargetStreamer().emitDirectiveModuleGINV();
8444 reportParseError(
"unexpected token, expected end of statement");
8449 }
else if (Option ==
"noginv") {
8450 clearModuleFeatureBits(Mips::FeatureGINV,
"ginv");
8454 getTargetStreamer().updateABIInfo(*
this);
8459 getTargetStreamer().emitDirectiveModuleNoGINV();
8463 reportParseError(
"unexpected token, expected end of statement");
8469 return Error(L,
"'" + Twine(Option) +
"' is not a valid .module option.");
8477bool MipsAsmParser::parseDirectiveModuleFP() {
8478 MCAsmParser &Parser = getParser();
8479 AsmLexer &Lexer = getLexer();
8482 reportParseError(
"unexpected token, expected equals sign '='");
8488 if (!parseFpABIValue(FpABI,
".module"))
8492 reportParseError(
"unexpected token, expected end of statement");
8498 getTargetStreamer().updateABIInfo(*
this);
8503 getTargetStreamer().emitDirectiveModuleFP();
8510 StringRef Directive) {
8511 MCAsmParser &Parser = getParser();
8512 AsmLexer &Lexer = getLexer();
8513 bool ModuleLevelOptions = Directive ==
".module";
8519 if (
Value !=
"xx") {
8520 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
8525 reportParseError(
"'" + Directive +
" fp=xx' requires the O32 ABI");
8529 FpABI = MipsABIFlagsSection::FpABIKind::XX;
8530 if (ModuleLevelOptions) {
8531 setModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8532 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8534 setFeatureBits(Mips::FeatureFPXX,
"fpxx");
8535 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8545 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
8551 reportParseError(
"'" + Directive +
" fp=32' requires the O32 ABI");
8555 FpABI = MipsABIFlagsSection::FpABIKind::S32;
8556 if (ModuleLevelOptions) {
8557 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8558 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8560 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
8561 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8564 FpABI = MipsABIFlagsSection::FpABIKind::S64;
8565 if (ModuleLevelOptions) {
8566 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8567 setModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8569 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
8570 setFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8580bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
8586 MCAsmParser &Parser = getParser();
8587 StringRef IDVal = DirectiveID.
getString();
8589 if (IDVal ==
".cpadd") {
8590 parseDirectiveCpAdd(DirectiveID.
getLoc());
8593 if (IDVal ==
".cpload") {
8594 parseDirectiveCpLoad(DirectiveID.
getLoc());
8597 if (IDVal ==
".cprestore") {
8598 parseDirectiveCpRestore(DirectiveID.
getLoc());
8601 if (IDVal ==
".cplocal") {
8602 parseDirectiveCpLocal(DirectiveID.
getLoc());
8605 if (IDVal ==
".ent") {
8609 reportParseError(
"expected identifier after .ent");
8623 reportParseError(
"unexpected token, expected end of statement");
8627 const MCExpr *DummyNumber;
8628 int64_t DummyNumberVal;
8632 reportParseError(
"expected number after comma");
8635 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
8636 reportParseError(
"expected an absolute expression after comma");
8643 reportParseError(
"unexpected token, expected end of statement");
8649 getTargetStreamer().emitDirectiveEnt(*Sym);
8651 IsCpRestoreSet =
false;
8655 if (IDVal ==
".end") {
8659 reportParseError(
"expected identifier after .end");
8664 reportParseError(
"unexpected token, expected end of statement");
8668 if (CurrentFn ==
nullptr) {
8669 reportParseError(
".end used without .ent");
8673 if ((SymbolName != CurrentFn->
getName())) {
8674 reportParseError(
".end symbol does not match .ent symbol");
8678 getTargetStreamer().emitDirectiveEnd(SymbolName);
8679 CurrentFn =
nullptr;
8680 IsCpRestoreSet =
false;
8684 if (IDVal ==
".frame") {
8687 ParseStatus Res = parseAnyRegister(TmpReg);
8689 reportParseError(
"expected stack register");
8693 MipsOperand &StackRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
8694 if (!StackRegOpnd.isGPRAsmReg()) {
8695 reportParseError(StackRegOpnd.getStartLoc(),
8696 "expected general purpose register");
8699 unsigned StackReg = StackRegOpnd.getGPR32Reg();
8704 reportParseError(
"unexpected token, expected comma");
8709 const MCExpr *FrameSize;
8710 int64_t FrameSizeVal;
8713 reportParseError(
"expected frame size value");
8717 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
8718 reportParseError(
"frame size not an absolute expression");
8725 reportParseError(
"unexpected token, expected comma");
8731 Res = parseAnyRegister(TmpReg);
8733 reportParseError(
"expected return register");
8737 MipsOperand &ReturnRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
8738 if (!ReturnRegOpnd.isGPRAsmReg()) {
8739 reportParseError(ReturnRegOpnd.getStartLoc(),
8740 "expected general purpose register");
8746 reportParseError(
"unexpected token, expected end of statement");
8750 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
8751 ReturnRegOpnd.getGPR32Reg());
8752 IsCpRestoreSet =
false;
8756 if (IDVal ==
".set") {
8757 parseDirectiveSet();
8761 if (IDVal ==
".mask" || IDVal ==
".fmask") {
8772 const MCExpr *BitMask;
8776 reportParseError(
"expected bitmask value");
8780 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
8781 reportParseError(
"bitmask not an absolute expression");
8788 reportParseError(
"unexpected token, expected comma");
8793 const MCExpr *FrameOffset;
8794 int64_t FrameOffsetVal;
8797 reportParseError(
"expected frame offset value");
8801 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
8802 reportParseError(
"frame offset not an absolute expression");
8808 reportParseError(
"unexpected token, expected end of statement");
8812 if (IDVal ==
".mask")
8813 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
8815 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
8819 if (IDVal ==
".nan")
8820 return parseDirectiveNaN();
8822 if (IDVal ==
".gpword") {
8823 parseDirectiveGpWord();
8827 if (IDVal ==
".gpdword") {
8828 parseDirectiveGpDWord();
8832 if (IDVal ==
".dtprelword") {
8833 parseDirectiveDtpRelWord();
8837 if (IDVal ==
".dtpreldword") {
8838 parseDirectiveDtpRelDWord();
8842 if (IDVal ==
".tprelword") {
8843 parseDirectiveTpRelWord();
8847 if (IDVal ==
".tpreldword") {
8848 parseDirectiveTpRelDWord();
8852 if (IDVal ==
".option") {
8853 parseDirectiveOption();
8857 if (IDVal ==
".abicalls") {
8858 getTargetStreamer().emitDirectiveAbiCalls();
8861 "unexpected token, expected end of statement");
8866 if (IDVal ==
".cpsetup") {
8867 parseDirectiveCPSetup();
8870 if (IDVal ==
".cpreturn") {
8871 parseDirectiveCPReturn();
8874 if (IDVal ==
".module") {
8875 parseDirectiveModule();
8878 if (IDVal ==
".llvm_internal_mips_reallow_module_directive") {
8879 parseInternalDirectiveReallowModule();
8882 if (IDVal ==
".insn") {
8883 parseInsnDirective();
8886 if (IDVal ==
".rdata") {
8887 parseRSectionDirective(
".rodata");
8890 if (IDVal ==
".sbss") {
8894 if (IDVal ==
".sdata") {
8902bool MipsAsmParser::parseInternalDirectiveReallowModule() {
8905 reportParseError(
"unexpected token, expected end of statement");
8909 getTargetStreamer().reallowModuleDirective();
8923#define GET_REGISTER_MATCHER
8924#define GET_MATCHER_IMPLEMENTATION
8925#define GET_MNEMONIC_SPELL_CHECKER
8926#include "MipsGenAsmMatcher.inc"
8928bool MipsAsmParser::mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID) {
8930 const MatchEntry *Start, *End;
8931 switch (VariantID) {
8933 case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0);
break;
8936 auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
8937 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.
virtual unsigned getHwMode(enum HwModeType type=HwMode_Default) const
HwMode ID corresponding to the 'type' parameter is retrieved from the HwMode bit set of the current s...
Represent a reference to a symbol from inside an expression.
uint16_t getSpecifier() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
bool isInSection() const
isInSection - Check if this symbol is defined in some section (i.e., it is defined but not absolute).
bool isUndefined() const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).
StringRef getName() const
getName - Get the symbol name.
bool isVariable() const
isVariable - Check if this is a variable symbol.
const MCExpr * getVariableValue() const
Get the expression of the variable symbol.
bool isTemporary() const
isTemporary - Check if this is an assembler temporary symbol.
MCTargetAsmParser - Generic interface to target specific assembly parsers.
MCStreamer & getStreamer()
Unary assembler expressions.
const MCSymbol * getAddSym() const
int64_t getConstant() const
const MCSymbol * getSubSym() const
void emitRRX(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, MCOperand Op2, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveSetReorder()
void emitRRRX(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, MCRegister Reg2, MCOperand Op3, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRX(unsigned Opcode, MCRegister Reg0, MCOperand Op1, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitR(unsigned Opcode, MCRegister Reg0, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void setUsesMicroMips()
void emitRRI(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, int16_t Imm, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitEmptyDelaySlot(bool hasShortDelaySlot, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRI(unsigned Opcode, MCRegister Reg0, int32_t Imm, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRR(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, SMLoc IDLoc, const MCSubtargetInfo *STI)
void updateABIInfo(const PredicateLibrary &P)
void emitRRIII(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, int16_t Imm0, int16_t Imm1, int16_t Imm2, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitDSLL(MCRegister DstReg, MCRegister SrcReg, int16_t ShiftAmount, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitGPRestore(int Offset, SMLoc IDLoc, const MCSubtargetInfo *STI)
Emit the $gp restore operation for .cprestore.
void emitNop(SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRRR(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, MCRegister Reg2, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveSetNoReorder()
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
static constexpr StatusTy Failure
constexpr bool isSuccess() const
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
constexpr bool isNoMatch() const
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
void push_back(const T &Elt)
iterator find(StringRef Key)
StringRef - Represent a constant reference to a string, i.e.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
empty - Check if the string is empty.
LLVM_ABI bool isLittleEndian() const
Tests whether the target triple is little endian.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
bool parseAssignmentExpression(StringRef Name, bool allow_redef, MCAsmParser &Parser, MCSymbol *&Symbol, const MCExpr *&Value)
Parse a value expression and return whether it can be assigned to a symbol with the given name.
@ CE
Windows NT (Windows on ARM)
LLVM_ABI std::string getABIName()
Context & getContext() const
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Target & getTheMips64Target()
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
static StringRef getCPU(StringRef CPU)
Processes a CPU name.
int bit_width(T Value)
Returns the number of bits needed to represent Value if Value is nonzero.
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
@ Success
The lock was released successfully.
Target & getTheMips64elTarget()
uint64_t offsetToAlignment(uint64_t Value, Align Alignment)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
@ Ref
The access may reference the value stored in memory.
To bit_cast(const From &from) noexcept
Target & getTheMipselTarget()
DWARFExpression::Operation Op
constexpr bool isShiftedInt(int64_t x)
Checks if a signed integer is an N bit number shifted left by S.
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
static uint16_t getSpecifier(const MCSymbolRefExpr *SRE)
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
Target & getTheMipsTarget()
constexpr bool isShiftedUInt(uint64_t x)
Checks if a unsigned integer is an N bit number shifted left by S.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
static LLVM_ABI const fltSemantics & IEEEdouble() LLVM_READNONE
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...