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));
700 bool inMips16Mode()
const {
701 return getSTI().hasFeature(Mips::FeatureMips16);
704 bool useTraps()
const {
705 return getSTI().hasFeature(Mips::FeatureUseTCCInDIV);
708 bool useSoftFloat()
const {
709 return getSTI().hasFeature(Mips::FeatureSoftFloat);
712 return getSTI().hasFeature(Mips::FeatureMT);
715 bool hasCRC()
const {
716 return getSTI().hasFeature(Mips::FeatureCRC);
719 bool hasVirt()
const {
720 return getSTI().hasFeature(Mips::FeatureVirt);
723 bool hasGINV()
const {
724 return getSTI().hasFeature(Mips::FeatureGINV);
727 bool hasForbiddenSlot(
const MCInstrDesc &MCID)
const {
731 bool SafeInForbiddenSlot(
const MCInstrDesc &MCID)
const {
735 void onEndOfFile()
override;
738 void warnIfRegIndexIsAT(MCRegister RegIndex, SMLoc Loc);
740 void warnIfNoMacro(SMLoc Loc);
742 bool isLittle()
const {
return IsLittleEndian; }
744 bool areEqualRegs(
const MCParsedAsmOperand &Op1,
745 const MCParsedAsmOperand &Op2)
const override;
760 RegKind_MSACtrl = 16,
765 RegKind_HWRegs = 256,
769 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
770 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
771 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
784 MipsOperand(KindTy K, MipsAsmParser &Parser) : Kind(
K), AsmParser(Parser) {}
786 ~MipsOperand()
override {
795 case k_RegisterIndex:
803 MipsAsmParser &AsmParser;
814 const MCRegisterInfo *RegInfo;
832 struct RegIdxOp RegIdx;
835 struct RegListOp RegList;
838 SMLoc StartLoc, EndLoc;
841 static std::unique_ptr<MipsOperand> CreateReg(
unsigned Index, StringRef Str,
843 const MCRegisterInfo *RegInfo,
845 MipsAsmParser &Parser) {
846 auto Op = std::make_unique<MipsOperand>(k_RegisterIndex, Parser);
848 Op->RegIdx.RegInfo = RegInfo;
849 Op->RegIdx.Kind = RegKind;
850 Op->RegIdx.Tok.Data = Str.data();
851 Op->RegIdx.Tok.Length = Str.size();
860 MCRegister getGPR32Reg()
const {
861 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
862 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
863 unsigned ClassID = Mips::GPR32RegClassID;
864 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
869 MCRegister getGPRMM16Reg()
const {
870 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
871 unsigned ClassID = Mips::GPR32RegClassID;
872 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
877 MCRegister getGPR64Reg()
const {
878 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
879 unsigned ClassID = Mips::GPR64RegClassID;
880 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
886 MCRegister getAFGR64Reg()
const {
887 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
888 if (RegIdx.Index % 2 != 0)
889 AsmParser.Warning(StartLoc,
"Float register should be even.");
890 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
891 .getRegister(RegIdx.Index / 2);
896 MCRegister getFGR64Reg()
const {
897 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
898 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
899 .getRegister(RegIdx.Index);
904 MCRegister getFGR32Reg()
const {
905 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
906 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
907 .getRegister(RegIdx.Index);
912 MCRegister getFCCReg()
const {
913 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) &&
"Invalid access!");
914 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
915 .getRegister(RegIdx.Index);
920 MCRegister getMSA128Reg()
const {
921 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) &&
"Invalid access!");
924 unsigned ClassID = Mips::MSA128BRegClassID;
925 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
930 MCRegister getMSACtrlReg()
const {
931 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) &&
"Invalid access!");
932 unsigned ClassID = Mips::MSACtrlRegClassID;
933 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
938 MCRegister getCOP0Reg()
const {
939 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) &&
"Invalid access!");
940 unsigned ClassID = Mips::COP0RegClassID;
941 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
946 MCRegister getCOP2Reg()
const {
947 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) &&
"Invalid access!");
948 unsigned ClassID = Mips::COP2RegClassID;
949 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
954 MCRegister getCOP3Reg()
const {
955 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) &&
"Invalid access!");
956 unsigned ClassID = Mips::COP3RegClassID;
957 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
962 MCRegister getACC64DSPReg()
const {
963 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
964 unsigned ClassID = Mips::ACC64DSPRegClassID;
965 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
970 MCRegister getHI32DSPReg()
const {
971 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
972 unsigned ClassID = Mips::HI32DSPRegClassID;
973 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
978 MCRegister getLO32DSPReg()
const {
979 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
980 unsigned ClassID = Mips::LO32DSPRegClassID;
981 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
986 MCRegister getCCRReg()
const {
987 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) &&
"Invalid access!");
988 unsigned ClassID = Mips::CCRRegClassID;
989 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
994 MCRegister getHWRegsReg()
const {
995 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) &&
"Invalid access!");
996 unsigned ClassID = Mips::HWRegsRegClassID;
997 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1001 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const {
1011 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1018 void addGPR32ZeroAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1019 assert(
N == 1 &&
"Invalid number of operands!");
1023 void addGPR32NonZeroAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1024 assert(
N == 1 &&
"Invalid number of operands!");
1028 void addGPR32AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1029 assert(
N == 1 &&
"Invalid number of operands!");
1033 void addGPRMM16AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1034 assert(
N == 1 &&
"Invalid number of operands!");
1038 void addGPRMM16AsmRegZeroOperands(MCInst &Inst,
unsigned N)
const {
1039 assert(
N == 1 &&
"Invalid number of operands!");
1043 void addGPRMM16AsmRegMovePOperands(MCInst &Inst,
unsigned N)
const {
1044 assert(
N == 1 &&
"Invalid number of operands!");
1048 void addGPRMM16AsmRegMovePPairFirstOperands(MCInst &Inst,
unsigned N)
const {
1049 assert(
N == 1 &&
"Invalid number of operands!");
1053 void addGPRMM16AsmRegMovePPairSecondOperands(MCInst &Inst,
1055 assert(
N == 1 &&
"Invalid number of operands!");
1062 void addGPR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1063 assert(
N == 1 &&
"Invalid number of operands!");
1067 void addAFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1068 assert(
N == 1 &&
"Invalid number of operands!");
1072 void addStrictlyAFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1073 assert(
N == 1 &&
"Invalid number of operands!");
1077 void addStrictlyFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1078 assert(
N == 1 &&
"Invalid number of operands!");
1082 void addFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1083 assert(
N == 1 &&
"Invalid number of operands!");
1087 void addFGR32AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1088 assert(
N == 1 &&
"Invalid number of operands!");
1092 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1093 AsmParser.getParser().printError(
1094 StartLoc,
"-mno-odd-spreg prohibits the use of odd FPU "
1098 void addStrictlyFGR32AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1099 assert(
N == 1 &&
"Invalid number of operands!");
1102 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1103 AsmParser.Error(StartLoc,
"-mno-odd-spreg prohibits the use of odd FPU "
1107 void addFCCAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1108 assert(
N == 1 &&
"Invalid number of operands!");
1112 void addMSA128AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1113 assert(
N == 1 &&
"Invalid number of operands!");
1117 void addMSACtrlAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1118 assert(
N == 1 &&
"Invalid number of operands!");
1122 void addCOP0AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1123 assert(
N == 1 &&
"Invalid number of operands!");
1127 void addCOP2AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1128 assert(
N == 1 &&
"Invalid number of operands!");
1132 void addCOP3AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1133 assert(
N == 1 &&
"Invalid number of operands!");
1137 void addACC64DSPAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1138 assert(
N == 1 &&
"Invalid number of operands!");
1142 void addHI32DSPAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1143 assert(
N == 1 &&
"Invalid number of operands!");
1147 void addLO32DSPAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1148 assert(
N == 1 &&
"Invalid number of operands!");
1152 void addCCRAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1153 assert(
N == 1 &&
"Invalid number of operands!");
1157 void addHWRegsAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1158 assert(
N == 1 &&
"Invalid number of operands!");
1162 template <
unsigned Bits,
int Offset = 0,
int AdjustOffset = 0>
1163 void addConstantUImmOperands(MCInst &Inst,
unsigned N)
const {
1164 assert(
N == 1 &&
"Invalid number of operands!");
1165 uint64_t
Imm = getConstantImm() -
Offset;
1168 Imm += AdjustOffset;
1172 template <
unsigned Bits>
1173 void addSImmOperands(MCInst &Inst,
unsigned N)
const {
1174 if (isImm() && !isConstantImm()) {
1178 addConstantSImmOperands<Bits, 0, 0>(Inst,
N);
1181 template <
unsigned Bits>
1182 void addUImmOperands(MCInst &Inst,
unsigned N)
const {
1183 if (isImm() && !isConstantImm()) {
1187 addConstantUImmOperands<Bits, 0, 0>(Inst,
N);
1190 template <
unsigned Bits,
int Offset = 0,
int AdjustOffset = 0>
1191 void addConstantSImmOperands(MCInst &Inst,
unsigned N)
const {
1192 assert(
N == 1 &&
"Invalid number of operands!");
1193 int64_t
Imm = getConstantImm() -
Offset;
1196 Imm += AdjustOffset;
1200 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1201 assert(
N == 1 &&
"Invalid number of operands!");
1202 const MCExpr *Expr =
getImm();
1203 addExpr(Inst, Expr);
1206 void addMemOperands(MCInst &Inst,
unsigned N)
const {
1207 assert(
N == 2 &&
"Invalid number of operands!");
1210 ? getMemBase()->getGPR64Reg()
1211 : getMemBase()->getGPR32Reg()));
1213 const MCExpr *Expr = getMemOff();
1214 addExpr(Inst, Expr);
1217 void addMicroMipsMemOperands(MCInst &Inst,
unsigned N)
const {
1218 assert(
N == 2 &&
"Invalid number of operands!");
1222 const MCExpr *Expr = getMemOff();
1223 addExpr(Inst, Expr);
1226 void addRegListOperands(MCInst &Inst,
unsigned N)
const {
1227 assert(
N == 1 &&
"Invalid number of operands!");
1229 for (
auto RegNo : getRegList())
1233 bool isReg()
const override {
1236 return isGPRAsmReg() && RegIdx.Index == 0;
1239 bool isRegIdx()
const {
return Kind == k_RegisterIndex; }
1240 bool isImm()
const override {
return Kind == k_Immediate; }
1242 bool isConstantImm()
const {
1244 return isImm() &&
getImm()->evaluateAsAbsolute(Res);
1247 bool isConstantImmz()
const {
1248 return isConstantImm() && getConstantImm() == 0;
1251 template <
unsigned Bits,
int Offset = 0>
bool isConstantUImm()
const {
1255 template <
unsigned Bits>
bool isSImm()
const {
1259 if (
getImm()->evaluateAsAbsolute(Res))
1265 template <
unsigned Bits>
bool isUImm()
const {
1269 if (
getImm()->evaluateAsAbsolute(Res))
1275 template <
unsigned Bits>
bool isAnyImm()
const {
1276 return isConstantImm() ? (
isInt<Bits>(getConstantImm()) ||
1281 template <
unsigned Bits,
int Offset = 0>
bool isConstantSImm()
const {
1285 template <
unsigned Bottom,
unsigned Top>
bool isConstantUImmRange()
const {
1286 return isConstantImm() && getConstantImm() >= Bottom &&
1287 getConstantImm() <= Top;
1290 bool isToken()
const override {
1293 return Kind == k_Token;
1296 bool isMem()
const override {
return Kind == k_Memory; }
1298 bool isConstantMemOff()
const {
1303 template <
unsigned Bits,
unsigned ShiftAmount = 0>
1304 bool isMemWithSimmOffset()
const {
1307 if (!getMemBase()->isGPRAsmReg())
1310 (isConstantMemOff() &&
1314 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res,
nullptr);
1318 bool isMemWithPtrSizeOffset()
const {
1321 if (!getMemBase()->isGPRAsmReg())
1323 const unsigned PtrBits = AsmParser.getABI().ArePtrs64bit() ? 64 : 32;
1325 (isConstantMemOff() &&
isIntN(PtrBits, getConstantMemOff())))
1328 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res,
nullptr);
1332 bool isMemWithGRPMM16Base()
const {
1333 return isMem() && getMemBase()->isMM16AsmReg();
1336 template <
unsigned Bits>
bool isMemWithUimmOffsetSP()
const {
1338 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1341 template <
unsigned Bits>
bool isMemWithUimmWordAlignedOffsetSP()
const {
1343 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1344 && (getMemBase()->getGPR32Reg() == Mips::SP);
1347 template <
unsigned Bits>
bool isMemWithSimmWordAlignedOffsetGP()
const {
1349 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1350 && (getMemBase()->getGPR32Reg() == Mips::GP);
1353 template <
unsigned Bits,
unsigned ShiftLeftAmount>
1354 bool isScaledUImm()
const {
1355 return isConstantImm() &&
1359 template <
unsigned Bits,
unsigned ShiftLeftAmount>
1360 bool isScaledSImm()
const {
1361 if (isConstantImm() &&
1366 if (Kind != k_Immediate)
1369 bool Success =
getImm()->evaluateAsRelocatable(Res,
nullptr);
1373 bool isRegList16()
const {
1377 int Size = RegList.List->size();
1381 MCRegister R0 = RegList.List->front();
1382 MCRegister R1 = RegList.List->back();
1383 if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1384 (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1387 MCRegister PrevReg = RegList.List->front();
1388 for (
int i = 1; i <
Size - 1; i++) {
1389 MCRegister
Reg = (*(RegList.List))[i];
1390 if (
Reg != PrevReg + 1)
1398 bool isInvNum()
const {
return Kind == k_Immediate; }
1400 bool isLSAImm()
const {
1401 if (!isConstantImm())
1403 int64_t Val = getConstantImm();
1404 return 1 <= Val && Val <= 4;
1407 bool isRegList()
const {
return Kind == k_RegList; }
1410 assert(Kind == k_Token &&
"Invalid access!");
1411 return StringRef(Tok.Data, Tok.Length);
1414 MCRegister
getReg()
const override {
1417 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1418 RegIdx.Kind & RegKind_GPR)
1419 return getGPR32Reg();
1425 const MCExpr *
getImm()
const {
1426 assert((Kind == k_Immediate) &&
"Invalid access!");
1430 int64_t getConstantImm()
const {
1431 const MCExpr *Val =
getImm();
1433 (void)Val->evaluateAsAbsolute(
Value);
1437 MipsOperand *getMemBase()
const {
1438 assert((Kind == k_Memory) &&
"Invalid access!");
1442 const MCExpr *getMemOff()
const {
1443 assert((Kind == k_Memory) &&
"Invalid access!");
1447 int64_t getConstantMemOff()
const {
1448 return static_cast<const MCConstantExpr *
>(getMemOff())->getValue();
1451 const SmallVectorImpl<MCRegister> &getRegList()
const {
1452 assert((Kind == k_RegList) &&
"Invalid access!");
1453 return *(RegList.List);
1456 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1457 MipsAsmParser &Parser) {
1458 auto Op = std::make_unique<MipsOperand>(k_Token, Parser);
1459 Op->Tok.Data = Str.data();
1460 Op->Tok.Length = Str.size();
1468 static std::unique_ptr<MipsOperand>
1469 createNumericReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1470 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1471 LLVM_DEBUG(
dbgs() <<
"createNumericReg(" << Index <<
", ...)\n");
1472 return CreateReg(Index, Str, RegKind_Numeric, RegInfo, S,
E, Parser);
1477 static std::unique_ptr<MipsOperand>
1478 createGPRReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1479 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1480 return CreateReg(Index, Str, RegKind_GPR, RegInfo, S,
E, Parser);
1485 static std::unique_ptr<MipsOperand>
1486 createFGRReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1487 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1488 return CreateReg(Index, Str, RegKind_FGR, RegInfo, S,
E, Parser);
1493 static std::unique_ptr<MipsOperand>
1494 createHWRegsReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1495 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1496 return CreateReg(Index, Str, RegKind_HWRegs, RegInfo, S,
E, Parser);
1501 static std::unique_ptr<MipsOperand>
1502 createFCCReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1503 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1504 return CreateReg(Index, Str, RegKind_FCC, RegInfo, S,
E, Parser);
1509 static std::unique_ptr<MipsOperand>
1510 createACCReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1511 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1512 return CreateReg(Index, Str, RegKind_ACC, RegInfo, S,
E, Parser);
1517 static std::unique_ptr<MipsOperand>
1518 createMSA128Reg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1519 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1520 return CreateReg(Index, Str, RegKind_MSA128, RegInfo, S,
E, Parser);
1525 static std::unique_ptr<MipsOperand>
1526 createMSACtrlReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1527 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1528 return CreateReg(Index, Str, RegKind_MSACtrl, RegInfo, S,
E, Parser);
1531 static std::unique_ptr<MipsOperand>
1532 CreateImm(
const MCExpr *Val, SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1533 auto Op = std::make_unique<MipsOperand>(k_Immediate, Parser);
1540 static std::unique_ptr<MipsOperand>
1541 CreateMem(std::unique_ptr<MipsOperand>
Base,
const MCExpr *Off, SMLoc S,
1542 SMLoc
E, MipsAsmParser &Parser) {
1543 auto Op = std::make_unique<MipsOperand>(k_Memory, Parser);
1544 Op->Mem.Base =
Base.release();
1551 static std::unique_ptr<MipsOperand>
1552 CreateRegList(SmallVectorImpl<MCRegister> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1553 MipsAsmParser &Parser) {
1554 assert(!Regs.
empty() &&
"Empty list not allowed");
1556 auto Op = std::make_unique<MipsOperand>(k_RegList, Parser);
1559 Op->StartLoc = StartLoc;
1560 Op->EndLoc = EndLoc;
1564 bool isGPRZeroAsmReg()
const {
1565 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
1568 bool isGPRNonZeroAsmReg()
const {
1569 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index > 0 &&
1573 bool isGPRAsmReg()
const {
1574 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1577 bool isMM16AsmReg()
const {
1578 if (!(isRegIdx() && RegIdx.Kind))
1580 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1581 || RegIdx.Index == 16 || RegIdx.Index == 17);
1584 bool isMM16AsmRegZero()
const {
1585 if (!(isRegIdx() && RegIdx.Kind))
1587 return (RegIdx.Index == 0 ||
1588 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1589 RegIdx.Index == 17);
1592 bool isMM16AsmRegMoveP()
const {
1593 if (!(isRegIdx() && RegIdx.Kind))
1595 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1596 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1599 bool isMM16AsmRegMovePPairFirst()
const {
1600 if (!(isRegIdx() && RegIdx.Kind))
1602 return RegIdx.Index >= 4 && RegIdx.Index <= 6;
1605 bool isMM16AsmRegMovePPairSecond()
const {
1606 if (!(isRegIdx() && RegIdx.Kind))
1608 return (RegIdx.Index == 21 || RegIdx.Index == 22 ||
1609 (RegIdx.Index >= 5 && RegIdx.Index <= 7));
1612 bool isFGRAsmReg()
const {
1614 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1617 bool isStrictlyFGRAsmReg()
const {
1619 return isRegIdx() && RegIdx.Kind == RegKind_FGR && RegIdx.Index <= 31;
1622 bool isHWRegsAsmReg()
const {
1623 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1626 bool isCCRAsmReg()
const {
1627 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1630 bool isFCCAsmReg()
const {
1631 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1633 return RegIdx.Index <= 7;
1636 bool isACCAsmReg()
const {
1637 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1640 bool isCOP0AsmReg()
const {
1641 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1644 bool isCOP2AsmReg()
const {
1645 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1648 bool isCOP3AsmReg()
const {
1649 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1652 bool isMSA128AsmReg()
const {
1653 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1656 bool isMSACtrlAsmReg()
const {
1657 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1661 SMLoc getStartLoc()
const override {
return StartLoc; }
1663 SMLoc getEndLoc()
const override {
return EndLoc; }
1665 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1674 Mem.Base->print(OS, MAI);
1679 case k_RegisterIndex:
1680 OS <<
"RegIdx<" << RegIdx.Index <<
":" << RegIdx.Kind <<
", "
1681 << StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) <<
">";
1688 for (
auto Reg : (*RegList.List))
1689 OS <<
Reg.
id() <<
" ";
1695 bool isValidForTie(
const MipsOperand &
Other)
const {
1696 if (Kind !=
Other.Kind)
1703 case k_RegisterIndex: {
1704 StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length);
1705 StringRef OtherToken(
Other.RegIdx.Tok.Data,
Other.RegIdx.Tok.Length);
1706 return Token == OtherToken;
1722 case Mips::JRC16_MM:
1724 case Mips::JALRS_MM:
1725 case Mips::JALRS16_MM:
1726 case Mips::BGEZALS_MM:
1727 case Mips::BLTZALS_MM:
1738 return &SRExpr->getSymbol();
1797 unsigned NumOp =
MCID.getNumOperands();
1798 if (NumOp != 3 && NumOp != 4)
1828bool MipsAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
1831 MipsTargetStreamer &TOut = getTargetStreamer();
1832 const unsigned Opcode = Inst.
getOpcode();
1833 const MCInstrDesc &MCID = MII.get(Opcode);
1834 bool ExpandedJalSym =
false;
1848 assert(hasCnMips() &&
"instruction only valid for octeon cpus");
1859 if (!
isIntN(inMicroMipsMode() ? 17 : 18,
Offset.getImm()))
1860 return Error(IDLoc,
"branch target out of range");
1863 return Error(IDLoc,
"branch to misaligned address");
1877 case Mips::BGEZAL_MM:
1878 case Mips::BLTZAL_MM:
1881 case Mips::BC1EQZC_MMR6:
1882 case Mips::BC1NEZC_MMR6:
1883 case Mips::BC2EQZC_MMR6:
1884 case Mips::BC2NEZC_MMR6:
1889 if (!
isIntN(inMicroMipsMode() ? 17 : 18,
Offset.getImm()))
1890 return Error(IDLoc,
"branch target out of range");
1893 return Error(IDLoc,
"branch to misaligned address");
1895 case Mips::BGEC:
case Mips::BGEC_MMR6:
1896 case Mips::BLTC:
case Mips::BLTC_MMR6:
1897 case Mips::BGEUC:
case Mips::BGEUC_MMR6:
1898 case Mips::BLTUC:
case Mips::BLTUC_MMR6:
1899 case Mips::BEQC:
case Mips::BEQC_MMR6:
1900 case Mips::BNEC:
case Mips::BNEC_MMR6:
1906 return Error(IDLoc,
"branch target out of range");
1908 return Error(IDLoc,
"branch to misaligned address");
1910 case Mips::BLEZC:
case Mips::BLEZC_MMR6:
1911 case Mips::BGEZC:
case Mips::BGEZC_MMR6:
1912 case Mips::BGTZC:
case Mips::BGTZC_MMR6:
1913 case Mips::BLTZC:
case Mips::BLTZC_MMR6:
1919 return Error(IDLoc,
"branch target out of range");
1921 return Error(IDLoc,
"branch to misaligned address");
1923 case Mips::BEQZC:
case Mips::BEQZC_MMR6:
1924 case Mips::BNEZC:
case Mips::BNEZC_MMR6:
1930 return Error(IDLoc,
"branch target out of range");
1932 return Error(IDLoc,
"branch to misaligned address");
1934 case Mips::BEQZ16_MM:
1935 case Mips::BEQZC16_MMR6:
1936 case Mips::BNEZ16_MM:
1937 case Mips::BNEZC16_MMR6:
1943 return Error(IDLoc,
"branch target out of range");
1945 return Error(IDLoc,
"branch to misaligned address");
1952 if (hasMips32r6() && Opcode == Mips::SSNOP) {
1953 std::string
ISA = hasMips64r6() ?
"MIPS64r6" :
"MIPS32r6";
1954 Warning(IDLoc,
"ssnop is deprecated for " + ISA +
" and is equivalent to a "
1974 return Error(IDLoc,
"expected immediate operand kind");
1976 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1977 Opcode == Mips::BBIT1 ? 63 : 31))
1978 return Error(IDLoc,
"immediate operand value out of range");
1980 Inst.
setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1991 return Error(IDLoc,
"expected immediate operand kind");
1994 return Error(IDLoc,
"immediate operand value out of range");
2006 unsigned FirstOp = 1;
2007 unsigned SecondOp = 2;
2011 case Mips::SDivIMacro:
2012 case Mips::UDivIMacro:
2013 case Mips::DSDivIMacro:
2014 case Mips::DUDivIMacro:
2018 Warning(IDLoc,
"dividing zero by zero");
2020 Warning(IDLoc,
"division by zero");
2032 case Mips::SDivMacro:
2033 case Mips::DSDivMacro:
2034 case Mips::UDivMacro:
2035 case Mips::DUDivMacro:
2040 case Mips::DIVU_MMR6:
2041 case Mips::DIV_MMR6:
2046 Warning(IDLoc,
"dividing zero by zero");
2048 Warning(IDLoc,
"division by zero");
2054 if ((Opcode == Mips::J || Opcode == Mips::J_MM) && inPicMode()) {
2056 BInst.
setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
2065 if ((Opcode == Mips::JAL || Opcode == Mips::JAL_MM) && inPicMode()) {
2066 warnIfNoMacro(IDLoc);
2069 return Error(IDLoc,
"unsupported constant in relocation");
2077 return Error(IDLoc,
"jal doesn't support multiple symbols in PIC mode");
2083 if (expandLoadAddress(Mips::T9, MCRegister(), Inst.
getOperand(0),
2084 !isGP64bit(), IDLoc, Out, STI))
2088 if (inMicroMipsMode())
2089 JalrInst.
setOpcode(IsCpRestoreSet ? Mips::JALRS_MM : Mips::JALR_MM);
2095 if (isJalrRelocAvailable(JalExpr)) {
2101 const MCExpr *RelocJalrExpr =
2105 *TmpExpr, inMicroMipsMode() ?
"R_MICROMIPS_JALR" :
"R_MIPS_JALR",
2111 ExpandedJalSym =
true;
2120 expandMem9Inst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2123 expandMem16Inst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2126 return getParser().hasPendingError();
2130 if (inMicroMipsMode()) {
2131 if (MCID.
mayLoad() && Opcode != Mips::LWP_MM) {
2134 const MCOperandInfo &OpInfo = MCID.
operands()[i];
2139 int MemOffset =
Op.getImm();
2142 if (
isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
2145 (
BaseReg.getReg() == Mips::GP ||
2146 BaseReg.getReg() == Mips::GP_64)) {
2148 TOut.
emitRRI(Mips::LWGP_MM, DstReg.
getReg(), Mips::GP, MemOffset,
2165 case Mips::ADDIUSP_MM:
2168 return Error(IDLoc,
"expected immediate operand kind");
2170 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
2172 return Error(IDLoc,
"immediate operand value out of range");
2174 case Mips::SLL16_MM:
2175 case Mips::SRL16_MM:
2178 return Error(IDLoc,
"expected immediate operand kind");
2180 if (Imm < 1 || Imm > 8)
2181 return Error(IDLoc,
"immediate operand value out of range");
2186 return Error(IDLoc,
"expected immediate operand kind");
2188 if (Imm < -1 || Imm > 126)
2189 return Error(IDLoc,
"immediate operand value out of range");
2191 case Mips::ADDIUR2_MM:
2194 return Error(IDLoc,
"expected immediate operand kind");
2196 if (!(Imm == 1 || Imm == -1 ||
2197 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
2198 return Error(IDLoc,
"immediate operand value out of range");
2200 case Mips::ANDI16_MM:
2203 return Error(IDLoc,
"expected immediate operand kind");
2205 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
2206 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
2207 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
2208 return Error(IDLoc,
"immediate operand value out of range");
2210 case Mips::LBU16_MM:
2213 return Error(IDLoc,
"expected immediate operand kind");
2215 if (Imm < -1 || Imm > 14)
2216 return Error(IDLoc,
"immediate operand value out of range");
2219 case Mips::SB16_MMR6:
2222 return Error(IDLoc,
"expected immediate operand kind");
2224 if (Imm < 0 || Imm > 15)
2225 return Error(IDLoc,
"immediate operand value out of range");
2227 case Mips::LHU16_MM:
2229 case Mips::SH16_MMR6:
2232 return Error(IDLoc,
"expected immediate operand kind");
2234 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
2235 return Error(IDLoc,
"immediate operand value out of range");
2239 case Mips::SW16_MMR6:
2242 return Error(IDLoc,
"expected immediate operand kind");
2244 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
2245 return Error(IDLoc,
"immediate operand value out of range");
2247 case Mips::ADDIUPC_MM:
2250 return Error(IDLoc,
"expected immediate operand kind");
2253 return Error(IDLoc,
"immediate operand value out of range");
2258 return Error(IDLoc,
"invalid operand for instruction");
2260 case Mips::MOVEP_MM:
2261 case Mips::MOVEP_MMR6: {
2264 bool RegPair = ((R0 == Mips::A1 && R1 == Mips::A2) ||
2265 (R0 == Mips::A1 && R1 == Mips::A3) ||
2266 (R0 == Mips::A2 && R1 == Mips::A3) ||
2267 (R0 == Mips::A0 && R1 == Mips::S5) ||
2268 (R0 == Mips::A0 && R1 == Mips::S6) ||
2269 (R0 == Mips::A0 && R1 == Mips::A1) ||
2270 (R0 == Mips::A0 && R1 == Mips::A2) ||
2271 (R0 == Mips::A0 && R1 == Mips::A3));
2273 return Error(IDLoc,
"invalid operand for instruction");
2279 bool FillDelaySlot =
2284 bool PrevForbiddenSlotAttr = CurForbiddenSlotAttr;
2287 bool SetReorderAfterNop =
false;
2292 if (PrevForbiddenSlotAttr && !SafeInForbiddenSlot(MCID)) {
2302 if (AssemblerOptions.
back()->isReorder() && !FillDelaySlot) {
2303 SetReorderAfterNop =
true;
2312 CurForbiddenSlotAttr =
2313 hasForbiddenSlot(MCID) && AssemblerOptions.
back()->isReorder();
2315 if (FillDelaySlot || CurForbiddenSlotAttr)
2318 MacroExpanderResultTy ExpandResult =
2319 tryExpandInstruction(Inst, IDLoc, Out, STI);
2320 switch (ExpandResult) {
2336 if (PrevForbiddenSlotAttr && !SetReorderAfterNop && !FillDelaySlot &&
2337 AssemblerOptions.
back()->isReorder()) {
2343 if (inMicroMipsMode()) {
2358 if (FillDelaySlot) {
2363 if ((Opcode == Mips::JalOneReg || Opcode == Mips::JalTwoReg ||
2365 isPicAndNotNxxAbi()) {
2366 if (IsCpRestoreSet) {
2370 if (!AssemblerOptions.
back()->isReorder())
2377 Warning(IDLoc,
"no .cprestore used in PIC mode");
2383void MipsAsmParser::onEndOfFile() {
2384 MipsTargetStreamer &TOut = getTargetStreamer();
2385 SMLoc IDLoc = SMLoc();
2387 if (CurForbiddenSlotAttr) {
2389 if (AssemblerOptions.
back()->isReorder())
2394MipsAsmParser::MacroExpanderResultTy
2395MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2396 const MCSubtargetInfo *STI) {
2399 return MER_NotAMacro;
2400 case Mips::LoadImm32:
2401 return expandLoadImm(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2402 case Mips::LoadImm64:
2403 return expandLoadImm(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2404 case Mips::LoadAddrImm32:
2405 case Mips::LoadAddrImm64:
2408 "expected immediate operand kind");
2410 return expandLoadAddress(
2412 Inst.
getOpcode() == Mips::LoadAddrImm32, IDLoc, Out, STI)
2415 case Mips::LoadAddrReg32:
2416 case Mips::LoadAddrReg64:
2420 "expected immediate operand kind");
2424 Inst.
getOpcode() == Mips::LoadAddrReg32, IDLoc,
2428 case Mips::B_MM_Pseudo:
2429 case Mips::B_MMR6_Pseudo:
2430 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2434 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2436 case Mips::JalOneReg:
2437 case Mips::JalTwoReg:
2438 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2441 case Mips::BEQLImmMacro:
2442 case Mips::BNELImmMacro:
2443 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2460 case Mips::BLTImmMacro:
2461 case Mips::BLEImmMacro:
2462 case Mips::BGEImmMacro:
2463 case Mips::BGTImmMacro:
2464 case Mips::BLTUImmMacro:
2465 case Mips::BLEUImmMacro:
2466 case Mips::BGEUImmMacro:
2467 case Mips::BGTUImmMacro:
2468 case Mips::BLTLImmMacro:
2469 case Mips::BLELImmMacro:
2470 case Mips::BGELImmMacro:
2471 case Mips::BGTLImmMacro:
2472 case Mips::BLTULImmMacro:
2473 case Mips::BLEULImmMacro:
2474 case Mips::BGEULImmMacro:
2475 case Mips::BGTULImmMacro:
2476 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2477 case Mips::SDivMacro:
2478 case Mips::SDivIMacro:
2479 case Mips::SRemMacro:
2480 case Mips::SRemIMacro:
2481 return expandDivRem(Inst, IDLoc, Out, STI,
false,
true) ? MER_Fail
2483 case Mips::DSDivMacro:
2484 case Mips::DSDivIMacro:
2485 case Mips::DSRemMacro:
2486 case Mips::DSRemIMacro:
2487 return expandDivRem(Inst, IDLoc, Out, STI,
true,
true) ? MER_Fail
2489 case Mips::UDivMacro:
2490 case Mips::UDivIMacro:
2491 case Mips::URemMacro:
2492 case Mips::URemIMacro:
2493 return expandDivRem(Inst, IDLoc, Out, STI,
false,
false) ? MER_Fail
2495 case Mips::DUDivMacro:
2496 case Mips::DUDivIMacro:
2497 case Mips::DURemMacro:
2498 case Mips::DURemIMacro:
2499 return expandDivRem(Inst, IDLoc, Out, STI,
true,
false) ? MER_Fail
2501 case Mips::PseudoTRUNC_W_S:
2502 return expandTrunc(Inst,
false,
false, IDLoc, Out, STI) ? MER_Fail
2504 case Mips::PseudoTRUNC_W_D32:
2505 return expandTrunc(Inst,
true,
false, IDLoc, Out, STI) ? MER_Fail
2507 case Mips::PseudoTRUNC_W_D:
2508 return expandTrunc(Inst,
true,
true, IDLoc, Out, STI) ? MER_Fail
2511 case Mips::LoadImmSingleGPR:
2512 return expandLoadSingleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2514 case Mips::LoadImmSingleFGR:
2515 return expandLoadSingleImmToFPR(Inst, IDLoc, Out, STI) ? MER_Fail
2517 case Mips::LoadImmDoubleGPR:
2518 return expandLoadDoubleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2520 case Mips::LoadImmDoubleFGR:
2521 return expandLoadDoubleImmToFPR(Inst,
true, IDLoc, Out, STI) ? MER_Fail
2523 case Mips::LoadImmDoubleFGR_32:
2524 return expandLoadDoubleImmToFPR(Inst,
false, IDLoc, Out, STI) ? MER_Fail
2528 return expandUlh(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2530 return expandUlh(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2532 return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2535 return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2537 case Mips::NORImm64:
2538 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2541 return expandSge(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2544 case Mips::SGEImm64:
2545 case Mips::SGEUImm64:
2546 return expandSgeImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2549 case Mips::SGTImm64:
2550 case Mips::SGTUImm64:
2551 return expandSgtImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2554 return expandSle(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2557 case Mips::SLEImm64:
2558 case Mips::SLEUImm64:
2559 return expandSleImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2560 case Mips::SLTImm64:
2563 return MER_NotAMacro;
2565 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2566 case Mips::SLTUImm64:
2569 return MER_NotAMacro;
2571 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2572 case Mips::ADDi:
case Mips::ADDi_MM:
2573 case Mips::ADDiu:
case Mips::ADDiu_MM:
2574 case Mips::SLTi:
case Mips::SLTi_MM:
2575 case Mips::SLTiu:
case Mips::SLTiu_MM:
2580 return MER_NotAMacro;
2581 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2584 return MER_NotAMacro;
2585 case Mips::ANDi:
case Mips::ANDi_MM:
case Mips::ANDi64:
2586 case Mips::ORi:
case Mips::ORi_MM:
case Mips::ORi64:
2587 case Mips::XORi:
case Mips::XORi_MM:
case Mips::XORi64:
2592 return MER_NotAMacro;
2593 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2596 return MER_NotAMacro;
2599 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2602 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2605 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2608 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2609 case Mips::ABSMacro:
2610 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2611 case Mips::MULImmMacro:
2612 case Mips::DMULImmMacro:
2613 return expandMulImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2614 case Mips::MULOMacro:
2615 case Mips::DMULOMacro:
2616 return expandMulO(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2617 case Mips::MULOUMacro:
2618 case Mips::DMULOUMacro:
2619 return expandMulOU(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2620 case Mips::DMULMacro:
2621 return expandDMULMacro(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2624 return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2629 return expandStoreDM1Macro(Inst, IDLoc, Out, STI)
2632 case Mips::SEQMacro:
2633 return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2634 case Mips::SEQIMacro:
2635 return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2636 case Mips::SNEMacro:
2637 return expandSne(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2638 case Mips::SNEIMacro:
2639 return expandSneI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2640 case Mips::MFTC0:
case Mips::MTTC0:
2641 case Mips::MFTGPR:
case Mips::MTTGPR:
2642 case Mips::MFTLO:
case Mips::MTTLO:
2643 case Mips::MFTHI:
case Mips::MTTHI:
2644 case Mips::MFTACX:
case Mips::MTTACX:
2645 case Mips::MFTDSP:
case Mips::MTTDSP:
2646 case Mips::MFTC1:
case Mips::MTTC1:
2647 case Mips::MFTHC1:
case Mips::MTTHC1:
2648 case Mips::CFTC1:
case Mips::CTTC1:
2649 return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2651 case Mips::SaadAddr:
2652 return expandSaaAddr(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2656bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2658 const MCSubtargetInfo *STI) {
2659 MipsTargetStreamer &TOut = getTargetStreamer();
2664 const MCOperand FirstRegOp = Inst.
getOperand(0);
2665 const unsigned Opcode = Inst.
getOpcode();
2667 if (Opcode == Mips::JalOneReg) {
2669 if (IsCpRestoreSet && inMicroMipsMode()) {
2672 }
else if (inMicroMipsMode()) {
2673 JalrInst.
setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2680 }
else if (Opcode == Mips::JalTwoReg) {
2682 if (IsCpRestoreSet && inMicroMipsMode())
2685 JalrInst.
setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2687 const MCOperand SecondRegOp = Inst.
getOperand(1);
2694 const MCInstrDesc &MCID = MII.get(JalrInst.
getOpcode());
2717bool MipsAsmParser::loadImmediate(int64_t ImmValue, MCRegister DstReg,
2718 MCRegister SrcReg,
bool Is32BitImm,
2719 bool IsAddress, SMLoc IDLoc, MCStreamer &Out,
2720 const MCSubtargetInfo *STI) {
2721 MipsTargetStreamer &TOut = getTargetStreamer();
2723 if (!Is32BitImm && !isGP64bit()) {
2724 Error(IDLoc,
"instruction requires a 64-bit architecture");
2735 Error(IDLoc,
"instruction requires a 32-bit immediate");
2740 MCRegister ZeroReg = IsAddress ?
ABI.GetNullPtr() :
ABI.GetZeroReg();
2741 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2743 bool UseSrcReg =
false;
2747 MCRegister TmpReg = DstReg;
2749 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2752 MCRegister ATReg = getATReg(IDLoc);
2765 if (IsAddress && !Is32BitImm) {
2766 TOut.
emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2770 TOut.
emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2775 MCRegister TmpReg = DstReg;
2776 if (SrcReg == DstReg) {
2777 TmpReg = getATReg(IDLoc);
2782 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2784 TOut.
emitRRR(
ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2789 warnIfNoMacro(IDLoc);
2791 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2792 uint16_t Bits15To0 = ImmValue & 0xffff;
2793 if (!Is32BitImm && !
isInt<32>(ImmValue)) {
2796 if (ImmValue == 0xffffffff) {
2797 TOut.
emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2798 TOut.
emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2800 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2806 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2807 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2809 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2811 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2815 TOut.
emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2817 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2819 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2825 Error(IDLoc,
"instruction requires a 32-bit immediate");
2832 assert(
BitWidth >= 17 &&
"ImmValue must be at least 17-bit wide");
2836 unsigned ShiftAmount =
BitWidth - 16;
2837 uint16_t
Bits = (ImmValue >> ShiftAmount) & 0xffff;
2838 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2839 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2842 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2847 warnIfNoMacro(IDLoc);
2854 if (loadImmediate(ImmValue >> 32, TmpReg, MCRegister(),
true,
false, IDLoc,
2860 unsigned ShiftCarriedForwards = 16;
2861 for (
int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2862 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2864 if (ImmChunk != 0) {
2865 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2866 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2867 ShiftCarriedForwards = 0;
2870 ShiftCarriedForwards += 16;
2872 ShiftCarriedForwards -= 16;
2875 if (ShiftCarriedForwards)
2876 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2879 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2884bool MipsAsmParser::expandLoadImm(MCInst &Inst,
bool Is32BitImm, SMLoc IDLoc,
2885 MCStreamer &Out,
const MCSubtargetInfo *STI) {
2887 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
2888 const MCOperand &DstRegOp = Inst.
getOperand(0);
2889 assert(DstRegOp.
isReg() &&
"expected register operand kind");
2891 if (loadImmediate(ImmOp.
getImm(), DstRegOp.
getReg(), MCRegister(), Is32BitImm,
2892 false, IDLoc, Out, STI))
2898bool MipsAsmParser::expandLoadAddress(MCRegister DstReg, MCRegister BaseReg,
2900 bool Is32BitAddress, SMLoc IDLoc,
2902 const MCSubtargetInfo *STI) {
2904 if (Is32BitAddress &&
ABI.ArePtrs64bit()) {
2905 Warning(IDLoc,
"la used to load 64-bit address");
2907 Is32BitAddress =
false;
2911 if (!Is32BitAddress && !hasMips3()) {
2912 Error(IDLoc,
"instruction requires a 64-bit architecture");
2917 return loadAndAddSymbolAddress(
Offset.getExpr(), DstReg, BaseReg,
2918 Is32BitAddress, IDLoc, Out, STI);
2920 if (!
ABI.ArePtrs64bit()) {
2922 Is32BitAddress =
true;
2925 return loadImmediate(
Offset.getImm(), DstReg, BaseReg, Is32BitAddress,
true,
2929bool MipsAsmParser::loadAndAddSymbolAddress(
const MCExpr *SymExpr,
2931 MCRegister SrcReg,
bool Is32BitSym,
2932 SMLoc IDLoc, MCStreamer &Out,
2933 const MCSubtargetInfo *STI) {
2934 MipsTargetStreamer &TOut = getTargetStreamer();
2936 SrcReg.
isValid() && SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64;
2937 warnIfNoMacro(IDLoc);
2942 Error(IDLoc,
"expected relocatable expression");
2946 Error(IDLoc,
"expected relocatable expression with only one symbol");
2950 bool IsPtr64 =
ABI.ArePtrs64bit();
2954 static_cast<const MCSymbolELF *
>(Res.
getAddSym())->getBinding() ==
2961 bool UseXGOT = STI->
hasFeature(Mips::FeatureXGOT) && !IsLocalSym;
2967 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2970 const MCExpr *CallHiExpr =
2972 const MCExpr *CallLoExpr =
2976 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, DstReg, GPReg,
2978 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, DstReg,
2981 const MCExpr *CallExpr =
2983 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, GPReg,
2989 MCRegister TmpReg = DstReg;
2991 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2995 MCRegister ATReg = getATReg(IDLoc);
3014 const MCExpr *CallHiExpr =
3021 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg, GPReg,
3023 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, TmpReg,
3027 TOut.
emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3033 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3038 const MCSpecifierExpr *GotExpr =
nullptr;
3039 const MCExpr *LoExpr =
nullptr;
3040 if (
ABI.IsN32() ||
ABI.IsN64()) {
3059 Error(IDLoc,
"macro instruction uses large offset, which is not "
3060 "currently supported");
3089 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, GPReg,
3093 TOut.
emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3097 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3103 const auto *HiExpr =
3105 const auto *LoExpr =
3109 if (
ABI.ArePtrs64bit() && isGP64bit()) {
3117 const auto *HighestExpr =
3119 const auto *HigherExpr =
3124 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
3126 if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
3127 MCRegister ATReg = getATReg(IDLoc);
3139 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3141 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3144 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3147 TOut.
emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
3150 }
else if (canUseATReg() && !RdRegIsRsReg && DstReg != getATReg(IDLoc)) {
3151 MCRegister ATReg = getATReg(IDLoc);
3167 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3171 TOut.
emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3172 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3174 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3177 }
else if ((!canUseATReg() && !RdRegIsRsReg) ||
3178 (canUseATReg() && DstReg == getATReg(IDLoc))) {
3189 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3191 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3192 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3194 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3195 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3198 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3204 assert(SrcReg == DstReg && !canUseATReg() &&
3205 "Could have expanded dla but didn't?");
3206 reportParseError(IDLoc,
3207 "pseudo-instruction requires $at, which is not available");
3221 MCRegister TmpReg = DstReg;
3223 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
3226 MCRegister ATReg = getATReg(IDLoc);
3237 TOut.
emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3240 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
3249 if (MipsMCRegisterClasses[Mips::FGR32RegClassID].
contains(
Reg))
3250 return Reg == (
unsigned)Mips::F31 ? (
unsigned)Mips::F0 :
Reg + 1;
3252 default:
llvm_unreachable(
"Unknown register in assembly macro expansion!");
3253 case Mips::ZERO:
return Mips::AT;
3254 case Mips::AT:
return Mips::V0;
3255 case Mips::V0:
return Mips::V1;
3256 case Mips::V1:
return Mips::A0;
3257 case Mips::A0:
return Mips::A1;
3258 case Mips::A1:
return Mips::A2;
3259 case Mips::A2:
return Mips::A3;
3260 case Mips::A3:
return Mips::T0;
3261 case Mips::T0:
return Mips::T1;
3262 case Mips::T1:
return Mips::T2;
3263 case Mips::T2:
return Mips::T3;
3264 case Mips::T3:
return Mips::T4;
3265 case Mips::T4:
return Mips::T5;
3266 case Mips::T5:
return Mips::T6;
3267 case Mips::T6:
return Mips::T7;
3268 case Mips::T7:
return Mips::S0;
3269 case Mips::S0:
return Mips::S1;
3270 case Mips::S1:
return Mips::S2;
3271 case Mips::S2:
return Mips::S3;
3272 case Mips::S3:
return Mips::S4;
3273 case Mips::S4:
return Mips::S5;
3274 case Mips::S5:
return Mips::S6;
3275 case Mips::S6:
return Mips::S7;
3276 case Mips::S7:
return Mips::T8;
3277 case Mips::T8:
return Mips::T9;
3278 case Mips::T9:
return Mips::K0;
3279 case Mips::K0:
return Mips::K1;
3280 case Mips::K1:
return Mips::GP;
3281 case Mips::GP:
return Mips::SP;
3282 case Mips::SP:
return Mips::FP;
3283 case Mips::FP:
return Mips::RA;
3284 case Mips::RA:
return Mips::ZERO;
3285 case Mips::D0:
return Mips::F1;
3286 case Mips::D1:
return Mips::F3;
3287 case Mips::D2:
return Mips::F5;
3288 case Mips::D3:
return Mips::F7;
3289 case Mips::D4:
return Mips::F9;
3290 case Mips::D5:
return Mips::F11;
3291 case Mips::D6:
return Mips::F13;
3292 case Mips::D7:
return Mips::F15;
3293 case Mips::D8:
return Mips::F17;
3294 case Mips::D9:
return Mips::F19;
3295 case Mips::D10:
return Mips::F21;
3296 case Mips::D11:
return Mips::F23;
3297 case Mips::D12:
return Mips::F25;
3298 case Mips::D13:
return Mips::F27;
3299 case Mips::D14:
return Mips::F29;
3300 case Mips::D15:
return Mips::F31;
3310bool MipsAsmParser::emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc,
3312 MCRegister ATReg = getATReg(IDLoc);
3318 const auto *GotExpr =
3321 if(isABI_O32() || isABI_N32()) {
3330 const auto *HiExpr =
3339 if(isABI_O32() || isABI_N32()) {
3343 const auto *HighestExpr =
3346 const auto *HigherExpr =
3351 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3353 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3356 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3365 if ((
Hi_32(ImmOp64) & 0x7ff00000) == 0) {
3376 float TmpFloat =
static_cast<float>(DoubleImm);
3380bool MipsAsmParser::expandLoadSingleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3382 const MCSubtargetInfo *STI) {
3385 "Invalid instruction operand.");
3392 return loadImmediate(ImmOp32, FirstReg, MCRegister(),
true,
false, IDLoc, Out,
3396bool MipsAsmParser::expandLoadSingleImmToFPR(MCInst &Inst, SMLoc IDLoc,
3398 const MCSubtargetInfo *STI) {
3399 MipsTargetStreamer &TOut = getTargetStreamer();
3402 "Invalid instruction operand.");
3411 MCRegister TmpReg = Mips::ZERO;
3413 TmpReg = getATReg(IDLoc);
3418 if (
Lo_32(ImmOp64) == 0) {
3419 if (TmpReg != Mips::ZERO && loadImmediate(ImmOp32, TmpReg, MCRegister(),
3420 true,
false, IDLoc, Out, STI))
3422 TOut.
emitRR(Mips::MTC1, FirstReg, TmpReg, IDLoc, STI);
3426 MCSection *CS = getStreamer().getCurrentSectionOnly();
3429 MCSection *ReadOnlySection =
3436 getStreamer().switchSection(ReadOnlySection);
3437 getStreamer().emitLabel(Sym, IDLoc);
3438 getStreamer().emitInt32(ImmOp32);
3439 getStreamer().switchSection(CS);
3441 if (emitPartialAddress(TOut, IDLoc, Sym))
3448bool MipsAsmParser::expandLoadDoubleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3450 const MCSubtargetInfo *STI) {
3451 MipsTargetStreamer &TOut = getTargetStreamer();
3454 "Invalid instruction operand.");
3461 if (
Lo_32(ImmOp64) == 0) {
3463 if (loadImmediate(ImmOp64, FirstReg, MCRegister(),
false,
false, IDLoc,
3467 if (loadImmediate(
Hi_32(ImmOp64), FirstReg, MCRegister(),
true,
false,
3471 if (loadImmediate(0,
nextReg(FirstReg), MCRegister(),
true,
false, IDLoc,
3478 MCSection *CS = getStreamer().getCurrentSectionOnly();
3479 MCSection *ReadOnlySection =
3486 getStreamer().switchSection(ReadOnlySection);
3487 getStreamer().emitLabel(Sym, IDLoc);
3488 getStreamer().emitValueToAlignment(
Align(8));
3489 getStreamer().emitIntValue(ImmOp64, 8);
3490 getStreamer().switchSection(CS);
3492 MCRegister TmpReg = getATReg(IDLoc);
3496 if (emitPartialAddress(TOut, IDLoc, Sym))
3499 TOut.
emitRRX(isABI_N64() ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3503 TOut.
emitRRI(Mips::LD, FirstReg, TmpReg, 0, IDLoc, STI);
3505 TOut.
emitRRI(Mips::LW, FirstReg, TmpReg, 0, IDLoc, STI);
3506 TOut.
emitRRI(Mips::LW,
nextReg(FirstReg), TmpReg, 4, IDLoc, STI);
3511bool MipsAsmParser::expandLoadDoubleImmToFPR(MCInst &Inst,
bool Is64FPU,
3512 SMLoc IDLoc, MCStreamer &Out,
3513 const MCSubtargetInfo *STI) {
3514 MipsTargetStreamer &TOut = getTargetStreamer();
3517 "Invalid instruction operand.");
3524 MCRegister TmpReg = Mips::ZERO;
3526 TmpReg = getATReg(IDLoc);
3531 if ((
Lo_32(ImmOp64) == 0) &&
3532 !((
Hi_32(ImmOp64) & 0xffff0000) && (
Hi_32(ImmOp64) & 0x0000ffff))) {
3534 if (TmpReg != Mips::ZERO && loadImmediate(ImmOp64, TmpReg, MCRegister(),
3535 false,
false, IDLoc, Out, STI))
3537 TOut.
emitRR(Mips::DMTC1, FirstReg, TmpReg, IDLoc, STI);
3541 if (TmpReg != Mips::ZERO &&
3542 loadImmediate(
Hi_32(ImmOp64), TmpReg, MCRegister(),
true,
false, IDLoc,
3546 if (hasMips32r2()) {
3547 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3548 TOut.
emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, TmpReg, IDLoc, STI);
3550 TOut.
emitRR(Mips::MTC1,
nextReg(FirstReg), TmpReg, IDLoc, STI);
3551 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3556 MCSection *CS = getStreamer().getCurrentSectionOnly();
3559 MCSection *ReadOnlySection =
3566 getStreamer().switchSection(ReadOnlySection);
3567 getStreamer().emitLabel(Sym, IDLoc);
3568 getStreamer().emitValueToAlignment(
Align(8));
3569 getStreamer().emitIntValue(ImmOp64, 8);
3570 getStreamer().switchSection(CS);
3572 if (emitPartialAddress(TOut, IDLoc, Sym))
3575 TOut.
emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, TmpReg,
3581bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
3583 const MCSubtargetInfo *STI) {
3584 MipsTargetStreamer &TOut = getTargetStreamer();
3587 "unexpected number of operands");
3597 assert(
Offset.isImm() &&
"expected immediate operand kind");
3601 if (inMicroMipsMode())
3602 Inst.
setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3605 return Error(IDLoc,
"branch target out of range");
3607 return Error(IDLoc,
"branch to misaligned address");
3619 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
3626bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3627 const MCSubtargetInfo *STI) {
3628 MipsTargetStreamer &TOut = getTargetStreamer();
3629 const MCOperand &DstRegOp = Inst.
getOperand(0);
3630 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3633 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
3635 const MCOperand &MemOffsetOp = Inst.
getOperand(2);
3637 "expected immediate or expression operand");
3639 bool IsLikely =
false;
3649 case Mips::BEQLImmMacro:
3653 case Mips::BNELImmMacro:
3662 int64_t ImmValue = ImmOp.
getImm();
3663 if (ImmValue == 0) {
3667 TOut.
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3669 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3672 warnIfNoMacro(IDLoc);
3674 MCRegister ATReg = getATReg(IDLoc);
3678 if (loadImmediate(ImmValue, ATReg, MCRegister(), !isGP64bit(),
true, IDLoc,
3682 if (IsLikely && MemOffsetOp.
isExpr()) {
3685 TOut.
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3687 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3692void MipsAsmParser::expandMem16Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3693 const MCSubtargetInfo *STI,
bool IsLoad) {
3695 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3696 unsigned StartOp = NumOp == 3 ? 0 : 1;
3698 const MCOperand &DstRegOp = Inst.
getOperand(StartOp);
3699 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3700 const MCOperand &BaseRegOp = Inst.
getOperand(StartOp + 1);
3701 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3704 MipsTargetStreamer &TOut = getTargetStreamer();
3706 MCRegister DstReg = DstRegOp.
getReg();
3708 MCRegister TmpReg = DstReg;
3710 const MCInstrDesc &
Desc = MII.get(OpCode);
3711 int16_t DstRegClass =
3712 MII.getOpRegClassID(
Desc.operands()[StartOp],
3714 unsigned DstRegClassID =
3715 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3716 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3717 (DstRegClassID == Mips::GPR64RegClassID);
3719 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3722 TmpReg = getATReg(IDLoc);
3727 auto emitInstWithOffset = [&](
const MCOperand &
Off) {
3729 TOut.
emitRRX(OpCode, DstReg, TmpReg, Off, IDLoc, STI);
3731 TOut.
emitRRRX(OpCode, DstReg, DstReg, TmpReg, Off, IDLoc, STI);
3735 int64_t LoOffset =
OffsetOp.getImm() & 0xffff;
3736 int64_t HiOffset =
OffsetOp.getImm() & ~0xffff;
3740 if (LoOffset & 0x8000)
3741 HiOffset += 0x10000;
3743 bool IsLargeOffset = HiOffset != 0;
3745 if (IsLargeOffset) {
3747 if (loadImmediate(HiOffset, TmpReg, MCRegister(), Is32BitImm,
true, IDLoc,
3752 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3753 TOut.
emitRRR(
ABI.ArePtrs64bit() ? Mips::DADDu : Mips::ADDu, TmpReg,
3754 TmpReg, BaseReg, IDLoc, STI);
3768 if (!
OffsetOp.getExpr()->evaluateAsRelocatable(Res,
nullptr)) {
3769 Error(IDLoc,
"expected relocatable expression");
3773 Error(IDLoc,
"expected relocatable expression with only one symbol");
3777 loadAndAddSymbolAddress(
3779 BaseReg, !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3787 const MCExpr *OffExpr =
OffsetOp.getExpr();
3799 TOut.
emitRX(Mips::LUi, TmpReg, HighestOperand, IDLoc, STI);
3800 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HigherOperand, IDLoc, STI);
3801 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3802 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HiOperand, IDLoc, STI);
3803 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3804 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3805 TOut.
emitRRR(Mips::DADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3806 emitInstWithOffset(LoOperand);
3809 TOut.
emitRX(Mips::LUi, TmpReg, HiOperand, IDLoc, STI);
3810 if (BaseReg != Mips::ZERO)
3811 TOut.
emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3813 emitInstWithOffset(LoOperand);
3822void MipsAsmParser::expandMem9Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3823 const MCSubtargetInfo *STI,
bool IsLoad) {
3825 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3826 unsigned StartOp = NumOp == 3 ? 0 : 1;
3828 const MCOperand &DstRegOp = Inst.
getOperand(StartOp);
3829 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3830 const MCOperand &BaseRegOp = Inst.
getOperand(StartOp + 1);
3831 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3834 MipsTargetStreamer &TOut = getTargetStreamer();
3836 MCRegister DstReg = DstRegOp.
getReg();
3838 MCRegister TmpReg = DstReg;
3840 const MCInstrDesc &
Desc = MII.get(OpCode);
3841 int16_t DstRegClass =
3842 MII.getOpRegClassID(
Desc.operands()[StartOp],
3845 unsigned DstRegClassID =
3846 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3847 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3848 (DstRegClassID == Mips::GPR64RegClassID);
3850 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3853 TmpReg = getATReg(IDLoc);
3858 auto emitInst = [&]() {
3867 loadImmediate(
OffsetOp.getImm(), TmpReg, BaseReg, !
ABI.ArePtrs64bit(),
true,
3874 loadAndAddSymbolAddress(
OffsetOp.getExpr(), TmpReg, BaseReg,
3875 !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3883bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
3885 const MCSubtargetInfo *STI) {
3888 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3892 Inst.
getOperand(OpNum - 3).
isReg() &&
"Invalid instruction operand.");
3901 if (inMicroMipsMode() && hasMips32r6())
3902 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3904 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3912bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
3914 const MCSubtargetInfo *STI) {
3915 MipsTargetStreamer &TOut = getTargetStreamer();
3916 bool EmittedNoMacroWarning =
false;
3917 unsigned PseudoOpcode = Inst.
getOpcode();
3922 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3923 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3928 else if (TrgOp.
isImm()) {
3929 warnIfNoMacro(IDLoc);
3930 EmittedNoMacroWarning =
true;
3932 TrgReg = getATReg(IDLoc);
3936 switch(PseudoOpcode) {
3939 case Mips::BLTImmMacro:
3940 PseudoOpcode = Mips::BLT;
3942 case Mips::BLEImmMacro:
3943 PseudoOpcode = Mips::BLE;
3945 case Mips::BGEImmMacro:
3946 PseudoOpcode = Mips::BGE;
3948 case Mips::BGTImmMacro:
3949 PseudoOpcode = Mips::BGT;
3951 case Mips::BLTUImmMacro:
3952 PseudoOpcode = Mips::BLTU;
3954 case Mips::BLEUImmMacro:
3955 PseudoOpcode = Mips::BLEU;
3957 case Mips::BGEUImmMacro:
3958 PseudoOpcode = Mips::BGEU;
3960 case Mips::BGTUImmMacro:
3961 PseudoOpcode = Mips::BGTU;
3963 case Mips::BLTLImmMacro:
3964 PseudoOpcode = Mips::BLTL;
3966 case Mips::BLELImmMacro:
3967 PseudoOpcode = Mips::BLEL;
3969 case Mips::BGELImmMacro:
3970 PseudoOpcode = Mips::BGEL;
3972 case Mips::BGTLImmMacro:
3973 PseudoOpcode = Mips::BGTL;
3975 case Mips::BLTULImmMacro:
3976 PseudoOpcode = Mips::BLTUL;
3978 case Mips::BLEULImmMacro:
3979 PseudoOpcode = Mips::BLEUL;
3981 case Mips::BGEULImmMacro:
3982 PseudoOpcode = Mips::BGEUL;
3984 case Mips::BGTULImmMacro:
3985 PseudoOpcode = Mips::BGTUL;
3989 if (loadImmediate(TrgOp.
getImm(), TrgReg, MCRegister(), !isGP64bit(),
false,
3994 switch (PseudoOpcode) {
3999 AcceptsEquality =
false;
4000 ReverseOrderSLT =
false;
4002 ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
4003 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
4004 ZeroSrcOpcode = Mips::BGTZ;
4005 ZeroTrgOpcode = Mips::BLTZ;
4011 AcceptsEquality =
true;
4012 ReverseOrderSLT =
true;
4014 ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
4015 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
4016 ZeroSrcOpcode = Mips::BGEZ;
4017 ZeroTrgOpcode = Mips::BLEZ;
4023 AcceptsEquality =
true;
4024 ReverseOrderSLT =
false;
4026 ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
4027 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
4028 ZeroSrcOpcode = Mips::BLEZ;
4029 ZeroTrgOpcode = Mips::BGEZ;
4035 AcceptsEquality =
false;
4036 ReverseOrderSLT =
true;
4038 ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
4039 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
4040 ZeroSrcOpcode = Mips::BLTZ;
4041 ZeroTrgOpcode = Mips::BGTZ;
4047 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
4048 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
4049 if (IsSrcRegZero && IsTrgRegZero) {
4053 if (PseudoOpcode == Mips::BLT) {
4058 if (PseudoOpcode == Mips::BLE) {
4061 Warning(IDLoc,
"branch is always taken");
4064 if (PseudoOpcode == Mips::BGE) {
4067 Warning(IDLoc,
"branch is always taken");
4070 if (PseudoOpcode == Mips::BGT) {
4075 if (PseudoOpcode == Mips::BGTU) {
4076 TOut.
emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
4080 if (AcceptsEquality) {
4083 TOut.
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4085 Warning(IDLoc,
"branch is always taken");
4092 if (IsSrcRegZero || IsTrgRegZero) {
4093 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
4094 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
4101 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
4102 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
4108 TOut.
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4110 Warning(IDLoc,
"branch is always taken");
4126 TOut.
emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
4127 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
4134 TOut.
emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
4135 IsSrcRegZero ? TrgReg : SrcReg,
4142 MCRegister ATRegNum = getATReg(IDLoc);
4146 if (!EmittedNoMacroWarning)
4147 warnIfNoMacro(IDLoc);
4164 TOut.
emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
4165 ReverseOrderSLT ? TrgReg : SrcReg,
4166 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
4168 TOut.
emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
4169 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
4183bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4184 const MCSubtargetInfo *STI,
4185 const bool IsMips64,
const bool Signed) {
4186 MipsTargetStreamer &TOut = getTargetStreamer();
4188 warnIfNoMacro(IDLoc);
4190 const MCOperand &RdRegOp = Inst.
getOperand(0);
4191 assert(RdRegOp.
isReg() &&
"expected register operand kind");
4192 MCRegister RdReg = RdRegOp.
getReg();
4194 const MCOperand &RsRegOp = Inst.
getOperand(1);
4195 assert(RsRegOp.
isReg() &&
"expected register operand kind");
4196 MCRegister RsReg = RsRegOp.
getReg();
4203 "expected register or immediate operand kind");
4207 ImmValue = RtOp.
getImm();
4214 DivOp =
Signed ? Mips::DSDIV : Mips::DUDIV;
4215 ZeroReg = Mips::ZERO_64;
4218 DivOp =
Signed ? Mips::SDIV : Mips::UDIV;
4219 ZeroReg = Mips::ZERO;
4223 bool UseTraps = useTraps();
4226 bool isDiv = Opcode == Mips::SDivMacro || Opcode == Mips::SDivIMacro ||
4227 Opcode == Mips::UDivMacro || Opcode == Mips::UDivIMacro ||
4228 Opcode == Mips::DSDivMacro || Opcode == Mips::DSDivIMacro ||
4229 Opcode == Mips::DUDivMacro || Opcode == Mips::DUDivIMacro;
4231 bool isRem = Opcode == Mips::SRemMacro || Opcode == Mips::SRemIMacro ||
4232 Opcode == Mips::URemMacro || Opcode == Mips::URemIMacro ||
4233 Opcode == Mips::DSRemMacro || Opcode == Mips::DSRemIMacro ||
4234 Opcode == Mips::DURemMacro || Opcode == Mips::DURemIMacro;
4237 MCRegister ATReg = getATReg(IDLoc);
4243 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4245 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4249 if (isRem && (ImmValue == 1 || (
Signed && (ImmValue == -1)))) {
4250 TOut.
emitRRR(Mips::OR, RdReg, ZeroReg, ZeroReg, IDLoc, STI);
4252 }
else if (isDiv && ImmValue == 1) {
4253 TOut.
emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI);
4255 }
else if (isDiv &&
Signed && ImmValue == -1) {
4256 TOut.
emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
4259 if (loadImmediate(ImmValue, ATReg, MCRegister(),
isInt<32>(ImmValue),
4260 false, Inst.
getLoc(), Out, STI))
4262 TOut.
emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
4263 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4273 if (!
NoZeroDivCheck && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
4275 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4278 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4284 if (isRem && (RdReg == Mips::ZERO || RdReg == Mips::ZERO_64)) {
4285 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4294 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4297 TOut.
emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4300 BrTarget =
Context.createTempSymbol();
4303 TOut.
emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4308 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4314 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4318bool MipsAsmParser::expandTrunc(MCInst &Inst,
bool IsDouble,
bool Is64FPU,
4319 SMLoc IDLoc, MCStreamer &Out,
4320 const MCSubtargetInfo *STI) {
4321 MipsTargetStreamer &TOut = getTargetStreamer();
4331 if (hasMips1() && !hasMips2()) {
4332 MCRegister ATReg = getATReg(IDLoc);
4335 TOut.
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4336 TOut.
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4338 TOut.
emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4339 TOut.
emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4340 TOut.
emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4342 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4344 FirstReg, SecondReg, IDLoc, STI);
4345 TOut.
emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4350 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4352 FirstReg, SecondReg, IDLoc, STI);
4357bool MipsAsmParser::expandUlh(MCInst &Inst,
bool Signed, SMLoc IDLoc,
4358 MCStreamer &Out,
const MCSubtargetInfo *STI) {
4359 if (hasMips32r6() || hasMips64r6()) {
4360 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4363 const MCOperand &DstRegOp = Inst.
getOperand(0);
4364 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4365 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4366 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4367 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4368 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4370 MipsTargetStreamer &TOut = getTargetStreamer();
4371 MCRegister DstReg = DstRegOp.
getReg();
4372 MCRegister SrcReg = SrcRegOp.
getReg();
4373 int64_t OffsetValue = OffsetImmOp.
getImm();
4377 warnIfNoMacro(IDLoc);
4378 MCRegister ATReg = getATReg(IDLoc);
4383 if (IsLargeOffset) {
4384 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4389 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4390 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4394 MCRegister FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4395 MCRegister SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4397 MCRegister LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4398 MCRegister SllReg = IsLargeOffset ? DstReg : ATReg;
4400 TOut.
emitRRI(
Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4401 FirstOffset, IDLoc, STI);
4402 TOut.
emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4403 TOut.
emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4404 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4409bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4410 const MCSubtargetInfo *STI) {
4411 if (hasMips32r6() || hasMips64r6()) {
4412 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4415 const MCOperand &DstRegOp = Inst.
getOperand(0);
4416 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4417 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4418 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4419 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4420 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4422 MipsTargetStreamer &TOut = getTargetStreamer();
4423 MCRegister DstReg = DstRegOp.
getReg();
4424 MCRegister SrcReg = SrcRegOp.
getReg();
4425 int64_t OffsetValue = OffsetImmOp.
getImm();
4427 warnIfNoMacro(IDLoc);
4428 MCRegister ATReg = getATReg(IDLoc);
4433 if (IsLargeOffset) {
4434 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4439 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4440 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4444 if (IsLargeOffset) {
4445 TOut.
emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4446 TOut.
emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4447 TOut.
emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4448 TOut.
emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4449 TOut.
emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4450 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4452 TOut.
emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4453 TOut.
emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4454 TOut.
emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4460bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4461 const MCSubtargetInfo *STI) {
4462 if (hasMips32r6() || hasMips64r6()) {
4463 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4466 const MCOperand &DstRegOp = Inst.
getOperand(0);
4467 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4468 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4469 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4470 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4471 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4473 MipsTargetStreamer &TOut = getTargetStreamer();
4474 MCRegister DstReg = DstRegOp.
getReg();
4475 MCRegister SrcReg = SrcRegOp.
getReg();
4476 int64_t OffsetValue = OffsetImmOp.
getImm();
4480 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4481 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4485 bool IsLoadInst = (Inst.
getOpcode() == Mips::Ulw);
4486 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4487 MCRegister TmpReg = SrcReg;
4488 if (IsLargeOffset || DoMove) {
4489 warnIfNoMacro(IDLoc);
4490 TmpReg = getATReg(IDLoc);
4495 if (IsLargeOffset) {
4496 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4504 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4505 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4506 TOut.
emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4507 TOut.
emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4510 TOut.
emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4515bool MipsAsmParser::expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4516 const MCSubtargetInfo *STI) {
4517 MipsTargetStreamer &TOut = getTargetStreamer();
4529 warnIfNoMacro(IDLoc);
4543 TOut.
emitRRR(OpCode, DstReg, SrcReg, OpReg, IDLoc, STI);
4544 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4549bool MipsAsmParser::expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4550 const MCSubtargetInfo *STI) {
4551 MipsTargetStreamer &TOut = getTargetStreamer();
4561 unsigned OpRegCode, OpImmCode;
4563 warnIfNoMacro(IDLoc);
4567 case Mips::SGEImm64:
4568 OpRegCode = Mips::SLT;
4569 OpImmCode = Mips::SLTi;
4572 case Mips::SGEUImm64:
4573 OpRegCode = Mips::SLTu;
4574 OpImmCode = Mips::SLTiu;
4583 TOut.
emitRRI(OpImmCode, DstReg, SrcReg, ImmValue, IDLoc, STI);
4584 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4586 MCRegister ImmReg = DstReg;
4587 if (DstReg == SrcReg) {
4588 MCRegister ATReg = getATReg(Inst.
getLoc());
4594 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
4595 false, IDLoc, Out, STI))
4598 TOut.
emitRRR(OpRegCode, DstReg, SrcReg, ImmReg, IDLoc, STI);
4599 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4605bool MipsAsmParser::expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4606 const MCSubtargetInfo *STI) {
4607 MipsTargetStreamer &TOut = getTargetStreamer();
4616 MCRegister ImmReg = DstReg;
4620 warnIfNoMacro(IDLoc);
4624 case Mips::SGTImm64:
4628 case Mips::SGTUImm64:
4635 if (DstReg == SrcReg) {
4636 MCRegister ATReg = getATReg(Inst.
getLoc());
4642 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
false,
4647 TOut.
emitRRR(OpCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4652bool MipsAsmParser::expandSle(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4653 const MCSubtargetInfo *STI) {
4654 MipsTargetStreamer &TOut = getTargetStreamer();
4666 warnIfNoMacro(IDLoc);
4680 TOut.
emitRRR(OpCode, DstReg, OpReg, SrcReg, IDLoc, STI);
4681 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4686bool MipsAsmParser::expandSleImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4687 const MCSubtargetInfo *STI) {
4688 MipsTargetStreamer &TOut = getTargetStreamer();
4700 warnIfNoMacro(IDLoc);
4704 case Mips::SLEImm64:
4705 OpRegCode = Mips::SLT;
4708 case Mips::SLEUImm64:
4709 OpRegCode = Mips::SLTu;
4716 MCRegister ImmReg = DstReg;
4717 if (DstReg == SrcReg) {
4718 MCRegister ATReg = getATReg(Inst.
getLoc());
4724 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
false,
4728 TOut.
emitRRR(OpRegCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4729 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4734bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
4736 const MCSubtargetInfo *STI) {
4737 MipsTargetStreamer &TOut = getTargetStreamer();
4745 MCRegister FinalDstReg;
4752 unsigned FinalOpcode = Inst.
getOpcode();
4754 if (DstReg == SrcReg) {
4755 ATReg = getATReg(Inst.
getLoc());
4758 FinalDstReg = DstReg;
4762 if (!loadImmediate(ImmValue, DstReg, MCRegister(), Is32Bit,
false,
4763 Inst.
getLoc(), Out, STI)) {
4764 switch (FinalOpcode) {
4768 FinalOpcode = Mips::ADD;
4771 FinalOpcode = Mips::ADDu;
4774 FinalOpcode = Mips::AND;
4777 FinalOpcode = Mips::NOR;
4780 FinalOpcode = Mips::OR;
4783 FinalOpcode = Mips::SLT;
4786 FinalOpcode = Mips::SLTu;
4789 FinalOpcode = Mips::XOR;
4792 FinalOpcode = Mips::ADD_MM;
4794 case Mips::ADDiu_MM:
4795 FinalOpcode = Mips::ADDu_MM;
4798 FinalOpcode = Mips::AND_MM;
4801 FinalOpcode = Mips::OR_MM;
4804 FinalOpcode = Mips::SLT_MM;
4806 case Mips::SLTiu_MM:
4807 FinalOpcode = Mips::SLTu_MM;
4810 FinalOpcode = Mips::XOR_MM;
4813 FinalOpcode = Mips::AND64;
4815 case Mips::NORImm64:
4816 FinalOpcode = Mips::NOR64;
4819 FinalOpcode = Mips::OR64;
4821 case Mips::SLTImm64:
4822 FinalOpcode = Mips::SLT64;
4824 case Mips::SLTUImm64:
4825 FinalOpcode = Mips::SLTu64;
4828 FinalOpcode = Mips::XOR64;
4833 TOut.
emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4835 TOut.
emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4841bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4842 const MCSubtargetInfo *STI) {
4843 MipsTargetStreamer &TOut = getTargetStreamer();
4848 MCRegister TmpReg =
DReg;
4850 unsigned FirstShift = Mips::NOP;
4851 unsigned SecondShift = Mips::NOP;
4853 if (hasMips32r2()) {
4855 TmpReg = getATReg(Inst.
getLoc());
4861 TOut.
emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4862 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
4867 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
4879 FirstShift = Mips::SRLV;
4880 SecondShift = Mips::SLLV;
4883 FirstShift = Mips::SLLV;
4884 SecondShift = Mips::SRLV;
4888 ATReg = getATReg(Inst.
getLoc());
4892 TOut.
emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4893 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
4894 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
4895 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
4903bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
4905 const MCSubtargetInfo *STI) {
4906 MipsTargetStreamer &TOut = getTargetStreamer();
4912 unsigned FirstShift = Mips::NOP;
4913 unsigned SecondShift = Mips::NOP;
4915 if (hasMips32r2()) {
4917 uint64_t MaxShift = 32;
4918 uint64_t ShiftValue = ImmValue;
4920 ShiftValue = MaxShift - ImmValue;
4921 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
4926 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.
getLoc(), STI);
4934 if (ImmValue == 0) {
4943 FirstShift = Mips::SLL;
4944 SecondShift = Mips::SRL;
4947 FirstShift = Mips::SRL;
4948 SecondShift = Mips::SLL;
4952 ATReg = getATReg(Inst.
getLoc());
4956 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.
getLoc(), STI);
4957 TOut.
emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.
getLoc(), STI);
4958 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
4966bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4967 const MCSubtargetInfo *STI) {
4968 MipsTargetStreamer &TOut = getTargetStreamer();
4973 MCRegister TmpReg =
DReg;
4975 unsigned FirstShift = Mips::NOP;
4976 unsigned SecondShift = Mips::NOP;
4978 if (hasMips64r2()) {
4979 if (TmpReg == SReg) {
4980 TmpReg = getATReg(Inst.
getLoc());
4986 TOut.
emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4987 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
4992 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
5004 FirstShift = Mips::DSRLV;
5005 SecondShift = Mips::DSLLV;
5008 FirstShift = Mips::DSLLV;
5009 SecondShift = Mips::DSRLV;
5013 ATReg = getATReg(Inst.
getLoc());
5017 TOut.
emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
5018 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
5019 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
5020 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5028bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
5030 const MCSubtargetInfo *STI) {
5031 MipsTargetStreamer &TOut = getTargetStreamer();
5037 unsigned FirstShift = Mips::NOP;
5038 unsigned SecondShift = Mips::NOP;
5042 if (hasMips64r2()) {
5043 unsigned FinalOpcode = Mips::NOP;
5045 FinalOpcode = Mips::DROTR;
5046 else if (ImmValue % 32 == 0)
5047 FinalOpcode = Mips::DROTR32;
5048 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
5050 FinalOpcode = Mips::DROTR32;
5052 FinalOpcode = Mips::DROTR;
5053 }
else if (ImmValue >= 33) {
5055 FinalOpcode = Mips::DROTR;
5057 FinalOpcode = Mips::DROTR32;
5060 uint64_t ShiftValue = ImmValue % 32;
5062 ShiftValue = (32 - ImmValue % 32) % 32;
5064 TOut.
emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
5070 if (ImmValue == 0) {
5071 TOut.
emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.
getLoc(), STI);
5079 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5080 FirstShift = Mips::DSLL;
5081 SecondShift = Mips::DSRL32;
5083 if (ImmValue == 32) {
5084 FirstShift = Mips::DSLL32;
5085 SecondShift = Mips::DSRL32;
5087 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5088 FirstShift = Mips::DSLL32;
5089 SecondShift = Mips::DSRL;
5093 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5094 FirstShift = Mips::DSRL;
5095 SecondShift = Mips::DSLL32;
5097 if (ImmValue == 32) {
5098 FirstShift = Mips::DSRL32;
5099 SecondShift = Mips::DSLL32;
5101 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5102 FirstShift = Mips::DSRL32;
5103 SecondShift = Mips::DSLL;
5108 ATReg = getATReg(Inst.
getLoc());
5112 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.
getLoc(), STI);
5113 TOut.
emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
5115 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5123bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5124 const MCSubtargetInfo *STI) {
5125 MipsTargetStreamer &TOut = getTargetStreamer();
5129 TOut.
emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
5130 if (FirstRegOp != SecondRegOp)
5131 TOut.
emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
5134 TOut.
emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
5139bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5140 const MCSubtargetInfo *STI) {
5141 MipsTargetStreamer &TOut = getTargetStreamer();
5147 ATReg = getATReg(IDLoc);
5151 loadImmediate(ImmValue, ATReg, MCRegister(),
true,
false, IDLoc, Out, STI);
5153 TOut.
emitRR(Inst.
getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
5154 SrcReg, ATReg, IDLoc, STI);
5156 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5161bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5162 const MCSubtargetInfo *STI) {
5163 MipsTargetStreamer &TOut = getTargetStreamer();
5169 ATReg = getATReg(Inst.
getLoc());
5173 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
5174 SrcReg, TmpReg, IDLoc, STI);
5176 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5178 TOut.
emitRRI(Inst.
getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
5179 DstReg, DstReg, 0x1F, IDLoc, STI);
5181 TOut.
emitR(Mips::MFHI, ATReg, IDLoc, STI);
5184 TOut.
emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
5191 TOut.
emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
5192 if (AssemblerOptions.
back()->isReorder())
5194 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5198 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5203bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5204 const MCSubtargetInfo *STI) {
5205 MipsTargetStreamer &TOut = getTargetStreamer();
5211 ATReg = getATReg(IDLoc);
5215 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
5216 SrcReg, TmpReg, IDLoc, STI);
5218 TOut.
emitR(Mips::MFHI, ATReg, IDLoc, STI);
5219 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5221 TOut.
emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);
5228 TOut.
emitRRX(Mips::BEQ, ATReg, Mips::ZERO, LabelOp, IDLoc, STI);
5229 if (AssemblerOptions.
back()->isReorder())
5231 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5239bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5240 const MCSubtargetInfo *STI) {
5241 MipsTargetStreamer &TOut = getTargetStreamer();
5246 TOut.
emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
5247 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5257bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
5259 const MCSubtargetInfo *STI,
5264 warnIfNoMacro(IDLoc);
5266 MipsTargetStreamer &TOut = getTargetStreamer();
5267 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
5269 MCRegister SecondReg =
nextReg(FirstReg);
5274 warnIfRegIndexIsAT(FirstReg, IDLoc);
5277 "Offset for load macro is not immediate!");
5280 signed NextOffset = FirstOffset.
getImm() + 4;
5288 if (FirstReg != BaseReg || !IsLoad) {
5289 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5290 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5292 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5293 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5305bool MipsAsmParser::expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc,
5307 const MCSubtargetInfo *STI) {
5311 warnIfNoMacro(IDLoc);
5313 MipsTargetStreamer &TOut = getTargetStreamer();
5314 unsigned Opcode = Mips::SWC1;
5316 MCRegister SecondReg =
nextReg(FirstReg);
5321 warnIfRegIndexIsAT(FirstReg, IDLoc);
5324 "Offset for macro is not immediate!");
5327 signed NextOffset = FirstOffset.
getImm() + 4;
5333 if (!IsLittleEndian)
5336 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5337 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5342bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5343 const MCSubtargetInfo *STI) {
5344 MipsTargetStreamer &TOut = getTargetStreamer();
5355 warnIfNoMacro(IDLoc);
5357 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5358 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5359 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5363 MCRegister
Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5364 TOut.
emitRRI(Mips::SLTiu, DstReg,
Reg, 1, IDLoc, STI);
5368bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5369 const MCSubtargetInfo *STI) {
5370 MipsTargetStreamer &TOut = getTargetStreamer();
5381 warnIfNoMacro(IDLoc);
5384 TOut.
emitRRI(Mips::SLTiu, DstReg, SrcReg, 1, IDLoc, STI);
5388 if (SrcReg == Mips::ZERO) {
5389 Warning(IDLoc,
"comparison is always false");
5390 TOut.
emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
5391 DstReg, SrcReg, SrcReg, IDLoc, STI);
5396 if (Imm > -0x8000 && Imm < 0) {
5398 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5404 MCRegister ATReg = getATReg(IDLoc);
5408 if (loadImmediate(Imm, ATReg, MCRegister(),
true, isGP64bit(), IDLoc, Out,
5412 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5413 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5417 TOut.
emitRRI(
Opc, DstReg, SrcReg, Imm, IDLoc, STI);
5418 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5422bool MipsAsmParser::expandSne(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5423 const MCSubtargetInfo *STI) {
5425 MipsTargetStreamer &TOut = getTargetStreamer();
5436 warnIfNoMacro(IDLoc);
5438 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5439 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5440 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5444 MCRegister
Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5445 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO,
Reg, IDLoc, STI);
5449bool MipsAsmParser::expandSneI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5450 const MCSubtargetInfo *STI) {
5451 MipsTargetStreamer &TOut = getTargetStreamer();
5462 warnIfNoMacro(IDLoc);
5464 if (ImmValue == 0) {
5465 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, SrcReg, IDLoc, STI);
5469 if (SrcReg == Mips::ZERO) {
5470 Warning(IDLoc,
"comparison is always true");
5471 if (loadImmediate(1, DstReg, MCRegister(),
true,
false, IDLoc, Out, STI))
5477 if (ImmValue > -0x8000 && ImmValue < 0) {
5478 ImmValue = -ImmValue;
5479 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5485 TOut.
emitRRI(
Opc, DstReg, SrcReg, ImmValue, IDLoc, STI);
5486 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5490 MCRegister ATReg = getATReg(IDLoc);
5494 if (loadImmediate(ImmValue, ATReg, MCRegister(),
isInt<32>(ImmValue),
false,
5498 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5499 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5562 case Mips::F0:
return Mips::ZERO;
5563 case Mips::F1:
return Mips::AT;
5564 case Mips::F2:
return Mips::V0;
5565 case Mips::F3:
return Mips::V1;
5566 case Mips::F4:
return Mips::A0;
5567 case Mips::F5:
return Mips::A1;
5568 case Mips::F6:
return Mips::A2;
5569 case Mips::F7:
return Mips::A3;
5570 case Mips::F8:
return Mips::T0;
5571 case Mips::F9:
return Mips::T1;
5572 case Mips::F10:
return Mips::T2;
5573 case Mips::F11:
return Mips::T3;
5574 case Mips::F12:
return Mips::T4;
5575 case Mips::F13:
return Mips::T5;
5576 case Mips::F14:
return Mips::T6;
5577 case Mips::F15:
return Mips::T7;
5578 case Mips::F16:
return Mips::S0;
5579 case Mips::F17:
return Mips::S1;
5580 case Mips::F18:
return Mips::S2;
5581 case Mips::F19:
return Mips::S3;
5582 case Mips::F20:
return Mips::S4;
5583 case Mips::F21:
return Mips::S5;
5584 case Mips::F22:
return Mips::S6;
5585 case Mips::F23:
return Mips::S7;
5586 case Mips::F24:
return Mips::T8;
5587 case Mips::F25:
return Mips::T9;
5588 case Mips::F26:
return Mips::K0;
5589 case Mips::F27:
return Mips::K1;
5590 case Mips::F28:
return Mips::GP;
5591 case Mips::F29:
return Mips::SP;
5592 case Mips::F30:
return Mips::FP;
5593 case Mips::F31:
return Mips::RA;
5601 case Mips::COP00:
return Mips::ZERO;
5602 case Mips::COP01:
return Mips::AT;
5603 case Mips::COP02:
return Mips::V0;
5604 case Mips::COP03:
return Mips::V1;
5605 case Mips::COP04:
return Mips::A0;
5606 case Mips::COP05:
return Mips::A1;
5607 case Mips::COP06:
return Mips::A2;
5608 case Mips::COP07:
return Mips::A3;
5609 case Mips::COP08:
return Mips::T0;
5610 case Mips::COP09:
return Mips::T1;
5611 case Mips::COP010:
return Mips::T2;
5612 case Mips::COP011:
return Mips::T3;
5613 case Mips::COP012:
return Mips::T4;
5614 case Mips::COP013:
return Mips::T5;
5615 case Mips::COP014:
return Mips::T6;
5616 case Mips::COP015:
return Mips::T7;
5617 case Mips::COP016:
return Mips::S0;
5618 case Mips::COP017:
return Mips::S1;
5619 case Mips::COP018:
return Mips::S2;
5620 case Mips::COP019:
return Mips::S3;
5621 case Mips::COP020:
return Mips::S4;
5622 case Mips::COP021:
return Mips::S5;
5623 case Mips::COP022:
return Mips::S6;
5624 case Mips::COP023:
return Mips::S7;
5625 case Mips::COP024:
return Mips::T8;
5626 case Mips::COP025:
return Mips::T9;
5627 case Mips::COP026:
return Mips::K0;
5628 case Mips::COP027:
return Mips::K1;
5629 case Mips::COP028:
return Mips::GP;
5630 case Mips::COP029:
return Mips::SP;
5631 case Mips::COP030:
return Mips::FP;
5632 case Mips::COP031:
return Mips::RA;
5639bool MipsAsmParser::expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5640 const MCSubtargetInfo *STI) {
5641 MipsTargetStreamer &TOut = getTargetStreamer();
5646 bool IsMFTR =
false;
5700 IsMFTR ? MCRegister(rd)
5702 : Inst.getOperand(0).
getReg());
5704 TOut.
emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, u, sel, h, IDLoc,
5709bool MipsAsmParser::expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5710 const MCSubtargetInfo *STI) {
5715 warnIfNoMacro(IDLoc);
5717 MipsTargetStreamer &TOut = getTargetStreamer();
5718 unsigned Opcode = Inst.
getOpcode() == Mips::SaaAddr ? Mips::SAA : Mips::SAAD;
5721 const MCOperand &BaseOp = Inst.
getOperand(2);
5723 if (BaseOp.
isImm()) {
5724 int64_t ImmValue = BaseOp.
getImm();
5725 if (ImmValue == 0) {
5726 TOut.
emitRR(Opcode, RtReg, BaseReg, IDLoc, STI);
5731 MCRegister ATReg = getATReg(IDLoc);
5735 if (expandLoadAddress(ATReg, BaseReg, BaseOp, !isGP64bit(), IDLoc, Out, STI))
5738 TOut.
emitRR(Opcode, RtReg, ATReg, IDLoc, STI);
5743MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
5747 return Match_Success;
5750 if (
static_cast<MipsOperand &
>(*Operands[1])
5751 .isValidForTie(
static_cast<MipsOperand &
>(*Operands[2])))
5752 return Match_Success;
5753 return Match_RequiresSameSrcAndDst;
5757unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
5764 return Match_RequiresNoZeroRegister;
5765 return Match_Success;
5771 case Mips::JALR_HB64:
5772 case Mips::JALRC_HB_MMR6:
5773 case Mips::JALRC_MMR6:
5775 return Match_RequiresDifferentSrcAndDst;
5776 return Match_Success;
5779 return Match_RequiresDifferentSrcAndDst;
5780 return Match_Success;
5783 return Match_NonZeroOperandForSync;
5784 return Match_Success;
5790 return Match_NonZeroOperandForMTCX;
5791 return Match_Success;
5804 case Mips::BLEZC:
case Mips::BLEZC_MMR6:
5805 case Mips::BGEZC:
case Mips::BGEZC_MMR6:
5806 case Mips::BGTZC:
case Mips::BGTZC_MMR6:
5807 case Mips::BLTZC:
case Mips::BLTZC_MMR6:
5808 case Mips::BEQZC:
case Mips::BEQZC_MMR6:
5809 case Mips::BNEZC:
case Mips::BNEZC_MMR6:
5818 return Match_RequiresNoZeroRegister;
5819 return Match_Success;
5820 case Mips::BGEC:
case Mips::BGEC_MMR6:
5821 case Mips::BLTC:
case Mips::BLTC_MMR6:
5822 case Mips::BGEUC:
case Mips::BGEUC_MMR6:
5823 case Mips::BLTUC:
case Mips::BLTUC_MMR6:
5824 case Mips::BEQC:
case Mips::BEQC_MMR6:
5825 case Mips::BNEC:
case Mips::BNEC_MMR6:
5834 return Match_RequiresNoZeroRegister;
5837 return Match_RequiresNoZeroRegister;
5839 return Match_RequiresDifferentOperands;
5840 return Match_Success;
5843 "Operands must be immediates for dins!");
5846 if ((0 > (Pos +
Size)) || ((Pos +
Size) > 32))
5847 return Match_RequiresPosSizeRange0_32;
5848 return Match_Success;
5853 "Operands must be immediates for dinsm/dinsu!");
5856 if ((32 >= (Pos +
Size)) || ((Pos +
Size) > 64))
5857 return Match_RequiresPosSizeRange33_64;
5858 return Match_Success;
5862 "Operands must be immediates for DEXTM!");
5865 if ((1 > (Pos +
Size)) || ((Pos +
Size) > 63))
5866 return Match_RequiresPosSizeUImm6;
5867 return Match_Success;
5872 "Operands must be immediates for dextm/dextu!");
5875 if ((32 > (Pos +
Size)) || ((Pos +
Size) > 64))
5876 return Match_RequiresPosSizeRange33_64;
5877 return Match_Success;
5879 case Mips::CRC32B:
case Mips::CRC32CB:
5880 case Mips::CRC32H:
case Mips::CRC32CH:
5881 case Mips::CRC32W:
case Mips::CRC32CW:
5882 case Mips::CRC32D:
case Mips::CRC32CD:
5884 return Match_RequiresSameSrcAndDst;
5885 return Match_Success;
5888 uint64_t TSFlags = MII.get(Inst.
getOpcode()).TSFlags;
5891 return Match_NoFCCRegisterForCurrentISA;
5893 return Match_Success;
5901 if (ErrorLoc ==
SMLoc())
5908bool MipsAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
5911 uint64_t &ErrorInfo,
5912 bool MatchingInlineAsm) {
5914 unsigned MatchResult =
5915 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
5917 switch (MatchResult) {
5919 if (processInstruction(Inst, IDLoc, Out, STI))
5922 case Match_MissingFeature:
5923 Error(IDLoc,
"instruction requires a CPU feature not currently enabled");
5925 case Match_InvalidTiedOperand:
5926 Error(IDLoc,
"operand must match destination register");
5928 case Match_InvalidOperand: {
5929 SMLoc ErrorLoc = IDLoc;
5930 if (ErrorInfo != ~0ULL) {
5931 if (ErrorInfo >= Operands.
size())
5932 return Error(IDLoc,
"too few operands for instruction");
5934 ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5935 if (ErrorLoc == SMLoc())
5939 return Error(ErrorLoc,
"invalid operand for instruction");
5941 case Match_NonZeroOperandForSync:
5943 "s-type must be zero or unspecified for pre-MIPS32 ISAs");
5944 case Match_NonZeroOperandForMTCX:
5945 return Error(IDLoc,
"selector must be zero for pre-MIPS32 ISAs");
5946 case Match_MnemonicFail:
5947 return Error(IDLoc,
"invalid instruction");
5948 case Match_RequiresDifferentSrcAndDst:
5949 return Error(IDLoc,
"source and destination must be different");
5950 case Match_RequiresDifferentOperands:
5951 return Error(IDLoc,
"registers must be different");
5952 case Match_RequiresNoZeroRegister:
5953 return Error(IDLoc,
"invalid operand ($zero) for instruction");
5954 case Match_RequiresSameSrcAndDst:
5955 return Error(IDLoc,
"source and destination must match");
5956 case Match_NoFCCRegisterForCurrentISA:
5958 "non-zero fcc register doesn't exist in current ISA level");
5963 "expected 1-bit unsigned immediate");
5966 "expected 2-bit unsigned immediate");
5969 "expected immediate in range 1 .. 4");
5972 "expected 3-bit unsigned immediate");
5975 "expected 4-bit unsigned immediate");
5978 "expected 4-bit signed immediate");
5981 "expected 5-bit unsigned immediate");
5984 "expected 5-bit signed immediate");
5987 "expected immediate in range 1 .. 32");
5988 case Match_UImm5_32:
5990 "expected immediate in range 32 .. 63");
5991 case Match_UImm5_33:
5993 "expected immediate in range 33 .. 64");
5994 case Match_UImm5_0_Report_UImm6:
5998 "expected 6-bit unsigned immediate");
5999 case Match_UImm5_Lsl2:
6001 "expected both 7-bit unsigned immediate and multiple of 4");
6002 case Match_UImmRange2_64:
6004 "expected immediate in range 2 .. 64");
6007 "expected 6-bit unsigned immediate");
6008 case Match_UImm6_Lsl2:
6010 "expected both 8-bit unsigned immediate and multiple of 4");
6013 "expected 6-bit signed immediate");
6016 "expected 7-bit unsigned immediate");
6017 case Match_UImm7_N1:
6019 "expected immediate in range -1 .. 126");
6020 case Match_SImm7_Lsl2:
6022 "expected both 9-bit signed immediate and multiple of 4");
6025 "expected 8-bit unsigned immediate");
6026 case Match_UImm10_0:
6028 "expected 10-bit unsigned immediate");
6029 case Match_SImm10_0:
6031 "expected 10-bit signed immediate");
6032 case Match_SImm11_0:
6034 "expected 11-bit signed immediate");
6036 case Match_UImm16_Relaxed:
6037 case Match_UImm16_AltRelaxed:
6039 "expected 16-bit unsigned immediate");
6041 case Match_SImm16_Relaxed:
6043 "expected 16-bit signed immediate");
6044 case Match_SImm19_Lsl2:
6046 "expected both 19-bit signed immediate and multiple of 4");
6047 case Match_UImm20_0:
6049 "expected 20-bit unsigned immediate");
6050 case Match_UImm26_0:
6052 "expected 26-bit unsigned immediate");
6054 case Match_SImm32_Relaxed:
6056 "expected 32-bit signed immediate");
6057 case Match_UImm32_Coerced:
6059 "expected 32-bit immediate");
6060 case Match_MemSImm9:
6062 "expected memory with 9-bit signed offset");
6063 case Match_MemSImm10:
6065 "expected memory with 10-bit signed offset");
6066 case Match_MemSImm10Lsl1:
6068 "expected memory with 11-bit signed offset and multiple of 2");
6069 case Match_MemSImm10Lsl2:
6071 "expected memory with 12-bit signed offset and multiple of 4");
6072 case Match_MemSImm10Lsl3:
6074 "expected memory with 13-bit signed offset and multiple of 8");
6075 case Match_MemSImm11:
6077 "expected memory with 11-bit signed offset");
6078 case Match_MemSImm12:
6080 "expected memory with 12-bit signed offset");
6081 case Match_MemSImm16:
6083 "expected memory with 16-bit signed offset");
6084 case Match_MemSImmPtr:
6086 "expected memory with 32-bit signed offset");
6087 case Match_RequiresPosSizeRange0_32: {
6088 SMLoc ErrorStart = Operands[3]->getStartLoc();
6089 SMLoc ErrorEnd = Operands[4]->getEndLoc();
6090 return Error(ErrorStart,
"size plus position are not in the range 0 .. 32",
6091 SMRange(ErrorStart, ErrorEnd));
6093 case Match_RequiresPosSizeUImm6: {
6094 SMLoc ErrorStart = Operands[3]->getStartLoc();
6095 SMLoc ErrorEnd = Operands[4]->getEndLoc();
6096 return Error(ErrorStart,
"size plus position are not in the range 1 .. 63",
6097 SMRange(ErrorStart, ErrorEnd));
6099 case Match_RequiresPosSizeRange33_64: {
6100 SMLoc ErrorStart = Operands[3]->getStartLoc();
6101 SMLoc ErrorEnd = Operands[4]->getEndLoc();
6102 return Error(ErrorStart,
"size plus position are not in the range 33 .. 64",
6103 SMRange(ErrorStart, ErrorEnd));
6110void MipsAsmParser::warnIfRegIndexIsAT(MCRegister RegIndex, SMLoc Loc) {
6111 if (RegIndex && AssemblerOptions.
back()->getATRegIndex() == RegIndex)
6112 Warning(Loc,
"used $at (currently $" + Twine(RegIndex.
id()) +
6113 ") without \".set noat\"");
6116void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
6117 if (!AssemblerOptions.
back()->isMacro())
6118 Warning(Loc,
"macro instruction expanded into multiple instructions");
6121void MipsAsmParser::ConvertXWPOperands(MCInst &Inst,
6125 "Unexpected instruction!");
6126 ((MipsOperand &)*Operands[1]).addGPR32ZeroAsmRegOperands(Inst, 1);
6127 MCRegister NextReg =
nextReg(((MipsOperand &)*Operands[1]).getGPR32Reg());
6129 ((MipsOperand &)*Operands[2]).addMemOperands(Inst, 2);
6133MipsAsmParser::printWarningWithFixIt(
const Twine &Msg,
const Twine &FixMsg,
6134 SMRange
Range,
bool ShowColors) {
6140int MipsAsmParser::matchCPURegisterName(StringRef Name) {
6143 CC = StringSwitch<unsigned>(Name)
6145 .Cases({
"at",
"AT"}, 1)
6179 if (!(isABI_N32() || isABI_N64()))
6182 if (12 <= CC && CC <= 15) {
6184 AsmToken RegTok = getLexer().peekTok();
6187 StringRef FixedName = StringSwitch<StringRef>(Name)
6193 assert(FixedName !=
"" &&
"Register name is not one of t4-t7.");
6195 printWarningWithFixIt(
"register names $t4-$t7 are only available in O32.",
6196 "Did you mean $" + FixedName +
"?", RegRange);
6202 if (8 <= CC && CC <= 11)
6206 CC = StringSwitch<unsigned>(Name)
6218int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
6221 CC = StringSwitch<unsigned>(Name)
6222 .Case(
"hwr_cpunum", 0)
6223 .Case(
"hwr_synci_step", 1)
6225 .Case(
"hwr_ccres", 3)
6226 .Case(
"hwr_ulr", 29)
6232int MipsAsmParser::matchFPURegisterName(StringRef Name) {
6233 if (Name[0] ==
'f') {
6234 StringRef NumString =
Name.substr(1);
6245int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
6246 if (
Name.starts_with(
"fcc")) {
6247 StringRef NumString =
Name.substr(3);
6258int MipsAsmParser::matchACRegisterName(StringRef Name) {
6259 if (
Name.starts_with(
"ac")) {
6260 StringRef NumString =
Name.substr(2);
6271int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
6274 if (
Name.front() !=
'w' ||
Name.drop_front(1).getAsInteger(10, IntVal))
6283int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
6286 CC = StringSwitch<unsigned>(Name)
6289 .Case(
"msaaccess", 2)
6291 .Case(
"msamodify", 4)
6292 .Case(
"msarequest", 5)
6294 .Case(
"msaunmap", 7)
6300bool MipsAsmParser::canUseATReg() {
6301 return AssemblerOptions.
back()->getATRegIndex() != 0;
6304MCRegister MipsAsmParser::getATReg(SMLoc Loc) {
6305 unsigned ATIndex = AssemblerOptions.
back()->getATRegIndex();
6307 reportParseError(Loc,
6308 "pseudo-instruction requires $at, which is not available");
6312 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
6316MCRegister MipsAsmParser::getReg(
int RC,
int RegNo) {
6317 return getContext().getRegisterInfo()->getRegClass(RC).getRegister(RegNo);
6323const MCExpr *MipsAsmParser::parseRelocExpr() {
6324 auto getOp = [](StringRef
Op) {
6325 return StringSwitch<Mips::Specifier>(
Op)
6353 MCAsmParser &Parser = getParser();
6355 const MCExpr *Res =
nullptr;
6361 auto Op = getOp(Name);
6370 while (
Ops.size()) {
6378bool MipsAsmParser::parseOperand(
OperandVector &Operands, StringRef Mnemonic) {
6379 MCAsmParser &Parser = getParser();
6389 ParseStatus Res = MatchOperandParserImpl(Operands, Mnemonic,
true);
6400 switch (getLexer().getKind()) {
6410 if (!parseAnyRegister(Operands).isNoMatch())
6423 Operands.
push_back(MipsOperand::CreateImm(SymRef, S,
E, *
this));
6428 const MCExpr *Expr = parseRelocExpr();
6432 Operands.
push_back(MipsOperand::CreateImm(Expr, S,
E, *
this));
6439bool MipsAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
6441 return !tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess();
6444ParseStatus MipsAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
6447 ParseStatus Res = parseAnyRegister(Operands);
6450 MipsOperand &Operand =
static_cast<MipsOperand &
>(*Operands.
front());
6451 StartLoc = Operand.getStartLoc();
6452 EndLoc = Operand.getEndLoc();
6458 if (Operand.isGPRAsmReg()) {
6460 Reg = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
6470ParseStatus MipsAsmParser::parseMemOperand(
OperandVector &Operands) {
6471 MCAsmParser &Parser = getParser();
6473 const MCExpr *IdVal =
nullptr;
6475 bool isParenExpr =
false;
6486 IdVal = parseRelocExpr();
6492 const AsmToken &Tok = Parser.
getTok();
6494 MipsOperand &Mnemonic =
static_cast<MipsOperand &
>(*Operands[0]);
6495 if (Mnemonic.getToken() ==
"la" || Mnemonic.getToken() ==
"dla") {
6498 Operands.
push_back(MipsOperand::CreateImm(IdVal, S,
E, *
this));
6507 auto Base = MipsOperand::createGPRReg(
6508 0,
"0",
getContext().getRegisterInfo(), S,
E, *
this);
6510 MipsOperand::CreateMem(std::move(
Base), IdVal, S,
E, *
this));
6562 const MCExpr * NextExpr;
6563 if (getParser().parseExpression(NextExpr))
6571 Res = parseAnyRegister(Operands);
6586 std::unique_ptr<MipsOperand>
op(
6587 static_cast<MipsOperand *
>(Operands.
back().release()));
6594 if (IdVal->evaluateAsAbsolute(Imm))
6601 Operands.
push_back(MipsOperand::CreateMem(std::move(
op), IdVal, S,
E, *
this));
6605bool MipsAsmParser::searchSymbolAlias(
OperandVector &Operands) {
6606 MCAsmParser &Parser = getParser();
6615 const MCSymbolRefExpr *
Ref =
static_cast<const MCSymbolRefExpr *
>(Expr);
6616 StringRef DefSymbol =
Ref->getSymbol().getName();
6619 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.
substr(1), S);
6633 if (Entry != RegisterSets.
end()) {
6635 matchAnyRegisterWithoutDollar(Operands,
Entry->getValue(), S);
6646ParseStatus MipsAsmParser::matchAnyRegisterNameWithoutDollar(
6648 int Index = matchCPURegisterName(Identifier);
6650 Operands.
push_back(MipsOperand::createGPRReg(
6651 Index, Identifier,
getContext().getRegisterInfo(), S,
6652 getLexer().getLoc(), *
this));
6656 Index = matchHWRegsRegisterName(Identifier);
6658 Operands.
push_back(MipsOperand::createHWRegsReg(
6659 Index, Identifier,
getContext().getRegisterInfo(), S,
6660 getLexer().getLoc(), *
this));
6664 Index = matchFPURegisterName(Identifier);
6666 Operands.
push_back(MipsOperand::createFGRReg(
6667 Index, Identifier,
getContext().getRegisterInfo(), S,
6668 getLexer().getLoc(), *
this));
6672 Index = matchFCCRegisterName(Identifier);
6674 Operands.
push_back(MipsOperand::createFCCReg(
6675 Index, Identifier,
getContext().getRegisterInfo(), S,
6676 getLexer().getLoc(), *
this));
6680 Index = matchACRegisterName(Identifier);
6682 Operands.
push_back(MipsOperand::createACCReg(
6683 Index, Identifier,
getContext().getRegisterInfo(), S,
6684 getLexer().getLoc(), *
this));
6688 Index = matchMSA128RegisterName(Identifier);
6690 Operands.
push_back(MipsOperand::createMSA128Reg(
6691 Index, Identifier,
getContext().getRegisterInfo(), S,
6692 getLexer().getLoc(), *
this));
6696 Index = matchMSA128CtrlRegisterName(Identifier);
6698 Operands.
push_back(MipsOperand::createMSACtrlReg(
6699 Index, Identifier,
getContext().getRegisterInfo(), S,
6700 getLexer().getLoc(), *
this));
6708MipsAsmParser::matchAnyRegisterWithoutDollar(
OperandVector &Operands,
6709 const AsmToken &Token, SMLoc S) {
6713 return matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
6718 if (RegNum < 0 || RegNum > 31) {
6722 Error(getLexer().getLoc(),
"invalid register number");
6724 Operands.
push_back(MipsOperand::createNumericReg(
6736MipsAsmParser::matchAnyRegisterWithoutDollar(
OperandVector &Operands, SMLoc S) {
6737 auto Token = getLexer().peekTok(
false);
6738 return matchAnyRegisterWithoutDollar(Operands, Token, S);
6741ParseStatus MipsAsmParser::parseAnyRegister(
OperandVector &Operands) {
6742 MCAsmParser &Parser = getParser();
6745 auto Token = Parser.
getTok();
6747 SMLoc S = Token.
getLoc();
6752 if (searchSymbolAlias(Operands))
6760 ParseStatus Res = matchAnyRegisterWithoutDollar(Operands, S);
6768ParseStatus MipsAsmParser::parseJumpTarget(
OperandVector &Operands) {
6769 MCAsmParser &Parser = getParser();
6772 SMLoc S = getLexer().getLoc();
6775 ParseStatus Res = parseAnyRegister(Operands);
6780 const MCExpr *Expr =
nullptr;
6786 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *
this));
6790ParseStatus MipsAsmParser::parseInvNum(
OperandVector &Operands) {
6791 MCAsmParser &Parser = getParser();
6792 const MCExpr *IdVal;
6803 if (getParser().parseExpression(IdVal))
6810 Operands.
push_back(MipsOperand::CreateImm(
6815ParseStatus MipsAsmParser::parseRegisterList(
OperandVector &Operands) {
6816 MCAsmParser &Parser = getParser();
6820 bool RegRange =
false;
6827 while (parseAnyRegister(TmpOperands).isSuccess()) {
6828 SMLoc
E = getLexer().getLoc();
6829 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*TmpOperands.
back());
6830 Reg = isGP64bit() ? RegOpnd.getGPR64Reg() : RegOpnd.getGPR32Reg();
6834 if ((isGP64bit() &&
Reg == Mips::RA_64) ||
6835 (!isGP64bit() &&
Reg == Mips::RA)) {
6838 MCRegister TmpReg = PrevReg + 1;
6839 while (TmpReg <=
Reg) {
6840 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
6841 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
6843 return Error(
E,
"invalid register operand");
6847 TmpReg = TmpReg.
id() + 1;
6854 ((isGP64bit() && (
Reg != Mips::S0_64) && (
Reg != Mips::RA_64)) ||
6855 (!isGP64bit() && (
Reg != Mips::S0) && (
Reg != Mips::RA))))
6856 return Error(
E,
"$16 or $31 expected");
6857 if (!(((
Reg == Mips::FP ||
Reg == Mips::RA ||
6858 (
Reg >= Mips::S0 &&
Reg <= Mips::S7)) &&
6860 ((
Reg == Mips::FP_64 ||
Reg == Mips::RA_64 ||
6861 (
Reg >= Mips::S0_64 &&
Reg <= Mips::S7_64)) &&
6863 return Error(
E,
"invalid register operand");
6864 if (PrevReg.
isValid() && (
Reg != PrevReg + 1) &&
6865 ((
Reg != Mips::FP &&
Reg != Mips::RA && !isGP64bit()) ||
6866 (
Reg != Mips::FP_64 &&
Reg != Mips::RA_64 && isGP64bit())))
6867 return Error(
E,
"consecutive register numbers expected");
6877 return Error(
E,
"',' or '-' expected");
6887 Operands.
push_back(MipsOperand::CreateRegList(Regs, S,
E, *
this));
6888 parseMemOperand(Operands);
6897bool MipsAsmParser::parseParenSuffix(StringRef Name,
OperandVector &Operands) {
6898 MCAsmParser &Parser = getParser();
6901 MipsOperand::CreateToken(
"(", getLexer().getLoc(), *
this));
6903 if (parseOperand(Operands, Name)) {
6904 SMLoc Loc = getLexer().getLoc();
6905 return Error(Loc,
"unexpected token in argument list");
6908 SMLoc Loc = getLexer().getLoc();
6909 return Error(Loc,
"unexpected token, expected ')'");
6912 MipsOperand::CreateToken(
")", getLexer().getLoc(), *
this));
6924bool MipsAsmParser::parseBracketSuffix(StringRef Name,
6926 MCAsmParser &Parser = getParser();
6929 MipsOperand::CreateToken(
"[", getLexer().getLoc(), *
this));
6931 if (parseOperand(Operands, Name)) {
6932 SMLoc Loc = getLexer().getLoc();
6933 return Error(Loc,
"unexpected token in argument list");
6936 SMLoc Loc = getLexer().getLoc();
6937 return Error(Loc,
"unexpected token, expected ']'");
6940 MipsOperand::CreateToken(
"]", getLexer().getLoc(), *
this));
6947 unsigned VariantID = 0);
6962bool MipsAsmParser::parseInstruction(ParseInstructionInfo &
Info, StringRef Name,
6964 MCAsmParser &Parser = getParser();
6968 getTargetStreamer().forbidModuleDirective();
6971 if (!mnemonicIsValid(Name, 0)) {
6972 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
6974 return Error(NameLoc,
"unknown instruction" + Suggestion);
6977 Operands.
push_back(MipsOperand::CreateToken(Name, NameLoc, *
this));
6982 if (parseOperand(Operands, Name)) {
6983 SMLoc Loc = getLexer().getLoc();
6984 return Error(Loc,
"unexpected token in argument list");
6986 if (getLexer().is(
AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
6993 if (parseOperand(Operands, Name)) {
6994 SMLoc Loc = getLexer().getLoc();
6995 return Error(Loc,
"unexpected token in argument list");
6999 if (parseBracketSuffix(Name, Operands))
7002 parseParenSuffix(Name, Operands))
7007 SMLoc Loc = getLexer().getLoc();
7008 return Error(Loc,
"unexpected token in argument list");
7016bool MipsAsmParser::reportParseError(
const Twine &ErrorMsg) {
7017 SMLoc Loc = getLexer().getLoc();
7018 return Error(Loc, ErrorMsg);
7021bool MipsAsmParser::reportParseError(SMLoc Loc,
const Twine &ErrorMsg) {
7022 return Error(Loc, ErrorMsg);
7025bool MipsAsmParser::parseSetNoAtDirective() {
7026 MCAsmParser &Parser = getParser();
7030 AssemblerOptions.
back()->setATRegIndex(0);
7036 reportParseError(
"unexpected token, expected end of statement");
7040 getTargetStreamer().emitDirectiveSetNoAt();
7045bool MipsAsmParser::parseSetAtDirective() {
7048 MCAsmParser &Parser = getParser();
7053 AssemblerOptions.
back()->setATRegIndex(1);
7055 getTargetStreamer().emitDirectiveSetAt();
7061 reportParseError(
"unexpected token, expected equals sign");
7068 reportParseError(
"no register specified");
7071 reportParseError(
"unexpected token, expected dollar sign '$'");
7081 AtRegNo = matchCPURegisterName(
Reg.getIdentifier());
7083 AtRegNo =
Reg.getIntVal();
7085 reportParseError(
"unexpected token, expected identifier or integer");
7090 if (!AssemblerOptions.
back()->setATRegIndex(AtRegNo)) {
7091 reportParseError(
"invalid register");
7098 reportParseError(
"unexpected token, expected end of statement");
7102 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
7108bool MipsAsmParser::parseSetReorderDirective() {
7109 MCAsmParser &Parser = getParser();
7113 reportParseError(
"unexpected token, expected end of statement");
7116 AssemblerOptions.
back()->setReorder();
7117 getTargetStreamer().emitDirectiveSetReorder();
7122bool MipsAsmParser::parseSetNoReorderDirective() {
7123 MCAsmParser &Parser = getParser();
7127 reportParseError(
"unexpected token, expected end of statement");
7130 AssemblerOptions.
back()->setNoReorder();
7131 getTargetStreamer().emitDirectiveSetNoReorder();
7136bool MipsAsmParser::parseSetMacroDirective() {
7137 MCAsmParser &Parser = getParser();
7141 reportParseError(
"unexpected token, expected end of statement");
7144 AssemblerOptions.
back()->setMacro();
7145 getTargetStreamer().emitDirectiveSetMacro();
7150bool MipsAsmParser::parseSetNoMacroDirective() {
7151 MCAsmParser &Parser = getParser();
7155 reportParseError(
"unexpected token, expected end of statement");
7158 if (AssemblerOptions.
back()->isReorder()) {
7159 reportParseError(
"`noreorder' must be set before `nomacro'");
7162 AssemblerOptions.
back()->setNoMacro();
7163 getTargetStreamer().emitDirectiveSetNoMacro();
7168bool MipsAsmParser::parseSetMsaDirective() {
7169 MCAsmParser &Parser = getParser();
7174 return reportParseError(
"unexpected token, expected end of statement");
7176 setFeatureBits(Mips::FeatureMSA,
"msa");
7177 getTargetStreamer().emitDirectiveSetMsa();
7181bool MipsAsmParser::parseSetNoMsaDirective() {
7182 MCAsmParser &Parser = getParser();
7187 return reportParseError(
"unexpected token, expected end of statement");
7189 clearFeatureBits(Mips::FeatureMSA,
"msa");
7190 getTargetStreamer().emitDirectiveSetNoMsa();
7194bool MipsAsmParser::parseSetNoDspDirective() {
7195 MCAsmParser &Parser = getParser();
7200 reportParseError(
"unexpected token, expected end of statement");
7204 clearFeatureBits(Mips::FeatureDSP,
"dsp");
7205 getTargetStreamer().emitDirectiveSetNoDsp();
7209bool MipsAsmParser::parseSetNoMips3DDirective() {
7210 MCAsmParser &Parser = getParser();
7215 reportParseError(
"unexpected token, expected end of statement");
7219 clearFeatureBits(Mips::FeatureMips3D,
"mips3d");
7220 getTargetStreamer().emitDirectiveSetNoMips3D();
7224bool MipsAsmParser::parseSetMips16Directive() {
7225 MCAsmParser &Parser = getParser();
7230 reportParseError(
"unexpected token, expected end of statement");
7234 setFeatureBits(Mips::FeatureMips16,
"mips16");
7235 getTargetStreamer().emitDirectiveSetMips16();
7240bool MipsAsmParser::parseSetNoMips16Directive() {
7241 MCAsmParser &Parser = getParser();
7246 reportParseError(
"unexpected token, expected end of statement");
7250 clearFeatureBits(Mips::FeatureMips16,
"mips16");
7251 getTargetStreamer().emitDirectiveSetNoMips16();
7256bool MipsAsmParser::parseSetFpDirective() {
7257 MCAsmParser &Parser = getParser();
7263 AsmToken Tok = Parser.
getTok();
7265 reportParseError(
"unexpected token, expected equals sign '='");
7271 if (!parseFpABIValue(FpAbiVal,
".set"))
7275 reportParseError(
"unexpected token, expected end of statement");
7278 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
7283bool MipsAsmParser::parseSetOddSPRegDirective() {
7284 MCAsmParser &Parser = getParser();
7288 reportParseError(
"unexpected token, expected end of statement");
7292 clearFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
7293 getTargetStreamer().emitDirectiveSetOddSPReg();
7297bool MipsAsmParser::parseSetNoOddSPRegDirective() {
7298 MCAsmParser &Parser = getParser();
7302 reportParseError(
"unexpected token, expected end of statement");
7306 setFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
7307 getTargetStreamer().emitDirectiveSetNoOddSPReg();
7311bool MipsAsmParser::parseSetMtDirective() {
7312 MCAsmParser &Parser = getParser();
7317 reportParseError(
"unexpected token, expected end of statement");
7321 setFeatureBits(Mips::FeatureMT,
"mt");
7322 getTargetStreamer().emitDirectiveSetMt();
7327bool MipsAsmParser::parseSetNoMtDirective() {
7328 MCAsmParser &Parser = getParser();
7333 reportParseError(
"unexpected token, expected end of statement");
7337 clearFeatureBits(Mips::FeatureMT,
"mt");
7339 getTargetStreamer().emitDirectiveSetNoMt();
7344bool MipsAsmParser::parseSetNoCRCDirective() {
7345 MCAsmParser &Parser = getParser();
7350 reportParseError(
"unexpected token, expected end of statement");
7354 clearFeatureBits(Mips::FeatureCRC,
"crc");
7356 getTargetStreamer().emitDirectiveSetNoCRC();
7361bool MipsAsmParser::parseSetNoVirtDirective() {
7362 MCAsmParser &Parser = getParser();
7367 reportParseError(
"unexpected token, expected end of statement");
7371 clearFeatureBits(Mips::FeatureVirt,
"virt");
7373 getTargetStreamer().emitDirectiveSetNoVirt();
7378bool MipsAsmParser::parseSetNoGINVDirective() {
7379 MCAsmParser &Parser = getParser();
7384 reportParseError(
"unexpected token, expected end of statement");
7388 clearFeatureBits(Mips::FeatureGINV,
"ginv");
7390 getTargetStreamer().emitDirectiveSetNoGINV();
7395bool MipsAsmParser::parseSetPopDirective() {
7396 MCAsmParser &Parser = getParser();
7397 SMLoc Loc = getLexer().getLoc();
7401 return reportParseError(
"unexpected token, expected end of statement");
7405 if (AssemblerOptions.
size() == 2)
7406 return reportParseError(Loc,
".set pop with no .set push");
7408 MCSubtargetInfo &STI = copySTI();
7410 setAvailableFeatures(
7411 ComputeAvailableFeatures(AssemblerOptions.
back()->getFeatures()));
7414 getTargetStreamer().emitDirectiveSetPop();
7418bool MipsAsmParser::parseSetPushDirective() {
7419 MCAsmParser &Parser = getParser();
7422 return reportParseError(
"unexpected token, expected end of statement");
7426 std::make_unique<MipsAssemblerOptions>(AssemblerOptions.
back().get()));
7428 getTargetStreamer().emitDirectiveSetPush();
7432bool MipsAsmParser::parseSetSoftFloatDirective() {
7433 MCAsmParser &Parser = getParser();
7436 return reportParseError(
"unexpected token, expected end of statement");
7438 setFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
7439 getTargetStreamer().emitDirectiveSetSoftFloat();
7443bool MipsAsmParser::parseSetHardFloatDirective() {
7444 MCAsmParser &Parser = getParser();
7447 return reportParseError(
"unexpected token, expected end of statement");
7449 clearFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
7450 getTargetStreamer().emitDirectiveSetHardFloat();
7454bool MipsAsmParser::parseSetAssignment() {
7456 MCAsmParser &Parser = getParser();
7459 return reportParseError(
"expected identifier after .set");
7462 return reportParseError(
"unexpected token, expected comma");
7477 const MCExpr *
Value;
7479 Parser, Sym,
Value))
7481 getStreamer().emitAssignment(Sym,
Value);
7486bool MipsAsmParser::parseSetMips0Directive() {
7487 MCAsmParser &Parser = getParser();
7490 return reportParseError(
"unexpected token, expected end of statement");
7493 MCSubtargetInfo &STI = copySTI();
7494 setAvailableFeatures(
7495 ComputeAvailableFeatures(AssemblerOptions.
front()->getFeatures()));
7497 AssemblerOptions.
back()->setFeatures(AssemblerOptions.
front()->getFeatures());
7499 getTargetStreamer().emitDirectiveSetMips0();
7503bool MipsAsmParser::parseSetArchDirective() {
7504 MCAsmParser &Parser = getParser();
7507 return reportParseError(
"unexpected token, expected equals sign");
7510 StringRef Arch = getParser().parseStringToEndOfStatement().trim();
7512 return reportParseError(
"expected arch identifier");
7514 StringRef ArchFeatureName =
7515 StringSwitch<StringRef>(Arch)
7516 .Case(
"mips1",
"mips1")
7517 .Case(
"mips2",
"mips2")
7518 .Case(
"mips3",
"mips3")
7519 .Case(
"mips4",
"mips4")
7520 .Case(
"mips5",
"mips5")
7521 .Case(
"mips32",
"mips32")
7522 .Case(
"mips32r2",
"mips32r2")
7523 .Case(
"mips32r3",
"mips32r3")
7524 .Case(
"mips32r5",
"mips32r5")
7525 .Case(
"mips32r6",
"mips32r6")
7526 .Case(
"mips64",
"mips64")
7527 .Case(
"mips64r2",
"mips64r2")
7528 .Case(
"mips64r3",
"mips64r3")
7529 .Case(
"mips64r5",
"mips64r5")
7530 .Case(
"mips64r6",
"mips64r6")
7531 .Case(
"octeon",
"cnmips")
7532 .Case(
"octeon+",
"cnmipsp")
7533 .Case(
"r4000",
"mips3")
7536 if (ArchFeatureName.
empty())
7537 return reportParseError(
"unsupported architecture");
7539 if (ArchFeatureName ==
"mips64r6" && inMicroMipsMode())
7540 return reportParseError(
"mips64r6 does not support microMIPS");
7542 selectArch(ArchFeatureName);
7543 getTargetStreamer().emitDirectiveSetArch(Arch);
7547bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
7548 MCAsmParser &Parser = getParser();
7551 return reportParseError(
"unexpected token, expected end of statement");
7556 case Mips::FeatureMips3D:
7557 setFeatureBits(Mips::FeatureMips3D,
"mips3d");
7558 getTargetStreamer().emitDirectiveSetMips3D();
7560 case Mips::FeatureDSP:
7561 setFeatureBits(Mips::FeatureDSP,
"dsp");
7562 getTargetStreamer().emitDirectiveSetDsp();
7564 case Mips::FeatureDSPR2:
7565 setFeatureBits(Mips::FeatureDSPR2,
"dspr2");
7566 getTargetStreamer().emitDirectiveSetDspr2();
7568 case Mips::FeatureMicroMips:
7569 setFeatureBits(Mips::FeatureMicroMips,
"micromips");
7570 getTargetStreamer().emitDirectiveSetMicroMips();
7572 case Mips::FeatureMips1:
7573 selectArch(
"mips1");
7574 getTargetStreamer().emitDirectiveSetMips1();
7576 case Mips::FeatureMips2:
7577 selectArch(
"mips2");
7578 getTargetStreamer().emitDirectiveSetMips2();
7580 case Mips::FeatureMips3:
7581 selectArch(
"mips3");
7582 getTargetStreamer().emitDirectiveSetMips3();
7584 case Mips::FeatureMips4:
7585 selectArch(
"mips4");
7586 getTargetStreamer().emitDirectiveSetMips4();
7588 case Mips::FeatureMips5:
7589 selectArch(
"mips5");
7590 getTargetStreamer().emitDirectiveSetMips5();
7592 case Mips::FeatureMips32:
7593 selectArch(
"mips32");
7594 getTargetStreamer().emitDirectiveSetMips32();
7596 case Mips::FeatureMips32r2:
7597 selectArch(
"mips32r2");
7598 getTargetStreamer().emitDirectiveSetMips32R2();
7600 case Mips::FeatureMips32r3:
7601 selectArch(
"mips32r3");
7602 getTargetStreamer().emitDirectiveSetMips32R3();
7604 case Mips::FeatureMips32r5:
7605 selectArch(
"mips32r5");
7606 getTargetStreamer().emitDirectiveSetMips32R5();
7608 case Mips::FeatureMips32r6:
7609 selectArch(
"mips32r6");
7610 getTargetStreamer().emitDirectiveSetMips32R6();
7612 case Mips::FeatureMips64:
7613 selectArch(
"mips64");
7614 getTargetStreamer().emitDirectiveSetMips64();
7616 case Mips::FeatureMips64r2:
7617 selectArch(
"mips64r2");
7618 getTargetStreamer().emitDirectiveSetMips64R2();
7620 case Mips::FeatureMips64r3:
7621 selectArch(
"mips64r3");
7622 getTargetStreamer().emitDirectiveSetMips64R3();
7624 case Mips::FeatureMips64r5:
7625 selectArch(
"mips64r5");
7626 getTargetStreamer().emitDirectiveSetMips64R5();
7628 case Mips::FeatureMips64r6:
7629 selectArch(
"mips64r6");
7630 getTargetStreamer().emitDirectiveSetMips64R6();
7632 case Mips::FeatureCRC:
7633 setFeatureBits(Mips::FeatureCRC,
"crc");
7634 getTargetStreamer().emitDirectiveSetCRC();
7636 case Mips::FeatureVirt:
7637 setFeatureBits(Mips::FeatureVirt,
"virt");
7638 getTargetStreamer().emitDirectiveSetVirt();
7640 case Mips::FeatureGINV:
7641 setFeatureBits(Mips::FeatureGINV,
"ginv");
7642 getTargetStreamer().emitDirectiveSetGINV();
7648bool MipsAsmParser::eatComma(StringRef ErrorStr) {
7649 MCAsmParser &Parser = getParser();
7651 SMLoc Loc = getLexer().getLoc();
7652 return Error(Loc, ErrorStr);
7663bool MipsAsmParser::isPicAndNotNxxAbi() {
7664 return inPicMode() && !(isABI_N32() || isABI_N64());
7667bool MipsAsmParser::parseDirectiveCpAdd(SMLoc Loc) {
7669 ParseStatus Res = parseAnyRegister(
Reg);
7671 reportParseError(
"expected register");
7675 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7676 if (!RegOpnd.isGPRAsmReg()) {
7677 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7683 reportParseError(
"unexpected token, expected end of statement");
7688 getTargetStreamer().emitDirectiveCpAdd(RegOpnd.getGPR32Reg());
7692bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
7693 if (AssemblerOptions.
back()->isReorder())
7694 Warning(Loc,
".cpload should be inside a noreorder section");
7696 if (inMips16Mode()) {
7697 reportParseError(
".cpload is not supported in Mips16 mode");
7702 ParseStatus Res = parseAnyRegister(
Reg);
7704 reportParseError(
"expected register containing function address");
7708 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7709 if (!RegOpnd.isGPRAsmReg()) {
7710 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7716 reportParseError(
"unexpected token, expected end of statement");
7720 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
7724bool MipsAsmParser::parseDirectiveCpLocal(SMLoc Loc) {
7725 if (!isABI_N32() && !isABI_N64()) {
7726 reportParseError(
".cplocal is allowed only in N32 or N64 mode");
7731 ParseStatus Res = parseAnyRegister(
Reg);
7733 reportParseError(
"expected register containing global pointer");
7737 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7738 if (!RegOpnd.isGPRAsmReg()) {
7739 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7745 reportParseError(
"unexpected token, expected end of statement");
7750 MCRegister NewReg = RegOpnd.getGPR32Reg();
7754 getTargetStreamer().emitDirectiveCpLocal(NewReg);
7758bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
7759 MCAsmParser &Parser = getParser();
7764 if (inMips16Mode()) {
7765 reportParseError(
".cprestore is not supported in Mips16 mode");
7770 const MCExpr *StackOffset;
7771 int64_t StackOffsetVal;
7773 reportParseError(
"expected stack offset value");
7777 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
7778 reportParseError(
"stack offset is not an absolute expression");
7782 if (StackOffsetVal < 0) {
7783 Warning(Loc,
".cprestore with negative stack offset has no effect");
7784 IsCpRestoreSet =
false;
7786 IsCpRestoreSet =
true;
7787 CpRestoreOffset = StackOffsetVal;
7792 reportParseError(
"unexpected token, expected end of statement");
7796 if (!getTargetStreamer().emitDirectiveCpRestore(
7797 CpRestoreOffset, [&]() {
return getATReg(Loc); }, Loc, STI))
7803bool MipsAsmParser::parseDirectiveCPSetup() {
7804 MCAsmParser &Parser = getParser();
7806 bool SaveIsReg =
true;
7809 ParseStatus Res = parseAnyRegister(TmpReg);
7811 reportParseError(
"expected register containing function address");
7815 MipsOperand &FuncRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7816 if (!FuncRegOpnd.isGPRAsmReg()) {
7817 reportParseError(FuncRegOpnd.getStartLoc(),
"invalid register");
7821 MCRegister FuncReg = FuncRegOpnd.getGPR32Reg();
7824 if (!eatComma(
"unexpected token, expected comma"))
7827 Res = parseAnyRegister(TmpReg);
7829 const MCExpr *OffsetExpr;
7831 SMLoc ExprLoc = getLexer().
getLoc();
7834 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
7835 reportParseError(ExprLoc,
"expected save register or stack offset");
7842 MipsOperand &SaveOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7843 if (!SaveOpnd.isGPRAsmReg()) {
7844 reportParseError(SaveOpnd.getStartLoc(),
"invalid register");
7847 Save = SaveOpnd.getGPR32Reg().id();
7850 if (!eatComma(
"unexpected token, expected comma"))
7855 reportParseError(
"expected expression");
7860 reportParseError(
"expected symbol");
7863 const MCSymbolRefExpr *
Ref =
static_cast<const MCSymbolRefExpr *
>(Expr);
7865 CpSaveLocation = Save;
7866 CpSaveLocationIsRegister = SaveIsReg;
7868 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save,
Ref->getSymbol(),
7873bool MipsAsmParser::parseDirectiveCPReturn() {
7874 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
7875 CpSaveLocationIsRegister);
7879bool MipsAsmParser::parseDirectiveNaN() {
7880 MCAsmParser &Parser = getParser();
7882 const AsmToken &Tok = Parser.
getTok();
7886 getTargetStreamer().emitDirectiveNaN2008();
7888 }
else if (Tok.
getString() ==
"legacy") {
7890 getTargetStreamer().emitDirectiveNaNLegacy();
7896 reportParseError(
"invalid option in .nan directive");
7900bool MipsAsmParser::parseDirectiveSet() {
7901 const AsmToken &Tok = getParser().getTok();
7903 SMLoc Loc = Tok.
getLoc();
7905 if (IdVal ==
"noat")
7906 return parseSetNoAtDirective();
7908 return parseSetAtDirective();
7909 if (IdVal ==
"arch")
7910 return parseSetArchDirective();
7911 if (IdVal ==
"bopt") {
7912 Warning(Loc,
"'bopt' feature is unsupported");
7916 if (IdVal ==
"nobopt") {
7922 return parseSetFpDirective();
7923 if (IdVal ==
"oddspreg")
7924 return parseSetOddSPRegDirective();
7925 if (IdVal ==
"nooddspreg")
7926 return parseSetNoOddSPRegDirective();
7928 return parseSetPopDirective();
7929 if (IdVal ==
"push")
7930 return parseSetPushDirective();
7931 if (IdVal ==
"reorder")
7932 return parseSetReorderDirective();
7933 if (IdVal ==
"noreorder")
7934 return parseSetNoReorderDirective();
7935 if (IdVal ==
"macro")
7936 return parseSetMacroDirective();
7937 if (IdVal ==
"nomacro")
7938 return parseSetNoMacroDirective();
7939 if (IdVal ==
"mips16")
7940 return parseSetMips16Directive();
7941 if (IdVal ==
"nomips16")
7942 return parseSetNoMips16Directive();
7943 if (IdVal ==
"nomicromips") {
7944 clearFeatureBits(Mips::FeatureMicroMips,
"micromips");
7945 getTargetStreamer().emitDirectiveSetNoMicroMips();
7946 getParser().eatToEndOfStatement();
7949 if (IdVal ==
"micromips") {
7950 if (hasMips64r6()) {
7951 Error(Loc,
".set micromips directive is not supported with MIPS64R6");
7954 return parseSetFeature(Mips::FeatureMicroMips);
7956 if (IdVal ==
"mips0")
7957 return parseSetMips0Directive();
7958 if (IdVal ==
"mips1")
7959 return parseSetFeature(Mips::FeatureMips1);
7960 if (IdVal ==
"mips2")
7961 return parseSetFeature(Mips::FeatureMips2);
7962 if (IdVal ==
"mips3")
7963 return parseSetFeature(Mips::FeatureMips3);
7964 if (IdVal ==
"mips4")
7965 return parseSetFeature(Mips::FeatureMips4);
7966 if (IdVal ==
"mips5")
7967 return parseSetFeature(Mips::FeatureMips5);
7968 if (IdVal ==
"mips32")
7969 return parseSetFeature(Mips::FeatureMips32);
7970 if (IdVal ==
"mips32r2")
7971 return parseSetFeature(Mips::FeatureMips32r2);
7972 if (IdVal ==
"mips32r3")
7973 return parseSetFeature(Mips::FeatureMips32r3);
7974 if (IdVal ==
"mips32r5")
7975 return parseSetFeature(Mips::FeatureMips32r5);
7976 if (IdVal ==
"mips32r6")
7977 return parseSetFeature(Mips::FeatureMips32r6);
7978 if (IdVal ==
"mips64")
7979 return parseSetFeature(Mips::FeatureMips64);
7980 if (IdVal ==
"mips64r2")
7981 return parseSetFeature(Mips::FeatureMips64r2);
7982 if (IdVal ==
"mips64r3")
7983 return parseSetFeature(Mips::FeatureMips64r3);
7984 if (IdVal ==
"mips64r5")
7985 return parseSetFeature(Mips::FeatureMips64r5);
7986 if (IdVal ==
"mips64r6") {
7987 if (inMicroMipsMode()) {
7988 Error(Loc,
"MIPS64R6 is not supported with microMIPS");
7991 return parseSetFeature(Mips::FeatureMips64r6);
7994 return parseSetFeature(Mips::FeatureDSP);
7995 if (IdVal ==
"dspr2")
7996 return parseSetFeature(Mips::FeatureDSPR2);
7997 if (IdVal ==
"nodsp")
7998 return parseSetNoDspDirective();
7999 if (IdVal ==
"mips3d")
8000 return parseSetFeature(Mips::FeatureMips3D);
8001 if (IdVal ==
"nomips3d")
8002 return parseSetNoMips3DDirective();
8004 return parseSetMsaDirective();
8005 if (IdVal ==
"nomsa")
8006 return parseSetNoMsaDirective();
8008 return parseSetMtDirective();
8009 if (IdVal ==
"nomt")
8010 return parseSetNoMtDirective();
8011 if (IdVal ==
"softfloat")
8012 return parseSetSoftFloatDirective();
8013 if (IdVal ==
"hardfloat")
8014 return parseSetHardFloatDirective();
8016 return parseSetFeature(Mips::FeatureCRC);
8017 if (IdVal ==
"nocrc")
8018 return parseSetNoCRCDirective();
8019 if (IdVal ==
"virt")
8020 return parseSetFeature(Mips::FeatureVirt);
8021 if (IdVal ==
"novirt")
8022 return parseSetNoVirtDirective();
8023 if (IdVal ==
"ginv")
8024 return parseSetFeature(Mips::FeatureGINV);
8025 if (IdVal ==
"noginv")
8026 return parseSetNoGINVDirective();
8029 return parseSetAssignment();
8034bool MipsAsmParser::parseDirectiveGpWord() {
8035 const MCExpr *
Value;
8036 if (getParser().parseExpression(
Value))
8038 getTargetStreamer().emitGPRel32Value(
Value);
8044bool MipsAsmParser::parseDirectiveGpDWord() {
8045 const MCExpr *
Value;
8046 if (getParser().parseExpression(
Value))
8048 getTargetStreamer().emitGPRel64Value(
Value);
8054bool MipsAsmParser::parseDirectiveDtpRelWord() {
8055 const MCExpr *
Value;
8056 if (getParser().parseExpression(
Value))
8058 getTargetStreamer().emitDTPRel32Value(
Value);
8064bool MipsAsmParser::parseDirectiveDtpRelDWord() {
8065 const MCExpr *
Value;
8066 if (getParser().parseExpression(
Value))
8068 getTargetStreamer().emitDTPRel64Value(
Value);
8074bool MipsAsmParser::parseDirectiveTpRelWord() {
8075 const MCExpr *
Value;
8076 if (getParser().parseExpression(
Value))
8078 getTargetStreamer().emitTPRel32Value(
Value);
8084bool MipsAsmParser::parseDirectiveTpRelDWord() {
8085 const MCExpr *
Value;
8086 if (getParser().parseExpression(
Value))
8088 getTargetStreamer().emitTPRel64Value(
Value);
8092bool MipsAsmParser::parseDirectiveOption() {
8093 MCAsmParser &Parser = getParser();
8095 AsmToken Tok = Parser.
getTok();
8099 "unexpected token, expected identifier");
8104 if (Option ==
"pic0") {
8106 IsPicEnabled =
false;
8108 getTargetStreamer().emitDirectiveOptionPic0();
8112 "unexpected token, expected end of statement");
8117 if (Option ==
"pic2") {
8119 IsPicEnabled =
true;
8121 getTargetStreamer().emitDirectiveOptionPic2();
8125 "unexpected token, expected end of statement");
8132 "unknown option, expected 'pic0' or 'pic2'");
8139bool MipsAsmParser::parseInsnDirective() {
8142 reportParseError(
"unexpected token, expected end of statement");
8148 getTargetStreamer().emitDirectiveInsn();
8156bool MipsAsmParser::parseRSectionDirective(StringRef Section) {
8159 reportParseError(
"unexpected token, expected end of statement");
8163 MCSection *ELFSection =
getContext().getELFSection(
8165 getParser().getStreamer().switchSection(ELFSection);
8174bool MipsAsmParser::parseSSectionDirective(StringRef Section,
unsigned Type) {
8177 reportParseError(
"unexpected token, expected end of statement");
8181 MCSection *ELFSection =
getContext().getELFSection(
8183 getParser().getStreamer().switchSection(ELFSection);
8202bool MipsAsmParser::parseDirectiveModule() {
8203 MCAsmParser &Parser = getParser();
8204 AsmLexer &Lexer = getLexer();
8207 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
8209 reportParseError(
".module directive must appear before any code");
8215 reportParseError(
"expected .module option identifier");
8219 if (Option ==
"oddspreg") {
8220 clearModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
8224 getTargetStreamer().updateABIInfo(*
this);
8229 getTargetStreamer().emitDirectiveModuleOddSPReg();
8233 reportParseError(
"unexpected token, expected end of statement");
8238 }
else if (Option ==
"nooddspreg") {
8240 return Error(L,
"'.module nooddspreg' requires the O32 ABI");
8243 setModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
8247 getTargetStreamer().updateABIInfo(*
this);
8252 getTargetStreamer().emitDirectiveModuleOddSPReg();
8256 reportParseError(
"unexpected token, expected end of statement");
8261 }
else if (Option ==
"fp") {
8262 return parseDirectiveModuleFP();
8263 }
else if (Option ==
"softfloat") {
8264 setModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
8268 getTargetStreamer().updateABIInfo(*
this);
8273 getTargetStreamer().emitDirectiveModuleSoftFloat();
8277 reportParseError(
"unexpected token, expected end of statement");
8282 }
else if (Option ==
"hardfloat") {
8283 clearModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
8287 getTargetStreamer().updateABIInfo(*
this);
8292 getTargetStreamer().emitDirectiveModuleHardFloat();
8296 reportParseError(
"unexpected token, expected end of statement");
8301 }
else if (Option ==
"mt") {
8302 setModuleFeatureBits(Mips::FeatureMT,
"mt");
8306 getTargetStreamer().updateABIInfo(*
this);
8311 getTargetStreamer().emitDirectiveModuleMT();
8315 reportParseError(
"unexpected token, expected end of statement");
8320 }
else if (Option ==
"crc") {
8321 setModuleFeatureBits(Mips::FeatureCRC,
"crc");
8325 getTargetStreamer().updateABIInfo(*
this);
8330 getTargetStreamer().emitDirectiveModuleCRC();
8334 reportParseError(
"unexpected token, expected end of statement");
8339 }
else if (Option ==
"nocrc") {
8340 clearModuleFeatureBits(Mips::FeatureCRC,
"crc");
8344 getTargetStreamer().updateABIInfo(*
this);
8349 getTargetStreamer().emitDirectiveModuleNoCRC();
8353 reportParseError(
"unexpected token, expected end of statement");
8358 }
else if (Option ==
"virt") {
8359 setModuleFeatureBits(Mips::FeatureVirt,
"virt");
8363 getTargetStreamer().updateABIInfo(*
this);
8368 getTargetStreamer().emitDirectiveModuleVirt();
8372 reportParseError(
"unexpected token, expected end of statement");
8377 }
else if (Option ==
"novirt") {
8378 clearModuleFeatureBits(Mips::FeatureVirt,
"virt");
8382 getTargetStreamer().updateABIInfo(*
this);
8387 getTargetStreamer().emitDirectiveModuleNoVirt();
8391 reportParseError(
"unexpected token, expected end of statement");
8396 }
else if (Option ==
"ginv") {
8397 setModuleFeatureBits(Mips::FeatureGINV,
"ginv");
8401 getTargetStreamer().updateABIInfo(*
this);
8406 getTargetStreamer().emitDirectiveModuleGINV();
8410 reportParseError(
"unexpected token, expected end of statement");
8415 }
else if (Option ==
"noginv") {
8416 clearModuleFeatureBits(Mips::FeatureGINV,
"ginv");
8420 getTargetStreamer().updateABIInfo(*
this);
8425 getTargetStreamer().emitDirectiveModuleNoGINV();
8429 reportParseError(
"unexpected token, expected end of statement");
8435 return Error(L,
"'" + Twine(Option) +
"' is not a valid .module option.");
8443bool MipsAsmParser::parseDirectiveModuleFP() {
8444 MCAsmParser &Parser = getParser();
8445 AsmLexer &Lexer = getLexer();
8448 reportParseError(
"unexpected token, expected equals sign '='");
8454 if (!parseFpABIValue(FpABI,
".module"))
8458 reportParseError(
"unexpected token, expected end of statement");
8464 getTargetStreamer().updateABIInfo(*
this);
8469 getTargetStreamer().emitDirectiveModuleFP();
8476 StringRef Directive) {
8477 MCAsmParser &Parser = getParser();
8478 AsmLexer &Lexer = getLexer();
8479 bool ModuleLevelOptions = Directive ==
".module";
8485 if (
Value !=
"xx") {
8486 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
8491 reportParseError(
"'" + Directive +
" fp=xx' requires the O32 ABI");
8495 FpABI = MipsABIFlagsSection::FpABIKind::XX;
8496 if (ModuleLevelOptions) {
8497 setModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8498 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8500 setFeatureBits(Mips::FeatureFPXX,
"fpxx");
8501 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8511 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
8517 reportParseError(
"'" + Directive +
" fp=32' requires the O32 ABI");
8521 FpABI = MipsABIFlagsSection::FpABIKind::S32;
8522 if (ModuleLevelOptions) {
8523 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8524 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8526 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
8527 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8530 FpABI = MipsABIFlagsSection::FpABIKind::S64;
8531 if (ModuleLevelOptions) {
8532 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8533 setModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8535 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
8536 setFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8546bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
8552 MCAsmParser &Parser = getParser();
8553 StringRef IDVal = DirectiveID.
getString();
8555 if (IDVal ==
".cpadd") {
8556 parseDirectiveCpAdd(DirectiveID.
getLoc());
8559 if (IDVal ==
".cpload") {
8560 parseDirectiveCpLoad(DirectiveID.
getLoc());
8563 if (IDVal ==
".cprestore") {
8564 parseDirectiveCpRestore(DirectiveID.
getLoc());
8567 if (IDVal ==
".cplocal") {
8568 parseDirectiveCpLocal(DirectiveID.
getLoc());
8571 if (IDVal ==
".ent") {
8575 reportParseError(
"expected identifier after .ent");
8589 reportParseError(
"unexpected token, expected end of statement");
8593 const MCExpr *DummyNumber;
8594 int64_t DummyNumberVal;
8598 reportParseError(
"expected number after comma");
8601 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
8602 reportParseError(
"expected an absolute expression after comma");
8609 reportParseError(
"unexpected token, expected end of statement");
8615 getTargetStreamer().emitDirectiveEnt(*Sym);
8617 IsCpRestoreSet =
false;
8621 if (IDVal ==
".end") {
8625 reportParseError(
"expected identifier after .end");
8630 reportParseError(
"unexpected token, expected end of statement");
8634 if (CurrentFn ==
nullptr) {
8635 reportParseError(
".end used without .ent");
8639 if ((SymbolName != CurrentFn->
getName())) {
8640 reportParseError(
".end symbol does not match .ent symbol");
8644 getTargetStreamer().emitDirectiveEnd(SymbolName);
8645 CurrentFn =
nullptr;
8646 IsCpRestoreSet =
false;
8650 if (IDVal ==
".frame") {
8653 ParseStatus Res = parseAnyRegister(TmpReg);
8655 reportParseError(
"expected stack register");
8659 MipsOperand &StackRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
8660 if (!StackRegOpnd.isGPRAsmReg()) {
8661 reportParseError(StackRegOpnd.getStartLoc(),
8662 "expected general purpose register");
8665 MCRegister StackReg = StackRegOpnd.getGPR32Reg();
8670 reportParseError(
"unexpected token, expected comma");
8675 const MCExpr *FrameSize;
8676 int64_t FrameSizeVal;
8679 reportParseError(
"expected frame size value");
8683 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
8684 reportParseError(
"frame size not an absolute expression");
8691 reportParseError(
"unexpected token, expected comma");
8697 Res = parseAnyRegister(TmpReg);
8699 reportParseError(
"expected return register");
8703 MipsOperand &ReturnRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
8704 if (!ReturnRegOpnd.isGPRAsmReg()) {
8705 reportParseError(ReturnRegOpnd.getStartLoc(),
8706 "expected general purpose register");
8712 reportParseError(
"unexpected token, expected end of statement");
8716 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
8717 ReturnRegOpnd.getGPR32Reg());
8718 IsCpRestoreSet =
false;
8722 if (IDVal ==
".set") {
8723 parseDirectiveSet();
8727 if (IDVal ==
".mask" || IDVal ==
".fmask") {
8738 const MCExpr *BitMask;
8742 reportParseError(
"expected bitmask value");
8746 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
8747 reportParseError(
"bitmask not an absolute expression");
8754 reportParseError(
"unexpected token, expected comma");
8759 const MCExpr *FrameOffset;
8760 int64_t FrameOffsetVal;
8763 reportParseError(
"expected frame offset value");
8767 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
8768 reportParseError(
"frame offset not an absolute expression");
8774 reportParseError(
"unexpected token, expected end of statement");
8778 if (IDVal ==
".mask")
8779 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
8781 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
8785 if (IDVal ==
".nan")
8786 return parseDirectiveNaN();
8788 if (IDVal ==
".gpword") {
8789 parseDirectiveGpWord();
8793 if (IDVal ==
".gpdword") {
8794 parseDirectiveGpDWord();
8798 if (IDVal ==
".dtprelword") {
8799 parseDirectiveDtpRelWord();
8803 if (IDVal ==
".dtpreldword") {
8804 parseDirectiveDtpRelDWord();
8808 if (IDVal ==
".tprelword") {
8809 parseDirectiveTpRelWord();
8813 if (IDVal ==
".tpreldword") {
8814 parseDirectiveTpRelDWord();
8818 if (IDVal ==
".option") {
8819 parseDirectiveOption();
8823 if (IDVal ==
".abicalls") {
8824 getTargetStreamer().emitDirectiveAbiCalls();
8827 "unexpected token, expected end of statement");
8832 if (IDVal ==
".cpsetup") {
8833 parseDirectiveCPSetup();
8836 if (IDVal ==
".cpreturn") {
8837 parseDirectiveCPReturn();
8840 if (IDVal ==
".module") {
8841 parseDirectiveModule();
8844 if (IDVal ==
".llvm_internal_mips_reallow_module_directive") {
8845 parseInternalDirectiveReallowModule();
8848 if (IDVal ==
".insn") {
8849 parseInsnDirective();
8852 if (IDVal ==
".rdata") {
8853 parseRSectionDirective(
".rodata");
8856 if (IDVal ==
".sbss") {
8860 if (IDVal ==
".sdata") {
8868bool MipsAsmParser::parseInternalDirectiveReallowModule() {
8871 reportParseError(
"unexpected token, expected end of statement");
8875 getTargetStreamer().reallowModuleDirective();
8889#define GET_REGISTER_MATCHER
8890#define GET_MATCHER_IMPLEMENTATION
8891#define GET_MNEMONIC_SPELL_CHECKER
8892#include "MipsGenAsmMatcher.inc"
8894bool MipsAsmParser::mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID) {
8896 const MatchEntry *Start, *End;
8897 switch (VariantID) {
8899 case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0);
break;
8902 auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
8903 return MnemonicRange.first != MnemonicRange.second;
static const TargetRegisterClass * getRegClass(const MachineInstr &MI, Register Reg)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
This file declares a class to represent arbitrary precision floating point values and provide a varie...
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Analysis containing CSE Info
#define LLVM_EXTERNAL_VISIBILITY
static Value * expandAbs(CallInst *Orig)
std::pair< Instruction::BinaryOps, Value * > OffsetOp
Find all possible pairs (BinOp, RHS) that BinOp V, RHS can be simplified.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static FeatureBitset getFeatures(MCSubtargetInfo &STI, StringRef CPU, StringRef TuneCPU, StringRef FS, ArrayRef< StringRef > ProcNames, ArrayRef< SubtargetSubTypeKV > ProcDesc, ArrayRef< SubtargetFeatureKV > ProcFeatures)
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,...