64#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);
143 const MipsMCOptions &CLOpts;
153 bool CurForbiddenSlotAttr;
156 unsigned CpSaveLocation;
158 bool CpSaveLocationIsRegister;
161 StringMap<AsmToken> RegisterSets;
164 void printWarningWithFixIt(
const Twine &
Msg,
const Twine &FixMsg,
165 SMRange
Range,
bool ShowColors =
true);
169#define GET_ASSEMBLER_HEADER
170#include "MipsGenAsmMatcher.inc"
173 checkEarlyTargetMatchPredicate(
MCInst &Inst,
175 unsigned checkTargetMatchPredicate(
MCInst &Inst)
override;
177 bool matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
180 bool MatchingInlineAsm)
override;
185 SMLoc &EndLoc)
override;
191 bool mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID);
196 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();
398 bool parseSetNoEVADirective();
400 bool parseSetAssignment();
402 bool parseDirectiveGpWord();
403 bool parseDirectiveGpDWord();
404 bool parseDirectiveDtpRelWord();
405 bool parseDirectiveDtpRelDWord();
406 bool parseDirectiveTpRelWord();
407 bool parseDirectiveTpRelDWord();
408 bool parseDirectiveModule();
409 bool parseDirectiveModuleFP();
411 StringRef Directive);
413 bool parseInternalDirectiveReallowModule();
415 bool eatComma(StringRef ErrorStr);
417 int matchCPURegisterName(StringRef Symbol);
419 int matchHWRegsRegisterName(StringRef Symbol);
421 int matchFPURegisterName(StringRef Name);
423 int matchFCCRegisterName(StringRef Name);
425 int matchACRegisterName(StringRef Name);
427 int matchMSA128RegisterName(StringRef Name);
429 int matchMSA128CtrlRegisterName(StringRef Name);
431 MCRegister
getReg(
int RC,
int RegNo);
436 MCRegister getATReg(SMLoc Loc);
440 bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
441 const MCSubtargetInfo *STI);
465 void selectArch(StringRef ArchFeature) {
466 MCSubtargetInfo &STI = copySTI();
468 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
470 setAvailableFeatures(
475 void setFeatureBits(
uint64_t Feature, StringRef FeatureString) {
477 MCSubtargetInfo &STI = copySTI();
478 setAvailableFeatures(
484 void clearFeatureBits(
uint64_t Feature, StringRef FeatureString) {
486 MCSubtargetInfo &STI = copySTI();
487 setAvailableFeatures(
493 void setModuleFeatureBits(
uint64_t Feature, StringRef FeatureString) {
494 setFeatureBits(Feature, FeatureString);
495 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
498 void clearModuleFeatureBits(
uint64_t Feature, StringRef FeatureString) {
499 clearFeatureBits(Feature, FeatureString);
500 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
504 enum MipsMatchResultTy {
505 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
506 Match_RequiresDifferentOperands,
507 Match_RequiresNoZeroRegister,
508 Match_RequiresSameSrcAndDst,
509 Match_NoFCCRegisterForCurrentISA,
510 Match_NonZeroOperandForSync,
511 Match_NonZeroOperandForMTCX,
512 Match_RequiresPosSizeRange0_32,
513 Match_RequiresPosSizeRange33_64,
514 Match_RequiresPosSizeUImm6,
515#define GET_OPERAND_DIAGNOSTIC_TYPES
516#include "MipsGenAsmMatcher.inc"
517#undef GET_OPERAND_DIAGNOSTIC_TYPES
520 MipsAsmParser(
const MCSubtargetInfo &sti, MCAsmParser &parser,
521 const MCInstrInfo &MII)
522 : MCTargetAsmParser(sti, MII), CLOpts(MipsMCOptions::
Global),
524 sti.getTargetTriple(),
534 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
537 AssemblerOptions.push_back(
538 std::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
541 AssemblerOptions.push_back(
542 std::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
544 getTargetStreamer().updateABIInfo(*
this);
546 if (!isABI_O32() && !useOddSPReg() != 0)
551 CurForbiddenSlotAttr =
false;
552 IsPicEnabled =
getContext().getObjectFileInfo()->isPositionIndependent();
554 IsCpRestoreSet =
false;
555 CpRestoreOffset = -1;
556 GPReg = ABI.GetGlobalPtr();
561 if (getSTI().
getCPU() ==
"mips64r6" && inMicroMipsMode())
564 if (!isABI_O32() && inMicroMipsMode())
569 bool hasEightFccRegisters()
const {
return hasMips4() || hasMips32(); }
571 bool isGP64bit()
const {
572 return getSTI().hasFeature(Mips::FeatureGP64Bit);
575 bool isFP64bit()
const {
576 return getSTI().hasFeature(Mips::FeatureFP64Bit);
579 bool isJalrRelocAvailable(
const MCExpr *JalExpr) {
580 if (!CLOpts.jalr_reloc)
588 return ABI.IsN32() || ABI.IsN64();
592 const MipsABIInfo &
getABI()
const {
return ABI; }
593 bool isABI_N32()
const {
return ABI.IsN32(); }
594 bool isABI_N64()
const {
return ABI.IsN64(); }
595 bool isABI_O32()
const {
return ABI.IsO32(); }
596 bool isABI_FPXX()
const {
597 return getSTI().hasFeature(Mips::FeatureFPXX);
600 bool useOddSPReg()
const {
601 return !(getSTI().hasFeature(Mips::FeatureNoOddSPReg));
604 bool inMicroMipsMode()
const {
605 return getSTI().hasFeature(Mips::FeatureMicroMips);
608 bool hasMips1()
const {
609 return getSTI().hasFeature(Mips::FeatureMips1);
612 bool hasMips2()
const {
613 return getSTI().hasFeature(Mips::FeatureMips2);
616 bool hasMips3()
const {
617 return getSTI().hasFeature(Mips::FeatureMips3);
620 bool hasMips4()
const {
621 return getSTI().hasFeature(Mips::FeatureMips4);
624 bool hasMips5()
const {
625 return getSTI().hasFeature(Mips::FeatureMips5);
628 bool hasMips32()
const {
629 return getSTI().hasFeature(Mips::FeatureMips32);
632 bool hasMips64()
const {
633 return getSTI().hasFeature(Mips::FeatureMips64);
636 bool hasMips32r2()
const {
637 return getSTI().hasFeature(Mips::FeatureMips32r2);
640 bool hasMips64r2()
const {
641 return getSTI().hasFeature(Mips::FeatureMips64r2);
644 bool hasMips32r3()
const {
645 return (getSTI().
hasFeature(Mips::FeatureMips32r3));
648 bool hasMips64r3()
const {
649 return (getSTI().
hasFeature(Mips::FeatureMips64r3));
652 bool hasMips32r5()
const {
653 return (getSTI().
hasFeature(Mips::FeatureMips32r5));
656 bool hasMips64r5()
const {
657 return (getSTI().
hasFeature(Mips::FeatureMips64r5));
660 bool hasMips32r6()
const {
661 return getSTI().hasFeature(Mips::FeatureMips32r6);
664 bool hasMips64r6()
const {
665 return getSTI().hasFeature(Mips::FeatureMips64r6);
668 bool hasDSP()
const {
669 return getSTI().hasFeature(Mips::FeatureDSP);
672 bool hasDSPR2()
const {
673 return getSTI().hasFeature(Mips::FeatureDSPR2);
676 bool hasDSPR3()
const {
677 return getSTI().hasFeature(Mips::FeatureDSPR3);
680 bool hasMSA()
const {
681 return getSTI().hasFeature(Mips::FeatureMSA);
684 bool hasCnMips()
const {
685 return (getSTI().
hasFeature(Mips::FeatureCnMips));
688 bool hasCnMipsP()
const {
689 return (getSTI().
hasFeature(Mips::FeatureCnMipsP));
692 bool isR5900()
const {
return (getSTI().
hasFeature(Mips::FeatureR5900)); }
698 bool inMips16Mode()
const {
699 return getSTI().hasFeature(Mips::FeatureMips16);
702 bool useTraps()
const {
703 return getSTI().hasFeature(Mips::FeatureUseTCCInDIV);
706 bool useSoftFloat()
const {
707 return getSTI().hasFeature(Mips::FeatureSoftFloat);
710 bool isSingleFloat()
const {
711 return getSTI().hasFeature(Mips::FeatureSingleFloat);
715 return getSTI().hasFeature(Mips::FeatureMT);
718 bool hasCRC()
const {
719 return getSTI().hasFeature(Mips::FeatureCRC);
722 bool hasVirt()
const {
723 return getSTI().hasFeature(Mips::FeatureVirt);
726 bool hasGINV()
const {
727 return getSTI().hasFeature(Mips::FeatureGINV);
730 bool hasForbiddenSlot(
const MCInstrDesc &MCID)
const {
734 bool SafeInForbiddenSlot(
const MCInstrDesc &MCID)
const {
738 void onEndOfFile()
override;
741 void warnIfRegIndexIsAT(MCRegister RegIndex, SMLoc Loc);
743 void warnIfNoMacro(SMLoc Loc);
745 bool isLittle()
const {
return IsLittleEndian; }
747 bool areEqualRegs(
const MCParsedAsmOperand &Op1,
748 const MCParsedAsmOperand &Op2)
const override;
763 RegKind_MSACtrl = 16,
768 RegKind_HWRegs = 256,
772 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
773 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
774 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
787 MipsOperand(KindTy K, MipsAsmParser &Parser) : Kind(
K), AsmParser(Parser) {}
789 ~MipsOperand()
override {
798 case k_RegisterIndex:
806 MipsAsmParser &AsmParser;
817 const MCRegisterInfo *RegInfo;
835 struct RegIdxOp RegIdx;
838 struct RegListOp RegList;
841 SMLoc StartLoc, EndLoc;
844 static std::unique_ptr<MipsOperand> CreateReg(
unsigned Index, StringRef Str,
846 const MCRegisterInfo *RegInfo,
848 MipsAsmParser &Parser) {
849 auto Op = std::make_unique<MipsOperand>(k_RegisterIndex, Parser);
851 Op->RegIdx.RegInfo = RegInfo;
852 Op->RegIdx.Kind = RegKind;
853 Op->RegIdx.Tok.Data = Str.data();
854 Op->RegIdx.Tok.Length = Str.size();
863 MCRegister getGPR32Reg()
const {
864 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
865 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
866 unsigned ClassID = Mips::GPR32RegClassID;
867 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
872 MCRegister getGPRMM16Reg()
const {
873 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
874 unsigned ClassID = Mips::GPR32RegClassID;
875 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
880 MCRegister getGPR64Reg()
const {
881 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
882 unsigned ClassID = Mips::GPR64RegClassID;
883 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
889 MCRegister getAFGR64Reg()
const {
890 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
891 if (RegIdx.Index % 2 != 0)
892 AsmParser.Warning(StartLoc,
"Float register should be even.");
893 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
894 .getRegister(RegIdx.Index / 2);
899 MCRegister getFGR64Reg()
const {
900 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
901 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
902 .getRegister(RegIdx.Index);
907 MCRegister getFGR32Reg()
const {
908 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
909 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
910 .getRegister(RegIdx.Index);
915 MCRegister getFCCReg()
const {
916 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) &&
"Invalid access!");
917 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
918 .getRegister(RegIdx.Index);
923 MCRegister getMSA128Reg()
const {
924 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) &&
"Invalid access!");
927 unsigned ClassID = Mips::MSA128BRegClassID;
928 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
933 MCRegister getMSACtrlReg()
const {
934 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) &&
"Invalid access!");
935 unsigned ClassID = Mips::MSACtrlRegClassID;
936 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
941 MCRegister getCOP0Reg()
const {
942 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) &&
"Invalid access!");
943 unsigned ClassID = Mips::COP0RegClassID;
944 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
949 MCRegister getCOP2Reg()
const {
950 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) &&
"Invalid access!");
951 unsigned ClassID = Mips::COP2RegClassID;
952 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
957 MCRegister getCOP3Reg()
const {
958 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) &&
"Invalid access!");
959 unsigned ClassID = Mips::COP3RegClassID;
960 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
965 MCRegister getACC64DSPReg()
const {
966 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
967 unsigned ClassID = Mips::ACC64DSPRegClassID;
968 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
973 MCRegister getHI32DSPReg()
const {
974 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
975 unsigned ClassID = Mips::HI32DSPRegClassID;
976 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
981 MCRegister getLO32DSPReg()
const {
982 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
983 unsigned ClassID = Mips::LO32DSPRegClassID;
984 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
989 MCRegister getCCRReg()
const {
990 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) &&
"Invalid access!");
991 unsigned ClassID = Mips::CCRRegClassID;
992 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
997 MCRegister getHWRegsReg()
const {
998 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) &&
"Invalid access!");
999 unsigned ClassID = Mips::HWRegsRegClassID;
1000 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1004 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const {
1014 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1021 void addGPR32ZeroAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1022 assert(
N == 1 &&
"Invalid number of operands!");
1026 void addGPR32NonZeroAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1027 assert(
N == 1 &&
"Invalid number of operands!");
1031 void addGPR32AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1032 assert(
N == 1 &&
"Invalid number of operands!");
1036 void addGPRMM16AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1037 assert(
N == 1 &&
"Invalid number of operands!");
1041 void addGPRMM16AsmRegZeroOperands(MCInst &Inst,
unsigned N)
const {
1042 assert(
N == 1 &&
"Invalid number of operands!");
1046 void addGPRMM16AsmRegMovePOperands(MCInst &Inst,
unsigned N)
const {
1047 assert(
N == 1 &&
"Invalid number of operands!");
1051 void addGPRMM16AsmRegMovePPairFirstOperands(MCInst &Inst,
unsigned N)
const {
1052 assert(
N == 1 &&
"Invalid number of operands!");
1056 void addGPRMM16AsmRegMovePPairSecondOperands(MCInst &Inst,
1058 assert(
N == 1 &&
"Invalid number of operands!");
1065 void addGPR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1066 assert(
N == 1 &&
"Invalid number of operands!");
1070 void addAFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1071 assert(
N == 1 &&
"Invalid number of operands!");
1075 void addStrictlyAFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1076 assert(
N == 1 &&
"Invalid number of operands!");
1080 void addStrictlyFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1081 assert(
N == 1 &&
"Invalid number of operands!");
1085 void addFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1086 assert(
N == 1 &&
"Invalid number of operands!");
1090 void addFGR32AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1091 assert(
N == 1 &&
"Invalid number of operands!");
1095 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1096 AsmParser.getParser().printError(
1097 StartLoc,
"-mno-odd-spreg prohibits the use of odd FPU "
1101 void addStrictlyFGR32AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1102 assert(
N == 1 &&
"Invalid number of operands!");
1105 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1106 AsmParser.Error(StartLoc,
"-mno-odd-spreg prohibits the use of odd FPU "
1110 void addFCCAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1111 assert(
N == 1 &&
"Invalid number of operands!");
1115 void addMSA128AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1116 assert(
N == 1 &&
"Invalid number of operands!");
1120 void addMSACtrlAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1121 assert(
N == 1 &&
"Invalid number of operands!");
1125 void addCOP0AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1126 assert(
N == 1 &&
"Invalid number of operands!");
1130 void addCOP2AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1131 assert(
N == 1 &&
"Invalid number of operands!");
1135 void addCOP3AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1136 assert(
N == 1 &&
"Invalid number of operands!");
1140 void addACC64DSPAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1141 assert(
N == 1 &&
"Invalid number of operands!");
1145 void addHI32DSPAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1146 assert(
N == 1 &&
"Invalid number of operands!");
1150 void addLO32DSPAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1151 assert(
N == 1 &&
"Invalid number of operands!");
1155 void addCCRAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1156 assert(
N == 1 &&
"Invalid number of operands!");
1160 void addHWRegsAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1161 assert(
N == 1 &&
"Invalid number of operands!");
1165 template <
unsigned Bits,
int Offset = 0,
int AdjustOffset = 0>
1166 void addConstantUImmOperands(MCInst &Inst,
unsigned N)
const {
1167 assert(
N == 1 &&
"Invalid number of operands!");
1171 Imm += AdjustOffset;
1175 template <
unsigned Bits>
1176 void addSImmOperands(MCInst &Inst,
unsigned N)
const {
1177 if (isImm() && !isConstantImm()) {
1181 addConstantSImmOperands<Bits, 0, 0>(Inst,
N);
1184 template <
unsigned Bits>
1185 void addUImmOperands(MCInst &Inst,
unsigned N)
const {
1186 if (isImm() && !isConstantImm()) {
1190 addConstantUImmOperands<Bits, 0, 0>(Inst,
N);
1193 template <
unsigned Bits,
int Offset = 0,
int AdjustOffset = 0>
1194 void addConstantSImmOperands(MCInst &Inst,
unsigned N)
const {
1195 assert(
N == 1 &&
"Invalid number of operands!");
1196 int64_t
Imm = getConstantImm() -
Offset;
1199 Imm += AdjustOffset;
1203 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1204 assert(
N == 1 &&
"Invalid number of operands!");
1205 const MCExpr *Expr =
getImm();
1206 addExpr(Inst, Expr);
1209 void addMemOperands(MCInst &Inst,
unsigned N)
const {
1210 assert(
N == 2 &&
"Invalid number of operands!");
1213 ? getMemBase()->getGPR64Reg()
1214 : getMemBase()->getGPR32Reg()));
1216 const MCExpr *Expr = getMemOff();
1217 addExpr(Inst, Expr);
1220 void addMicroMipsMemOperands(MCInst &Inst,
unsigned N)
const {
1221 assert(
N == 2 &&
"Invalid number of operands!");
1225 const MCExpr *Expr = getMemOff();
1226 addExpr(Inst, Expr);
1229 void addRegListOperands(MCInst &Inst,
unsigned N)
const {
1230 assert(
N == 1 &&
"Invalid number of operands!");
1232 for (
auto RegNo : getRegList())
1236 bool isReg()
const override {
1239 return isGPRAsmReg() && RegIdx.Index == 0;
1242 bool isRegIdx()
const {
return Kind == k_RegisterIndex; }
1243 bool isImm()
const override {
return Kind == k_Immediate; }
1245 bool isConstantImm()
const {
1247 return isImm() &&
getImm()->evaluateAsAbsolute(Res);
1250 bool isConstantImmz()
const {
1251 return isConstantImm() && getConstantImm() == 0;
1254 template <
unsigned Bits,
int Offset = 0>
bool isConstantUImm()
const {
1258 template <
unsigned Bits>
bool isSImm()
const {
1262 if (
getImm()->evaluateAsAbsolute(Res))
1268 template <
unsigned Bits>
bool isUImm()
const {
1272 if (
getImm()->evaluateAsAbsolute(Res))
1278 template <
unsigned Bits>
bool isAnyImm()
const {
1279 return isConstantImm() ? (
isInt<Bits>(getConstantImm()) ||
1284 template <
unsigned Bits,
int Offset = 0>
bool isConstantSImm()
const {
1288 template <
unsigned Bottom,
unsigned Top>
bool isConstantUImmRange()
const {
1289 return isConstantImm() && getConstantImm() >= Bottom &&
1290 getConstantImm() <= Top;
1293 bool isToken()
const override {
1296 return Kind == k_Token;
1299 bool isMem()
const override {
return Kind == k_Memory; }
1301 bool isConstantMemOff()
const {
1306 template <
unsigned Bits,
unsigned ShiftAmount = 0>
1307 bool isMemWithSimmOffset()
const {
1310 if (!getMemBase()->isGPRAsmReg())
1313 (isConstantMemOff() &&
1317 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res,
nullptr);
1321 bool isMemWithPtrSizeOffset()
const {
1324 if (!getMemBase()->isGPRAsmReg())
1326 const unsigned PtrBits = AsmParser.getABI().ArePtrs64bit() ? 64 : 32;
1328 (isConstantMemOff() &&
isIntN(PtrBits, getConstantMemOff())))
1331 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res,
nullptr);
1335 bool isMemWithGRPMM16Base()
const {
1336 return isMem() && getMemBase()->isMM16AsmReg();
1339 template <
unsigned Bits>
bool isMemWithUimmOffsetSP()
const {
1341 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1344 template <
unsigned Bits>
bool isMemWithUimmWordAlignedOffsetSP()
const {
1346 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1347 && (getMemBase()->getGPR32Reg() == Mips::SP);
1350 template <
unsigned Bits>
bool isMemWithSimmWordAlignedOffsetGP()
const {
1352 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1353 && (getMemBase()->getGPR32Reg() == Mips::GP);
1356 template <
unsigned Bits,
unsigned ShiftLeftAmount>
1357 bool isScaledUImm()
const {
1358 return isConstantImm() &&
1362 template <
unsigned Bits,
unsigned ShiftLeftAmount>
1363 bool isScaledSImm()
const {
1364 if (isConstantImm() &&
1369 if (Kind != k_Immediate)
1372 bool Success =
getImm()->evaluateAsRelocatable(Res,
nullptr);
1376 bool isRegList16()
const {
1380 int Size = RegList.List->size();
1384 MCRegister R0 = RegList.List->front();
1385 MCRegister R1 = RegList.List->back();
1386 if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1387 (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1390 MCRegister PrevReg = RegList.List->front();
1391 for (
int i = 1; i <
Size - 1; i++) {
1392 MCRegister
Reg = (*(RegList.List))[i];
1393 if (
Reg != PrevReg + 1)
1401 bool isInvNum()
const {
return Kind == k_Immediate; }
1403 bool isLSAImm()
const {
1404 if (!isConstantImm())
1406 int64_t Val = getConstantImm();
1407 return 1 <= Val && Val <= 4;
1410 bool isRegList()
const {
return Kind == k_RegList; }
1413 assert(Kind == k_Token &&
"Invalid access!");
1414 return StringRef(Tok.Data, Tok.Length);
1417 MCRegister
getReg()
const override {
1420 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1421 RegIdx.Kind & RegKind_GPR)
1422 return getGPR32Reg();
1428 const MCExpr *
getImm()
const {
1429 assert((Kind == k_Immediate) &&
"Invalid access!");
1433 int64_t getConstantImm()
const {
1434 const MCExpr *Val =
getImm();
1436 (void)Val->evaluateAsAbsolute(
Value);
1440 MipsOperand *getMemBase()
const {
1441 assert((Kind == k_Memory) &&
"Invalid access!");
1445 const MCExpr *getMemOff()
const {
1446 assert((Kind == k_Memory) &&
"Invalid access!");
1450 int64_t getConstantMemOff()
const {
1451 return static_cast<const MCConstantExpr *
>(getMemOff())->
getValue();
1454 const SmallVectorImpl<MCRegister> &getRegList()
const {
1455 assert((Kind == k_RegList) &&
"Invalid access!");
1456 return *(RegList.List);
1459 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1460 MipsAsmParser &Parser) {
1461 auto Op = std::make_unique<MipsOperand>(k_Token, Parser);
1462 Op->Tok.Data = Str.data();
1463 Op->Tok.Length = Str.size();
1471 static std::unique_ptr<MipsOperand>
1472 createNumericReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1473 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1474 LLVM_DEBUG(
dbgs() <<
"createNumericReg(" << Index <<
", ...)\n");
1475 return CreateReg(Index, Str, RegKind_Numeric, RegInfo, S,
E, Parser);
1480 static std::unique_ptr<MipsOperand>
1481 createGPRReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1482 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1483 return CreateReg(Index, Str, RegKind_GPR, RegInfo, S,
E, Parser);
1488 static std::unique_ptr<MipsOperand>
1489 createFGRReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1490 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1491 return CreateReg(Index, Str, RegKind_FGR, RegInfo, S,
E, Parser);
1496 static std::unique_ptr<MipsOperand>
1497 createHWRegsReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1498 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1499 return CreateReg(Index, Str, RegKind_HWRegs, RegInfo, S,
E, Parser);
1504 static std::unique_ptr<MipsOperand>
1505 createFCCReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1506 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1507 return CreateReg(Index, Str, RegKind_FCC, RegInfo, S,
E, Parser);
1512 static std::unique_ptr<MipsOperand>
1513 createACCReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1514 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1515 return CreateReg(Index, Str, RegKind_ACC, RegInfo, S,
E, Parser);
1520 static std::unique_ptr<MipsOperand>
1521 createMSA128Reg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1522 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1523 return CreateReg(Index, Str, RegKind_MSA128, RegInfo, S,
E, Parser);
1528 static std::unique_ptr<MipsOperand>
1529 createMSACtrlReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1530 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1531 return CreateReg(Index, Str, RegKind_MSACtrl, RegInfo, S,
E, Parser);
1534 static std::unique_ptr<MipsOperand>
1535 CreateImm(
const MCExpr *Val, SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1536 auto Op = std::make_unique<MipsOperand>(k_Immediate, Parser);
1543 static std::unique_ptr<MipsOperand>
1544 CreateMem(std::unique_ptr<MipsOperand>
Base,
const MCExpr *
Off, SMLoc S,
1545 SMLoc
E, MipsAsmParser &Parser) {
1546 auto Op = std::make_unique<MipsOperand>(k_Memory, Parser);
1547 Op->Mem.Base =
Base.release();
1554 static std::unique_ptr<MipsOperand>
1555 CreateRegList(SmallVectorImpl<MCRegister> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1556 MipsAsmParser &Parser) {
1557 assert(!Regs.
empty() &&
"Empty list not allowed");
1559 auto Op = std::make_unique<MipsOperand>(k_RegList, Parser);
1562 Op->StartLoc = StartLoc;
1563 Op->EndLoc = EndLoc;
1567 bool isGPRZeroAsmReg()
const {
1568 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
1571 bool isGPRNonZeroAsmReg()
const {
1572 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index > 0 &&
1576 bool isGPRAsmReg()
const {
1577 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1580 bool isMM16AsmReg()
const {
1581 if (!(isRegIdx() && RegIdx.Kind))
1583 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1584 || RegIdx.Index == 16 || RegIdx.Index == 17);
1587 bool isMM16AsmRegZero()
const {
1588 if (!(isRegIdx() && RegIdx.Kind))
1590 return (RegIdx.Index == 0 ||
1591 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1592 RegIdx.Index == 17);
1595 bool isMM16AsmRegMoveP()
const {
1596 if (!(isRegIdx() && RegIdx.Kind))
1598 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1599 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1602 bool isMM16AsmRegMovePPairFirst()
const {
1603 if (!(isRegIdx() && RegIdx.Kind))
1605 return RegIdx.Index >= 4 && RegIdx.Index <= 6;
1608 bool isMM16AsmRegMovePPairSecond()
const {
1609 if (!(isRegIdx() && RegIdx.Kind))
1611 return (RegIdx.Index == 21 || RegIdx.Index == 22 ||
1612 (RegIdx.Index >= 5 && RegIdx.Index <= 7));
1615 bool isFGRAsmReg()
const {
1617 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1620 bool isStrictlyFGRAsmReg()
const {
1622 return isRegIdx() && RegIdx.Kind == RegKind_FGR && RegIdx.Index <= 31;
1625 bool isHWRegsAsmReg()
const {
1626 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1629 bool isCCRAsmReg()
const {
1630 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1633 bool isFCCAsmReg()
const {
1634 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1636 return RegIdx.Index <= 7;
1639 bool isACCAsmReg()
const {
1640 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1643 bool isCOP0AsmReg()
const {
1644 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1647 bool isCOP2AsmReg()
const {
1648 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1651 bool isCOP3AsmReg()
const {
1652 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1655 bool isMSA128AsmReg()
const {
1656 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1659 bool isMSACtrlAsmReg()
const {
1660 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1664 SMLoc getStartLoc()
const override {
return StartLoc; }
1666 SMLoc getEndLoc()
const override {
return EndLoc; }
1668 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1677 Mem.Base->print(OS, MAI);
1682 case k_RegisterIndex:
1683 OS <<
"RegIdx<" << RegIdx.Index <<
":" << RegIdx.Kind <<
", "
1684 << StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) <<
">";
1691 for (
auto Reg : (*RegList.List))
1692 OS <<
Reg.
id() <<
" ";
1698 bool isValidForTie(
const MipsOperand &
Other)
const {
1699 if (Kind !=
Other.Kind)
1706 case k_RegisterIndex: {
1707 StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length);
1708 StringRef OtherToken(
Other.RegIdx.Tok.Data,
Other.RegIdx.Tok.Length);
1709 return Token == OtherToken;
1725 case Mips::JRC16_MM:
1727 case Mips::JALRS_MM:
1728 case Mips::JALRS16_MM:
1729 case Mips::BGEZALS_MM:
1730 case Mips::BLTZALS_MM:
1741 return &SRExpr->getSymbol();
1800 unsigned NumOp =
MCID.getNumOperands();
1801 if (NumOp != 3 && NumOp != 4)
1831bool MipsAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
1834 MipsTargetStreamer &TOut = getTargetStreamer();
1835 const unsigned Opcode = Inst.
getOpcode();
1836 const MCInstrDesc &MCID = MII.get(Opcode);
1837 bool ExpandedJalSym =
false;
1851 assert(hasCnMips() &&
"instruction only valid for octeon cpus");
1862 if (!
isIntN(inMicroMipsMode() ? 17 : 18,
Offset.getImm()))
1863 return Error(IDLoc,
"branch target out of range");
1866 return Error(IDLoc,
"branch to misaligned address");
1880 case Mips::BGEZAL_MM:
1881 case Mips::BLTZAL_MM:
1884 case Mips::BC1EQZC_MMR6:
1885 case Mips::BC1NEZC_MMR6:
1886 case Mips::BC2EQZC_MMR6:
1887 case Mips::BC2NEZC_MMR6:
1892 if (!
isIntN(inMicroMipsMode() ? 17 : 18,
Offset.getImm()))
1893 return Error(IDLoc,
"branch target out of range");
1896 return Error(IDLoc,
"branch to misaligned address");
1898 case Mips::BGEC:
case Mips::BGEC_MMR6:
1899 case Mips::BLTC:
case Mips::BLTC_MMR6:
1900 case Mips::BGEUC:
case Mips::BGEUC_MMR6:
1901 case Mips::BLTUC:
case Mips::BLTUC_MMR6:
1902 case Mips::BEQC:
case Mips::BEQC_MMR6:
1903 case Mips::BNEC:
case Mips::BNEC_MMR6:
1909 return Error(IDLoc,
"branch target out of range");
1911 return Error(IDLoc,
"branch to misaligned address");
1913 case Mips::BLEZC:
case Mips::BLEZC_MMR6:
1914 case Mips::BGEZC:
case Mips::BGEZC_MMR6:
1915 case Mips::BGTZC:
case Mips::BGTZC_MMR6:
1916 case Mips::BLTZC:
case Mips::BLTZC_MMR6:
1922 return Error(IDLoc,
"branch target out of range");
1924 return Error(IDLoc,
"branch to misaligned address");
1926 case Mips::BEQZC:
case Mips::BEQZC_MMR6:
1927 case Mips::BNEZC:
case Mips::BNEZC_MMR6:
1933 return Error(IDLoc,
"branch target out of range");
1935 return Error(IDLoc,
"branch to misaligned address");
1937 case Mips::BEQZ16_MM:
1938 case Mips::BEQZC16_MMR6:
1939 case Mips::BNEZ16_MM:
1940 case Mips::BNEZC16_MMR6:
1946 return Error(IDLoc,
"branch target out of range");
1948 return Error(IDLoc,
"branch to misaligned address");
1955 if (hasMips32r6() && Opcode == Mips::SSNOP) {
1956 std::string
ISA = hasMips64r6() ?
"MIPS64r6" :
"MIPS32r6";
1957 Warning(IDLoc,
"ssnop is deprecated for " + ISA +
" and is equivalent to a "
1977 return Error(IDLoc,
"expected immediate operand kind");
1980 Opcode == Mips::BBIT1 ? 63 : 31))
1981 return Error(IDLoc,
"immediate operand value out of range");
1983 Inst.
setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1994 return Error(IDLoc,
"expected immediate operand kind");
1997 return Error(IDLoc,
"immediate operand value out of range");
2009 unsigned FirstOp = 1;
2010 unsigned SecondOp = 2;
2014 case Mips::SDivIMacro:
2015 case Mips::UDivIMacro:
2016 case Mips::DSDivIMacro:
2017 case Mips::DUDivIMacro:
2019 return Error(IDLoc,
"expected immediate operand kind");
2023 Warning(IDLoc,
"dividing zero by zero");
2025 Warning(IDLoc,
"division by zero");
2037 case Mips::SDivMacro:
2038 case Mips::DSDivMacro:
2039 case Mips::UDivMacro:
2040 case Mips::DUDivMacro:
2045 case Mips::DIVU_MMR6:
2046 case Mips::DIV_MMR6:
2051 Warning(IDLoc,
"dividing zero by zero");
2053 Warning(IDLoc,
"division by zero");
2059 if ((Opcode == Mips::J || Opcode == Mips::J_MM) && inPicMode()) {
2061 BInst.
setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
2070 if ((Opcode == Mips::JAL || Opcode == Mips::JAL_MM) && inPicMode()) {
2071 warnIfNoMacro(IDLoc);
2074 return Error(IDLoc,
"unsupported constant in relocation");
2082 return Error(IDLoc,
"jal doesn't support multiple symbols in PIC mode");
2088 if (expandLoadAddress(Mips::T9, MCRegister(), Inst.
getOperand(0),
2089 !isGP64bit(), IDLoc, Out, STI))
2093 if (inMicroMipsMode())
2094 JalrInst.
setOpcode(IsCpRestoreSet ? Mips::JALRS_MM : Mips::JALR_MM);
2100 if (isJalrRelocAvailable(JalExpr)) {
2106 const MCExpr *RelocJalrExpr =
2110 *TmpExpr, inMicroMipsMode() ?
"R_MICROMIPS_JALR" :
"R_MIPS_JALR",
2116 ExpandedJalSym =
true;
2125 expandMem9Inst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2128 expandMem16Inst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2131 return getParser().hasPendingError();
2135 if (inMicroMipsMode()) {
2136 if (Opcode == Mips::LW_MM || Opcode == Mips::LW_MMR6) {
2139 const MCOperandInfo &OpInfo = MCID.
operands()[i];
2144 int MemOffset =
Op.getImm();
2147 if (
isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
2150 (
BaseReg.getReg() == Mips::GP ||
2151 BaseReg.getReg() == Mips::GP_64)) {
2153 TOut.
emitRRI(Mips::LWGP_MM, DstReg.
getReg(), Mips::GP, MemOffset,
2170 case Mips::ADDIUSP_MM:
2173 return Error(IDLoc,
"expected immediate operand kind");
2177 return Error(IDLoc,
"immediate operand value out of range");
2179 case Mips::SLL16_MM:
2180 case Mips::SRL16_MM:
2183 return Error(IDLoc,
"expected immediate operand kind");
2186 return Error(IDLoc,
"immediate operand value out of range");
2191 return Error(IDLoc,
"expected immediate operand kind");
2194 return Error(IDLoc,
"immediate operand value out of range");
2196 case Mips::ADDIUR2_MM:
2199 return Error(IDLoc,
"expected immediate operand kind");
2201 if (!(
Imm == 1 ||
Imm == -1 ||
2203 return Error(IDLoc,
"immediate operand value out of range");
2205 case Mips::ANDI16_MM:
2208 return Error(IDLoc,
"expected immediate operand kind");
2212 Imm == 64 ||
Imm == 255 ||
Imm == 32768 ||
Imm == 65535))
2213 return Error(IDLoc,
"immediate operand value out of range");
2215 case Mips::LBU16_MM:
2218 return Error(IDLoc,
"expected immediate operand kind");
2221 return Error(IDLoc,
"immediate operand value out of range");
2224 case Mips::SB16_MMR6:
2227 return Error(IDLoc,
"expected immediate operand kind");
2230 return Error(IDLoc,
"immediate operand value out of range");
2232 case Mips::LHU16_MM:
2234 case Mips::SH16_MMR6:
2237 return Error(IDLoc,
"expected immediate operand kind");
2240 return Error(IDLoc,
"immediate operand value out of range");
2244 case Mips::SW16_MMR6:
2247 return Error(IDLoc,
"expected immediate operand kind");
2250 return Error(IDLoc,
"immediate operand value out of range");
2252 case Mips::ADDIUPC_MM:
2255 return Error(IDLoc,
"expected immediate operand kind");
2258 return Error(IDLoc,
"immediate operand value out of range");
2263 return Error(IDLoc,
"invalid operand for instruction");
2265 case Mips::MOVEP_MM:
2266 case Mips::MOVEP_MMR6: {
2269 bool RegPair = ((R0 == Mips::A1 && R1 == Mips::A2) ||
2270 (R0 == Mips::A1 && R1 == Mips::A3) ||
2271 (R0 == Mips::A2 && R1 == Mips::A3) ||
2272 (R0 == Mips::A0 && R1 == Mips::S5) ||
2273 (R0 == Mips::A0 && R1 == Mips::S6) ||
2274 (R0 == Mips::A0 && R1 == Mips::A1) ||
2275 (R0 == Mips::A0 && R1 == Mips::A2) ||
2276 (R0 == Mips::A0 && R1 == Mips::A3));
2278 return Error(IDLoc,
"invalid operand for instruction");
2284 bool FillDelaySlot =
2289 bool PrevForbiddenSlotAttr = CurForbiddenSlotAttr;
2292 bool SetReorderAfterNop =
false;
2297 if (PrevForbiddenSlotAttr && !SafeInForbiddenSlot(MCID)) {
2307 if (AssemblerOptions.
back()->isReorder() && !FillDelaySlot) {
2308 SetReorderAfterNop =
true;
2317 CurForbiddenSlotAttr =
2318 hasForbiddenSlot(MCID) && AssemblerOptions.
back()->isReorder();
2320 if (FillDelaySlot || CurForbiddenSlotAttr)
2323 MacroExpanderResultTy ExpandResult =
2324 tryExpandInstruction(Inst, IDLoc, Out, STI);
2325 switch (ExpandResult) {
2327 Out.emitInstruction(Inst, *STI);
2341 if (PrevForbiddenSlotAttr && !SetReorderAfterNop && !FillDelaySlot &&
2342 AssemblerOptions.
back()->isReorder()) {
2348 if (inMicroMipsMode()) {
2363 if (FillDelaySlot) {
2368 if ((Opcode == Mips::JalOneReg || Opcode == Mips::JalTwoReg ||
2370 isPicAndNotNxxAbi()) {
2371 if (IsCpRestoreSet) {
2375 if (!AssemblerOptions.
back()->isReorder())
2382 Warning(IDLoc,
"no .cprestore used in PIC mode");
2388void MipsAsmParser::onEndOfFile() {
2389 MipsTargetStreamer &TOut = getTargetStreamer();
2390 SMLoc IDLoc = SMLoc();
2392 if (CurForbiddenSlotAttr) {
2394 if (AssemblerOptions.
back()->isReorder())
2399MipsAsmParser::MacroExpanderResultTy
2400MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2401 const MCSubtargetInfo *STI) {
2404 return MER_NotAMacro;
2405 case Mips::LoadImm32:
2406 return expandLoadImm(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2407 case Mips::LoadImm64:
2408 return expandLoadImm(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2409 case Mips::LoadAddrImm32:
2410 case Mips::LoadAddrImm64:
2413 "expected immediate operand kind");
2415 return expandLoadAddress(
2417 Inst.
getOpcode() == Mips::LoadAddrImm32, IDLoc, Out, STI)
2420 case Mips::LoadAddrReg32:
2421 case Mips::LoadAddrReg64:
2425 "expected immediate operand kind");
2429 Inst.
getOpcode() == Mips::LoadAddrReg32, IDLoc,
2433 case Mips::B_MM_Pseudo:
2434 case Mips::B_MMR6_Pseudo:
2435 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2439 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2441 case Mips::JalOneReg:
2442 case Mips::JalTwoReg:
2443 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2446 case Mips::BEQLImmMacro:
2447 case Mips::BNELImmMacro:
2448 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2465 case Mips::BLTImmMacro:
2466 case Mips::BLEImmMacro:
2467 case Mips::BGEImmMacro:
2468 case Mips::BGTImmMacro:
2469 case Mips::BLTUImmMacro:
2470 case Mips::BLEUImmMacro:
2471 case Mips::BGEUImmMacro:
2472 case Mips::BGTUImmMacro:
2473 case Mips::BLTLImmMacro:
2474 case Mips::BLELImmMacro:
2475 case Mips::BGELImmMacro:
2476 case Mips::BGTLImmMacro:
2477 case Mips::BLTULImmMacro:
2478 case Mips::BLEULImmMacro:
2479 case Mips::BGEULImmMacro:
2480 case Mips::BGTULImmMacro:
2481 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2482 case Mips::SDivMacro:
2483 case Mips::SDivIMacro:
2484 case Mips::SRemMacro:
2485 case Mips::SRemIMacro:
2486 return expandDivRem(Inst, IDLoc, Out, STI,
false,
true) ? MER_Fail
2488 case Mips::DSDivMacro:
2489 case Mips::DSDivIMacro:
2490 case Mips::DSRemMacro:
2491 case Mips::DSRemIMacro:
2492 return expandDivRem(Inst, IDLoc, Out, STI,
true,
true) ? MER_Fail
2494 case Mips::UDivMacro:
2495 case Mips::UDivIMacro:
2496 case Mips::URemMacro:
2497 case Mips::URemIMacro:
2498 return expandDivRem(Inst, IDLoc, Out, STI,
false,
false) ? MER_Fail
2500 case Mips::DUDivMacro:
2501 case Mips::DUDivIMacro:
2502 case Mips::DURemMacro:
2503 case Mips::DURemIMacro:
2504 return expandDivRem(Inst, IDLoc, Out, STI,
true,
false) ? MER_Fail
2506 case Mips::PseudoTRUNC_W_S:
2507 return expandTrunc(Inst,
false,
false, IDLoc, Out, STI) ? MER_Fail
2509 case Mips::PseudoTRUNC_W_D32:
2510 return expandTrunc(Inst,
true,
false, IDLoc, Out, STI) ? MER_Fail
2512 case Mips::PseudoTRUNC_W_D:
2513 return expandTrunc(Inst,
true,
true, IDLoc, Out, STI) ? MER_Fail
2516 case Mips::LoadImmSingleGPR:
2517 return expandLoadSingleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2519 case Mips::LoadImmSingleFGR:
2520 return expandLoadSingleImmToFPR(Inst, IDLoc, Out, STI) ? MER_Fail
2522 case Mips::LoadImmDoubleGPR:
2523 return expandLoadDoubleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2525 case Mips::LoadImmDoubleFGR:
2526 return expandLoadDoubleImmToFPR(Inst,
true, IDLoc, Out, STI) ? MER_Fail
2528 case Mips::LoadImmDoubleFGR_32:
2529 return expandLoadDoubleImmToFPR(Inst,
false, IDLoc, Out, STI) ? MER_Fail
2533 return expandUlh(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2535 return expandUlh(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2537 return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2540 return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2542 case Mips::NORImm64:
2543 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2546 return expandSge(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2549 case Mips::SGEImm64:
2550 case Mips::SGEUImm64:
2551 return expandSgeImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2554 case Mips::SGTImm64:
2555 case Mips::SGTUImm64:
2556 return expandSgtImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2559 return expandSle(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2562 case Mips::SLEImm64:
2563 case Mips::SLEUImm64:
2564 return expandSleImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2565 case Mips::SLTImm64:
2568 return MER_NotAMacro;
2570 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2571 case Mips::SLTUImm64:
2574 return MER_NotAMacro;
2576 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2577 case Mips::ADDi:
case Mips::ADDi_MM:
2578 case Mips::ADDiu:
case Mips::ADDiu_MM:
2579 case Mips::SLTi:
case Mips::SLTi_MM:
2580 case Mips::SLTiu:
case Mips::SLTiu_MM:
2585 return MER_NotAMacro;
2586 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2589 return MER_NotAMacro;
2590 case Mips::ANDi:
case Mips::ANDi_MM:
case Mips::ANDi64:
2591 case Mips::ORi:
case Mips::ORi_MM:
case Mips::ORi64:
2592 case Mips::XORi:
case Mips::XORi_MM:
case Mips::XORi64:
2597 return MER_NotAMacro;
2598 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2601 return MER_NotAMacro;
2604 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2607 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2610 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2613 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2614 case Mips::ABSMacro:
2615 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2616 case Mips::MULImmMacro:
2617 case Mips::DMULImmMacro:
2618 return expandMulImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2619 case Mips::MULOMacro:
2620 case Mips::DMULOMacro:
2621 return expandMulO(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2622 case Mips::MULOUMacro:
2623 case Mips::DMULOUMacro:
2624 return expandMulOU(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2625 case Mips::DMULMacro:
2626 return expandDMULMacro(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2629 return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2634 return expandStoreDM1Macro(Inst, IDLoc, Out, STI)
2637 case Mips::SEQMacro:
2638 return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2639 case Mips::SEQIMacro:
2640 return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2641 case Mips::SNEMacro:
2642 return expandSne(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2643 case Mips::SNEIMacro:
2644 return expandSneI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2645 case Mips::MFTC0:
case Mips::MTTC0:
2646 case Mips::MFTGPR:
case Mips::MTTGPR:
2647 case Mips::MFTLO:
case Mips::MTTLO:
2648 case Mips::MFTHI:
case Mips::MTTHI:
2649 case Mips::MFTACX:
case Mips::MTTACX:
2650 case Mips::MFTDSP:
case Mips::MTTDSP:
2651 case Mips::MFTC1:
case Mips::MTTC1:
2652 case Mips::MFTHC1:
case Mips::MTTHC1:
2653 case Mips::CFTC1:
case Mips::CTTC1:
2654 return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2656 case Mips::SaadAddr:
2657 return expandSaaAddr(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2661bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2663 const MCSubtargetInfo *STI) {
2664 MipsTargetStreamer &TOut = getTargetStreamer();
2669 const MCOperand FirstRegOp = Inst.
getOperand(0);
2670 const unsigned Opcode = Inst.
getOpcode();
2672 if (Opcode == Mips::JalOneReg) {
2674 if (IsCpRestoreSet && inMicroMipsMode()) {
2677 }
else if (inMicroMipsMode()) {
2678 JalrInst.
setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2685 }
else if (Opcode == Mips::JalTwoReg) {
2687 if (IsCpRestoreSet && inMicroMipsMode())
2690 JalrInst.
setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2692 const MCOperand SecondRegOp = Inst.
getOperand(1);
2695 Out.emitInstruction(JalrInst, *STI);
2699 const MCInstrDesc &MCID = MII.get(JalrInst.
getOpcode());
2722bool MipsAsmParser::loadImmediate(int64_t ImmValue, MCRegister DstReg,
2723 MCRegister SrcReg,
bool Is32BitImm,
2724 bool IsAddress, SMLoc IDLoc, MCStreamer &Out,
2725 const MCSubtargetInfo *STI) {
2726 MipsTargetStreamer &TOut = getTargetStreamer();
2728 if (!Is32BitImm && !isGP64bit()) {
2729 Error(IDLoc,
"instruction requires a 64-bit architecture");
2740 Error(IDLoc,
"instruction requires a 32-bit immediate");
2745 MCRegister ZeroReg = IsAddress ?
ABI.GetNullPtr() :
ABI.GetZeroReg();
2746 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2748 bool UseSrcReg =
false;
2752 MCRegister TmpReg = DstReg;
2754 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2757 MCRegister ATReg = getATReg(IDLoc);
2770 if (IsAddress && !Is32BitImm) {
2771 TOut.
emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2775 TOut.
emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2780 MCRegister TmpReg = DstReg;
2781 if (SrcReg == DstReg) {
2782 TmpReg = getATReg(IDLoc);
2787 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2789 TOut.
emitRRR(
ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2794 warnIfNoMacro(IDLoc);
2796 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2797 uint16_t Bits15To0 = ImmValue & 0xffff;
2798 if (!Is32BitImm && !
isInt<32>(ImmValue)) {
2801 if (ImmValue == 0xffffffff) {
2802 TOut.
emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2803 TOut.
emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2805 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2811 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2812 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2814 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2816 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2820 TOut.
emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2822 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2824 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2830 Error(IDLoc,
"instruction requires a 32-bit immediate");
2837 assert(
BitWidth >= 17 &&
"ImmValue must be at least 17-bit wide");
2841 unsigned ShiftAmount =
BitWidth - 16;
2842 uint16_t
Bits = (ImmValue >> ShiftAmount) & 0xffff;
2843 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2844 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2847 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2852 warnIfNoMacro(IDLoc);
2859 if (loadImmediate(ImmValue >> 32, TmpReg, MCRegister(),
true,
false, IDLoc,
2865 unsigned ShiftCarriedForwards = 16;
2866 for (
int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2867 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2869 if (ImmChunk != 0) {
2870 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2871 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2872 ShiftCarriedForwards = 0;
2875 ShiftCarriedForwards += 16;
2877 ShiftCarriedForwards -= 16;
2880 if (ShiftCarriedForwards)
2881 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2884 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2889bool MipsAsmParser::expandLoadImm(MCInst &Inst,
bool Is32BitImm, SMLoc IDLoc,
2890 MCStreamer &Out,
const MCSubtargetInfo *STI) {
2892 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
2893 const MCOperand &DstRegOp = Inst.
getOperand(0);
2894 assert(DstRegOp.
isReg() &&
"expected register operand kind");
2896 if (loadImmediate(ImmOp.
getImm(), DstRegOp.
getReg(), MCRegister(), Is32BitImm,
2897 false, IDLoc, Out, STI))
2903bool MipsAsmParser::expandLoadAddress(MCRegister DstReg, MCRegister BaseReg,
2905 bool Is32BitAddress, SMLoc IDLoc,
2907 const MCSubtargetInfo *STI) {
2909 if (Is32BitAddress &&
ABI.ArePtrs64bit()) {
2910 Warning(IDLoc,
"la used to load 64-bit address");
2912 Is32BitAddress =
false;
2916 if (!Is32BitAddress && !hasMips3()) {
2917 Error(IDLoc,
"instruction requires a 64-bit architecture");
2922 return loadAndAddSymbolAddress(
Offset.getExpr(), DstReg, BaseReg,
2923 Is32BitAddress, IDLoc, Out, STI);
2925 if (!
ABI.ArePtrs64bit()) {
2927 Is32BitAddress =
true;
2930 return loadImmediate(
Offset.getImm(), DstReg, BaseReg, Is32BitAddress,
true,
2934bool MipsAsmParser::loadAndAddSymbolAddress(
const MCExpr *SymExpr,
2936 MCRegister SrcReg,
bool Is32BitSym,
2937 SMLoc IDLoc, MCStreamer &Out,
2938 const MCSubtargetInfo *STI) {
2939 MipsTargetStreamer &TOut = getTargetStreamer();
2941 SrcReg.
isValid() && SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64;
2942 warnIfNoMacro(IDLoc);
2947 Error(IDLoc,
"expected relocatable expression");
2951 Error(IDLoc,
"expected relocatable expression with only one symbol");
2955 bool IsPtr64 =
ABI.ArePtrs64bit();
2958 ?
static_cast<const MCSymbolELF *
>(Res.
getAddSym())
2966 bool UseXGOT = STI->
hasFeature(Mips::FeatureXGOT) && !IsLocalSym;
2972 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2975 const MCExpr *CallHiExpr =
2977 const MCExpr *CallLoExpr =
2981 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, DstReg, GPReg,
2983 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, DstReg,
2986 const MCExpr *CallExpr =
2988 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, GPReg,
2994 MCRegister TmpReg = DstReg;
2996 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
3000 MCRegister ATReg = getATReg(IDLoc);
3019 const MCExpr *CallHiExpr =
3026 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg, GPReg,
3028 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, TmpReg,
3032 TOut.
emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3038 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3043 const MCSpecifierExpr *GotExpr =
nullptr;
3044 const MCExpr *LoExpr =
nullptr;
3045 if (
ABI.IsN32() ||
ABI.IsN64()) {
3064 Error(IDLoc,
"macro instruction uses large offset, which is not "
3065 "currently supported");
3094 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, GPReg,
3098 TOut.
emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3102 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3108 const auto *HiExpr =
3110 const auto *LoExpr =
3114 if (
ABI.ArePtrs64bit() && isGP64bit()) {
3122 const auto *HighestExpr =
3124 const auto *HigherExpr =
3129 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
3131 if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
3132 MCRegister ATReg = getATReg(IDLoc);
3144 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3146 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3149 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3152 TOut.
emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
3155 }
else if (canUseATReg() && !RdRegIsRsReg && DstReg != getATReg(IDLoc)) {
3156 MCRegister ATReg = getATReg(IDLoc);
3172 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3176 TOut.
emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3177 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3179 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3182 }
else if ((!canUseATReg() && !RdRegIsRsReg) ||
3183 (canUseATReg() && DstReg == getATReg(IDLoc))) {
3194 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3196 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3197 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3199 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3200 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3203 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3209 assert(SrcReg == DstReg && !canUseATReg() &&
3210 "Could have expanded dla but didn't?");
3211 reportParseError(IDLoc,
3212 "pseudo-instruction requires $at, which is not available");
3226 MCRegister TmpReg = DstReg;
3228 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
3231 MCRegister ATReg = getATReg(IDLoc);
3242 TOut.
emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3245 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
3254 if (getMipsMCRegisterClass(Mips::FGR32RegClassID).
contains(
Reg))
3255 return Reg == (
unsigned)Mips::F31 ? (
unsigned)Mips::F0 :
Reg + 1;
3257 default:
llvm_unreachable(
"Unknown register in assembly macro expansion!");
3258 case Mips::ZERO:
return Mips::AT;
3259 case Mips::AT:
return Mips::V0;
3260 case Mips::V0:
return Mips::V1;
3261 case Mips::V1:
return Mips::A0;
3262 case Mips::A0:
return Mips::A1;
3263 case Mips::A1:
return Mips::A2;
3264 case Mips::A2:
return Mips::A3;
3265 case Mips::A3:
return Mips::T0;
3266 case Mips::T0:
return Mips::T1;
3267 case Mips::T1:
return Mips::T2;
3268 case Mips::T2:
return Mips::T3;
3269 case Mips::T3:
return Mips::T4;
3270 case Mips::T4:
return Mips::T5;
3271 case Mips::T5:
return Mips::T6;
3272 case Mips::T6:
return Mips::T7;
3273 case Mips::T7:
return Mips::S0;
3274 case Mips::S0:
return Mips::S1;
3275 case Mips::S1:
return Mips::S2;
3276 case Mips::S2:
return Mips::S3;
3277 case Mips::S3:
return Mips::S4;
3278 case Mips::S4:
return Mips::S5;
3279 case Mips::S5:
return Mips::S6;
3280 case Mips::S6:
return Mips::S7;
3281 case Mips::S7:
return Mips::T8;
3282 case Mips::T8:
return Mips::T9;
3283 case Mips::T9:
return Mips::K0;
3284 case Mips::K0:
return Mips::K1;
3285 case Mips::K1:
return Mips::GP;
3286 case Mips::GP:
return Mips::SP;
3287 case Mips::SP:
return Mips::FP;
3288 case Mips::FP:
return Mips::RA;
3289 case Mips::RA:
return Mips::ZERO;
3290 case Mips::D0:
return Mips::F1;
3291 case Mips::D1:
return Mips::F3;
3292 case Mips::D2:
return Mips::F5;
3293 case Mips::D3:
return Mips::F7;
3294 case Mips::D4:
return Mips::F9;
3295 case Mips::D5:
return Mips::F11;
3296 case Mips::D6:
return Mips::F13;
3297 case Mips::D7:
return Mips::F15;
3298 case Mips::D8:
return Mips::F17;
3299 case Mips::D9:
return Mips::F19;
3300 case Mips::D10:
return Mips::F21;
3301 case Mips::D11:
return Mips::F23;
3302 case Mips::D12:
return Mips::F25;
3303 case Mips::D13:
return Mips::F27;
3304 case Mips::D14:
return Mips::F29;
3305 case Mips::D15:
return Mips::F31;
3315bool MipsAsmParser::emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc,
3317 MCRegister ATReg = getATReg(IDLoc);
3323 const auto *GotExpr =
3326 if(isABI_O32() || isABI_N32()) {
3335 const auto *HiExpr =
3344 if(isABI_O32() || isABI_N32()) {
3348 const auto *HighestExpr =
3351 const auto *HigherExpr =
3356 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3358 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3361 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3370 if ((
Hi_32(ImmOp64) & 0x7ff00000) == 0) {
3381 float TmpFloat =
static_cast<float>(DoubleImm);
3385bool MipsAsmParser::expandLoadSingleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3387 const MCSubtargetInfo *STI) {
3390 "Invalid instruction operand.");
3397 return loadImmediate(ImmOp32, FirstReg, MCRegister(),
true,
false, IDLoc, Out,
3401bool MipsAsmParser::expandLoadSingleImmToFPR(MCInst &Inst, SMLoc IDLoc,
3403 const MCSubtargetInfo *STI) {
3404 MipsTargetStreamer &TOut = getTargetStreamer();
3407 "Invalid instruction operand.");
3416 MCRegister TmpReg = Mips::ZERO;
3418 TmpReg = getATReg(IDLoc);
3423 if (
Lo_32(ImmOp64) == 0) {
3424 if (TmpReg != Mips::ZERO && loadImmediate(ImmOp32, TmpReg, MCRegister(),
3425 true,
false, IDLoc, Out, STI))
3427 TOut.
emitRR(Mips::MTC1, FirstReg, TmpReg, IDLoc, STI);
3431 MCSection *CS = getStreamer().getCurrentSectionOnly();
3434 MCSection *ReadOnlySection =
3441 getStreamer().switchSection(ReadOnlySection);
3442 getStreamer().emitLabel(Sym, IDLoc);
3443 getStreamer().emitInt32(ImmOp32);
3444 getStreamer().switchSection(CS);
3446 if (emitPartialAddress(TOut, IDLoc, Sym))
3453bool MipsAsmParser::expandLoadDoubleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3455 const MCSubtargetInfo *STI) {
3456 MipsTargetStreamer &TOut = getTargetStreamer();
3459 "Invalid instruction operand.");
3466 if (
Lo_32(ImmOp64) == 0) {
3468 if (loadImmediate(ImmOp64, FirstReg, MCRegister(),
false,
false, IDLoc,
3472 if (loadImmediate(
Hi_32(ImmOp64), FirstReg, MCRegister(),
true,
false,
3476 if (loadImmediate(0,
nextReg(FirstReg), MCRegister(),
true,
false, IDLoc,
3483 MCSection *CS = getStreamer().getCurrentSectionOnly();
3484 MCSection *ReadOnlySection =
3491 getStreamer().switchSection(ReadOnlySection);
3492 getStreamer().emitLabel(Sym, IDLoc);
3493 getStreamer().emitValueToAlignment(
Align(8));
3494 getStreamer().emitIntValue(ImmOp64, 8);
3495 getStreamer().switchSection(CS);
3497 MCRegister TmpReg = getATReg(IDLoc);
3501 if (emitPartialAddress(TOut, IDLoc, Sym))
3504 TOut.
emitRRX(isABI_N64() ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3508 TOut.
emitRRI(Mips::LD, FirstReg, TmpReg, 0, IDLoc, STI);
3510 TOut.
emitRRI(Mips::LW, FirstReg, TmpReg, 0, IDLoc, STI);
3511 TOut.
emitRRI(Mips::LW,
nextReg(FirstReg), TmpReg, 4, IDLoc, STI);
3516bool MipsAsmParser::expandLoadDoubleImmToFPR(MCInst &Inst,
bool Is64FPU,
3517 SMLoc IDLoc, MCStreamer &Out,
3518 const MCSubtargetInfo *STI) {
3519 MipsTargetStreamer &TOut = getTargetStreamer();
3522 "Invalid instruction operand.");
3529 MCRegister TmpReg = Mips::ZERO;
3531 TmpReg = getATReg(IDLoc);
3536 if ((
Lo_32(ImmOp64) == 0) &&
3537 !((
Hi_32(ImmOp64) & 0xffff0000) && (
Hi_32(ImmOp64) & 0x0000ffff))) {
3539 if (TmpReg != Mips::ZERO && loadImmediate(ImmOp64, TmpReg, MCRegister(),
3540 false,
false, IDLoc, Out, STI))
3542 TOut.
emitRR(Mips::DMTC1, FirstReg, TmpReg, IDLoc, STI);
3546 if (TmpReg != Mips::ZERO &&
3547 loadImmediate(
Hi_32(ImmOp64), TmpReg, MCRegister(),
true,
false, IDLoc,
3551 if (hasMips32r2()) {
3552 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3553 TOut.
emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, TmpReg, IDLoc, STI);
3555 TOut.
emitRR(Mips::MTC1,
nextReg(FirstReg), TmpReg, IDLoc, STI);
3556 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3561 MCSection *CS = getStreamer().getCurrentSectionOnly();
3564 MCSection *ReadOnlySection =
3571 getStreamer().switchSection(ReadOnlySection);
3572 getStreamer().emitLabel(Sym, IDLoc);
3573 getStreamer().emitValueToAlignment(
Align(8));
3574 getStreamer().emitIntValue(ImmOp64, 8);
3575 getStreamer().switchSection(CS);
3577 if (emitPartialAddress(TOut, IDLoc, Sym))
3580 TOut.
emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, TmpReg,
3586bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
3588 const MCSubtargetInfo *STI) {
3589 MipsTargetStreamer &TOut = getTargetStreamer();
3592 "unexpected number of operands");
3602 assert(
Offset.isImm() &&
"expected immediate operand kind");
3606 if (inMicroMipsMode())
3607 Inst.
setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3610 return Error(IDLoc,
"branch target out of range");
3612 return Error(IDLoc,
"branch to misaligned address");
3620 Out.emitInstruction(Inst, *STI);
3624 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
3631bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3632 const MCSubtargetInfo *STI) {
3633 MipsTargetStreamer &TOut = getTargetStreamer();
3634 const MCOperand &DstRegOp = Inst.
getOperand(0);
3635 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3638 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
3640 const MCOperand &MemOffsetOp = Inst.
getOperand(2);
3642 "expected immediate or expression operand");
3644 bool IsLikely =
false;
3654 case Mips::BEQLImmMacro:
3658 case Mips::BNELImmMacro:
3667 int64_t ImmValue = ImmOp.
getImm();
3668 if (ImmValue == 0) {
3672 TOut.
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3674 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3677 warnIfNoMacro(IDLoc);
3679 MCRegister ATReg = getATReg(IDLoc);
3683 if (loadImmediate(ImmValue, ATReg, MCRegister(), !isGP64bit(),
true, IDLoc,
3687 if (IsLikely && MemOffsetOp.
isExpr()) {
3690 TOut.
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3692 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3697void MipsAsmParser::expandMem16Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3698 const MCSubtargetInfo *STI,
bool IsLoad) {
3700 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3701 unsigned StartOp = NumOp == 3 ? 0 : 1;
3703 const MCOperand &DstRegOp = Inst.
getOperand(StartOp);
3704 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3705 const MCOperand &BaseRegOp = Inst.
getOperand(StartOp + 1);
3706 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3709 MipsTargetStreamer &TOut = getTargetStreamer();
3711 MCRegister DstReg = DstRegOp.
getReg();
3713 MCRegister TmpReg = DstReg;
3715 const MCInstrDesc &
Desc = MII.get(OpCode);
3716 int16_t DstRegClass =
3717 MII.getOpRegClassID(
Desc.operands()[StartOp],
3719 unsigned DstRegClassID =
3720 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3721 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3722 (DstRegClassID == Mips::GPR64RegClassID);
3724 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3727 TmpReg = getATReg(IDLoc);
3732 auto emitInstWithOffset = [&](
const MCOperand &
Off) {
3734 TOut.
emitRRX(OpCode, DstReg, TmpReg,
Off, IDLoc, STI);
3736 TOut.
emitRRRX(OpCode, DstReg, DstReg, TmpReg,
Off, IDLoc, STI);
3740 int64_t LoOffset =
OffsetOp.getImm() & 0xffff;
3741 int64_t HiOffset =
OffsetOp.getImm() & ~0xffff;
3745 if (LoOffset & 0x8000)
3746 HiOffset += 0x10000;
3748 bool IsLargeOffset = HiOffset != 0;
3750 if (IsLargeOffset) {
3752 if (loadImmediate(HiOffset, TmpReg, MCRegister(), Is32BitImm,
true, IDLoc,
3757 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3758 TOut.
emitRRR(
ABI.ArePtrs64bit() ? Mips::DADDu : Mips::ADDu, TmpReg,
3759 TmpReg, BaseReg, IDLoc, STI);
3773 if (!
OffsetOp.getExpr()->evaluateAsRelocatable(Res,
nullptr)) {
3774 Error(IDLoc,
"expected relocatable expression");
3778 Error(IDLoc,
"expected relocatable expression with only one symbol");
3782 loadAndAddSymbolAddress(
3784 BaseReg, !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3792 const MCExpr *OffExpr =
OffsetOp.getExpr();
3804 TOut.
emitRX(Mips::LUi, TmpReg, HighestOperand, IDLoc, STI);
3805 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HigherOperand, IDLoc, STI);
3806 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3807 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HiOperand, IDLoc, STI);
3808 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3809 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3810 TOut.
emitRRR(Mips::DADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3811 emitInstWithOffset(LoOperand);
3814 TOut.
emitRX(Mips::LUi, TmpReg, HiOperand, IDLoc, STI);
3815 if (BaseReg != Mips::ZERO)
3816 TOut.
emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3818 emitInstWithOffset(LoOperand);
3827void MipsAsmParser::expandMem9Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3828 const MCSubtargetInfo *STI,
bool IsLoad) {
3830 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3831 unsigned StartOp = NumOp == 3 ? 0 : 1;
3833 const MCOperand &DstRegOp = Inst.
getOperand(StartOp);
3834 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3835 const MCOperand &BaseRegOp = Inst.
getOperand(StartOp + 1);
3836 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3839 MipsTargetStreamer &TOut = getTargetStreamer();
3841 MCRegister DstReg = DstRegOp.
getReg();
3843 MCRegister TmpReg = DstReg;
3845 const MCInstrDesc &
Desc = MII.get(OpCode);
3846 int16_t DstRegClass =
3847 MII.getOpRegClassID(
Desc.operands()[StartOp],
3850 unsigned DstRegClassID =
3851 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3852 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3853 (DstRegClassID == Mips::GPR64RegClassID);
3855 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3858 TmpReg = getATReg(IDLoc);
3863 auto emitInst = [&]() {
3872 loadImmediate(
OffsetOp.getImm(), TmpReg, BaseReg, !
ABI.ArePtrs64bit(),
true,
3879 loadAndAddSymbolAddress(
OffsetOp.getExpr(), TmpReg, BaseReg,
3880 !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3888bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
3890 const MCSubtargetInfo *STI) {
3893 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3897 Inst.
getOperand(OpNum - 3).
isReg() &&
"Invalid instruction operand.");
3906 if (inMicroMipsMode() && hasMips32r6())
3907 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3909 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3913 Out.emitInstruction(Inst, *STI);
3917bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
3919 const MCSubtargetInfo *STI) {
3920 MipsTargetStreamer &TOut = getTargetStreamer();
3921 bool EmittedNoMacroWarning =
false;
3922 unsigned PseudoOpcode = Inst.
getOpcode();
3927 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3928 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3933 else if (TrgOp.
isImm()) {
3934 warnIfNoMacro(IDLoc);
3935 EmittedNoMacroWarning =
true;
3937 TrgReg = getATReg(IDLoc);
3941 switch(PseudoOpcode) {
3944 case Mips::BLTImmMacro:
3945 PseudoOpcode = Mips::BLT;
3947 case Mips::BLEImmMacro:
3948 PseudoOpcode = Mips::BLE;
3950 case Mips::BGEImmMacro:
3951 PseudoOpcode = Mips::BGE;
3953 case Mips::BGTImmMacro:
3954 PseudoOpcode = Mips::BGT;
3956 case Mips::BLTUImmMacro:
3957 PseudoOpcode = Mips::BLTU;
3959 case Mips::BLEUImmMacro:
3960 PseudoOpcode = Mips::BLEU;
3962 case Mips::BGEUImmMacro:
3963 PseudoOpcode = Mips::BGEU;
3965 case Mips::BGTUImmMacro:
3966 PseudoOpcode = Mips::BGTU;
3968 case Mips::BLTLImmMacro:
3969 PseudoOpcode = Mips::BLTL;
3971 case Mips::BLELImmMacro:
3972 PseudoOpcode = Mips::BLEL;
3974 case Mips::BGELImmMacro:
3975 PseudoOpcode = Mips::BGEL;
3977 case Mips::BGTLImmMacro:
3978 PseudoOpcode = Mips::BGTL;
3980 case Mips::BLTULImmMacro:
3981 PseudoOpcode = Mips::BLTUL;
3983 case Mips::BLEULImmMacro:
3984 PseudoOpcode = Mips::BLEUL;
3986 case Mips::BGEULImmMacro:
3987 PseudoOpcode = Mips::BGEUL;
3989 case Mips::BGTULImmMacro:
3990 PseudoOpcode = Mips::BGTUL;
3994 if (loadImmediate(TrgOp.
getImm(), TrgReg, MCRegister(), !isGP64bit(),
false,
3999 switch (PseudoOpcode) {
4004 AcceptsEquality =
false;
4005 ReverseOrderSLT =
false;
4007 ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
4008 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
4009 ZeroSrcOpcode = Mips::BGTZ;
4010 ZeroTrgOpcode = Mips::BLTZ;
4016 AcceptsEquality =
true;
4017 ReverseOrderSLT =
true;
4019 ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
4020 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
4021 ZeroSrcOpcode = Mips::BGEZ;
4022 ZeroTrgOpcode = Mips::BLEZ;
4028 AcceptsEquality =
true;
4029 ReverseOrderSLT =
false;
4031 ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
4032 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
4033 ZeroSrcOpcode = Mips::BLEZ;
4034 ZeroTrgOpcode = Mips::BGEZ;
4040 AcceptsEquality =
false;
4041 ReverseOrderSLT =
true;
4043 ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
4044 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
4045 ZeroSrcOpcode = Mips::BLTZ;
4046 ZeroTrgOpcode = Mips::BGTZ;
4052 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
4053 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
4054 if (IsSrcRegZero && IsTrgRegZero) {
4058 if (PseudoOpcode == Mips::BLT) {
4063 if (PseudoOpcode == Mips::BLE) {
4066 Warning(IDLoc,
"branch is always taken");
4069 if (PseudoOpcode == Mips::BGE) {
4072 Warning(IDLoc,
"branch is always taken");
4075 if (PseudoOpcode == Mips::BGT) {
4080 if (PseudoOpcode == Mips::BGTU) {
4081 TOut.
emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
4085 if (AcceptsEquality) {
4088 TOut.
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4090 Warning(IDLoc,
"branch is always taken");
4097 if (IsSrcRegZero || IsTrgRegZero) {
4098 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
4099 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
4106 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
4107 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
4113 TOut.
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4115 Warning(IDLoc,
"branch is always taken");
4131 TOut.
emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
4132 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
4139 TOut.
emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
4140 IsSrcRegZero ? TrgReg : SrcReg,
4147 MCRegister ATRegNum = getATReg(IDLoc);
4151 if (!EmittedNoMacroWarning)
4152 warnIfNoMacro(IDLoc);
4169 TOut.
emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
4170 ReverseOrderSLT ? TrgReg : SrcReg,
4171 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
4173 TOut.
emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
4174 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
4188bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4189 const MCSubtargetInfo *STI,
4190 const bool IsMips64,
const bool Signed) {
4191 MipsTargetStreamer &TOut = getTargetStreamer();
4193 warnIfNoMacro(IDLoc);
4195 const MCOperand &RdRegOp = Inst.
getOperand(0);
4196 assert(RdRegOp.
isReg() &&
"expected register operand kind");
4197 MCRegister RdReg = RdRegOp.
getReg();
4199 const MCOperand &RsRegOp = Inst.
getOperand(1);
4200 assert(RsRegOp.
isReg() &&
"expected register operand kind");
4201 MCRegister RsReg = RsRegOp.
getReg();
4208 "expected register or immediate operand kind");
4212 ImmValue = RtOp.
getImm();
4219 DivOp =
Signed ? Mips::DSDIV : Mips::DUDIV;
4220 ZeroReg = Mips::ZERO_64;
4223 DivOp =
Signed ? Mips::SDIV : Mips::UDIV;
4224 ZeroReg = Mips::ZERO;
4228 bool UseTraps = useTraps();
4231 bool isDiv = Opcode == Mips::SDivMacro || Opcode == Mips::SDivIMacro ||
4232 Opcode == Mips::UDivMacro || Opcode == Mips::UDivIMacro ||
4233 Opcode == Mips::DSDivMacro || Opcode == Mips::DSDivIMacro ||
4234 Opcode == Mips::DUDivMacro || Opcode == Mips::DUDivIMacro;
4236 bool isRem = Opcode == Mips::SRemMacro || Opcode == Mips::SRemIMacro ||
4237 Opcode == Mips::URemMacro || Opcode == Mips::URemIMacro ||
4238 Opcode == Mips::DSRemMacro || Opcode == Mips::DSRemIMacro ||
4239 Opcode == Mips::DURemMacro || Opcode == Mips::DURemIMacro;
4242 MCRegister ATReg = getATReg(IDLoc);
4246 if (!CLOpts.mno_check_zero_division && ImmValue == 0) {
4248 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4250 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4254 if (isRem && (ImmValue == 1 || (
Signed && (ImmValue == -1)))) {
4255 TOut.
emitRRR(Mips::OR, RdReg, ZeroReg, ZeroReg, IDLoc, STI);
4257 }
else if (isDiv && ImmValue == 1) {
4258 TOut.
emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI);
4260 }
else if (isDiv &&
Signed && ImmValue == -1) {
4261 TOut.
emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
4264 if (loadImmediate(ImmValue, ATReg, MCRegister(),
isInt<32>(ImmValue),
4265 false, Inst.
getLoc(), Out, STI))
4267 TOut.
emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
4268 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4278 if (!CLOpts.mno_check_zero_division &&
4279 (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
4281 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4284 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4290 if (isRem && (RdReg == Mips::ZERO || RdReg == Mips::ZERO_64)) {
4291 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4300 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4301 if (!CLOpts.mno_check_zero_division) {
4303 TOut.
emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4306 BrTarget =
Context.createTempSymbol();
4309 TOut.
emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4314 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4320 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4324bool MipsAsmParser::expandTrunc(MCInst &Inst,
bool IsDouble,
bool Is64FPU,
4325 SMLoc IDLoc, MCStreamer &Out,
4326 const MCSubtargetInfo *STI) {
4327 MipsTargetStreamer &TOut = getTargetStreamer();
4337 if (hasMips1() && !hasMips2()) {
4338 MCRegister ATReg = getATReg(IDLoc);
4341 TOut.
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4342 TOut.
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4344 TOut.
emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4345 TOut.
emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4346 TOut.
emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4348 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4350 FirstReg, SecondReg, IDLoc, STI);
4351 TOut.
emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4356 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4358 FirstReg, SecondReg, IDLoc, STI);
4363bool MipsAsmParser::expandUlh(MCInst &Inst,
bool Signed, SMLoc IDLoc,
4364 MCStreamer &Out,
const MCSubtargetInfo *STI) {
4365 if (hasMips32r6() || hasMips64r6()) {
4366 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4369 const MCOperand &DstRegOp = Inst.
getOperand(0);
4370 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4371 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4372 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4373 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4374 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4376 MipsTargetStreamer &TOut = getTargetStreamer();
4377 MCRegister DstReg = DstRegOp.
getReg();
4378 MCRegister SrcReg = SrcRegOp.
getReg();
4379 int64_t OffsetValue = OffsetImmOp.
getImm();
4383 warnIfNoMacro(IDLoc);
4384 MCRegister ATReg = getATReg(IDLoc);
4389 if (IsLargeOffset) {
4390 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4395 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4396 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4400 MCRegister FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4401 MCRegister SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4403 MCRegister LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4404 MCRegister SllReg = IsLargeOffset ? DstReg : ATReg;
4406 TOut.
emitRRI(
Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4407 FirstOffset, IDLoc, STI);
4408 TOut.
emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4409 TOut.
emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4410 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4415bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4416 const MCSubtargetInfo *STI) {
4417 if (hasMips32r6() || hasMips64r6()) {
4418 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4421 const MCOperand &DstRegOp = Inst.
getOperand(0);
4422 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4423 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4424 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4425 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4426 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4428 MipsTargetStreamer &TOut = getTargetStreamer();
4429 MCRegister DstReg = DstRegOp.
getReg();
4430 MCRegister SrcReg = SrcRegOp.
getReg();
4431 int64_t OffsetValue = OffsetImmOp.
getImm();
4433 warnIfNoMacro(IDLoc);
4434 MCRegister ATReg = getATReg(IDLoc);
4439 if (IsLargeOffset) {
4440 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4445 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4446 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4450 if (IsLargeOffset) {
4451 TOut.
emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4452 TOut.
emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4453 TOut.
emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4454 TOut.
emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4455 TOut.
emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4456 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4458 TOut.
emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4459 TOut.
emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4460 TOut.
emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4466bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4467 const MCSubtargetInfo *STI) {
4468 if (hasMips32r6() || hasMips64r6()) {
4469 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4472 const MCOperand &DstRegOp = Inst.
getOperand(0);
4473 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4474 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4475 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4476 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4477 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4479 MipsTargetStreamer &TOut = getTargetStreamer();
4480 MCRegister DstReg = DstRegOp.
getReg();
4481 MCRegister SrcReg = SrcRegOp.
getReg();
4482 int64_t OffsetValue = OffsetImmOp.
getImm();
4486 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4487 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4491 bool IsLoadInst = (Inst.
getOpcode() == Mips::Ulw);
4492 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4493 MCRegister TmpReg = SrcReg;
4494 if (IsLargeOffset || DoMove) {
4495 warnIfNoMacro(IDLoc);
4496 TmpReg = getATReg(IDLoc);
4501 if (IsLargeOffset) {
4502 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4510 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4511 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4512 TOut.
emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4513 TOut.
emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4516 TOut.
emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4521bool MipsAsmParser::expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4522 const MCSubtargetInfo *STI) {
4523 MipsTargetStreamer &TOut = getTargetStreamer();
4535 warnIfNoMacro(IDLoc);
4549 TOut.
emitRRR(OpCode, DstReg, SrcReg, OpReg, IDLoc, STI);
4550 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4555bool MipsAsmParser::expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4556 const MCSubtargetInfo *STI) {
4557 MipsTargetStreamer &TOut = getTargetStreamer();
4567 unsigned OpRegCode, OpImmCode;
4569 warnIfNoMacro(IDLoc);
4573 case Mips::SGEImm64:
4574 OpRegCode = Mips::SLT;
4575 OpImmCode = Mips::SLTi;
4578 case Mips::SGEUImm64:
4579 OpRegCode = Mips::SLTu;
4580 OpImmCode = Mips::SLTiu;
4589 TOut.
emitRRI(OpImmCode, DstReg, SrcReg, ImmValue, IDLoc, STI);
4590 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4592 MCRegister ImmReg = DstReg;
4593 if (DstReg == SrcReg) {
4594 MCRegister ATReg = getATReg(Inst.
getLoc());
4600 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
4601 false, IDLoc, Out, STI))
4604 TOut.
emitRRR(OpRegCode, DstReg, SrcReg, ImmReg, IDLoc, STI);
4605 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4611bool MipsAsmParser::expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4612 const MCSubtargetInfo *STI) {
4613 MipsTargetStreamer &TOut = getTargetStreamer();
4622 MCRegister ImmReg = DstReg;
4626 warnIfNoMacro(IDLoc);
4630 case Mips::SGTImm64:
4634 case Mips::SGTUImm64:
4641 if (DstReg == SrcReg) {
4642 MCRegister ATReg = getATReg(Inst.
getLoc());
4648 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
false,
4653 TOut.
emitRRR(OpCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4658bool MipsAsmParser::expandSle(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4659 const MCSubtargetInfo *STI) {
4660 MipsTargetStreamer &TOut = getTargetStreamer();
4672 warnIfNoMacro(IDLoc);
4686 TOut.
emitRRR(OpCode, DstReg, OpReg, SrcReg, IDLoc, STI);
4687 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4692bool MipsAsmParser::expandSleImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4693 const MCSubtargetInfo *STI) {
4694 MipsTargetStreamer &TOut = getTargetStreamer();
4706 warnIfNoMacro(IDLoc);
4710 case Mips::SLEImm64:
4711 OpRegCode = Mips::SLT;
4714 case Mips::SLEUImm64:
4715 OpRegCode = Mips::SLTu;
4722 MCRegister ImmReg = DstReg;
4723 if (DstReg == SrcReg) {
4724 MCRegister ATReg = getATReg(Inst.
getLoc());
4730 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
false,
4734 TOut.
emitRRR(OpRegCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4735 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4740bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
4742 const MCSubtargetInfo *STI) {
4743 MipsTargetStreamer &TOut = getTargetStreamer();
4751 MCRegister FinalDstReg;
4758 unsigned FinalOpcode = Inst.
getOpcode();
4760 if (DstReg == SrcReg) {
4761 ATReg = getATReg(Inst.
getLoc());
4764 FinalDstReg = DstReg;
4768 if (!loadImmediate(ImmValue, DstReg, MCRegister(), Is32Bit,
false,
4769 Inst.
getLoc(), Out, STI)) {
4770 switch (FinalOpcode) {
4774 FinalOpcode = Mips::ADD;
4777 FinalOpcode = Mips::ADDu;
4780 FinalOpcode = Mips::AND;
4783 FinalOpcode = Mips::NOR;
4786 FinalOpcode = Mips::OR;
4789 FinalOpcode = Mips::SLT;
4792 FinalOpcode = Mips::SLTu;
4795 FinalOpcode = Mips::XOR;
4798 FinalOpcode = Mips::ADD_MM;
4800 case Mips::ADDiu_MM:
4801 FinalOpcode = Mips::ADDu_MM;
4804 FinalOpcode = Mips::AND_MM;
4807 FinalOpcode = Mips::OR_MM;
4810 FinalOpcode = Mips::SLT_MM;
4812 case Mips::SLTiu_MM:
4813 FinalOpcode = Mips::SLTu_MM;
4816 FinalOpcode = Mips::XOR_MM;
4819 FinalOpcode = Mips::AND64;
4821 case Mips::NORImm64:
4822 FinalOpcode = Mips::NOR64;
4825 FinalOpcode = Mips::OR64;
4827 case Mips::SLTImm64:
4828 FinalOpcode = Mips::SLT64;
4830 case Mips::SLTUImm64:
4831 FinalOpcode = Mips::SLTu64;
4834 FinalOpcode = Mips::XOR64;
4839 TOut.
emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4841 TOut.
emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4847bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4848 const MCSubtargetInfo *STI) {
4849 MipsTargetStreamer &TOut = getTargetStreamer();
4854 MCRegister TmpReg =
DReg;
4856 unsigned FirstShift = Mips::NOP;
4857 unsigned SecondShift = Mips::NOP;
4859 if (hasMips32r2()) {
4861 TmpReg = getATReg(Inst.
getLoc());
4867 TOut.
emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4868 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
4873 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
4885 FirstShift = Mips::SRLV;
4886 SecondShift = Mips::SLLV;
4889 FirstShift = Mips::SLLV;
4890 SecondShift = Mips::SRLV;
4894 ATReg = getATReg(Inst.
getLoc());
4898 TOut.
emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4899 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
4900 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
4901 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
4909bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
4911 const MCSubtargetInfo *STI) {
4912 MipsTargetStreamer &TOut = getTargetStreamer();
4918 unsigned FirstShift = Mips::NOP;
4919 unsigned SecondShift = Mips::NOP;
4921 if (hasMips32r2()) {
4926 ShiftValue = MaxShift - ImmValue;
4927 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
4932 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.
getLoc(), STI);
4940 if (ImmValue == 0) {
4949 FirstShift = Mips::SLL;
4950 SecondShift = Mips::SRL;
4953 FirstShift = Mips::SRL;
4954 SecondShift = Mips::SLL;
4958 ATReg = getATReg(Inst.
getLoc());
4962 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.
getLoc(), STI);
4963 TOut.
emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.
getLoc(), STI);
4964 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
4972bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4973 const MCSubtargetInfo *STI) {
4974 MipsTargetStreamer &TOut = getTargetStreamer();
4979 MCRegister TmpReg =
DReg;
4981 unsigned FirstShift = Mips::NOP;
4982 unsigned SecondShift = Mips::NOP;
4984 if (hasMips64r2()) {
4985 if (TmpReg == SReg) {
4986 TmpReg = getATReg(Inst.
getLoc());
4992 TOut.
emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4993 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
4998 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
5010 FirstShift = Mips::DSRLV;
5011 SecondShift = Mips::DSLLV;
5014 FirstShift = Mips::DSLLV;
5015 SecondShift = Mips::DSRLV;
5019 ATReg = getATReg(Inst.
getLoc());
5023 TOut.
emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
5024 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
5025 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
5026 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5034bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
5036 const MCSubtargetInfo *STI) {
5037 MipsTargetStreamer &TOut = getTargetStreamer();
5043 unsigned FirstShift = Mips::NOP;
5044 unsigned SecondShift = Mips::NOP;
5048 if (hasMips64r2()) {
5049 unsigned FinalOpcode = Mips::NOP;
5051 FinalOpcode = Mips::DROTR;
5052 else if (ImmValue % 32 == 0)
5053 FinalOpcode = Mips::DROTR32;
5054 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
5056 FinalOpcode = Mips::DROTR32;
5058 FinalOpcode = Mips::DROTR;
5059 }
else if (ImmValue >= 33) {
5061 FinalOpcode = Mips::DROTR;
5063 FinalOpcode = Mips::DROTR32;
5066 uint64_t ShiftValue = ImmValue % 32;
5068 ShiftValue = (32 - ImmValue % 32) % 32;
5070 TOut.
emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
5076 if (ImmValue == 0) {
5077 TOut.
emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.
getLoc(), STI);
5085 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5086 FirstShift = Mips::DSLL;
5087 SecondShift = Mips::DSRL32;
5089 if (ImmValue == 32) {
5090 FirstShift = Mips::DSLL32;
5091 SecondShift = Mips::DSRL32;
5093 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5094 FirstShift = Mips::DSLL32;
5095 SecondShift = Mips::DSRL;
5099 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5100 FirstShift = Mips::DSRL;
5101 SecondShift = Mips::DSLL32;
5103 if (ImmValue == 32) {
5104 FirstShift = Mips::DSRL32;
5105 SecondShift = Mips::DSLL32;
5107 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5108 FirstShift = Mips::DSRL32;
5109 SecondShift = Mips::DSLL;
5114 ATReg = getATReg(Inst.
getLoc());
5118 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.
getLoc(), STI);
5119 TOut.
emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
5121 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5129bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5130 const MCSubtargetInfo *STI) {
5131 MipsTargetStreamer &TOut = getTargetStreamer();
5135 TOut.
emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
5136 if (FirstRegOp != SecondRegOp)
5137 TOut.
emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
5140 TOut.
emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
5145bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5146 const MCSubtargetInfo *STI) {
5147 MipsTargetStreamer &TOut = getTargetStreamer();
5153 ATReg = getATReg(IDLoc);
5157 loadImmediate(ImmValue, ATReg, MCRegister(),
true,
false, IDLoc, Out, STI);
5159 TOut.
emitRR(Inst.
getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
5160 SrcReg, ATReg, IDLoc, STI);
5162 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5167bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5168 const MCSubtargetInfo *STI) {
5169 MipsTargetStreamer &TOut = getTargetStreamer();
5175 ATReg = getATReg(Inst.
getLoc());
5179 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
5180 SrcReg, TmpReg, IDLoc, STI);
5182 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5184 TOut.
emitRRI(Inst.
getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
5185 DstReg, DstReg, 0x1F, IDLoc, STI);
5187 TOut.
emitR(Mips::MFHI, ATReg, IDLoc, STI);
5190 TOut.
emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
5197 TOut.
emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
5198 if (AssemblerOptions.
back()->isReorder())
5200 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5204 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5209bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5210 const MCSubtargetInfo *STI) {
5211 MipsTargetStreamer &TOut = getTargetStreamer();
5217 ATReg = getATReg(IDLoc);
5221 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
5222 SrcReg, TmpReg, IDLoc, STI);
5224 TOut.
emitR(Mips::MFHI, ATReg, IDLoc, STI);
5225 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5227 TOut.
emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);
5234 TOut.
emitRRX(Mips::BEQ, ATReg, Mips::ZERO, LabelOp, IDLoc, STI);
5235 if (AssemblerOptions.
back()->isReorder())
5237 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5245bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5246 const MCSubtargetInfo *STI) {
5247 MipsTargetStreamer &TOut = getTargetStreamer();
5252 TOut.
emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
5253 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5263bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
5265 const MCSubtargetInfo *STI,
5270 warnIfNoMacro(IDLoc);
5272 MipsTargetStreamer &TOut = getTargetStreamer();
5273 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
5275 MCRegister SecondReg =
nextReg(FirstReg);
5280 warnIfRegIndexIsAT(FirstReg, IDLoc);
5283 "Offset for load macro is not immediate!");
5286 signed NextOffset = FirstOffset.
getImm() + 4;
5294 if (FirstReg != BaseReg || !IsLoad) {
5295 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5296 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5298 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5299 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5311bool MipsAsmParser::expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc,
5313 const MCSubtargetInfo *STI) {
5317 warnIfNoMacro(IDLoc);
5319 MipsTargetStreamer &TOut = getTargetStreamer();
5320 unsigned Opcode = Mips::SWC1;
5322 MCRegister SecondReg =
nextReg(FirstReg);
5327 warnIfRegIndexIsAT(FirstReg, IDLoc);
5330 "Offset for macro is not immediate!");
5333 signed NextOffset = FirstOffset.
getImm() + 4;
5339 if (!IsLittleEndian)
5342 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5343 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5348bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5349 const MCSubtargetInfo *STI) {
5350 MipsTargetStreamer &TOut = getTargetStreamer();
5361 warnIfNoMacro(IDLoc);
5363 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5364 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5365 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5369 MCRegister
Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5370 TOut.
emitRRI(Mips::SLTiu, DstReg,
Reg, 1, IDLoc, STI);
5374bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5375 const MCSubtargetInfo *STI) {
5376 MipsTargetStreamer &TOut = getTargetStreamer();
5387 warnIfNoMacro(IDLoc);
5390 TOut.
emitRRI(Mips::SLTiu, DstReg, SrcReg, 1, IDLoc, STI);
5394 if (SrcReg == Mips::ZERO) {
5395 Warning(IDLoc,
"comparison is always false");
5396 TOut.
emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
5397 DstReg, SrcReg, SrcReg, IDLoc, STI);
5402 if (
Imm > -0x8000 &&
Imm < 0) {
5404 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5410 MCRegister ATReg = getATReg(IDLoc);
5414 if (loadImmediate(
Imm, ATReg, MCRegister(),
true, isGP64bit(), IDLoc, Out,
5418 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5419 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5424 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5428bool MipsAsmParser::expandSne(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5429 const MCSubtargetInfo *STI) {
5431 MipsTargetStreamer &TOut = getTargetStreamer();
5442 warnIfNoMacro(IDLoc);
5444 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5445 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5446 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5450 MCRegister
Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5451 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO,
Reg, IDLoc, STI);
5455bool MipsAsmParser::expandSneI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5456 const MCSubtargetInfo *STI) {
5457 MipsTargetStreamer &TOut = getTargetStreamer();
5468 warnIfNoMacro(IDLoc);
5470 if (ImmValue == 0) {
5471 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, SrcReg, IDLoc, STI);
5475 if (SrcReg == Mips::ZERO) {
5476 Warning(IDLoc,
"comparison is always true");
5477 if (loadImmediate(1, DstReg, MCRegister(),
true,
false, IDLoc, Out, STI))
5483 if (ImmValue > -0x8000 && ImmValue < 0) {
5484 ImmValue = -ImmValue;
5485 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5491 TOut.
emitRRI(
Opc, DstReg, SrcReg, ImmValue, IDLoc, STI);
5492 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5496 MCRegister ATReg = getATReg(IDLoc);
5500 if (loadImmediate(ImmValue, ATReg, MCRegister(),
isInt<32>(ImmValue),
false,
5504 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5505 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5568 case Mips::F0:
return Mips::ZERO;
5569 case Mips::F1:
return Mips::AT;
5570 case Mips::F2:
return Mips::V0;
5571 case Mips::F3:
return Mips::V1;
5572 case Mips::F4:
return Mips::A0;
5573 case Mips::F5:
return Mips::A1;
5574 case Mips::F6:
return Mips::A2;
5575 case Mips::F7:
return Mips::A3;
5576 case Mips::F8:
return Mips::T0;
5577 case Mips::F9:
return Mips::T1;
5578 case Mips::F10:
return Mips::T2;
5579 case Mips::F11:
return Mips::T3;
5580 case Mips::F12:
return Mips::T4;
5581 case Mips::F13:
return Mips::T5;
5582 case Mips::F14:
return Mips::T6;
5583 case Mips::F15:
return Mips::T7;
5584 case Mips::F16:
return Mips::S0;
5585 case Mips::F17:
return Mips::S1;
5586 case Mips::F18:
return Mips::S2;
5587 case Mips::F19:
return Mips::S3;
5588 case Mips::F20:
return Mips::S4;
5589 case Mips::F21:
return Mips::S5;
5590 case Mips::F22:
return Mips::S6;
5591 case Mips::F23:
return Mips::S7;
5592 case Mips::F24:
return Mips::T8;
5593 case Mips::F25:
return Mips::T9;
5594 case Mips::F26:
return Mips::K0;
5595 case Mips::F27:
return Mips::K1;
5596 case Mips::F28:
return Mips::GP;
5597 case Mips::F29:
return Mips::SP;
5598 case Mips::F30:
return Mips::FP;
5599 case Mips::F31:
return Mips::RA;
5607 case Mips::COP00:
return Mips::ZERO;
5608 case Mips::COP01:
return Mips::AT;
5609 case Mips::COP02:
return Mips::V0;
5610 case Mips::COP03:
return Mips::V1;
5611 case Mips::COP04:
return Mips::A0;
5612 case Mips::COP05:
return Mips::A1;
5613 case Mips::COP06:
return Mips::A2;
5614 case Mips::COP07:
return Mips::A3;
5615 case Mips::COP08:
return Mips::T0;
5616 case Mips::COP09:
return Mips::T1;
5617 case Mips::COP010:
return Mips::T2;
5618 case Mips::COP011:
return Mips::T3;
5619 case Mips::COP012:
return Mips::T4;
5620 case Mips::COP013:
return Mips::T5;
5621 case Mips::COP014:
return Mips::T6;
5622 case Mips::COP015:
return Mips::T7;
5623 case Mips::COP016:
return Mips::S0;
5624 case Mips::COP017:
return Mips::S1;
5625 case Mips::COP018:
return Mips::S2;
5626 case Mips::COP019:
return Mips::S3;
5627 case Mips::COP020:
return Mips::S4;
5628 case Mips::COP021:
return Mips::S5;
5629 case Mips::COP022:
return Mips::S6;
5630 case Mips::COP023:
return Mips::S7;
5631 case Mips::COP024:
return Mips::T8;
5632 case Mips::COP025:
return Mips::T9;
5633 case Mips::COP026:
return Mips::K0;
5634 case Mips::COP027:
return Mips::K1;
5635 case Mips::COP028:
return Mips::GP;
5636 case Mips::COP029:
return Mips::SP;
5637 case Mips::COP030:
return Mips::FP;
5638 case Mips::COP031:
return Mips::RA;
5645bool MipsAsmParser::expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5646 const MCSubtargetInfo *STI) {
5647 MipsTargetStreamer &TOut = getTargetStreamer();
5652 bool IsMFTR =
false;
5706 IsMFTR ? MCRegister(rd)
5708 : Inst.getOperand(0).
getReg());
5710 TOut.
emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, u, sel, h, IDLoc,
5715bool MipsAsmParser::expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5716 const MCSubtargetInfo *STI) {
5721 warnIfNoMacro(IDLoc);
5723 MipsTargetStreamer &TOut = getTargetStreamer();
5724 unsigned Opcode = Inst.
getOpcode() == Mips::SaaAddr ? Mips::SAA : Mips::SAAD;
5727 const MCOperand &BaseOp = Inst.
getOperand(2);
5729 if (BaseOp.
isImm()) {
5730 int64_t ImmValue = BaseOp.
getImm();
5731 if (ImmValue == 0) {
5732 TOut.
emitRR(Opcode, RtReg, BaseReg, IDLoc, STI);
5737 MCRegister ATReg = getATReg(IDLoc);
5741 if (expandLoadAddress(ATReg, BaseReg, BaseOp, !isGP64bit(), IDLoc, Out, STI))
5744 TOut.
emitRR(Opcode, RtReg, ATReg, IDLoc, STI);
5749MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
5753 return Match_Success;
5756 if (
static_cast<MipsOperand &
>(*
Operands[1])
5757 .isValidForTie(
static_cast<MipsOperand &
>(*
Operands[2])))
5758 return Match_Success;
5759 return Match_RequiresSameSrcAndDst;
5763unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
5770 return Match_RequiresNoZeroRegister;
5771 return Match_Success;
5777 case Mips::JALR_HB64:
5778 case Mips::JALRC_HB_MMR6:
5779 case Mips::JALRC_MMR6:
5781 return Match_RequiresDifferentSrcAndDst;
5782 return Match_Success;
5785 return Match_RequiresDifferentSrcAndDst;
5786 return Match_Success;
5789 return Match_NonZeroOperandForSync;
5790 return Match_Success;
5796 return Match_NonZeroOperandForMTCX;
5797 return Match_Success;
5810 case Mips::BLEZC:
case Mips::BLEZC_MMR6:
5811 case Mips::BGEZC:
case Mips::BGEZC_MMR6:
5812 case Mips::BGTZC:
case Mips::BGTZC_MMR6:
5813 case Mips::BLTZC:
case Mips::BLTZC_MMR6:
5814 case Mips::BEQZC:
case Mips::BEQZC_MMR6:
5815 case Mips::BNEZC:
case Mips::BNEZC_MMR6:
5824 return Match_RequiresNoZeroRegister;
5825 return Match_Success;
5826 case Mips::BGEC:
case Mips::BGEC_MMR6:
5827 case Mips::BLTC:
case Mips::BLTC_MMR6:
5828 case Mips::BGEUC:
case Mips::BGEUC_MMR6:
5829 case Mips::BLTUC:
case Mips::BLTUC_MMR6:
5830 case Mips::BEQC:
case Mips::BEQC_MMR6:
5831 case Mips::BNEC:
case Mips::BNEC_MMR6:
5840 return Match_RequiresNoZeroRegister;
5843 return Match_RequiresNoZeroRegister;
5845 return Match_RequiresDifferentOperands;
5846 return Match_Success;
5849 "Operands must be immediates for dins!");
5852 if ((0 > (Pos +
Size)) || ((Pos +
Size) > 32))
5853 return Match_RequiresPosSizeRange0_32;
5854 return Match_Success;
5859 "Operands must be immediates for dinsm/dinsu!");
5862 if ((32 >= (Pos +
Size)) || ((Pos +
Size) > 64))
5863 return Match_RequiresPosSizeRange33_64;
5864 return Match_Success;
5868 "Operands must be immediates for DEXTM!");
5871 if ((1 > (Pos +
Size)) || ((Pos +
Size) > 63))
5872 return Match_RequiresPosSizeUImm6;
5873 return Match_Success;
5878 "Operands must be immediates for dextm/dextu!");
5881 if ((32 > (Pos +
Size)) || ((Pos +
Size) > 64))
5882 return Match_RequiresPosSizeRange33_64;
5883 return Match_Success;
5885 case Mips::CRC32B:
case Mips::CRC32CB:
5886 case Mips::CRC32H:
case Mips::CRC32CH:
5887 case Mips::CRC32W:
case Mips::CRC32CW:
5888 case Mips::CRC32D:
case Mips::CRC32CD:
5890 return Match_RequiresSameSrcAndDst;
5891 return Match_Success;
5897 return Match_NoFCCRegisterForCurrentISA;
5899 return Match_Success;
5907 if (ErrorLoc ==
SMLoc())
5914bool MipsAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
5918 bool MatchingInlineAsm) {
5920 unsigned MatchResult =
5921 MatchInstructionImpl(
Operands, Inst, ErrorInfo, MatchingInlineAsm);
5923 switch (MatchResult) {
5925 if (processInstruction(Inst, IDLoc, Out, STI))
5928 case Match_MissingFeature:
5929 Error(IDLoc,
"instruction requires a CPU feature not currently enabled");
5931 case Match_InvalidTiedOperand:
5932 Error(IDLoc,
"operand must match destination register");
5934 case Match_InvalidOperand: {
5935 SMLoc ErrorLoc = IDLoc;
5936 if (ErrorInfo != ~0ULL) {
5938 return Error(IDLoc,
"too few operands for instruction");
5940 ErrorLoc =
Operands[ErrorInfo]->getStartLoc();
5941 if (ErrorLoc == SMLoc())
5945 return Error(ErrorLoc,
"invalid operand for instruction");
5947 case Match_NonZeroOperandForSync:
5949 "s-type must be zero or unspecified for pre-MIPS32 ISAs");
5950 case Match_NonZeroOperandForMTCX:
5951 return Error(IDLoc,
"selector must be zero for pre-MIPS32 ISAs");
5952 case Match_MnemonicFail:
5953 return Error(IDLoc,
"invalid instruction");
5954 case Match_RequiresDifferentSrcAndDst:
5955 return Error(IDLoc,
"source and destination must be different");
5956 case Match_RequiresDifferentOperands:
5957 return Error(IDLoc,
"registers must be different");
5958 case Match_RequiresNoZeroRegister:
5959 return Error(IDLoc,
"invalid operand ($zero) for instruction");
5960 case Match_RequiresSameSrcAndDst:
5961 return Error(IDLoc,
"source and destination must match");
5962 case Match_NoFCCRegisterForCurrentISA:
5964 "non-zero fcc register doesn't exist in current ISA level");
5969 "expected 1-bit unsigned immediate");
5972 "expected 2-bit unsigned immediate");
5975 "expected immediate in range 1 .. 4");
5978 "expected 3-bit unsigned immediate");
5981 "expected 4-bit unsigned immediate");
5984 "expected 4-bit signed immediate");
5987 "expected 5-bit unsigned immediate");
5990 "expected 5-bit signed immediate");
5993 "expected immediate in range 1 .. 32");
5994 case Match_UImm5_32:
5996 "expected immediate in range 32 .. 63");
5997 case Match_UImm5_33:
5999 "expected immediate in range 33 .. 64");
6000 case Match_UImm5_0_Report_UImm6:
6004 "expected 6-bit unsigned immediate");
6005 case Match_UImm5_Lsl2:
6007 "expected both 7-bit unsigned immediate and multiple of 4");
6008 case Match_UImmRange2_64:
6010 "expected immediate in range 2 .. 64");
6013 "expected 6-bit unsigned immediate");
6014 case Match_UImm6_Lsl2:
6016 "expected both 8-bit unsigned immediate and multiple of 4");
6019 "expected 6-bit signed immediate");
6022 "expected 7-bit unsigned immediate");
6023 case Match_UImm7_N1:
6025 "expected immediate in range -1 .. 126");
6026 case Match_SImm7_Lsl2:
6028 "expected both 9-bit signed immediate and multiple of 4");
6031 "expected 8-bit unsigned immediate");
6032 case Match_UImm10_0:
6034 "expected 10-bit unsigned immediate");
6035 case Match_SImm10_0:
6037 "expected 10-bit signed immediate");
6038 case Match_SImm11_0:
6040 "expected 11-bit signed immediate");
6042 case Match_UImm16_Relaxed:
6043 case Match_UImm16_AltRelaxed:
6045 "expected 16-bit unsigned immediate");
6047 case Match_SImm16_Relaxed:
6049 "expected 16-bit signed immediate");
6050 case Match_SImm18_Lsl3:
6052 "expected both 18-bit signed immediate and multiple of 8");
6053 case Match_SImm19_Lsl2:
6055 "expected both 19-bit signed immediate and multiple of 4");
6056 case Match_UImm20_0:
6058 "expected 20-bit unsigned immediate");
6059 case Match_UImm26_0:
6061 "expected 26-bit unsigned immediate");
6063 case Match_SImm32_Relaxed:
6065 "expected 32-bit signed immediate");
6066 case Match_UImm32_Coerced:
6068 "expected 32-bit immediate");
6069 case Match_MemSImm9:
6071 "expected memory with 9-bit signed offset");
6072 case Match_MemSImm10:
6074 "expected memory with 10-bit signed offset");
6075 case Match_MemSImm10Lsl1:
6077 "expected memory with 11-bit signed offset and multiple of 2");
6078 case Match_MemSImm10Lsl2:
6080 "expected memory with 12-bit signed offset and multiple of 4");
6081 case Match_MemSImm10Lsl3:
6083 "expected memory with 13-bit signed offset and multiple of 8");
6084 case Match_MemSImm11:
6086 "expected memory with 11-bit signed offset");
6087 case Match_MemSImm12:
6089 "expected memory with 12-bit signed offset");
6090 case Match_MemSImm16:
6092 "expected memory with 16-bit signed offset");
6093 case Match_MemSImmPtr:
6095 "expected memory with 32-bit signed offset");
6096 case Match_RequiresPosSizeRange0_32: {
6097 SMLoc ErrorStart =
Operands[3]->getStartLoc();
6098 SMLoc ErrorEnd =
Operands[4]->getEndLoc();
6099 return Error(ErrorStart,
"size plus position are not in the range 0 .. 32",
6100 SMRange(ErrorStart, ErrorEnd));
6102 case Match_RequiresPosSizeUImm6: {
6103 SMLoc ErrorStart =
Operands[3]->getStartLoc();
6104 SMLoc ErrorEnd =
Operands[4]->getEndLoc();
6105 return Error(ErrorStart,
"size plus position are not in the range 1 .. 63",
6106 SMRange(ErrorStart, ErrorEnd));
6108 case Match_RequiresPosSizeRange33_64: {
6109 SMLoc ErrorStart =
Operands[3]->getStartLoc();
6110 SMLoc ErrorEnd =
Operands[4]->getEndLoc();
6111 return Error(ErrorStart,
"size plus position are not in the range 33 .. 64",
6112 SMRange(ErrorStart, ErrorEnd));
6119void MipsAsmParser::warnIfRegIndexIsAT(MCRegister RegIndex, SMLoc Loc) {
6120 if (RegIndex && AssemblerOptions.
back()->getATRegIndex() == RegIndex)
6121 Warning(Loc,
"used $at (currently $" + Twine(RegIndex.
id()) +
6122 ") without \".set noat\"");
6125void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
6126 if (!AssemblerOptions.
back()->isMacro())
6127 Warning(Loc,
"macro instruction expanded into multiple instructions");
6130void MipsAsmParser::ConvertXWPOperands(MCInst &Inst,
6134 "Unexpected instruction!");
6135 ((MipsOperand &)*
Operands[1]).addGPR32ZeroAsmRegOperands(Inst, 1);
6136 MCRegister NextReg =
nextReg(((MipsOperand &)*
Operands[1]).getGPR32Reg());
6138 ((MipsOperand &)*
Operands[2]).addMemOperands(Inst, 2);
6142MipsAsmParser::printWarningWithFixIt(
const Twine &
Msg,
const Twine &FixMsg,
6143 SMRange
Range,
bool ShowColors) {
6149int MipsAsmParser::matchCPURegisterName(StringRef Name) {
6150 const MCRegisterInfo &MRI = *
getContext().getRegisterInfo();
6156 AsmToken RegTok = getLexer().peekTok();
6157 StringRef FixedName =
6159 printWarningWithFixIt(
"register names $t4-$t7 are only available in O32.",
6160 "Did you mean $" + FixedName +
"?",
6166int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
6167 const MCRegisterInfo &MRI = *
getContext().getRegisterInfo();
6169 Mips::RegAliasName);
6173int MipsAsmParser::matchFPURegisterName(StringRef Name) {
6174 if (Name[0] ==
'f') {
6175 StringRef NumString =
Name.substr(1);
6186int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
6187 if (
Name.starts_with(
"fcc")) {
6188 StringRef NumString =
Name.substr(3);
6199int MipsAsmParser::matchACRegisterName(StringRef Name) {
6200 if (
Name.starts_with(
"ac")) {
6201 StringRef NumString =
Name.substr(2);
6212int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
6215 if (
Name.front() !=
'w' ||
Name.drop_front(1).getAsInteger(10, IntVal))
6224int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
6225 const MCRegisterInfo &MRI = *
getContext().getRegisterInfo();
6227 Name, MRI, Mips::MSACtrlRegClassID, Mips::RegAliasName);
6231bool MipsAsmParser::canUseATReg() {
6232 return AssemblerOptions.
back()->getATRegIndex() != 0;
6235MCRegister MipsAsmParser::getATReg(SMLoc Loc) {
6236 unsigned ATIndex = AssemblerOptions.
back()->getATRegIndex();
6238 reportParseError(Loc,
6239 "pseudo-instruction requires $at, which is not available");
6243 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
6247MCRegister MipsAsmParser::getReg(
int RC,
int RegNo) {
6248 return getContext().getRegisterInfo()->getRegClass(RC).getRegister(RegNo);
6254const MCExpr *MipsAsmParser::parseRelocExpr() {
6255 auto getOp = [](StringRef
Op) {
6256 return StringSwitch<Mips::Specifier>(
Op)
6284 MCAsmParser &Parser = getParser();
6286 const MCExpr *Res =
nullptr;
6292 auto Op = getOp(Name);
6301 while (
Ops.size()) {
6310 MCAsmParser &Parser = getParser();
6320 ParseStatus Res = MatchOperandParserImpl(
Operands, Mnemonic,
true);
6331 switch (getLexer().getKind()) {
6341 if (!parseAnyRegister(
Operands).isNoMatch())
6354 Operands.push_back(MipsOperand::CreateImm(SymRef, S,
E, *
this));
6359 const MCExpr *Expr = parseRelocExpr();
6363 Operands.push_back(MipsOperand::CreateImm(Expr, S,
E, *
this));
6370bool MipsAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
6372 return !tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess();
6375ParseStatus MipsAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
6378 ParseStatus Res = parseAnyRegister(
Operands);
6381 MipsOperand &Operand =
static_cast<MipsOperand &
>(*
Operands.front());
6382 StartLoc = Operand.getStartLoc();
6383 EndLoc = Operand.getEndLoc();
6389 if (Operand.isGPRAsmReg()) {
6391 Reg = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
6402 MCAsmParser &Parser = getParser();
6404 const MCExpr *IdVal =
nullptr;
6406 bool isParenExpr =
false;
6417 IdVal = parseRelocExpr();
6423 const AsmToken &Tok = Parser.
getTok();
6425 MipsOperand &Mnemonic =
static_cast<MipsOperand &
>(*
Operands[0]);
6426 if (Mnemonic.getToken() ==
"la" || Mnemonic.getToken() ==
"dla") {
6429 Operands.push_back(MipsOperand::CreateImm(IdVal, S,
E, *
this));
6438 auto Base = MipsOperand::createGPRReg(
6439 0,
"0",
getContext().getRegisterInfo(), S,
E, *
this);
6441 MipsOperand::CreateMem(std::move(
Base), IdVal, S,
E, *
this));
6493 const MCExpr * NextExpr;
6494 if (getParser().parseExpression(NextExpr))
6517 std::unique_ptr<MipsOperand>
op(
6518 static_cast<MipsOperand *
>(
Operands.back().release()));
6525 if (IdVal->evaluateAsAbsolute(
Imm))
6532 Operands.push_back(MipsOperand::CreateMem(std::move(
op), IdVal, S,
E, *
this));
6537 MCAsmParser &Parser = getParser();
6546 const MCSymbolRefExpr *
Ref =
static_cast<const MCSymbolRefExpr *
>(Expr);
6547 StringRef DefSymbol =
Ref->getSymbol().getName();
6550 matchAnyRegisterNameWithoutDollar(
Operands, DefSymbol.
substr(1), S);
6564 if (Entry != RegisterSets.
end()) {
6566 matchAnyRegisterWithoutDollar(
Operands,
Entry->getValue(), S);
6577ParseStatus MipsAsmParser::matchAnyRegisterNameWithoutDollar(
6579 int Index = matchCPURegisterName(Identifier);
6581 Operands.push_back(MipsOperand::createGPRReg(
6582 Index, Identifier,
getContext().getRegisterInfo(), S,
6583 getLexer().getLoc(), *
this));
6587 Index = matchHWRegsRegisterName(Identifier);
6589 Operands.push_back(MipsOperand::createHWRegsReg(
6590 Index, Identifier,
getContext().getRegisterInfo(), S,
6591 getLexer().getLoc(), *
this));
6595 Index = matchFPURegisterName(Identifier);
6597 Operands.push_back(MipsOperand::createFGRReg(
6598 Index, Identifier,
getContext().getRegisterInfo(), S,
6599 getLexer().getLoc(), *
this));
6603 Index = matchFCCRegisterName(Identifier);
6605 Operands.push_back(MipsOperand::createFCCReg(
6606 Index, Identifier,
getContext().getRegisterInfo(), S,
6607 getLexer().getLoc(), *
this));
6611 Index = matchACRegisterName(Identifier);
6613 Operands.push_back(MipsOperand::createACCReg(
6614 Index, Identifier,
getContext().getRegisterInfo(), S,
6615 getLexer().getLoc(), *
this));
6619 Index = matchMSA128RegisterName(Identifier);
6621 Operands.push_back(MipsOperand::createMSA128Reg(
6622 Index, Identifier,
getContext().getRegisterInfo(), S,
6623 getLexer().getLoc(), *
this));
6627 Index = matchMSA128CtrlRegisterName(Identifier);
6629 Operands.push_back(MipsOperand::createMSACtrlReg(
6630 Index, Identifier,
getContext().getRegisterInfo(), S,
6631 getLexer().getLoc(), *
this));
6640 const AsmToken &Token, SMLoc S) {
6644 return matchAnyRegisterNameWithoutDollar(
Operands, Identifier, S);
6649 if (RegNum < 0 || RegNum > 31) {
6653 Error(getLexer().getLoc(),
"invalid register number");
6655 Operands.push_back(MipsOperand::createNumericReg(
6668 auto Token = getLexer().peekTok(
false);
6669 return matchAnyRegisterWithoutDollar(
Operands, Token, S);
6673 MCAsmParser &Parser = getParser();
6676 auto Token = Parser.
getTok();
6678 SMLoc S = Token.
getLoc();
6691 ParseStatus Res = matchAnyRegisterWithoutDollar(
Operands, S);
6700 MCAsmParser &Parser = getParser();
6703 SMLoc S = getLexer().getLoc();
6706 ParseStatus Res = parseAnyRegister(
Operands);
6711 const MCExpr *Expr =
nullptr;
6717 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *
this));
6722 MCAsmParser &Parser = getParser();
6723 const MCExpr *IdVal;
6734 if (getParser().parseExpression(IdVal))
6741 Operands.push_back(MipsOperand::CreateImm(
6747 MCAsmParser &Parser = getParser();
6751 bool RegRange =
false;
6758 while (parseAnyRegister(TmpOperands).isSuccess()) {
6759 SMLoc
E = getLexer().getLoc();
6760 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*TmpOperands.
back());
6761 Reg = isGP64bit() ? RegOpnd.getGPR64Reg() : RegOpnd.getGPR32Reg();
6765 if ((isGP64bit() &&
Reg == Mips::RA_64) ||
6766 (!isGP64bit() &&
Reg == Mips::RA)) {
6769 MCRegister TmpReg = PrevReg + 1;
6770 while (TmpReg <=
Reg) {
6771 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
6772 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
6774 return Error(
E,
"invalid register operand");
6778 TmpReg = TmpReg.
id() + 1;
6785 ((isGP64bit() && (
Reg != Mips::S0_64) && (
Reg != Mips::RA_64)) ||
6786 (!isGP64bit() && (
Reg != Mips::S0) && (
Reg != Mips::RA))))
6787 return Error(
E,
"$16 or $31 expected");
6788 if (!(((
Reg == Mips::FP ||
Reg == Mips::RA ||
6789 (
Reg >= Mips::S0 &&
Reg <= Mips::S7)) &&
6791 ((
Reg == Mips::FP_64 ||
Reg == Mips::RA_64 ||
6792 (
Reg >= Mips::S0_64 &&
Reg <= Mips::S7_64)) &&
6794 return Error(
E,
"invalid register operand");
6795 if (PrevReg.
isValid() && (
Reg != PrevReg + 1) &&
6796 ((
Reg != Mips::FP &&
Reg != Mips::RA && !isGP64bit()) ||
6797 (
Reg != Mips::FP_64 &&
Reg != Mips::RA_64 && isGP64bit())))
6798 return Error(
E,
"consecutive register numbers expected");
6808 return Error(
E,
"',' or '-' expected");
6818 Operands.push_back(MipsOperand::CreateRegList(Regs, S,
E, *
this));
6829 MCAsmParser &Parser = getParser();
6832 MipsOperand::CreateToken(
"(", getLexer().getLoc(), *
this));
6834 if (parseOperand(
Operands, Name)) {
6835 SMLoc Loc = getLexer().getLoc();
6836 return Error(Loc,
"unexpected token in argument list");
6839 SMLoc Loc = getLexer().getLoc();
6840 return Error(Loc,
"unexpected token, expected ')'");
6843 MipsOperand::CreateToken(
")", getLexer().getLoc(), *
this));
6855bool MipsAsmParser::parseBracketSuffix(StringRef Name,
6857 MCAsmParser &Parser = getParser();
6860 MipsOperand::CreateToken(
"[", getLexer().getLoc(), *
this));
6862 if (parseOperand(
Operands, Name)) {
6863 SMLoc Loc = getLexer().getLoc();
6864 return Error(Loc,
"unexpected token in argument list");
6867 SMLoc Loc = getLexer().getLoc();
6868 return Error(Loc,
"unexpected token, expected ']'");
6871 MipsOperand::CreateToken(
"]", getLexer().getLoc(), *
this));
6878 unsigned VariantID = 0);
6893bool MipsAsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
6895 MCAsmParser &Parser = getParser();
6899 getTargetStreamer().forbidModuleDirective();
6902 if (!mnemonicIsValid(Name, 0)) {
6903 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
6905 return Error(NameLoc,
"unknown instruction" + Suggestion);
6908 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *
this));
6913 if (parseOperand(
Operands, Name)) {
6914 SMLoc Loc = getLexer().getLoc();
6915 return Error(Loc,
"unexpected token in argument list");
6924 if (parseOperand(
Operands, Name)) {
6925 SMLoc Loc = getLexer().getLoc();
6926 return Error(Loc,
"unexpected token in argument list");
6930 if (parseBracketSuffix(Name,
Operands))
6938 SMLoc Loc = getLexer().getLoc();
6939 return Error(Loc,
"unexpected token in argument list");
6947bool MipsAsmParser::reportParseError(
const Twine &ErrorMsg) {
6948 SMLoc Loc = getLexer().getLoc();
6949 return Error(Loc, ErrorMsg);
6952bool MipsAsmParser::reportParseError(SMLoc Loc,
const Twine &ErrorMsg) {
6953 return Error(Loc, ErrorMsg);
6956bool MipsAsmParser::parseSetNoAtDirective() {
6957 MCAsmParser &Parser = getParser();
6961 AssemblerOptions.
back()->setATRegIndex(0);
6967 reportParseError(
"unexpected token, expected end of statement");
6971 getTargetStreamer().emitDirectiveSetNoAt();
6976bool MipsAsmParser::parseSetAtDirective() {
6979 MCAsmParser &Parser = getParser();
6984 AssemblerOptions.
back()->setATRegIndex(1);
6986 getTargetStreamer().emitDirectiveSetAt();
6992 reportParseError(
"unexpected token, expected equals sign");
6999 reportParseError(
"no register specified");
7002 reportParseError(
"unexpected token, expected dollar sign '$'");
7012 AtRegNo = matchCPURegisterName(
Reg.getIdentifier());
7014 AtRegNo =
Reg.getIntVal();
7016 reportParseError(
"unexpected token, expected identifier or integer");
7021 if (!AssemblerOptions.
back()->setATRegIndex(AtRegNo)) {
7022 reportParseError(
"invalid register");
7029 reportParseError(
"unexpected token, expected end of statement");
7033 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
7039bool MipsAsmParser::parseSetReorderDirective() {
7040 MCAsmParser &Parser = getParser();
7044 reportParseError(
"unexpected token, expected end of statement");
7047 AssemblerOptions.
back()->setReorder();
7048 getTargetStreamer().emitDirectiveSetReorder();
7053bool MipsAsmParser::parseSetNoReorderDirective() {
7054 MCAsmParser &Parser = getParser();
7058 reportParseError(
"unexpected token, expected end of statement");
7061 AssemblerOptions.
back()->setNoReorder();
7062 getTargetStreamer().emitDirectiveSetNoReorder();
7067bool MipsAsmParser::parseSetMacroDirective() {
7068 MCAsmParser &Parser = getParser();
7072 reportParseError(
"unexpected token, expected end of statement");
7075 AssemblerOptions.
back()->setMacro();
7076 getTargetStreamer().emitDirectiveSetMacro();
7081bool MipsAsmParser::parseSetNoMacroDirective() {
7082 MCAsmParser &Parser = getParser();
7086 reportParseError(
"unexpected token, expected end of statement");
7089 if (AssemblerOptions.
back()->isReorder()) {
7090 reportParseError(
"`noreorder' must be set before `nomacro'");
7093 AssemblerOptions.
back()->setNoMacro();
7094 getTargetStreamer().emitDirectiveSetNoMacro();
7099bool MipsAsmParser::parseSetMsaDirective() {
7100 MCAsmParser &Parser = getParser();
7105 return reportParseError(
"unexpected token, expected end of statement");
7107 setFeatureBits(Mips::FeatureMSA,
"msa");
7108 getTargetStreamer().emitDirectiveSetMsa();
7112bool MipsAsmParser::parseSetNoMsaDirective() {
7113 MCAsmParser &Parser = getParser();
7118 return reportParseError(
"unexpected token, expected end of statement");
7120 clearFeatureBits(Mips::FeatureMSA,
"msa");
7121 getTargetStreamer().emitDirectiveSetNoMsa();
7125bool MipsAsmParser::parseSetNoDspDirective() {
7126 MCAsmParser &Parser = getParser();
7131 reportParseError(
"unexpected token, expected end of statement");
7135 clearFeatureBits(Mips::FeatureDSP,
"dsp");
7136 getTargetStreamer().emitDirectiveSetNoDsp();
7140bool MipsAsmParser::parseSetNoMips3DDirective() {
7141 MCAsmParser &Parser = getParser();
7146 reportParseError(
"unexpected token, expected end of statement");
7150 clearFeatureBits(Mips::FeatureMips3D,
"mips3d");
7151 getTargetStreamer().emitDirectiveSetNoMips3D();
7155bool MipsAsmParser::parseSetMips16Directive() {
7156 MCAsmParser &Parser = getParser();
7161 reportParseError(
"unexpected token, expected end of statement");
7165 clearFeatureBits(Mips::FeatureMicroMips,
"micromips");
7166 setFeatureBits(Mips::FeatureMips16,
"mips16");
7167 getTargetStreamer().emitDirectiveSetMips16();
7172bool MipsAsmParser::parseSetNoMips16Directive() {
7173 MCAsmParser &Parser = getParser();
7178 reportParseError(
"unexpected token, expected end of statement");
7182 clearFeatureBits(Mips::FeatureMips16,
"mips16");
7183 getTargetStreamer().emitDirectiveSetNoMips16();
7188bool MipsAsmParser::parseSetFpDirective() {
7189 MCAsmParser &Parser = getParser();
7195 AsmToken Tok = Parser.
getTok();
7197 reportParseError(
"unexpected token, expected equals sign '='");
7203 if (!parseFpABIValue(FpAbiVal,
".set"))
7207 reportParseError(
"unexpected token, expected end of statement");
7210 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
7215bool MipsAsmParser::parseSetOddSPRegDirective() {
7216 MCAsmParser &Parser = getParser();
7220 reportParseError(
"unexpected token, expected end of statement");
7224 clearFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
7225 getTargetStreamer().emitDirectiveSetOddSPReg();
7229bool MipsAsmParser::parseSetNoOddSPRegDirective() {
7230 MCAsmParser &Parser = getParser();
7234 reportParseError(
"unexpected token, expected end of statement");
7238 setFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
7239 getTargetStreamer().emitDirectiveSetNoOddSPReg();
7243bool MipsAsmParser::parseSetMtDirective() {
7244 MCAsmParser &Parser = getParser();
7249 reportParseError(
"unexpected token, expected end of statement");
7253 setFeatureBits(Mips::FeatureMT,
"mt");
7254 getTargetStreamer().emitDirectiveSetMt();
7259bool MipsAsmParser::parseSetNoMtDirective() {
7260 MCAsmParser &Parser = getParser();
7265 reportParseError(
"unexpected token, expected end of statement");
7269 clearFeatureBits(Mips::FeatureMT,
"mt");
7271 getTargetStreamer().emitDirectiveSetNoMt();
7276bool MipsAsmParser::parseSetNoCRCDirective() {
7277 MCAsmParser &Parser = getParser();
7282 reportParseError(
"unexpected token, expected end of statement");
7286 clearFeatureBits(Mips::FeatureCRC,
"crc");
7288 getTargetStreamer().emitDirectiveSetNoCRC();
7293bool MipsAsmParser::parseSetNoVirtDirective() {
7294 MCAsmParser &Parser = getParser();
7299 reportParseError(
"unexpected token, expected end of statement");
7303 clearFeatureBits(Mips::FeatureVirt,
"virt");
7305 getTargetStreamer().emitDirectiveSetNoVirt();
7310bool MipsAsmParser::parseSetNoGINVDirective() {
7311 MCAsmParser &Parser = getParser();
7316 reportParseError(
"unexpected token, expected end of statement");
7320 clearFeatureBits(Mips::FeatureGINV,
"ginv");
7322 getTargetStreamer().emitDirectiveSetNoGINV();
7327bool MipsAsmParser::parseSetNoEVADirective() {
7328 MCAsmParser &Parser = getParser();
7333 reportParseError(
"unexpected token, expected end of statement");
7337 clearFeatureBits(Mips::FeatureEVA,
"eva");
7339 getTargetStreamer().emitDirectiveSetNoEVA();
7344bool MipsAsmParser::parseSetPopDirective() {
7345 MCAsmParser &Parser = getParser();
7346 SMLoc Loc = getLexer().getLoc();
7350 return reportParseError(
"unexpected token, expected end of statement");
7354 if (AssemblerOptions.
size() == 2)
7355 return reportParseError(Loc,
".set pop with no .set push");
7357 MCSubtargetInfo &STI = copySTI();
7359 setAvailableFeatures(
7360 ComputeAvailableFeatures(AssemblerOptions.
back()->getFeatures()));
7363 getTargetStreamer().emitDirectiveSetPop();
7367bool MipsAsmParser::parseSetPushDirective() {
7368 MCAsmParser &Parser = getParser();
7371 return reportParseError(
"unexpected token, expected end of statement");
7375 std::make_unique<MipsAssemblerOptions>(AssemblerOptions.
back().get()));
7377 getTargetStreamer().emitDirectiveSetPush();
7381bool MipsAsmParser::parseSetSoftFloatDirective() {
7382 MCAsmParser &Parser = getParser();
7385 return reportParseError(
"unexpected token, expected end of statement");
7387 setFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
7388 getTargetStreamer().emitDirectiveSetSoftFloat();
7392bool MipsAsmParser::parseSetHardFloatDirective() {
7393 MCAsmParser &Parser = getParser();
7396 return reportParseError(
"unexpected token, expected end of statement");
7398 clearFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
7399 getTargetStreamer().emitDirectiveSetHardFloat();
7403bool MipsAsmParser::parseSetAssignment() {
7405 MCAsmParser &Parser = getParser();
7408 return reportParseError(
"expected identifier after .set");
7411 return reportParseError(
"unexpected token, expected comma");
7426 const MCExpr *
Value;
7428 Parser, Sym,
Value))
7430 getStreamer().emitAssignment(Sym,
Value);
7435bool MipsAsmParser::parseSetMips0Directive() {
7436 MCAsmParser &Parser = getParser();
7439 return reportParseError(
"unexpected token, expected end of statement");
7442 MCSubtargetInfo &STI = copySTI();
7443 setAvailableFeatures(
7444 ComputeAvailableFeatures(AssemblerOptions.
front()->getFeatures()));
7446 AssemblerOptions.
back()->setFeatures(AssemblerOptions.
front()->getFeatures());
7448 getTargetStreamer().emitDirectiveSetMips0();
7452bool MipsAsmParser::parseSetArchDirective() {
7453 MCAsmParser &Parser = getParser();
7456 return reportParseError(
"unexpected token, expected equals sign");
7459 StringRef Arch = getParser().parseStringToEndOfStatement().trim();
7461 return reportParseError(
"expected arch identifier");
7463 StringRef ArchFeatureName =
7464 StringSwitch<StringRef>(Arch)
7465 .Case(
"mips1",
"mips1")
7466 .Case(
"mips2",
"mips2")
7467 .Case(
"mips3",
"mips3")
7468 .Case(
"mips4",
"mips4")
7469 .Case(
"mips5",
"mips5")
7470 .Case(
"mips32",
"mips32")
7471 .Case(
"mips32r2",
"mips32r2")
7472 .Case(
"mips32r3",
"mips32r3")
7473 .Case(
"mips32r5",
"mips32r5")
7474 .Case(
"mips32r6",
"mips32r6")
7475 .Case(
"mips64",
"mips64")
7476 .Case(
"mips64r2",
"mips64r2")
7477 .Case(
"mips64r3",
"mips64r3")
7478 .Case(
"mips64r5",
"mips64r5")
7479 .Case(
"mips64r6",
"mips64r6")
7480 .Case(
"octeon",
"cnmips")
7481 .Case(
"octeon+",
"cnmipsp")
7482 .Case(
"r4000",
"mips3")
7485 if (ArchFeatureName.
empty())
7486 return reportParseError(
"unsupported architecture");
7488 if (ArchFeatureName ==
"mips64r6" && inMicroMipsMode())
7489 return reportParseError(
"mips64r6 does not support microMIPS");
7491 selectArch(ArchFeatureName);
7492 getTargetStreamer().emitDirectiveSetArch(Arch);
7496bool MipsAsmParser::parseSetFeature(
uint64_t Feature) {
7497 MCAsmParser &Parser = getParser();
7500 return reportParseError(
"unexpected token, expected end of statement");
7505 case Mips::FeatureMips3D:
7506 setFeatureBits(Mips::FeatureMips3D,
"mips3d");
7507 getTargetStreamer().emitDirectiveSetMips3D();
7509 case Mips::FeatureDSP:
7510 setFeatureBits(Mips::FeatureDSP,
"dsp");
7511 getTargetStreamer().emitDirectiveSetDsp();
7513 case Mips::FeatureDSPR2:
7514 setFeatureBits(Mips::FeatureDSPR2,
"dspr2");
7515 getTargetStreamer().emitDirectiveSetDspr2();
7517 case Mips::FeatureMicroMips:
7518 clearFeatureBits(Mips::FeatureMips16,
"mips16");
7519 setFeatureBits(Mips::FeatureMicroMips,
"micromips");
7520 getTargetStreamer().emitDirectiveSetMicroMips();
7522 case Mips::FeatureMips1:
7523 selectArch(
"mips1");
7524 getTargetStreamer().emitDirectiveSetMips1();
7526 case Mips::FeatureMips2:
7527 selectArch(
"mips2");
7528 getTargetStreamer().emitDirectiveSetMips2();
7530 case Mips::FeatureMips3:
7531 selectArch(
"mips3");
7532 getTargetStreamer().emitDirectiveSetMips3();
7534 case Mips::FeatureMips4:
7535 selectArch(
"mips4");
7536 getTargetStreamer().emitDirectiveSetMips4();
7538 case Mips::FeatureMips5:
7539 selectArch(
"mips5");
7540 getTargetStreamer().emitDirectiveSetMips5();
7542 case Mips::FeatureMips32:
7543 selectArch(
"mips32");
7544 getTargetStreamer().emitDirectiveSetMips32();
7546 case Mips::FeatureMips32r2:
7547 selectArch(
"mips32r2");
7548 getTargetStreamer().emitDirectiveSetMips32R2();
7550 case Mips::FeatureMips32r3:
7551 selectArch(
"mips32r3");
7552 getTargetStreamer().emitDirectiveSetMips32R3();
7554 case Mips::FeatureMips32r5:
7555 selectArch(
"mips32r5");
7556 getTargetStreamer().emitDirectiveSetMips32R5();
7558 case Mips::FeatureMips32r6:
7559 selectArch(
"mips32r6");
7560 getTargetStreamer().emitDirectiveSetMips32R6();
7562 case Mips::FeatureMips64:
7563 selectArch(
"mips64");
7564 getTargetStreamer().emitDirectiveSetMips64();
7566 case Mips::FeatureMips64r2:
7567 selectArch(
"mips64r2");
7568 getTargetStreamer().emitDirectiveSetMips64R2();
7570 case Mips::FeatureMips64r3:
7571 selectArch(
"mips64r3");
7572 getTargetStreamer().emitDirectiveSetMips64R3();
7574 case Mips::FeatureMips64r5:
7575 selectArch(
"mips64r5");
7576 getTargetStreamer().emitDirectiveSetMips64R5();
7578 case Mips::FeatureMips64r6:
7579 selectArch(
"mips64r6");
7580 getTargetStreamer().emitDirectiveSetMips64R6();
7582 case Mips::FeatureCRC:
7583 setFeatureBits(Mips::FeatureCRC,
"crc");
7584 getTargetStreamer().emitDirectiveSetCRC();
7586 case Mips::FeatureVirt:
7587 setFeatureBits(Mips::FeatureVirt,
"virt");
7588 getTargetStreamer().emitDirectiveSetVirt();
7590 case Mips::FeatureGINV:
7591 setFeatureBits(Mips::FeatureGINV,
"ginv");
7592 getTargetStreamer().emitDirectiveSetGINV();
7594 case Mips::FeatureEVA:
7595 setFeatureBits(Mips::FeatureEVA,
"eva");
7596 getTargetStreamer().emitDirectiveSetEVA();
7602bool MipsAsmParser::eatComma(StringRef ErrorStr) {
7603 MCAsmParser &Parser = getParser();
7605 SMLoc Loc = getLexer().getLoc();
7606 return Error(Loc, ErrorStr);
7617bool MipsAsmParser::isPicAndNotNxxAbi() {
7618 return inPicMode() && !(isABI_N32() || isABI_N64());
7621bool MipsAsmParser::parseDirectiveCpAdd(SMLoc Loc) {
7623 ParseStatus Res = parseAnyRegister(
Reg);
7625 reportParseError(
"expected register");
7629 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7630 if (!RegOpnd.isGPRAsmReg()) {
7631 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7637 reportParseError(
"unexpected token, expected end of statement");
7642 getTargetStreamer().emitDirectiveCpAdd(RegOpnd.getGPR32Reg());
7646bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
7647 if (AssemblerOptions.
back()->isReorder())
7648 Warning(Loc,
".cpload should be inside a noreorder section");
7650 if (inMips16Mode()) {
7651 reportParseError(
".cpload is not supported in Mips16 mode");
7656 ParseStatus Res = parseAnyRegister(
Reg);
7658 reportParseError(
"expected register containing function address");
7662 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7663 if (!RegOpnd.isGPRAsmReg()) {
7664 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7670 reportParseError(
"unexpected token, expected end of statement");
7674 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
7678bool MipsAsmParser::parseDirectiveCpLocal(SMLoc Loc) {
7679 if (!isABI_N32() && !isABI_N64()) {
7680 reportParseError(
".cplocal is allowed only in N32 or N64 mode");
7685 ParseStatus Res = parseAnyRegister(
Reg);
7687 reportParseError(
"expected register containing global pointer");
7691 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7692 if (!RegOpnd.isGPRAsmReg()) {
7693 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7699 reportParseError(
"unexpected token, expected end of statement");
7704 MCRegister NewReg = RegOpnd.getGPR32Reg();
7708 getTargetStreamer().emitDirectiveCpLocal(NewReg);
7712bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
7713 MCAsmParser &Parser = getParser();
7718 if (inMips16Mode()) {
7719 reportParseError(
".cprestore is not supported in Mips16 mode");
7724 const MCExpr *StackOffset;
7725 int64_t StackOffsetVal;
7727 reportParseError(
"expected stack offset value");
7731 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
7732 reportParseError(
"stack offset is not an absolute expression");
7736 if (StackOffsetVal < 0) {
7737 Warning(Loc,
".cprestore with negative stack offset has no effect");
7738 IsCpRestoreSet =
false;
7740 IsCpRestoreSet =
true;
7741 CpRestoreOffset = StackOffsetVal;
7746 reportParseError(
"unexpected token, expected end of statement");
7750 if (!getTargetStreamer().emitDirectiveCpRestore(
7751 CpRestoreOffset, [&]() {
return getATReg(Loc); }, Loc, STI))
7757bool MipsAsmParser::parseDirectiveCPSetup() {
7758 MCAsmParser &Parser = getParser();
7760 bool SaveIsReg =
true;
7763 ParseStatus Res = parseAnyRegister(TmpReg);
7765 reportParseError(
"expected register containing function address");
7769 MipsOperand &FuncRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7770 if (!FuncRegOpnd.isGPRAsmReg()) {
7771 reportParseError(FuncRegOpnd.getStartLoc(),
"invalid register");
7775 MCRegister FuncReg = FuncRegOpnd.getGPR32Reg();
7778 if (!eatComma(
"unexpected token, expected comma"))
7781 Res = parseAnyRegister(TmpReg);
7783 const MCExpr *OffsetExpr;
7785 SMLoc ExprLoc = getLexer().
getLoc();
7788 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
7789 reportParseError(ExprLoc,
"expected save register or stack offset");
7796 MipsOperand &SaveOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7797 if (!SaveOpnd.isGPRAsmReg()) {
7798 reportParseError(SaveOpnd.getStartLoc(),
"invalid register");
7801 Save = SaveOpnd.getGPR32Reg().id();
7804 if (!eatComma(
"unexpected token, expected comma"))
7809 reportParseError(
"expected expression");
7814 reportParseError(
"expected symbol");
7817 const MCSymbolRefExpr *
Ref =
static_cast<const MCSymbolRefExpr *
>(Expr);
7819 CpSaveLocation = Save;
7820 CpSaveLocationIsRegister = SaveIsReg;
7822 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save,
Ref->getSymbol(),
7827bool MipsAsmParser::parseDirectiveCPReturn() {
7828 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
7829 CpSaveLocationIsRegister);
7833bool MipsAsmParser::parseDirectiveNaN() {
7834 MCAsmParser &Parser = getParser();
7836 const AsmToken &Tok = Parser.
getTok();
7840 getTargetStreamer().emitDirectiveNaN2008();
7842 }
else if (Tok.
getString() ==
"legacy") {
7844 getTargetStreamer().emitDirectiveNaNLegacy();
7850 reportParseError(
"invalid option in .nan directive");
7854bool MipsAsmParser::parseDirectiveSet() {
7855 const AsmToken &Tok = getParser().getTok();
7857 SMLoc Loc = Tok.
getLoc();
7859 if (IdVal ==
"noat")
7860 return parseSetNoAtDirective();
7862 return parseSetAtDirective();
7863 if (IdVal ==
"arch")
7864 return parseSetArchDirective();
7865 if (IdVal ==
"bopt") {
7866 Warning(Loc,
"'bopt' feature is unsupported");
7870 if (IdVal ==
"nobopt") {
7876 return parseSetFpDirective();
7877 if (IdVal ==
"oddspreg")
7878 return parseSetOddSPRegDirective();
7879 if (IdVal ==
"nooddspreg")
7880 return parseSetNoOddSPRegDirective();
7882 return parseSetPopDirective();
7883 if (IdVal ==
"push")
7884 return parseSetPushDirective();
7885 if (IdVal ==
"reorder")
7886 return parseSetReorderDirective();
7887 if (IdVal ==
"noreorder")
7888 return parseSetNoReorderDirective();
7889 if (IdVal ==
"macro")
7890 return parseSetMacroDirective();
7891 if (IdVal ==
"nomacro")
7892 return parseSetNoMacroDirective();
7893 if (IdVal ==
"mips16")
7894 return parseSetMips16Directive();
7895 if (IdVal ==
"nomips16")
7896 return parseSetNoMips16Directive();
7897 if (IdVal ==
"nomicromips") {
7898 clearFeatureBits(Mips::FeatureMicroMips,
"micromips");
7899 getTargetStreamer().emitDirectiveSetNoMicroMips();
7900 getParser().eatToEndOfStatement();
7903 if (IdVal ==
"micromips") {
7904 if (hasMips64r6()) {
7905 Error(Loc,
".set micromips directive is not supported with MIPS64R6");
7908 return parseSetFeature(Mips::FeatureMicroMips);
7910 if (IdVal ==
"mips0")
7911 return parseSetMips0Directive();
7912 if (IdVal ==
"mips1")
7913 return parseSetFeature(Mips::FeatureMips1);
7914 if (IdVal ==
"mips2")
7915 return parseSetFeature(Mips::FeatureMips2);
7916 if (IdVal ==
"mips3")
7917 return parseSetFeature(Mips::FeatureMips3);
7918 if (IdVal ==
"mips4")
7919 return parseSetFeature(Mips::FeatureMips4);
7920 if (IdVal ==
"mips5")
7921 return parseSetFeature(Mips::FeatureMips5);
7922 if (IdVal ==
"mips32")
7923 return parseSetFeature(Mips::FeatureMips32);
7924 if (IdVal ==
"mips32r2")
7925 return parseSetFeature(Mips::FeatureMips32r2);
7926 if (IdVal ==
"mips32r3")
7927 return parseSetFeature(Mips::FeatureMips32r3);
7928 if (IdVal ==
"mips32r5")
7929 return parseSetFeature(Mips::FeatureMips32r5);
7930 if (IdVal ==
"mips32r6")
7931 return parseSetFeature(Mips::FeatureMips32r6);
7932 if (IdVal ==
"mips64")
7933 return parseSetFeature(Mips::FeatureMips64);
7934 if (IdVal ==
"mips64r2")
7935 return parseSetFeature(Mips::FeatureMips64r2);
7936 if (IdVal ==
"mips64r3")
7937 return parseSetFeature(Mips::FeatureMips64r3);
7938 if (IdVal ==
"mips64r5")
7939 return parseSetFeature(Mips::FeatureMips64r5);
7940 if (IdVal ==
"mips64r6") {
7941 if (inMicroMipsMode()) {
7942 Error(Loc,
"MIPS64R6 is not supported with microMIPS");
7945 return parseSetFeature(Mips::FeatureMips64r6);
7948 return parseSetFeature(Mips::FeatureDSP);
7949 if (IdVal ==
"dspr2")
7950 return parseSetFeature(Mips::FeatureDSPR2);
7951 if (IdVal ==
"nodsp")
7952 return parseSetNoDspDirective();
7953 if (IdVal ==
"mips3d")
7954 return parseSetFeature(Mips::FeatureMips3D);
7955 if (IdVal ==
"nomips3d")
7956 return parseSetNoMips3DDirective();
7958 return parseSetMsaDirective();
7959 if (IdVal ==
"nomsa")
7960 return parseSetNoMsaDirective();
7962 return parseSetMtDirective();
7963 if (IdVal ==
"nomt")
7964 return parseSetNoMtDirective();
7965 if (IdVal ==
"softfloat")
7966 return parseSetSoftFloatDirective();
7967 if (IdVal ==
"hardfloat")
7968 return parseSetHardFloatDirective();
7970 return parseSetFeature(Mips::FeatureCRC);
7971 if (IdVal ==
"nocrc")
7972 return parseSetNoCRCDirective();
7973 if (IdVal ==
"virt")
7974 return parseSetFeature(Mips::FeatureVirt);
7975 if (IdVal ==
"novirt")
7976 return parseSetNoVirtDirective();
7977 if (IdVal ==
"ginv")
7978 return parseSetFeature(Mips::FeatureGINV);
7979 if (IdVal ==
"noginv")
7980 return parseSetNoGINVDirective();
7982 return parseSetFeature(Mips::FeatureEVA);
7983 if (IdVal ==
"noeva")
7984 return parseSetNoEVADirective();
7987 return parseSetAssignment();
7992bool MipsAsmParser::parseDirectiveGpWord() {
7993 const MCExpr *
Value;
7994 if (getParser().parseExpression(
Value))
7996 getTargetStreamer().emitGPRel32Value(
Value);
8002bool MipsAsmParser::parseDirectiveGpDWord() {
8003 const MCExpr *
Value;
8004 if (getParser().parseExpression(
Value))
8006 getTargetStreamer().emitGPRel64Value(
Value);
8012bool MipsAsmParser::parseDirectiveDtpRelWord() {
8013 const MCExpr *
Value;
8014 if (getParser().parseExpression(
Value))
8016 getTargetStreamer().emitDTPRel32Value(
Value);
8022bool MipsAsmParser::parseDirectiveDtpRelDWord() {
8023 const MCExpr *
Value;
8024 if (getParser().parseExpression(
Value))
8026 getTargetStreamer().emitDTPRel64Value(
Value);
8032bool MipsAsmParser::parseDirectiveTpRelWord() {
8033 const MCExpr *
Value;
8034 if (getParser().parseExpression(
Value))
8036 getTargetStreamer().emitTPRel32Value(
Value);
8042bool MipsAsmParser::parseDirectiveTpRelDWord() {
8043 const MCExpr *
Value;
8044 if (getParser().parseExpression(
Value))
8046 getTargetStreamer().emitTPRel64Value(
Value);
8050bool MipsAsmParser::parseDirectiveOption() {
8051 MCAsmParser &Parser = getParser();
8053 AsmToken Tok = Parser.
getTok();
8057 "unexpected token, expected identifier");
8062 if (Option ==
"pic0") {
8064 IsPicEnabled =
false;
8066 getTargetStreamer().emitDirectiveOptionPic0();
8070 "unexpected token, expected end of statement");
8075 if (Option ==
"pic2") {
8077 IsPicEnabled =
true;
8079 getTargetStreamer().emitDirectiveOptionPic2();
8083 "unexpected token, expected end of statement");
8090 "unknown option, expected 'pic0' or 'pic2'");
8097bool MipsAsmParser::parseInsnDirective() {
8100 reportParseError(
"unexpected token, expected end of statement");
8106 getTargetStreamer().emitDirectiveInsn();
8114bool MipsAsmParser::parseRSectionDirective(StringRef Section) {
8117 reportParseError(
"unexpected token, expected end of statement");
8121 MCSection *ELFSection =
getContext().getELFSection(
8123 getParser().getStreamer().switchSection(ELFSection);
8132bool MipsAsmParser::parseSSectionDirective(StringRef Section,
unsigned Type) {
8135 reportParseError(
"unexpected token, expected end of statement");
8139 MCSection *ELFSection =
getContext().getELFSection(
8141 getParser().getStreamer().switchSection(ELFSection);
8160bool MipsAsmParser::parseDirectiveModule() {
8161 MCAsmParser &Parser = getParser();
8162 AsmLexer &Lexer = getLexer();
8165 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
8167 reportParseError(
".module directive must appear before any code");
8173 reportParseError(
"expected .module option identifier");
8177 if (Option ==
"oddspreg") {
8178 clearModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
8182 getTargetStreamer().updateABIInfo(*
this);
8187 getTargetStreamer().emitDirectiveModuleOddSPReg();
8191 reportParseError(
"unexpected token, expected end of statement");
8196 }
else if (Option ==
"nooddspreg") {
8198 return Error(L,
"'.module nooddspreg' requires the O32 ABI");
8201 setModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
8205 getTargetStreamer().updateABIInfo(*
this);
8210 getTargetStreamer().emitDirectiveModuleOddSPReg();
8214 reportParseError(
"unexpected token, expected end of statement");
8219 }
else if (Option ==
"fp") {
8220 return parseDirectiveModuleFP();
8221 }
else if (Option ==
"softfloat") {
8222 setModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
8226 getTargetStreamer().updateABIInfo(*
this);
8231 getTargetStreamer().emitDirectiveModuleSoftFloat();
8235 reportParseError(
"unexpected token, expected end of statement");
8240 }
else if (Option ==
"hardfloat") {
8241 clearModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
8245 getTargetStreamer().updateABIInfo(*
this);
8250 getTargetStreamer().emitDirectiveModuleHardFloat();
8254 reportParseError(
"unexpected token, expected end of statement");
8259 }
else if (Option ==
"mt") {
8260 setModuleFeatureBits(Mips::FeatureMT,
"mt");
8264 getTargetStreamer().updateABIInfo(*
this);
8269 getTargetStreamer().emitDirectiveModuleMT();
8273 reportParseError(
"unexpected token, expected end of statement");
8278 }
else if (Option ==
"crc") {
8279 setModuleFeatureBits(Mips::FeatureCRC,
"crc");
8283 getTargetStreamer().updateABIInfo(*
this);
8288 getTargetStreamer().emitDirectiveModuleCRC();
8292 reportParseError(
"unexpected token, expected end of statement");
8297 }
else if (Option ==
"nocrc") {
8298 clearModuleFeatureBits(Mips::FeatureCRC,
"crc");
8302 getTargetStreamer().updateABIInfo(*
this);
8307 getTargetStreamer().emitDirectiveModuleNoCRC();
8311 reportParseError(
"unexpected token, expected end of statement");
8316 }
else if (Option ==
"virt") {
8317 setModuleFeatureBits(Mips::FeatureVirt,
"virt");
8321 getTargetStreamer().updateABIInfo(*
this);
8326 getTargetStreamer().emitDirectiveModuleVirt();
8330 reportParseError(
"unexpected token, expected end of statement");
8335 }
else if (Option ==
"novirt") {
8336 clearModuleFeatureBits(Mips::FeatureVirt,
"virt");
8340 getTargetStreamer().updateABIInfo(*
this);
8345 getTargetStreamer().emitDirectiveModuleNoVirt();
8349 reportParseError(
"unexpected token, expected end of statement");
8354 }
else if (Option ==
"ginv") {
8355 setModuleFeatureBits(Mips::FeatureGINV,
"ginv");
8359 getTargetStreamer().updateABIInfo(*
this);
8364 getTargetStreamer().emitDirectiveModuleGINV();
8368 reportParseError(
"unexpected token, expected end of statement");
8373 }
else if (Option ==
"noginv") {
8374 clearModuleFeatureBits(Mips::FeatureGINV,
"ginv");
8378 getTargetStreamer().updateABIInfo(*
this);
8383 getTargetStreamer().emitDirectiveModuleNoGINV();
8387 reportParseError(
"unexpected token, expected end of statement");
8393 return Error(L,
"'" + Twine(Option) +
"' is not a valid .module option.");
8401bool MipsAsmParser::parseDirectiveModuleFP() {
8402 MCAsmParser &Parser = getParser();
8403 AsmLexer &Lexer = getLexer();
8406 reportParseError(
"unexpected token, expected equals sign '='");
8412 if (!parseFpABIValue(FpABI,
".module"))
8416 reportParseError(
"unexpected token, expected end of statement");
8422 getTargetStreamer().updateABIInfo(*
this);
8427 getTargetStreamer().emitDirectiveModuleFP();
8434 StringRef Directive) {
8435 MCAsmParser &Parser = getParser();
8436 AsmLexer &Lexer = getLexer();
8437 bool ModuleLevelOptions = Directive ==
".module";
8443 if (
Value !=
"xx") {
8444 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
8449 reportParseError(
"'" + Directive +
" fp=xx' requires the O32 ABI");
8453 FpABI = MipsABIFlagsSection::FpABIKind::XX;
8454 if (ModuleLevelOptions) {
8455 setModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8456 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8458 setFeatureBits(Mips::FeatureFPXX,
"fpxx");
8459 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8469 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
8475 reportParseError(
"'" + Directive +
" fp=32' requires the O32 ABI");
8479 FpABI = MipsABIFlagsSection::FpABIKind::S32;
8480 if (ModuleLevelOptions) {
8481 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8482 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8484 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
8485 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8488 FpABI = MipsABIFlagsSection::FpABIKind::S64;
8489 if (ModuleLevelOptions) {
8490 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8491 setModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8493 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
8494 setFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8504bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
8510 MCAsmParser &Parser = getParser();
8511 StringRef IDVal = DirectiveID.
getString();
8513 if (IDVal ==
".cpadd") {
8514 parseDirectiveCpAdd(DirectiveID.
getLoc());
8517 if (IDVal ==
".cpload") {
8518 parseDirectiveCpLoad(DirectiveID.
getLoc());
8521 if (IDVal ==
".cprestore") {
8522 parseDirectiveCpRestore(DirectiveID.
getLoc());
8525 if (IDVal ==
".cplocal") {
8526 parseDirectiveCpLocal(DirectiveID.
getLoc());
8529 if (IDVal ==
".ent") {
8533 reportParseError(
"expected identifier after .ent");
8547 reportParseError(
"unexpected token, expected end of statement");
8551 const MCExpr *DummyNumber;
8552 int64_t DummyNumberVal;
8556 reportParseError(
"expected number after comma");
8559 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
8560 reportParseError(
"expected an absolute expression after comma");
8567 reportParseError(
"unexpected token, expected end of statement");
8573 getTargetStreamer().emitDirectiveEnt(*Sym);
8575 IsCpRestoreSet =
false;
8579 if (IDVal ==
".end") {
8583 reportParseError(
"expected identifier after .end");
8588 reportParseError(
"unexpected token, expected end of statement");
8592 if (CurrentFn ==
nullptr) {
8593 reportParseError(
".end used without .ent");
8597 if ((SymbolName != CurrentFn->
getName())) {
8598 reportParseError(
".end symbol does not match .ent symbol");
8602 getTargetStreamer().emitDirectiveEnd(SymbolName);
8603 CurrentFn =
nullptr;
8604 IsCpRestoreSet =
false;
8608 if (IDVal ==
".frame") {
8611 ParseStatus Res = parseAnyRegister(TmpReg);
8613 reportParseError(
"expected stack register");
8617 MipsOperand &StackRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
8618 if (!StackRegOpnd.isGPRAsmReg()) {
8619 reportParseError(StackRegOpnd.getStartLoc(),
8620 "expected general purpose register");
8623 MCRegister StackReg = StackRegOpnd.getGPR32Reg();
8628 reportParseError(
"unexpected token, expected comma");
8633 const MCExpr *FrameSize;
8634 int64_t FrameSizeVal;
8637 reportParseError(
"expected frame size value");
8641 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
8642 reportParseError(
"frame size not an absolute expression");
8649 reportParseError(
"unexpected token, expected comma");
8655 Res = parseAnyRegister(TmpReg);
8657 reportParseError(
"expected return register");
8661 MipsOperand &ReturnRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
8662 if (!ReturnRegOpnd.isGPRAsmReg()) {
8663 reportParseError(ReturnRegOpnd.getStartLoc(),
8664 "expected general purpose register");
8670 reportParseError(
"unexpected token, expected end of statement");
8674 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
8675 ReturnRegOpnd.getGPR32Reg());
8676 IsCpRestoreSet =
false;
8680 if (IDVal ==
".set") {
8681 parseDirectiveSet();
8685 if (IDVal ==
".mask" || IDVal ==
".fmask") {
8696 const MCExpr *BitMask;
8700 reportParseError(
"expected bitmask value");
8704 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
8705 reportParseError(
"bitmask not an absolute expression");
8712 reportParseError(
"unexpected token, expected comma");
8717 const MCExpr *FrameOffset;
8718 int64_t FrameOffsetVal;
8721 reportParseError(
"expected frame offset value");
8725 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
8726 reportParseError(
"frame offset not an absolute expression");
8732 reportParseError(
"unexpected token, expected end of statement");
8736 if (IDVal ==
".mask")
8737 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
8739 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
8743 if (IDVal ==
".nan")
8744 return parseDirectiveNaN();
8746 if (IDVal ==
".gpword") {
8747 parseDirectiveGpWord();
8751 if (IDVal ==
".gpdword") {
8752 parseDirectiveGpDWord();
8756 if (IDVal ==
".dtprelword") {
8757 parseDirectiveDtpRelWord();
8761 if (IDVal ==
".dtpreldword") {
8762 parseDirectiveDtpRelDWord();
8766 if (IDVal ==
".tprelword") {
8767 parseDirectiveTpRelWord();
8771 if (IDVal ==
".tpreldword") {
8772 parseDirectiveTpRelDWord();
8776 if (IDVal ==
".option") {
8777 parseDirectiveOption();
8781 if (IDVal ==
".abicalls") {
8782 getTargetStreamer().emitDirectiveAbiCalls();
8785 "unexpected token, expected end of statement");
8790 if (IDVal ==
".cpsetup") {
8791 parseDirectiveCPSetup();
8794 if (IDVal ==
".cpreturn") {
8795 parseDirectiveCPReturn();
8798 if (IDVal ==
".module") {
8799 parseDirectiveModule();
8802 if (IDVal ==
".llvm_internal_mips_reallow_module_directive") {
8803 parseInternalDirectiveReallowModule();
8806 if (IDVal ==
".insn") {
8807 parseInsnDirective();
8810 if (IDVal ==
".rdata") {
8811 parseRSectionDirective(
".rodata");
8814 if (IDVal ==
".sbss") {
8818 if (IDVal ==
".sdata") {
8826bool MipsAsmParser::parseInternalDirectiveReallowModule() {
8829 reportParseError(
"unexpected token, expected end of statement");
8833 getTargetStreamer().reallowModuleDirective();
8847#define GET_REGISTER_MATCHER
8848#define GET_MATCHER_IMPLEMENTATION
8849#define GET_MNEMONIC_SPELL_CHECKER
8850#include "MipsGenAsmMatcher.inc"
8852bool MipsAsmParser::mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID) {
8854 const MatchEntry *Start, *
End;
8855 switch (VariantID) {
8857 case 0: Start = std::begin(MatchTable0);
End = std::end(MatchTable0);
break;
8860 auto MnemonicRange = std::equal_range(Start,
End, Mnemonic, LessOpcode());
8861 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")
#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.
static constexpr Value * getValue(Ty &ValueOrUse)
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static FeatureBitset getFeatures(MCSubtargetInfo &STI, StringRef CPU, StringRef TuneCPU, StringRef FS, StringTable ProcNames, ArrayRef< SubtargetSubTypeKV > ProcDesc, ArrayRef< SubtargetFeatureKV > ProcFeatures)
static bool hasFeature(StringRef Feature, const FeatureBitset &FeatureBits, ArrayRef< SubtargetFeatureKV > ProcFeatures)
static unsigned countMCSymbolRefExpr(const MCExpr *Expr)
static std::string MipsMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, unsigned VariantID=0)
static uint64_t convertIntToDoubleImm(uint64_t ImmOp64)
static uint32_t covertDoubleImmToSingleImm(uint64_t ImmOp64)
static unsigned getRegisterForMxtrDSP(MCInst &Inst, bool IsMFDSP)
static bool hasShortDelaySlot(MCInst &Inst)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsAsmParser()
static bool needsExpandMemInst(MCInst &Inst, const MCInstrDesc &MCID)
static bool isShiftedUIntAtAnyPosition(uint64_t x)
Can the value be represented by a unsigned N-bit value and a shift left?
static bool isEvaluated(const MCExpr *Expr)
static unsigned getRegisterForMxtrC0(MCInst &Inst, bool IsMFTC0)
static const MCSymbol * getSingleMCSymbol(const MCExpr *Expr)
static MCRegister nextReg(MCRegister Reg)
static unsigned getRegisterForMxtrFP(MCInst &Inst, bool IsMFTC1)
static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands, uint64_t ErrorInfo)
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
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 const fltSemantics & IEEEdouble()
APInt bitcastToAPInt() const
uint64_t getZExtValue() const
Get zero extended value.
SMLoc getLoc() const
Get the current source location.
const AsmToken peekTok(bool ShouldSkipSpace=true)
Look ahead at the next token to be lexed.
bool is(AsmToken::TokenKind K) const
Check if the current token has kind K.
bool isNot(AsmToken::TokenKind K) const
Check if the current token has kind K.
Target independent representation for an assembler token.
LLVM_ABI SMLoc getLoc() const
int64_t getIntVal() const
bool isNot(TokenKind K) const
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
bool is(TokenKind K) const
TokenKind getKind() const
LLVM_ABI SMRange getLocRange() const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
Base class for user error types.
Container class for subtarget features.
void printExpr(raw_ostream &, const MCExpr &) const
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
bool parseToken(AsmToken::TokenKind T, const Twine &Msg="unexpected token")
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
Binary assembler expressions.
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
static LLVM_ABI const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
@ LShr
Logical shift right.
@ Xor
Bitwise exclusive or.
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Base class for the full range of assembler expressions which are needed for parsing.
LLVM_ABI bool evaluateAsRelocatable(MCValue &Res, const MCAssembler *Asm) const
Try to evaluate the expression to a relocatable value, i.e.
@ Unary
Unary expressions.
@ Constant
Constant expressions.
@ SymbolRef
References to labels and assigned expressions.
@ Target
Target specific expression.
@ Specifier
Expression with a relocation specifier.
@ Binary
Binary expressions.
Instances of this class represent a single low-level machine instruction.
unsigned getNumOperands() const
unsigned getOpcode() const
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
const MCOperand & getOperand(unsigned i) const
Describe properties that are true of each instruction in the target description file.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
ArrayRef< MCOperandInfo > operands() const
bool mayStore() const
Return true if this instruction could possibly modify memory.
bool mayLoad() const
Return true if this instruction could possibly read memory.
bool isBranch() const
Returns true if this is a conditional, unconditional, or indirect branch.
bool isCall() const
Return true if the instruction is a call.
bool hasDelaySlot() const
Returns true if the specified instruction has a delay slot which must be filled by the code generator...
Interface to description of machine instruction set.
This holds information about one operand of a machine instruction, indicating the register class for ...
uint8_t OperandType
Information about the type of the operand.
Instances of this class represent operands of the MCInst class.
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
MCRegister getReg() const
Returns the register number.
const MCExpr * getExpr() const
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual bool isReg() const =0
isReg - Is this a register operand?
virtual MCRegister getReg() const =0
MCRegister getRegister(unsigned i) const
getRegister - Return the specified register in the class.
uint16_t getEncodingValue(MCRegister Reg) const
Returns the encoding for Reg.
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
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 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
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
static const char * getRegisterName(MCRegister Reg, unsigned AltIdx=Mips::NoRegAltName)
void emitRRX(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, MCOperand Op2, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveSetReorder()
void emitRRRX(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, MCRegister Reg2, MCOperand Op3, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRX(unsigned Opcode, MCRegister Reg0, MCOperand Op1, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitR(unsigned Opcode, MCRegister Reg0, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void setUsesMicroMips()
void emitRRI(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, int16_t Imm, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitEmptyDelaySlot(bool hasShortDelaySlot, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRI(unsigned Opcode, MCRegister Reg0, int32_t Imm, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRR(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, SMLoc IDLoc, const MCSubtargetInfo *STI)
void updateABIInfo(const PredicateLibrary &P)
void emitRRIII(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, int16_t Imm0, int16_t Imm1, int16_t Imm2, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitDSLL(MCRegister DstReg, MCRegister SrcReg, int16_t ShiftAmount, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitGPRestore(int Offset, SMLoc IDLoc, const MCSubtargetInfo *STI)
Emit the $gp restore operation for .cprestore.
void emitNop(SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRRR(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, MCRegister Reg2, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveSetNoReorder()
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
static constexpr StatusTy Failure
constexpr bool isSuccess() const
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
constexpr bool isNoMatch() const
constexpr unsigned id() const
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
void push_back(const T &Elt)
iterator find(StringRef Key)
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
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.
LLVM_ABI LLVM_READONLY ARMABI computeTargetABI(const Triple &TT, StringRef ABIName="")
LLVM_ABI 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.
MCRegister matchRegisterName(StringRef Name, const MCRegisterInfo &MRI, unsigned RegClassID, unsigned AltIdx)
Match a symbolic name in RegClassID, or return an invalid register.
int getCPURegisterIndex(StringRef Name, const MCRegisterInfo &MRI, unsigned AltIdx, bool *IsDeprecated=nullptr)
Return a GPR name's hardware index, or -1 if unknown.
WebAssemblyABI getABI(StringRef Name)
Parse an ABI name into the corresponding enum.
@ CE
Windows NT (Windows on ARM)
LLVM_ABI StringRef getABIName()
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
unsigned getOpcode(const VPValue *V)
Return the instruction opcode for the recipe defining V or 0 for unsupported recipes and VPValues not...
This is an optimization pass for GlobalISel generic memory operations.
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.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
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...
@ Global
Append to llvm.global_dtors.
@ 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()
@ End
Run the machine verifier once, at the end of the pipeline.
constexpr bool isShiftedUInt(uint64_t x)
Checks if a unsigned integer is an N bit number shifted left by S.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...