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),
525 sti.getTargetTriple(),
535 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
538 AssemblerOptions.push_back(
539 std::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
542 AssemblerOptions.push_back(
543 std::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
545 getTargetStreamer().updateABIInfo(*
this);
547 if (!isABI_O32() && !useOddSPReg() != 0)
552 CurForbiddenSlotAttr =
false;
553 IsPicEnabled =
getContext().getObjectFileInfo()->isPositionIndependent();
555 IsCpRestoreSet =
false;
556 CpRestoreOffset = -1;
557 GPReg = ABI.GetGlobalPtr();
562 if (getSTI().
getCPU() ==
"mips64r6" && inMicroMipsMode())
565 if (!isABI_O32() && inMicroMipsMode())
570 bool hasEightFccRegisters()
const {
return hasMips4() || hasMips32(); }
572 bool isGP64bit()
const {
573 return getSTI().hasFeature(Mips::FeatureGP64Bit);
576 bool isFP64bit()
const {
577 return getSTI().hasFeature(Mips::FeatureFP64Bit);
580 bool isJalrRelocAvailable(
const MCExpr *JalExpr) {
581 if (!CLOpts.jalr_reloc)
589 return ABI.IsN32() || ABI.IsN64();
593 const MipsABIInfo &
getABI()
const {
return ABI; }
594 bool isABI_N32()
const {
return ABI.IsN32(); }
595 bool isABI_N64()
const {
return ABI.IsN64(); }
596 bool isABI_O32()
const {
return ABI.IsO32(); }
597 bool isABI_FPXX()
const {
598 return getSTI().hasFeature(Mips::FeatureFPXX);
601 bool useOddSPReg()
const {
602 return !(getSTI().hasFeature(Mips::FeatureNoOddSPReg));
605 bool inMicroMipsMode()
const {
606 return getSTI().hasFeature(Mips::FeatureMicroMips);
609 bool hasMips1()
const {
610 return getSTI().hasFeature(Mips::FeatureMips1);
613 bool hasMips2()
const {
614 return getSTI().hasFeature(Mips::FeatureMips2);
617 bool hasMips3()
const {
618 return getSTI().hasFeature(Mips::FeatureMips3);
621 bool hasMips4()
const {
622 return getSTI().hasFeature(Mips::FeatureMips4);
625 bool hasMips5()
const {
626 return getSTI().hasFeature(Mips::FeatureMips5);
629 bool hasMips32()
const {
630 return getSTI().hasFeature(Mips::FeatureMips32);
633 bool hasMips64()
const {
634 return getSTI().hasFeature(Mips::FeatureMips64);
637 bool hasMips32r2()
const {
638 return getSTI().hasFeature(Mips::FeatureMips32r2);
641 bool hasMips64r2()
const {
642 return getSTI().hasFeature(Mips::FeatureMips64r2);
645 bool hasMips32r3()
const {
646 return (getSTI().
hasFeature(Mips::FeatureMips32r3));
649 bool hasMips64r3()
const {
650 return (getSTI().
hasFeature(Mips::FeatureMips64r3));
653 bool hasMips32r5()
const {
654 return (getSTI().
hasFeature(Mips::FeatureMips32r5));
657 bool hasMips64r5()
const {
658 return (getSTI().
hasFeature(Mips::FeatureMips64r5));
661 bool hasMips32r6()
const {
662 return getSTI().hasFeature(Mips::FeatureMips32r6);
665 bool hasMips64r6()
const {
666 return getSTI().hasFeature(Mips::FeatureMips64r6);
669 bool hasDSP()
const {
670 return getSTI().hasFeature(Mips::FeatureDSP);
673 bool hasDSPR2()
const {
674 return getSTI().hasFeature(Mips::FeatureDSPR2);
677 bool hasDSPR3()
const {
678 return getSTI().hasFeature(Mips::FeatureDSPR3);
681 bool hasMSA()
const {
682 return getSTI().hasFeature(Mips::FeatureMSA);
685 bool hasCnMips()
const {
686 return (getSTI().
hasFeature(Mips::FeatureCnMips));
689 bool hasCnMipsP()
const {
690 return (getSTI().
hasFeature(Mips::FeatureCnMipsP));
693 bool isR5900()
const {
return (getSTI().
hasFeature(Mips::FeatureR5900)); }
699 bool inMips16Mode()
const {
700 return getSTI().hasFeature(Mips::FeatureMips16);
703 bool useTraps()
const {
704 return getSTI().hasFeature(Mips::FeatureUseTCCInDIV);
707 bool useSoftFloat()
const {
708 return getSTI().hasFeature(Mips::FeatureSoftFloat);
711 bool isSingleFloat()
const {
712 return getSTI().hasFeature(Mips::FeatureSingleFloat);
716 return getSTI().hasFeature(Mips::FeatureMT);
719 bool hasCRC()
const {
720 return getSTI().hasFeature(Mips::FeatureCRC);
723 bool hasVirt()
const {
724 return getSTI().hasFeature(Mips::FeatureVirt);
727 bool hasGINV()
const {
728 return getSTI().hasFeature(Mips::FeatureGINV);
731 bool hasForbiddenSlot(
const MCInstrDesc &MCID)
const {
735 bool SafeInForbiddenSlot(
const MCInstrDesc &MCID)
const {
739 void onEndOfFile()
override;
742 void warnIfRegIndexIsAT(MCRegister RegIndex, SMLoc Loc);
744 void warnIfNoMacro(SMLoc Loc);
746 bool isLittle()
const {
return IsLittleEndian; }
748 bool areEqualRegs(
const MCParsedAsmOperand &Op1,
749 const MCParsedAsmOperand &Op2)
const override;
764 RegKind_MSACtrl = 16,
769 RegKind_HWRegs = 256,
773 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
774 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
775 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
788 MipsOperand(KindTy K, MipsAsmParser &Parser) : Kind(
K), AsmParser(Parser) {}
790 ~MipsOperand()
override {
799 case k_RegisterIndex:
807 MipsAsmParser &AsmParser;
818 const MCRegisterInfo *RegInfo;
836 struct RegIdxOp RegIdx;
839 struct RegListOp RegList;
842 SMLoc StartLoc, EndLoc;
845 static std::unique_ptr<MipsOperand> CreateReg(
unsigned Index, StringRef Str,
847 const MCRegisterInfo *RegInfo,
849 MipsAsmParser &Parser) {
850 auto Op = std::make_unique<MipsOperand>(k_RegisterIndex, Parser);
852 Op->RegIdx.RegInfo = RegInfo;
853 Op->RegIdx.Kind = RegKind;
854 Op->RegIdx.Tok.Data = Str.data();
855 Op->RegIdx.Tok.Length = Str.size();
864 MCRegister getGPR32Reg()
const {
865 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
866 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
867 unsigned ClassID = Mips::GPR32RegClassID;
868 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
873 MCRegister getGPRMM16Reg()
const {
874 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
875 unsigned ClassID = Mips::GPR32RegClassID;
876 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
881 MCRegister getGPR64Reg()
const {
882 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
883 unsigned ClassID = Mips::GPR64RegClassID;
884 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
890 MCRegister getAFGR64Reg()
const {
891 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
892 if (RegIdx.Index % 2 != 0)
893 AsmParser.Warning(StartLoc,
"Float register should be even.");
894 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
895 .getRegister(RegIdx.Index / 2);
900 MCRegister getFGR64Reg()
const {
901 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
902 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
903 .getRegister(RegIdx.Index);
908 MCRegister getFGR32Reg()
const {
909 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
910 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
911 .getRegister(RegIdx.Index);
916 MCRegister getFCCReg()
const {
917 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) &&
"Invalid access!");
918 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
919 .getRegister(RegIdx.Index);
924 MCRegister getMSA128Reg()
const {
925 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) &&
"Invalid access!");
928 unsigned ClassID = Mips::MSA128BRegClassID;
929 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
934 MCRegister getMSACtrlReg()
const {
935 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) &&
"Invalid access!");
936 unsigned ClassID = Mips::MSACtrlRegClassID;
937 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
942 MCRegister getCOP0Reg()
const {
943 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) &&
"Invalid access!");
944 unsigned ClassID = Mips::COP0RegClassID;
945 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
950 MCRegister getCOP2Reg()
const {
951 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) &&
"Invalid access!");
952 unsigned ClassID = Mips::COP2RegClassID;
953 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
958 MCRegister getCOP3Reg()
const {
959 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) &&
"Invalid access!");
960 unsigned ClassID = Mips::COP3RegClassID;
961 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
966 MCRegister getACC64DSPReg()
const {
967 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
968 unsigned ClassID = Mips::ACC64DSPRegClassID;
969 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
974 MCRegister getHI32DSPReg()
const {
975 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
976 unsigned ClassID = Mips::HI32DSPRegClassID;
977 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
982 MCRegister getLO32DSPReg()
const {
983 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
984 unsigned ClassID = Mips::LO32DSPRegClassID;
985 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
990 MCRegister getCCRReg()
const {
991 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) &&
"Invalid access!");
992 unsigned ClassID = Mips::CCRRegClassID;
993 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
998 MCRegister getHWRegsReg()
const {
999 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) &&
"Invalid access!");
1000 unsigned ClassID = Mips::HWRegsRegClassID;
1001 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1005 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const {
1015 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1022 void addGPR32ZeroAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1023 assert(
N == 1 &&
"Invalid number of operands!");
1027 void addGPR32NonZeroAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1028 assert(
N == 1 &&
"Invalid number of operands!");
1032 void addGPR32AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1033 assert(
N == 1 &&
"Invalid number of operands!");
1037 void addGPRMM16AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1038 assert(
N == 1 &&
"Invalid number of operands!");
1042 void addGPRMM16AsmRegZeroOperands(MCInst &Inst,
unsigned N)
const {
1043 assert(
N == 1 &&
"Invalid number of operands!");
1047 void addGPRMM16AsmRegMovePOperands(MCInst &Inst,
unsigned N)
const {
1048 assert(
N == 1 &&
"Invalid number of operands!");
1052 void addGPRMM16AsmRegMovePPairFirstOperands(MCInst &Inst,
unsigned N)
const {
1053 assert(
N == 1 &&
"Invalid number of operands!");
1057 void addGPRMM16AsmRegMovePPairSecondOperands(MCInst &Inst,
1059 assert(
N == 1 &&
"Invalid number of operands!");
1066 void addGPR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1067 assert(
N == 1 &&
"Invalid number of operands!");
1071 void addAFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1072 assert(
N == 1 &&
"Invalid number of operands!");
1076 void addStrictlyAFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1077 assert(
N == 1 &&
"Invalid number of operands!");
1081 void addStrictlyFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1082 assert(
N == 1 &&
"Invalid number of operands!");
1086 void addFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1087 assert(
N == 1 &&
"Invalid number of operands!");
1091 void addFGR32AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1092 assert(
N == 1 &&
"Invalid number of operands!");
1096 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1097 AsmParser.getParser().printError(
1098 StartLoc,
"-mno-odd-spreg prohibits the use of odd FPU "
1102 void addStrictlyFGR32AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1103 assert(
N == 1 &&
"Invalid number of operands!");
1106 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1107 AsmParser.Error(StartLoc,
"-mno-odd-spreg prohibits the use of odd FPU "
1111 void addFCCAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1112 assert(
N == 1 &&
"Invalid number of operands!");
1116 void addMSA128AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1117 assert(
N == 1 &&
"Invalid number of operands!");
1121 void addMSACtrlAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1122 assert(
N == 1 &&
"Invalid number of operands!");
1126 void addCOP0AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1127 assert(
N == 1 &&
"Invalid number of operands!");
1131 void addCOP2AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1132 assert(
N == 1 &&
"Invalid number of operands!");
1136 void addCOP3AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1137 assert(
N == 1 &&
"Invalid number of operands!");
1141 void addACC64DSPAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1142 assert(
N == 1 &&
"Invalid number of operands!");
1146 void addHI32DSPAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1147 assert(
N == 1 &&
"Invalid number of operands!");
1151 void addLO32DSPAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1152 assert(
N == 1 &&
"Invalid number of operands!");
1156 void addCCRAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1157 assert(
N == 1 &&
"Invalid number of operands!");
1161 void addHWRegsAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1162 assert(
N == 1 &&
"Invalid number of operands!");
1166 template <
unsigned Bits,
int Offset = 0,
int AdjustOffset = 0>
1167 void addConstantUImmOperands(MCInst &Inst,
unsigned N)
const {
1168 assert(
N == 1 &&
"Invalid number of operands!");
1172 Imm += AdjustOffset;
1176 template <
unsigned Bits>
1177 void addSImmOperands(MCInst &Inst,
unsigned N)
const {
1178 if (isImm() && !isConstantImm()) {
1182 addConstantSImmOperands<Bits, 0, 0>(Inst,
N);
1185 template <
unsigned Bits>
1186 void addUImmOperands(MCInst &Inst,
unsigned N)
const {
1187 if (isImm() && !isConstantImm()) {
1191 addConstantUImmOperands<Bits, 0, 0>(Inst,
N);
1194 template <
unsigned Bits,
int Offset = 0,
int AdjustOffset = 0>
1195 void addConstantSImmOperands(MCInst &Inst,
unsigned N)
const {
1196 assert(
N == 1 &&
"Invalid number of operands!");
1197 int64_t
Imm = getConstantImm() -
Offset;
1200 Imm += AdjustOffset;
1204 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1205 assert(
N == 1 &&
"Invalid number of operands!");
1206 const MCExpr *Expr =
getImm();
1207 addExpr(Inst, Expr);
1210 void addMemOperands(MCInst &Inst,
unsigned N)
const {
1211 assert(
N == 2 &&
"Invalid number of operands!");
1214 ? getMemBase()->getGPR64Reg()
1215 : getMemBase()->getGPR32Reg()));
1217 const MCExpr *Expr = getMemOff();
1218 addExpr(Inst, Expr);
1221 void addMicroMipsMemOperands(MCInst &Inst,
unsigned N)
const {
1222 assert(
N == 2 &&
"Invalid number of operands!");
1226 const MCExpr *Expr = getMemOff();
1227 addExpr(Inst, Expr);
1230 void addRegListOperands(MCInst &Inst,
unsigned N)
const {
1231 assert(
N == 1 &&
"Invalid number of operands!");
1233 for (
auto RegNo : getRegList())
1237 bool isReg()
const override {
1240 return isGPRAsmReg() && RegIdx.Index == 0;
1243 bool isRegIdx()
const {
return Kind == k_RegisterIndex; }
1244 bool isImm()
const override {
return Kind == k_Immediate; }
1246 bool isConstantImm()
const {
1248 return isImm() &&
getImm()->evaluateAsAbsolute(Res);
1251 bool isConstantImmz()
const {
1252 return isConstantImm() && getConstantImm() == 0;
1255 template <
unsigned Bits,
int Offset = 0>
bool isConstantUImm()
const {
1259 template <
unsigned Bits>
bool isSImm()
const {
1263 if (
getImm()->evaluateAsAbsolute(Res))
1269 template <
unsigned Bits>
bool isUImm()
const {
1273 if (
getImm()->evaluateAsAbsolute(Res))
1279 template <
unsigned Bits>
bool isAnyImm()
const {
1280 return isConstantImm() ? (
isInt<Bits>(getConstantImm()) ||
1285 template <
unsigned Bits,
int Offset = 0>
bool isConstantSImm()
const {
1289 template <
unsigned Bottom,
unsigned Top>
bool isConstantUImmRange()
const {
1290 return isConstantImm() && getConstantImm() >= Bottom &&
1291 getConstantImm() <= Top;
1294 bool isToken()
const override {
1297 return Kind == k_Token;
1300 bool isMem()
const override {
return Kind == k_Memory; }
1302 bool isConstantMemOff()
const {
1307 template <
unsigned Bits,
unsigned ShiftAmount = 0>
1308 bool isMemWithSimmOffset()
const {
1311 if (!getMemBase()->isGPRAsmReg())
1314 (isConstantMemOff() &&
1318 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res,
nullptr);
1322 bool isMemWithPtrSizeOffset()
const {
1325 if (!getMemBase()->isGPRAsmReg())
1327 const unsigned PtrBits = AsmParser.getABI().ArePtrs64bit() ? 64 : 32;
1329 (isConstantMemOff() &&
isIntN(PtrBits, getConstantMemOff())))
1332 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res,
nullptr);
1336 bool isMemWithGRPMM16Base()
const {
1337 return isMem() && getMemBase()->isMM16AsmReg();
1340 template <
unsigned Bits>
bool isMemWithUimmOffsetSP()
const {
1342 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() ==
Mips::SP);
1345 template <
unsigned Bits>
bool isMemWithUimmWordAlignedOffsetSP()
const {
1347 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1348 && (getMemBase()->getGPR32Reg() ==
Mips::SP);
1351 template <
unsigned Bits>
bool isMemWithSimmWordAlignedOffsetGP()
const {
1353 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1354 && (getMemBase()->getGPR32Reg() ==
Mips::GP);
1357 template <
unsigned Bits,
unsigned ShiftLeftAmount>
1358 bool isScaledUImm()
const {
1359 return isConstantImm() &&
1363 template <
unsigned Bits,
unsigned ShiftLeftAmount>
1364 bool isScaledSImm()
const {
1365 if (isConstantImm() &&
1370 if (Kind != k_Immediate)
1373 bool Success =
getImm()->evaluateAsRelocatable(Res,
nullptr);
1377 bool isRegList16()
const {
1381 int Size = RegList.List->size();
1385 MCRegister R0 = RegList.List->front();
1386 MCRegister R1 = RegList.List->back();
1387 if (!((R0 == Mips::R16 && R1 ==
Mips::RA) ||
1391 MCRegister PrevReg = RegList.List->front();
1392 for (
int i = 1; i <
Size - 1; i++) {
1393 MCRegister
Reg = (*(RegList.List))[i];
1394 if (
Reg != PrevReg + 1)
1402 bool isInvNum()
const {
return Kind == k_Immediate; }
1404 bool isLSAImm()
const {
1405 if (!isConstantImm())
1407 int64_t Val = getConstantImm();
1408 return 1 <= Val && Val <= 4;
1411 bool isRegList()
const {
return Kind == k_RegList; }
1414 assert(Kind == k_Token &&
"Invalid access!");
1415 return StringRef(Tok.Data, Tok.Length);
1418 MCRegister
getReg()
const override {
1421 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1422 RegIdx.Kind & RegKind_GPR)
1423 return getGPR32Reg();
1429 const MCExpr *
getImm()
const {
1430 assert((Kind == k_Immediate) &&
"Invalid access!");
1434 int64_t getConstantImm()
const {
1435 const MCExpr *Val =
getImm();
1437 (void)Val->evaluateAsAbsolute(
Value);
1441 MipsOperand *getMemBase()
const {
1442 assert((Kind == k_Memory) &&
"Invalid access!");
1446 const MCExpr *getMemOff()
const {
1447 assert((Kind == k_Memory) &&
"Invalid access!");
1451 int64_t getConstantMemOff()
const {
1452 return static_cast<const MCConstantExpr *
>(getMemOff())->
getValue();
1455 const SmallVectorImpl<MCRegister> &getRegList()
const {
1456 assert((Kind == k_RegList) &&
"Invalid access!");
1457 return *(RegList.List);
1460 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1461 MipsAsmParser &Parser) {
1462 auto Op = std::make_unique<MipsOperand>(k_Token, Parser);
1463 Op->Tok.Data = Str.data();
1464 Op->Tok.Length = Str.size();
1472 static std::unique_ptr<MipsOperand>
1473 createNumericReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1474 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1475 LLVM_DEBUG(
dbgs() <<
"createNumericReg(" << Index <<
", ...)\n");
1476 return CreateReg(Index, Str, RegKind_Numeric, RegInfo, S,
E, Parser);
1481 static std::unique_ptr<MipsOperand>
1482 createGPRReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1483 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1484 return CreateReg(Index, Str, RegKind_GPR, RegInfo, S,
E, Parser);
1489 static std::unique_ptr<MipsOperand>
1490 createFGRReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1491 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1492 return CreateReg(Index, Str, RegKind_FGR, RegInfo, S,
E, Parser);
1497 static std::unique_ptr<MipsOperand>
1498 createHWRegsReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1499 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1500 return CreateReg(Index, Str, RegKind_HWRegs, RegInfo, S,
E, Parser);
1505 static std::unique_ptr<MipsOperand>
1506 createFCCReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1507 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1508 return CreateReg(Index, Str, RegKind_FCC, RegInfo, S,
E, Parser);
1513 static std::unique_ptr<MipsOperand>
1514 createACCReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1515 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1516 return CreateReg(Index, Str, RegKind_ACC, RegInfo, S,
E, Parser);
1521 static std::unique_ptr<MipsOperand>
1522 createMSA128Reg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1523 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1524 return CreateReg(Index, Str, RegKind_MSA128, RegInfo, S,
E, Parser);
1529 static std::unique_ptr<MipsOperand>
1530 createMSACtrlReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1531 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1532 return CreateReg(Index, Str, RegKind_MSACtrl, RegInfo, S,
E, Parser);
1535 static std::unique_ptr<MipsOperand>
1536 CreateImm(
const MCExpr *Val, SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1537 auto Op = std::make_unique<MipsOperand>(k_Immediate, Parser);
1544 static std::unique_ptr<MipsOperand>
1545 CreateMem(std::unique_ptr<MipsOperand>
Base,
const MCExpr *
Off, SMLoc S,
1546 SMLoc
E, MipsAsmParser &Parser) {
1547 auto Op = std::make_unique<MipsOperand>(k_Memory, Parser);
1548 Op->Mem.Base =
Base.release();
1555 static std::unique_ptr<MipsOperand>
1556 CreateRegList(SmallVectorImpl<MCRegister> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1557 MipsAsmParser &Parser) {
1558 assert(!Regs.
empty() &&
"Empty list not allowed");
1560 auto Op = std::make_unique<MipsOperand>(k_RegList, Parser);
1563 Op->StartLoc = StartLoc;
1564 Op->EndLoc = EndLoc;
1568 bool isGPRZeroAsmReg()
const {
1569 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
1572 bool isGPRNonZeroAsmReg()
const {
1573 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index > 0 &&
1577 bool isGPRAsmReg()
const {
1578 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1581 bool isMM16AsmReg()
const {
1582 if (!(isRegIdx() && RegIdx.Kind))
1584 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1585 || RegIdx.Index == 16 || RegIdx.Index == 17);
1588 bool isMM16AsmRegZero()
const {
1589 if (!(isRegIdx() && RegIdx.Kind))
1591 return (RegIdx.Index == 0 ||
1592 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1593 RegIdx.Index == 17);
1596 bool isMM16AsmRegMoveP()
const {
1597 if (!(isRegIdx() && RegIdx.Kind))
1599 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1600 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1603 bool isMM16AsmRegMovePPairFirst()
const {
1604 if (!(isRegIdx() && RegIdx.Kind))
1606 return RegIdx.Index >= 4 && RegIdx.Index <= 6;
1609 bool isMM16AsmRegMovePPairSecond()
const {
1610 if (!(isRegIdx() && RegIdx.Kind))
1612 return (RegIdx.Index == 21 || RegIdx.Index == 22 ||
1613 (RegIdx.Index >= 5 && RegIdx.Index <= 7));
1616 bool isFGRAsmReg()
const {
1618 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1621 bool isStrictlyFGRAsmReg()
const {
1623 return isRegIdx() && RegIdx.Kind == RegKind_FGR && RegIdx.Index <= 31;
1626 bool isHWRegsAsmReg()
const {
1627 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1630 bool isCCRAsmReg()
const {
1631 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1634 bool isFCCAsmReg()
const {
1635 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1637 return RegIdx.Index <= 7;
1640 bool isACCAsmReg()
const {
1641 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1644 bool isCOP0AsmReg()
const {
1645 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1648 bool isCOP2AsmReg()
const {
1649 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1652 bool isCOP3AsmReg()
const {
1653 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1656 bool isMSA128AsmReg()
const {
1657 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1660 bool isMSACtrlAsmReg()
const {
1661 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1665 SMLoc getStartLoc()
const override {
return StartLoc; }
1667 SMLoc getEndLoc()
const override {
return EndLoc; }
1669 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1678 Mem.Base->print(OS, MAI);
1683 case k_RegisterIndex:
1684 OS <<
"RegIdx<" << RegIdx.Index <<
":" << RegIdx.Kind <<
", "
1685 << StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) <<
">";
1692 for (
auto Reg : (*RegList.List))
1693 OS <<
Reg.
id() <<
" ";
1699 bool isValidForTie(
const MipsOperand &
Other)
const {
1700 if (Kind !=
Other.Kind)
1707 case k_RegisterIndex: {
1708 StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length);
1709 StringRef OtherToken(
Other.RegIdx.Tok.Data,
Other.RegIdx.Tok.Length);
1710 return Token == OtherToken;
1726 case Mips::JRC16_MM:
1728 case Mips::JALRS_MM:
1729 case Mips::JALRS16_MM:
1730 case Mips::BGEZALS_MM:
1731 case Mips::BLTZALS_MM:
1742 return &SRExpr->getSymbol();
1801 unsigned NumOp =
MCID.getNumOperands();
1802 if (NumOp != 3 && NumOp != 4)
1832bool MipsAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
1835 MipsTargetStreamer &TOut = getTargetStreamer();
1836 const unsigned Opcode = Inst.
getOpcode();
1837 const MCInstrDesc &MCID = MII.get(Opcode);
1838 bool ExpandedJalSym =
false;
1852 assert(hasCnMips() &&
"instruction only valid for octeon cpus");
1863 if (!
isIntN(inMicroMipsMode() ? 17 : 18,
Offset.getImm()))
1864 return Error(IDLoc,
"branch target out of range");
1867 return Error(IDLoc,
"branch to misaligned address");
1881 case Mips::BGEZAL_MM:
1882 case Mips::BLTZAL_MM:
1885 case Mips::BC1EQZC_MMR6:
1886 case Mips::BC1NEZC_MMR6:
1887 case Mips::BC2EQZC_MMR6:
1888 case Mips::BC2NEZC_MMR6:
1893 if (!
isIntN(inMicroMipsMode() ? 17 : 18,
Offset.getImm()))
1894 return Error(IDLoc,
"branch target out of range");
1897 return Error(IDLoc,
"branch to misaligned address");
1899 case Mips::BGEC:
case Mips::BGEC_MMR6:
1900 case Mips::BLTC:
case Mips::BLTC_MMR6:
1901 case Mips::BGEUC:
case Mips::BGEUC_MMR6:
1902 case Mips::BLTUC:
case Mips::BLTUC_MMR6:
1903 case Mips::BEQC:
case Mips::BEQC_MMR6:
1904 case Mips::BNEC:
case Mips::BNEC_MMR6:
1910 return Error(IDLoc,
"branch target out of range");
1912 return Error(IDLoc,
"branch to misaligned address");
1914 case Mips::BLEZC:
case Mips::BLEZC_MMR6:
1915 case Mips::BGEZC:
case Mips::BGEZC_MMR6:
1916 case Mips::BGTZC:
case Mips::BGTZC_MMR6:
1917 case Mips::BLTZC:
case Mips::BLTZC_MMR6:
1923 return Error(IDLoc,
"branch target out of range");
1925 return Error(IDLoc,
"branch to misaligned address");
1927 case Mips::BEQZC:
case Mips::BEQZC_MMR6:
1928 case Mips::BNEZC:
case Mips::BNEZC_MMR6:
1934 return Error(IDLoc,
"branch target out of range");
1936 return Error(IDLoc,
"branch to misaligned address");
1938 case Mips::BEQZ16_MM:
1939 case Mips::BEQZC16_MMR6:
1940 case Mips::BNEZ16_MM:
1941 case Mips::BNEZC16_MMR6:
1947 return Error(IDLoc,
"branch target out of range");
1949 return Error(IDLoc,
"branch to misaligned address");
1956 if (hasMips32r6() && Opcode == Mips::SSNOP) {
1957 std::string
ISA = hasMips64r6() ?
"MIPS64r6" :
"MIPS32r6";
1958 Warning(IDLoc,
"ssnop is deprecated for " + ISA +
" and is equivalent to a "
1978 return Error(IDLoc,
"expected immediate operand kind");
1981 Opcode == Mips::BBIT1 ? 63 : 31))
1982 return Error(IDLoc,
"immediate operand value out of range");
1984 Inst.
setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1995 return Error(IDLoc,
"expected immediate operand kind");
1998 return Error(IDLoc,
"immediate operand value out of range");
2010 unsigned FirstOp = 1;
2011 unsigned SecondOp = 2;
2015 case Mips::SDivIMacro:
2016 case Mips::UDivIMacro:
2017 case Mips::DSDivIMacro:
2018 case Mips::DUDivIMacro:
2020 return Error(IDLoc,
"expected immediate operand kind");
2024 Warning(IDLoc,
"dividing zero by zero");
2026 Warning(IDLoc,
"division by zero");
2038 case Mips::SDivMacro:
2039 case Mips::DSDivMacro:
2040 case Mips::UDivMacro:
2041 case Mips::DUDivMacro:
2046 case Mips::DIVU_MMR6:
2047 case Mips::DIV_MMR6:
2052 Warning(IDLoc,
"dividing zero by zero");
2054 Warning(IDLoc,
"division by zero");
2060 if ((Opcode == Mips::J || Opcode == Mips::J_MM) && inPicMode()) {
2062 BInst.
setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
2071 if ((Opcode == Mips::JAL || Opcode == Mips::JAL_MM) && inPicMode()) {
2072 warnIfNoMacro(IDLoc);
2075 return Error(IDLoc,
"unsupported constant in relocation");
2083 return Error(IDLoc,
"jal doesn't support multiple symbols in PIC mode");
2089 if (expandLoadAddress(
getABI().getTempReg(9), MCRegister(),
2090 Inst.
getOperand(0), !isGP64bit(), IDLoc, Out, STI))
2094 if (inMicroMipsMode())
2095 JalrInst.
setOpcode(IsCpRestoreSet ? Mips::JALRS_MM : Mips::JALR_MM);
2101 if (isJalrRelocAvailable(JalExpr)) {
2107 const MCExpr *RelocJalrExpr =
2111 *TmpExpr, inMicroMipsMode() ?
"R_MICROMIPS_JALR" :
"R_MIPS_JALR",
2117 ExpandedJalSym =
true;
2126 expandMem9Inst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2129 expandMem16Inst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2132 return getParser().hasPendingError();
2136 if (inMicroMipsMode()) {
2137 if (Opcode == Mips::LW_MM || Opcode == Mips::LW_MMR6) {
2140 const MCOperandInfo &OpInfo = MCID.
operands()[i];
2145 int MemOffset =
Op.getImm();
2148 if (
isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
2171 case Mips::ADDIUSP_MM:
2174 return Error(IDLoc,
"expected immediate operand kind");
2178 return Error(IDLoc,
"immediate operand value out of range");
2180 case Mips::SLL16_MM:
2181 case Mips::SRL16_MM:
2184 return Error(IDLoc,
"expected immediate operand kind");
2187 return Error(IDLoc,
"immediate operand value out of range");
2192 return Error(IDLoc,
"expected immediate operand kind");
2195 return Error(IDLoc,
"immediate operand value out of range");
2197 case Mips::ADDIUR2_MM:
2200 return Error(IDLoc,
"expected immediate operand kind");
2202 if (!(
Imm == 1 ||
Imm == -1 ||
2204 return Error(IDLoc,
"immediate operand value out of range");
2206 case Mips::ANDI16_MM:
2209 return Error(IDLoc,
"expected immediate operand kind");
2213 Imm == 64 ||
Imm == 255 ||
Imm == 32768 ||
Imm == 65535))
2214 return Error(IDLoc,
"immediate operand value out of range");
2216 case Mips::LBU16_MM:
2219 return Error(IDLoc,
"expected immediate operand kind");
2222 return Error(IDLoc,
"immediate operand value out of range");
2225 case Mips::SB16_MMR6:
2228 return Error(IDLoc,
"expected immediate operand kind");
2231 return Error(IDLoc,
"immediate operand value out of range");
2233 case Mips::LHU16_MM:
2235 case Mips::SH16_MMR6:
2238 return Error(IDLoc,
"expected immediate operand kind");
2241 return Error(IDLoc,
"immediate operand value out of range");
2245 case Mips::SW16_MMR6:
2248 return Error(IDLoc,
"expected immediate operand kind");
2251 return Error(IDLoc,
"immediate operand value out of range");
2253 case Mips::ADDIUPC_MM:
2256 return Error(IDLoc,
"expected immediate operand kind");
2259 return Error(IDLoc,
"immediate operand value out of range");
2264 return Error(IDLoc,
"invalid operand for instruction");
2266 case Mips::MOVEP_MM:
2267 case Mips::MOVEP_MMR6: {
2270 bool RegPair = ((R0 == Mips::R5 && R1 == Mips::R6) ||
2271 (R0 == Mips::R5 && R1 == Mips::R7) ||
2272 (R0 == Mips::R6 && R1 == Mips::R7) ||
2273 (R0 == Mips::R4 && R1 == Mips::R21) ||
2274 (R0 == Mips::R4 && R1 == Mips::R22) ||
2275 (R0 == Mips::R4 && R1 == Mips::R5) ||
2276 (R0 == Mips::R4 && R1 == Mips::R6) ||
2277 (R0 == Mips::R4 && R1 == Mips::R7));
2279 return Error(IDLoc,
"invalid operand for instruction");
2285 bool FillDelaySlot =
2290 bool PrevForbiddenSlotAttr = CurForbiddenSlotAttr;
2293 bool SetReorderAfterNop =
false;
2298 if (PrevForbiddenSlotAttr && !SafeInForbiddenSlot(MCID)) {
2308 if (AssemblerOptions.
back()->isReorder() && !FillDelaySlot) {
2309 SetReorderAfterNop =
true;
2318 CurForbiddenSlotAttr =
2319 hasForbiddenSlot(MCID) && AssemblerOptions.
back()->isReorder();
2321 if (FillDelaySlot || CurForbiddenSlotAttr)
2324 MacroExpanderResultTy ExpandResult =
2325 tryExpandInstruction(Inst, IDLoc, Out, STI);
2326 switch (ExpandResult) {
2328 Out.emitInstruction(Inst, *STI);
2342 if (PrevForbiddenSlotAttr && !SetReorderAfterNop && !FillDelaySlot &&
2343 AssemblerOptions.
back()->isReorder()) {
2349 if (inMicroMipsMode()) {
2364 if (FillDelaySlot) {
2369 if ((Opcode == Mips::JalOneReg || Opcode == Mips::JalTwoReg ||
2371 isPicAndNotNxxAbi()) {
2372 if (IsCpRestoreSet) {
2376 if (!AssemblerOptions.
back()->isReorder())
2383 Warning(IDLoc,
"no .cprestore used in PIC mode");
2389void MipsAsmParser::onEndOfFile() {
2390 MipsTargetStreamer &TOut = getTargetStreamer();
2391 SMLoc IDLoc = SMLoc();
2393 if (CurForbiddenSlotAttr) {
2395 if (AssemblerOptions.
back()->isReorder())
2400MipsAsmParser::MacroExpanderResultTy
2401MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2402 const MCSubtargetInfo *STI) {
2405 return MER_NotAMacro;
2406 case Mips::LoadImm32:
2407 return expandLoadImm(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2408 case Mips::LoadImm64:
2409 return expandLoadImm(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2410 case Mips::LoadAddrImm32:
2411 case Mips::LoadAddrImm64:
2414 "expected immediate operand kind");
2416 return expandLoadAddress(
2418 Inst.
getOpcode() == Mips::LoadAddrImm32, IDLoc, Out, STI)
2421 case Mips::LoadAddrReg32:
2422 case Mips::LoadAddrReg64:
2426 "expected immediate operand kind");
2430 Inst.
getOpcode() == Mips::LoadAddrReg32, IDLoc,
2434 case Mips::B_MM_Pseudo:
2435 case Mips::B_MMR6_Pseudo:
2436 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2440 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2442 case Mips::JalOneReg:
2443 case Mips::JalTwoReg:
2444 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2447 case Mips::BEQLImmMacro:
2448 case Mips::BNELImmMacro:
2449 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2466 case Mips::BLTImmMacro:
2467 case Mips::BLEImmMacro:
2468 case Mips::BGEImmMacro:
2469 case Mips::BGTImmMacro:
2470 case Mips::BLTUImmMacro:
2471 case Mips::BLEUImmMacro:
2472 case Mips::BGEUImmMacro:
2473 case Mips::BGTUImmMacro:
2474 case Mips::BLTLImmMacro:
2475 case Mips::BLELImmMacro:
2476 case Mips::BGELImmMacro:
2477 case Mips::BGTLImmMacro:
2478 case Mips::BLTULImmMacro:
2479 case Mips::BLEULImmMacro:
2480 case Mips::BGEULImmMacro:
2481 case Mips::BGTULImmMacro:
2482 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2483 case Mips::SDivMacro:
2484 case Mips::SDivIMacro:
2485 case Mips::SRemMacro:
2486 case Mips::SRemIMacro:
2487 return expandDivRem(Inst, IDLoc, Out, STI,
false,
true) ? MER_Fail
2489 case Mips::DSDivMacro:
2490 case Mips::DSDivIMacro:
2491 case Mips::DSRemMacro:
2492 case Mips::DSRemIMacro:
2493 return expandDivRem(Inst, IDLoc, Out, STI,
true,
true) ? MER_Fail
2495 case Mips::UDivMacro:
2496 case Mips::UDivIMacro:
2497 case Mips::URemMacro:
2498 case Mips::URemIMacro:
2499 return expandDivRem(Inst, IDLoc, Out, STI,
false,
false) ? MER_Fail
2501 case Mips::DUDivMacro:
2502 case Mips::DUDivIMacro:
2503 case Mips::DURemMacro:
2504 case Mips::DURemIMacro:
2505 return expandDivRem(Inst, IDLoc, Out, STI,
true,
false) ? MER_Fail
2507 case Mips::PseudoTRUNC_W_S:
2508 return expandTrunc(Inst,
false,
false, IDLoc, Out, STI) ? MER_Fail
2510 case Mips::PseudoTRUNC_W_D32:
2511 return expandTrunc(Inst,
true,
false, IDLoc, Out, STI) ? MER_Fail
2513 case Mips::PseudoTRUNC_W_D:
2514 return expandTrunc(Inst,
true,
true, IDLoc, Out, STI) ? MER_Fail
2517 case Mips::LoadImmSingleGPR:
2518 return expandLoadSingleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2520 case Mips::LoadImmSingleFGR:
2521 return expandLoadSingleImmToFPR(Inst, IDLoc, Out, STI) ? MER_Fail
2523 case Mips::LoadImmDoubleGPR:
2524 return expandLoadDoubleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2526 case Mips::LoadImmDoubleFGR:
2527 return expandLoadDoubleImmToFPR(Inst,
true, IDLoc, Out, STI) ? MER_Fail
2529 case Mips::LoadImmDoubleFGR_32:
2530 return expandLoadDoubleImmToFPR(Inst,
false, IDLoc, Out, STI) ? MER_Fail
2534 return expandUlh(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2536 return expandUlh(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2538 return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2541 return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2543 case Mips::NORImm64:
2544 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2547 return expandSge(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2550 case Mips::SGEImm64:
2551 case Mips::SGEUImm64:
2552 return expandSgeImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2555 case Mips::SGTImm64:
2556 case Mips::SGTUImm64:
2557 return expandSgtImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2560 return expandSle(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2563 case Mips::SLEImm64:
2564 case Mips::SLEUImm64:
2565 return expandSleImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2566 case Mips::SLTImm64:
2569 return MER_NotAMacro;
2571 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2572 case Mips::SLTUImm64:
2575 return MER_NotAMacro;
2577 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2578 case Mips::ADDi:
case Mips::ADDi_MM:
2579 case Mips::ADDiu:
case Mips::ADDiu_MM:
2580 case Mips::SLTi:
case Mips::SLTi_MM:
2581 case Mips::SLTiu:
case Mips::SLTiu_MM:
2586 return MER_NotAMacro;
2587 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2590 return MER_NotAMacro;
2591 case Mips::ANDi:
case Mips::ANDi_MM:
case Mips::ANDi64:
2592 case Mips::ORi:
case Mips::ORi_MM:
case Mips::ORi64:
2593 case Mips::XORi:
case Mips::XORi_MM:
case Mips::XORi64:
2598 return MER_NotAMacro;
2599 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2602 return MER_NotAMacro;
2605 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2608 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2611 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2614 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2615 case Mips::ABSMacro:
2616 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2617 case Mips::MULImmMacro:
2618 case Mips::DMULImmMacro:
2619 return expandMulImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2620 case Mips::MULOMacro:
2621 case Mips::DMULOMacro:
2622 return expandMulO(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2623 case Mips::MULOUMacro:
2624 case Mips::DMULOUMacro:
2625 return expandMulOU(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2626 case Mips::DMULMacro:
2627 return expandDMULMacro(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2630 return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2635 return expandStoreDM1Macro(Inst, IDLoc, Out, STI)
2638 case Mips::SEQMacro:
2639 return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2640 case Mips::SEQIMacro:
2641 return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2642 case Mips::SNEMacro:
2643 return expandSne(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2644 case Mips::SNEIMacro:
2645 return expandSneI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2646 case Mips::MFTC0:
case Mips::MTTC0:
2647 case Mips::MFTGPR:
case Mips::MTTGPR:
2648 case Mips::MFTLO:
case Mips::MTTLO:
2649 case Mips::MFTHI:
case Mips::MTTHI:
2650 case Mips::MFTACX:
case Mips::MTTACX:
2651 case Mips::MFTDSP:
case Mips::MTTDSP:
2652 case Mips::MFTC1:
case Mips::MTTC1:
2653 case Mips::MFTHC1:
case Mips::MTTHC1:
2654 case Mips::CFTC1:
case Mips::CTTC1:
2655 return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2657 case Mips::SaadAddr:
2658 return expandSaaAddr(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2662bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2664 const MCSubtargetInfo *STI) {
2665 MipsTargetStreamer &TOut = getTargetStreamer();
2670 const MCOperand FirstRegOp = Inst.
getOperand(0);
2671 const unsigned Opcode = Inst.
getOpcode();
2673 if (Opcode == Mips::JalOneReg) {
2675 if (IsCpRestoreSet && inMicroMipsMode()) {
2678 }
else if (inMicroMipsMode()) {
2679 JalrInst.
setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2686 }
else if (Opcode == Mips::JalTwoReg) {
2688 if (IsCpRestoreSet && inMicroMipsMode())
2691 JalrInst.
setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2693 const MCOperand SecondRegOp = Inst.
getOperand(1);
2696 Out.emitInstruction(JalrInst, *STI);
2700 const MCInstrDesc &MCID = MII.get(JalrInst.
getOpcode());
2723bool MipsAsmParser::loadImmediate(int64_t ImmValue, MCRegister DstReg,
2724 MCRegister SrcReg,
bool Is32BitImm,
2725 bool IsAddress, SMLoc IDLoc, MCStreamer &Out,
2726 const MCSubtargetInfo *STI) {
2727 MipsTargetStreamer &TOut = getTargetStreamer();
2729 if (!Is32BitImm && !isGP64bit()) {
2730 Error(IDLoc,
"instruction requires a 64-bit architecture");
2741 Error(IDLoc,
"instruction requires a 32-bit immediate");
2746 MCRegister ZeroReg = IsAddress ?
ABI.GetNullPtr() :
ABI.GetZeroReg();
2747 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2749 bool UseSrcReg =
false;
2753 MCRegister TmpReg = DstReg;
2755 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2758 MCRegister ATReg = getATReg(IDLoc);
2771 if (IsAddress && !Is32BitImm) {
2772 TOut.
emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2776 TOut.
emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2781 MCRegister TmpReg = DstReg;
2782 if (SrcReg == DstReg) {
2783 TmpReg = getATReg(IDLoc);
2788 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2790 TOut.
emitRRR(
ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2795 warnIfNoMacro(IDLoc);
2797 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2798 uint16_t Bits15To0 = ImmValue & 0xffff;
2799 if (!Is32BitImm && !
isInt<32>(ImmValue)) {
2802 if (ImmValue == 0xffffffff) {
2803 TOut.
emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2804 TOut.
emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2806 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2812 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2813 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2815 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2817 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2821 TOut.
emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2823 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2825 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2831 Error(IDLoc,
"instruction requires a 32-bit immediate");
2838 assert(
BitWidth >= 17 &&
"ImmValue must be at least 17-bit wide");
2842 unsigned ShiftAmount =
BitWidth - 16;
2843 uint16_t
Bits = (ImmValue >> ShiftAmount) & 0xffff;
2844 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2845 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2848 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2853 warnIfNoMacro(IDLoc);
2860 if (loadImmediate(ImmValue >> 32, TmpReg, MCRegister(),
true,
false, IDLoc,
2866 unsigned ShiftCarriedForwards = 16;
2867 for (
int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2868 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2870 if (ImmChunk != 0) {
2871 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2872 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2873 ShiftCarriedForwards = 0;
2876 ShiftCarriedForwards += 16;
2878 ShiftCarriedForwards -= 16;
2881 if (ShiftCarriedForwards)
2882 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2885 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2890bool MipsAsmParser::expandLoadImm(MCInst &Inst,
bool Is32BitImm, SMLoc IDLoc,
2891 MCStreamer &Out,
const MCSubtargetInfo *STI) {
2893 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
2894 const MCOperand &DstRegOp = Inst.
getOperand(0);
2895 assert(DstRegOp.
isReg() &&
"expected register operand kind");
2897 if (loadImmediate(ImmOp.
getImm(), DstRegOp.
getReg(), MCRegister(), Is32BitImm,
2898 false, IDLoc, Out, STI))
2904bool MipsAsmParser::expandLoadAddress(MCRegister DstReg, MCRegister BaseReg,
2906 bool Is32BitAddress, SMLoc IDLoc,
2908 const MCSubtargetInfo *STI) {
2910 if (Is32BitAddress &&
ABI.ArePtrs64bit()) {
2911 Warning(IDLoc,
"la used to load 64-bit address");
2913 Is32BitAddress =
false;
2917 if (!Is32BitAddress && !hasMips3()) {
2918 Error(IDLoc,
"instruction requires a 64-bit architecture");
2923 return loadAndAddSymbolAddress(
Offset.getExpr(), DstReg, BaseReg,
2924 Is32BitAddress, IDLoc, Out, STI);
2926 if (!
ABI.ArePtrs64bit()) {
2928 Is32BitAddress =
true;
2931 return loadImmediate(
Offset.getImm(), DstReg, BaseReg, Is32BitAddress,
true,
2935bool MipsAsmParser::loadAndAddSymbolAddress(
const MCExpr *SymExpr,
2937 MCRegister SrcReg,
bool Is32BitSym,
2938 SMLoc IDLoc, MCStreamer &Out,
2939 const MCSubtargetInfo *STI) {
2940 MipsTargetStreamer &TOut = getTargetStreamer();
2942 SrcReg.
isValid() && SrcReg != Mips::R0 && SrcReg != Mips::R0_64;
2943 warnIfNoMacro(IDLoc);
2948 Error(IDLoc,
"expected relocatable expression");
2952 Error(IDLoc,
"expected relocatable expression with only one symbol");
2956 bool IsPtr64 =
ABI.ArePtrs64bit();
2959 ?
static_cast<const MCSymbolELF *
>(Res.
getAddSym())
2967 bool UseXGOT = STI->
hasFeature(Mips::FeatureXGOT) && !IsLocalSym;
2973 if ((DstReg ==
getABI().getTempReg(9,
false) ||
2974 DstReg ==
getABI().getTempReg(9,
true)) &&
2975 !UseSrcReg && Res.
getConstant() == 0 && !IsLocalSym) {
2977 const MCExpr *CallHiExpr =
2979 const MCExpr *CallLoExpr =
2983 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, DstReg, GPReg,
2985 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, DstReg,
2988 const MCExpr *CallExpr =
2990 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, GPReg,
2996 MCRegister TmpReg = DstReg;
2998 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
3002 MCRegister ATReg = getATReg(IDLoc);
3021 const MCExpr *CallHiExpr =
3028 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg, GPReg,
3030 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, TmpReg,
3034 TOut.
emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3040 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3045 const MCSpecifierExpr *GotExpr =
nullptr;
3046 const MCExpr *LoExpr =
nullptr;
3047 if (
ABI.IsN32() ||
ABI.IsN64()) {
3066 Error(IDLoc,
"macro instruction uses large offset, which is not "
3067 "currently supported");
3096 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, GPReg,
3100 TOut.
emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3104 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3110 const auto *HiExpr =
3112 const auto *LoExpr =
3116 if (
ABI.ArePtrs64bit() && isGP64bit()) {
3124 const auto *HighestExpr =
3126 const auto *HigherExpr =
3131 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
3133 if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
3134 MCRegister ATReg = getATReg(IDLoc);
3146 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3148 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3151 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3154 TOut.
emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
3157 }
else if (canUseATReg() && !RdRegIsRsReg && DstReg != getATReg(IDLoc)) {
3158 MCRegister ATReg = getATReg(IDLoc);
3174 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3178 TOut.
emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3179 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3181 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3184 }
else if ((!canUseATReg() && !RdRegIsRsReg) ||
3185 (canUseATReg() && DstReg == getATReg(IDLoc))) {
3196 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3198 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3199 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3201 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3202 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3205 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3211 assert(SrcReg == DstReg && !canUseATReg() &&
3212 "Could have expanded dla but didn't?");
3213 reportParseError(IDLoc,
3214 "pseudo-instruction requires $at, which is not available");
3228 MCRegister TmpReg = DstReg;
3230 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
3233 MCRegister ATReg = getATReg(IDLoc);
3244 TOut.
emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3247 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
3256 if (getMipsMCRegisterClass(Mips::FGR32RegClassID).
contains(
Reg))
3257 return Reg == (
unsigned)Mips::F31 ? (
unsigned)Mips::F0 :
Reg + 1;
3259 default:
llvm_unreachable(
"Unknown register in assembly macro expansion!");
3324 case Mips::D0:
return Mips::F1;
3325 case Mips::D1:
return Mips::F3;
3326 case Mips::D2:
return Mips::F5;
3327 case Mips::D3:
return Mips::F7;
3328 case Mips::D4:
return Mips::F9;
3329 case Mips::D5:
return Mips::F11;
3330 case Mips::D6:
return Mips::F13;
3331 case Mips::D7:
return Mips::F15;
3332 case Mips::D8:
return Mips::F17;
3333 case Mips::D9:
return Mips::F19;
3355bool MipsAsmParser::emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc,
3357 MCRegister ATReg = getATReg(IDLoc);
3363 const auto *GotExpr =
3366 if(isABI_O32() || isABI_N32()) {
3375 const auto *HiExpr =
3384 if(isABI_O32() || isABI_N32()) {
3388 const auto *HighestExpr =
3391 const auto *HigherExpr =
3396 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3398 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3401 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3410 if ((
Hi_32(ImmOp64) & 0x7ff00000) == 0) {
3421 float TmpFloat =
static_cast<float>(DoubleImm);
3425bool MipsAsmParser::expandLoadSingleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3427 const MCSubtargetInfo *STI) {
3430 "Invalid instruction operand.");
3437 return loadImmediate(ImmOp32, FirstReg, MCRegister(),
true,
false, IDLoc, Out,
3441bool MipsAsmParser::expandLoadSingleImmToFPR(MCInst &Inst, SMLoc IDLoc,
3443 const MCSubtargetInfo *STI) {
3444 MipsTargetStreamer &TOut = getTargetStreamer();
3447 "Invalid instruction operand.");
3456 MCRegister TmpReg = Mips::R0;
3458 TmpReg = getATReg(IDLoc);
3463 if (
Lo_32(ImmOp64) == 0) {
3464 if (TmpReg != Mips::R0 && loadImmediate(ImmOp32, TmpReg, MCRegister(),
true,
3465 false, IDLoc, Out, STI))
3467 TOut.
emitRR(Mips::MTC1, FirstReg, TmpReg, IDLoc, STI);
3471 MCSection *CS = getStreamer().getCurrentSectionOnly();
3474 MCSection *ReadOnlySection =
3481 getStreamer().switchSection(ReadOnlySection);
3482 getStreamer().emitLabel(Sym, IDLoc);
3483 getStreamer().emitInt32(ImmOp32);
3484 getStreamer().switchSection(CS);
3486 if (emitPartialAddress(TOut, IDLoc, Sym))
3493bool MipsAsmParser::expandLoadDoubleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3495 const MCSubtargetInfo *STI) {
3496 MipsTargetStreamer &TOut = getTargetStreamer();
3499 "Invalid instruction operand.");
3506 if (
Lo_32(ImmOp64) == 0) {
3508 if (loadImmediate(ImmOp64, FirstReg, MCRegister(),
false,
false, IDLoc,
3512 if (loadImmediate(
Hi_32(ImmOp64), FirstReg, MCRegister(),
true,
false,
3516 if (loadImmediate(0,
nextReg(FirstReg), MCRegister(),
true,
false, IDLoc,
3523 MCSection *CS = getStreamer().getCurrentSectionOnly();
3524 MCSection *ReadOnlySection =
3531 getStreamer().switchSection(ReadOnlySection);
3532 getStreamer().emitLabel(Sym, IDLoc);
3533 getStreamer().emitValueToAlignment(
Align(8));
3534 getStreamer().emitIntValue(ImmOp64, 8);
3535 getStreamer().switchSection(CS);
3537 MCRegister TmpReg = getATReg(IDLoc);
3541 if (emitPartialAddress(TOut, IDLoc, Sym))
3544 TOut.
emitRRX(isABI_N64() ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3548 TOut.
emitRRI(Mips::LD, FirstReg, TmpReg, 0, IDLoc, STI);
3550 TOut.
emitRRI(Mips::LW, FirstReg, TmpReg, 0, IDLoc, STI);
3551 TOut.
emitRRI(Mips::LW,
nextReg(FirstReg), TmpReg, 4, IDLoc, STI);
3556bool MipsAsmParser::expandLoadDoubleImmToFPR(MCInst &Inst,
bool Is64FPU,
3557 SMLoc IDLoc, MCStreamer &Out,
3558 const MCSubtargetInfo *STI) {
3559 MipsTargetStreamer &TOut = getTargetStreamer();
3562 "Invalid instruction operand.");
3569 MCRegister TmpReg = Mips::R0;
3571 TmpReg = getATReg(IDLoc);
3576 if ((
Lo_32(ImmOp64) == 0) &&
3577 !((
Hi_32(ImmOp64) & 0xffff0000) && (
Hi_32(ImmOp64) & 0x0000ffff))) {
3579 if (TmpReg != Mips::R0 && loadImmediate(ImmOp64, TmpReg, MCRegister(),
3580 false,
false, IDLoc, Out, STI))
3582 TOut.
emitRR(Mips::DMTC1, FirstReg, TmpReg, IDLoc, STI);
3586 if (TmpReg != Mips::R0 &&
3587 loadImmediate(
Hi_32(ImmOp64), TmpReg, MCRegister(),
true,
false, IDLoc,
3591 if (hasMips32r2()) {
3592 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::R0, IDLoc, STI);
3593 TOut.
emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, TmpReg, IDLoc, STI);
3595 TOut.
emitRR(Mips::MTC1,
nextReg(FirstReg), TmpReg, IDLoc, STI);
3596 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::R0, IDLoc, STI);
3601 MCSection *CS = getStreamer().getCurrentSectionOnly();
3604 MCSection *ReadOnlySection =
3611 getStreamer().switchSection(ReadOnlySection);
3612 getStreamer().emitLabel(Sym, IDLoc);
3613 getStreamer().emitValueToAlignment(
Align(8));
3614 getStreamer().emitIntValue(ImmOp64, 8);
3615 getStreamer().switchSection(CS);
3617 if (emitPartialAddress(TOut, IDLoc, Sym))
3620 TOut.
emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, TmpReg,
3626bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
3628 const MCSubtargetInfo *STI) {
3629 MipsTargetStreamer &TOut = getTargetStreamer();
3632 "unexpected number of operands");
3642 assert(
Offset.isImm() &&
"expected immediate operand kind");
3646 if (inMicroMipsMode())
3647 Inst.
setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3650 return Error(IDLoc,
"branch target out of range");
3652 return Error(IDLoc,
"branch to misaligned address");
3660 Out.emitInstruction(Inst, *STI);
3664 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
3671bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3672 const MCSubtargetInfo *STI) {
3673 MipsTargetStreamer &TOut = getTargetStreamer();
3674 const MCOperand &DstRegOp = Inst.
getOperand(0);
3675 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3678 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
3680 const MCOperand &MemOffsetOp = Inst.
getOperand(2);
3682 "expected immediate or expression operand");
3684 bool IsLikely =
false;
3694 case Mips::BEQLImmMacro:
3698 case Mips::BNELImmMacro:
3707 int64_t ImmValue = ImmOp.
getImm();
3708 if (ImmValue == 0) {
3712 TOut.
emitRRI(Mips::SLL, Mips::R0, Mips::R0, 0, IDLoc, STI);
3714 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), Mips::R0, MemOffsetOp, IDLoc,
3717 warnIfNoMacro(IDLoc);
3719 MCRegister ATReg = getATReg(IDLoc);
3723 if (loadImmediate(ImmValue, ATReg, MCRegister(), !isGP64bit(),
true, IDLoc,
3727 if (IsLikely && MemOffsetOp.
isExpr()) {
3730 TOut.
emitRRI(Mips::SLL, Mips::R0, Mips::R0, 0, IDLoc, STI);
3732 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3737void MipsAsmParser::expandMem16Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3738 const MCSubtargetInfo *STI,
bool IsLoad) {
3740 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3741 unsigned StartOp = NumOp == 3 ? 0 : 1;
3743 const MCOperand &DstRegOp = Inst.
getOperand(StartOp);
3744 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3745 const MCOperand &BaseRegOp = Inst.
getOperand(StartOp + 1);
3746 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3749 MipsTargetStreamer &TOut = getTargetStreamer();
3751 MCRegister DstReg = DstRegOp.
getReg();
3753 MCRegister TmpReg = DstReg;
3755 const MCInstrDesc &
Desc = MII.get(OpCode);
3756 int16_t DstRegClass =
3757 MII.getOpRegClassID(
Desc.operands()[StartOp],
3759 unsigned DstRegClassID =
3760 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3761 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3762 (DstRegClassID == Mips::GPR64RegClassID);
3764 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3767 TmpReg = getATReg(IDLoc);
3772 auto emitInstWithOffset = [&](
const MCOperand &
Off) {
3774 TOut.
emitRRX(OpCode, DstReg, TmpReg,
Off, IDLoc, STI);
3776 TOut.
emitRRRX(OpCode, DstReg, DstReg, TmpReg,
Off, IDLoc, STI);
3780 int64_t LoOffset =
OffsetOp.getImm() & 0xffff;
3781 int64_t HiOffset =
OffsetOp.getImm() & ~0xffff;
3785 if (LoOffset & 0x8000)
3786 HiOffset += 0x10000;
3788 bool IsLargeOffset = HiOffset != 0;
3790 if (IsLargeOffset) {
3792 if (loadImmediate(HiOffset, TmpReg, MCRegister(), Is32BitImm,
true, IDLoc,
3797 if (BaseReg != Mips::R0 && BaseReg != Mips::R0_64)
3798 TOut.
emitRRR(
ABI.ArePtrs64bit() ? Mips::DADDu : Mips::ADDu, TmpReg,
3799 TmpReg, BaseReg, IDLoc, STI);
3813 if (!
OffsetOp.getExpr()->evaluateAsRelocatable(Res,
nullptr)) {
3814 Error(IDLoc,
"expected relocatable expression");
3818 Error(IDLoc,
"expected relocatable expression with only one symbol");
3822 loadAndAddSymbolAddress(
3824 BaseReg, !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3832 const MCExpr *OffExpr =
OffsetOp.getExpr();
3844 TOut.
emitRX(Mips::LUi, TmpReg, HighestOperand, IDLoc, STI);
3845 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HigherOperand, IDLoc, STI);
3846 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3847 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HiOperand, IDLoc, STI);
3848 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3849 if (BaseReg != Mips::R0 && BaseReg != Mips::R0_64)
3850 TOut.
emitRRR(Mips::DADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3851 emitInstWithOffset(LoOperand);
3854 TOut.
emitRX(Mips::LUi, TmpReg, HiOperand, IDLoc, STI);
3855 if (BaseReg != Mips::R0)
3856 TOut.
emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3858 emitInstWithOffset(LoOperand);
3867void MipsAsmParser::expandMem9Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3868 const MCSubtargetInfo *STI,
bool IsLoad) {
3870 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3871 unsigned StartOp = NumOp == 3 ? 0 : 1;
3873 const MCOperand &DstRegOp = Inst.
getOperand(StartOp);
3874 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3875 const MCOperand &BaseRegOp = Inst.
getOperand(StartOp + 1);
3876 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3879 MipsTargetStreamer &TOut = getTargetStreamer();
3881 MCRegister DstReg = DstRegOp.
getReg();
3883 MCRegister TmpReg = DstReg;
3885 const MCInstrDesc &
Desc = MII.get(OpCode);
3886 int16_t DstRegClass =
3887 MII.getOpRegClassID(
Desc.operands()[StartOp],
3890 unsigned DstRegClassID =
3891 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3892 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3893 (DstRegClassID == Mips::GPR64RegClassID);
3895 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3898 TmpReg = getATReg(IDLoc);
3903 auto emitInst = [&]() {
3912 loadImmediate(
OffsetOp.getImm(), TmpReg, BaseReg, !
ABI.ArePtrs64bit(),
true,
3919 loadAndAddSymbolAddress(
OffsetOp.getExpr(), TmpReg, BaseReg,
3920 !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3928bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
3930 const MCSubtargetInfo *STI) {
3933 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3937 Inst.
getOperand(OpNum - 3).
isReg() &&
"Invalid instruction operand.");
3946 if (inMicroMipsMode() && hasMips32r6())
3947 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3949 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3953 Out.emitInstruction(Inst, *STI);
3957bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
3959 const MCSubtargetInfo *STI) {
3960 MipsTargetStreamer &TOut = getTargetStreamer();
3961 bool EmittedNoMacroWarning =
false;
3962 unsigned PseudoOpcode = Inst.
getOpcode();
3967 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3968 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3973 else if (TrgOp.
isImm()) {
3974 warnIfNoMacro(IDLoc);
3975 EmittedNoMacroWarning =
true;
3977 TrgReg = getATReg(IDLoc);
3981 switch(PseudoOpcode) {
3984 case Mips::BLTImmMacro:
3985 PseudoOpcode = Mips::BLT;
3987 case Mips::BLEImmMacro:
3988 PseudoOpcode = Mips::BLE;
3990 case Mips::BGEImmMacro:
3991 PseudoOpcode = Mips::BGE;
3993 case Mips::BGTImmMacro:
3994 PseudoOpcode = Mips::BGT;
3996 case Mips::BLTUImmMacro:
3997 PseudoOpcode = Mips::BLTU;
3999 case Mips::BLEUImmMacro:
4000 PseudoOpcode = Mips::BLEU;
4002 case Mips::BGEUImmMacro:
4003 PseudoOpcode = Mips::BGEU;
4005 case Mips::BGTUImmMacro:
4006 PseudoOpcode = Mips::BGTU;
4008 case Mips::BLTLImmMacro:
4009 PseudoOpcode = Mips::BLTL;
4011 case Mips::BLELImmMacro:
4012 PseudoOpcode = Mips::BLEL;
4014 case Mips::BGELImmMacro:
4015 PseudoOpcode = Mips::BGEL;
4017 case Mips::BGTLImmMacro:
4018 PseudoOpcode = Mips::BGTL;
4020 case Mips::BLTULImmMacro:
4021 PseudoOpcode = Mips::BLTUL;
4023 case Mips::BLEULImmMacro:
4024 PseudoOpcode = Mips::BLEUL;
4026 case Mips::BGEULImmMacro:
4027 PseudoOpcode = Mips::BGEUL;
4029 case Mips::BGTULImmMacro:
4030 PseudoOpcode = Mips::BGTUL;
4034 if (loadImmediate(TrgOp.
getImm(), TrgReg, MCRegister(), !isGP64bit(),
false,
4039 switch (PseudoOpcode) {
4044 AcceptsEquality =
false;
4045 ReverseOrderSLT =
false;
4047 ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
4048 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
4049 ZeroSrcOpcode = Mips::BGTZ;
4050 ZeroTrgOpcode = Mips::BLTZ;
4056 AcceptsEquality =
true;
4057 ReverseOrderSLT =
true;
4059 ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
4060 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
4061 ZeroSrcOpcode = Mips::BGEZ;
4062 ZeroTrgOpcode = Mips::BLEZ;
4068 AcceptsEquality =
true;
4069 ReverseOrderSLT =
false;
4071 ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
4072 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
4073 ZeroSrcOpcode = Mips::BLEZ;
4074 ZeroTrgOpcode = Mips::BGEZ;
4080 AcceptsEquality =
false;
4081 ReverseOrderSLT =
true;
4083 ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
4084 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
4085 ZeroSrcOpcode = Mips::BLTZ;
4086 ZeroTrgOpcode = Mips::BGTZ;
4092 bool IsTrgRegZero = (TrgReg == Mips::R0);
4093 bool IsSrcRegZero = (SrcReg == Mips::R0);
4094 if (IsSrcRegZero && IsTrgRegZero) {
4098 if (PseudoOpcode == Mips::BLT) {
4103 if (PseudoOpcode == Mips::BLE) {
4106 Warning(IDLoc,
"branch is always taken");
4109 if (PseudoOpcode == Mips::BGE) {
4112 Warning(IDLoc,
"branch is always taken");
4115 if (PseudoOpcode == Mips::BGT) {
4120 if (PseudoOpcode == Mips::BGTU) {
4121 TOut.
emitRRX(Mips::BNE, Mips::R0, Mips::R0,
4125 if (AcceptsEquality) {
4128 TOut.
emitRRX(Mips::BEQ, Mips::R0, Mips::R0,
4130 Warning(IDLoc,
"branch is always taken");
4137 if (IsSrcRegZero || IsTrgRegZero) {
4138 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
4139 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
4146 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
4147 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
4153 TOut.
emitRRX(Mips::BEQ, Mips::R0, Mips::R0,
4155 Warning(IDLoc,
"branch is always taken");
4171 TOut.
emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
4172 IsSrcRegZero ? TrgReg : SrcReg, Mips::R0,
4179 TOut.
emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
4180 IsSrcRegZero ? TrgReg : SrcReg,
4187 MCRegister ATRegNum = getATReg(IDLoc);
4191 if (!EmittedNoMacroWarning)
4192 warnIfNoMacro(IDLoc);
4209 TOut.
emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
4210 ReverseOrderSLT ? TrgReg : SrcReg,
4211 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
4213 TOut.
emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
4214 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
4228bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4229 const MCSubtargetInfo *STI,
4230 const bool IsMips64,
const bool Signed) {
4231 MipsTargetStreamer &TOut = getTargetStreamer();
4233 warnIfNoMacro(IDLoc);
4235 const MCOperand &RdRegOp = Inst.
getOperand(0);
4236 assert(RdRegOp.
isReg() &&
"expected register operand kind");
4237 MCRegister RdReg = RdRegOp.
getReg();
4239 const MCOperand &RsRegOp = Inst.
getOperand(1);
4240 assert(RsRegOp.
isReg() &&
"expected register operand kind");
4241 MCRegister RsReg = RsRegOp.
getReg();
4248 "expected register or immediate operand kind");
4252 ImmValue = RtOp.
getImm();
4259 DivOp =
Signed ? Mips::DSDIV : Mips::DUDIV;
4260 ZeroReg = Mips::R0_64;
4263 DivOp =
Signed ? Mips::SDIV : Mips::UDIV;
4268 bool UseTraps = useTraps();
4271 bool isDiv = Opcode == Mips::SDivMacro || Opcode == Mips::SDivIMacro ||
4272 Opcode == Mips::UDivMacro || Opcode == Mips::UDivIMacro ||
4273 Opcode == Mips::DSDivMacro || Opcode == Mips::DSDivIMacro ||
4274 Opcode == Mips::DUDivMacro || Opcode == Mips::DUDivIMacro;
4276 bool isRem = Opcode == Mips::SRemMacro || Opcode == Mips::SRemIMacro ||
4277 Opcode == Mips::URemMacro || Opcode == Mips::URemIMacro ||
4278 Opcode == Mips::DSRemMacro || Opcode == Mips::DSRemIMacro ||
4279 Opcode == Mips::DURemMacro || Opcode == Mips::DURemIMacro;
4282 MCRegister ATReg = getATReg(IDLoc);
4286 if (!CLOpts.mno_check_zero_division && ImmValue == 0) {
4288 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4290 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4294 if (isRem && (ImmValue == 1 || (
Signed && (ImmValue == -1)))) {
4295 TOut.
emitRRR(Mips::OR, RdReg, ZeroReg, ZeroReg, IDLoc, STI);
4297 }
else if (isDiv && ImmValue == 1) {
4298 TOut.
emitRRR(Mips::OR, RdReg, RsReg, Mips::R0, IDLoc, STI);
4300 }
else if (isDiv &&
Signed && ImmValue == -1) {
4301 TOut.
emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
4304 if (loadImmediate(ImmValue, ATReg, MCRegister(),
isInt<32>(ImmValue),
4305 false, Inst.
getLoc(), Out, STI))
4307 TOut.
emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
4308 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4318 if (!CLOpts.mno_check_zero_division &&
4319 (RtReg == Mips::R0 || RtReg == Mips::R0_64)) {
4321 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4324 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4330 if (isRem && (RdReg == Mips::R0 || RdReg == Mips::R0_64)) {
4331 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4340 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4341 if (!CLOpts.mno_check_zero_division) {
4343 TOut.
emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4346 BrTarget =
Context.createTempSymbol();
4349 TOut.
emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4354 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4360 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4364bool MipsAsmParser::expandTrunc(MCInst &Inst,
bool IsDouble,
bool Is64FPU,
4365 SMLoc IDLoc, MCStreamer &Out,
4366 const MCSubtargetInfo *STI) {
4367 MipsTargetStreamer &TOut = getTargetStreamer();
4377 if (hasMips1() && !hasMips2()) {
4378 MCRegister ATReg = getATReg(IDLoc);
4384 TOut.
emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4385 TOut.
emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4388 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4390 FirstReg, SecondReg, IDLoc, STI);
4396 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4398 FirstReg, SecondReg, IDLoc, STI);
4403bool MipsAsmParser::expandUlh(MCInst &Inst,
bool Signed, SMLoc IDLoc,
4404 MCStreamer &Out,
const MCSubtargetInfo *STI) {
4405 if (hasMips32r6() || hasMips64r6()) {
4406 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4409 const MCOperand &DstRegOp = Inst.
getOperand(0);
4410 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4411 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4412 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4413 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4414 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4416 MipsTargetStreamer &TOut = getTargetStreamer();
4417 MCRegister DstReg = DstRegOp.
getReg();
4418 MCRegister SrcReg = SrcRegOp.
getReg();
4419 int64_t OffsetValue = OffsetImmOp.
getImm();
4423 warnIfNoMacro(IDLoc);
4424 MCRegister ATReg = getATReg(IDLoc);
4429 if (IsLargeOffset) {
4430 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4435 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4436 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4440 MCRegister FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4441 MCRegister SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4443 MCRegister LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4444 MCRegister SllReg = IsLargeOffset ? DstReg : ATReg;
4446 TOut.
emitRRI(
Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4447 FirstOffset, IDLoc, STI);
4448 TOut.
emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4449 TOut.
emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4450 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4455bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4456 const MCSubtargetInfo *STI) {
4457 if (hasMips32r6() || hasMips64r6()) {
4458 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4461 const MCOperand &DstRegOp = Inst.
getOperand(0);
4462 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4463 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4464 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4465 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4466 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4468 MipsTargetStreamer &TOut = getTargetStreamer();
4469 MCRegister DstReg = DstRegOp.
getReg();
4470 MCRegister SrcReg = SrcRegOp.
getReg();
4471 int64_t OffsetValue = OffsetImmOp.
getImm();
4473 warnIfNoMacro(IDLoc);
4474 MCRegister ATReg = getATReg(IDLoc);
4479 if (IsLargeOffset) {
4480 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4485 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4486 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4490 if (IsLargeOffset) {
4491 TOut.
emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4492 TOut.
emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4493 TOut.
emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4494 TOut.
emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4495 TOut.
emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4496 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4498 TOut.
emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4499 TOut.
emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4500 TOut.
emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4506bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4507 const MCSubtargetInfo *STI) {
4508 if (hasMips32r6() || hasMips64r6()) {
4509 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4512 const MCOperand &DstRegOp = Inst.
getOperand(0);
4513 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4514 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4515 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4516 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4517 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4519 MipsTargetStreamer &TOut = getTargetStreamer();
4520 MCRegister DstReg = DstRegOp.
getReg();
4521 MCRegister SrcReg = SrcRegOp.
getReg();
4522 int64_t OffsetValue = OffsetImmOp.
getImm();
4526 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4527 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4531 bool IsLoadInst = (Inst.
getOpcode() == Mips::Ulw);
4532 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4533 MCRegister TmpReg = SrcReg;
4534 if (IsLargeOffset || DoMove) {
4535 warnIfNoMacro(IDLoc);
4536 TmpReg = getATReg(IDLoc);
4541 if (IsLargeOffset) {
4542 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4550 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4551 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4552 TOut.
emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4553 TOut.
emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4556 TOut.
emitRRR(Mips::OR, TmpReg, DstReg, Mips::R0, IDLoc, STI);
4561bool MipsAsmParser::expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4562 const MCSubtargetInfo *STI) {
4563 MipsTargetStreamer &TOut = getTargetStreamer();
4575 warnIfNoMacro(IDLoc);
4589 TOut.
emitRRR(OpCode, DstReg, SrcReg, OpReg, IDLoc, STI);
4590 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4595bool MipsAsmParser::expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4596 const MCSubtargetInfo *STI) {
4597 MipsTargetStreamer &TOut = getTargetStreamer();
4607 unsigned OpRegCode, OpImmCode;
4609 warnIfNoMacro(IDLoc);
4613 case Mips::SGEImm64:
4614 OpRegCode = Mips::SLT;
4615 OpImmCode = Mips::SLTi;
4618 case Mips::SGEUImm64:
4619 OpRegCode = Mips::SLTu;
4620 OpImmCode = Mips::SLTiu;
4629 TOut.
emitRRI(OpImmCode, DstReg, SrcReg, ImmValue, IDLoc, STI);
4630 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4632 MCRegister ImmReg = DstReg;
4633 if (DstReg == SrcReg) {
4634 MCRegister ATReg = getATReg(Inst.
getLoc());
4640 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
4641 false, IDLoc, Out, STI))
4644 TOut.
emitRRR(OpRegCode, DstReg, SrcReg, ImmReg, IDLoc, STI);
4645 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4651bool MipsAsmParser::expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4652 const MCSubtargetInfo *STI) {
4653 MipsTargetStreamer &TOut = getTargetStreamer();
4662 MCRegister ImmReg = DstReg;
4666 warnIfNoMacro(IDLoc);
4670 case Mips::SGTImm64:
4674 case Mips::SGTUImm64:
4681 if (DstReg == SrcReg) {
4682 MCRegister ATReg = getATReg(Inst.
getLoc());
4688 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
false,
4693 TOut.
emitRRR(OpCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4698bool MipsAsmParser::expandSle(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4699 const MCSubtargetInfo *STI) {
4700 MipsTargetStreamer &TOut = getTargetStreamer();
4712 warnIfNoMacro(IDLoc);
4726 TOut.
emitRRR(OpCode, DstReg, OpReg, SrcReg, IDLoc, STI);
4727 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4732bool MipsAsmParser::expandSleImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4733 const MCSubtargetInfo *STI) {
4734 MipsTargetStreamer &TOut = getTargetStreamer();
4746 warnIfNoMacro(IDLoc);
4750 case Mips::SLEImm64:
4751 OpRegCode = Mips::SLT;
4754 case Mips::SLEUImm64:
4755 OpRegCode = Mips::SLTu;
4762 MCRegister ImmReg = DstReg;
4763 if (DstReg == SrcReg) {
4764 MCRegister ATReg = getATReg(Inst.
getLoc());
4770 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
false,
4774 TOut.
emitRRR(OpRegCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4775 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4780bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
4782 const MCSubtargetInfo *STI) {
4783 MipsTargetStreamer &TOut = getTargetStreamer();
4791 MCRegister FinalDstReg;
4798 unsigned FinalOpcode = Inst.
getOpcode();
4800 if (DstReg == SrcReg) {
4801 ATReg = getATReg(Inst.
getLoc());
4804 FinalDstReg = DstReg;
4808 if (!loadImmediate(ImmValue, DstReg, MCRegister(), Is32Bit,
false,
4809 Inst.
getLoc(), Out, STI)) {
4810 switch (FinalOpcode) {
4814 FinalOpcode = Mips::ADD;
4817 FinalOpcode = Mips::ADDu;
4820 FinalOpcode = Mips::AND;
4823 FinalOpcode = Mips::NOR;
4826 FinalOpcode = Mips::OR;
4829 FinalOpcode = Mips::SLT;
4832 FinalOpcode = Mips::SLTu;
4835 FinalOpcode = Mips::XOR;
4838 FinalOpcode = Mips::ADD_MM;
4840 case Mips::ADDiu_MM:
4841 FinalOpcode = Mips::ADDu_MM;
4844 FinalOpcode = Mips::AND_MM;
4847 FinalOpcode = Mips::OR_MM;
4850 FinalOpcode = Mips::SLT_MM;
4852 case Mips::SLTiu_MM:
4853 FinalOpcode = Mips::SLTu_MM;
4856 FinalOpcode = Mips::XOR_MM;
4859 FinalOpcode = Mips::AND64;
4861 case Mips::NORImm64:
4862 FinalOpcode = Mips::NOR64;
4865 FinalOpcode = Mips::OR64;
4867 case Mips::SLTImm64:
4868 FinalOpcode = Mips::SLT64;
4870 case Mips::SLTUImm64:
4871 FinalOpcode = Mips::SLTu64;
4874 FinalOpcode = Mips::XOR64;
4879 TOut.
emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4881 TOut.
emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4887bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4888 const MCSubtargetInfo *STI) {
4889 MipsTargetStreamer &TOut = getTargetStreamer();
4894 MCRegister TmpReg =
DReg;
4896 unsigned FirstShift = Mips::NOP;
4897 unsigned SecondShift = Mips::NOP;
4899 if (hasMips32r2()) {
4901 TmpReg = getATReg(Inst.
getLoc());
4907 TOut.
emitRRR(Mips::SUBu, TmpReg, Mips::R0, TReg, Inst.
getLoc(), STI);
4908 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
4913 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
4925 FirstShift = Mips::SRLV;
4926 SecondShift = Mips::SLLV;
4929 FirstShift = Mips::SLLV;
4930 SecondShift = Mips::SRLV;
4934 ATReg = getATReg(Inst.
getLoc());
4938 TOut.
emitRRR(Mips::SUBu, ATReg, Mips::R0, TReg, Inst.
getLoc(), STI);
4939 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
4940 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
4941 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
4949bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
4951 const MCSubtargetInfo *STI) {
4952 MipsTargetStreamer &TOut = getTargetStreamer();
4958 unsigned FirstShift = Mips::NOP;
4959 unsigned SecondShift = Mips::NOP;
4961 if (hasMips32r2()) {
4966 ShiftValue = MaxShift - ImmValue;
4967 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
4972 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.
getLoc(), STI);
4980 if (ImmValue == 0) {
4989 FirstShift = Mips::SLL;
4990 SecondShift = Mips::SRL;
4993 FirstShift = Mips::SRL;
4994 SecondShift = Mips::SLL;
4998 ATReg = getATReg(Inst.
getLoc());
5002 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.
getLoc(), STI);
5003 TOut.
emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.
getLoc(), STI);
5004 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5012bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5013 const MCSubtargetInfo *STI) {
5014 MipsTargetStreamer &TOut = getTargetStreamer();
5019 MCRegister TmpReg =
DReg;
5021 unsigned FirstShift = Mips::NOP;
5022 unsigned SecondShift = Mips::NOP;
5024 if (hasMips64r2()) {
5025 if (TmpReg == SReg) {
5026 TmpReg = getATReg(Inst.
getLoc());
5032 TOut.
emitRRR(Mips::DSUBu, TmpReg, Mips::R0, TReg, Inst.
getLoc(), STI);
5033 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
5038 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
5050 FirstShift = Mips::DSRLV;
5051 SecondShift = Mips::DSLLV;
5054 FirstShift = Mips::DSLLV;
5055 SecondShift = Mips::DSRLV;
5059 ATReg = getATReg(Inst.
getLoc());
5063 TOut.
emitRRR(Mips::DSUBu, ATReg, Mips::R0, TReg, Inst.
getLoc(), STI);
5064 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
5065 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
5066 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5074bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
5076 const MCSubtargetInfo *STI) {
5077 MipsTargetStreamer &TOut = getTargetStreamer();
5083 unsigned FirstShift = Mips::NOP;
5084 unsigned SecondShift = Mips::NOP;
5088 if (hasMips64r2()) {
5089 unsigned FinalOpcode = Mips::NOP;
5091 FinalOpcode = Mips::DROTR;
5092 else if (ImmValue % 32 == 0)
5093 FinalOpcode = Mips::DROTR32;
5094 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
5096 FinalOpcode = Mips::DROTR32;
5098 FinalOpcode = Mips::DROTR;
5099 }
else if (ImmValue >= 33) {
5101 FinalOpcode = Mips::DROTR;
5103 FinalOpcode = Mips::DROTR32;
5106 uint64_t ShiftValue = ImmValue % 32;
5108 ShiftValue = (32 - ImmValue % 32) % 32;
5110 TOut.
emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
5116 if (ImmValue == 0) {
5117 TOut.
emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.
getLoc(), STI);
5125 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5126 FirstShift = Mips::DSLL;
5127 SecondShift = Mips::DSRL32;
5129 if (ImmValue == 32) {
5130 FirstShift = Mips::DSLL32;
5131 SecondShift = Mips::DSRL32;
5133 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5134 FirstShift = Mips::DSLL32;
5135 SecondShift = Mips::DSRL;
5139 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5140 FirstShift = Mips::DSRL;
5141 SecondShift = Mips::DSLL32;
5143 if (ImmValue == 32) {
5144 FirstShift = Mips::DSRL32;
5145 SecondShift = Mips::DSLL32;
5147 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5148 FirstShift = Mips::DSRL32;
5149 SecondShift = Mips::DSLL;
5154 ATReg = getATReg(Inst.
getLoc());
5158 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.
getLoc(), STI);
5159 TOut.
emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
5161 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5169bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5170 const MCSubtargetInfo *STI) {
5171 MipsTargetStreamer &TOut = getTargetStreamer();
5175 TOut.
emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
5176 if (FirstRegOp != SecondRegOp)
5177 TOut.
emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::R0, IDLoc, STI);
5180 TOut.
emitRRR(Mips::SUB, FirstRegOp, Mips::R0, SecondRegOp, IDLoc, STI);
5185bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5186 const MCSubtargetInfo *STI) {
5187 MipsTargetStreamer &TOut = getTargetStreamer();
5193 ATReg = getATReg(IDLoc);
5197 loadImmediate(ImmValue, ATReg, MCRegister(),
true,
false, IDLoc, Out, STI);
5199 TOut.
emitRR(Inst.
getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
5200 SrcReg, ATReg, IDLoc, STI);
5202 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5207bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5208 const MCSubtargetInfo *STI) {
5209 MipsTargetStreamer &TOut = getTargetStreamer();
5215 ATReg = getATReg(Inst.
getLoc());
5219 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
5220 SrcReg, TmpReg, IDLoc, STI);
5222 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5224 TOut.
emitRRI(Inst.
getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
5225 DstReg, DstReg, 0x1F, IDLoc, STI);
5227 TOut.
emitR(Mips::MFHI, ATReg, IDLoc, STI);
5230 TOut.
emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
5237 TOut.
emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
5238 if (AssemblerOptions.
back()->isReorder())
5240 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5244 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5249bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5250 const MCSubtargetInfo *STI) {
5251 MipsTargetStreamer &TOut = getTargetStreamer();
5257 ATReg = getATReg(IDLoc);
5261 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
5262 SrcReg, TmpReg, IDLoc, STI);
5264 TOut.
emitR(Mips::MFHI, ATReg, IDLoc, STI);
5265 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5267 TOut.
emitRRI(Mips::TNE, ATReg, Mips::R0, 6, IDLoc, STI);
5274 TOut.
emitRRX(Mips::BEQ, ATReg, Mips::R0, LabelOp, IDLoc, STI);
5275 if (AssemblerOptions.
back()->isReorder())
5277 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5285bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5286 const MCSubtargetInfo *STI) {
5287 MipsTargetStreamer &TOut = getTargetStreamer();
5292 TOut.
emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
5293 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5303bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
5305 const MCSubtargetInfo *STI,
5310 warnIfNoMacro(IDLoc);
5312 MipsTargetStreamer &TOut = getTargetStreamer();
5313 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
5315 MCRegister SecondReg =
nextReg(FirstReg);
5320 warnIfRegIndexIsAT(FirstReg, IDLoc);
5323 "Offset for load macro is not immediate!");
5326 signed NextOffset = FirstOffset.
getImm() + 4;
5334 if (FirstReg != BaseReg || !IsLoad) {
5335 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5336 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5338 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5339 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5351bool MipsAsmParser::expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc,
5353 const MCSubtargetInfo *STI) {
5357 warnIfNoMacro(IDLoc);
5359 MipsTargetStreamer &TOut = getTargetStreamer();
5360 unsigned Opcode = Mips::SWC1;
5362 MCRegister SecondReg =
nextReg(FirstReg);
5367 warnIfRegIndexIsAT(FirstReg, IDLoc);
5370 "Offset for macro is not immediate!");
5373 signed NextOffset = FirstOffset.
getImm() + 4;
5379 if (!IsLittleEndian)
5382 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5383 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5388bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5389 const MCSubtargetInfo *STI) {
5390 MipsTargetStreamer &TOut = getTargetStreamer();
5401 warnIfNoMacro(IDLoc);
5403 if (SrcReg != Mips::R0 && OpReg != Mips::R0) {
5404 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5405 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5409 MCRegister
Reg = SrcReg == Mips::R0 ? OpReg : SrcReg;
5410 TOut.
emitRRI(Mips::SLTiu, DstReg,
Reg, 1, IDLoc, STI);
5414bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5415 const MCSubtargetInfo *STI) {
5416 MipsTargetStreamer &TOut = getTargetStreamer();
5427 warnIfNoMacro(IDLoc);
5430 TOut.
emitRRI(Mips::SLTiu, DstReg, SrcReg, 1, IDLoc, STI);
5434 if (SrcReg == Mips::R0) {
5435 Warning(IDLoc,
"comparison is always false");
5436 TOut.
emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
5437 DstReg, SrcReg, SrcReg, IDLoc, STI);
5442 if (
Imm > -0x8000 &&
Imm < 0) {
5444 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5450 MCRegister ATReg = getATReg(IDLoc);
5454 if (loadImmediate(
Imm, ATReg, MCRegister(),
true, isGP64bit(), IDLoc, Out,
5458 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5459 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5464 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5468bool MipsAsmParser::expandSne(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5469 const MCSubtargetInfo *STI) {
5471 MipsTargetStreamer &TOut = getTargetStreamer();
5482 warnIfNoMacro(IDLoc);
5484 if (SrcReg != Mips::R0 && OpReg != Mips::R0) {
5485 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5486 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::R0, DstReg, IDLoc, STI);
5490 MCRegister
Reg = SrcReg == Mips::R0 ? OpReg : SrcReg;
5491 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::R0,
Reg, IDLoc, STI);
5495bool MipsAsmParser::expandSneI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5496 const MCSubtargetInfo *STI) {
5497 MipsTargetStreamer &TOut = getTargetStreamer();
5508 warnIfNoMacro(IDLoc);
5510 if (ImmValue == 0) {
5511 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::R0, SrcReg, IDLoc, STI);
5515 if (SrcReg == Mips::R0) {
5516 Warning(IDLoc,
"comparison is always true");
5517 if (loadImmediate(1, DstReg, MCRegister(),
true,
false, IDLoc, Out, STI))
5523 if (ImmValue > -0x8000 && ImmValue < 0) {
5524 ImmValue = -ImmValue;
5525 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5531 TOut.
emitRRI(
Opc, DstReg, SrcReg, ImmValue, IDLoc, STI);
5532 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::R0, DstReg, IDLoc, STI);
5536 MCRegister ATReg = getATReg(IDLoc);
5540 if (loadImmediate(ImmValue, ATReg, MCRegister(),
isInt<32>(ImmValue),
false,
5544 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5545 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::R0, DstReg, IDLoc, STI);
5751bool MipsAsmParser::expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5752 const MCSubtargetInfo *STI) {
5753 MipsTargetStreamer &TOut = getTargetStreamer();
5758 bool IsMFTR =
false;
5812 IsMFTR ? MCRegister(rd)
5814 : Inst.getOperand(0).
getReg());
5816 TOut.
emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, u, sel, h, IDLoc,
5821bool MipsAsmParser::expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5822 const MCSubtargetInfo *STI) {
5827 warnIfNoMacro(IDLoc);
5829 MipsTargetStreamer &TOut = getTargetStreamer();
5830 unsigned Opcode = Inst.
getOpcode() == Mips::SaaAddr ? Mips::SAA : Mips::SAAD;
5833 const MCOperand &BaseOp = Inst.
getOperand(2);
5835 if (BaseOp.
isImm()) {
5836 int64_t ImmValue = BaseOp.
getImm();
5837 if (ImmValue == 0) {
5838 TOut.
emitRR(Opcode, RtReg, BaseReg, IDLoc, STI);
5843 MCRegister ATReg = getATReg(IDLoc);
5847 if (expandLoadAddress(ATReg, BaseReg, BaseOp, !isGP64bit(), IDLoc, Out, STI))
5850 TOut.
emitRR(Opcode, RtReg, ATReg, IDLoc, STI);
5855MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
5859 return Match_Success;
5862 if (
static_cast<MipsOperand &
>(*
Operands[1])
5863 .isValidForTie(
static_cast<MipsOperand &
>(*
Operands[2])))
5864 return Match_Success;
5865 return Match_RequiresSameSrcAndDst;
5869unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
5876 return Match_RequiresNoZeroRegister;
5877 return Match_Success;
5883 case Mips::JALR_HB64:
5884 case Mips::JALRC_HB_MMR6:
5885 case Mips::JALRC_MMR6:
5887 return Match_RequiresDifferentSrcAndDst;
5888 return Match_Success;
5891 return Match_RequiresDifferentSrcAndDst;
5892 return Match_Success;
5895 return Match_NonZeroOperandForSync;
5896 return Match_Success;
5902 return Match_NonZeroOperandForMTCX;
5903 return Match_Success;
5916 case Mips::BLEZC:
case Mips::BLEZC_MMR6:
5917 case Mips::BGEZC:
case Mips::BGEZC_MMR6:
5918 case Mips::BGTZC:
case Mips::BGTZC_MMR6:
5919 case Mips::BLTZC:
case Mips::BLTZC_MMR6:
5920 case Mips::BEQZC:
case Mips::BEQZC_MMR6:
5921 case Mips::BNEZC:
case Mips::BNEZC_MMR6:
5930 return Match_RequiresNoZeroRegister;
5931 return Match_Success;
5932 case Mips::BGEC:
case Mips::BGEC_MMR6:
5933 case Mips::BLTC:
case Mips::BLTC_MMR6:
5934 case Mips::BGEUC:
case Mips::BGEUC_MMR6:
5935 case Mips::BLTUC:
case Mips::BLTUC_MMR6:
5936 case Mips::BEQC:
case Mips::BEQC_MMR6:
5937 case Mips::BNEC:
case Mips::BNEC_MMR6:
5946 return Match_RequiresNoZeroRegister;
5949 return Match_RequiresNoZeroRegister;
5951 return Match_RequiresDifferentOperands;
5952 return Match_Success;
5955 "Operands must be immediates for dins!");
5958 if ((0 > (Pos +
Size)) || ((Pos +
Size) > 32))
5959 return Match_RequiresPosSizeRange0_32;
5960 return Match_Success;
5965 "Operands must be immediates for dinsm/dinsu!");
5968 if ((32 >= (Pos +
Size)) || ((Pos +
Size) > 64))
5969 return Match_RequiresPosSizeRange33_64;
5970 return Match_Success;
5974 "Operands must be immediates for DEXTM!");
5977 if ((1 > (Pos +
Size)) || ((Pos +
Size) > 63))
5978 return Match_RequiresPosSizeUImm6;
5979 return Match_Success;
5984 "Operands must be immediates for dextm/dextu!");
5987 if ((32 > (Pos +
Size)) || ((Pos +
Size) > 64))
5988 return Match_RequiresPosSizeRange33_64;
5989 return Match_Success;
5991 case Mips::CRC32B:
case Mips::CRC32CB:
5992 case Mips::CRC32H:
case Mips::CRC32CH:
5993 case Mips::CRC32W:
case Mips::CRC32CW:
5994 case Mips::CRC32D:
case Mips::CRC32CD:
5996 return Match_RequiresSameSrcAndDst;
5997 return Match_Success;
6003 return Match_NoFCCRegisterForCurrentISA;
6005 return Match_Success;
6013 if (ErrorLoc ==
SMLoc())
6020bool MipsAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
6024 bool MatchingInlineAsm) {
6026 unsigned MatchResult =
6027 MatchInstructionImpl(
Operands, Inst, ErrorInfo, MatchingInlineAsm);
6029 switch (MatchResult) {
6031 if (processInstruction(Inst, IDLoc, Out, STI))
6034 case Match_MissingFeature:
6035 Error(IDLoc,
"instruction requires a CPU feature not currently enabled");
6037 case Match_InvalidTiedOperand:
6038 Error(IDLoc,
"operand must match destination register");
6040 case Match_InvalidOperand: {
6041 SMLoc ErrorLoc = IDLoc;
6042 if (ErrorInfo != ~0ULL) {
6044 return Error(IDLoc,
"too few operands for instruction");
6046 ErrorLoc =
Operands[ErrorInfo]->getStartLoc();
6047 if (ErrorLoc == SMLoc())
6051 return Error(ErrorLoc,
"invalid operand for instruction");
6053 case Match_NonZeroOperandForSync:
6055 "s-type must be zero or unspecified for pre-MIPS32 ISAs");
6056 case Match_NonZeroOperandForMTCX:
6057 return Error(IDLoc,
"selector must be zero for pre-MIPS32 ISAs");
6058 case Match_MnemonicFail:
6059 return Error(IDLoc,
"invalid instruction");
6060 case Match_RequiresDifferentSrcAndDst:
6061 return Error(IDLoc,
"source and destination must be different");
6062 case Match_RequiresDifferentOperands:
6063 return Error(IDLoc,
"registers must be different");
6064 case Match_RequiresNoZeroRegister:
6065 return Error(IDLoc,
"invalid operand ($zero) for instruction");
6066 case Match_RequiresSameSrcAndDst:
6067 return Error(IDLoc,
"source and destination must match");
6068 case Match_NoFCCRegisterForCurrentISA:
6070 "non-zero fcc register doesn't exist in current ISA level");
6075 "expected 1-bit unsigned immediate");
6078 "expected 2-bit unsigned immediate");
6081 "expected immediate in range 1 .. 4");
6084 "expected 3-bit unsigned immediate");
6087 "expected 4-bit unsigned immediate");
6090 "expected 4-bit signed immediate");
6093 "expected 5-bit unsigned immediate");
6096 "expected 5-bit signed immediate");
6099 "expected immediate in range 1 .. 32");
6100 case Match_UImm5_32:
6102 "expected immediate in range 32 .. 63");
6103 case Match_UImm5_33:
6105 "expected immediate in range 33 .. 64");
6106 case Match_UImm5_0_Report_UImm6:
6110 "expected 6-bit unsigned immediate");
6111 case Match_UImm5_Lsl2:
6113 "expected both 7-bit unsigned immediate and multiple of 4");
6114 case Match_UImmRange2_64:
6116 "expected immediate in range 2 .. 64");
6119 "expected 6-bit unsigned immediate");
6120 case Match_UImm6_Lsl2:
6122 "expected both 8-bit unsigned immediate and multiple of 4");
6125 "expected 6-bit signed immediate");
6128 "expected 7-bit unsigned immediate");
6129 case Match_UImm7_N1:
6131 "expected immediate in range -1 .. 126");
6132 case Match_SImm7_Lsl2:
6134 "expected both 9-bit signed immediate and multiple of 4");
6137 "expected 8-bit unsigned immediate");
6138 case Match_UImm10_0:
6140 "expected 10-bit unsigned immediate");
6141 case Match_SImm10_0:
6143 "expected 10-bit signed immediate");
6144 case Match_SImm11_0:
6146 "expected 11-bit signed immediate");
6148 case Match_UImm16_Relaxed:
6149 case Match_UImm16_AltRelaxed:
6151 "expected 16-bit unsigned immediate");
6153 case Match_SImm16_Relaxed:
6155 "expected 16-bit signed immediate");
6156 case Match_SImm18_Lsl3:
6158 "expected both 18-bit signed immediate and multiple of 8");
6159 case Match_SImm19_Lsl2:
6161 "expected both 19-bit signed immediate and multiple of 4");
6162 case Match_UImm20_0:
6164 "expected 20-bit unsigned immediate");
6165 case Match_UImm26_0:
6167 "expected 26-bit unsigned immediate");
6169 case Match_SImm32_Relaxed:
6171 "expected 32-bit signed immediate");
6172 case Match_UImm32_Coerced:
6174 "expected 32-bit immediate");
6175 case Match_MemSImm9:
6177 "expected memory with 9-bit signed offset");
6178 case Match_MemSImm10:
6180 "expected memory with 10-bit signed offset");
6181 case Match_MemSImm10Lsl1:
6183 "expected memory with 11-bit signed offset and multiple of 2");
6184 case Match_MemSImm10Lsl2:
6186 "expected memory with 12-bit signed offset and multiple of 4");
6187 case Match_MemSImm10Lsl3:
6189 "expected memory with 13-bit signed offset and multiple of 8");
6190 case Match_MemSImm11:
6192 "expected memory with 11-bit signed offset");
6193 case Match_MemSImm12:
6195 "expected memory with 12-bit signed offset");
6196 case Match_MemSImm16:
6198 "expected memory with 16-bit signed offset");
6199 case Match_MemSImmPtr:
6201 "expected memory with 32-bit signed offset");
6202 case Match_RequiresPosSizeRange0_32: {
6203 SMLoc ErrorStart =
Operands[3]->getStartLoc();
6204 SMLoc ErrorEnd =
Operands[4]->getEndLoc();
6205 return Error(ErrorStart,
"size plus position are not in the range 0 .. 32",
6206 SMRange(ErrorStart, ErrorEnd));
6208 case Match_RequiresPosSizeUImm6: {
6209 SMLoc ErrorStart =
Operands[3]->getStartLoc();
6210 SMLoc ErrorEnd =
Operands[4]->getEndLoc();
6211 return Error(ErrorStart,
"size plus position are not in the range 1 .. 63",
6212 SMRange(ErrorStart, ErrorEnd));
6214 case Match_RequiresPosSizeRange33_64: {
6215 SMLoc ErrorStart =
Operands[3]->getStartLoc();
6216 SMLoc ErrorEnd =
Operands[4]->getEndLoc();
6217 return Error(ErrorStart,
"size plus position are not in the range 33 .. 64",
6218 SMRange(ErrorStart, ErrorEnd));
6225void MipsAsmParser::warnIfRegIndexIsAT(MCRegister RegIndex, SMLoc Loc) {
6226 if (RegIndex && AssemblerOptions.
back()->getATRegIndex() == RegIndex)
6227 Warning(Loc,
"used $at (currently $" + Twine(RegIndex.
id()) +
6228 ") without \".set noat\"");
6231void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
6232 if (!AssemblerOptions.
back()->isMacro())
6233 Warning(Loc,
"macro instruction expanded into multiple instructions");
6236void MipsAsmParser::ConvertXWPOperands(MCInst &Inst,
6240 "Unexpected instruction!");
6241 ((MipsOperand &)*
Operands[1]).addGPR32ZeroAsmRegOperands(Inst, 1);
6242 MCRegister NextReg =
nextReg(((MipsOperand &)*
Operands[1]).getGPR32Reg());
6244 ((MipsOperand &)*
Operands[2]).addMemOperands(Inst, 2);
6248MipsAsmParser::printWarningWithFixIt(
const Twine &
Msg,
const Twine &FixMsg,
6249 SMRange
Range,
bool ShowColors) {
6255int MipsAsmParser::matchCPURegisterName(StringRef Name) {
6256 const MCRegisterInfo &MRI = *
getContext().getRegisterInfo();
6262 AsmToken RegTok = getLexer().peekTok();
6263 StringRef FixedName =
6265 printWarningWithFixIt(
"register names $t4-$t7 are only available in O32.",
6266 "Did you mean $" + FixedName +
"?",
6272int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
6273 const MCRegisterInfo &MRI = *
getContext().getRegisterInfo();
6275 Mips::RegAliasName);
6279int MipsAsmParser::matchFPURegisterName(StringRef Name) {
6280 if (Name[0] ==
'f') {
6281 StringRef NumString =
Name.substr(1);
6292int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
6293 if (
Name.starts_with(
"fcc")) {
6294 StringRef NumString =
Name.substr(3);
6305int MipsAsmParser::matchACRegisterName(StringRef Name) {
6306 if (
Name.starts_with(
"ac")) {
6307 StringRef NumString =
Name.substr(2);
6318int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
6321 if (
Name.front() !=
'w' ||
Name.drop_front(1).getAsInteger(10, IntVal))
6330int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
6331 const MCRegisterInfo &MRI = *
getContext().getRegisterInfo();
6333 Name, MRI, Mips::MSACtrlRegClassID, Mips::RegAliasName);
6337bool MipsAsmParser::canUseATReg() {
6338 return AssemblerOptions.
back()->getATRegIndex() != 0;
6341MCRegister MipsAsmParser::getATReg(SMLoc Loc) {
6342 unsigned ATIndex = AssemblerOptions.
back()->getATRegIndex();
6344 reportParseError(Loc,
6345 "pseudo-instruction requires $at, which is not available");
6349 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
6353MCRegister MipsAsmParser::getReg(
int RC,
int RegNo) {
6354 return getContext().getRegisterInfo()->getRegClass(RC).getRegister(RegNo);
6360const MCExpr *MipsAsmParser::parseRelocExpr() {
6361 auto getOp = [](StringRef
Op) {
6362 return StringSwitch<Mips::Specifier>(
Op)
6390 MCAsmParser &Parser = getParser();
6392 const MCExpr *Res =
nullptr;
6398 auto Op = getOp(Name);
6407 while (
Ops.size()) {
6416 MCAsmParser &Parser = getParser();
6426 ParseStatus Res = MatchOperandParserImpl(
Operands, Mnemonic,
true);
6437 switch (getLexer().getKind()) {
6447 if (!parseAnyRegister(
Operands).isNoMatch())
6460 Operands.push_back(MipsOperand::CreateImm(SymRef, S,
E, *
this));
6465 const MCExpr *Expr = parseRelocExpr();
6469 Operands.push_back(MipsOperand::CreateImm(Expr, S,
E, *
this));
6476bool MipsAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
6478 return !tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess();
6481ParseStatus MipsAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
6484 ParseStatus Res = parseAnyRegister(
Operands);
6487 MipsOperand &Operand =
static_cast<MipsOperand &
>(*
Operands.front());
6488 StartLoc = Operand.getStartLoc();
6489 EndLoc = Operand.getEndLoc();
6495 if (Operand.isGPRAsmReg()) {
6497 Reg = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
6508 MCAsmParser &Parser = getParser();
6510 const MCExpr *IdVal =
nullptr;
6512 bool isParenExpr =
false;
6523 IdVal = parseRelocExpr();
6529 const AsmToken &Tok = Parser.
getTok();
6531 MipsOperand &Mnemonic =
static_cast<MipsOperand &
>(*
Operands[0]);
6532 if (Mnemonic.getToken() ==
"la" || Mnemonic.getToken() ==
"dla") {
6535 Operands.push_back(MipsOperand::CreateImm(IdVal, S,
E, *
this));
6544 auto Base = MipsOperand::createGPRReg(
6545 0,
"0",
getContext().getRegisterInfo(), S,
E, *
this);
6547 MipsOperand::CreateMem(std::move(
Base), IdVal, S,
E, *
this));
6599 const MCExpr * NextExpr;
6600 if (getParser().parseExpression(NextExpr))
6623 std::unique_ptr<MipsOperand>
op(
6624 static_cast<MipsOperand *
>(
Operands.back().release()));
6631 if (IdVal->evaluateAsAbsolute(
Imm))
6638 Operands.push_back(MipsOperand::CreateMem(std::move(
op), IdVal, S,
E, *
this));
6643 MCAsmParser &Parser = getParser();
6652 const MCSymbolRefExpr *
Ref =
static_cast<const MCSymbolRefExpr *
>(Expr);
6653 StringRef DefSymbol =
Ref->getSymbol().getName();
6656 matchAnyRegisterNameWithoutDollar(
Operands, DefSymbol.
substr(1), S);
6670 if (Entry != RegisterSets.
end()) {
6672 matchAnyRegisterWithoutDollar(
Operands,
Entry->getValue(), S);
6683ParseStatus MipsAsmParser::matchAnyRegisterNameWithoutDollar(
6685 int Index = matchCPURegisterName(Identifier);
6687 Operands.push_back(MipsOperand::createGPRReg(
6688 Index, Identifier,
getContext().getRegisterInfo(), S,
6689 getLexer().getLoc(), *
this));
6693 Index = matchHWRegsRegisterName(Identifier);
6695 Operands.push_back(MipsOperand::createHWRegsReg(
6696 Index, Identifier,
getContext().getRegisterInfo(), S,
6697 getLexer().getLoc(), *
this));
6701 Index = matchFPURegisterName(Identifier);
6703 Operands.push_back(MipsOperand::createFGRReg(
6704 Index, Identifier,
getContext().getRegisterInfo(), S,
6705 getLexer().getLoc(), *
this));
6709 Index = matchFCCRegisterName(Identifier);
6711 Operands.push_back(MipsOperand::createFCCReg(
6712 Index, Identifier,
getContext().getRegisterInfo(), S,
6713 getLexer().getLoc(), *
this));
6717 Index = matchACRegisterName(Identifier);
6719 Operands.push_back(MipsOperand::createACCReg(
6720 Index, Identifier,
getContext().getRegisterInfo(), S,
6721 getLexer().getLoc(), *
this));
6725 Index = matchMSA128RegisterName(Identifier);
6727 Operands.push_back(MipsOperand::createMSA128Reg(
6728 Index, Identifier,
getContext().getRegisterInfo(), S,
6729 getLexer().getLoc(), *
this));
6733 Index = matchMSA128CtrlRegisterName(Identifier);
6735 Operands.push_back(MipsOperand::createMSACtrlReg(
6736 Index, Identifier,
getContext().getRegisterInfo(), S,
6737 getLexer().getLoc(), *
this));
6746 const AsmToken &Token, SMLoc S) {
6750 return matchAnyRegisterNameWithoutDollar(
Operands, Identifier, S);
6755 if (RegNum < 0 || RegNum > 31) {
6759 Error(getLexer().getLoc(),
"invalid register number");
6761 Operands.push_back(MipsOperand::createNumericReg(
6774 auto Token = getLexer().peekTok(
false);
6775 return matchAnyRegisterWithoutDollar(
Operands, Token, S);
6779 MCAsmParser &Parser = getParser();
6782 auto Token = Parser.
getTok();
6784 SMLoc S = Token.
getLoc();
6797 ParseStatus Res = matchAnyRegisterWithoutDollar(
Operands, S);
6806 MCAsmParser &Parser = getParser();
6809 SMLoc S = getLexer().getLoc();
6812 ParseStatus Res = parseAnyRegister(
Operands);
6817 const MCExpr *Expr =
nullptr;
6823 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *
this));
6828 MCAsmParser &Parser = getParser();
6829 const MCExpr *IdVal;
6840 if (getParser().parseExpression(IdVal))
6847 Operands.push_back(MipsOperand::CreateImm(
6853 MCAsmParser &Parser = getParser();
6857 bool RegRange =
false;
6864 while (parseAnyRegister(TmpOperands).isSuccess()) {
6865 SMLoc
E = getLexer().getLoc();
6866 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*TmpOperands.
back());
6867 Reg = isGP64bit() ? RegOpnd.getGPR64Reg() : RegOpnd.getGPR32Reg();
6875 MCRegister TmpReg = PrevReg + 1;
6876 while (TmpReg <=
Reg) {
6877 if ((((TmpReg < Mips::R16) || (TmpReg > Mips::R23)) &&
6879 (((TmpReg < Mips::R16_64) || (TmpReg > Mips::R23_64)) &&
6881 return Error(
E,
"invalid register operand");
6885 TmpReg = TmpReg.
id() + 1;
6894 return Error(
E,
"$16 or $31 expected");
6896 (
Reg >= Mips::R16 &&
Reg <= Mips::R23)) &&
6899 (
Reg >= Mips::R16_64 &&
Reg <= Mips::R23_64)) &&
6901 return Error(
E,
"invalid register operand");
6902 if (PrevReg.
isValid() && (
Reg != PrevReg + 1) &&
6905 return Error(
E,
"consecutive register numbers expected");
6915 return Error(
E,
"',' or '-' expected");
6925 Operands.push_back(MipsOperand::CreateRegList(Regs, S,
E, *
this));
6936 MCAsmParser &Parser = getParser();
6939 MipsOperand::CreateToken(
"(", getLexer().getLoc(), *
this));
6941 if (parseOperand(
Operands, Name)) {
6942 SMLoc Loc = getLexer().getLoc();
6943 return Error(Loc,
"unexpected token in argument list");
6946 SMLoc Loc = getLexer().getLoc();
6947 return Error(Loc,
"unexpected token, expected ')'");
6950 MipsOperand::CreateToken(
")", getLexer().getLoc(), *
this));
6962bool MipsAsmParser::parseBracketSuffix(StringRef Name,
6964 MCAsmParser &Parser = getParser();
6967 MipsOperand::CreateToken(
"[", getLexer().getLoc(), *
this));
6969 if (parseOperand(
Operands, Name)) {
6970 SMLoc Loc = getLexer().getLoc();
6971 return Error(Loc,
"unexpected token in argument list");
6974 SMLoc Loc = getLexer().getLoc();
6975 return Error(Loc,
"unexpected token, expected ']'");
6978 MipsOperand::CreateToken(
"]", getLexer().getLoc(), *
this));
6985 unsigned VariantID = 0);
7000bool MipsAsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
7002 MCAsmParser &Parser = getParser();
7006 getTargetStreamer().forbidModuleDirective();
7009 if (!mnemonicIsValid(Name, 0)) {
7010 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
7012 return Error(NameLoc,
"unknown instruction" + Suggestion);
7015 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *
this));
7020 if (parseOperand(
Operands, Name)) {
7021 SMLoc Loc = getLexer().getLoc();
7022 return Error(Loc,
"unexpected token in argument list");
7031 if (parseOperand(
Operands, Name)) {
7032 SMLoc Loc = getLexer().getLoc();
7033 return Error(Loc,
"unexpected token in argument list");
7037 if (parseBracketSuffix(Name,
Operands))
7045 SMLoc Loc = getLexer().getLoc();
7046 return Error(Loc,
"unexpected token in argument list");
7054bool MipsAsmParser::reportParseError(
const Twine &ErrorMsg) {
7055 SMLoc Loc = getLexer().getLoc();
7056 return Error(Loc, ErrorMsg);
7059bool MipsAsmParser::reportParseError(SMLoc Loc,
const Twine &ErrorMsg) {
7060 return Error(Loc, ErrorMsg);
7063bool MipsAsmParser::parseSetNoAtDirective() {
7064 MCAsmParser &Parser = getParser();
7068 AssemblerOptions.
back()->setATRegIndex(0);
7074 reportParseError(
"unexpected token, expected end of statement");
7078 getTargetStreamer().emitDirectiveSetNoAt();
7083bool MipsAsmParser::parseSetAtDirective() {
7086 MCAsmParser &Parser = getParser();
7091 AssemblerOptions.
back()->setATRegIndex(1);
7093 getTargetStreamer().emitDirectiveSetAt();
7099 reportParseError(
"unexpected token, expected equals sign");
7106 reportParseError(
"no register specified");
7109 reportParseError(
"unexpected token, expected dollar sign '$'");
7119 AtRegNo = matchCPURegisterName(
Reg.getIdentifier());
7121 AtRegNo =
Reg.getIntVal();
7123 reportParseError(
"unexpected token, expected identifier or integer");
7128 if (!AssemblerOptions.
back()->setATRegIndex(AtRegNo)) {
7129 reportParseError(
"invalid register");
7136 reportParseError(
"unexpected token, expected end of statement");
7140 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
7146bool MipsAsmParser::parseSetReorderDirective() {
7147 MCAsmParser &Parser = getParser();
7151 reportParseError(
"unexpected token, expected end of statement");
7154 AssemblerOptions.
back()->setReorder();
7155 getTargetStreamer().emitDirectiveSetReorder();
7160bool MipsAsmParser::parseSetNoReorderDirective() {
7161 MCAsmParser &Parser = getParser();
7165 reportParseError(
"unexpected token, expected end of statement");
7168 AssemblerOptions.
back()->setNoReorder();
7169 getTargetStreamer().emitDirectiveSetNoReorder();
7174bool MipsAsmParser::parseSetMacroDirective() {
7175 MCAsmParser &Parser = getParser();
7179 reportParseError(
"unexpected token, expected end of statement");
7182 AssemblerOptions.
back()->setMacro();
7183 getTargetStreamer().emitDirectiveSetMacro();
7188bool MipsAsmParser::parseSetNoMacroDirective() {
7189 MCAsmParser &Parser = getParser();
7193 reportParseError(
"unexpected token, expected end of statement");
7196 if (AssemblerOptions.
back()->isReorder()) {
7197 reportParseError(
"`noreorder' must be set before `nomacro'");
7200 AssemblerOptions.
back()->setNoMacro();
7201 getTargetStreamer().emitDirectiveSetNoMacro();
7206bool MipsAsmParser::parseSetMsaDirective() {
7207 MCAsmParser &Parser = getParser();
7212 return reportParseError(
"unexpected token, expected end of statement");
7214 setFeatureBits(Mips::FeatureMSA,
"msa");
7215 getTargetStreamer().emitDirectiveSetMsa();
7219bool MipsAsmParser::parseSetNoMsaDirective() {
7220 MCAsmParser &Parser = getParser();
7225 return reportParseError(
"unexpected token, expected end of statement");
7227 clearFeatureBits(Mips::FeatureMSA,
"msa");
7228 getTargetStreamer().emitDirectiveSetNoMsa();
7232bool MipsAsmParser::parseSetNoDspDirective() {
7233 MCAsmParser &Parser = getParser();
7238 reportParseError(
"unexpected token, expected end of statement");
7242 clearFeatureBits(Mips::FeatureDSP,
"dsp");
7243 getTargetStreamer().emitDirectiveSetNoDsp();
7247bool MipsAsmParser::parseSetNoMips3DDirective() {
7248 MCAsmParser &Parser = getParser();
7253 reportParseError(
"unexpected token, expected end of statement");
7257 clearFeatureBits(Mips::FeatureMips3D,
"mips3d");
7258 getTargetStreamer().emitDirectiveSetNoMips3D();
7262bool MipsAsmParser::parseSetMips16Directive() {
7263 MCAsmParser &Parser = getParser();
7268 reportParseError(
"unexpected token, expected end of statement");
7272 clearFeatureBits(Mips::FeatureMicroMips,
"micromips");
7273 setFeatureBits(Mips::FeatureMips16,
"mips16");
7274 getTargetStreamer().emitDirectiveSetMips16();
7279bool MipsAsmParser::parseSetNoMips16Directive() {
7280 MCAsmParser &Parser = getParser();
7285 reportParseError(
"unexpected token, expected end of statement");
7289 clearFeatureBits(Mips::FeatureMips16,
"mips16");
7290 getTargetStreamer().emitDirectiveSetNoMips16();
7295bool MipsAsmParser::parseSetFpDirective() {
7296 MCAsmParser &Parser = getParser();
7302 AsmToken Tok = Parser.
getTok();
7304 reportParseError(
"unexpected token, expected equals sign '='");
7310 if (!parseFpABIValue(FpAbiVal,
".set"))
7314 reportParseError(
"unexpected token, expected end of statement");
7317 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
7322bool MipsAsmParser::parseSetOddSPRegDirective() {
7323 MCAsmParser &Parser = getParser();
7327 reportParseError(
"unexpected token, expected end of statement");
7331 clearFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
7332 getTargetStreamer().emitDirectiveSetOddSPReg();
7336bool MipsAsmParser::parseSetNoOddSPRegDirective() {
7337 MCAsmParser &Parser = getParser();
7341 reportParseError(
"unexpected token, expected end of statement");
7345 setFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
7346 getTargetStreamer().emitDirectiveSetNoOddSPReg();
7350bool MipsAsmParser::parseSetMtDirective() {
7351 MCAsmParser &Parser = getParser();
7356 reportParseError(
"unexpected token, expected end of statement");
7360 setFeatureBits(Mips::FeatureMT,
"mt");
7361 getTargetStreamer().emitDirectiveSetMt();
7366bool MipsAsmParser::parseSetNoMtDirective() {
7367 MCAsmParser &Parser = getParser();
7372 reportParseError(
"unexpected token, expected end of statement");
7376 clearFeatureBits(Mips::FeatureMT,
"mt");
7378 getTargetStreamer().emitDirectiveSetNoMt();
7383bool MipsAsmParser::parseSetNoCRCDirective() {
7384 MCAsmParser &Parser = getParser();
7389 reportParseError(
"unexpected token, expected end of statement");
7393 clearFeatureBits(Mips::FeatureCRC,
"crc");
7395 getTargetStreamer().emitDirectiveSetNoCRC();
7400bool MipsAsmParser::parseSetNoVirtDirective() {
7401 MCAsmParser &Parser = getParser();
7406 reportParseError(
"unexpected token, expected end of statement");
7410 clearFeatureBits(Mips::FeatureVirt,
"virt");
7412 getTargetStreamer().emitDirectiveSetNoVirt();
7417bool MipsAsmParser::parseSetNoGINVDirective() {
7418 MCAsmParser &Parser = getParser();
7423 reportParseError(
"unexpected token, expected end of statement");
7427 clearFeatureBits(Mips::FeatureGINV,
"ginv");
7429 getTargetStreamer().emitDirectiveSetNoGINV();
7434bool MipsAsmParser::parseSetNoEVADirective() {
7435 MCAsmParser &Parser = getParser();
7440 reportParseError(
"unexpected token, expected end of statement");
7444 clearFeatureBits(Mips::FeatureEVA,
"eva");
7446 getTargetStreamer().emitDirectiveSetNoEVA();
7451bool MipsAsmParser::parseSetPopDirective() {
7452 MCAsmParser &Parser = getParser();
7453 SMLoc Loc = getLexer().getLoc();
7457 return reportParseError(
"unexpected token, expected end of statement");
7461 if (AssemblerOptions.
size() == 2)
7462 return reportParseError(Loc,
".set pop with no .set push");
7464 MCSubtargetInfo &STI = copySTI();
7466 setAvailableFeatures(
7467 ComputeAvailableFeatures(AssemblerOptions.
back()->getFeatures()));
7470 getTargetStreamer().emitDirectiveSetPop();
7474bool MipsAsmParser::parseSetPushDirective() {
7475 MCAsmParser &Parser = getParser();
7478 return reportParseError(
"unexpected token, expected end of statement");
7482 std::make_unique<MipsAssemblerOptions>(AssemblerOptions.
back().get()));
7484 getTargetStreamer().emitDirectiveSetPush();
7488bool MipsAsmParser::parseSetSoftFloatDirective() {
7489 MCAsmParser &Parser = getParser();
7492 return reportParseError(
"unexpected token, expected end of statement");
7494 setFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
7495 getTargetStreamer().emitDirectiveSetSoftFloat();
7499bool MipsAsmParser::parseSetHardFloatDirective() {
7500 MCAsmParser &Parser = getParser();
7503 return reportParseError(
"unexpected token, expected end of statement");
7505 clearFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
7506 getTargetStreamer().emitDirectiveSetHardFloat();
7510bool MipsAsmParser::parseSetAssignment() {
7512 MCAsmParser &Parser = getParser();
7515 return reportParseError(
"expected identifier after .set");
7518 return reportParseError(
"unexpected token, expected comma");
7533 const MCExpr *
Value;
7535 Parser, Sym,
Value))
7537 getStreamer().emitAssignment(Sym,
Value);
7542bool MipsAsmParser::parseSetMips0Directive() {
7543 MCAsmParser &Parser = getParser();
7546 return reportParseError(
"unexpected token, expected end of statement");
7549 MCSubtargetInfo &STI = copySTI();
7550 setAvailableFeatures(
7551 ComputeAvailableFeatures(AssemblerOptions.
front()->getFeatures()));
7553 AssemblerOptions.
back()->setFeatures(AssemblerOptions.
front()->getFeatures());
7555 getTargetStreamer().emitDirectiveSetMips0();
7559bool MipsAsmParser::parseSetArchDirective() {
7560 MCAsmParser &Parser = getParser();
7563 return reportParseError(
"unexpected token, expected equals sign");
7566 StringRef Arch = getParser().parseStringToEndOfStatement().trim();
7568 return reportParseError(
"expected arch identifier");
7570 StringRef ArchFeatureName =
7571 StringSwitch<StringRef>(Arch)
7572 .Case(
"mips1",
"mips1")
7573 .Case(
"mips2",
"mips2")
7574 .Case(
"mips3",
"mips3")
7575 .Case(
"mips4",
"mips4")
7576 .Case(
"mips5",
"mips5")
7577 .Case(
"mips32",
"mips32")
7578 .Case(
"mips32r2",
"mips32r2")
7579 .Case(
"mips32r3",
"mips32r3")
7580 .Case(
"mips32r5",
"mips32r5")
7581 .Case(
"mips32r6",
"mips32r6")
7582 .Case(
"mips64",
"mips64")
7583 .Case(
"mips64r2",
"mips64r2")
7584 .Case(
"mips64r3",
"mips64r3")
7585 .Case(
"mips64r5",
"mips64r5")
7586 .Case(
"mips64r6",
"mips64r6")
7587 .Case(
"octeon",
"cnmips")
7588 .Case(
"octeon+",
"cnmipsp")
7589 .Case(
"r4000",
"mips3")
7592 if (ArchFeatureName.
empty())
7593 return reportParseError(
"unsupported architecture");
7595 if (ArchFeatureName ==
"mips64r6" && inMicroMipsMode())
7596 return reportParseError(
"mips64r6 does not support microMIPS");
7598 selectArch(ArchFeatureName);
7599 getTargetStreamer().emitDirectiveSetArch(Arch);
7603bool MipsAsmParser::parseSetFeature(
uint64_t Feature) {
7604 MCAsmParser &Parser = getParser();
7607 return reportParseError(
"unexpected token, expected end of statement");
7612 case Mips::FeatureMips3D:
7613 setFeatureBits(Mips::FeatureMips3D,
"mips3d");
7614 getTargetStreamer().emitDirectiveSetMips3D();
7616 case Mips::FeatureDSP:
7617 setFeatureBits(Mips::FeatureDSP,
"dsp");
7618 getTargetStreamer().emitDirectiveSetDsp();
7620 case Mips::FeatureDSPR2:
7621 setFeatureBits(Mips::FeatureDSPR2,
"dspr2");
7622 getTargetStreamer().emitDirectiveSetDspr2();
7624 case Mips::FeatureMicroMips:
7625 clearFeatureBits(Mips::FeatureMips16,
"mips16");
7626 setFeatureBits(Mips::FeatureMicroMips,
"micromips");
7627 getTargetStreamer().emitDirectiveSetMicroMips();
7629 case Mips::FeatureMips1:
7630 selectArch(
"mips1");
7631 getTargetStreamer().emitDirectiveSetMips1();
7633 case Mips::FeatureMips2:
7634 selectArch(
"mips2");
7635 getTargetStreamer().emitDirectiveSetMips2();
7637 case Mips::FeatureMips3:
7638 selectArch(
"mips3");
7639 getTargetStreamer().emitDirectiveSetMips3();
7641 case Mips::FeatureMips4:
7642 selectArch(
"mips4");
7643 getTargetStreamer().emitDirectiveSetMips4();
7645 case Mips::FeatureMips5:
7646 selectArch(
"mips5");
7647 getTargetStreamer().emitDirectiveSetMips5();
7649 case Mips::FeatureMips32:
7650 selectArch(
"mips32");
7651 getTargetStreamer().emitDirectiveSetMips32();
7653 case Mips::FeatureMips32r2:
7654 selectArch(
"mips32r2");
7655 getTargetStreamer().emitDirectiveSetMips32R2();
7657 case Mips::FeatureMips32r3:
7658 selectArch(
"mips32r3");
7659 getTargetStreamer().emitDirectiveSetMips32R3();
7661 case Mips::FeatureMips32r5:
7662 selectArch(
"mips32r5");
7663 getTargetStreamer().emitDirectiveSetMips32R5();
7665 case Mips::FeatureMips32r6:
7666 selectArch(
"mips32r6");
7667 getTargetStreamer().emitDirectiveSetMips32R6();
7669 case Mips::FeatureMips64:
7670 selectArch(
"mips64");
7671 getTargetStreamer().emitDirectiveSetMips64();
7673 case Mips::FeatureMips64r2:
7674 selectArch(
"mips64r2");
7675 getTargetStreamer().emitDirectiveSetMips64R2();
7677 case Mips::FeatureMips64r3:
7678 selectArch(
"mips64r3");
7679 getTargetStreamer().emitDirectiveSetMips64R3();
7681 case Mips::FeatureMips64r5:
7682 selectArch(
"mips64r5");
7683 getTargetStreamer().emitDirectiveSetMips64R5();
7685 case Mips::FeatureMips64r6:
7686 selectArch(
"mips64r6");
7687 getTargetStreamer().emitDirectiveSetMips64R6();
7689 case Mips::FeatureCRC:
7690 setFeatureBits(Mips::FeatureCRC,
"crc");
7691 getTargetStreamer().emitDirectiveSetCRC();
7693 case Mips::FeatureVirt:
7694 setFeatureBits(Mips::FeatureVirt,
"virt");
7695 getTargetStreamer().emitDirectiveSetVirt();
7697 case Mips::FeatureGINV:
7698 setFeatureBits(Mips::FeatureGINV,
"ginv");
7699 getTargetStreamer().emitDirectiveSetGINV();
7701 case Mips::FeatureEVA:
7702 setFeatureBits(Mips::FeatureEVA,
"eva");
7703 getTargetStreamer().emitDirectiveSetEVA();
7709bool MipsAsmParser::eatComma(StringRef ErrorStr) {
7710 MCAsmParser &Parser = getParser();
7712 SMLoc Loc = getLexer().getLoc();
7713 return Error(Loc, ErrorStr);
7724bool MipsAsmParser::isPicAndNotNxxAbi() {
7725 return inPicMode() && !(isABI_N32() || isABI_N64());
7728bool MipsAsmParser::parseDirectiveCpAdd(SMLoc Loc) {
7730 ParseStatus Res = parseAnyRegister(
Reg);
7732 reportParseError(
"expected register");
7736 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7737 if (!RegOpnd.isGPRAsmReg()) {
7738 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7744 reportParseError(
"unexpected token, expected end of statement");
7749 getTargetStreamer().emitDirectiveCpAdd(RegOpnd.getGPR32Reg());
7753bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
7754 if (AssemblerOptions.
back()->isReorder())
7755 Warning(Loc,
".cpload should be inside a noreorder section");
7757 if (inMips16Mode()) {
7758 reportParseError(
".cpload is not supported in Mips16 mode");
7763 ParseStatus Res = parseAnyRegister(
Reg);
7765 reportParseError(
"expected register containing function address");
7769 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7770 if (!RegOpnd.isGPRAsmReg()) {
7771 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7777 reportParseError(
"unexpected token, expected end of statement");
7781 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
7785bool MipsAsmParser::parseDirectiveCpLocal(SMLoc Loc) {
7786 if (!isABI_N32() && !isABI_N64()) {
7787 reportParseError(
".cplocal is allowed only in N32 or N64 mode");
7792 ParseStatus Res = parseAnyRegister(
Reg);
7794 reportParseError(
"expected register containing global pointer");
7798 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7799 if (!RegOpnd.isGPRAsmReg()) {
7800 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7806 reportParseError(
"unexpected token, expected end of statement");
7811 MCRegister NewReg = RegOpnd.getGPR32Reg();
7815 getTargetStreamer().emitDirectiveCpLocal(NewReg);
7819bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
7820 MCAsmParser &Parser = getParser();
7825 if (inMips16Mode()) {
7826 reportParseError(
".cprestore is not supported in Mips16 mode");
7831 const MCExpr *StackOffset;
7832 int64_t StackOffsetVal;
7834 reportParseError(
"expected stack offset value");
7838 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
7839 reportParseError(
"stack offset is not an absolute expression");
7843 if (StackOffsetVal < 0) {
7844 Warning(Loc,
".cprestore with negative stack offset has no effect");
7845 IsCpRestoreSet =
false;
7847 IsCpRestoreSet =
true;
7848 CpRestoreOffset = StackOffsetVal;
7853 reportParseError(
"unexpected token, expected end of statement");
7857 if (!getTargetStreamer().emitDirectiveCpRestore(
7858 CpRestoreOffset, [&]() {
return getATReg(Loc); }, Loc, STI))
7864bool MipsAsmParser::parseDirectiveCPSetup() {
7865 MCAsmParser &Parser = getParser();
7867 bool SaveIsReg =
true;
7870 ParseStatus Res = parseAnyRegister(TmpReg);
7872 reportParseError(
"expected register containing function address");
7876 MipsOperand &FuncRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7877 if (!FuncRegOpnd.isGPRAsmReg()) {
7878 reportParseError(FuncRegOpnd.getStartLoc(),
"invalid register");
7882 MCRegister FuncReg = FuncRegOpnd.getGPR32Reg();
7885 if (!eatComma(
"unexpected token, expected comma"))
7888 Res = parseAnyRegister(TmpReg);
7890 const MCExpr *OffsetExpr;
7892 SMLoc ExprLoc = getLexer().
getLoc();
7895 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
7896 reportParseError(ExprLoc,
"expected save register or stack offset");
7903 MipsOperand &SaveOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7904 if (!SaveOpnd.isGPRAsmReg()) {
7905 reportParseError(SaveOpnd.getStartLoc(),
"invalid register");
7908 Save = SaveOpnd.getGPR32Reg().id();
7911 if (!eatComma(
"unexpected token, expected comma"))
7916 reportParseError(
"expected expression");
7921 reportParseError(
"expected symbol");
7924 const MCSymbolRefExpr *
Ref =
static_cast<const MCSymbolRefExpr *
>(Expr);
7926 CpSaveLocation = Save;
7927 CpSaveLocationIsRegister = SaveIsReg;
7929 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save,
Ref->getSymbol(),
7934bool MipsAsmParser::parseDirectiveCPReturn() {
7935 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
7936 CpSaveLocationIsRegister);
7940bool MipsAsmParser::parseDirectiveNaN() {
7941 MCAsmParser &Parser = getParser();
7943 const AsmToken &Tok = Parser.
getTok();
7947 getTargetStreamer().emitDirectiveNaN2008();
7949 }
else if (Tok.
getString() ==
"legacy") {
7951 getTargetStreamer().emitDirectiveNaNLegacy();
7957 reportParseError(
"invalid option in .nan directive");
7961bool MipsAsmParser::parseDirectiveSet() {
7962 const AsmToken &Tok = getParser().getTok();
7964 SMLoc Loc = Tok.
getLoc();
7966 if (IdVal ==
"noat")
7967 return parseSetNoAtDirective();
7969 return parseSetAtDirective();
7970 if (IdVal ==
"arch")
7971 return parseSetArchDirective();
7972 if (IdVal ==
"bopt") {
7973 Warning(Loc,
"'bopt' feature is unsupported");
7977 if (IdVal ==
"nobopt") {
7983 return parseSetFpDirective();
7984 if (IdVal ==
"oddspreg")
7985 return parseSetOddSPRegDirective();
7986 if (IdVal ==
"nooddspreg")
7987 return parseSetNoOddSPRegDirective();
7989 return parseSetPopDirective();
7990 if (IdVal ==
"push")
7991 return parseSetPushDirective();
7992 if (IdVal ==
"reorder")
7993 return parseSetReorderDirective();
7994 if (IdVal ==
"noreorder")
7995 return parseSetNoReorderDirective();
7996 if (IdVal ==
"macro")
7997 return parseSetMacroDirective();
7998 if (IdVal ==
"nomacro")
7999 return parseSetNoMacroDirective();
8000 if (IdVal ==
"mips16")
8001 return parseSetMips16Directive();
8002 if (IdVal ==
"nomips16")
8003 return parseSetNoMips16Directive();
8004 if (IdVal ==
"nomicromips") {
8005 clearFeatureBits(Mips::FeatureMicroMips,
"micromips");
8006 getTargetStreamer().emitDirectiveSetNoMicroMips();
8007 getParser().eatToEndOfStatement();
8010 if (IdVal ==
"micromips") {
8011 if (hasMips64r6()) {
8012 Error(Loc,
".set micromips directive is not supported with MIPS64R6");
8015 return parseSetFeature(Mips::FeatureMicroMips);
8017 if (IdVal ==
"mips0")
8018 return parseSetMips0Directive();
8019 if (IdVal ==
"mips1")
8020 return parseSetFeature(Mips::FeatureMips1);
8021 if (IdVal ==
"mips2")
8022 return parseSetFeature(Mips::FeatureMips2);
8023 if (IdVal ==
"mips3")
8024 return parseSetFeature(Mips::FeatureMips3);
8025 if (IdVal ==
"mips4")
8026 return parseSetFeature(Mips::FeatureMips4);
8027 if (IdVal ==
"mips5")
8028 return parseSetFeature(Mips::FeatureMips5);
8029 if (IdVal ==
"mips32")
8030 return parseSetFeature(Mips::FeatureMips32);
8031 if (IdVal ==
"mips32r2")
8032 return parseSetFeature(Mips::FeatureMips32r2);
8033 if (IdVal ==
"mips32r3")
8034 return parseSetFeature(Mips::FeatureMips32r3);
8035 if (IdVal ==
"mips32r5")
8036 return parseSetFeature(Mips::FeatureMips32r5);
8037 if (IdVal ==
"mips32r6")
8038 return parseSetFeature(Mips::FeatureMips32r6);
8039 if (IdVal ==
"mips64")
8040 return parseSetFeature(Mips::FeatureMips64);
8041 if (IdVal ==
"mips64r2")
8042 return parseSetFeature(Mips::FeatureMips64r2);
8043 if (IdVal ==
"mips64r3")
8044 return parseSetFeature(Mips::FeatureMips64r3);
8045 if (IdVal ==
"mips64r5")
8046 return parseSetFeature(Mips::FeatureMips64r5);
8047 if (IdVal ==
"mips64r6") {
8048 if (inMicroMipsMode()) {
8049 Error(Loc,
"MIPS64R6 is not supported with microMIPS");
8052 return parseSetFeature(Mips::FeatureMips64r6);
8055 return parseSetFeature(Mips::FeatureDSP);
8056 if (IdVal ==
"dspr2")
8057 return parseSetFeature(Mips::FeatureDSPR2);
8058 if (IdVal ==
"nodsp")
8059 return parseSetNoDspDirective();
8060 if (IdVal ==
"mips3d")
8061 return parseSetFeature(Mips::FeatureMips3D);
8062 if (IdVal ==
"nomips3d")
8063 return parseSetNoMips3DDirective();
8065 return parseSetMsaDirective();
8066 if (IdVal ==
"nomsa")
8067 return parseSetNoMsaDirective();
8069 return parseSetMtDirective();
8070 if (IdVal ==
"nomt")
8071 return parseSetNoMtDirective();
8072 if (IdVal ==
"softfloat")
8073 return parseSetSoftFloatDirective();
8074 if (IdVal ==
"hardfloat")
8075 return parseSetHardFloatDirective();
8077 return parseSetFeature(Mips::FeatureCRC);
8078 if (IdVal ==
"nocrc")
8079 return parseSetNoCRCDirective();
8080 if (IdVal ==
"virt")
8081 return parseSetFeature(Mips::FeatureVirt);
8082 if (IdVal ==
"novirt")
8083 return parseSetNoVirtDirective();
8084 if (IdVal ==
"ginv")
8085 return parseSetFeature(Mips::FeatureGINV);
8086 if (IdVal ==
"noginv")
8087 return parseSetNoGINVDirective();
8089 return parseSetFeature(Mips::FeatureEVA);
8090 if (IdVal ==
"noeva")
8091 return parseSetNoEVADirective();
8094 return parseSetAssignment();
8099bool MipsAsmParser::parseDirectiveGpWord() {
8100 const MCExpr *
Value;
8101 if (getParser().parseExpression(
Value))
8103 getTargetStreamer().emitGPRel32Value(
Value);
8109bool MipsAsmParser::parseDirectiveGpDWord() {
8110 const MCExpr *
Value;
8111 if (getParser().parseExpression(
Value))
8113 getTargetStreamer().emitGPRel64Value(
Value);
8119bool MipsAsmParser::parseDirectiveDtpRelWord() {
8120 const MCExpr *
Value;
8121 if (getParser().parseExpression(
Value))
8123 getTargetStreamer().emitDTPRel32Value(
Value);
8129bool MipsAsmParser::parseDirectiveDtpRelDWord() {
8130 const MCExpr *
Value;
8131 if (getParser().parseExpression(
Value))
8133 getTargetStreamer().emitDTPRel64Value(
Value);
8139bool MipsAsmParser::parseDirectiveTpRelWord() {
8140 const MCExpr *
Value;
8141 if (getParser().parseExpression(
Value))
8143 getTargetStreamer().emitTPRel32Value(
Value);
8149bool MipsAsmParser::parseDirectiveTpRelDWord() {
8150 const MCExpr *
Value;
8151 if (getParser().parseExpression(
Value))
8153 getTargetStreamer().emitTPRel64Value(
Value);
8157bool MipsAsmParser::parseDirectiveOption() {
8158 MCAsmParser &Parser = getParser();
8160 AsmToken Tok = Parser.
getTok();
8164 "unexpected token, expected identifier");
8169 if (Option ==
"pic0") {
8171 IsPicEnabled =
false;
8173 getTargetStreamer().emitDirectiveOptionPic0();
8177 "unexpected token, expected end of statement");
8182 if (Option ==
"pic2") {
8184 IsPicEnabled =
true;
8186 getTargetStreamer().emitDirectiveOptionPic2();
8190 "unexpected token, expected end of statement");
8197 "unknown option, expected 'pic0' or 'pic2'");
8204bool MipsAsmParser::parseInsnDirective() {
8207 reportParseError(
"unexpected token, expected end of statement");
8213 getTargetStreamer().emitDirectiveInsn();
8221bool MipsAsmParser::parseRSectionDirective(StringRef Section) {
8224 reportParseError(
"unexpected token, expected end of statement");
8228 MCSection *ELFSection =
getContext().getELFSection(
8230 getParser().getStreamer().switchSection(ELFSection);
8239bool MipsAsmParser::parseSSectionDirective(StringRef Section,
unsigned Type) {
8242 reportParseError(
"unexpected token, expected end of statement");
8246 MCSection *ELFSection =
getContext().getELFSection(
8248 getParser().getStreamer().switchSection(ELFSection);
8267bool MipsAsmParser::parseDirectiveModule() {
8268 MCAsmParser &Parser = getParser();
8269 AsmLexer &Lexer = getLexer();
8272 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
8274 reportParseError(
".module directive must appear before any code");
8280 reportParseError(
"expected .module option identifier");
8284 if (Option ==
"oddspreg") {
8285 clearModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
8289 getTargetStreamer().updateABIInfo(*
this);
8294 getTargetStreamer().emitDirectiveModuleOddSPReg();
8298 reportParseError(
"unexpected token, expected end of statement");
8303 }
else if (Option ==
"nooddspreg") {
8305 return Error(L,
"'.module nooddspreg' requires the O32 ABI");
8308 setModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
8312 getTargetStreamer().updateABIInfo(*
this);
8317 getTargetStreamer().emitDirectiveModuleOddSPReg();
8321 reportParseError(
"unexpected token, expected end of statement");
8326 }
else if (Option ==
"fp") {
8327 return parseDirectiveModuleFP();
8328 }
else if (Option ==
"softfloat") {
8329 setModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
8333 getTargetStreamer().updateABIInfo(*
this);
8338 getTargetStreamer().emitDirectiveModuleSoftFloat();
8342 reportParseError(
"unexpected token, expected end of statement");
8347 }
else if (Option ==
"hardfloat") {
8348 clearModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
8352 getTargetStreamer().updateABIInfo(*
this);
8357 getTargetStreamer().emitDirectiveModuleHardFloat();
8361 reportParseError(
"unexpected token, expected end of statement");
8366 }
else if (Option ==
"mt") {
8367 setModuleFeatureBits(Mips::FeatureMT,
"mt");
8371 getTargetStreamer().updateABIInfo(*
this);
8376 getTargetStreamer().emitDirectiveModuleMT();
8380 reportParseError(
"unexpected token, expected end of statement");
8385 }
else if (Option ==
"crc") {
8386 setModuleFeatureBits(Mips::FeatureCRC,
"crc");
8390 getTargetStreamer().updateABIInfo(*
this);
8395 getTargetStreamer().emitDirectiveModuleCRC();
8399 reportParseError(
"unexpected token, expected end of statement");
8404 }
else if (Option ==
"nocrc") {
8405 clearModuleFeatureBits(Mips::FeatureCRC,
"crc");
8409 getTargetStreamer().updateABIInfo(*
this);
8414 getTargetStreamer().emitDirectiveModuleNoCRC();
8418 reportParseError(
"unexpected token, expected end of statement");
8423 }
else if (Option ==
"virt") {
8424 setModuleFeatureBits(Mips::FeatureVirt,
"virt");
8428 getTargetStreamer().updateABIInfo(*
this);
8433 getTargetStreamer().emitDirectiveModuleVirt();
8437 reportParseError(
"unexpected token, expected end of statement");
8442 }
else if (Option ==
"novirt") {
8443 clearModuleFeatureBits(Mips::FeatureVirt,
"virt");
8447 getTargetStreamer().updateABIInfo(*
this);
8452 getTargetStreamer().emitDirectiveModuleNoVirt();
8456 reportParseError(
"unexpected token, expected end of statement");
8461 }
else if (Option ==
"ginv") {
8462 setModuleFeatureBits(Mips::FeatureGINV,
"ginv");
8466 getTargetStreamer().updateABIInfo(*
this);
8471 getTargetStreamer().emitDirectiveModuleGINV();
8475 reportParseError(
"unexpected token, expected end of statement");
8480 }
else if (Option ==
"noginv") {
8481 clearModuleFeatureBits(Mips::FeatureGINV,
"ginv");
8485 getTargetStreamer().updateABIInfo(*
this);
8490 getTargetStreamer().emitDirectiveModuleNoGINV();
8494 reportParseError(
"unexpected token, expected end of statement");
8500 return Error(L,
"'" + Twine(Option) +
"' is not a valid .module option.");
8508bool MipsAsmParser::parseDirectiveModuleFP() {
8509 MCAsmParser &Parser = getParser();
8510 AsmLexer &Lexer = getLexer();
8513 reportParseError(
"unexpected token, expected equals sign '='");
8519 if (!parseFpABIValue(FpABI,
".module"))
8523 reportParseError(
"unexpected token, expected end of statement");
8529 getTargetStreamer().updateABIInfo(*
this);
8534 getTargetStreamer().emitDirectiveModuleFP();
8541 StringRef Directive) {
8542 MCAsmParser &Parser = getParser();
8543 AsmLexer &Lexer = getLexer();
8544 bool ModuleLevelOptions = Directive ==
".module";
8550 if (
Value !=
"xx") {
8551 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
8556 reportParseError(
"'" + Directive +
" fp=xx' requires the O32 ABI");
8560 FpABI = MipsABIFlagsSection::FpABIKind::XX;
8561 if (ModuleLevelOptions) {
8562 setModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8563 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8565 setFeatureBits(Mips::FeatureFPXX,
"fpxx");
8566 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8576 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
8582 reportParseError(
"'" + Directive +
" fp=32' requires the O32 ABI");
8586 FpABI = MipsABIFlagsSection::FpABIKind::S32;
8587 if (ModuleLevelOptions) {
8588 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8589 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8591 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
8592 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8595 FpABI = MipsABIFlagsSection::FpABIKind::S64;
8596 if (ModuleLevelOptions) {
8597 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8598 setModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8600 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
8601 setFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8611bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
8617 MCAsmParser &Parser = getParser();
8618 StringRef IDVal = DirectiveID.
getString();
8620 if (IDVal ==
".cpadd") {
8621 parseDirectiveCpAdd(DirectiveID.
getLoc());
8624 if (IDVal ==
".cpload") {
8625 parseDirectiveCpLoad(DirectiveID.
getLoc());
8628 if (IDVal ==
".cprestore") {
8629 parseDirectiveCpRestore(DirectiveID.
getLoc());
8632 if (IDVal ==
".cplocal") {
8633 parseDirectiveCpLocal(DirectiveID.
getLoc());
8636 if (IDVal ==
".ent") {
8640 reportParseError(
"expected identifier after .ent");
8654 reportParseError(
"unexpected token, expected end of statement");
8658 const MCExpr *DummyNumber;
8659 int64_t DummyNumberVal;
8663 reportParseError(
"expected number after comma");
8666 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
8667 reportParseError(
"expected an absolute expression after comma");
8674 reportParseError(
"unexpected token, expected end of statement");
8680 getTargetStreamer().emitDirectiveEnt(*Sym);
8682 IsCpRestoreSet =
false;
8686 if (IDVal ==
".end") {
8690 reportParseError(
"expected identifier after .end");
8695 reportParseError(
"unexpected token, expected end of statement");
8699 if (CurrentFn ==
nullptr) {
8700 reportParseError(
".end used without .ent");
8704 if ((SymbolName != CurrentFn->
getName())) {
8705 reportParseError(
".end symbol does not match .ent symbol");
8709 getTargetStreamer().emitDirectiveEnd(SymbolName);
8710 CurrentFn =
nullptr;
8711 IsCpRestoreSet =
false;
8715 if (IDVal ==
".frame") {
8718 ParseStatus Res = parseAnyRegister(TmpReg);
8720 reportParseError(
"expected stack register");
8724 MipsOperand &StackRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
8725 if (!StackRegOpnd.isGPRAsmReg()) {
8726 reportParseError(StackRegOpnd.getStartLoc(),
8727 "expected general purpose register");
8730 MCRegister StackReg = StackRegOpnd.getGPR32Reg();
8735 reportParseError(
"unexpected token, expected comma");
8740 const MCExpr *FrameSize;
8741 int64_t FrameSizeVal;
8744 reportParseError(
"expected frame size value");
8748 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
8749 reportParseError(
"frame size not an absolute expression");
8756 reportParseError(
"unexpected token, expected comma");
8762 Res = parseAnyRegister(TmpReg);
8764 reportParseError(
"expected return register");
8768 MipsOperand &ReturnRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
8769 if (!ReturnRegOpnd.isGPRAsmReg()) {
8770 reportParseError(ReturnRegOpnd.getStartLoc(),
8771 "expected general purpose register");
8777 reportParseError(
"unexpected token, expected end of statement");
8781 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
8782 ReturnRegOpnd.getGPR32Reg());
8783 IsCpRestoreSet =
false;
8787 if (IDVal ==
".set") {
8788 parseDirectiveSet();
8792 if (IDVal ==
".mask" || IDVal ==
".fmask") {
8803 const MCExpr *BitMask;
8807 reportParseError(
"expected bitmask value");
8811 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
8812 reportParseError(
"bitmask not an absolute expression");
8819 reportParseError(
"unexpected token, expected comma");
8824 const MCExpr *FrameOffset;
8825 int64_t FrameOffsetVal;
8828 reportParseError(
"expected frame offset value");
8832 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
8833 reportParseError(
"frame offset not an absolute expression");
8839 reportParseError(
"unexpected token, expected end of statement");
8843 if (IDVal ==
".mask")
8844 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
8846 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
8850 if (IDVal ==
".nan")
8851 return parseDirectiveNaN();
8853 if (IDVal ==
".gpword") {
8854 parseDirectiveGpWord();
8858 if (IDVal ==
".gpdword") {
8859 parseDirectiveGpDWord();
8863 if (IDVal ==
".dtprelword") {
8864 parseDirectiveDtpRelWord();
8868 if (IDVal ==
".dtpreldword") {
8869 parseDirectiveDtpRelDWord();
8873 if (IDVal ==
".tprelword") {
8874 parseDirectiveTpRelWord();
8878 if (IDVal ==
".tpreldword") {
8879 parseDirectiveTpRelDWord();
8883 if (IDVal ==
".option") {
8884 parseDirectiveOption();
8888 if (IDVal ==
".abicalls") {
8889 getTargetStreamer().emitDirectiveAbiCalls();
8892 "unexpected token, expected end of statement");
8897 if (IDVal ==
".cpsetup") {
8898 parseDirectiveCPSetup();
8901 if (IDVal ==
".cpreturn") {
8902 parseDirectiveCPReturn();
8905 if (IDVal ==
".module") {
8906 parseDirectiveModule();
8909 if (IDVal ==
".llvm_internal_mips_reallow_module_directive") {
8910 parseInternalDirectiveReallowModule();
8913 if (IDVal ==
".insn") {
8914 parseInsnDirective();
8917 if (IDVal ==
".rdata") {
8918 parseRSectionDirective(
".rodata");
8921 if (IDVal ==
".sbss") {
8925 if (IDVal ==
".sdata") {
8933bool MipsAsmParser::parseInternalDirectiveReallowModule() {
8936 reportParseError(
"unexpected token, expected end of statement");
8940 getTargetStreamer().reallowModuleDirective();
8954#define GET_REGISTER_MATCHER
8955#define GET_MATCHER_IMPLEMENTATION
8956#define GET_MNEMONIC_SPELL_CHECKER
8957#include "MipsGenAsmMatcher.inc"
8959bool MipsAsmParser::mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID) {
8961 const MatchEntry *Start, *
End;
8962 switch (VariantID) {
8964 case 0: Start = std::begin(MatchTable0);
End = std::end(MatchTable0);
break;
8967 auto MnemonicRange = std::equal_range(Start,
End, Mnemonic, LessOpcode());
8968 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.
const MipsMCOptions & getCLOpts(const MCTargetOptions &Options)
int getCPURegisterIndex(StringRef Name, const MCRegisterInfo &MRI, unsigned AltIdx, bool *IsDeprecated=nullptr)
Return a GPR name's hardware index, or -1 if unknown.
constexpr MCPhysReg FP_64
constexpr MCPhysReg GP_64
constexpr MCPhysReg RA_64
constexpr MCPhysReg SP_64
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...
@ 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,...