62#define DEBUG_TYPE "mips-asm-parser"
75class MipsAssemblerOptions {
77 MipsAssemblerOptions(
const FeatureBitset &Features_) : Features(Features_) {}
79 MipsAssemblerOptions(
const MipsAssemblerOptions *Opts) {
80 ATReg = Opts->getATRegIndex();
81 Reorder = Opts->isReorder();
82 Macro = Opts->isMacro();
83 Features = Opts->getFeatures();
86 unsigned getATRegIndex()
const {
return ATReg; }
87 bool setATRegIndex(
unsigned Reg) {
95 bool isReorder()
const {
return Reorder; }
96 void setReorder() { Reorder =
true; }
97 void setNoReorder() { Reorder =
false; }
99 bool isMacro()
const {
return Macro; }
100 void setMacro() {
Macro =
true; }
101 void setNoMacro() {
Macro =
false; }
103 const FeatureBitset &
getFeatures()
const {
return Features; }
104 void setFeatures(
const FeatureBitset &Features_) { Features = Features_; }
111 static const FeatureBitset AllArchRelatedMask;
117 FeatureBitset Features;
122const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
123 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
124 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
125 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
126 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
127 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
128 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
129 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
130 Mips::FeatureCnMipsP, Mips::FeatureFP64Bit, Mips::FeatureGP64Bit,
137 MipsTargetStreamer &getTargetStreamer() {
138 assert(getParser().getStreamer().getTargetStreamer() &&
139 "do not have a target streamer");
140 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
141 return static_cast<MipsTargetStreamer &
>(TS);
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);
167 void ConvertXWPOperands(MCInst &Inst,
const OperandVector &Operands);
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;
209 const MCExpr *parseRelocExpr();
215 enum MacroExpanderResultTy {
222 MacroExpanderResultTy tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
224 const MCSubtargetInfo *STI);
226 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
227 const MCSubtargetInfo *STI);
229 bool loadImmediate(int64_t ImmValue, MCRegister DstReg, MCRegister SrcReg,
230 bool Is32BitImm,
bool IsAddress, SMLoc IDLoc,
231 MCStreamer &Out,
const MCSubtargetInfo *STI);
233 bool loadAndAddSymbolAddress(
const MCExpr *SymExpr, MCRegister DstReg,
234 MCRegister SrcReg,
bool Is32BitSym, SMLoc IDLoc,
235 MCStreamer &Out,
const MCSubtargetInfo *STI);
237 bool emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc, MCSymbol *Sym);
239 bool expandLoadImm(MCInst &Inst,
bool Is32BitImm, SMLoc IDLoc,
240 MCStreamer &Out,
const MCSubtargetInfo *STI);
242 bool expandLoadSingleImmToGPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
243 const MCSubtargetInfo *STI);
244 bool expandLoadSingleImmToFPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
245 const MCSubtargetInfo *STI);
246 bool expandLoadDoubleImmToGPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
247 const MCSubtargetInfo *STI);
248 bool expandLoadDoubleImmToFPR(MCInst &Inst,
bool Is64FPU, SMLoc IDLoc,
249 MCStreamer &Out,
const MCSubtargetInfo *STI);
251 bool expandLoadAddress(MCRegister DstReg, MCRegister BaseReg,
252 const MCOperand &
Offset,
bool Is32BitAddress,
253 SMLoc IDLoc, MCStreamer &Out,
254 const MCSubtargetInfo *STI);
256 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
257 const MCSubtargetInfo *STI);
259 void expandMem16Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
260 const MCSubtargetInfo *STI,
bool IsLoad);
261 void expandMem9Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
262 const MCSubtargetInfo *STI,
bool IsLoad);
264 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
265 const MCSubtargetInfo *STI);
267 bool expandAliasImmediate(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
268 const MCSubtargetInfo *STI);
270 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
271 const MCSubtargetInfo *STI);
273 bool expandCondBranches(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
274 const MCSubtargetInfo *STI);
276 bool expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
277 const MCSubtargetInfo *STI,
const bool IsMips64,
280 bool expandTrunc(MCInst &Inst,
bool IsDouble,
bool Is64FPU, SMLoc IDLoc,
281 MCStreamer &Out,
const MCSubtargetInfo *STI);
283 bool expandUlh(MCInst &Inst,
bool Signed, SMLoc IDLoc, MCStreamer &Out,
284 const MCSubtargetInfo *STI);
286 bool expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
287 const MCSubtargetInfo *STI);
289 bool expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
290 const MCSubtargetInfo *STI);
292 bool expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
293 const MCSubtargetInfo *STI);
295 bool expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
296 const MCSubtargetInfo *STI);
298 bool expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
299 const MCSubtargetInfo *STI);
301 bool expandSle(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
302 const MCSubtargetInfo *STI);
304 bool expandSleImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
305 const MCSubtargetInfo *STI);
307 bool expandRotation(MCInst &Inst, SMLoc IDLoc,
308 MCStreamer &Out,
const MCSubtargetInfo *STI);
309 bool expandRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
310 const MCSubtargetInfo *STI);
311 bool expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
312 const MCSubtargetInfo *STI);
313 bool expandDRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
314 const MCSubtargetInfo *STI);
316 bool expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
317 const MCSubtargetInfo *STI);
319 bool expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
320 const MCSubtargetInfo *STI);
322 bool expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
323 const MCSubtargetInfo *STI);
325 bool expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
326 const MCSubtargetInfo *STI);
328 bool expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
329 const MCSubtargetInfo *STI);
331 bool expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
332 const MCSubtargetInfo *STI,
bool IsLoad);
334 bool expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
335 const MCSubtargetInfo *STI);
337 bool expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
338 const MCSubtargetInfo *STI);
340 bool expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
341 const MCSubtargetInfo *STI);
343 bool expandSne(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
344 const MCSubtargetInfo *STI);
346 bool expandSneI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
347 const MCSubtargetInfo *STI);
349 bool expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
350 const MCSubtargetInfo *STI);
352 bool expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
353 const MCSubtargetInfo *STI);
355 bool reportParseError(
const Twine &ErrorMsg);
356 bool reportParseError(SMLoc Loc,
const Twine &ErrorMsg);
358 bool parseSetMips0Directive();
359 bool parseSetArchDirective();
360 bool parseSetFeature(uint64_t Feature);
361 bool isPicAndNotNxxAbi();
362 bool parseDirectiveCpAdd(SMLoc Loc);
363 bool parseDirectiveCpLoad(SMLoc Loc);
364 bool parseDirectiveCpLocal(SMLoc Loc);
365 bool parseDirectiveCpRestore(SMLoc Loc);
366 bool parseDirectiveCPSetup();
367 bool parseDirectiveCPReturn();
368 bool parseDirectiveNaN();
369 bool parseDirectiveSet();
370 bool parseDirectiveOption();
371 bool parseInsnDirective();
372 bool parseRSectionDirective(StringRef Section);
373 bool parseSSectionDirective(StringRef Section,
unsigned Type);
375 bool parseSetAtDirective();
376 bool parseSetNoAtDirective();
377 bool parseSetMacroDirective();
378 bool parseSetNoMacroDirective();
379 bool parseSetMsaDirective();
380 bool parseSetNoMsaDirective();
381 bool parseSetNoDspDirective();
382 bool parseSetNoMips3DDirective();
383 bool parseSetReorderDirective();
384 bool parseSetNoReorderDirective();
385 bool parseSetMips16Directive();
386 bool parseSetNoMips16Directive();
387 bool parseSetFpDirective();
388 bool parseSetOddSPRegDirective();
389 bool parseSetNoOddSPRegDirective();
390 bool parseSetPopDirective();
391 bool parseSetPushDirective();
392 bool parseSetSoftFloatDirective();
393 bool parseSetHardFloatDirective();
394 bool parseSetMtDirective();
395 bool parseSetNoMtDirective();
396 bool parseSetNoCRCDirective();
397 bool parseSetNoVirtDirective();
398 bool parseSetNoGINVDirective();
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);
446 bool validateMSAIndex(
int Val,
int RegKind);
470 void selectArch(StringRef ArchFeature) {
471 MCSubtargetInfo &STI = copySTI();
473 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
475 setAvailableFeatures(
480 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
481 if (!(getSTI().hasFeature(Feature))) {
482 MCSubtargetInfo &STI = copySTI();
483 setAvailableFeatures(
489 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
490 if (getSTI().hasFeature(Feature)) {
491 MCSubtargetInfo &STI = copySTI();
492 setAvailableFeatures(
498 void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
499 setFeatureBits(Feature, FeatureString);
500 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
503 void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
504 clearFeatureBits(Feature, FeatureString);
505 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
509 enum MipsMatchResultTy {
510 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
511 Match_RequiresDifferentOperands,
512 Match_RequiresNoZeroRegister,
513 Match_RequiresSameSrcAndDst,
514 Match_NoFCCRegisterForCurrentISA,
515 Match_NonZeroOperandForSync,
516 Match_NonZeroOperandForMTCX,
517 Match_RequiresPosSizeRange0_32,
518 Match_RequiresPosSizeRange33_64,
519 Match_RequiresPosSizeUImm6,
520#define GET_OPERAND_DIAGNOSTIC_TYPES
521#include "MipsGenAsmMatcher.inc"
522#undef GET_OPERAND_DIAGNOSTIC_TYPES
525 MipsAsmParser(
const MCSubtargetInfo &sti, MCAsmParser &parser,
526 const MCInstrInfo &MII,
const MCTargetOptions &
Options)
527 : MCTargetAsmParser(
Options, sti, MII),
538 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
541 AssemblerOptions.push_back(
542 std::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
545 AssemblerOptions.push_back(
546 std::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
548 getTargetStreamer().updateABIInfo(*
this);
550 if (!isABI_O32() && !useOddSPReg() != 0)
555 CurForbiddenSlotAttr =
false;
556 IsPicEnabled =
getContext().getObjectFileInfo()->isPositionIndependent();
558 IsCpRestoreSet =
false;
559 CpRestoreOffset = -1;
560 GPReg = ABI.GetGlobalPtr();
565 if (getSTI().
getCPU() ==
"mips64r6" && inMicroMipsMode())
568 if (!isABI_O32() && inMicroMipsMode())
573 bool hasEightFccRegisters()
const {
return hasMips4() || hasMips32(); }
575 bool isGP64bit()
const {
576 return getSTI().hasFeature(Mips::FeatureGP64Bit);
579 bool isFP64bit()
const {
580 return getSTI().hasFeature(Mips::FeatureFP64Bit);
583 bool isJalrRelocAvailable(
const MCExpr *JalExpr) {
592 return ABI.IsN32() || ABI.IsN64();
596 const MipsABIInfo &getABI()
const {
return ABI; }
597 bool isABI_N32()
const {
return ABI.IsN32(); }
598 bool isABI_N64()
const {
return ABI.IsN64(); }
599 bool isABI_O32()
const {
return ABI.IsO32(); }
600 bool isABI_FPXX()
const {
601 return getSTI().hasFeature(Mips::FeatureFPXX);
604 bool useOddSPReg()
const {
605 return !(getSTI().hasFeature(Mips::FeatureNoOddSPReg));
608 bool inMicroMipsMode()
const {
609 return getSTI().hasFeature(Mips::FeatureMicroMips);
612 bool hasMips1()
const {
613 return getSTI().hasFeature(Mips::FeatureMips1);
616 bool hasMips2()
const {
617 return getSTI().hasFeature(Mips::FeatureMips2);
620 bool hasMips3()
const {
621 return getSTI().hasFeature(Mips::FeatureMips3);
624 bool hasMips4()
const {
625 return getSTI().hasFeature(Mips::FeatureMips4);
628 bool hasMips5()
const {
629 return getSTI().hasFeature(Mips::FeatureMips5);
632 bool hasMips32()
const {
633 return getSTI().hasFeature(Mips::FeatureMips32);
636 bool hasMips64()
const {
637 return getSTI().hasFeature(Mips::FeatureMips64);
640 bool hasMips32r2()
const {
641 return getSTI().hasFeature(Mips::FeatureMips32r2);
644 bool hasMips64r2()
const {
645 return getSTI().hasFeature(Mips::FeatureMips64r2);
648 bool hasMips32r3()
const {
649 return (getSTI().hasFeature(Mips::FeatureMips32r3));
652 bool hasMips64r3()
const {
653 return (getSTI().hasFeature(Mips::FeatureMips64r3));
656 bool hasMips32r5()
const {
657 return (getSTI().hasFeature(Mips::FeatureMips32r5));
660 bool hasMips64r5()
const {
661 return (getSTI().hasFeature(Mips::FeatureMips64r5));
664 bool hasMips32r6()
const {
665 return getSTI().hasFeature(Mips::FeatureMips32r6);
668 bool hasMips64r6()
const {
669 return getSTI().hasFeature(Mips::FeatureMips64r6);
672 bool hasDSP()
const {
673 return getSTI().hasFeature(Mips::FeatureDSP);
676 bool hasDSPR2()
const {
677 return getSTI().hasFeature(Mips::FeatureDSPR2);
680 bool hasDSPR3()
const {
681 return getSTI().hasFeature(Mips::FeatureDSPR3);
684 bool hasMSA()
const {
685 return getSTI().hasFeature(Mips::FeatureMSA);
688 bool hasCnMips()
const {
689 return (getSTI().hasFeature(Mips::FeatureCnMips));
692 bool hasCnMipsP()
const {
693 return (getSTI().hasFeature(Mips::FeatureCnMipsP));
696 bool isR5900()
const {
return (getSTI().hasFeature(Mips::FeatureR5900)); }
702 bool inMips16Mode()
const {
703 return getSTI().hasFeature(Mips::FeatureMips16);
706 bool useTraps()
const {
707 return getSTI().hasFeature(Mips::FeatureUseTCCInDIV);
710 bool useSoftFloat()
const {
711 return getSTI().hasFeature(Mips::FeatureSoftFloat);
714 return getSTI().hasFeature(Mips::FeatureMT);
717 bool hasCRC()
const {
718 return getSTI().hasFeature(Mips::FeatureCRC);
721 bool hasVirt()
const {
722 return getSTI().hasFeature(Mips::FeatureVirt);
725 bool hasGINV()
const {
726 return getSTI().hasFeature(Mips::FeatureGINV);
729 bool hasForbiddenSlot(
const MCInstrDesc &MCID)
const {
733 bool SafeInForbiddenSlot(
const MCInstrDesc &MCID)
const {
737 void onEndOfFile()
override;
740 void warnIfRegIndexIsAT(MCRegister RegIndex, SMLoc Loc);
742 void warnIfNoMacro(SMLoc Loc);
744 bool isLittle()
const {
return IsLittleEndian; }
746 bool areEqualRegs(
const MCParsedAsmOperand &Op1,
747 const MCParsedAsmOperand &Op2)
const override;
762 RegKind_MSACtrl = 16,
767 RegKind_HWRegs = 256,
771 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
772 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
773 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
786 MipsOperand(KindTy K, MipsAsmParser &Parser) : Kind(
K), AsmParser(Parser) {}
788 ~MipsOperand()
override {
797 case k_RegisterIndex:
805 MipsAsmParser &AsmParser;
816 const MCRegisterInfo *RegInfo;
834 struct RegIdxOp RegIdx;
837 struct RegListOp RegList;
840 SMLoc StartLoc, EndLoc;
843 static std::unique_ptr<MipsOperand> CreateReg(
unsigned Index, StringRef Str,
845 const MCRegisterInfo *RegInfo,
847 MipsAsmParser &Parser) {
848 auto Op = std::make_unique<MipsOperand>(k_RegisterIndex, Parser);
850 Op->RegIdx.RegInfo = RegInfo;
851 Op->RegIdx.Kind = RegKind;
852 Op->RegIdx.Tok.Data = Str.data();
853 Op->RegIdx.Tok.Length = Str.size();
862 MCRegister getGPR32Reg()
const {
863 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
864 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
865 unsigned ClassID = Mips::GPR32RegClassID;
866 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
871 MCRegister getGPRMM16Reg()
const {
872 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
873 unsigned ClassID = Mips::GPR32RegClassID;
874 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
879 MCRegister getGPR64Reg()
const {
880 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
881 unsigned ClassID = Mips::GPR64RegClassID;
882 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
888 MCRegister getAFGR64Reg()
const {
889 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
890 if (RegIdx.Index % 2 != 0)
891 AsmParser.Warning(StartLoc,
"Float register should be even.");
892 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
893 .getRegister(RegIdx.Index / 2);
898 MCRegister getFGR64Reg()
const {
899 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
900 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
901 .getRegister(RegIdx.Index);
906 MCRegister getFGR32Reg()
const {
907 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
908 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
909 .getRegister(RegIdx.Index);
914 MCRegister getFCCReg()
const {
915 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) &&
"Invalid access!");
916 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
917 .getRegister(RegIdx.Index);
922 MCRegister getMSA128Reg()
const {
923 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) &&
"Invalid access!");
926 unsigned ClassID = Mips::MSA128BRegClassID;
927 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
932 MCRegister getMSACtrlReg()
const {
933 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) &&
"Invalid access!");
934 unsigned ClassID = Mips::MSACtrlRegClassID;
935 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
940 MCRegister getCOP0Reg()
const {
941 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) &&
"Invalid access!");
942 unsigned ClassID = Mips::COP0RegClassID;
943 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
948 MCRegister getCOP2Reg()
const {
949 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) &&
"Invalid access!");
950 unsigned ClassID = Mips::COP2RegClassID;
951 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
956 MCRegister getCOP3Reg()
const {
957 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) &&
"Invalid access!");
958 unsigned ClassID = Mips::COP3RegClassID;
959 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
964 MCRegister getACC64DSPReg()
const {
965 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
966 unsigned ClassID = Mips::ACC64DSPRegClassID;
967 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
972 MCRegister getHI32DSPReg()
const {
973 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
974 unsigned ClassID = Mips::HI32DSPRegClassID;
975 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
980 MCRegister getLO32DSPReg()
const {
981 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
982 unsigned ClassID = Mips::LO32DSPRegClassID;
983 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
988 MCRegister getCCRReg()
const {
989 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) &&
"Invalid access!");
990 unsigned ClassID = Mips::CCRRegClassID;
991 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
996 MCRegister getHWRegsReg()
const {
997 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) &&
"Invalid access!");
998 unsigned ClassID = Mips::HWRegsRegClassID;
999 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1003 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const {
1013 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1020 void addGPR32ZeroAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1021 assert(
N == 1 &&
"Invalid number of operands!");
1025 void addGPR32NonZeroAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1026 assert(
N == 1 &&
"Invalid number of operands!");
1030 void addGPR32AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1031 assert(
N == 1 &&
"Invalid number of operands!");
1035 void addGPRMM16AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1036 assert(
N == 1 &&
"Invalid number of operands!");
1040 void addGPRMM16AsmRegZeroOperands(MCInst &Inst,
unsigned N)
const {
1041 assert(
N == 1 &&
"Invalid number of operands!");
1045 void addGPRMM16AsmRegMovePOperands(MCInst &Inst,
unsigned N)
const {
1046 assert(
N == 1 &&
"Invalid number of operands!");
1050 void addGPRMM16AsmRegMovePPairFirstOperands(MCInst &Inst,
unsigned N)
const {
1051 assert(
N == 1 &&
"Invalid number of operands!");
1055 void addGPRMM16AsmRegMovePPairSecondOperands(MCInst &Inst,
1057 assert(
N == 1 &&
"Invalid number of operands!");
1064 void addGPR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1065 assert(
N == 1 &&
"Invalid number of operands!");
1069 void addAFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1070 assert(
N == 1 &&
"Invalid number of operands!");
1074 void addStrictlyAFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1075 assert(
N == 1 &&
"Invalid number of operands!");
1079 void addStrictlyFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1080 assert(
N == 1 &&
"Invalid number of operands!");
1084 void addFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1085 assert(
N == 1 &&
"Invalid number of operands!");
1089 void addFGR32AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1090 assert(
N == 1 &&
"Invalid number of operands!");
1094 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1095 AsmParser.getParser().printError(
1096 StartLoc,
"-mno-odd-spreg prohibits the use of odd FPU "
1100 void addStrictlyFGR32AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1101 assert(
N == 1 &&
"Invalid number of operands!");
1104 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1105 AsmParser.Error(StartLoc,
"-mno-odd-spreg prohibits the use of odd FPU "
1109 void addFCCAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1110 assert(
N == 1 &&
"Invalid number of operands!");
1114 void addMSA128AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1115 assert(
N == 1 &&
"Invalid number of operands!");
1119 void addMSACtrlAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1120 assert(
N == 1 &&
"Invalid number of operands!");
1124 void addCOP0AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1125 assert(
N == 1 &&
"Invalid number of operands!");
1129 void addCOP2AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1130 assert(
N == 1 &&
"Invalid number of operands!");
1134 void addCOP3AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1135 assert(
N == 1 &&
"Invalid number of operands!");
1139 void addACC64DSPAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1140 assert(
N == 1 &&
"Invalid number of operands!");
1144 void addHI32DSPAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1145 assert(
N == 1 &&
"Invalid number of operands!");
1149 void addLO32DSPAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1150 assert(
N == 1 &&
"Invalid number of operands!");
1154 void addCCRAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1155 assert(
N == 1 &&
"Invalid number of operands!");
1159 void addHWRegsAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1160 assert(
N == 1 &&
"Invalid number of operands!");
1164 template <
unsigned Bits,
int Offset = 0,
int AdjustOffset = 0>
1165 void addConstantUImmOperands(MCInst &Inst,
unsigned N)
const {
1166 assert(
N == 1 &&
"Invalid number of operands!");
1167 uint64_t
Imm = getConstantImm() -
Offset;
1170 Imm += AdjustOffset;
1174 template <
unsigned Bits>
1175 void addSImmOperands(MCInst &Inst,
unsigned N)
const {
1176 if (isImm() && !isConstantImm()) {
1180 addConstantSImmOperands<Bits, 0, 0>(Inst,
N);
1183 template <
unsigned Bits>
1184 void addUImmOperands(MCInst &Inst,
unsigned N)
const {
1185 if (isImm() && !isConstantImm()) {
1189 addConstantUImmOperands<Bits, 0, 0>(Inst,
N);
1192 template <
unsigned Bits,
int Offset = 0,
int AdjustOffset = 0>
1193 void addConstantSImmOperands(MCInst &Inst,
unsigned N)
const {
1194 assert(
N == 1 &&
"Invalid number of operands!");
1195 int64_t
Imm = getConstantImm() -
Offset;
1198 Imm += AdjustOffset;
1202 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1203 assert(
N == 1 &&
"Invalid number of operands!");
1204 const MCExpr *Expr =
getImm();
1205 addExpr(Inst, Expr);
1208 void addMemOperands(MCInst &Inst,
unsigned N)
const {
1209 assert(
N == 2 &&
"Invalid number of operands!");
1212 ? getMemBase()->getGPR64Reg()
1213 : getMemBase()->getGPR32Reg()));
1215 const MCExpr *Expr = getMemOff();
1216 addExpr(Inst, Expr);
1219 void addMicroMipsMemOperands(MCInst &Inst,
unsigned N)
const {
1220 assert(
N == 2 &&
"Invalid number of operands!");
1224 const MCExpr *Expr = getMemOff();
1225 addExpr(Inst, Expr);
1228 void addRegListOperands(MCInst &Inst,
unsigned N)
const {
1229 assert(
N == 1 &&
"Invalid number of operands!");
1231 for (
auto RegNo : getRegList())
1235 bool isReg()
const override {
1238 return isGPRAsmReg() && RegIdx.Index == 0;
1241 bool isRegIdx()
const {
return Kind == k_RegisterIndex; }
1242 bool isImm()
const override {
return Kind == k_Immediate; }
1244 bool isConstantImm()
const {
1246 return isImm() &&
getImm()->evaluateAsAbsolute(Res);
1249 bool isConstantImmz()
const {
1250 return isConstantImm() && getConstantImm() == 0;
1253 template <
unsigned Bits,
int Offset = 0>
bool isConstantUImm()
const {
1257 template <
unsigned Bits>
bool isSImm()
const {
1261 if (
getImm()->evaluateAsAbsolute(Res))
1267 template <
unsigned Bits>
bool isUImm()
const {
1271 if (
getImm()->evaluateAsAbsolute(Res))
1277 template <
unsigned Bits>
bool isAnyImm()
const {
1278 return isConstantImm() ? (
isInt<Bits>(getConstantImm()) ||
1283 template <
unsigned Bits,
int Offset = 0>
bool isConstantSImm()
const {
1287 template <
unsigned Bottom,
unsigned Top>
bool isConstantUImmRange()
const {
1288 return isConstantImm() && getConstantImm() >= Bottom &&
1289 getConstantImm() <= Top;
1292 bool isToken()
const override {
1295 return Kind == k_Token;
1298 bool isMem()
const override {
return Kind == k_Memory; }
1300 bool isConstantMemOff()
const {
1305 template <
unsigned Bits,
unsigned ShiftAmount = 0>
1306 bool isMemWithSimmOffset()
const {
1309 if (!getMemBase()->isGPRAsmReg())
1312 (isConstantMemOff() &&
1316 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res,
nullptr);
1320 bool isMemWithPtrSizeOffset()
const {
1323 if (!getMemBase()->isGPRAsmReg())
1325 const unsigned PtrBits = AsmParser.getABI().ArePtrs64bit() ? 64 : 32;
1327 (isConstantMemOff() &&
isIntN(PtrBits, getConstantMemOff())))
1330 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res,
nullptr);
1334 bool isMemWithGRPMM16Base()
const {
1335 return isMem() && getMemBase()->isMM16AsmReg();
1338 template <
unsigned Bits>
bool isMemWithUimmOffsetSP()
const {
1340 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1343 template <
unsigned Bits>
bool isMemWithUimmWordAlignedOffsetSP()
const {
1345 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1346 && (getMemBase()->getGPR32Reg() == Mips::SP);
1349 template <
unsigned Bits>
bool isMemWithSimmWordAlignedOffsetGP()
const {
1351 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1352 && (getMemBase()->getGPR32Reg() == Mips::GP);
1355 template <
unsigned Bits,
unsigned ShiftLeftAmount>
1356 bool isScaledUImm()
const {
1357 return isConstantImm() &&
1361 template <
unsigned Bits,
unsigned ShiftLeftAmount>
1362 bool isScaledSImm()
const {
1363 if (isConstantImm() &&
1368 if (Kind != k_Immediate)
1371 bool Success =
getImm()->evaluateAsRelocatable(Res,
nullptr);
1375 bool isRegList16()
const {
1379 int Size = RegList.List->size();
1383 MCRegister R0 = RegList.List->front();
1384 MCRegister R1 = RegList.List->back();
1385 if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1386 (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1389 MCRegister PrevReg = RegList.List->front();
1390 for (
int i = 1; i <
Size - 1; i++) {
1391 MCRegister
Reg = (*(RegList.List))[i];
1392 if (
Reg != PrevReg + 1)
1400 bool isInvNum()
const {
return Kind == k_Immediate; }
1402 bool isLSAImm()
const {
1403 if (!isConstantImm())
1405 int64_t Val = getConstantImm();
1406 return 1 <= Val && Val <= 4;
1409 bool isRegList()
const {
return Kind == k_RegList; }
1412 assert(Kind == k_Token &&
"Invalid access!");
1413 return StringRef(Tok.Data, Tok.Length);
1416 MCRegister
getReg()
const override {
1419 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1420 RegIdx.Kind & RegKind_GPR)
1421 return getGPR32Reg();
1427 const MCExpr *
getImm()
const {
1428 assert((Kind == k_Immediate) &&
"Invalid access!");
1432 int64_t getConstantImm()
const {
1433 const MCExpr *Val =
getImm();
1435 (void)Val->evaluateAsAbsolute(
Value);
1439 MipsOperand *getMemBase()
const {
1440 assert((Kind == k_Memory) &&
"Invalid access!");
1444 const MCExpr *getMemOff()
const {
1445 assert((Kind == k_Memory) &&
"Invalid access!");
1449 int64_t getConstantMemOff()
const {
1450 return static_cast<const MCConstantExpr *
>(getMemOff())->getValue();
1453 const SmallVectorImpl<MCRegister> &getRegList()
const {
1454 assert((Kind == k_RegList) &&
"Invalid access!");
1455 return *(RegList.List);
1458 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1459 MipsAsmParser &Parser) {
1460 auto Op = std::make_unique<MipsOperand>(k_Token, Parser);
1461 Op->Tok.Data = Str.data();
1462 Op->Tok.Length = Str.size();
1470 static std::unique_ptr<MipsOperand>
1471 createNumericReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1472 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1473 LLVM_DEBUG(
dbgs() <<
"createNumericReg(" << Index <<
", ...)\n");
1474 return CreateReg(Index, Str, RegKind_Numeric, RegInfo, S,
E, Parser);
1479 static std::unique_ptr<MipsOperand>
1480 createGPRReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1481 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1482 return CreateReg(Index, Str, RegKind_GPR, RegInfo, S,
E, Parser);
1487 static std::unique_ptr<MipsOperand>
1488 createFGRReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1489 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1490 return CreateReg(Index, Str, RegKind_FGR, RegInfo, S,
E, Parser);
1495 static std::unique_ptr<MipsOperand>
1496 createHWRegsReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1497 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1498 return CreateReg(Index, Str, RegKind_HWRegs, RegInfo, S,
E, Parser);
1503 static std::unique_ptr<MipsOperand>
1504 createFCCReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1505 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1506 return CreateReg(Index, Str, RegKind_FCC, RegInfo, S,
E, Parser);
1511 static std::unique_ptr<MipsOperand>
1512 createACCReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1513 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1514 return CreateReg(Index, Str, RegKind_ACC, RegInfo, S,
E, Parser);
1519 static std::unique_ptr<MipsOperand>
1520 createMSA128Reg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1521 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1522 return CreateReg(Index, Str, RegKind_MSA128, RegInfo, S,
E, Parser);
1527 static std::unique_ptr<MipsOperand>
1528 createMSACtrlReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1529 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1530 return CreateReg(Index, Str, RegKind_MSACtrl, RegInfo, S,
E, Parser);
1533 static std::unique_ptr<MipsOperand>
1534 CreateImm(
const MCExpr *Val, SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1535 auto Op = std::make_unique<MipsOperand>(k_Immediate, Parser);
1542 static std::unique_ptr<MipsOperand>
1543 CreateMem(std::unique_ptr<MipsOperand>
Base,
const MCExpr *Off, SMLoc S,
1544 SMLoc
E, MipsAsmParser &Parser) {
1545 auto Op = std::make_unique<MipsOperand>(k_Memory, Parser);
1546 Op->Mem.Base =
Base.release();
1553 static std::unique_ptr<MipsOperand>
1554 CreateRegList(SmallVectorImpl<MCRegister> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1555 MipsAsmParser &Parser) {
1556 assert(!Regs.
empty() &&
"Empty list not allowed");
1558 auto Op = std::make_unique<MipsOperand>(k_RegList, Parser);
1561 Op->StartLoc = StartLoc;
1562 Op->EndLoc = EndLoc;
1566 bool isGPRZeroAsmReg()
const {
1567 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
1570 bool isGPRNonZeroAsmReg()
const {
1571 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index > 0 &&
1575 bool isGPRAsmReg()
const {
1576 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1579 bool isMM16AsmReg()
const {
1580 if (!(isRegIdx() && RegIdx.Kind))
1582 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1583 || RegIdx.Index == 16 || RegIdx.Index == 17);
1586 bool isMM16AsmRegZero()
const {
1587 if (!(isRegIdx() && RegIdx.Kind))
1589 return (RegIdx.Index == 0 ||
1590 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1591 RegIdx.Index == 17);
1594 bool isMM16AsmRegMoveP()
const {
1595 if (!(isRegIdx() && RegIdx.Kind))
1597 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1598 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1601 bool isMM16AsmRegMovePPairFirst()
const {
1602 if (!(isRegIdx() && RegIdx.Kind))
1604 return RegIdx.Index >= 4 && RegIdx.Index <= 6;
1607 bool isMM16AsmRegMovePPairSecond()
const {
1608 if (!(isRegIdx() && RegIdx.Kind))
1610 return (RegIdx.Index == 21 || RegIdx.Index == 22 ||
1611 (RegIdx.Index >= 5 && RegIdx.Index <= 7));
1614 bool isFGRAsmReg()
const {
1616 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1619 bool isStrictlyFGRAsmReg()
const {
1621 return isRegIdx() && RegIdx.Kind == RegKind_FGR && RegIdx.Index <= 31;
1624 bool isHWRegsAsmReg()
const {
1625 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1628 bool isCCRAsmReg()
const {
1629 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1632 bool isFCCAsmReg()
const {
1633 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1635 return RegIdx.Index <= 7;
1638 bool isACCAsmReg()
const {
1639 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1642 bool isCOP0AsmReg()
const {
1643 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1646 bool isCOP2AsmReg()
const {
1647 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1650 bool isCOP3AsmReg()
const {
1651 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1654 bool isMSA128AsmReg()
const {
1655 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1658 bool isMSACtrlAsmReg()
const {
1659 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1663 SMLoc getStartLoc()
const override {
return StartLoc; }
1665 SMLoc getEndLoc()
const override {
return EndLoc; }
1667 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1676 Mem.Base->print(OS, MAI);
1681 case k_RegisterIndex:
1682 OS <<
"RegIdx<" << RegIdx.Index <<
":" << RegIdx.Kind <<
", "
1683 << StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) <<
">";
1690 for (
auto Reg : (*RegList.List))
1691 OS <<
Reg.
id() <<
" ";
1697 bool isValidForTie(
const MipsOperand &
Other)
const {
1698 if (Kind !=
Other.Kind)
1705 case k_RegisterIndex: {
1706 StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length);
1707 StringRef OtherToken(
Other.RegIdx.Tok.Data,
Other.RegIdx.Tok.Length);
1708 return Token == OtherToken;
1724 case Mips::JRC16_MM:
1726 case Mips::JALRS_MM:
1727 case Mips::JALRS16_MM:
1728 case Mips::BGEZALS_MM:
1729 case Mips::BLTZALS_MM:
1740 return &SRExpr->getSymbol();
1799 unsigned NumOp =
MCID.getNumOperands();
1800 if (NumOp != 3 && NumOp != 4)
1830bool MipsAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
1833 MipsTargetStreamer &TOut = getTargetStreamer();
1834 const unsigned Opcode = Inst.
getOpcode();
1835 const MCInstrDesc &MCID = MII.get(Opcode);
1836 bool ExpandedJalSym =
false;
1850 assert(hasCnMips() &&
"instruction only valid for octeon cpus");
1861 if (!
isIntN(inMicroMipsMode() ? 17 : 18,
Offset.getImm()))
1862 return Error(IDLoc,
"branch target out of range");
1865 return Error(IDLoc,
"branch to misaligned address");
1879 case Mips::BGEZAL_MM:
1880 case Mips::BLTZAL_MM:
1883 case Mips::BC1EQZC_MMR6:
1884 case Mips::BC1NEZC_MMR6:
1885 case Mips::BC2EQZC_MMR6:
1886 case Mips::BC2NEZC_MMR6:
1891 if (!
isIntN(inMicroMipsMode() ? 17 : 18,
Offset.getImm()))
1892 return Error(IDLoc,
"branch target out of range");
1895 return Error(IDLoc,
"branch to misaligned address");
1897 case Mips::BGEC:
case Mips::BGEC_MMR6:
1898 case Mips::BLTC:
case Mips::BLTC_MMR6:
1899 case Mips::BGEUC:
case Mips::BGEUC_MMR6:
1900 case Mips::BLTUC:
case Mips::BLTUC_MMR6:
1901 case Mips::BEQC:
case Mips::BEQC_MMR6:
1902 case Mips::BNEC:
case Mips::BNEC_MMR6:
1908 return Error(IDLoc,
"branch target out of range");
1910 return Error(IDLoc,
"branch to misaligned address");
1912 case Mips::BLEZC:
case Mips::BLEZC_MMR6:
1913 case Mips::BGEZC:
case Mips::BGEZC_MMR6:
1914 case Mips::BGTZC:
case Mips::BGTZC_MMR6:
1915 case Mips::BLTZC:
case Mips::BLTZC_MMR6:
1921 return Error(IDLoc,
"branch target out of range");
1923 return Error(IDLoc,
"branch to misaligned address");
1925 case Mips::BEQZC:
case Mips::BEQZC_MMR6:
1926 case Mips::BNEZC:
case Mips::BNEZC_MMR6:
1932 return Error(IDLoc,
"branch target out of range");
1934 return Error(IDLoc,
"branch to misaligned address");
1936 case Mips::BEQZ16_MM:
1937 case Mips::BEQZC16_MMR6:
1938 case Mips::BNEZ16_MM:
1939 case Mips::BNEZC16_MMR6:
1945 return Error(IDLoc,
"branch target out of range");
1947 return Error(IDLoc,
"branch to misaligned address");
1954 if (hasMips32r6() && Opcode == Mips::SSNOP) {
1955 std::string
ISA = hasMips64r6() ?
"MIPS64r6" :
"MIPS32r6";
1956 Warning(IDLoc,
"ssnop is deprecated for " + ISA +
" and is equivalent to a "
1976 return Error(IDLoc,
"expected immediate operand kind");
1978 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1979 Opcode == Mips::BBIT1 ? 63 : 31))
1980 return Error(IDLoc,
"immediate operand value out of range");
1982 Inst.
setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1993 return Error(IDLoc,
"expected immediate operand kind");
1996 return Error(IDLoc,
"immediate operand value out of range");
2008 unsigned FirstOp = 1;
2009 unsigned SecondOp = 2;
2013 case Mips::SDivIMacro:
2014 case Mips::UDivIMacro:
2015 case Mips::DSDivIMacro:
2016 case Mips::DUDivIMacro:
2020 Warning(IDLoc,
"dividing zero by zero");
2022 Warning(IDLoc,
"division by zero");
2034 case Mips::SDivMacro:
2035 case Mips::DSDivMacro:
2036 case Mips::UDivMacro:
2037 case Mips::DUDivMacro:
2042 case Mips::DIVU_MMR6:
2043 case Mips::DIV_MMR6:
2048 Warning(IDLoc,
"dividing zero by zero");
2050 Warning(IDLoc,
"division by zero");
2056 if ((Opcode == Mips::J || Opcode == Mips::J_MM) && inPicMode()) {
2058 BInst.
setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
2067 if ((Opcode == Mips::JAL || Opcode == Mips::JAL_MM) && inPicMode()) {
2068 warnIfNoMacro(IDLoc);
2071 return Error(IDLoc,
"unsupported constant in relocation");
2079 return Error(IDLoc,
"jal doesn't support multiple symbols in PIC mode");
2085 if (expandLoadAddress(Mips::T9, MCRegister(), Inst.
getOperand(0),
2086 !isGP64bit(), IDLoc, Out, STI))
2090 if (inMicroMipsMode())
2091 JalrInst.
setOpcode(IsCpRestoreSet ? Mips::JALRS_MM : Mips::JALR_MM);
2097 if (isJalrRelocAvailable(JalExpr)) {
2103 const MCExpr *RelocJalrExpr =
2107 *TmpExpr, inMicroMipsMode() ?
"R_MICROMIPS_JALR" :
"R_MIPS_JALR",
2113 ExpandedJalSym =
true;
2122 expandMem9Inst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2125 expandMem16Inst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2128 return getParser().hasPendingError();
2132 if (inMicroMipsMode()) {
2133 if (MCID.
mayLoad() && Opcode != Mips::LWP_MM) {
2136 const MCOperandInfo &OpInfo = MCID.
operands()[i];
2141 int MemOffset =
Op.getImm();
2144 if (
isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
2147 (
BaseReg.getReg() == Mips::GP ||
2148 BaseReg.getReg() == Mips::GP_64)) {
2150 TOut.
emitRRI(Mips::LWGP_MM, DstReg.
getReg(), Mips::GP, MemOffset,
2167 case Mips::ADDIUSP_MM:
2170 return Error(IDLoc,
"expected immediate operand kind");
2172 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
2174 return Error(IDLoc,
"immediate operand value out of range");
2176 case Mips::SLL16_MM:
2177 case Mips::SRL16_MM:
2180 return Error(IDLoc,
"expected immediate operand kind");
2182 if (Imm < 1 || Imm > 8)
2183 return Error(IDLoc,
"immediate operand value out of range");
2188 return Error(IDLoc,
"expected immediate operand kind");
2190 if (Imm < -1 || Imm > 126)
2191 return Error(IDLoc,
"immediate operand value out of range");
2193 case Mips::ADDIUR2_MM:
2196 return Error(IDLoc,
"expected immediate operand kind");
2198 if (!(Imm == 1 || Imm == -1 ||
2199 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
2200 return Error(IDLoc,
"immediate operand value out of range");
2202 case Mips::ANDI16_MM:
2205 return Error(IDLoc,
"expected immediate operand kind");
2207 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
2208 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
2209 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
2210 return Error(IDLoc,
"immediate operand value out of range");
2212 case Mips::LBU16_MM:
2215 return Error(IDLoc,
"expected immediate operand kind");
2217 if (Imm < -1 || Imm > 14)
2218 return Error(IDLoc,
"immediate operand value out of range");
2221 case Mips::SB16_MMR6:
2224 return Error(IDLoc,
"expected immediate operand kind");
2226 if (Imm < 0 || Imm > 15)
2227 return Error(IDLoc,
"immediate operand value out of range");
2229 case Mips::LHU16_MM:
2231 case Mips::SH16_MMR6:
2234 return Error(IDLoc,
"expected immediate operand kind");
2236 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
2237 return Error(IDLoc,
"immediate operand value out of range");
2241 case Mips::SW16_MMR6:
2244 return Error(IDLoc,
"expected immediate operand kind");
2246 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
2247 return Error(IDLoc,
"immediate operand value out of range");
2249 case Mips::ADDIUPC_MM:
2252 return Error(IDLoc,
"expected immediate operand kind");
2255 return Error(IDLoc,
"immediate operand value out of range");
2260 return Error(IDLoc,
"invalid operand for instruction");
2262 case Mips::MOVEP_MM:
2263 case Mips::MOVEP_MMR6: {
2266 bool RegPair = ((R0 == Mips::A1 && R1 == Mips::A2) ||
2267 (R0 == Mips::A1 && R1 == Mips::A3) ||
2268 (R0 == Mips::A2 && R1 == Mips::A3) ||
2269 (R0 == Mips::A0 && R1 == Mips::S5) ||
2270 (R0 == Mips::A0 && R1 == Mips::S6) ||
2271 (R0 == Mips::A0 && R1 == Mips::A1) ||
2272 (R0 == Mips::A0 && R1 == Mips::A2) ||
2273 (R0 == Mips::A0 && R1 == Mips::A3));
2275 return Error(IDLoc,
"invalid operand for instruction");
2281 bool FillDelaySlot =
2286 bool PrevForbiddenSlotAttr = CurForbiddenSlotAttr;
2289 bool SetReorderAfterNop =
false;
2294 if (PrevForbiddenSlotAttr && !SafeInForbiddenSlot(MCID)) {
2304 if (AssemblerOptions.
back()->isReorder() && !FillDelaySlot) {
2305 SetReorderAfterNop =
true;
2314 CurForbiddenSlotAttr =
2315 hasForbiddenSlot(MCID) && AssemblerOptions.
back()->isReorder();
2317 if (FillDelaySlot || CurForbiddenSlotAttr)
2320 MacroExpanderResultTy ExpandResult =
2321 tryExpandInstruction(Inst, IDLoc, Out, STI);
2322 switch (ExpandResult) {
2338 if (PrevForbiddenSlotAttr && !SetReorderAfterNop && !FillDelaySlot &&
2339 AssemblerOptions.
back()->isReorder()) {
2345 if (inMicroMipsMode()) {
2360 if (FillDelaySlot) {
2365 if ((Opcode == Mips::JalOneReg || Opcode == Mips::JalTwoReg ||
2367 isPicAndNotNxxAbi()) {
2368 if (IsCpRestoreSet) {
2372 if (!AssemblerOptions.
back()->isReorder())
2379 Warning(IDLoc,
"no .cprestore used in PIC mode");
2385void MipsAsmParser::onEndOfFile() {
2386 MipsTargetStreamer &TOut = getTargetStreamer();
2387 SMLoc IDLoc = SMLoc();
2389 if (CurForbiddenSlotAttr) {
2391 if (AssemblerOptions.
back()->isReorder())
2396MipsAsmParser::MacroExpanderResultTy
2397MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2398 const MCSubtargetInfo *STI) {
2401 return MER_NotAMacro;
2402 case Mips::LoadImm32:
2403 return expandLoadImm(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2404 case Mips::LoadImm64:
2405 return expandLoadImm(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2406 case Mips::LoadAddrImm32:
2407 case Mips::LoadAddrImm64:
2410 "expected immediate operand kind");
2412 return expandLoadAddress(
2414 Inst.
getOpcode() == Mips::LoadAddrImm32, IDLoc, Out, STI)
2417 case Mips::LoadAddrReg32:
2418 case Mips::LoadAddrReg64:
2422 "expected immediate operand kind");
2426 Inst.
getOpcode() == Mips::LoadAddrReg32, IDLoc,
2430 case Mips::B_MM_Pseudo:
2431 case Mips::B_MMR6_Pseudo:
2432 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2436 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2438 case Mips::JalOneReg:
2439 case Mips::JalTwoReg:
2440 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2443 case Mips::BEQLImmMacro:
2444 case Mips::BNELImmMacro:
2445 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2462 case Mips::BLTImmMacro:
2463 case Mips::BLEImmMacro:
2464 case Mips::BGEImmMacro:
2465 case Mips::BGTImmMacro:
2466 case Mips::BLTUImmMacro:
2467 case Mips::BLEUImmMacro:
2468 case Mips::BGEUImmMacro:
2469 case Mips::BGTUImmMacro:
2470 case Mips::BLTLImmMacro:
2471 case Mips::BLELImmMacro:
2472 case Mips::BGELImmMacro:
2473 case Mips::BGTLImmMacro:
2474 case Mips::BLTULImmMacro:
2475 case Mips::BLEULImmMacro:
2476 case Mips::BGEULImmMacro:
2477 case Mips::BGTULImmMacro:
2478 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2479 case Mips::SDivMacro:
2480 case Mips::SDivIMacro:
2481 case Mips::SRemMacro:
2482 case Mips::SRemIMacro:
2483 return expandDivRem(Inst, IDLoc, Out, STI,
false,
true) ? MER_Fail
2485 case Mips::DSDivMacro:
2486 case Mips::DSDivIMacro:
2487 case Mips::DSRemMacro:
2488 case Mips::DSRemIMacro:
2489 return expandDivRem(Inst, IDLoc, Out, STI,
true,
true) ? MER_Fail
2491 case Mips::UDivMacro:
2492 case Mips::UDivIMacro:
2493 case Mips::URemMacro:
2494 case Mips::URemIMacro:
2495 return expandDivRem(Inst, IDLoc, Out, STI,
false,
false) ? MER_Fail
2497 case Mips::DUDivMacro:
2498 case Mips::DUDivIMacro:
2499 case Mips::DURemMacro:
2500 case Mips::DURemIMacro:
2501 return expandDivRem(Inst, IDLoc, Out, STI,
true,
false) ? MER_Fail
2503 case Mips::PseudoTRUNC_W_S:
2504 return expandTrunc(Inst,
false,
false, IDLoc, Out, STI) ? MER_Fail
2506 case Mips::PseudoTRUNC_W_D32:
2507 return expandTrunc(Inst,
true,
false, IDLoc, Out, STI) ? MER_Fail
2509 case Mips::PseudoTRUNC_W_D:
2510 return expandTrunc(Inst,
true,
true, IDLoc, Out, STI) ? MER_Fail
2513 case Mips::LoadImmSingleGPR:
2514 return expandLoadSingleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2516 case Mips::LoadImmSingleFGR:
2517 return expandLoadSingleImmToFPR(Inst, IDLoc, Out, STI) ? MER_Fail
2519 case Mips::LoadImmDoubleGPR:
2520 return expandLoadDoubleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2522 case Mips::LoadImmDoubleFGR:
2523 return expandLoadDoubleImmToFPR(Inst,
true, IDLoc, Out, STI) ? MER_Fail
2525 case Mips::LoadImmDoubleFGR_32:
2526 return expandLoadDoubleImmToFPR(Inst,
false, IDLoc, Out, STI) ? MER_Fail
2530 return expandUlh(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2532 return expandUlh(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2534 return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2537 return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2539 case Mips::NORImm64:
2540 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2543 return expandSge(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2546 case Mips::SGEImm64:
2547 case Mips::SGEUImm64:
2548 return expandSgeImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2551 case Mips::SGTImm64:
2552 case Mips::SGTUImm64:
2553 return expandSgtImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2556 return expandSle(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2559 case Mips::SLEImm64:
2560 case Mips::SLEUImm64:
2561 return expandSleImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2562 case Mips::SLTImm64:
2565 return MER_NotAMacro;
2567 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2568 case Mips::SLTUImm64:
2571 return MER_NotAMacro;
2573 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2574 case Mips::ADDi:
case Mips::ADDi_MM:
2575 case Mips::ADDiu:
case Mips::ADDiu_MM:
2576 case Mips::SLTi:
case Mips::SLTi_MM:
2577 case Mips::SLTiu:
case Mips::SLTiu_MM:
2582 return MER_NotAMacro;
2583 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2586 return MER_NotAMacro;
2587 case Mips::ANDi:
case Mips::ANDi_MM:
case Mips::ANDi64:
2588 case Mips::ORi:
case Mips::ORi_MM:
case Mips::ORi64:
2589 case Mips::XORi:
case Mips::XORi_MM:
case Mips::XORi64:
2594 return MER_NotAMacro;
2595 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2598 return MER_NotAMacro;
2601 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2604 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2607 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2610 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2611 case Mips::ABSMacro:
2612 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2613 case Mips::MULImmMacro:
2614 case Mips::DMULImmMacro:
2615 return expandMulImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2616 case Mips::MULOMacro:
2617 case Mips::DMULOMacro:
2618 return expandMulO(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2619 case Mips::MULOUMacro:
2620 case Mips::DMULOUMacro:
2621 return expandMulOU(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2622 case Mips::DMULMacro:
2623 return expandDMULMacro(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2626 return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2631 return expandStoreDM1Macro(Inst, IDLoc, Out, STI)
2634 case Mips::SEQMacro:
2635 return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2636 case Mips::SEQIMacro:
2637 return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2638 case Mips::SNEMacro:
2639 return expandSne(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2640 case Mips::SNEIMacro:
2641 return expandSneI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2642 case Mips::MFTC0:
case Mips::MTTC0:
2643 case Mips::MFTGPR:
case Mips::MTTGPR:
2644 case Mips::MFTLO:
case Mips::MTTLO:
2645 case Mips::MFTHI:
case Mips::MTTHI:
2646 case Mips::MFTACX:
case Mips::MTTACX:
2647 case Mips::MFTDSP:
case Mips::MTTDSP:
2648 case Mips::MFTC1:
case Mips::MTTC1:
2649 case Mips::MFTHC1:
case Mips::MTTHC1:
2650 case Mips::CFTC1:
case Mips::CTTC1:
2651 return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2653 case Mips::SaadAddr:
2654 return expandSaaAddr(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2658bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2660 const MCSubtargetInfo *STI) {
2661 MipsTargetStreamer &TOut = getTargetStreamer();
2666 const MCOperand FirstRegOp = Inst.
getOperand(0);
2667 const unsigned Opcode = Inst.
getOpcode();
2669 if (Opcode == Mips::JalOneReg) {
2671 if (IsCpRestoreSet && inMicroMipsMode()) {
2674 }
else if (inMicroMipsMode()) {
2675 JalrInst.
setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2682 }
else if (Opcode == Mips::JalTwoReg) {
2684 if (IsCpRestoreSet && inMicroMipsMode())
2687 JalrInst.
setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2689 const MCOperand SecondRegOp = Inst.
getOperand(1);
2696 const MCInstrDesc &MCID = MII.get(JalrInst.
getOpcode());
2719bool MipsAsmParser::loadImmediate(int64_t ImmValue, MCRegister DstReg,
2720 MCRegister SrcReg,
bool Is32BitImm,
2721 bool IsAddress, SMLoc IDLoc, MCStreamer &Out,
2722 const MCSubtargetInfo *STI) {
2723 MipsTargetStreamer &TOut = getTargetStreamer();
2725 if (!Is32BitImm && !isGP64bit()) {
2726 Error(IDLoc,
"instruction requires a 64-bit architecture");
2737 Error(IDLoc,
"instruction requires a 32-bit immediate");
2742 MCRegister ZeroReg = IsAddress ?
ABI.GetNullPtr() :
ABI.GetZeroReg();
2743 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2745 bool UseSrcReg =
false;
2749 MCRegister TmpReg = DstReg;
2751 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2754 MCRegister ATReg = getATReg(IDLoc);
2767 if (IsAddress && !Is32BitImm) {
2768 TOut.
emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2772 TOut.
emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2777 MCRegister TmpReg = DstReg;
2778 if (SrcReg == DstReg) {
2779 TmpReg = getATReg(IDLoc);
2784 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2786 TOut.
emitRRR(
ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2791 warnIfNoMacro(IDLoc);
2793 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2794 uint16_t Bits15To0 = ImmValue & 0xffff;
2795 if (!Is32BitImm && !
isInt<32>(ImmValue)) {
2798 if (ImmValue == 0xffffffff) {
2799 TOut.
emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2800 TOut.
emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2802 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2808 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2809 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2811 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2813 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2817 TOut.
emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2819 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2821 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2827 Error(IDLoc,
"instruction requires a 32-bit immediate");
2834 assert(
BitWidth >= 17 &&
"ImmValue must be at least 17-bit wide");
2838 unsigned ShiftAmount =
BitWidth - 16;
2839 uint16_t
Bits = (ImmValue >> ShiftAmount) & 0xffff;
2840 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2841 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2844 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2849 warnIfNoMacro(IDLoc);
2856 if (loadImmediate(ImmValue >> 32, TmpReg, MCRegister(),
true,
false, IDLoc,
2862 unsigned ShiftCarriedForwards = 16;
2863 for (
int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2864 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2866 if (ImmChunk != 0) {
2867 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2868 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2869 ShiftCarriedForwards = 0;
2872 ShiftCarriedForwards += 16;
2874 ShiftCarriedForwards -= 16;
2877 if (ShiftCarriedForwards)
2878 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2881 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2886bool MipsAsmParser::expandLoadImm(MCInst &Inst,
bool Is32BitImm, SMLoc IDLoc,
2887 MCStreamer &Out,
const MCSubtargetInfo *STI) {
2889 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
2890 const MCOperand &DstRegOp = Inst.
getOperand(0);
2891 assert(DstRegOp.
isReg() &&
"expected register operand kind");
2893 if (loadImmediate(ImmOp.
getImm(), DstRegOp.
getReg(), MCRegister(), Is32BitImm,
2894 false, IDLoc, Out, STI))
2900bool MipsAsmParser::expandLoadAddress(MCRegister DstReg, MCRegister BaseReg,
2902 bool Is32BitAddress, SMLoc IDLoc,
2904 const MCSubtargetInfo *STI) {
2906 if (Is32BitAddress &&
ABI.ArePtrs64bit()) {
2907 Warning(IDLoc,
"la used to load 64-bit address");
2909 Is32BitAddress =
false;
2913 if (!Is32BitAddress && !hasMips3()) {
2914 Error(IDLoc,
"instruction requires a 64-bit architecture");
2919 return loadAndAddSymbolAddress(
Offset.getExpr(), DstReg, BaseReg,
2920 Is32BitAddress, IDLoc, Out, STI);
2922 if (!
ABI.ArePtrs64bit()) {
2924 Is32BitAddress =
true;
2927 return loadImmediate(
Offset.getImm(), DstReg, BaseReg, Is32BitAddress,
true,
2931bool MipsAsmParser::loadAndAddSymbolAddress(
const MCExpr *SymExpr,
2933 MCRegister SrcReg,
bool Is32BitSym,
2934 SMLoc IDLoc, MCStreamer &Out,
2935 const MCSubtargetInfo *STI) {
2936 MipsTargetStreamer &TOut = getTargetStreamer();
2938 SrcReg.
isValid() && SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64;
2939 warnIfNoMacro(IDLoc);
2944 Error(IDLoc,
"expected relocatable expression");
2948 Error(IDLoc,
"expected relocatable expression with only one symbol");
2952 bool IsPtr64 =
ABI.ArePtrs64bit();
2956 static_cast<const MCSymbolELF *
>(Res.
getAddSym())->getBinding() ==
2963 bool UseXGOT = STI->
hasFeature(Mips::FeatureXGOT) && !IsLocalSym;
2969 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2972 const MCExpr *CallHiExpr =
2974 const MCExpr *CallLoExpr =
2978 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, DstReg, GPReg,
2980 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, DstReg,
2983 const MCExpr *CallExpr =
2985 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, GPReg,
2991 MCRegister TmpReg = DstReg;
2993 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2997 MCRegister ATReg = getATReg(IDLoc);
3016 const MCExpr *CallHiExpr =
3023 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg, GPReg,
3025 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, TmpReg,
3029 TOut.
emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3035 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3040 const MCSpecifierExpr *GotExpr =
nullptr;
3041 const MCExpr *LoExpr =
nullptr;
3042 if (
ABI.IsN32() ||
ABI.IsN64()) {
3061 Error(IDLoc,
"macro instruction uses large offset, which is not "
3062 "currently supported");
3091 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, GPReg,
3095 TOut.
emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3099 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3105 const auto *HiExpr =
3107 const auto *LoExpr =
3111 if (
ABI.ArePtrs64bit() && isGP64bit()) {
3119 const auto *HighestExpr =
3121 const auto *HigherExpr =
3126 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
3128 if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
3129 MCRegister ATReg = getATReg(IDLoc);
3141 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3143 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3146 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3149 TOut.
emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
3152 }
else if (canUseATReg() && !RdRegIsRsReg && DstReg != getATReg(IDLoc)) {
3153 MCRegister ATReg = getATReg(IDLoc);
3169 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3173 TOut.
emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3174 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3176 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3179 }
else if ((!canUseATReg() && !RdRegIsRsReg) ||
3180 (canUseATReg() && DstReg == getATReg(IDLoc))) {
3191 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3193 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3194 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3196 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3197 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3200 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3206 assert(SrcReg == DstReg && !canUseATReg() &&
3207 "Could have expanded dla but didn't?");
3208 reportParseError(IDLoc,
3209 "pseudo-instruction requires $at, which is not available");
3223 MCRegister TmpReg = DstReg;
3225 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
3228 MCRegister ATReg = getATReg(IDLoc);
3239 TOut.
emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3242 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
3251 if (MipsMCRegisterClasses[Mips::FGR32RegClassID].
contains(
Reg))
3252 return Reg == (
unsigned)Mips::F31 ? (
unsigned)Mips::F0 :
Reg + 1;
3254 default:
llvm_unreachable(
"Unknown register in assembly macro expansion!");
3255 case Mips::ZERO:
return Mips::AT;
3256 case Mips::AT:
return Mips::V0;
3257 case Mips::V0:
return Mips::V1;
3258 case Mips::V1:
return Mips::A0;
3259 case Mips::A0:
return Mips::A1;
3260 case Mips::A1:
return Mips::A2;
3261 case Mips::A2:
return Mips::A3;
3262 case Mips::A3:
return Mips::T0;
3263 case Mips::T0:
return Mips::T1;
3264 case Mips::T1:
return Mips::T2;
3265 case Mips::T2:
return Mips::T3;
3266 case Mips::T3:
return Mips::T4;
3267 case Mips::T4:
return Mips::T5;
3268 case Mips::T5:
return Mips::T6;
3269 case Mips::T6:
return Mips::T7;
3270 case Mips::T7:
return Mips::S0;
3271 case Mips::S0:
return Mips::S1;
3272 case Mips::S1:
return Mips::S2;
3273 case Mips::S2:
return Mips::S3;
3274 case Mips::S3:
return Mips::S4;
3275 case Mips::S4:
return Mips::S5;
3276 case Mips::S5:
return Mips::S6;
3277 case Mips::S6:
return Mips::S7;
3278 case Mips::S7:
return Mips::T8;
3279 case Mips::T8:
return Mips::T9;
3280 case Mips::T9:
return Mips::K0;
3281 case Mips::K0:
return Mips::K1;
3282 case Mips::K1:
return Mips::GP;
3283 case Mips::GP:
return Mips::SP;
3284 case Mips::SP:
return Mips::FP;
3285 case Mips::FP:
return Mips::RA;
3286 case Mips::RA:
return Mips::ZERO;
3287 case Mips::D0:
return Mips::F1;
3288 case Mips::D1:
return Mips::F3;
3289 case Mips::D2:
return Mips::F5;
3290 case Mips::D3:
return Mips::F7;
3291 case Mips::D4:
return Mips::F9;
3292 case Mips::D5:
return Mips::F11;
3293 case Mips::D6:
return Mips::F13;
3294 case Mips::D7:
return Mips::F15;
3295 case Mips::D8:
return Mips::F17;
3296 case Mips::D9:
return Mips::F19;
3297 case Mips::D10:
return Mips::F21;
3298 case Mips::D11:
return Mips::F23;
3299 case Mips::D12:
return Mips::F25;
3300 case Mips::D13:
return Mips::F27;
3301 case Mips::D14:
return Mips::F29;
3302 case Mips::D15:
return Mips::F31;
3312bool MipsAsmParser::emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc,
3314 MCRegister ATReg = getATReg(IDLoc);
3320 const auto *GotExpr =
3323 if(isABI_O32() || isABI_N32()) {
3332 const auto *HiExpr =
3341 if(isABI_O32() || isABI_N32()) {
3345 const auto *HighestExpr =
3348 const auto *HigherExpr =
3353 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3355 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3358 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3367 if ((
Hi_32(ImmOp64) & 0x7ff00000) == 0) {
3378 float TmpFloat =
static_cast<float>(DoubleImm);
3382bool MipsAsmParser::expandLoadSingleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3384 const MCSubtargetInfo *STI) {
3387 "Invalid instruction operand.");
3394 return loadImmediate(ImmOp32, FirstReg, MCRegister(),
true,
false, IDLoc, Out,
3398bool MipsAsmParser::expandLoadSingleImmToFPR(MCInst &Inst, SMLoc IDLoc,
3400 const MCSubtargetInfo *STI) {
3401 MipsTargetStreamer &TOut = getTargetStreamer();
3404 "Invalid instruction operand.");
3413 MCRegister TmpReg = Mips::ZERO;
3415 TmpReg = getATReg(IDLoc);
3420 if (
Lo_32(ImmOp64) == 0) {
3421 if (TmpReg != Mips::ZERO && loadImmediate(ImmOp32, TmpReg, MCRegister(),
3422 true,
false, IDLoc, Out, STI))
3424 TOut.
emitRR(Mips::MTC1, FirstReg, TmpReg, IDLoc, STI);
3428 MCSection *CS = getStreamer().getCurrentSectionOnly();
3431 MCSection *ReadOnlySection =
3438 getStreamer().switchSection(ReadOnlySection);
3439 getStreamer().emitLabel(Sym, IDLoc);
3440 getStreamer().emitInt32(ImmOp32);
3441 getStreamer().switchSection(CS);
3443 if (emitPartialAddress(TOut, IDLoc, Sym))
3450bool MipsAsmParser::expandLoadDoubleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3452 const MCSubtargetInfo *STI) {
3453 MipsTargetStreamer &TOut = getTargetStreamer();
3456 "Invalid instruction operand.");
3463 if (
Lo_32(ImmOp64) == 0) {
3465 if (loadImmediate(ImmOp64, FirstReg, MCRegister(),
false,
false, IDLoc,
3469 if (loadImmediate(
Hi_32(ImmOp64), FirstReg, MCRegister(),
true,
false,
3473 if (loadImmediate(0,
nextReg(FirstReg), MCRegister(),
true,
false, IDLoc,
3480 MCSection *CS = getStreamer().getCurrentSectionOnly();
3481 MCSection *ReadOnlySection =
3488 getStreamer().switchSection(ReadOnlySection);
3489 getStreamer().emitLabel(Sym, IDLoc);
3490 getStreamer().emitValueToAlignment(
Align(8));
3491 getStreamer().emitIntValue(ImmOp64, 8);
3492 getStreamer().switchSection(CS);
3494 MCRegister TmpReg = getATReg(IDLoc);
3498 if (emitPartialAddress(TOut, IDLoc, Sym))
3501 TOut.
emitRRX(isABI_N64() ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3505 TOut.
emitRRI(Mips::LD, FirstReg, TmpReg, 0, IDLoc, STI);
3507 TOut.
emitRRI(Mips::LW, FirstReg, TmpReg, 0, IDLoc, STI);
3508 TOut.
emitRRI(Mips::LW,
nextReg(FirstReg), TmpReg, 4, IDLoc, STI);
3513bool MipsAsmParser::expandLoadDoubleImmToFPR(MCInst &Inst,
bool Is64FPU,
3514 SMLoc IDLoc, MCStreamer &Out,
3515 const MCSubtargetInfo *STI) {
3516 MipsTargetStreamer &TOut = getTargetStreamer();
3519 "Invalid instruction operand.");
3526 MCRegister TmpReg = Mips::ZERO;
3528 TmpReg = getATReg(IDLoc);
3533 if ((
Lo_32(ImmOp64) == 0) &&
3534 !((
Hi_32(ImmOp64) & 0xffff0000) && (
Hi_32(ImmOp64) & 0x0000ffff))) {
3536 if (TmpReg != Mips::ZERO && loadImmediate(ImmOp64, TmpReg, MCRegister(),
3537 false,
false, IDLoc, Out, STI))
3539 TOut.
emitRR(Mips::DMTC1, FirstReg, TmpReg, IDLoc, STI);
3543 if (TmpReg != Mips::ZERO &&
3544 loadImmediate(
Hi_32(ImmOp64), TmpReg, MCRegister(),
true,
false, IDLoc,
3548 if (hasMips32r2()) {
3549 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3550 TOut.
emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, TmpReg, IDLoc, STI);
3552 TOut.
emitRR(Mips::MTC1,
nextReg(FirstReg), TmpReg, IDLoc, STI);
3553 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3558 MCSection *CS = getStreamer().getCurrentSectionOnly();
3561 MCSection *ReadOnlySection =
3568 getStreamer().switchSection(ReadOnlySection);
3569 getStreamer().emitLabel(Sym, IDLoc);
3570 getStreamer().emitValueToAlignment(
Align(8));
3571 getStreamer().emitIntValue(ImmOp64, 8);
3572 getStreamer().switchSection(CS);
3574 if (emitPartialAddress(TOut, IDLoc, Sym))
3577 TOut.
emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, TmpReg,
3583bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
3585 const MCSubtargetInfo *STI) {
3586 MipsTargetStreamer &TOut = getTargetStreamer();
3589 "unexpected number of operands");
3599 assert(
Offset.isImm() &&
"expected immediate operand kind");
3603 if (inMicroMipsMode())
3604 Inst.
setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3607 return Error(IDLoc,
"branch target out of range");
3609 return Error(IDLoc,
"branch to misaligned address");
3621 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
3628bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3629 const MCSubtargetInfo *STI) {
3630 MipsTargetStreamer &TOut = getTargetStreamer();
3631 const MCOperand &DstRegOp = Inst.
getOperand(0);
3632 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3635 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
3637 const MCOperand &MemOffsetOp = Inst.
getOperand(2);
3639 "expected immediate or expression operand");
3641 bool IsLikely =
false;
3651 case Mips::BEQLImmMacro:
3655 case Mips::BNELImmMacro:
3664 int64_t ImmValue = ImmOp.
getImm();
3665 if (ImmValue == 0) {
3669 TOut.
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3671 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3674 warnIfNoMacro(IDLoc);
3676 MCRegister ATReg = getATReg(IDLoc);
3680 if (loadImmediate(ImmValue, ATReg, MCRegister(), !isGP64bit(),
true, IDLoc,
3684 if (IsLikely && MemOffsetOp.
isExpr()) {
3687 TOut.
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3689 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3694void MipsAsmParser::expandMem16Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3695 const MCSubtargetInfo *STI,
bool IsLoad) {
3697 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3698 unsigned StartOp = NumOp == 3 ? 0 : 1;
3700 const MCOperand &DstRegOp = Inst.
getOperand(StartOp);
3701 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3702 const MCOperand &BaseRegOp = Inst.
getOperand(StartOp + 1);
3703 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3706 MipsTargetStreamer &TOut = getTargetStreamer();
3708 MCRegister DstReg = DstRegOp.
getReg();
3710 MCRegister TmpReg = DstReg;
3712 const MCInstrDesc &
Desc = MII.get(OpCode);
3713 int16_t DstRegClass =
3714 MII.getOpRegClassID(
Desc.operands()[StartOp],
3716 unsigned DstRegClassID =
3717 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3718 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3719 (DstRegClassID == Mips::GPR64RegClassID);
3721 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3724 TmpReg = getATReg(IDLoc);
3729 auto emitInstWithOffset = [&](
const MCOperand &
Off) {
3731 TOut.
emitRRX(OpCode, DstReg, TmpReg, Off, IDLoc, STI);
3733 TOut.
emitRRRX(OpCode, DstReg, DstReg, TmpReg, Off, IDLoc, STI);
3737 int64_t LoOffset =
OffsetOp.getImm() & 0xffff;
3738 int64_t HiOffset =
OffsetOp.getImm() & ~0xffff;
3742 if (LoOffset & 0x8000)
3743 HiOffset += 0x10000;
3745 bool IsLargeOffset = HiOffset != 0;
3747 if (IsLargeOffset) {
3749 if (loadImmediate(HiOffset, TmpReg, MCRegister(), Is32BitImm,
true, IDLoc,
3754 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3755 TOut.
emitRRR(
ABI.ArePtrs64bit() ? Mips::DADDu : Mips::ADDu, TmpReg,
3756 TmpReg, BaseReg, IDLoc, STI);
3770 if (!
OffsetOp.getExpr()->evaluateAsRelocatable(Res,
nullptr)) {
3771 Error(IDLoc,
"expected relocatable expression");
3775 Error(IDLoc,
"expected relocatable expression with only one symbol");
3779 loadAndAddSymbolAddress(
3781 BaseReg, !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3789 const MCExpr *OffExpr =
OffsetOp.getExpr();
3801 TOut.
emitRX(Mips::LUi, TmpReg, HighestOperand, IDLoc, STI);
3802 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HigherOperand, IDLoc, STI);
3803 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3804 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HiOperand, IDLoc, STI);
3805 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3806 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3807 TOut.
emitRRR(Mips::DADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3808 emitInstWithOffset(LoOperand);
3811 TOut.
emitRX(Mips::LUi, TmpReg, HiOperand, IDLoc, STI);
3812 if (BaseReg != Mips::ZERO)
3813 TOut.
emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3815 emitInstWithOffset(LoOperand);
3824void MipsAsmParser::expandMem9Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3825 const MCSubtargetInfo *STI,
bool IsLoad) {
3827 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3828 unsigned StartOp = NumOp == 3 ? 0 : 1;
3830 const MCOperand &DstRegOp = Inst.
getOperand(StartOp);
3831 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3832 const MCOperand &BaseRegOp = Inst.
getOperand(StartOp + 1);
3833 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3836 MipsTargetStreamer &TOut = getTargetStreamer();
3838 MCRegister DstReg = DstRegOp.
getReg();
3840 MCRegister TmpReg = DstReg;
3842 const MCInstrDesc &
Desc = MII.get(OpCode);
3843 int16_t DstRegClass =
3844 MII.getOpRegClassID(
Desc.operands()[StartOp],
3847 unsigned DstRegClassID =
3848 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3849 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3850 (DstRegClassID == Mips::GPR64RegClassID);
3852 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3855 TmpReg = getATReg(IDLoc);
3860 auto emitInst = [&]() {
3869 loadImmediate(
OffsetOp.getImm(), TmpReg, BaseReg, !
ABI.ArePtrs64bit(),
true,
3876 loadAndAddSymbolAddress(
OffsetOp.getExpr(), TmpReg, BaseReg,
3877 !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3885bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
3887 const MCSubtargetInfo *STI) {
3890 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3894 Inst.
getOperand(OpNum - 3).
isReg() &&
"Invalid instruction operand.");
3903 if (inMicroMipsMode() && hasMips32r6())
3904 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3906 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3914bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
3916 const MCSubtargetInfo *STI) {
3917 MipsTargetStreamer &TOut = getTargetStreamer();
3918 bool EmittedNoMacroWarning =
false;
3919 unsigned PseudoOpcode = Inst.
getOpcode();
3924 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3925 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3930 else if (TrgOp.
isImm()) {
3931 warnIfNoMacro(IDLoc);
3932 EmittedNoMacroWarning =
true;
3934 TrgReg = getATReg(IDLoc);
3938 switch(PseudoOpcode) {
3941 case Mips::BLTImmMacro:
3942 PseudoOpcode = Mips::BLT;
3944 case Mips::BLEImmMacro:
3945 PseudoOpcode = Mips::BLE;
3947 case Mips::BGEImmMacro:
3948 PseudoOpcode = Mips::BGE;
3950 case Mips::BGTImmMacro:
3951 PseudoOpcode = Mips::BGT;
3953 case Mips::BLTUImmMacro:
3954 PseudoOpcode = Mips::BLTU;
3956 case Mips::BLEUImmMacro:
3957 PseudoOpcode = Mips::BLEU;
3959 case Mips::BGEUImmMacro:
3960 PseudoOpcode = Mips::BGEU;
3962 case Mips::BGTUImmMacro:
3963 PseudoOpcode = Mips::BGTU;
3965 case Mips::BLTLImmMacro:
3966 PseudoOpcode = Mips::BLTL;
3968 case Mips::BLELImmMacro:
3969 PseudoOpcode = Mips::BLEL;
3971 case Mips::BGELImmMacro:
3972 PseudoOpcode = Mips::BGEL;
3974 case Mips::BGTLImmMacro:
3975 PseudoOpcode = Mips::BGTL;
3977 case Mips::BLTULImmMacro:
3978 PseudoOpcode = Mips::BLTUL;
3980 case Mips::BLEULImmMacro:
3981 PseudoOpcode = Mips::BLEUL;
3983 case Mips::BGEULImmMacro:
3984 PseudoOpcode = Mips::BGEUL;
3986 case Mips::BGTULImmMacro:
3987 PseudoOpcode = Mips::BGTUL;
3991 if (loadImmediate(TrgOp.
getImm(), TrgReg, MCRegister(), !isGP64bit(),
false,
3996 switch (PseudoOpcode) {
4001 AcceptsEquality =
false;
4002 ReverseOrderSLT =
false;
4004 ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
4005 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
4006 ZeroSrcOpcode = Mips::BGTZ;
4007 ZeroTrgOpcode = Mips::BLTZ;
4013 AcceptsEquality =
true;
4014 ReverseOrderSLT =
true;
4016 ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
4017 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
4018 ZeroSrcOpcode = Mips::BGEZ;
4019 ZeroTrgOpcode = Mips::BLEZ;
4025 AcceptsEquality =
true;
4026 ReverseOrderSLT =
false;
4028 ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
4029 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
4030 ZeroSrcOpcode = Mips::BLEZ;
4031 ZeroTrgOpcode = Mips::BGEZ;
4037 AcceptsEquality =
false;
4038 ReverseOrderSLT =
true;
4040 ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
4041 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
4042 ZeroSrcOpcode = Mips::BLTZ;
4043 ZeroTrgOpcode = Mips::BGTZ;
4049 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
4050 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
4051 if (IsSrcRegZero && IsTrgRegZero) {
4055 if (PseudoOpcode == Mips::BLT) {
4060 if (PseudoOpcode == Mips::BLE) {
4063 Warning(IDLoc,
"branch is always taken");
4066 if (PseudoOpcode == Mips::BGE) {
4069 Warning(IDLoc,
"branch is always taken");
4072 if (PseudoOpcode == Mips::BGT) {
4077 if (PseudoOpcode == Mips::BGTU) {
4078 TOut.
emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
4082 if (AcceptsEquality) {
4085 TOut.
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4087 Warning(IDLoc,
"branch is always taken");
4094 if (IsSrcRegZero || IsTrgRegZero) {
4095 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
4096 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
4103 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
4104 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
4110 TOut.
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4112 Warning(IDLoc,
"branch is always taken");
4128 TOut.
emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
4129 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
4136 TOut.
emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
4137 IsSrcRegZero ? TrgReg : SrcReg,
4144 MCRegister ATRegNum = getATReg(IDLoc);
4148 if (!EmittedNoMacroWarning)
4149 warnIfNoMacro(IDLoc);
4166 TOut.
emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
4167 ReverseOrderSLT ? TrgReg : SrcReg,
4168 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
4170 TOut.
emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
4171 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
4185bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4186 const MCSubtargetInfo *STI,
4187 const bool IsMips64,
const bool Signed) {
4188 MipsTargetStreamer &TOut = getTargetStreamer();
4190 warnIfNoMacro(IDLoc);
4192 const MCOperand &RdRegOp = Inst.
getOperand(0);
4193 assert(RdRegOp.
isReg() &&
"expected register operand kind");
4194 MCRegister RdReg = RdRegOp.
getReg();
4196 const MCOperand &RsRegOp = Inst.
getOperand(1);
4197 assert(RsRegOp.
isReg() &&
"expected register operand kind");
4198 MCRegister RsReg = RsRegOp.
getReg();
4205 "expected register or immediate operand kind");
4209 ImmValue = RtOp.
getImm();
4216 DivOp =
Signed ? Mips::DSDIV : Mips::DUDIV;
4217 ZeroReg = Mips::ZERO_64;
4220 DivOp =
Signed ? Mips::SDIV : Mips::UDIV;
4221 ZeroReg = Mips::ZERO;
4225 bool UseTraps = useTraps();
4228 bool isDiv = Opcode == Mips::SDivMacro || Opcode == Mips::SDivIMacro ||
4229 Opcode == Mips::UDivMacro || Opcode == Mips::UDivIMacro ||
4230 Opcode == Mips::DSDivMacro || Opcode == Mips::DSDivIMacro ||
4231 Opcode == Mips::DUDivMacro || Opcode == Mips::DUDivIMacro;
4233 bool isRem = Opcode == Mips::SRemMacro || Opcode == Mips::SRemIMacro ||
4234 Opcode == Mips::URemMacro || Opcode == Mips::URemIMacro ||
4235 Opcode == Mips::DSRemMacro || Opcode == Mips::DSRemIMacro ||
4236 Opcode == Mips::DURemMacro || Opcode == Mips::DURemIMacro;
4239 MCRegister ATReg = getATReg(IDLoc);
4245 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4247 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4251 if (isRem && (ImmValue == 1 || (
Signed && (ImmValue == -1)))) {
4252 TOut.
emitRRR(Mips::OR, RdReg, ZeroReg, ZeroReg, IDLoc, STI);
4254 }
else if (isDiv && ImmValue == 1) {
4255 TOut.
emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI);
4257 }
else if (isDiv &&
Signed && ImmValue == -1) {
4258 TOut.
emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
4261 if (loadImmediate(ImmValue, ATReg, MCRegister(),
isInt<32>(ImmValue),
4262 false, Inst.
getLoc(), Out, STI))
4264 TOut.
emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
4265 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4275 if (!
NoZeroDivCheck && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
4277 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4280 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4286 if (isRem && (RdReg == Mips::ZERO || RdReg == Mips::ZERO_64)) {
4287 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4296 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4299 TOut.
emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4302 BrTarget =
Context.createTempSymbol();
4305 TOut.
emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4310 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4316 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4320bool MipsAsmParser::expandTrunc(MCInst &Inst,
bool IsDouble,
bool Is64FPU,
4321 SMLoc IDLoc, MCStreamer &Out,
4322 const MCSubtargetInfo *STI) {
4323 MipsTargetStreamer &TOut = getTargetStreamer();
4333 if (hasMips1() && !hasMips2()) {
4334 MCRegister ATReg = getATReg(IDLoc);
4337 TOut.
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4338 TOut.
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4340 TOut.
emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4341 TOut.
emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4342 TOut.
emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4344 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4346 FirstReg, SecondReg, IDLoc, STI);
4347 TOut.
emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4352 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4354 FirstReg, SecondReg, IDLoc, STI);
4359bool MipsAsmParser::expandUlh(MCInst &Inst,
bool Signed, SMLoc IDLoc,
4360 MCStreamer &Out,
const MCSubtargetInfo *STI) {
4361 if (hasMips32r6() || hasMips64r6()) {
4362 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4365 const MCOperand &DstRegOp = Inst.
getOperand(0);
4366 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4367 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4368 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4369 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4370 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4372 MipsTargetStreamer &TOut = getTargetStreamer();
4373 MCRegister DstReg = DstRegOp.
getReg();
4374 MCRegister SrcReg = SrcRegOp.
getReg();
4375 int64_t OffsetValue = OffsetImmOp.
getImm();
4379 warnIfNoMacro(IDLoc);
4380 MCRegister ATReg = getATReg(IDLoc);
4385 if (IsLargeOffset) {
4386 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4391 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4392 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4396 MCRegister FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4397 MCRegister SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4399 MCRegister LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4400 MCRegister SllReg = IsLargeOffset ? DstReg : ATReg;
4402 TOut.
emitRRI(
Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4403 FirstOffset, IDLoc, STI);
4404 TOut.
emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4405 TOut.
emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4406 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4411bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4412 const MCSubtargetInfo *STI) {
4413 if (hasMips32r6() || hasMips64r6()) {
4414 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4417 const MCOperand &DstRegOp = Inst.
getOperand(0);
4418 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4419 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4420 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4421 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4422 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4424 MipsTargetStreamer &TOut = getTargetStreamer();
4425 MCRegister DstReg = DstRegOp.
getReg();
4426 MCRegister SrcReg = SrcRegOp.
getReg();
4427 int64_t OffsetValue = OffsetImmOp.
getImm();
4429 warnIfNoMacro(IDLoc);
4430 MCRegister ATReg = getATReg(IDLoc);
4435 if (IsLargeOffset) {
4436 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4441 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4442 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4446 if (IsLargeOffset) {
4447 TOut.
emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4448 TOut.
emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4449 TOut.
emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4450 TOut.
emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4451 TOut.
emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4452 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4454 TOut.
emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4455 TOut.
emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4456 TOut.
emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4462bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4463 const MCSubtargetInfo *STI) {
4464 if (hasMips32r6() || hasMips64r6()) {
4465 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4468 const MCOperand &DstRegOp = Inst.
getOperand(0);
4469 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4470 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4471 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4472 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4473 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4475 MipsTargetStreamer &TOut = getTargetStreamer();
4476 MCRegister DstReg = DstRegOp.
getReg();
4477 MCRegister SrcReg = SrcRegOp.
getReg();
4478 int64_t OffsetValue = OffsetImmOp.
getImm();
4482 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4483 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4487 bool IsLoadInst = (Inst.
getOpcode() == Mips::Ulw);
4488 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4489 MCRegister TmpReg = SrcReg;
4490 if (IsLargeOffset || DoMove) {
4491 warnIfNoMacro(IDLoc);
4492 TmpReg = getATReg(IDLoc);
4497 if (IsLargeOffset) {
4498 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4506 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4507 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4508 TOut.
emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4509 TOut.
emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4512 TOut.
emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4517bool MipsAsmParser::expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4518 const MCSubtargetInfo *STI) {
4519 MipsTargetStreamer &TOut = getTargetStreamer();
4531 warnIfNoMacro(IDLoc);
4545 TOut.
emitRRR(OpCode, DstReg, SrcReg, OpReg, IDLoc, STI);
4546 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4551bool MipsAsmParser::expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4552 const MCSubtargetInfo *STI) {
4553 MipsTargetStreamer &TOut = getTargetStreamer();
4563 unsigned OpRegCode, OpImmCode;
4565 warnIfNoMacro(IDLoc);
4569 case Mips::SGEImm64:
4570 OpRegCode = Mips::SLT;
4571 OpImmCode = Mips::SLTi;
4574 case Mips::SGEUImm64:
4575 OpRegCode = Mips::SLTu;
4576 OpImmCode = Mips::SLTiu;
4585 TOut.
emitRRI(OpImmCode, DstReg, SrcReg, ImmValue, IDLoc, STI);
4586 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4588 MCRegister ImmReg = DstReg;
4589 if (DstReg == SrcReg) {
4590 MCRegister ATReg = getATReg(Inst.
getLoc());
4596 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
4597 false, IDLoc, Out, STI))
4600 TOut.
emitRRR(OpRegCode, DstReg, SrcReg, ImmReg, IDLoc, STI);
4601 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4607bool MipsAsmParser::expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4608 const MCSubtargetInfo *STI) {
4609 MipsTargetStreamer &TOut = getTargetStreamer();
4618 MCRegister ImmReg = DstReg;
4622 warnIfNoMacro(IDLoc);
4626 case Mips::SGTImm64:
4630 case Mips::SGTUImm64:
4637 if (DstReg == SrcReg) {
4638 MCRegister ATReg = getATReg(Inst.
getLoc());
4644 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
false,
4649 TOut.
emitRRR(OpCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4654bool MipsAsmParser::expandSle(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4655 const MCSubtargetInfo *STI) {
4656 MipsTargetStreamer &TOut = getTargetStreamer();
4668 warnIfNoMacro(IDLoc);
4682 TOut.
emitRRR(OpCode, DstReg, OpReg, SrcReg, IDLoc, STI);
4683 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4688bool MipsAsmParser::expandSleImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4689 const MCSubtargetInfo *STI) {
4690 MipsTargetStreamer &TOut = getTargetStreamer();
4702 warnIfNoMacro(IDLoc);
4706 case Mips::SLEImm64:
4707 OpRegCode = Mips::SLT;
4710 case Mips::SLEUImm64:
4711 OpRegCode = Mips::SLTu;
4718 MCRegister ImmReg = DstReg;
4719 if (DstReg == SrcReg) {
4720 MCRegister ATReg = getATReg(Inst.
getLoc());
4726 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
false,
4730 TOut.
emitRRR(OpRegCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4731 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4736bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
4738 const MCSubtargetInfo *STI) {
4739 MipsTargetStreamer &TOut = getTargetStreamer();
4747 MCRegister FinalDstReg;
4754 unsigned FinalOpcode = Inst.
getOpcode();
4756 if (DstReg == SrcReg) {
4757 ATReg = getATReg(Inst.
getLoc());
4760 FinalDstReg = DstReg;
4764 if (!loadImmediate(ImmValue, DstReg, MCRegister(), Is32Bit,
false,
4765 Inst.
getLoc(), Out, STI)) {
4766 switch (FinalOpcode) {
4770 FinalOpcode = Mips::ADD;
4773 FinalOpcode = Mips::ADDu;
4776 FinalOpcode = Mips::AND;
4779 FinalOpcode = Mips::NOR;
4782 FinalOpcode = Mips::OR;
4785 FinalOpcode = Mips::SLT;
4788 FinalOpcode = Mips::SLTu;
4791 FinalOpcode = Mips::XOR;
4794 FinalOpcode = Mips::ADD_MM;
4796 case Mips::ADDiu_MM:
4797 FinalOpcode = Mips::ADDu_MM;
4800 FinalOpcode = Mips::AND_MM;
4803 FinalOpcode = Mips::OR_MM;
4806 FinalOpcode = Mips::SLT_MM;
4808 case Mips::SLTiu_MM:
4809 FinalOpcode = Mips::SLTu_MM;
4812 FinalOpcode = Mips::XOR_MM;
4815 FinalOpcode = Mips::AND64;
4817 case Mips::NORImm64:
4818 FinalOpcode = Mips::NOR64;
4821 FinalOpcode = Mips::OR64;
4823 case Mips::SLTImm64:
4824 FinalOpcode = Mips::SLT64;
4826 case Mips::SLTUImm64:
4827 FinalOpcode = Mips::SLTu64;
4830 FinalOpcode = Mips::XOR64;
4835 TOut.
emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4837 TOut.
emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4843bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4844 const MCSubtargetInfo *STI) {
4845 MipsTargetStreamer &TOut = getTargetStreamer();
4850 MCRegister TmpReg =
DReg;
4852 unsigned FirstShift = Mips::NOP;
4853 unsigned SecondShift = Mips::NOP;
4855 if (hasMips32r2()) {
4857 TmpReg = getATReg(Inst.
getLoc());
4863 TOut.
emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4864 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
4869 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
4881 FirstShift = Mips::SRLV;
4882 SecondShift = Mips::SLLV;
4885 FirstShift = Mips::SLLV;
4886 SecondShift = Mips::SRLV;
4890 ATReg = getATReg(Inst.
getLoc());
4894 TOut.
emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4895 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
4896 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
4897 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
4905bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
4907 const MCSubtargetInfo *STI) {
4908 MipsTargetStreamer &TOut = getTargetStreamer();
4914 unsigned FirstShift = Mips::NOP;
4915 unsigned SecondShift = Mips::NOP;
4917 if (hasMips32r2()) {
4919 uint64_t MaxShift = 32;
4920 uint64_t ShiftValue = ImmValue;
4922 ShiftValue = MaxShift - ImmValue;
4923 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
4928 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.
getLoc(), STI);
4936 if (ImmValue == 0) {
4945 FirstShift = Mips::SLL;
4946 SecondShift = Mips::SRL;
4949 FirstShift = Mips::SRL;
4950 SecondShift = Mips::SLL;
4954 ATReg = getATReg(Inst.
getLoc());
4958 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.
getLoc(), STI);
4959 TOut.
emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.
getLoc(), STI);
4960 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
4968bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4969 const MCSubtargetInfo *STI) {
4970 MipsTargetStreamer &TOut = getTargetStreamer();
4975 MCRegister TmpReg =
DReg;
4977 unsigned FirstShift = Mips::NOP;
4978 unsigned SecondShift = Mips::NOP;
4980 if (hasMips64r2()) {
4981 if (TmpReg == SReg) {
4982 TmpReg = getATReg(Inst.
getLoc());
4988 TOut.
emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4989 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
4994 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
5006 FirstShift = Mips::DSRLV;
5007 SecondShift = Mips::DSLLV;
5010 FirstShift = Mips::DSLLV;
5011 SecondShift = Mips::DSRLV;
5015 ATReg = getATReg(Inst.
getLoc());
5019 TOut.
emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
5020 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
5021 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
5022 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5030bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
5032 const MCSubtargetInfo *STI) {
5033 MipsTargetStreamer &TOut = getTargetStreamer();
5039 unsigned FirstShift = Mips::NOP;
5040 unsigned SecondShift = Mips::NOP;
5044 if (hasMips64r2()) {
5045 unsigned FinalOpcode = Mips::NOP;
5047 FinalOpcode = Mips::DROTR;
5048 else if (ImmValue % 32 == 0)
5049 FinalOpcode = Mips::DROTR32;
5050 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
5052 FinalOpcode = Mips::DROTR32;
5054 FinalOpcode = Mips::DROTR;
5055 }
else if (ImmValue >= 33) {
5057 FinalOpcode = Mips::DROTR;
5059 FinalOpcode = Mips::DROTR32;
5062 uint64_t ShiftValue = ImmValue % 32;
5064 ShiftValue = (32 - ImmValue % 32) % 32;
5066 TOut.
emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
5072 if (ImmValue == 0) {
5073 TOut.
emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.
getLoc(), STI);
5081 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5082 FirstShift = Mips::DSLL;
5083 SecondShift = Mips::DSRL32;
5085 if (ImmValue == 32) {
5086 FirstShift = Mips::DSLL32;
5087 SecondShift = Mips::DSRL32;
5089 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5090 FirstShift = Mips::DSLL32;
5091 SecondShift = Mips::DSRL;
5095 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5096 FirstShift = Mips::DSRL;
5097 SecondShift = Mips::DSLL32;
5099 if (ImmValue == 32) {
5100 FirstShift = Mips::DSRL32;
5101 SecondShift = Mips::DSLL32;
5103 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5104 FirstShift = Mips::DSRL32;
5105 SecondShift = Mips::DSLL;
5110 ATReg = getATReg(Inst.
getLoc());
5114 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.
getLoc(), STI);
5115 TOut.
emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
5117 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5125bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5126 const MCSubtargetInfo *STI) {
5127 MipsTargetStreamer &TOut = getTargetStreamer();
5131 TOut.
emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
5132 if (FirstRegOp != SecondRegOp)
5133 TOut.
emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
5136 TOut.
emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
5141bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5142 const MCSubtargetInfo *STI) {
5143 MipsTargetStreamer &TOut = getTargetStreamer();
5149 ATReg = getATReg(IDLoc);
5153 loadImmediate(ImmValue, ATReg, MCRegister(),
true,
false, IDLoc, Out, STI);
5155 TOut.
emitRR(Inst.
getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
5156 SrcReg, ATReg, IDLoc, STI);
5158 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5163bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5164 const MCSubtargetInfo *STI) {
5165 MipsTargetStreamer &TOut = getTargetStreamer();
5171 ATReg = getATReg(Inst.
getLoc());
5175 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
5176 SrcReg, TmpReg, IDLoc, STI);
5178 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5180 TOut.
emitRRI(Inst.
getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
5181 DstReg, DstReg, 0x1F, IDLoc, STI);
5183 TOut.
emitR(Mips::MFHI, ATReg, IDLoc, STI);
5186 TOut.
emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
5193 TOut.
emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
5194 if (AssemblerOptions.
back()->isReorder())
5196 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5200 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5205bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5206 const MCSubtargetInfo *STI) {
5207 MipsTargetStreamer &TOut = getTargetStreamer();
5213 ATReg = getATReg(IDLoc);
5217 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
5218 SrcReg, TmpReg, IDLoc, STI);
5220 TOut.
emitR(Mips::MFHI, ATReg, IDLoc, STI);
5221 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5223 TOut.
emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);
5230 TOut.
emitRRX(Mips::BEQ, ATReg, Mips::ZERO, LabelOp, IDLoc, STI);
5231 if (AssemblerOptions.
back()->isReorder())
5233 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5241bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5242 const MCSubtargetInfo *STI) {
5243 MipsTargetStreamer &TOut = getTargetStreamer();
5248 TOut.
emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
5249 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5259bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
5261 const MCSubtargetInfo *STI,
5266 warnIfNoMacro(IDLoc);
5268 MipsTargetStreamer &TOut = getTargetStreamer();
5269 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
5271 MCRegister SecondReg =
nextReg(FirstReg);
5276 warnIfRegIndexIsAT(FirstReg, IDLoc);
5279 "Offset for load macro is not immediate!");
5282 signed NextOffset = FirstOffset.
getImm() + 4;
5290 if (FirstReg != BaseReg || !IsLoad) {
5291 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5292 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5294 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5295 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5307bool MipsAsmParser::expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc,
5309 const MCSubtargetInfo *STI) {
5313 warnIfNoMacro(IDLoc);
5315 MipsTargetStreamer &TOut = getTargetStreamer();
5316 unsigned Opcode = Mips::SWC1;
5318 MCRegister SecondReg =
nextReg(FirstReg);
5323 warnIfRegIndexIsAT(FirstReg, IDLoc);
5326 "Offset for macro is not immediate!");
5329 signed NextOffset = FirstOffset.
getImm() + 4;
5335 if (!IsLittleEndian)
5338 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5339 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5344bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5345 const MCSubtargetInfo *STI) {
5346 MipsTargetStreamer &TOut = getTargetStreamer();
5357 warnIfNoMacro(IDLoc);
5359 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5360 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5361 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5365 MCRegister
Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5366 TOut.
emitRRI(Mips::SLTiu, DstReg,
Reg, 1, IDLoc, STI);
5370bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5371 const MCSubtargetInfo *STI) {
5372 MipsTargetStreamer &TOut = getTargetStreamer();
5383 warnIfNoMacro(IDLoc);
5386 TOut.
emitRRI(Mips::SLTiu, DstReg, SrcReg, 1, IDLoc, STI);
5390 if (SrcReg == Mips::ZERO) {
5391 Warning(IDLoc,
"comparison is always false");
5392 TOut.
emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
5393 DstReg, SrcReg, SrcReg, IDLoc, STI);
5398 if (Imm > -0x8000 && Imm < 0) {
5400 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5406 MCRegister ATReg = getATReg(IDLoc);
5410 if (loadImmediate(Imm, ATReg, MCRegister(),
true, isGP64bit(), IDLoc, Out,
5414 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5415 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5419 TOut.
emitRRI(
Opc, DstReg, SrcReg, Imm, IDLoc, STI);
5420 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5424bool MipsAsmParser::expandSne(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5425 const MCSubtargetInfo *STI) {
5427 MipsTargetStreamer &TOut = getTargetStreamer();
5438 warnIfNoMacro(IDLoc);
5440 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5441 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5442 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5446 MCRegister
Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5447 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO,
Reg, IDLoc, STI);
5451bool MipsAsmParser::expandSneI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5452 const MCSubtargetInfo *STI) {
5453 MipsTargetStreamer &TOut = getTargetStreamer();
5464 warnIfNoMacro(IDLoc);
5466 if (ImmValue == 0) {
5467 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, SrcReg, IDLoc, STI);
5471 if (SrcReg == Mips::ZERO) {
5472 Warning(IDLoc,
"comparison is always true");
5473 if (loadImmediate(1, DstReg, MCRegister(),
true,
false, IDLoc, Out, STI))
5479 if (ImmValue > -0x8000 && ImmValue < 0) {
5480 ImmValue = -ImmValue;
5481 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5487 TOut.
emitRRI(
Opc, DstReg, SrcReg, ImmValue, IDLoc, STI);
5488 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5492 MCRegister ATReg = getATReg(IDLoc);
5496 if (loadImmediate(ImmValue, ATReg, MCRegister(),
isInt<32>(ImmValue),
false,
5500 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5501 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5564 case Mips::F0:
return Mips::ZERO;
5565 case Mips::F1:
return Mips::AT;
5566 case Mips::F2:
return Mips::V0;
5567 case Mips::F3:
return Mips::V1;
5568 case Mips::F4:
return Mips::A0;
5569 case Mips::F5:
return Mips::A1;
5570 case Mips::F6:
return Mips::A2;
5571 case Mips::F7:
return Mips::A3;
5572 case Mips::F8:
return Mips::T0;
5573 case Mips::F9:
return Mips::T1;
5574 case Mips::F10:
return Mips::T2;
5575 case Mips::F11:
return Mips::T3;
5576 case Mips::F12:
return Mips::T4;
5577 case Mips::F13:
return Mips::T5;
5578 case Mips::F14:
return Mips::T6;
5579 case Mips::F15:
return Mips::T7;
5580 case Mips::F16:
return Mips::S0;
5581 case Mips::F17:
return Mips::S1;
5582 case Mips::F18:
return Mips::S2;
5583 case Mips::F19:
return Mips::S3;
5584 case Mips::F20:
return Mips::S4;
5585 case Mips::F21:
return Mips::S5;
5586 case Mips::F22:
return Mips::S6;
5587 case Mips::F23:
return Mips::S7;
5588 case Mips::F24:
return Mips::T8;
5589 case Mips::F25:
return Mips::T9;
5590 case Mips::F26:
return Mips::K0;
5591 case Mips::F27:
return Mips::K1;
5592 case Mips::F28:
return Mips::GP;
5593 case Mips::F29:
return Mips::SP;
5594 case Mips::F30:
return Mips::FP;
5595 case Mips::F31:
return Mips::RA;
5603 case Mips::COP00:
return Mips::ZERO;
5604 case Mips::COP01:
return Mips::AT;
5605 case Mips::COP02:
return Mips::V0;
5606 case Mips::COP03:
return Mips::V1;
5607 case Mips::COP04:
return Mips::A0;
5608 case Mips::COP05:
return Mips::A1;
5609 case Mips::COP06:
return Mips::A2;
5610 case Mips::COP07:
return Mips::A3;
5611 case Mips::COP08:
return Mips::T0;
5612 case Mips::COP09:
return Mips::T1;
5613 case Mips::COP010:
return Mips::T2;
5614 case Mips::COP011:
return Mips::T3;
5615 case Mips::COP012:
return Mips::T4;
5616 case Mips::COP013:
return Mips::T5;
5617 case Mips::COP014:
return Mips::T6;
5618 case Mips::COP015:
return Mips::T7;
5619 case Mips::COP016:
return Mips::S0;
5620 case Mips::COP017:
return Mips::S1;
5621 case Mips::COP018:
return Mips::S2;
5622 case Mips::COP019:
return Mips::S3;
5623 case Mips::COP020:
return Mips::S4;
5624 case Mips::COP021:
return Mips::S5;
5625 case Mips::COP022:
return Mips::S6;
5626 case Mips::COP023:
return Mips::S7;
5627 case Mips::COP024:
return Mips::T8;
5628 case Mips::COP025:
return Mips::T9;
5629 case Mips::COP026:
return Mips::K0;
5630 case Mips::COP027:
return Mips::K1;
5631 case Mips::COP028:
return Mips::GP;
5632 case Mips::COP029:
return Mips::SP;
5633 case Mips::COP030:
return Mips::FP;
5634 case Mips::COP031:
return Mips::RA;
5641bool MipsAsmParser::expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5642 const MCSubtargetInfo *STI) {
5643 MipsTargetStreamer &TOut = getTargetStreamer();
5648 bool IsMFTR =
false;
5702 IsMFTR ? MCRegister(rd)
5704 : Inst.getOperand(0).
getReg());
5706 TOut.
emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, u, sel, h, IDLoc,
5711bool MipsAsmParser::expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5712 const MCSubtargetInfo *STI) {
5717 warnIfNoMacro(IDLoc);
5719 MipsTargetStreamer &TOut = getTargetStreamer();
5720 unsigned Opcode = Inst.
getOpcode() == Mips::SaaAddr ? Mips::SAA : Mips::SAAD;
5723 const MCOperand &BaseOp = Inst.
getOperand(2);
5725 if (BaseOp.
isImm()) {
5726 int64_t ImmValue = BaseOp.
getImm();
5727 if (ImmValue == 0) {
5728 TOut.
emitRR(Opcode, RtReg, BaseReg, IDLoc, STI);
5733 MCRegister ATReg = getATReg(IDLoc);
5737 if (expandLoadAddress(ATReg, BaseReg, BaseOp, !isGP64bit(), IDLoc, Out, STI))
5740 TOut.
emitRR(Opcode, RtReg, ATReg, IDLoc, STI);
5745MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
5749 return Match_Success;
5752 if (
static_cast<MipsOperand &
>(*Operands[1])
5753 .isValidForTie(
static_cast<MipsOperand &
>(*Operands[2])))
5754 return Match_Success;
5755 return Match_RequiresSameSrcAndDst;
5759unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
5766 return Match_RequiresNoZeroRegister;
5767 return Match_Success;
5773 case Mips::JALR_HB64:
5774 case Mips::JALRC_HB_MMR6:
5775 case Mips::JALRC_MMR6:
5777 return Match_RequiresDifferentSrcAndDst;
5778 return Match_Success;
5781 return Match_RequiresDifferentSrcAndDst;
5782 return Match_Success;
5785 return Match_NonZeroOperandForSync;
5786 return Match_Success;
5792 return Match_NonZeroOperandForMTCX;
5793 return Match_Success;
5806 case Mips::BLEZC:
case Mips::BLEZC_MMR6:
5807 case Mips::BGEZC:
case Mips::BGEZC_MMR6:
5808 case Mips::BGTZC:
case Mips::BGTZC_MMR6:
5809 case Mips::BLTZC:
case Mips::BLTZC_MMR6:
5810 case Mips::BEQZC:
case Mips::BEQZC_MMR6:
5811 case Mips::BNEZC:
case Mips::BNEZC_MMR6:
5820 return Match_RequiresNoZeroRegister;
5821 return Match_Success;
5822 case Mips::BGEC:
case Mips::BGEC_MMR6:
5823 case Mips::BLTC:
case Mips::BLTC_MMR6:
5824 case Mips::BGEUC:
case Mips::BGEUC_MMR6:
5825 case Mips::BLTUC:
case Mips::BLTUC_MMR6:
5826 case Mips::BEQC:
case Mips::BEQC_MMR6:
5827 case Mips::BNEC:
case Mips::BNEC_MMR6:
5836 return Match_RequiresNoZeroRegister;
5839 return Match_RequiresNoZeroRegister;
5841 return Match_RequiresDifferentOperands;
5842 return Match_Success;
5845 "Operands must be immediates for dins!");
5848 if ((0 > (Pos +
Size)) || ((Pos +
Size) > 32))
5849 return Match_RequiresPosSizeRange0_32;
5850 return Match_Success;
5855 "Operands must be immediates for dinsm/dinsu!");
5858 if ((32 >= (Pos +
Size)) || ((Pos +
Size) > 64))
5859 return Match_RequiresPosSizeRange33_64;
5860 return Match_Success;
5864 "Operands must be immediates for DEXTM!");
5867 if ((1 > (Pos +
Size)) || ((Pos +
Size) > 63))
5868 return Match_RequiresPosSizeUImm6;
5869 return Match_Success;
5874 "Operands must be immediates for dextm/dextu!");
5877 if ((32 > (Pos +
Size)) || ((Pos +
Size) > 64))
5878 return Match_RequiresPosSizeRange33_64;
5879 return Match_Success;
5881 case Mips::CRC32B:
case Mips::CRC32CB:
5882 case Mips::CRC32H:
case Mips::CRC32CH:
5883 case Mips::CRC32W:
case Mips::CRC32CW:
5884 case Mips::CRC32D:
case Mips::CRC32CD:
5886 return Match_RequiresSameSrcAndDst;
5887 return Match_Success;
5890 uint64_t TSFlags = MII.get(Inst.
getOpcode()).TSFlags;
5893 return Match_NoFCCRegisterForCurrentISA;
5895 return Match_Success;
5903 if (ErrorLoc ==
SMLoc())
5910bool MipsAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
5913 uint64_t &ErrorInfo,
5914 bool MatchingInlineAsm) {
5916 unsigned MatchResult =
5917 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
5919 switch (MatchResult) {
5921 if (processInstruction(Inst, IDLoc, Out, STI))
5924 case Match_MissingFeature:
5925 Error(IDLoc,
"instruction requires a CPU feature not currently enabled");
5927 case Match_InvalidTiedOperand:
5928 Error(IDLoc,
"operand must match destination register");
5930 case Match_InvalidOperand: {
5931 SMLoc ErrorLoc = IDLoc;
5932 if (ErrorInfo != ~0ULL) {
5933 if (ErrorInfo >= Operands.
size())
5934 return Error(IDLoc,
"too few operands for instruction");
5936 ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5937 if (ErrorLoc == SMLoc())
5941 return Error(ErrorLoc,
"invalid operand for instruction");
5943 case Match_NonZeroOperandForSync:
5945 "s-type must be zero or unspecified for pre-MIPS32 ISAs");
5946 case Match_NonZeroOperandForMTCX:
5947 return Error(IDLoc,
"selector must be zero for pre-MIPS32 ISAs");
5948 case Match_MnemonicFail:
5949 return Error(IDLoc,
"invalid instruction");
5950 case Match_RequiresDifferentSrcAndDst:
5951 return Error(IDLoc,
"source and destination must be different");
5952 case Match_RequiresDifferentOperands:
5953 return Error(IDLoc,
"registers must be different");
5954 case Match_RequiresNoZeroRegister:
5955 return Error(IDLoc,
"invalid operand ($zero) for instruction");
5956 case Match_RequiresSameSrcAndDst:
5957 return Error(IDLoc,
"source and destination must match");
5958 case Match_NoFCCRegisterForCurrentISA:
5960 "non-zero fcc register doesn't exist in current ISA level");
5965 "expected 1-bit unsigned immediate");
5968 "expected 2-bit unsigned immediate");
5971 "expected immediate in range 1 .. 4");
5974 "expected 3-bit unsigned immediate");
5977 "expected 4-bit unsigned immediate");
5980 "expected 4-bit signed immediate");
5983 "expected 5-bit unsigned immediate");
5986 "expected 5-bit signed immediate");
5989 "expected immediate in range 1 .. 32");
5990 case Match_UImm5_32:
5992 "expected immediate in range 32 .. 63");
5993 case Match_UImm5_33:
5995 "expected immediate in range 33 .. 64");
5996 case Match_UImm5_0_Report_UImm6:
6000 "expected 6-bit unsigned immediate");
6001 case Match_UImm5_Lsl2:
6003 "expected both 7-bit unsigned immediate and multiple of 4");
6004 case Match_UImmRange2_64:
6006 "expected immediate in range 2 .. 64");
6009 "expected 6-bit unsigned immediate");
6010 case Match_UImm6_Lsl2:
6012 "expected both 8-bit unsigned immediate and multiple of 4");
6015 "expected 6-bit signed immediate");
6018 "expected 7-bit unsigned immediate");
6019 case Match_UImm7_N1:
6021 "expected immediate in range -1 .. 126");
6022 case Match_SImm7_Lsl2:
6024 "expected both 9-bit signed immediate and multiple of 4");
6027 "expected 8-bit unsigned immediate");
6028 case Match_UImm10_0:
6030 "expected 10-bit unsigned immediate");
6031 case Match_SImm10_0:
6033 "expected 10-bit signed immediate");
6034 case Match_SImm11_0:
6036 "expected 11-bit signed immediate");
6038 case Match_UImm16_Relaxed:
6039 case Match_UImm16_AltRelaxed:
6041 "expected 16-bit unsigned immediate");
6043 case Match_SImm16_Relaxed:
6045 "expected 16-bit signed immediate");
6046 case Match_SImm19_Lsl2:
6048 "expected both 19-bit signed immediate and multiple of 4");
6049 case Match_UImm20_0:
6051 "expected 20-bit unsigned immediate");
6052 case Match_UImm26_0:
6054 "expected 26-bit unsigned immediate");
6056 case Match_SImm32_Relaxed:
6058 "expected 32-bit signed immediate");
6059 case Match_UImm32_Coerced:
6061 "expected 32-bit immediate");
6062 case Match_MemSImm9:
6064 "expected memory with 9-bit signed offset");
6065 case Match_MemSImm10:
6067 "expected memory with 10-bit signed offset");
6068 case Match_MemSImm10Lsl1:
6070 "expected memory with 11-bit signed offset and multiple of 2");
6071 case Match_MemSImm10Lsl2:
6073 "expected memory with 12-bit signed offset and multiple of 4");
6074 case Match_MemSImm10Lsl3:
6076 "expected memory with 13-bit signed offset and multiple of 8");
6077 case Match_MemSImm11:
6079 "expected memory with 11-bit signed offset");
6080 case Match_MemSImm12:
6082 "expected memory with 12-bit signed offset");
6083 case Match_MemSImm16:
6085 "expected memory with 16-bit signed offset");
6086 case Match_MemSImmPtr:
6088 "expected memory with 32-bit signed offset");
6089 case Match_RequiresPosSizeRange0_32: {
6090 SMLoc ErrorStart = Operands[3]->getStartLoc();
6091 SMLoc ErrorEnd = Operands[4]->getEndLoc();
6092 return Error(ErrorStart,
"size plus position are not in the range 0 .. 32",
6093 SMRange(ErrorStart, ErrorEnd));
6095 case Match_RequiresPosSizeUImm6: {
6096 SMLoc ErrorStart = Operands[3]->getStartLoc();
6097 SMLoc ErrorEnd = Operands[4]->getEndLoc();
6098 return Error(ErrorStart,
"size plus position are not in the range 1 .. 63",
6099 SMRange(ErrorStart, ErrorEnd));
6101 case Match_RequiresPosSizeRange33_64: {
6102 SMLoc ErrorStart = Operands[3]->getStartLoc();
6103 SMLoc ErrorEnd = Operands[4]->getEndLoc();
6104 return Error(ErrorStart,
"size plus position are not in the range 33 .. 64",
6105 SMRange(ErrorStart, ErrorEnd));
6112void MipsAsmParser::warnIfRegIndexIsAT(MCRegister RegIndex, SMLoc Loc) {
6113 if (RegIndex && AssemblerOptions.
back()->getATRegIndex() == RegIndex)
6114 Warning(Loc,
"used $at (currently $" + Twine(RegIndex.
id()) +
6115 ") without \".set noat\"");
6118void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
6119 if (!AssemblerOptions.
back()->isMacro())
6120 Warning(Loc,
"macro instruction expanded into multiple instructions");
6123void MipsAsmParser::ConvertXWPOperands(MCInst &Inst,
6127 "Unexpected instruction!");
6128 ((MipsOperand &)*Operands[1]).addGPR32ZeroAsmRegOperands(Inst, 1);
6129 MCRegister NextReg =
nextReg(((MipsOperand &)*Operands[1]).getGPR32Reg());
6131 ((MipsOperand &)*Operands[2]).addMemOperands(Inst, 2);
6135MipsAsmParser::printWarningWithFixIt(
const Twine &Msg,
const Twine &FixMsg,
6136 SMRange
Range,
bool ShowColors) {
6142int MipsAsmParser::matchCPURegisterName(StringRef Name) {
6145 CC = StringSwitch<unsigned>(Name)
6147 .Cases({
"at",
"AT"}, 1)
6181 if (!(isABI_N32() || isABI_N64()))
6184 if (12 <= CC && CC <= 15) {
6186 AsmToken RegTok = getLexer().peekTok();
6189 StringRef FixedName = StringSwitch<StringRef>(Name)
6195 assert(FixedName !=
"" &&
"Register name is not one of t4-t7.");
6197 printWarningWithFixIt(
"register names $t4-$t7 are only available in O32.",
6198 "Did you mean $" + FixedName +
"?", RegRange);
6204 if (8 <= CC && CC <= 11)
6208 CC = StringSwitch<unsigned>(Name)
6220int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
6223 CC = StringSwitch<unsigned>(Name)
6224 .Case(
"hwr_cpunum", 0)
6225 .Case(
"hwr_synci_step", 1)
6227 .Case(
"hwr_ccres", 3)
6228 .Case(
"hwr_ulr", 29)
6234int MipsAsmParser::matchFPURegisterName(StringRef Name) {
6235 if (Name[0] ==
'f') {
6236 StringRef NumString =
Name.substr(1);
6247int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
6248 if (
Name.starts_with(
"fcc")) {
6249 StringRef NumString =
Name.substr(3);
6260int MipsAsmParser::matchACRegisterName(StringRef Name) {
6261 if (
Name.starts_with(
"ac")) {
6262 StringRef NumString =
Name.substr(2);
6273int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
6276 if (
Name.front() !=
'w' ||
Name.drop_front(1).getAsInteger(10, IntVal))
6285int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
6288 CC = StringSwitch<unsigned>(Name)
6291 .Case(
"msaaccess", 2)
6293 .Case(
"msamodify", 4)
6294 .Case(
"msarequest", 5)
6296 .Case(
"msaunmap", 7)
6302bool MipsAsmParser::canUseATReg() {
6303 return AssemblerOptions.
back()->getATRegIndex() != 0;
6306MCRegister MipsAsmParser::getATReg(SMLoc Loc) {
6307 unsigned ATIndex = AssemblerOptions.
back()->getATRegIndex();
6309 reportParseError(Loc,
6310 "pseudo-instruction requires $at, which is not available");
6314 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
6318MCRegister MipsAsmParser::getReg(
int RC,
int RegNo) {
6319 return getContext().getRegisterInfo()->getRegClass(RC).getRegister(RegNo);
6325const MCExpr *MipsAsmParser::parseRelocExpr() {
6326 auto getOp = [](StringRef
Op) {
6327 return StringSwitch<Mips::Specifier>(
Op)
6355 MCAsmParser &Parser = getParser();
6357 const MCExpr *Res =
nullptr;
6363 auto Op = getOp(Name);
6372 while (
Ops.size()) {
6380bool MipsAsmParser::parseOperand(
OperandVector &Operands, StringRef Mnemonic) {
6381 MCAsmParser &Parser = getParser();
6391 ParseStatus Res = MatchOperandParserImpl(Operands, Mnemonic,
true);
6402 switch (getLexer().getKind()) {
6412 if (!parseAnyRegister(Operands).isNoMatch())
6425 Operands.
push_back(MipsOperand::CreateImm(SymRef, S,
E, *
this));
6430 const MCExpr *Expr = parseRelocExpr();
6434 Operands.
push_back(MipsOperand::CreateImm(Expr, S,
E, *
this));
6441bool MipsAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
6443 return !tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess();
6446ParseStatus MipsAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
6449 ParseStatus Res = parseAnyRegister(Operands);
6452 MipsOperand &Operand =
static_cast<MipsOperand &
>(*Operands.
front());
6453 StartLoc = Operand.getStartLoc();
6454 EndLoc = Operand.getEndLoc();
6460 if (Operand.isGPRAsmReg()) {
6462 Reg = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
6472ParseStatus MipsAsmParser::parseMemOperand(
OperandVector &Operands) {
6473 MCAsmParser &Parser = getParser();
6475 const MCExpr *IdVal =
nullptr;
6477 bool isParenExpr =
false;
6488 IdVal = parseRelocExpr();
6494 const AsmToken &Tok = Parser.
getTok();
6496 MipsOperand &Mnemonic =
static_cast<MipsOperand &
>(*Operands[0]);
6497 if (Mnemonic.getToken() ==
"la" || Mnemonic.getToken() ==
"dla") {
6500 Operands.
push_back(MipsOperand::CreateImm(IdVal, S,
E, *
this));
6509 auto Base = MipsOperand::createGPRReg(
6510 0,
"0",
getContext().getRegisterInfo(), S,
E, *
this);
6512 MipsOperand::CreateMem(std::move(
Base), IdVal, S,
E, *
this));
6564 const MCExpr * NextExpr;
6565 if (getParser().parseExpression(NextExpr))
6573 Res = parseAnyRegister(Operands);
6588 std::unique_ptr<MipsOperand>
op(
6589 static_cast<MipsOperand *
>(Operands.
back().release()));
6596 if (IdVal->evaluateAsAbsolute(Imm))
6603 Operands.
push_back(MipsOperand::CreateMem(std::move(
op), IdVal, S,
E, *
this));
6607bool MipsAsmParser::searchSymbolAlias(
OperandVector &Operands) {
6608 MCAsmParser &Parser = getParser();
6617 const MCSymbolRefExpr *
Ref =
static_cast<const MCSymbolRefExpr *
>(Expr);
6618 StringRef DefSymbol =
Ref->getSymbol().getName();
6621 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.
substr(1), S);
6635 if (Entry != RegisterSets.
end()) {
6637 matchAnyRegisterWithoutDollar(Operands,
Entry->getValue(), S);
6648ParseStatus MipsAsmParser::matchAnyRegisterNameWithoutDollar(
6650 int Index = matchCPURegisterName(Identifier);
6652 Operands.
push_back(MipsOperand::createGPRReg(
6653 Index, Identifier,
getContext().getRegisterInfo(), S,
6654 getLexer().getLoc(), *
this));
6658 Index = matchHWRegsRegisterName(Identifier);
6660 Operands.
push_back(MipsOperand::createHWRegsReg(
6661 Index, Identifier,
getContext().getRegisterInfo(), S,
6662 getLexer().getLoc(), *
this));
6666 Index = matchFPURegisterName(Identifier);
6668 Operands.
push_back(MipsOperand::createFGRReg(
6669 Index, Identifier,
getContext().getRegisterInfo(), S,
6670 getLexer().getLoc(), *
this));
6674 Index = matchFCCRegisterName(Identifier);
6676 Operands.
push_back(MipsOperand::createFCCReg(
6677 Index, Identifier,
getContext().getRegisterInfo(), S,
6678 getLexer().getLoc(), *
this));
6682 Index = matchACRegisterName(Identifier);
6684 Operands.
push_back(MipsOperand::createACCReg(
6685 Index, Identifier,
getContext().getRegisterInfo(), S,
6686 getLexer().getLoc(), *
this));
6690 Index = matchMSA128RegisterName(Identifier);
6692 Operands.
push_back(MipsOperand::createMSA128Reg(
6693 Index, Identifier,
getContext().getRegisterInfo(), S,
6694 getLexer().getLoc(), *
this));
6698 Index = matchMSA128CtrlRegisterName(Identifier);
6700 Operands.
push_back(MipsOperand::createMSACtrlReg(
6701 Index, Identifier,
getContext().getRegisterInfo(), S,
6702 getLexer().getLoc(), *
this));
6710MipsAsmParser::matchAnyRegisterWithoutDollar(
OperandVector &Operands,
6711 const AsmToken &Token, SMLoc S) {
6715 return matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
6720 if (RegNum < 0 || RegNum > 31) {
6724 Error(getLexer().getLoc(),
"invalid register number");
6726 Operands.
push_back(MipsOperand::createNumericReg(
6738MipsAsmParser::matchAnyRegisterWithoutDollar(
OperandVector &Operands, SMLoc S) {
6739 auto Token = getLexer().peekTok(
false);
6740 return matchAnyRegisterWithoutDollar(Operands, Token, S);
6743ParseStatus MipsAsmParser::parseAnyRegister(
OperandVector &Operands) {
6744 MCAsmParser &Parser = getParser();
6747 auto Token = Parser.
getTok();
6749 SMLoc S = Token.
getLoc();
6754 if (searchSymbolAlias(Operands))
6762 ParseStatus Res = matchAnyRegisterWithoutDollar(Operands, S);
6770ParseStatus MipsAsmParser::parseJumpTarget(
OperandVector &Operands) {
6771 MCAsmParser &Parser = getParser();
6774 SMLoc S = getLexer().getLoc();
6777 ParseStatus Res = parseAnyRegister(Operands);
6782 const MCExpr *Expr =
nullptr;
6788 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *
this));
6792ParseStatus MipsAsmParser::parseInvNum(
OperandVector &Operands) {
6793 MCAsmParser &Parser = getParser();
6794 const MCExpr *IdVal;
6805 if (getParser().parseExpression(IdVal))
6812 Operands.
push_back(MipsOperand::CreateImm(
6817ParseStatus MipsAsmParser::parseRegisterList(
OperandVector &Operands) {
6818 MCAsmParser &Parser = getParser();
6822 bool RegRange =
false;
6829 while (parseAnyRegister(TmpOperands).isSuccess()) {
6830 SMLoc
E = getLexer().getLoc();
6831 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*TmpOperands.
back());
6832 Reg = isGP64bit() ? RegOpnd.getGPR64Reg() : RegOpnd.getGPR32Reg();
6836 if ((isGP64bit() &&
Reg == Mips::RA_64) ||
6837 (!isGP64bit() &&
Reg == Mips::RA)) {
6840 MCRegister TmpReg = PrevReg + 1;
6841 while (TmpReg <=
Reg) {
6842 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
6843 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
6845 return Error(
E,
"invalid register operand");
6849 TmpReg = TmpReg.
id() + 1;
6856 ((isGP64bit() && (
Reg != Mips::S0_64) && (
Reg != Mips::RA_64)) ||
6857 (!isGP64bit() && (
Reg != Mips::S0) && (
Reg != Mips::RA))))
6858 return Error(
E,
"$16 or $31 expected");
6859 if (!(((
Reg == Mips::FP ||
Reg == Mips::RA ||
6860 (
Reg >= Mips::S0 &&
Reg <= Mips::S7)) &&
6862 ((
Reg == Mips::FP_64 ||
Reg == Mips::RA_64 ||
6863 (
Reg >= Mips::S0_64 &&
Reg <= Mips::S7_64)) &&
6865 return Error(
E,
"invalid register operand");
6866 if (PrevReg.
isValid() && (
Reg != PrevReg + 1) &&
6867 ((
Reg != Mips::FP &&
Reg != Mips::RA && !isGP64bit()) ||
6868 (
Reg != Mips::FP_64 &&
Reg != Mips::RA_64 && isGP64bit())))
6869 return Error(
E,
"consecutive register numbers expected");
6879 return Error(
E,
"',' or '-' expected");
6889 Operands.
push_back(MipsOperand::CreateRegList(Regs, S,
E, *
this));
6890 parseMemOperand(Operands);
6899bool MipsAsmParser::parseParenSuffix(StringRef Name,
OperandVector &Operands) {
6900 MCAsmParser &Parser = getParser();
6903 MipsOperand::CreateToken(
"(", getLexer().getLoc(), *
this));
6905 if (parseOperand(Operands, Name)) {
6906 SMLoc Loc = getLexer().getLoc();
6907 return Error(Loc,
"unexpected token in argument list");
6910 SMLoc Loc = getLexer().getLoc();
6911 return Error(Loc,
"unexpected token, expected ')'");
6914 MipsOperand::CreateToken(
")", getLexer().getLoc(), *
this));
6926bool MipsAsmParser::parseBracketSuffix(StringRef Name,
6928 MCAsmParser &Parser = getParser();
6931 MipsOperand::CreateToken(
"[", getLexer().getLoc(), *
this));
6933 if (parseOperand(Operands, Name)) {
6934 SMLoc Loc = getLexer().getLoc();
6935 return Error(Loc,
"unexpected token in argument list");
6938 SMLoc Loc = getLexer().getLoc();
6939 return Error(Loc,
"unexpected token, expected ']'");
6942 MipsOperand::CreateToken(
"]", getLexer().getLoc(), *
this));
6949 unsigned VariantID = 0);
6964bool MipsAsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
6966 MCAsmParser &Parser = getParser();
6970 getTargetStreamer().forbidModuleDirective();
6973 if (!mnemonicIsValid(Name, 0)) {
6974 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
6976 return Error(NameLoc,
"unknown instruction" + Suggestion);
6979 Operands.
push_back(MipsOperand::CreateToken(Name, NameLoc, *
this));
6984 if (parseOperand(Operands, Name)) {
6985 SMLoc Loc = getLexer().getLoc();
6986 return Error(Loc,
"unexpected token in argument list");
6988 if (getLexer().is(
AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
6995 if (parseOperand(Operands, Name)) {
6996 SMLoc Loc = getLexer().getLoc();
6997 return Error(Loc,
"unexpected token in argument list");
7001 if (parseBracketSuffix(Name, Operands))
7004 parseParenSuffix(Name, Operands))
7009 SMLoc Loc = getLexer().getLoc();
7010 return Error(Loc,
"unexpected token in argument list");
7018bool MipsAsmParser::reportParseError(
const Twine &ErrorMsg) {
7019 SMLoc Loc = getLexer().getLoc();
7020 return Error(Loc, ErrorMsg);
7023bool MipsAsmParser::reportParseError(SMLoc Loc,
const Twine &ErrorMsg) {
7024 return Error(Loc, ErrorMsg);
7027bool MipsAsmParser::parseSetNoAtDirective() {
7028 MCAsmParser &Parser = getParser();
7032 AssemblerOptions.
back()->setATRegIndex(0);
7038 reportParseError(
"unexpected token, expected end of statement");
7042 getTargetStreamer().emitDirectiveSetNoAt();
7047bool MipsAsmParser::parseSetAtDirective() {
7050 MCAsmParser &Parser = getParser();
7055 AssemblerOptions.
back()->setATRegIndex(1);
7057 getTargetStreamer().emitDirectiveSetAt();
7063 reportParseError(
"unexpected token, expected equals sign");
7070 reportParseError(
"no register specified");
7073 reportParseError(
"unexpected token, expected dollar sign '$'");
7083 AtRegNo = matchCPURegisterName(
Reg.getIdentifier());
7085 AtRegNo =
Reg.getIntVal();
7087 reportParseError(
"unexpected token, expected identifier or integer");
7092 if (!AssemblerOptions.
back()->setATRegIndex(AtRegNo)) {
7093 reportParseError(
"invalid register");
7100 reportParseError(
"unexpected token, expected end of statement");
7104 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
7110bool MipsAsmParser::parseSetReorderDirective() {
7111 MCAsmParser &Parser = getParser();
7115 reportParseError(
"unexpected token, expected end of statement");
7118 AssemblerOptions.
back()->setReorder();
7119 getTargetStreamer().emitDirectiveSetReorder();
7124bool MipsAsmParser::parseSetNoReorderDirective() {
7125 MCAsmParser &Parser = getParser();
7129 reportParseError(
"unexpected token, expected end of statement");
7132 AssemblerOptions.
back()->setNoReorder();
7133 getTargetStreamer().emitDirectiveSetNoReorder();
7138bool MipsAsmParser::parseSetMacroDirective() {
7139 MCAsmParser &Parser = getParser();
7143 reportParseError(
"unexpected token, expected end of statement");
7146 AssemblerOptions.
back()->setMacro();
7147 getTargetStreamer().emitDirectiveSetMacro();
7152bool MipsAsmParser::parseSetNoMacroDirective() {
7153 MCAsmParser &Parser = getParser();
7157 reportParseError(
"unexpected token, expected end of statement");
7160 if (AssemblerOptions.
back()->isReorder()) {
7161 reportParseError(
"`noreorder' must be set before `nomacro'");
7164 AssemblerOptions.
back()->setNoMacro();
7165 getTargetStreamer().emitDirectiveSetNoMacro();
7170bool MipsAsmParser::parseSetMsaDirective() {
7171 MCAsmParser &Parser = getParser();
7176 return reportParseError(
"unexpected token, expected end of statement");
7178 setFeatureBits(Mips::FeatureMSA,
"msa");
7179 getTargetStreamer().emitDirectiveSetMsa();
7183bool MipsAsmParser::parseSetNoMsaDirective() {
7184 MCAsmParser &Parser = getParser();
7189 return reportParseError(
"unexpected token, expected end of statement");
7191 clearFeatureBits(Mips::FeatureMSA,
"msa");
7192 getTargetStreamer().emitDirectiveSetNoMsa();
7196bool MipsAsmParser::parseSetNoDspDirective() {
7197 MCAsmParser &Parser = getParser();
7202 reportParseError(
"unexpected token, expected end of statement");
7206 clearFeatureBits(Mips::FeatureDSP,
"dsp");
7207 getTargetStreamer().emitDirectiveSetNoDsp();
7211bool MipsAsmParser::parseSetNoMips3DDirective() {
7212 MCAsmParser &Parser = getParser();
7217 reportParseError(
"unexpected token, expected end of statement");
7221 clearFeatureBits(Mips::FeatureMips3D,
"mips3d");
7222 getTargetStreamer().emitDirectiveSetNoMips3D();
7226bool MipsAsmParser::parseSetMips16Directive() {
7227 MCAsmParser &Parser = getParser();
7232 reportParseError(
"unexpected token, expected end of statement");
7236 setFeatureBits(Mips::FeatureMips16,
"mips16");
7237 getTargetStreamer().emitDirectiveSetMips16();
7242bool MipsAsmParser::parseSetNoMips16Directive() {
7243 MCAsmParser &Parser = getParser();
7248 reportParseError(
"unexpected token, expected end of statement");
7252 clearFeatureBits(Mips::FeatureMips16,
"mips16");
7253 getTargetStreamer().emitDirectiveSetNoMips16();
7258bool MipsAsmParser::parseSetFpDirective() {
7259 MCAsmParser &Parser = getParser();
7265 AsmToken Tok = Parser.
getTok();
7267 reportParseError(
"unexpected token, expected equals sign '='");
7273 if (!parseFpABIValue(FpAbiVal,
".set"))
7277 reportParseError(
"unexpected token, expected end of statement");
7280 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
7285bool MipsAsmParser::parseSetOddSPRegDirective() {
7286 MCAsmParser &Parser = getParser();
7290 reportParseError(
"unexpected token, expected end of statement");
7294 clearFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
7295 getTargetStreamer().emitDirectiveSetOddSPReg();
7299bool MipsAsmParser::parseSetNoOddSPRegDirective() {
7300 MCAsmParser &Parser = getParser();
7304 reportParseError(
"unexpected token, expected end of statement");
7308 setFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
7309 getTargetStreamer().emitDirectiveSetNoOddSPReg();
7313bool MipsAsmParser::parseSetMtDirective() {
7314 MCAsmParser &Parser = getParser();
7319 reportParseError(
"unexpected token, expected end of statement");
7323 setFeatureBits(Mips::FeatureMT,
"mt");
7324 getTargetStreamer().emitDirectiveSetMt();
7329bool MipsAsmParser::parseSetNoMtDirective() {
7330 MCAsmParser &Parser = getParser();
7335 reportParseError(
"unexpected token, expected end of statement");
7339 clearFeatureBits(Mips::FeatureMT,
"mt");
7341 getTargetStreamer().emitDirectiveSetNoMt();
7346bool MipsAsmParser::parseSetNoCRCDirective() {
7347 MCAsmParser &Parser = getParser();
7352 reportParseError(
"unexpected token, expected end of statement");
7356 clearFeatureBits(Mips::FeatureCRC,
"crc");
7358 getTargetStreamer().emitDirectiveSetNoCRC();
7363bool MipsAsmParser::parseSetNoVirtDirective() {
7364 MCAsmParser &Parser = getParser();
7369 reportParseError(
"unexpected token, expected end of statement");
7373 clearFeatureBits(Mips::FeatureVirt,
"virt");
7375 getTargetStreamer().emitDirectiveSetNoVirt();
7380bool MipsAsmParser::parseSetNoGINVDirective() {
7381 MCAsmParser &Parser = getParser();
7386 reportParseError(
"unexpected token, expected end of statement");
7390 clearFeatureBits(Mips::FeatureGINV,
"ginv");
7392 getTargetStreamer().emitDirectiveSetNoGINV();
7397bool MipsAsmParser::parseSetPopDirective() {
7398 MCAsmParser &Parser = getParser();
7399 SMLoc Loc = getLexer().getLoc();
7403 return reportParseError(
"unexpected token, expected end of statement");
7407 if (AssemblerOptions.
size() == 2)
7408 return reportParseError(Loc,
".set pop with no .set push");
7410 MCSubtargetInfo &STI = copySTI();
7412 setAvailableFeatures(
7413 ComputeAvailableFeatures(AssemblerOptions.
back()->getFeatures()));
7416 getTargetStreamer().emitDirectiveSetPop();
7420bool MipsAsmParser::parseSetPushDirective() {
7421 MCAsmParser &Parser = getParser();
7424 return reportParseError(
"unexpected token, expected end of statement");
7428 std::make_unique<MipsAssemblerOptions>(AssemblerOptions.
back().get()));
7430 getTargetStreamer().emitDirectiveSetPush();
7434bool MipsAsmParser::parseSetSoftFloatDirective() {
7435 MCAsmParser &Parser = getParser();
7438 return reportParseError(
"unexpected token, expected end of statement");
7440 setFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
7441 getTargetStreamer().emitDirectiveSetSoftFloat();
7445bool MipsAsmParser::parseSetHardFloatDirective() {
7446 MCAsmParser &Parser = getParser();
7449 return reportParseError(
"unexpected token, expected end of statement");
7451 clearFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
7452 getTargetStreamer().emitDirectiveSetHardFloat();
7456bool MipsAsmParser::parseSetAssignment() {
7458 MCAsmParser &Parser = getParser();
7461 return reportParseError(
"expected identifier after .set");
7464 return reportParseError(
"unexpected token, expected comma");
7479 const MCExpr *
Value;
7481 Parser, Sym,
Value))
7483 getStreamer().emitAssignment(Sym,
Value);
7488bool MipsAsmParser::parseSetMips0Directive() {
7489 MCAsmParser &Parser = getParser();
7492 return reportParseError(
"unexpected token, expected end of statement");
7495 MCSubtargetInfo &STI = copySTI();
7496 setAvailableFeatures(
7497 ComputeAvailableFeatures(AssemblerOptions.
front()->getFeatures()));
7499 AssemblerOptions.
back()->setFeatures(AssemblerOptions.
front()->getFeatures());
7501 getTargetStreamer().emitDirectiveSetMips0();
7505bool MipsAsmParser::parseSetArchDirective() {
7506 MCAsmParser &Parser = getParser();
7509 return reportParseError(
"unexpected token, expected equals sign");
7512 StringRef Arch = getParser().parseStringToEndOfStatement().trim();
7514 return reportParseError(
"expected arch identifier");
7516 StringRef ArchFeatureName =
7517 StringSwitch<StringRef>(Arch)
7518 .Case(
"mips1",
"mips1")
7519 .Case(
"mips2",
"mips2")
7520 .Case(
"mips3",
"mips3")
7521 .Case(
"mips4",
"mips4")
7522 .Case(
"mips5",
"mips5")
7523 .Case(
"mips32",
"mips32")
7524 .Case(
"mips32r2",
"mips32r2")
7525 .Case(
"mips32r3",
"mips32r3")
7526 .Case(
"mips32r5",
"mips32r5")
7527 .Case(
"mips32r6",
"mips32r6")
7528 .Case(
"mips64",
"mips64")
7529 .Case(
"mips64r2",
"mips64r2")
7530 .Case(
"mips64r3",
"mips64r3")
7531 .Case(
"mips64r5",
"mips64r5")
7532 .Case(
"mips64r6",
"mips64r6")
7533 .Case(
"octeon",
"cnmips")
7534 .Case(
"octeon+",
"cnmipsp")
7535 .Case(
"r4000",
"mips3")
7538 if (ArchFeatureName.
empty())
7539 return reportParseError(
"unsupported architecture");
7541 if (ArchFeatureName ==
"mips64r6" && inMicroMipsMode())
7542 return reportParseError(
"mips64r6 does not support microMIPS");
7544 selectArch(ArchFeatureName);
7545 getTargetStreamer().emitDirectiveSetArch(Arch);
7549bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
7550 MCAsmParser &Parser = getParser();
7553 return reportParseError(
"unexpected token, expected end of statement");
7558 case Mips::FeatureMips3D:
7559 setFeatureBits(Mips::FeatureMips3D,
"mips3d");
7560 getTargetStreamer().emitDirectiveSetMips3D();
7562 case Mips::FeatureDSP:
7563 setFeatureBits(Mips::FeatureDSP,
"dsp");
7564 getTargetStreamer().emitDirectiveSetDsp();
7566 case Mips::FeatureDSPR2:
7567 setFeatureBits(Mips::FeatureDSPR2,
"dspr2");
7568 getTargetStreamer().emitDirectiveSetDspr2();
7570 case Mips::FeatureMicroMips:
7571 setFeatureBits(Mips::FeatureMicroMips,
"micromips");
7572 getTargetStreamer().emitDirectiveSetMicroMips();
7574 case Mips::FeatureMips1:
7575 selectArch(
"mips1");
7576 getTargetStreamer().emitDirectiveSetMips1();
7578 case Mips::FeatureMips2:
7579 selectArch(
"mips2");
7580 getTargetStreamer().emitDirectiveSetMips2();
7582 case Mips::FeatureMips3:
7583 selectArch(
"mips3");
7584 getTargetStreamer().emitDirectiveSetMips3();
7586 case Mips::FeatureMips4:
7587 selectArch(
"mips4");
7588 getTargetStreamer().emitDirectiveSetMips4();
7590 case Mips::FeatureMips5:
7591 selectArch(
"mips5");
7592 getTargetStreamer().emitDirectiveSetMips5();
7594 case Mips::FeatureMips32:
7595 selectArch(
"mips32");
7596 getTargetStreamer().emitDirectiveSetMips32();
7598 case Mips::FeatureMips32r2:
7599 selectArch(
"mips32r2");
7600 getTargetStreamer().emitDirectiveSetMips32R2();
7602 case Mips::FeatureMips32r3:
7603 selectArch(
"mips32r3");
7604 getTargetStreamer().emitDirectiveSetMips32R3();
7606 case Mips::FeatureMips32r5:
7607 selectArch(
"mips32r5");
7608 getTargetStreamer().emitDirectiveSetMips32R5();
7610 case Mips::FeatureMips32r6:
7611 selectArch(
"mips32r6");
7612 getTargetStreamer().emitDirectiveSetMips32R6();
7614 case Mips::FeatureMips64:
7615 selectArch(
"mips64");
7616 getTargetStreamer().emitDirectiveSetMips64();
7618 case Mips::FeatureMips64r2:
7619 selectArch(
"mips64r2");
7620 getTargetStreamer().emitDirectiveSetMips64R2();
7622 case Mips::FeatureMips64r3:
7623 selectArch(
"mips64r3");
7624 getTargetStreamer().emitDirectiveSetMips64R3();
7626 case Mips::FeatureMips64r5:
7627 selectArch(
"mips64r5");
7628 getTargetStreamer().emitDirectiveSetMips64R5();
7630 case Mips::FeatureMips64r6:
7631 selectArch(
"mips64r6");
7632 getTargetStreamer().emitDirectiveSetMips64R6();
7634 case Mips::FeatureCRC:
7635 setFeatureBits(Mips::FeatureCRC,
"crc");
7636 getTargetStreamer().emitDirectiveSetCRC();
7638 case Mips::FeatureVirt:
7639 setFeatureBits(Mips::FeatureVirt,
"virt");
7640 getTargetStreamer().emitDirectiveSetVirt();
7642 case Mips::FeatureGINV:
7643 setFeatureBits(Mips::FeatureGINV,
"ginv");
7644 getTargetStreamer().emitDirectiveSetGINV();
7650bool MipsAsmParser::eatComma(StringRef ErrorStr) {
7651 MCAsmParser &Parser = getParser();
7653 SMLoc Loc = getLexer().getLoc();
7654 return Error(Loc, ErrorStr);
7665bool MipsAsmParser::isPicAndNotNxxAbi() {
7666 return inPicMode() && !(isABI_N32() || isABI_N64());
7669bool MipsAsmParser::parseDirectiveCpAdd(SMLoc Loc) {
7671 ParseStatus Res = parseAnyRegister(
Reg);
7673 reportParseError(
"expected register");
7677 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7678 if (!RegOpnd.isGPRAsmReg()) {
7679 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7685 reportParseError(
"unexpected token, expected end of statement");
7690 getTargetStreamer().emitDirectiveCpAdd(RegOpnd.getGPR32Reg());
7694bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
7695 if (AssemblerOptions.
back()->isReorder())
7696 Warning(Loc,
".cpload should be inside a noreorder section");
7698 if (inMips16Mode()) {
7699 reportParseError(
".cpload is not supported in Mips16 mode");
7704 ParseStatus Res = parseAnyRegister(
Reg);
7706 reportParseError(
"expected register containing function address");
7710 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7711 if (!RegOpnd.isGPRAsmReg()) {
7712 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7718 reportParseError(
"unexpected token, expected end of statement");
7722 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
7726bool MipsAsmParser::parseDirectiveCpLocal(SMLoc Loc) {
7727 if (!isABI_N32() && !isABI_N64()) {
7728 reportParseError(
".cplocal is allowed only in N32 or N64 mode");
7733 ParseStatus Res = parseAnyRegister(
Reg);
7735 reportParseError(
"expected register containing global pointer");
7739 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7740 if (!RegOpnd.isGPRAsmReg()) {
7741 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7747 reportParseError(
"unexpected token, expected end of statement");
7752 MCRegister NewReg = RegOpnd.getGPR32Reg();
7756 getTargetStreamer().emitDirectiveCpLocal(NewReg);
7760bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
7761 MCAsmParser &Parser = getParser();
7766 if (inMips16Mode()) {
7767 reportParseError(
".cprestore is not supported in Mips16 mode");
7772 const MCExpr *StackOffset;
7773 int64_t StackOffsetVal;
7775 reportParseError(
"expected stack offset value");
7779 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
7780 reportParseError(
"stack offset is not an absolute expression");
7784 if (StackOffsetVal < 0) {
7785 Warning(Loc,
".cprestore with negative stack offset has no effect");
7786 IsCpRestoreSet =
false;
7788 IsCpRestoreSet =
true;
7789 CpRestoreOffset = StackOffsetVal;
7794 reportParseError(
"unexpected token, expected end of statement");
7798 if (!getTargetStreamer().emitDirectiveCpRestore(
7799 CpRestoreOffset, [&]() {
return getATReg(Loc); }, Loc, STI))
7805bool MipsAsmParser::parseDirectiveCPSetup() {
7806 MCAsmParser &Parser = getParser();
7808 bool SaveIsReg =
true;
7811 ParseStatus Res = parseAnyRegister(TmpReg);
7813 reportParseError(
"expected register containing function address");
7817 MipsOperand &FuncRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7818 if (!FuncRegOpnd.isGPRAsmReg()) {
7819 reportParseError(FuncRegOpnd.getStartLoc(),
"invalid register");
7823 MCRegister FuncReg = FuncRegOpnd.getGPR32Reg();
7826 if (!eatComma(
"unexpected token, expected comma"))
7829 Res = parseAnyRegister(TmpReg);
7831 const MCExpr *OffsetExpr;
7833 SMLoc ExprLoc = getLexer().
getLoc();
7836 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
7837 reportParseError(ExprLoc,
"expected save register or stack offset");
7844 MipsOperand &SaveOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7845 if (!SaveOpnd.isGPRAsmReg()) {
7846 reportParseError(SaveOpnd.getStartLoc(),
"invalid register");
7849 Save = SaveOpnd.getGPR32Reg().id();
7852 if (!eatComma(
"unexpected token, expected comma"))
7857 reportParseError(
"expected expression");
7862 reportParseError(
"expected symbol");
7865 const MCSymbolRefExpr *
Ref =
static_cast<const MCSymbolRefExpr *
>(Expr);
7867 CpSaveLocation = Save;
7868 CpSaveLocationIsRegister = SaveIsReg;
7870 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save,
Ref->getSymbol(),
7875bool MipsAsmParser::parseDirectiveCPReturn() {
7876 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
7877 CpSaveLocationIsRegister);
7881bool MipsAsmParser::parseDirectiveNaN() {
7882 MCAsmParser &Parser = getParser();
7884 const AsmToken &Tok = Parser.
getTok();
7888 getTargetStreamer().emitDirectiveNaN2008();
7890 }
else if (Tok.
getString() ==
"legacy") {
7892 getTargetStreamer().emitDirectiveNaNLegacy();
7898 reportParseError(
"invalid option in .nan directive");
7902bool MipsAsmParser::parseDirectiveSet() {
7903 const AsmToken &Tok = getParser().getTok();
7905 SMLoc Loc = Tok.
getLoc();
7907 if (IdVal ==
"noat")
7908 return parseSetNoAtDirective();
7910 return parseSetAtDirective();
7911 if (IdVal ==
"arch")
7912 return parseSetArchDirective();
7913 if (IdVal ==
"bopt") {
7914 Warning(Loc,
"'bopt' feature is unsupported");
7918 if (IdVal ==
"nobopt") {
7924 return parseSetFpDirective();
7925 if (IdVal ==
"oddspreg")
7926 return parseSetOddSPRegDirective();
7927 if (IdVal ==
"nooddspreg")
7928 return parseSetNoOddSPRegDirective();
7930 return parseSetPopDirective();
7931 if (IdVal ==
"push")
7932 return parseSetPushDirective();
7933 if (IdVal ==
"reorder")
7934 return parseSetReorderDirective();
7935 if (IdVal ==
"noreorder")
7936 return parseSetNoReorderDirective();
7937 if (IdVal ==
"macro")
7938 return parseSetMacroDirective();
7939 if (IdVal ==
"nomacro")
7940 return parseSetNoMacroDirective();
7941 if (IdVal ==
"mips16")
7942 return parseSetMips16Directive();
7943 if (IdVal ==
"nomips16")
7944 return parseSetNoMips16Directive();
7945 if (IdVal ==
"nomicromips") {
7946 clearFeatureBits(Mips::FeatureMicroMips,
"micromips");
7947 getTargetStreamer().emitDirectiveSetNoMicroMips();
7948 getParser().eatToEndOfStatement();
7951 if (IdVal ==
"micromips") {
7952 if (hasMips64r6()) {
7953 Error(Loc,
".set micromips directive is not supported with MIPS64R6");
7956 return parseSetFeature(Mips::FeatureMicroMips);
7958 if (IdVal ==
"mips0")
7959 return parseSetMips0Directive();
7960 if (IdVal ==
"mips1")
7961 return parseSetFeature(Mips::FeatureMips1);
7962 if (IdVal ==
"mips2")
7963 return parseSetFeature(Mips::FeatureMips2);
7964 if (IdVal ==
"mips3")
7965 return parseSetFeature(Mips::FeatureMips3);
7966 if (IdVal ==
"mips4")
7967 return parseSetFeature(Mips::FeatureMips4);
7968 if (IdVal ==
"mips5")
7969 return parseSetFeature(Mips::FeatureMips5);
7970 if (IdVal ==
"mips32")
7971 return parseSetFeature(Mips::FeatureMips32);
7972 if (IdVal ==
"mips32r2")
7973 return parseSetFeature(Mips::FeatureMips32r2);
7974 if (IdVal ==
"mips32r3")
7975 return parseSetFeature(Mips::FeatureMips32r3);
7976 if (IdVal ==
"mips32r5")
7977 return parseSetFeature(Mips::FeatureMips32r5);
7978 if (IdVal ==
"mips32r6")
7979 return parseSetFeature(Mips::FeatureMips32r6);
7980 if (IdVal ==
"mips64")
7981 return parseSetFeature(Mips::FeatureMips64);
7982 if (IdVal ==
"mips64r2")
7983 return parseSetFeature(Mips::FeatureMips64r2);
7984 if (IdVal ==
"mips64r3")
7985 return parseSetFeature(Mips::FeatureMips64r3);
7986 if (IdVal ==
"mips64r5")
7987 return parseSetFeature(Mips::FeatureMips64r5);
7988 if (IdVal ==
"mips64r6") {
7989 if (inMicroMipsMode()) {
7990 Error(Loc,
"MIPS64R6 is not supported with microMIPS");
7993 return parseSetFeature(Mips::FeatureMips64r6);
7996 return parseSetFeature(Mips::FeatureDSP);
7997 if (IdVal ==
"dspr2")
7998 return parseSetFeature(Mips::FeatureDSPR2);
7999 if (IdVal ==
"nodsp")
8000 return parseSetNoDspDirective();
8001 if (IdVal ==
"mips3d")
8002 return parseSetFeature(Mips::FeatureMips3D);
8003 if (IdVal ==
"nomips3d")
8004 return parseSetNoMips3DDirective();
8006 return parseSetMsaDirective();
8007 if (IdVal ==
"nomsa")
8008 return parseSetNoMsaDirective();
8010 return parseSetMtDirective();
8011 if (IdVal ==
"nomt")
8012 return parseSetNoMtDirective();
8013 if (IdVal ==
"softfloat")
8014 return parseSetSoftFloatDirective();
8015 if (IdVal ==
"hardfloat")
8016 return parseSetHardFloatDirective();
8018 return parseSetFeature(Mips::FeatureCRC);
8019 if (IdVal ==
"nocrc")
8020 return parseSetNoCRCDirective();
8021 if (IdVal ==
"virt")
8022 return parseSetFeature(Mips::FeatureVirt);
8023 if (IdVal ==
"novirt")
8024 return parseSetNoVirtDirective();
8025 if (IdVal ==
"ginv")
8026 return parseSetFeature(Mips::FeatureGINV);
8027 if (IdVal ==
"noginv")
8028 return parseSetNoGINVDirective();
8031 return parseSetAssignment();
8036bool MipsAsmParser::parseDirectiveGpWord() {
8037 const MCExpr *
Value;
8038 if (getParser().parseExpression(
Value))
8040 getTargetStreamer().emitGPRel32Value(
Value);
8046bool MipsAsmParser::parseDirectiveGpDWord() {
8047 const MCExpr *
Value;
8048 if (getParser().parseExpression(
Value))
8050 getTargetStreamer().emitGPRel64Value(
Value);
8056bool MipsAsmParser::parseDirectiveDtpRelWord() {
8057 const MCExpr *
Value;
8058 if (getParser().parseExpression(
Value))
8060 getTargetStreamer().emitDTPRel32Value(
Value);
8066bool MipsAsmParser::parseDirectiveDtpRelDWord() {
8067 const MCExpr *
Value;
8068 if (getParser().parseExpression(
Value))
8070 getTargetStreamer().emitDTPRel64Value(
Value);
8076bool MipsAsmParser::parseDirectiveTpRelWord() {
8077 const MCExpr *
Value;
8078 if (getParser().parseExpression(
Value))
8080 getTargetStreamer().emitTPRel32Value(
Value);
8086bool MipsAsmParser::parseDirectiveTpRelDWord() {
8087 const MCExpr *
Value;
8088 if (getParser().parseExpression(
Value))
8090 getTargetStreamer().emitTPRel64Value(
Value);
8094bool MipsAsmParser::parseDirectiveOption() {
8095 MCAsmParser &Parser = getParser();
8097 AsmToken Tok = Parser.
getTok();
8101 "unexpected token, expected identifier");
8106 if (Option ==
"pic0") {
8108 IsPicEnabled =
false;
8110 getTargetStreamer().emitDirectiveOptionPic0();
8114 "unexpected token, expected end of statement");
8119 if (Option ==
"pic2") {
8121 IsPicEnabled =
true;
8123 getTargetStreamer().emitDirectiveOptionPic2();
8127 "unexpected token, expected end of statement");
8134 "unknown option, expected 'pic0' or 'pic2'");
8141bool MipsAsmParser::parseInsnDirective() {
8144 reportParseError(
"unexpected token, expected end of statement");
8150 getTargetStreamer().emitDirectiveInsn();
8158bool MipsAsmParser::parseRSectionDirective(StringRef Section) {
8161 reportParseError(
"unexpected token, expected end of statement");
8165 MCSection *ELFSection =
getContext().getELFSection(
8167 getParser().getStreamer().switchSection(ELFSection);
8176bool MipsAsmParser::parseSSectionDirective(StringRef Section,
unsigned Type) {
8179 reportParseError(
"unexpected token, expected end of statement");
8183 MCSection *ELFSection =
getContext().getELFSection(
8185 getParser().getStreamer().switchSection(ELFSection);
8204bool MipsAsmParser::parseDirectiveModule() {
8205 MCAsmParser &Parser = getParser();
8206 AsmLexer &Lexer = getLexer();
8209 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
8211 reportParseError(
".module directive must appear before any code");
8217 reportParseError(
"expected .module option identifier");
8221 if (Option ==
"oddspreg") {
8222 clearModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
8226 getTargetStreamer().updateABIInfo(*
this);
8231 getTargetStreamer().emitDirectiveModuleOddSPReg();
8235 reportParseError(
"unexpected token, expected end of statement");
8240 }
else if (Option ==
"nooddspreg") {
8242 return Error(L,
"'.module nooddspreg' requires the O32 ABI");
8245 setModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
8249 getTargetStreamer().updateABIInfo(*
this);
8254 getTargetStreamer().emitDirectiveModuleOddSPReg();
8258 reportParseError(
"unexpected token, expected end of statement");
8263 }
else if (Option ==
"fp") {
8264 return parseDirectiveModuleFP();
8265 }
else if (Option ==
"softfloat") {
8266 setModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
8270 getTargetStreamer().updateABIInfo(*
this);
8275 getTargetStreamer().emitDirectiveModuleSoftFloat();
8279 reportParseError(
"unexpected token, expected end of statement");
8284 }
else if (Option ==
"hardfloat") {
8285 clearModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
8289 getTargetStreamer().updateABIInfo(*
this);
8294 getTargetStreamer().emitDirectiveModuleHardFloat();
8298 reportParseError(
"unexpected token, expected end of statement");
8303 }
else if (Option ==
"mt") {
8304 setModuleFeatureBits(Mips::FeatureMT,
"mt");
8308 getTargetStreamer().updateABIInfo(*
this);
8313 getTargetStreamer().emitDirectiveModuleMT();
8317 reportParseError(
"unexpected token, expected end of statement");
8322 }
else if (Option ==
"crc") {
8323 setModuleFeatureBits(Mips::FeatureCRC,
"crc");
8327 getTargetStreamer().updateABIInfo(*
this);
8332 getTargetStreamer().emitDirectiveModuleCRC();
8336 reportParseError(
"unexpected token, expected end of statement");
8341 }
else if (Option ==
"nocrc") {
8342 clearModuleFeatureBits(Mips::FeatureCRC,
"crc");
8346 getTargetStreamer().updateABIInfo(*
this);
8351 getTargetStreamer().emitDirectiveModuleNoCRC();
8355 reportParseError(
"unexpected token, expected end of statement");
8360 }
else if (Option ==
"virt") {
8361 setModuleFeatureBits(Mips::FeatureVirt,
"virt");
8365 getTargetStreamer().updateABIInfo(*
this);
8370 getTargetStreamer().emitDirectiveModuleVirt();
8374 reportParseError(
"unexpected token, expected end of statement");
8379 }
else if (Option ==
"novirt") {
8380 clearModuleFeatureBits(Mips::FeatureVirt,
"virt");
8384 getTargetStreamer().updateABIInfo(*
this);
8389 getTargetStreamer().emitDirectiveModuleNoVirt();
8393 reportParseError(
"unexpected token, expected end of statement");
8398 }
else if (Option ==
"ginv") {
8399 setModuleFeatureBits(Mips::FeatureGINV,
"ginv");
8403 getTargetStreamer().updateABIInfo(*
this);
8408 getTargetStreamer().emitDirectiveModuleGINV();
8412 reportParseError(
"unexpected token, expected end of statement");
8417 }
else if (Option ==
"noginv") {
8418 clearModuleFeatureBits(Mips::FeatureGINV,
"ginv");
8422 getTargetStreamer().updateABIInfo(*
this);
8427 getTargetStreamer().emitDirectiveModuleNoGINV();
8431 reportParseError(
"unexpected token, expected end of statement");
8437 return Error(L,
"'" + Twine(Option) +
"' is not a valid .module option.");
8445bool MipsAsmParser::parseDirectiveModuleFP() {
8446 MCAsmParser &Parser = getParser();
8447 AsmLexer &Lexer = getLexer();
8450 reportParseError(
"unexpected token, expected equals sign '='");
8456 if (!parseFpABIValue(FpABI,
".module"))
8460 reportParseError(
"unexpected token, expected end of statement");
8466 getTargetStreamer().updateABIInfo(*
this);
8471 getTargetStreamer().emitDirectiveModuleFP();
8478 StringRef Directive) {
8479 MCAsmParser &Parser = getParser();
8480 AsmLexer &Lexer = getLexer();
8481 bool ModuleLevelOptions = Directive ==
".module";
8487 if (
Value !=
"xx") {
8488 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
8493 reportParseError(
"'" + Directive +
" fp=xx' requires the O32 ABI");
8497 FpABI = MipsABIFlagsSection::FpABIKind::XX;
8498 if (ModuleLevelOptions) {
8499 setModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8500 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8502 setFeatureBits(Mips::FeatureFPXX,
"fpxx");
8503 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8513 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
8519 reportParseError(
"'" + Directive +
" fp=32' requires the O32 ABI");
8523 FpABI = MipsABIFlagsSection::FpABIKind::S32;
8524 if (ModuleLevelOptions) {
8525 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8526 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8528 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
8529 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8532 FpABI = MipsABIFlagsSection::FpABIKind::S64;
8533 if (ModuleLevelOptions) {
8534 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8535 setModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8537 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
8538 setFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8548bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
8554 MCAsmParser &Parser = getParser();
8555 StringRef IDVal = DirectiveID.
getString();
8557 if (IDVal ==
".cpadd") {
8558 parseDirectiveCpAdd(DirectiveID.
getLoc());
8561 if (IDVal ==
".cpload") {
8562 parseDirectiveCpLoad(DirectiveID.
getLoc());
8565 if (IDVal ==
".cprestore") {
8566 parseDirectiveCpRestore(DirectiveID.
getLoc());
8569 if (IDVal ==
".cplocal") {
8570 parseDirectiveCpLocal(DirectiveID.
getLoc());
8573 if (IDVal ==
".ent") {
8577 reportParseError(
"expected identifier after .ent");
8591 reportParseError(
"unexpected token, expected end of statement");
8595 const MCExpr *DummyNumber;
8596 int64_t DummyNumberVal;
8600 reportParseError(
"expected number after comma");
8603 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
8604 reportParseError(
"expected an absolute expression after comma");
8611 reportParseError(
"unexpected token, expected end of statement");
8617 getTargetStreamer().emitDirectiveEnt(*Sym);
8619 IsCpRestoreSet =
false;
8623 if (IDVal ==
".end") {
8627 reportParseError(
"expected identifier after .end");
8632 reportParseError(
"unexpected token, expected end of statement");
8636 if (CurrentFn ==
nullptr) {
8637 reportParseError(
".end used without .ent");
8641 if ((SymbolName != CurrentFn->
getName())) {
8642 reportParseError(
".end symbol does not match .ent symbol");
8646 getTargetStreamer().emitDirectiveEnd(SymbolName);
8647 CurrentFn =
nullptr;
8648 IsCpRestoreSet =
false;
8652 if (IDVal ==
".frame") {
8655 ParseStatus Res = parseAnyRegister(TmpReg);
8657 reportParseError(
"expected stack register");
8661 MipsOperand &StackRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
8662 if (!StackRegOpnd.isGPRAsmReg()) {
8663 reportParseError(StackRegOpnd.getStartLoc(),
8664 "expected general purpose register");
8667 MCRegister StackReg = StackRegOpnd.getGPR32Reg();
8672 reportParseError(
"unexpected token, expected comma");
8677 const MCExpr *FrameSize;
8678 int64_t FrameSizeVal;
8681 reportParseError(
"expected frame size value");
8685 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
8686 reportParseError(
"frame size not an absolute expression");
8693 reportParseError(
"unexpected token, expected comma");
8699 Res = parseAnyRegister(TmpReg);
8701 reportParseError(
"expected return register");
8705 MipsOperand &ReturnRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
8706 if (!ReturnRegOpnd.isGPRAsmReg()) {
8707 reportParseError(ReturnRegOpnd.getStartLoc(),
8708 "expected general purpose register");
8714 reportParseError(
"unexpected token, expected end of statement");
8718 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
8719 ReturnRegOpnd.getGPR32Reg());
8720 IsCpRestoreSet =
false;
8724 if (IDVal ==
".set") {
8725 parseDirectiveSet();
8729 if (IDVal ==
".mask" || IDVal ==
".fmask") {
8740 const MCExpr *BitMask;
8744 reportParseError(
"expected bitmask value");
8748 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
8749 reportParseError(
"bitmask not an absolute expression");
8756 reportParseError(
"unexpected token, expected comma");
8761 const MCExpr *FrameOffset;
8762 int64_t FrameOffsetVal;
8765 reportParseError(
"expected frame offset value");
8769 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
8770 reportParseError(
"frame offset not an absolute expression");
8776 reportParseError(
"unexpected token, expected end of statement");
8780 if (IDVal ==
".mask")
8781 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
8783 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
8787 if (IDVal ==
".nan")
8788 return parseDirectiveNaN();
8790 if (IDVal ==
".gpword") {
8791 parseDirectiveGpWord();
8795 if (IDVal ==
".gpdword") {
8796 parseDirectiveGpDWord();
8800 if (IDVal ==
".dtprelword") {
8801 parseDirectiveDtpRelWord();
8805 if (IDVal ==
".dtpreldword") {
8806 parseDirectiveDtpRelDWord();
8810 if (IDVal ==
".tprelword") {
8811 parseDirectiveTpRelWord();
8815 if (IDVal ==
".tpreldword") {
8816 parseDirectiveTpRelDWord();
8820 if (IDVal ==
".option") {
8821 parseDirectiveOption();
8825 if (IDVal ==
".abicalls") {
8826 getTargetStreamer().emitDirectiveAbiCalls();
8829 "unexpected token, expected end of statement");
8834 if (IDVal ==
".cpsetup") {
8835 parseDirectiveCPSetup();
8838 if (IDVal ==
".cpreturn") {
8839 parseDirectiveCPReturn();
8842 if (IDVal ==
".module") {
8843 parseDirectiveModule();
8846 if (IDVal ==
".llvm_internal_mips_reallow_module_directive") {
8847 parseInternalDirectiveReallowModule();
8850 if (IDVal ==
".insn") {
8851 parseInsnDirective();
8854 if (IDVal ==
".rdata") {
8855 parseRSectionDirective(
".rodata");
8858 if (IDVal ==
".sbss") {
8862 if (IDVal ==
".sdata") {
8870bool MipsAsmParser::parseInternalDirectiveReallowModule() {
8873 reportParseError(
"unexpected token, expected end of statement");
8877 getTargetStreamer().reallowModuleDirective();
8891#define GET_REGISTER_MATCHER
8892#define GET_MATCHER_IMPLEMENTATION
8893#define GET_MNEMONIC_SPELL_CHECKER
8894#include "MipsGenAsmMatcher.inc"
8896bool MipsAsmParser::mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID) {
8898 const MatchEntry *Start, *End;
8899 switch (VariantID) {
8901 case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0);
break;
8904 auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
8905 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.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static FeatureBitset getFeatures(MCSubtargetInfo &STI, StringRef CPU, StringRef TuneCPU, StringRef FS, ArrayRef< StringRef > ProcNames, ArrayRef< SubtargetSubTypeKV > ProcDesc, ArrayRef< SubtargetFeatureKV > ProcFeatures)
static unsigned countMCSymbolRefExpr(const MCExpr *Expr)
static std::string MipsMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, unsigned VariantID=0)
static uint64_t convertIntToDoubleImm(uint64_t ImmOp64)
static uint32_t covertDoubleImmToSingleImm(uint64_t ImmOp64)
static unsigned getRegisterForMxtrDSP(MCInst &Inst, bool IsMFDSP)
static bool hasShortDelaySlot(MCInst &Inst)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsAsmParser()
static bool needsExpandMemInst(MCInst &Inst, const MCInstrDesc &MCID)
cl::opt< bool > EmitJalrReloc
static bool isShiftedUIntAtAnyPosition(uint64_t x)
Can the value be represented by a unsigned N-bit value and a shift left?
static bool isEvaluated(const MCExpr *Expr)
static unsigned getRegisterForMxtrC0(MCInst &Inst, bool IsMFTC0)
static const MCSymbol * getSingleMCSymbol(const MCExpr *Expr)
static MCRegister nextReg(MCRegister Reg)
static unsigned getRegisterForMxtrFP(MCInst &Inst, bool IsMFTC1)
cl::opt< bool > NoZeroDivCheck
static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands, uint64_t ErrorInfo)
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
static PPCTargetMachine::PPCABI computeTargetABI(const Triple &TT, const TargetOptions &Options)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
static const fltSemantics & IEEEdouble()
APInt bitcastToAPInt() const
uint64_t getZExtValue() const
Get zero extended value.
SMLoc getLoc() const
Get the current source location.
const AsmToken peekTok(bool ShouldSkipSpace=true)
Look ahead at the next token to be lexed.
bool is(AsmToken::TokenKind K) const
Check if the current token has kind K.
bool isNot(AsmToken::TokenKind K) const
Check if the current token has kind K.
Target independent representation for an assembler token.
LLVM_ABI SMLoc getLoc() const
int64_t getIntVal() const
bool isNot(TokenKind K) const
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
bool is(TokenKind K) const
TokenKind getKind() const
LLVM_ABI SMRange getLocRange() const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
Base class for user error types.
Container class for subtarget features.
void printExpr(raw_ostream &, const MCExpr &) const
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
bool parseToken(AsmToken::TokenKind T, const Twine &Msg="unexpected token")
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
Binary assembler expressions.
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
static LLVM_ABI const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
@ LShr
Logical shift right.
@ Xor
Bitwise exclusive or.
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Base class for the full range of assembler expressions which are needed for parsing.
LLVM_ABI bool evaluateAsRelocatable(MCValue &Res, const MCAssembler *Asm) const
Try to evaluate the expression to a relocatable value, i.e.
@ Unary
Unary expressions.
@ Constant
Constant expressions.
@ SymbolRef
References to labels and assigned expressions.
@ Target
Target specific expression.
@ Specifier
Expression with a relocation specifier.
@ Binary
Binary expressions.
Instances of this class represent a single low-level machine instruction.
unsigned getNumOperands() const
unsigned getOpcode() const
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
const MCOperand & getOperand(unsigned i) const
Describe properties that are true of each instruction in the target description file.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
ArrayRef< MCOperandInfo > operands() const
bool mayStore() const
Return true if this instruction could possibly modify memory.
bool mayLoad() const
Return true if this instruction could possibly read memory.
bool isBranch() const
Returns true if this is a conditional, unconditional, or indirect branch.
bool isCall() const
Return true if the instruction is a call.
bool hasDelaySlot() const
Returns true if the specified instruction has a delay slot which must be filled by the code generator...
Interface to description of machine instruction set.
This holds information about one operand of a machine instruction, indicating the register class for ...
uint8_t OperandType
Information about the type of the operand.
Instances of this class represent operands of the MCInst class.
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
MCRegister getReg() const
Returns the register number.
const MCExpr * getExpr() const
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual bool isReg() const =0
isReg - Is this a register operand?
virtual MCRegister getReg() const =0
Wrapper class representing physical registers. Should be passed by value.
constexpr bool isValid() const
constexpr unsigned id() const
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
Streaming machine code generation interface.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
virtual void emitRelocDirective(const MCExpr &Offset, StringRef Name, const MCExpr *Expr, SMLoc Loc={})
Record a relocation described by the .reloc directive.
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
void setFeatureBits(const FeatureBitset &FeatureBits_)
const Triple & getTargetTriple() const
const FeatureBitset & getFeatureBits() const
FeatureBitset ToggleFeature(uint64_t FB)
Toggle a feature and return the re-computed feature bits.
virtual unsigned getHwMode(enum HwModeType type=HwMode_Default) const
HwMode ID corresponding to the 'type' parameter is retrieved from the HwMode bit set of the current s...
Represent a reference to a symbol from inside an expression.
uint16_t getSpecifier() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
bool isInSection() const
isInSection - Check if this symbol is defined in some section (i.e., it is defined but not absolute).
bool isUndefined() const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).
StringRef getName() const
getName - Get the symbol name.
bool isVariable() const
isVariable - Check if this is a variable symbol.
const MCExpr * getVariableValue() const
Get the expression of the variable symbol.
bool isTemporary() const
isTemporary - Check if this is an assembler temporary symbol.
MCTargetAsmParser - Generic interface to target specific assembly parsers.
MCStreamer & getStreamer()
Unary assembler expressions.
const MCSymbol * getAddSym() const
int64_t getConstant() const
const MCSymbol * getSubSym() const
void emitRRX(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, MCOperand Op2, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveSetReorder()
void emitRRRX(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, MCRegister Reg2, MCOperand Op3, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRX(unsigned Opcode, MCRegister Reg0, MCOperand Op1, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitR(unsigned Opcode, MCRegister Reg0, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void setUsesMicroMips()
void emitRRI(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, int16_t Imm, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitEmptyDelaySlot(bool hasShortDelaySlot, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRI(unsigned Opcode, MCRegister Reg0, int32_t Imm, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRR(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, SMLoc IDLoc, const MCSubtargetInfo *STI)
void updateABIInfo(const PredicateLibrary &P)
void emitRRIII(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, int16_t Imm0, int16_t Imm1, int16_t Imm2, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitDSLL(MCRegister DstReg, MCRegister SrcReg, int16_t ShiftAmount, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitGPRestore(int Offset, SMLoc IDLoc, const MCSubtargetInfo *STI)
Emit the $gp restore operation for .cprestore.
void emitNop(SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRRR(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, MCRegister Reg2, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveSetNoReorder()
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
static constexpr StatusTy Failure
constexpr bool isSuccess() const
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
constexpr bool isNoMatch() const
constexpr unsigned id() const
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
void push_back(const T &Elt)
iterator find(StringRef Key)
StringRef - Represent a constant reference to a string, i.e.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
empty - Check if the string is empty.
LLVM_ABI bool isLittleEndian() const
Tests whether the target triple is little endian.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
bool parseAssignmentExpression(StringRef Name, bool allow_redef, MCAsmParser &Parser, MCSymbol *&Symbol, const MCExpr *&Value)
Parse a value expression and return whether it can be assigned to a symbol with the given name.
@ CE
Windows NT (Windows on ARM)
LLVM_ABI StringRef getABIName()
Context & getContext() const
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Target & getTheMips64Target()
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
static StringRef getCPU(StringRef CPU)
Processes a CPU name.
int bit_width(T Value)
Returns the number of bits needed to represent Value if Value is nonzero.
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
@ Success
The lock was released successfully.
Target & getTheMips64elTarget()
uint64_t offsetToAlignment(uint64_t Value, Align Alignment)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
@ Ref
The access may reference the value stored in memory.
To bit_cast(const From &from) noexcept
Target & getTheMipselTarget()
DWARFExpression::Operation Op
constexpr bool isShiftedInt(int64_t x)
Checks if a signed integer is an N bit number shifted left by S.
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
static uint16_t getSpecifier(const MCSymbolRefExpr *SRE)
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
Target & getTheMipsTarget()
constexpr bool isShiftedUInt(uint64_t x)
Checks if a unsigned integer is an N bit number shifted left by S.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...