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);
4307 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4313 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4317bool MipsAsmParser::expandTrunc(MCInst &Inst,
bool IsDouble,
bool Is64FPU,
4318 SMLoc IDLoc, MCStreamer &Out,
4319 const MCSubtargetInfo *STI) {
4320 MipsTargetStreamer &TOut = getTargetStreamer();
4330 if (hasMips1() && !hasMips2()) {
4331 MCRegister ATReg = getATReg(IDLoc);
4334 TOut.
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4335 TOut.
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4337 TOut.
emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4338 TOut.
emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4339 TOut.
emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4341 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4343 FirstReg, SecondReg, IDLoc, STI);
4344 TOut.
emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4349 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4351 FirstReg, SecondReg, IDLoc, STI);
4356bool MipsAsmParser::expandUlh(MCInst &Inst,
bool Signed, SMLoc IDLoc,
4357 MCStreamer &Out,
const MCSubtargetInfo *STI) {
4358 if (hasMips32r6() || hasMips64r6()) {
4359 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4362 const MCOperand &DstRegOp = Inst.
getOperand(0);
4363 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4364 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4365 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4366 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4367 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4369 MipsTargetStreamer &TOut = getTargetStreamer();
4370 MCRegister DstReg = DstRegOp.
getReg();
4371 MCRegister SrcReg = SrcRegOp.
getReg();
4372 int64_t OffsetValue = OffsetImmOp.
getImm();
4376 warnIfNoMacro(IDLoc);
4377 MCRegister ATReg = getATReg(IDLoc);
4382 if (IsLargeOffset) {
4383 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4388 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4389 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4393 MCRegister FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4394 MCRegister SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4396 MCRegister LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4397 MCRegister SllReg = IsLargeOffset ? DstReg : ATReg;
4399 TOut.
emitRRI(
Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4400 FirstOffset, IDLoc, STI);
4401 TOut.
emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4402 TOut.
emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4403 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4408bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4409 const MCSubtargetInfo *STI) {
4410 if (hasMips32r6() || hasMips64r6()) {
4411 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4414 const MCOperand &DstRegOp = Inst.
getOperand(0);
4415 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4416 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4417 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4418 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4419 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4421 MipsTargetStreamer &TOut = getTargetStreamer();
4422 MCRegister DstReg = DstRegOp.
getReg();
4423 MCRegister SrcReg = SrcRegOp.
getReg();
4424 int64_t OffsetValue = OffsetImmOp.
getImm();
4426 warnIfNoMacro(IDLoc);
4427 MCRegister ATReg = getATReg(IDLoc);
4432 if (IsLargeOffset) {
4433 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4438 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4439 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4443 if (IsLargeOffset) {
4444 TOut.
emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4445 TOut.
emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4446 TOut.
emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4447 TOut.
emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4448 TOut.
emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4449 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4451 TOut.
emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4452 TOut.
emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4453 TOut.
emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4459bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4460 const MCSubtargetInfo *STI) {
4461 if (hasMips32r6() || hasMips64r6()) {
4462 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4465 const MCOperand &DstRegOp = Inst.
getOperand(0);
4466 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4467 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4468 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4469 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4470 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4472 MipsTargetStreamer &TOut = getTargetStreamer();
4473 MCRegister DstReg = DstRegOp.
getReg();
4474 MCRegister SrcReg = SrcRegOp.
getReg();
4475 int64_t OffsetValue = OffsetImmOp.
getImm();
4479 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4480 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4484 bool IsLoadInst = (Inst.
getOpcode() == Mips::Ulw);
4485 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4486 MCRegister TmpReg = SrcReg;
4487 if (IsLargeOffset || DoMove) {
4488 warnIfNoMacro(IDLoc);
4489 TmpReg = getATReg(IDLoc);
4494 if (IsLargeOffset) {
4495 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4503 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4504 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4505 TOut.
emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4506 TOut.
emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4509 TOut.
emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4514bool MipsAsmParser::expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4515 const MCSubtargetInfo *STI) {
4516 MipsTargetStreamer &TOut = getTargetStreamer();
4528 warnIfNoMacro(IDLoc);
4542 TOut.
emitRRR(OpCode, DstReg, SrcReg, OpReg, IDLoc, STI);
4543 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4548bool MipsAsmParser::expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4549 const MCSubtargetInfo *STI) {
4550 MipsTargetStreamer &TOut = getTargetStreamer();
4560 unsigned OpRegCode, OpImmCode;
4562 warnIfNoMacro(IDLoc);
4566 case Mips::SGEImm64:
4567 OpRegCode = Mips::SLT;
4568 OpImmCode = Mips::SLTi;
4571 case Mips::SGEUImm64:
4572 OpRegCode = Mips::SLTu;
4573 OpImmCode = Mips::SLTiu;
4582 TOut.
emitRRI(OpImmCode, DstReg, SrcReg, ImmValue, IDLoc, STI);
4583 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4585 MCRegister ImmReg = DstReg;
4586 if (DstReg == SrcReg) {
4587 MCRegister ATReg = getATReg(Inst.
getLoc());
4593 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
4594 false, IDLoc, Out, STI))
4597 TOut.
emitRRR(OpRegCode, DstReg, SrcReg, ImmReg, IDLoc, STI);
4598 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4604bool MipsAsmParser::expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4605 const MCSubtargetInfo *STI) {
4606 MipsTargetStreamer &TOut = getTargetStreamer();
4615 MCRegister ImmReg = DstReg;
4619 warnIfNoMacro(IDLoc);
4623 case Mips::SGTImm64:
4627 case Mips::SGTUImm64:
4634 if (DstReg == SrcReg) {
4635 MCRegister ATReg = getATReg(Inst.
getLoc());
4641 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
false,
4646 TOut.
emitRRR(OpCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4651bool MipsAsmParser::expandSle(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4652 const MCSubtargetInfo *STI) {
4653 MipsTargetStreamer &TOut = getTargetStreamer();
4665 warnIfNoMacro(IDLoc);
4679 TOut.
emitRRR(OpCode, DstReg, OpReg, SrcReg, IDLoc, STI);
4680 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4685bool MipsAsmParser::expandSleImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4686 const MCSubtargetInfo *STI) {
4687 MipsTargetStreamer &TOut = getTargetStreamer();
4699 warnIfNoMacro(IDLoc);
4703 case Mips::SLEImm64:
4704 OpRegCode = Mips::SLT;
4707 case Mips::SLEUImm64:
4708 OpRegCode = Mips::SLTu;
4715 MCRegister ImmReg = DstReg;
4716 if (DstReg == SrcReg) {
4717 MCRegister ATReg = getATReg(Inst.
getLoc());
4723 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
false,
4727 TOut.
emitRRR(OpRegCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4728 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4733bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
4735 const MCSubtargetInfo *STI) {
4736 MipsTargetStreamer &TOut = getTargetStreamer();
4744 MCRegister FinalDstReg;
4751 unsigned FinalOpcode = Inst.
getOpcode();
4753 if (DstReg == SrcReg) {
4754 ATReg = getATReg(Inst.
getLoc());
4757 FinalDstReg = DstReg;
4761 if (!loadImmediate(ImmValue, DstReg, MCRegister(), Is32Bit,
false,
4762 Inst.
getLoc(), Out, STI)) {
4763 switch (FinalOpcode) {
4767 FinalOpcode = Mips::ADD;
4770 FinalOpcode = Mips::ADDu;
4773 FinalOpcode = Mips::AND;
4776 FinalOpcode = Mips::NOR;
4779 FinalOpcode = Mips::OR;
4782 FinalOpcode = Mips::SLT;
4785 FinalOpcode = Mips::SLTu;
4788 FinalOpcode = Mips::XOR;
4791 FinalOpcode = Mips::ADD_MM;
4793 case Mips::ADDiu_MM:
4794 FinalOpcode = Mips::ADDu_MM;
4797 FinalOpcode = Mips::AND_MM;
4800 FinalOpcode = Mips::OR_MM;
4803 FinalOpcode = Mips::SLT_MM;
4805 case Mips::SLTiu_MM:
4806 FinalOpcode = Mips::SLTu_MM;
4809 FinalOpcode = Mips::XOR_MM;
4812 FinalOpcode = Mips::AND64;
4814 case Mips::NORImm64:
4815 FinalOpcode = Mips::NOR64;
4818 FinalOpcode = Mips::OR64;
4820 case Mips::SLTImm64:
4821 FinalOpcode = Mips::SLT64;
4823 case Mips::SLTUImm64:
4824 FinalOpcode = Mips::SLTu64;
4827 FinalOpcode = Mips::XOR64;
4832 TOut.
emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4834 TOut.
emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4840bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4841 const MCSubtargetInfo *STI) {
4842 MipsTargetStreamer &TOut = getTargetStreamer();
4847 MCRegister TmpReg =
DReg;
4849 unsigned FirstShift = Mips::NOP;
4850 unsigned SecondShift = Mips::NOP;
4852 if (hasMips32r2()) {
4854 TmpReg = getATReg(Inst.
getLoc());
4860 TOut.
emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4861 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
4866 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
4878 FirstShift = Mips::SRLV;
4879 SecondShift = Mips::SLLV;
4882 FirstShift = Mips::SLLV;
4883 SecondShift = Mips::SRLV;
4887 ATReg = getATReg(Inst.
getLoc());
4891 TOut.
emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4892 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
4893 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
4894 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
4902bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
4904 const MCSubtargetInfo *STI) {
4905 MipsTargetStreamer &TOut = getTargetStreamer();
4911 unsigned FirstShift = Mips::NOP;
4912 unsigned SecondShift = Mips::NOP;
4914 if (hasMips32r2()) {
4916 uint64_t MaxShift = 32;
4917 uint64_t ShiftValue = ImmValue;
4919 ShiftValue = MaxShift - ImmValue;
4920 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
4925 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.
getLoc(), STI);
4933 if (ImmValue == 0) {
4942 FirstShift = Mips::SLL;
4943 SecondShift = Mips::SRL;
4946 FirstShift = Mips::SRL;
4947 SecondShift = Mips::SLL;
4951 ATReg = getATReg(Inst.
getLoc());
4955 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.
getLoc(), STI);
4956 TOut.
emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.
getLoc(), STI);
4957 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
4965bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4966 const MCSubtargetInfo *STI) {
4967 MipsTargetStreamer &TOut = getTargetStreamer();
4972 MCRegister TmpReg =
DReg;
4974 unsigned FirstShift = Mips::NOP;
4975 unsigned SecondShift = Mips::NOP;
4977 if (hasMips64r2()) {
4978 if (TmpReg == SReg) {
4979 TmpReg = getATReg(Inst.
getLoc());
4985 TOut.
emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4986 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
4991 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
5003 FirstShift = Mips::DSRLV;
5004 SecondShift = Mips::DSLLV;
5007 FirstShift = Mips::DSLLV;
5008 SecondShift = Mips::DSRLV;
5012 ATReg = getATReg(Inst.
getLoc());
5016 TOut.
emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
5017 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
5018 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
5019 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5027bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
5029 const MCSubtargetInfo *STI) {
5030 MipsTargetStreamer &TOut = getTargetStreamer();
5036 unsigned FirstShift = Mips::NOP;
5037 unsigned SecondShift = Mips::NOP;
5041 if (hasMips64r2()) {
5042 unsigned FinalOpcode = Mips::NOP;
5044 FinalOpcode = Mips::DROTR;
5045 else if (ImmValue % 32 == 0)
5046 FinalOpcode = Mips::DROTR32;
5047 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
5049 FinalOpcode = Mips::DROTR32;
5051 FinalOpcode = Mips::DROTR;
5052 }
else if (ImmValue >= 33) {
5054 FinalOpcode = Mips::DROTR;
5056 FinalOpcode = Mips::DROTR32;
5059 uint64_t ShiftValue = ImmValue % 32;
5061 ShiftValue = (32 - ImmValue % 32) % 32;
5063 TOut.
emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
5069 if (ImmValue == 0) {
5070 TOut.
emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.
getLoc(), STI);
5078 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5079 FirstShift = Mips::DSLL;
5080 SecondShift = Mips::DSRL32;
5082 if (ImmValue == 32) {
5083 FirstShift = Mips::DSLL32;
5084 SecondShift = Mips::DSRL32;
5086 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5087 FirstShift = Mips::DSLL32;
5088 SecondShift = Mips::DSRL;
5092 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5093 FirstShift = Mips::DSRL;
5094 SecondShift = Mips::DSLL32;
5096 if (ImmValue == 32) {
5097 FirstShift = Mips::DSRL32;
5098 SecondShift = Mips::DSLL32;
5100 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5101 FirstShift = Mips::DSRL32;
5102 SecondShift = Mips::DSLL;
5107 ATReg = getATReg(Inst.
getLoc());
5111 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.
getLoc(), STI);
5112 TOut.
emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
5114 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5122bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5123 const MCSubtargetInfo *STI) {
5124 MipsTargetStreamer &TOut = getTargetStreamer();
5128 TOut.
emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
5129 if (FirstRegOp != SecondRegOp)
5130 TOut.
emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
5133 TOut.
emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
5138bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5139 const MCSubtargetInfo *STI) {
5140 MipsTargetStreamer &TOut = getTargetStreamer();
5146 ATReg = getATReg(IDLoc);
5150 loadImmediate(ImmValue, ATReg, MCRegister(),
true,
false, IDLoc, Out, STI);
5152 TOut.
emitRR(Inst.
getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
5153 SrcReg, ATReg, IDLoc, STI);
5155 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5160bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5161 const MCSubtargetInfo *STI) {
5162 MipsTargetStreamer &TOut = getTargetStreamer();
5168 ATReg = getATReg(Inst.
getLoc());
5172 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
5173 SrcReg, TmpReg, IDLoc, STI);
5175 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5177 TOut.
emitRRI(Inst.
getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
5178 DstReg, DstReg, 0x1F, IDLoc, STI);
5180 TOut.
emitR(Mips::MFHI, ATReg, IDLoc, STI);
5183 TOut.
emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
5190 TOut.
emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
5191 if (AssemblerOptions.
back()->isReorder())
5193 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5197 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5202bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5203 const MCSubtargetInfo *STI) {
5204 MipsTargetStreamer &TOut = getTargetStreamer();
5210 ATReg = getATReg(IDLoc);
5214 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
5215 SrcReg, TmpReg, IDLoc, STI);
5217 TOut.
emitR(Mips::MFHI, ATReg, IDLoc, STI);
5218 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5220 TOut.
emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);
5227 TOut.
emitRRX(Mips::BEQ, ATReg, Mips::ZERO, LabelOp, IDLoc, STI);
5228 if (AssemblerOptions.
back()->isReorder())
5230 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5238bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5239 const MCSubtargetInfo *STI) {
5240 MipsTargetStreamer &TOut = getTargetStreamer();
5245 TOut.
emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
5246 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5256bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
5258 const MCSubtargetInfo *STI,
5263 warnIfNoMacro(IDLoc);
5265 MipsTargetStreamer &TOut = getTargetStreamer();
5266 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
5268 MCRegister SecondReg =
nextReg(FirstReg);
5273 warnIfRegIndexIsAT(FirstReg, IDLoc);
5276 "Offset for load macro is not immediate!");
5279 signed NextOffset = FirstOffset.
getImm() + 4;
5287 if (FirstReg != BaseReg || !IsLoad) {
5288 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5289 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5291 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5292 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5304bool MipsAsmParser::expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc,
5306 const MCSubtargetInfo *STI) {
5310 warnIfNoMacro(IDLoc);
5312 MipsTargetStreamer &TOut = getTargetStreamer();
5313 unsigned Opcode = Mips::SWC1;
5315 MCRegister SecondReg =
nextReg(FirstReg);
5320 warnIfRegIndexIsAT(FirstReg, IDLoc);
5323 "Offset for macro is not immediate!");
5326 signed NextOffset = FirstOffset.
getImm() + 4;
5332 if (!IsLittleEndian)
5335 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5336 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5341bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5342 const MCSubtargetInfo *STI) {
5343 MipsTargetStreamer &TOut = getTargetStreamer();
5354 warnIfNoMacro(IDLoc);
5356 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5357 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5358 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5362 MCRegister
Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5363 TOut.
emitRRI(Mips::SLTiu, DstReg,
Reg, 1, IDLoc, STI);
5367bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5368 const MCSubtargetInfo *STI) {
5369 MipsTargetStreamer &TOut = getTargetStreamer();
5380 warnIfNoMacro(IDLoc);
5383 TOut.
emitRRI(Mips::SLTiu, DstReg, SrcReg, 1, IDLoc, STI);
5387 if (SrcReg == Mips::ZERO) {
5388 Warning(IDLoc,
"comparison is always false");
5389 TOut.
emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
5390 DstReg, SrcReg, SrcReg, IDLoc, STI);
5395 if (Imm > -0x8000 && Imm < 0) {
5397 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5403 MCRegister ATReg = getATReg(IDLoc);
5407 if (loadImmediate(Imm, ATReg, MCRegister(),
true, isGP64bit(), IDLoc, Out,
5411 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5412 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5416 TOut.
emitRRI(
Opc, DstReg, SrcReg, Imm, IDLoc, STI);
5417 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5421bool MipsAsmParser::expandSne(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5422 const MCSubtargetInfo *STI) {
5424 MipsTargetStreamer &TOut = getTargetStreamer();
5435 warnIfNoMacro(IDLoc);
5437 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5438 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5439 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5443 MCRegister
Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5444 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO,
Reg, IDLoc, STI);
5448bool MipsAsmParser::expandSneI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5449 const MCSubtargetInfo *STI) {
5450 MipsTargetStreamer &TOut = getTargetStreamer();
5461 warnIfNoMacro(IDLoc);
5463 if (ImmValue == 0) {
5464 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, SrcReg, IDLoc, STI);
5468 if (SrcReg == Mips::ZERO) {
5469 Warning(IDLoc,
"comparison is always true");
5470 if (loadImmediate(1, DstReg, MCRegister(),
true,
false, IDLoc, Out, STI))
5476 if (ImmValue > -0x8000 && ImmValue < 0) {
5477 ImmValue = -ImmValue;
5478 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5484 TOut.
emitRRI(
Opc, DstReg, SrcReg, ImmValue, IDLoc, STI);
5485 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5489 MCRegister ATReg = getATReg(IDLoc);
5493 if (loadImmediate(ImmValue, ATReg, MCRegister(),
isInt<32>(ImmValue),
false,
5497 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5498 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5561 case Mips::F0:
return Mips::ZERO;
5562 case Mips::F1:
return Mips::AT;
5563 case Mips::F2:
return Mips::V0;
5564 case Mips::F3:
return Mips::V1;
5565 case Mips::F4:
return Mips::A0;
5566 case Mips::F5:
return Mips::A1;
5567 case Mips::F6:
return Mips::A2;
5568 case Mips::F7:
return Mips::A3;
5569 case Mips::F8:
return Mips::T0;
5570 case Mips::F9:
return Mips::T1;
5571 case Mips::F10:
return Mips::T2;
5572 case Mips::F11:
return Mips::T3;
5573 case Mips::F12:
return Mips::T4;
5574 case Mips::F13:
return Mips::T5;
5575 case Mips::F14:
return Mips::T6;
5576 case Mips::F15:
return Mips::T7;
5577 case Mips::F16:
return Mips::S0;
5578 case Mips::F17:
return Mips::S1;
5579 case Mips::F18:
return Mips::S2;
5580 case Mips::F19:
return Mips::S3;
5581 case Mips::F20:
return Mips::S4;
5582 case Mips::F21:
return Mips::S5;
5583 case Mips::F22:
return Mips::S6;
5584 case Mips::F23:
return Mips::S7;
5585 case Mips::F24:
return Mips::T8;
5586 case Mips::F25:
return Mips::T9;
5587 case Mips::F26:
return Mips::K0;
5588 case Mips::F27:
return Mips::K1;
5589 case Mips::F28:
return Mips::GP;
5590 case Mips::F29:
return Mips::SP;
5591 case Mips::F30:
return Mips::FP;
5592 case Mips::F31:
return Mips::RA;
5600 case Mips::COP00:
return Mips::ZERO;
5601 case Mips::COP01:
return Mips::AT;
5602 case Mips::COP02:
return Mips::V0;
5603 case Mips::COP03:
return Mips::V1;
5604 case Mips::COP04:
return Mips::A0;
5605 case Mips::COP05:
return Mips::A1;
5606 case Mips::COP06:
return Mips::A2;
5607 case Mips::COP07:
return Mips::A3;
5608 case Mips::COP08:
return Mips::T0;
5609 case Mips::COP09:
return Mips::T1;
5610 case Mips::COP010:
return Mips::T2;
5611 case Mips::COP011:
return Mips::T3;
5612 case Mips::COP012:
return Mips::T4;
5613 case Mips::COP013:
return Mips::T5;
5614 case Mips::COP014:
return Mips::T6;
5615 case Mips::COP015:
return Mips::T7;
5616 case Mips::COP016:
return Mips::S0;
5617 case Mips::COP017:
return Mips::S1;
5618 case Mips::COP018:
return Mips::S2;
5619 case Mips::COP019:
return Mips::S3;
5620 case Mips::COP020:
return Mips::S4;
5621 case Mips::COP021:
return Mips::S5;
5622 case Mips::COP022:
return Mips::S6;
5623 case Mips::COP023:
return Mips::S7;
5624 case Mips::COP024:
return Mips::T8;
5625 case Mips::COP025:
return Mips::T9;
5626 case Mips::COP026:
return Mips::K0;
5627 case Mips::COP027:
return Mips::K1;
5628 case Mips::COP028:
return Mips::GP;
5629 case Mips::COP029:
return Mips::SP;
5630 case Mips::COP030:
return Mips::FP;
5631 case Mips::COP031:
return Mips::RA;
5638bool MipsAsmParser::expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5639 const MCSubtargetInfo *STI) {
5640 MipsTargetStreamer &TOut = getTargetStreamer();
5645 bool IsMFTR =
false;
5699 IsMFTR ? MCRegister(rd)
5701 : Inst.getOperand(0).
getReg());
5703 TOut.
emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, u, sel, h, IDLoc,
5708bool MipsAsmParser::expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5709 const MCSubtargetInfo *STI) {
5714 warnIfNoMacro(IDLoc);
5716 MipsTargetStreamer &TOut = getTargetStreamer();
5717 unsigned Opcode = Inst.
getOpcode() == Mips::SaaAddr ? Mips::SAA : Mips::SAAD;
5720 const MCOperand &BaseOp = Inst.
getOperand(2);
5722 if (BaseOp.
isImm()) {
5723 int64_t ImmValue = BaseOp.
getImm();
5724 if (ImmValue == 0) {
5725 TOut.
emitRR(Opcode, RtReg, BaseReg, IDLoc, STI);
5730 MCRegister ATReg = getATReg(IDLoc);
5734 if (expandLoadAddress(ATReg, BaseReg, BaseOp, !isGP64bit(), IDLoc, Out, STI))
5737 TOut.
emitRR(Opcode, RtReg, ATReg, IDLoc, STI);
5742MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
5746 return Match_Success;
5749 if (
static_cast<MipsOperand &
>(*Operands[1])
5750 .isValidForTie(
static_cast<MipsOperand &
>(*Operands[2])))
5751 return Match_Success;
5752 return Match_RequiresSameSrcAndDst;
5756unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
5763 return Match_RequiresNoZeroRegister;
5764 return Match_Success;
5770 case Mips::JALR_HB64:
5771 case Mips::JALRC_HB_MMR6:
5772 case Mips::JALRC_MMR6:
5774 return Match_RequiresDifferentSrcAndDst;
5775 return Match_Success;
5778 return Match_RequiresDifferentSrcAndDst;
5779 return Match_Success;
5782 return Match_NonZeroOperandForSync;
5783 return Match_Success;
5789 return Match_NonZeroOperandForMTCX;
5790 return Match_Success;
5803 case Mips::BLEZC:
case Mips::BLEZC_MMR6:
5804 case Mips::BGEZC:
case Mips::BGEZC_MMR6:
5805 case Mips::BGTZC:
case Mips::BGTZC_MMR6:
5806 case Mips::BLTZC:
case Mips::BLTZC_MMR6:
5807 case Mips::BEQZC:
case Mips::BEQZC_MMR6:
5808 case Mips::BNEZC:
case Mips::BNEZC_MMR6:
5817 return Match_RequiresNoZeroRegister;
5818 return Match_Success;
5819 case Mips::BGEC:
case Mips::BGEC_MMR6:
5820 case Mips::BLTC:
case Mips::BLTC_MMR6:
5821 case Mips::BGEUC:
case Mips::BGEUC_MMR6:
5822 case Mips::BLTUC:
case Mips::BLTUC_MMR6:
5823 case Mips::BEQC:
case Mips::BEQC_MMR6:
5824 case Mips::BNEC:
case Mips::BNEC_MMR6:
5833 return Match_RequiresNoZeroRegister;
5836 return Match_RequiresNoZeroRegister;
5838 return Match_RequiresDifferentOperands;
5839 return Match_Success;
5842 "Operands must be immediates for dins!");
5845 if ((0 > (Pos +
Size)) || ((Pos +
Size) > 32))
5846 return Match_RequiresPosSizeRange0_32;
5847 return Match_Success;
5852 "Operands must be immediates for dinsm/dinsu!");
5855 if ((32 >= (Pos +
Size)) || ((Pos +
Size) > 64))
5856 return Match_RequiresPosSizeRange33_64;
5857 return Match_Success;
5861 "Operands must be immediates for DEXTM!");
5864 if ((1 > (Pos +
Size)) || ((Pos +
Size) > 63))
5865 return Match_RequiresPosSizeUImm6;
5866 return Match_Success;
5871 "Operands must be immediates for dextm/dextu!");
5874 if ((32 > (Pos +
Size)) || ((Pos +
Size) > 64))
5875 return Match_RequiresPosSizeRange33_64;
5876 return Match_Success;
5878 case Mips::CRC32B:
case Mips::CRC32CB:
5879 case Mips::CRC32H:
case Mips::CRC32CH:
5880 case Mips::CRC32W:
case Mips::CRC32CW:
5881 case Mips::CRC32D:
case Mips::CRC32CD:
5883 return Match_RequiresSameSrcAndDst;
5884 return Match_Success;
5887 uint64_t TSFlags = MII.get(Inst.
getOpcode()).TSFlags;
5890 return Match_NoFCCRegisterForCurrentISA;
5892 return Match_Success;
5900 if (ErrorLoc ==
SMLoc())
5907bool MipsAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
5910 uint64_t &ErrorInfo,
5911 bool MatchingInlineAsm) {
5913 unsigned MatchResult =
5914 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
5916 switch (MatchResult) {
5918 if (processInstruction(Inst, IDLoc, Out, STI))
5921 case Match_MissingFeature:
5922 Error(IDLoc,
"instruction requires a CPU feature not currently enabled");
5924 case Match_InvalidTiedOperand:
5925 Error(IDLoc,
"operand must match destination register");
5927 case Match_InvalidOperand: {
5928 SMLoc ErrorLoc = IDLoc;
5929 if (ErrorInfo != ~0ULL) {
5930 if (ErrorInfo >= Operands.
size())
5931 return Error(IDLoc,
"too few operands for instruction");
5933 ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5934 if (ErrorLoc == SMLoc())
5938 return Error(ErrorLoc,
"invalid operand for instruction");
5940 case Match_NonZeroOperandForSync:
5942 "s-type must be zero or unspecified for pre-MIPS32 ISAs");
5943 case Match_NonZeroOperandForMTCX:
5944 return Error(IDLoc,
"selector must be zero for pre-MIPS32 ISAs");
5945 case Match_MnemonicFail:
5946 return Error(IDLoc,
"invalid instruction");
5947 case Match_RequiresDifferentSrcAndDst:
5948 return Error(IDLoc,
"source and destination must be different");
5949 case Match_RequiresDifferentOperands:
5950 return Error(IDLoc,
"registers must be different");
5951 case Match_RequiresNoZeroRegister:
5952 return Error(IDLoc,
"invalid operand ($zero) for instruction");
5953 case Match_RequiresSameSrcAndDst:
5954 return Error(IDLoc,
"source and destination must match");
5955 case Match_NoFCCRegisterForCurrentISA:
5957 "non-zero fcc register doesn't exist in current ISA level");
5962 "expected 1-bit unsigned immediate");
5965 "expected 2-bit unsigned immediate");
5968 "expected immediate in range 1 .. 4");
5971 "expected 3-bit unsigned immediate");
5974 "expected 4-bit unsigned immediate");
5977 "expected 4-bit signed immediate");
5980 "expected 5-bit unsigned immediate");
5983 "expected 5-bit signed immediate");
5986 "expected immediate in range 1 .. 32");
5987 case Match_UImm5_32:
5989 "expected immediate in range 32 .. 63");
5990 case Match_UImm5_33:
5992 "expected immediate in range 33 .. 64");
5993 case Match_UImm5_0_Report_UImm6:
5997 "expected 6-bit unsigned immediate");
5998 case Match_UImm5_Lsl2:
6000 "expected both 7-bit unsigned immediate and multiple of 4");
6001 case Match_UImmRange2_64:
6003 "expected immediate in range 2 .. 64");
6006 "expected 6-bit unsigned immediate");
6007 case Match_UImm6_Lsl2:
6009 "expected both 8-bit unsigned immediate and multiple of 4");
6012 "expected 6-bit signed immediate");
6015 "expected 7-bit unsigned immediate");
6016 case Match_UImm7_N1:
6018 "expected immediate in range -1 .. 126");
6019 case Match_SImm7_Lsl2:
6021 "expected both 9-bit signed immediate and multiple of 4");
6024 "expected 8-bit unsigned immediate");
6025 case Match_UImm10_0:
6027 "expected 10-bit unsigned immediate");
6028 case Match_SImm10_0:
6030 "expected 10-bit signed immediate");
6031 case Match_SImm11_0:
6033 "expected 11-bit signed immediate");
6035 case Match_UImm16_Relaxed:
6036 case Match_UImm16_AltRelaxed:
6038 "expected 16-bit unsigned immediate");
6040 case Match_SImm16_Relaxed:
6042 "expected 16-bit signed immediate");
6043 case Match_SImm19_Lsl2:
6045 "expected both 19-bit signed immediate and multiple of 4");
6046 case Match_UImm20_0:
6048 "expected 20-bit unsigned immediate");
6049 case Match_UImm26_0:
6051 "expected 26-bit unsigned immediate");
6053 case Match_SImm32_Relaxed:
6055 "expected 32-bit signed immediate");
6056 case Match_UImm32_Coerced:
6058 "expected 32-bit immediate");
6059 case Match_MemSImm9:
6061 "expected memory with 9-bit signed offset");
6062 case Match_MemSImm10:
6064 "expected memory with 10-bit signed offset");
6065 case Match_MemSImm10Lsl1:
6067 "expected memory with 11-bit signed offset and multiple of 2");
6068 case Match_MemSImm10Lsl2:
6070 "expected memory with 12-bit signed offset and multiple of 4");
6071 case Match_MemSImm10Lsl3:
6073 "expected memory with 13-bit signed offset and multiple of 8");
6074 case Match_MemSImm11:
6076 "expected memory with 11-bit signed offset");
6077 case Match_MemSImm12:
6079 "expected memory with 12-bit signed offset");
6080 case Match_MemSImm16:
6082 "expected memory with 16-bit signed offset");
6083 case Match_MemSImmPtr:
6085 "expected memory with 32-bit signed offset");
6086 case Match_RequiresPosSizeRange0_32: {
6087 SMLoc ErrorStart = Operands[3]->getStartLoc();
6088 SMLoc ErrorEnd = Operands[4]->getEndLoc();
6089 return Error(ErrorStart,
"size plus position are not in the range 0 .. 32",
6090 SMRange(ErrorStart, ErrorEnd));
6092 case Match_RequiresPosSizeUImm6: {
6093 SMLoc ErrorStart = Operands[3]->getStartLoc();
6094 SMLoc ErrorEnd = Operands[4]->getEndLoc();
6095 return Error(ErrorStart,
"size plus position are not in the range 1 .. 63",
6096 SMRange(ErrorStart, ErrorEnd));
6098 case Match_RequiresPosSizeRange33_64: {
6099 SMLoc ErrorStart = Operands[3]->getStartLoc();
6100 SMLoc ErrorEnd = Operands[4]->getEndLoc();
6101 return Error(ErrorStart,
"size plus position are not in the range 33 .. 64",
6102 SMRange(ErrorStart, ErrorEnd));
6109void MipsAsmParser::warnIfRegIndexIsAT(MCRegister RegIndex, SMLoc Loc) {
6110 if (RegIndex && AssemblerOptions.
back()->getATRegIndex() == RegIndex)
6111 Warning(Loc,
"used $at (currently $" + Twine(RegIndex.
id()) +
6112 ") without \".set noat\"");
6115void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
6116 if (!AssemblerOptions.
back()->isMacro())
6117 Warning(Loc,
"macro instruction expanded into multiple instructions");
6120void MipsAsmParser::ConvertXWPOperands(MCInst &Inst,
6124 "Unexpected instruction!");
6125 ((MipsOperand &)*Operands[1]).addGPR32ZeroAsmRegOperands(Inst, 1);
6126 MCRegister NextReg =
nextReg(((MipsOperand &)*Operands[1]).getGPR32Reg());
6128 ((MipsOperand &)*Operands[2]).addMemOperands(Inst, 2);
6132MipsAsmParser::printWarningWithFixIt(
const Twine &Msg,
const Twine &FixMsg,
6133 SMRange
Range,
bool ShowColors) {
6139int MipsAsmParser::matchCPURegisterName(StringRef Name) {
6142 CC = StringSwitch<unsigned>(Name)
6144 .Cases({
"at",
"AT"}, 1)
6178 if (!(isABI_N32() || isABI_N64()))
6181 if (12 <= CC && CC <= 15) {
6183 AsmToken RegTok = getLexer().peekTok();
6186 StringRef FixedName = StringSwitch<StringRef>(Name)
6192 assert(FixedName !=
"" &&
"Register name is not one of t4-t7.");
6194 printWarningWithFixIt(
"register names $t4-$t7 are only available in O32.",
6195 "Did you mean $" + FixedName +
"?", RegRange);
6201 if (8 <= CC && CC <= 11)
6205 CC = StringSwitch<unsigned>(Name)
6217int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
6220 CC = StringSwitch<unsigned>(Name)
6221 .Case(
"hwr_cpunum", 0)
6222 .Case(
"hwr_synci_step", 1)
6224 .Case(
"hwr_ccres", 3)
6225 .Case(
"hwr_ulr", 29)
6231int MipsAsmParser::matchFPURegisterName(StringRef Name) {
6232 if (Name[0] ==
'f') {
6233 StringRef NumString =
Name.substr(1);
6244int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
6245 if (
Name.starts_with(
"fcc")) {
6246 StringRef NumString =
Name.substr(3);
6257int MipsAsmParser::matchACRegisterName(StringRef Name) {
6258 if (
Name.starts_with(
"ac")) {
6259 StringRef NumString =
Name.substr(2);
6270int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
6273 if (
Name.front() !=
'w' ||
Name.drop_front(1).getAsInteger(10, IntVal))
6282int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
6285 CC = StringSwitch<unsigned>(Name)
6288 .Case(
"msaaccess", 2)
6290 .Case(
"msamodify", 4)
6291 .Case(
"msarequest", 5)
6293 .Case(
"msaunmap", 7)
6299bool MipsAsmParser::canUseATReg() {
6300 return AssemblerOptions.
back()->getATRegIndex() != 0;
6303MCRegister MipsAsmParser::getATReg(SMLoc Loc) {
6304 unsigned ATIndex = AssemblerOptions.
back()->getATRegIndex();
6306 reportParseError(Loc,
6307 "pseudo-instruction requires $at, which is not available");
6311 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
6315MCRegister MipsAsmParser::getReg(
int RC,
int RegNo) {
6316 return getContext().getRegisterInfo()->getRegClass(RC).getRegister(RegNo);
6322const MCExpr *MipsAsmParser::parseRelocExpr() {
6323 auto getOp = [](StringRef
Op) {
6324 return StringSwitch<Mips::Specifier>(
Op)
6352 MCAsmParser &Parser = getParser();
6354 const MCExpr *Res =
nullptr;
6360 auto Op = getOp(Name);
6369 while (
Ops.size()) {
6377bool MipsAsmParser::parseOperand(
OperandVector &Operands, StringRef Mnemonic) {
6378 MCAsmParser &Parser = getParser();
6388 ParseStatus Res = MatchOperandParserImpl(Operands, Mnemonic,
true);
6399 switch (getLexer().getKind()) {
6409 if (!parseAnyRegister(Operands).isNoMatch())
6422 Operands.
push_back(MipsOperand::CreateImm(SymRef, S,
E, *
this));
6427 const MCExpr *Expr = parseRelocExpr();
6431 Operands.
push_back(MipsOperand::CreateImm(Expr, S,
E, *
this));
6438bool MipsAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
6440 return !tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess();
6443ParseStatus MipsAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
6446 ParseStatus Res = parseAnyRegister(Operands);
6449 MipsOperand &Operand =
static_cast<MipsOperand &
>(*Operands.
front());
6450 StartLoc = Operand.getStartLoc();
6451 EndLoc = Operand.getEndLoc();
6457 if (Operand.isGPRAsmReg()) {
6459 Reg = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
6469ParseStatus MipsAsmParser::parseMemOperand(
OperandVector &Operands) {
6470 MCAsmParser &Parser = getParser();
6472 const MCExpr *IdVal =
nullptr;
6474 bool isParenExpr =
false;
6485 IdVal = parseRelocExpr();
6491 const AsmToken &Tok = Parser.
getTok();
6493 MipsOperand &Mnemonic =
static_cast<MipsOperand &
>(*Operands[0]);
6494 if (Mnemonic.getToken() ==
"la" || Mnemonic.getToken() ==
"dla") {
6497 Operands.
push_back(MipsOperand::CreateImm(IdVal, S,
E, *
this));
6506 auto Base = MipsOperand::createGPRReg(
6507 0,
"0",
getContext().getRegisterInfo(), S,
E, *
this);
6509 MipsOperand::CreateMem(std::move(
Base), IdVal, S,
E, *
this));
6561 const MCExpr * NextExpr;
6562 if (getParser().parseExpression(NextExpr))
6570 Res = parseAnyRegister(Operands);
6585 std::unique_ptr<MipsOperand>
op(
6586 static_cast<MipsOperand *
>(Operands.
back().release()));
6593 if (IdVal->evaluateAsAbsolute(Imm))
6600 Operands.
push_back(MipsOperand::CreateMem(std::move(
op), IdVal, S,
E, *
this));
6604bool MipsAsmParser::searchSymbolAlias(
OperandVector &Operands) {
6605 MCAsmParser &Parser = getParser();
6614 const MCSymbolRefExpr *
Ref =
static_cast<const MCSymbolRefExpr *
>(Expr);
6615 StringRef DefSymbol =
Ref->getSymbol().getName();
6618 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.
substr(1), S);
6632 if (Entry != RegisterSets.
end()) {
6634 matchAnyRegisterWithoutDollar(Operands,
Entry->getValue(), S);
6645ParseStatus MipsAsmParser::matchAnyRegisterNameWithoutDollar(
6647 int Index = matchCPURegisterName(Identifier);
6649 Operands.
push_back(MipsOperand::createGPRReg(
6650 Index, Identifier,
getContext().getRegisterInfo(), S,
6651 getLexer().getLoc(), *
this));
6655 Index = matchHWRegsRegisterName(Identifier);
6657 Operands.
push_back(MipsOperand::createHWRegsReg(
6658 Index, Identifier,
getContext().getRegisterInfo(), S,
6659 getLexer().getLoc(), *
this));
6663 Index = matchFPURegisterName(Identifier);
6665 Operands.
push_back(MipsOperand::createFGRReg(
6666 Index, Identifier,
getContext().getRegisterInfo(), S,
6667 getLexer().getLoc(), *
this));
6671 Index = matchFCCRegisterName(Identifier);
6673 Operands.
push_back(MipsOperand::createFCCReg(
6674 Index, Identifier,
getContext().getRegisterInfo(), S,
6675 getLexer().getLoc(), *
this));
6679 Index = matchACRegisterName(Identifier);
6681 Operands.
push_back(MipsOperand::createACCReg(
6682 Index, Identifier,
getContext().getRegisterInfo(), S,
6683 getLexer().getLoc(), *
this));
6687 Index = matchMSA128RegisterName(Identifier);
6689 Operands.
push_back(MipsOperand::createMSA128Reg(
6690 Index, Identifier,
getContext().getRegisterInfo(), S,
6691 getLexer().getLoc(), *
this));
6695 Index = matchMSA128CtrlRegisterName(Identifier);
6697 Operands.
push_back(MipsOperand::createMSACtrlReg(
6698 Index, Identifier,
getContext().getRegisterInfo(), S,
6699 getLexer().getLoc(), *
this));
6707MipsAsmParser::matchAnyRegisterWithoutDollar(
OperandVector &Operands,
6708 const AsmToken &Token, SMLoc S) {
6712 return matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
6717 if (RegNum < 0 || RegNum > 31) {
6721 Error(getLexer().getLoc(),
"invalid register number");
6723 Operands.
push_back(MipsOperand::createNumericReg(
6735MipsAsmParser::matchAnyRegisterWithoutDollar(
OperandVector &Operands, SMLoc S) {
6736 auto Token = getLexer().peekTok(
false);
6737 return matchAnyRegisterWithoutDollar(Operands, Token, S);
6740ParseStatus MipsAsmParser::parseAnyRegister(
OperandVector &Operands) {
6741 MCAsmParser &Parser = getParser();
6744 auto Token = Parser.
getTok();
6746 SMLoc S = Token.
getLoc();
6751 if (searchSymbolAlias(Operands))
6759 ParseStatus Res = matchAnyRegisterWithoutDollar(Operands, S);
6767ParseStatus MipsAsmParser::parseJumpTarget(
OperandVector &Operands) {
6768 MCAsmParser &Parser = getParser();
6771 SMLoc S = getLexer().getLoc();
6774 ParseStatus Res = parseAnyRegister(Operands);
6779 const MCExpr *Expr =
nullptr;
6785 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *
this));
6789ParseStatus MipsAsmParser::parseInvNum(
OperandVector &Operands) {
6790 MCAsmParser &Parser = getParser();
6791 const MCExpr *IdVal;
6802 if (getParser().parseExpression(IdVal))
6809 Operands.
push_back(MipsOperand::CreateImm(
6814ParseStatus MipsAsmParser::parseRegisterList(
OperandVector &Operands) {
6815 MCAsmParser &Parser = getParser();
6819 bool RegRange =
false;
6826 while (parseAnyRegister(TmpOperands).isSuccess()) {
6827 SMLoc
E = getLexer().getLoc();
6828 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*TmpOperands.
back());
6829 Reg = isGP64bit() ? RegOpnd.getGPR64Reg() : RegOpnd.getGPR32Reg();
6833 if ((isGP64bit() &&
Reg == Mips::RA_64) ||
6834 (!isGP64bit() &&
Reg == Mips::RA)) {
6837 MCRegister TmpReg = PrevReg + 1;
6838 while (TmpReg <=
Reg) {
6839 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
6840 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
6842 return Error(
E,
"invalid register operand");
6846 TmpReg = TmpReg.
id() + 1;
6853 ((isGP64bit() && (
Reg != Mips::S0_64) && (
Reg != Mips::RA_64)) ||
6854 (!isGP64bit() && (
Reg != Mips::S0) && (
Reg != Mips::RA))))
6855 return Error(
E,
"$16 or $31 expected");
6856 if (!(((
Reg == Mips::FP ||
Reg == Mips::RA ||
6857 (
Reg >= Mips::S0 &&
Reg <= Mips::S7)) &&
6859 ((
Reg == Mips::FP_64 ||
Reg == Mips::RA_64 ||
6860 (
Reg >= Mips::S0_64 &&
Reg <= Mips::S7_64)) &&
6862 return Error(
E,
"invalid register operand");
6863 if (PrevReg.
isValid() && (
Reg != PrevReg + 1) &&
6864 ((
Reg != Mips::FP &&
Reg != Mips::RA && !isGP64bit()) ||
6865 (
Reg != Mips::FP_64 &&
Reg != Mips::RA_64 && isGP64bit())))
6866 return Error(
E,
"consecutive register numbers expected");
6876 return Error(
E,
"',' or '-' expected");
6886 Operands.
push_back(MipsOperand::CreateRegList(Regs, S,
E, *
this));
6887 parseMemOperand(Operands);
6896bool MipsAsmParser::parseParenSuffix(StringRef Name,
OperandVector &Operands) {
6897 MCAsmParser &Parser = getParser();
6900 MipsOperand::CreateToken(
"(", getLexer().getLoc(), *
this));
6902 if (parseOperand(Operands, Name)) {
6903 SMLoc Loc = getLexer().getLoc();
6904 return Error(Loc,
"unexpected token in argument list");
6907 SMLoc Loc = getLexer().getLoc();
6908 return Error(Loc,
"unexpected token, expected ')'");
6911 MipsOperand::CreateToken(
")", getLexer().getLoc(), *
this));
6923bool MipsAsmParser::parseBracketSuffix(StringRef Name,
6925 MCAsmParser &Parser = getParser();
6928 MipsOperand::CreateToken(
"[", getLexer().getLoc(), *
this));
6930 if (parseOperand(Operands, Name)) {
6931 SMLoc Loc = getLexer().getLoc();
6932 return Error(Loc,
"unexpected token in argument list");
6935 SMLoc Loc = getLexer().getLoc();
6936 return Error(Loc,
"unexpected token, expected ']'");
6939 MipsOperand::CreateToken(
"]", getLexer().getLoc(), *
this));
6946 unsigned VariantID = 0);
6961bool MipsAsmParser::parseInstruction(ParseInstructionInfo &
Info, StringRef Name,
6963 MCAsmParser &Parser = getParser();
6967 getTargetStreamer().forbidModuleDirective();
6970 if (!mnemonicIsValid(Name, 0)) {
6971 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
6973 return Error(NameLoc,
"unknown instruction" + Suggestion);
6976 Operands.
push_back(MipsOperand::CreateToken(Name, NameLoc, *
this));
6981 if (parseOperand(Operands, Name)) {
6982 SMLoc Loc = getLexer().getLoc();
6983 return Error(Loc,
"unexpected token in argument list");
6985 if (getLexer().is(
AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
6992 if (parseOperand(Operands, Name)) {
6993 SMLoc Loc = getLexer().getLoc();
6994 return Error(Loc,
"unexpected token in argument list");
6998 if (parseBracketSuffix(Name, Operands))
7001 parseParenSuffix(Name, Operands))
7006 SMLoc Loc = getLexer().getLoc();
7007 return Error(Loc,
"unexpected token in argument list");
7015bool MipsAsmParser::reportParseError(
const Twine &ErrorMsg) {
7016 SMLoc Loc = getLexer().getLoc();
7017 return Error(Loc, ErrorMsg);
7020bool MipsAsmParser::reportParseError(SMLoc Loc,
const Twine &ErrorMsg) {
7021 return Error(Loc, ErrorMsg);
7024bool MipsAsmParser::parseSetNoAtDirective() {
7025 MCAsmParser &Parser = getParser();
7029 AssemblerOptions.
back()->setATRegIndex(0);
7035 reportParseError(
"unexpected token, expected end of statement");
7039 getTargetStreamer().emitDirectiveSetNoAt();
7044bool MipsAsmParser::parseSetAtDirective() {
7047 MCAsmParser &Parser = getParser();
7052 AssemblerOptions.
back()->setATRegIndex(1);
7054 getTargetStreamer().emitDirectiveSetAt();
7060 reportParseError(
"unexpected token, expected equals sign");
7067 reportParseError(
"no register specified");
7070 reportParseError(
"unexpected token, expected dollar sign '$'");
7080 AtRegNo = matchCPURegisterName(
Reg.getIdentifier());
7082 AtRegNo =
Reg.getIntVal();
7084 reportParseError(
"unexpected token, expected identifier or integer");
7089 if (!AssemblerOptions.
back()->setATRegIndex(AtRegNo)) {
7090 reportParseError(
"invalid register");
7097 reportParseError(
"unexpected token, expected end of statement");
7101 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
7107bool MipsAsmParser::parseSetReorderDirective() {
7108 MCAsmParser &Parser = getParser();
7112 reportParseError(
"unexpected token, expected end of statement");
7115 AssemblerOptions.
back()->setReorder();
7116 getTargetStreamer().emitDirectiveSetReorder();
7121bool MipsAsmParser::parseSetNoReorderDirective() {
7122 MCAsmParser &Parser = getParser();
7126 reportParseError(
"unexpected token, expected end of statement");
7129 AssemblerOptions.
back()->setNoReorder();
7130 getTargetStreamer().emitDirectiveSetNoReorder();
7135bool MipsAsmParser::parseSetMacroDirective() {
7136 MCAsmParser &Parser = getParser();
7140 reportParseError(
"unexpected token, expected end of statement");
7143 AssemblerOptions.
back()->setMacro();
7144 getTargetStreamer().emitDirectiveSetMacro();
7149bool MipsAsmParser::parseSetNoMacroDirective() {
7150 MCAsmParser &Parser = getParser();
7154 reportParseError(
"unexpected token, expected end of statement");
7157 if (AssemblerOptions.
back()->isReorder()) {
7158 reportParseError(
"`noreorder' must be set before `nomacro'");
7161 AssemblerOptions.
back()->setNoMacro();
7162 getTargetStreamer().emitDirectiveSetNoMacro();
7167bool MipsAsmParser::parseSetMsaDirective() {
7168 MCAsmParser &Parser = getParser();
7173 return reportParseError(
"unexpected token, expected end of statement");
7175 setFeatureBits(Mips::FeatureMSA,
"msa");
7176 getTargetStreamer().emitDirectiveSetMsa();
7180bool MipsAsmParser::parseSetNoMsaDirective() {
7181 MCAsmParser &Parser = getParser();
7186 return reportParseError(
"unexpected token, expected end of statement");
7188 clearFeatureBits(Mips::FeatureMSA,
"msa");
7189 getTargetStreamer().emitDirectiveSetNoMsa();
7193bool MipsAsmParser::parseSetNoDspDirective() {
7194 MCAsmParser &Parser = getParser();
7199 reportParseError(
"unexpected token, expected end of statement");
7203 clearFeatureBits(Mips::FeatureDSP,
"dsp");
7204 getTargetStreamer().emitDirectiveSetNoDsp();
7208bool MipsAsmParser::parseSetNoMips3DDirective() {
7209 MCAsmParser &Parser = getParser();
7214 reportParseError(
"unexpected token, expected end of statement");
7218 clearFeatureBits(Mips::FeatureMips3D,
"mips3d");
7219 getTargetStreamer().emitDirectiveSetNoMips3D();
7223bool MipsAsmParser::parseSetMips16Directive() {
7224 MCAsmParser &Parser = getParser();
7229 reportParseError(
"unexpected token, expected end of statement");
7233 setFeatureBits(Mips::FeatureMips16,
"mips16");
7234 getTargetStreamer().emitDirectiveSetMips16();
7239bool MipsAsmParser::parseSetNoMips16Directive() {
7240 MCAsmParser &Parser = getParser();
7245 reportParseError(
"unexpected token, expected end of statement");
7249 clearFeatureBits(Mips::FeatureMips16,
"mips16");
7250 getTargetStreamer().emitDirectiveSetNoMips16();
7255bool MipsAsmParser::parseSetFpDirective() {
7256 MCAsmParser &Parser = getParser();
7262 AsmToken Tok = Parser.
getTok();
7264 reportParseError(
"unexpected token, expected equals sign '='");
7270 if (!parseFpABIValue(FpAbiVal,
".set"))
7274 reportParseError(
"unexpected token, expected end of statement");
7277 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
7282bool MipsAsmParser::parseSetOddSPRegDirective() {
7283 MCAsmParser &Parser = getParser();
7287 reportParseError(
"unexpected token, expected end of statement");
7291 clearFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
7292 getTargetStreamer().emitDirectiveSetOddSPReg();
7296bool MipsAsmParser::parseSetNoOddSPRegDirective() {
7297 MCAsmParser &Parser = getParser();
7301 reportParseError(
"unexpected token, expected end of statement");
7305 setFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
7306 getTargetStreamer().emitDirectiveSetNoOddSPReg();
7310bool MipsAsmParser::parseSetMtDirective() {
7311 MCAsmParser &Parser = getParser();
7316 reportParseError(
"unexpected token, expected end of statement");
7320 setFeatureBits(Mips::FeatureMT,
"mt");
7321 getTargetStreamer().emitDirectiveSetMt();
7326bool MipsAsmParser::parseSetNoMtDirective() {
7327 MCAsmParser &Parser = getParser();
7332 reportParseError(
"unexpected token, expected end of statement");
7336 clearFeatureBits(Mips::FeatureMT,
"mt");
7338 getTargetStreamer().emitDirectiveSetNoMt();
7343bool MipsAsmParser::parseSetNoCRCDirective() {
7344 MCAsmParser &Parser = getParser();
7349 reportParseError(
"unexpected token, expected end of statement");
7353 clearFeatureBits(Mips::FeatureCRC,
"crc");
7355 getTargetStreamer().emitDirectiveSetNoCRC();
7360bool MipsAsmParser::parseSetNoVirtDirective() {
7361 MCAsmParser &Parser = getParser();
7366 reportParseError(
"unexpected token, expected end of statement");
7370 clearFeatureBits(Mips::FeatureVirt,
"virt");
7372 getTargetStreamer().emitDirectiveSetNoVirt();
7377bool MipsAsmParser::parseSetNoGINVDirective() {
7378 MCAsmParser &Parser = getParser();
7383 reportParseError(
"unexpected token, expected end of statement");
7387 clearFeatureBits(Mips::FeatureGINV,
"ginv");
7389 getTargetStreamer().emitDirectiveSetNoGINV();
7394bool MipsAsmParser::parseSetPopDirective() {
7395 MCAsmParser &Parser = getParser();
7396 SMLoc Loc = getLexer().getLoc();
7400 return reportParseError(
"unexpected token, expected end of statement");
7404 if (AssemblerOptions.
size() == 2)
7405 return reportParseError(Loc,
".set pop with no .set push");
7407 MCSubtargetInfo &STI = copySTI();
7409 setAvailableFeatures(
7410 ComputeAvailableFeatures(AssemblerOptions.
back()->getFeatures()));
7413 getTargetStreamer().emitDirectiveSetPop();
7417bool MipsAsmParser::parseSetPushDirective() {
7418 MCAsmParser &Parser = getParser();
7421 return reportParseError(
"unexpected token, expected end of statement");
7425 std::make_unique<MipsAssemblerOptions>(AssemblerOptions.
back().get()));
7427 getTargetStreamer().emitDirectiveSetPush();
7431bool MipsAsmParser::parseSetSoftFloatDirective() {
7432 MCAsmParser &Parser = getParser();
7435 return reportParseError(
"unexpected token, expected end of statement");
7437 setFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
7438 getTargetStreamer().emitDirectiveSetSoftFloat();
7442bool MipsAsmParser::parseSetHardFloatDirective() {
7443 MCAsmParser &Parser = getParser();
7446 return reportParseError(
"unexpected token, expected end of statement");
7448 clearFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
7449 getTargetStreamer().emitDirectiveSetHardFloat();
7453bool MipsAsmParser::parseSetAssignment() {
7455 MCAsmParser &Parser = getParser();
7458 return reportParseError(
"expected identifier after .set");
7461 return reportParseError(
"unexpected token, expected comma");
7476 const MCExpr *
Value;
7478 Parser, Sym,
Value))
7480 getStreamer().emitAssignment(Sym,
Value);
7485bool MipsAsmParser::parseSetMips0Directive() {
7486 MCAsmParser &Parser = getParser();
7489 return reportParseError(
"unexpected token, expected end of statement");
7492 MCSubtargetInfo &STI = copySTI();
7493 setAvailableFeatures(
7494 ComputeAvailableFeatures(AssemblerOptions.
front()->getFeatures()));
7496 AssemblerOptions.
back()->setFeatures(AssemblerOptions.
front()->getFeatures());
7498 getTargetStreamer().emitDirectiveSetMips0();
7502bool MipsAsmParser::parseSetArchDirective() {
7503 MCAsmParser &Parser = getParser();
7506 return reportParseError(
"unexpected token, expected equals sign");
7509 StringRef Arch = getParser().parseStringToEndOfStatement().trim();
7511 return reportParseError(
"expected arch identifier");
7513 StringRef ArchFeatureName =
7514 StringSwitch<StringRef>(Arch)
7515 .Case(
"mips1",
"mips1")
7516 .Case(
"mips2",
"mips2")
7517 .Case(
"mips3",
"mips3")
7518 .Case(
"mips4",
"mips4")
7519 .Case(
"mips5",
"mips5")
7520 .Case(
"mips32",
"mips32")
7521 .Case(
"mips32r2",
"mips32r2")
7522 .Case(
"mips32r3",
"mips32r3")
7523 .Case(
"mips32r5",
"mips32r5")
7524 .Case(
"mips32r6",
"mips32r6")
7525 .Case(
"mips64",
"mips64")
7526 .Case(
"mips64r2",
"mips64r2")
7527 .Case(
"mips64r3",
"mips64r3")
7528 .Case(
"mips64r5",
"mips64r5")
7529 .Case(
"mips64r6",
"mips64r6")
7530 .Case(
"octeon",
"cnmips")
7531 .Case(
"octeon+",
"cnmipsp")
7532 .Case(
"r4000",
"mips3")
7535 if (ArchFeatureName.
empty())
7536 return reportParseError(
"unsupported architecture");
7538 if (ArchFeatureName ==
"mips64r6" && inMicroMipsMode())
7539 return reportParseError(
"mips64r6 does not support microMIPS");
7541 selectArch(ArchFeatureName);
7542 getTargetStreamer().emitDirectiveSetArch(Arch);
7546bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
7547 MCAsmParser &Parser = getParser();
7550 return reportParseError(
"unexpected token, expected end of statement");
7555 case Mips::FeatureMips3D:
7556 setFeatureBits(Mips::FeatureMips3D,
"mips3d");
7557 getTargetStreamer().emitDirectiveSetMips3D();
7559 case Mips::FeatureDSP:
7560 setFeatureBits(Mips::FeatureDSP,
"dsp");
7561 getTargetStreamer().emitDirectiveSetDsp();
7563 case Mips::FeatureDSPR2:
7564 setFeatureBits(Mips::FeatureDSPR2,
"dspr2");
7565 getTargetStreamer().emitDirectiveSetDspr2();
7567 case Mips::FeatureMicroMips:
7568 setFeatureBits(Mips::FeatureMicroMips,
"micromips");
7569 getTargetStreamer().emitDirectiveSetMicroMips();
7571 case Mips::FeatureMips1:
7572 selectArch(
"mips1");
7573 getTargetStreamer().emitDirectiveSetMips1();
7575 case Mips::FeatureMips2:
7576 selectArch(
"mips2");
7577 getTargetStreamer().emitDirectiveSetMips2();
7579 case Mips::FeatureMips3:
7580 selectArch(
"mips3");
7581 getTargetStreamer().emitDirectiveSetMips3();
7583 case Mips::FeatureMips4:
7584 selectArch(
"mips4");
7585 getTargetStreamer().emitDirectiveSetMips4();
7587 case Mips::FeatureMips5:
7588 selectArch(
"mips5");
7589 getTargetStreamer().emitDirectiveSetMips5();
7591 case Mips::FeatureMips32:
7592 selectArch(
"mips32");
7593 getTargetStreamer().emitDirectiveSetMips32();
7595 case Mips::FeatureMips32r2:
7596 selectArch(
"mips32r2");
7597 getTargetStreamer().emitDirectiveSetMips32R2();
7599 case Mips::FeatureMips32r3:
7600 selectArch(
"mips32r3");
7601 getTargetStreamer().emitDirectiveSetMips32R3();
7603 case Mips::FeatureMips32r5:
7604 selectArch(
"mips32r5");
7605 getTargetStreamer().emitDirectiveSetMips32R5();
7607 case Mips::FeatureMips32r6:
7608 selectArch(
"mips32r6");
7609 getTargetStreamer().emitDirectiveSetMips32R6();
7611 case Mips::FeatureMips64:
7612 selectArch(
"mips64");
7613 getTargetStreamer().emitDirectiveSetMips64();
7615 case Mips::FeatureMips64r2:
7616 selectArch(
"mips64r2");
7617 getTargetStreamer().emitDirectiveSetMips64R2();
7619 case Mips::FeatureMips64r3:
7620 selectArch(
"mips64r3");
7621 getTargetStreamer().emitDirectiveSetMips64R3();
7623 case Mips::FeatureMips64r5:
7624 selectArch(
"mips64r5");
7625 getTargetStreamer().emitDirectiveSetMips64R5();
7627 case Mips::FeatureMips64r6:
7628 selectArch(
"mips64r6");
7629 getTargetStreamer().emitDirectiveSetMips64R6();
7631 case Mips::FeatureCRC:
7632 setFeatureBits(Mips::FeatureCRC,
"crc");
7633 getTargetStreamer().emitDirectiveSetCRC();
7635 case Mips::FeatureVirt:
7636 setFeatureBits(Mips::FeatureVirt,
"virt");
7637 getTargetStreamer().emitDirectiveSetVirt();
7639 case Mips::FeatureGINV:
7640 setFeatureBits(Mips::FeatureGINV,
"ginv");
7641 getTargetStreamer().emitDirectiveSetGINV();
7647bool MipsAsmParser::eatComma(StringRef ErrorStr) {
7648 MCAsmParser &Parser = getParser();
7650 SMLoc Loc = getLexer().getLoc();
7651 return Error(Loc, ErrorStr);
7662bool MipsAsmParser::isPicAndNotNxxAbi() {
7663 return inPicMode() && !(isABI_N32() || isABI_N64());
7666bool MipsAsmParser::parseDirectiveCpAdd(SMLoc Loc) {
7668 ParseStatus Res = parseAnyRegister(
Reg);
7670 reportParseError(
"expected register");
7674 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7675 if (!RegOpnd.isGPRAsmReg()) {
7676 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7682 reportParseError(
"unexpected token, expected end of statement");
7687 getTargetStreamer().emitDirectiveCpAdd(RegOpnd.getGPR32Reg());
7691bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
7692 if (AssemblerOptions.
back()->isReorder())
7693 Warning(Loc,
".cpload should be inside a noreorder section");
7695 if (inMips16Mode()) {
7696 reportParseError(
".cpload is not supported in Mips16 mode");
7701 ParseStatus Res = parseAnyRegister(
Reg);
7703 reportParseError(
"expected register containing function address");
7707 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7708 if (!RegOpnd.isGPRAsmReg()) {
7709 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7715 reportParseError(
"unexpected token, expected end of statement");
7719 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
7723bool MipsAsmParser::parseDirectiveCpLocal(SMLoc Loc) {
7724 if (!isABI_N32() && !isABI_N64()) {
7725 reportParseError(
".cplocal is allowed only in N32 or N64 mode");
7730 ParseStatus Res = parseAnyRegister(
Reg);
7732 reportParseError(
"expected register containing global pointer");
7736 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7737 if (!RegOpnd.isGPRAsmReg()) {
7738 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7744 reportParseError(
"unexpected token, expected end of statement");
7749 MCRegister NewReg = RegOpnd.getGPR32Reg();
7753 getTargetStreamer().emitDirectiveCpLocal(NewReg);
7757bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
7758 MCAsmParser &Parser = getParser();
7763 if (inMips16Mode()) {
7764 reportParseError(
".cprestore is not supported in Mips16 mode");
7769 const MCExpr *StackOffset;
7770 int64_t StackOffsetVal;
7772 reportParseError(
"expected stack offset value");
7776 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
7777 reportParseError(
"stack offset is not an absolute expression");
7781 if (StackOffsetVal < 0) {
7782 Warning(Loc,
".cprestore with negative stack offset has no effect");
7783 IsCpRestoreSet =
false;
7785 IsCpRestoreSet =
true;
7786 CpRestoreOffset = StackOffsetVal;
7791 reportParseError(
"unexpected token, expected end of statement");
7795 if (!getTargetStreamer().emitDirectiveCpRestore(
7796 CpRestoreOffset, [&]() {
return getATReg(Loc); }, Loc, STI))
7802bool MipsAsmParser::parseDirectiveCPSetup() {
7803 MCAsmParser &Parser = getParser();
7805 bool SaveIsReg =
true;
7808 ParseStatus Res = parseAnyRegister(TmpReg);
7810 reportParseError(
"expected register containing function address");
7814 MipsOperand &FuncRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7815 if (!FuncRegOpnd.isGPRAsmReg()) {
7816 reportParseError(FuncRegOpnd.getStartLoc(),
"invalid register");
7820 MCRegister FuncReg = FuncRegOpnd.getGPR32Reg();
7823 if (!eatComma(
"unexpected token, expected comma"))
7826 Res = parseAnyRegister(TmpReg);
7828 const MCExpr *OffsetExpr;
7830 SMLoc ExprLoc = getLexer().
getLoc();
7833 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
7834 reportParseError(ExprLoc,
"expected save register or stack offset");
7841 MipsOperand &SaveOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7842 if (!SaveOpnd.isGPRAsmReg()) {
7843 reportParseError(SaveOpnd.getStartLoc(),
"invalid register");
7846 Save = SaveOpnd.getGPR32Reg().id();
7849 if (!eatComma(
"unexpected token, expected comma"))
7854 reportParseError(
"expected expression");
7859 reportParseError(
"expected symbol");
7862 const MCSymbolRefExpr *
Ref =
static_cast<const MCSymbolRefExpr *
>(Expr);
7864 CpSaveLocation = Save;
7865 CpSaveLocationIsRegister = SaveIsReg;
7867 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save,
Ref->getSymbol(),
7872bool MipsAsmParser::parseDirectiveCPReturn() {
7873 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
7874 CpSaveLocationIsRegister);
7878bool MipsAsmParser::parseDirectiveNaN() {
7879 MCAsmParser &Parser = getParser();
7881 const AsmToken &Tok = Parser.
getTok();
7885 getTargetStreamer().emitDirectiveNaN2008();
7887 }
else if (Tok.
getString() ==
"legacy") {
7889 getTargetStreamer().emitDirectiveNaNLegacy();
7895 reportParseError(
"invalid option in .nan directive");
7899bool MipsAsmParser::parseDirectiveSet() {
7900 const AsmToken &Tok = getParser().getTok();
7902 SMLoc Loc = Tok.
getLoc();
7904 if (IdVal ==
"noat")
7905 return parseSetNoAtDirective();
7907 return parseSetAtDirective();
7908 if (IdVal ==
"arch")
7909 return parseSetArchDirective();
7910 if (IdVal ==
"bopt") {
7911 Warning(Loc,
"'bopt' feature is unsupported");
7915 if (IdVal ==
"nobopt") {
7921 return parseSetFpDirective();
7922 if (IdVal ==
"oddspreg")
7923 return parseSetOddSPRegDirective();
7924 if (IdVal ==
"nooddspreg")
7925 return parseSetNoOddSPRegDirective();
7927 return parseSetPopDirective();
7928 if (IdVal ==
"push")
7929 return parseSetPushDirective();
7930 if (IdVal ==
"reorder")
7931 return parseSetReorderDirective();
7932 if (IdVal ==
"noreorder")
7933 return parseSetNoReorderDirective();
7934 if (IdVal ==
"macro")
7935 return parseSetMacroDirective();
7936 if (IdVal ==
"nomacro")
7937 return parseSetNoMacroDirective();
7938 if (IdVal ==
"mips16")
7939 return parseSetMips16Directive();
7940 if (IdVal ==
"nomips16")
7941 return parseSetNoMips16Directive();
7942 if (IdVal ==
"nomicromips") {
7943 clearFeatureBits(Mips::FeatureMicroMips,
"micromips");
7944 getTargetStreamer().emitDirectiveSetNoMicroMips();
7945 getParser().eatToEndOfStatement();
7948 if (IdVal ==
"micromips") {
7949 if (hasMips64r6()) {
7950 Error(Loc,
".set micromips directive is not supported with MIPS64R6");
7953 return parseSetFeature(Mips::FeatureMicroMips);
7955 if (IdVal ==
"mips0")
7956 return parseSetMips0Directive();
7957 if (IdVal ==
"mips1")
7958 return parseSetFeature(Mips::FeatureMips1);
7959 if (IdVal ==
"mips2")
7960 return parseSetFeature(Mips::FeatureMips2);
7961 if (IdVal ==
"mips3")
7962 return parseSetFeature(Mips::FeatureMips3);
7963 if (IdVal ==
"mips4")
7964 return parseSetFeature(Mips::FeatureMips4);
7965 if (IdVal ==
"mips5")
7966 return parseSetFeature(Mips::FeatureMips5);
7967 if (IdVal ==
"mips32")
7968 return parseSetFeature(Mips::FeatureMips32);
7969 if (IdVal ==
"mips32r2")
7970 return parseSetFeature(Mips::FeatureMips32r2);
7971 if (IdVal ==
"mips32r3")
7972 return parseSetFeature(Mips::FeatureMips32r3);
7973 if (IdVal ==
"mips32r5")
7974 return parseSetFeature(Mips::FeatureMips32r5);
7975 if (IdVal ==
"mips32r6")
7976 return parseSetFeature(Mips::FeatureMips32r6);
7977 if (IdVal ==
"mips64")
7978 return parseSetFeature(Mips::FeatureMips64);
7979 if (IdVal ==
"mips64r2")
7980 return parseSetFeature(Mips::FeatureMips64r2);
7981 if (IdVal ==
"mips64r3")
7982 return parseSetFeature(Mips::FeatureMips64r3);
7983 if (IdVal ==
"mips64r5")
7984 return parseSetFeature(Mips::FeatureMips64r5);
7985 if (IdVal ==
"mips64r6") {
7986 if (inMicroMipsMode()) {
7987 Error(Loc,
"MIPS64R6 is not supported with microMIPS");
7990 return parseSetFeature(Mips::FeatureMips64r6);
7993 return parseSetFeature(Mips::FeatureDSP);
7994 if (IdVal ==
"dspr2")
7995 return parseSetFeature(Mips::FeatureDSPR2);
7996 if (IdVal ==
"nodsp")
7997 return parseSetNoDspDirective();
7998 if (IdVal ==
"mips3d")
7999 return parseSetFeature(Mips::FeatureMips3D);
8000 if (IdVal ==
"nomips3d")
8001 return parseSetNoMips3DDirective();
8003 return parseSetMsaDirective();
8004 if (IdVal ==
"nomsa")
8005 return parseSetNoMsaDirective();
8007 return parseSetMtDirective();
8008 if (IdVal ==
"nomt")
8009 return parseSetNoMtDirective();
8010 if (IdVal ==
"softfloat")
8011 return parseSetSoftFloatDirective();
8012 if (IdVal ==
"hardfloat")
8013 return parseSetHardFloatDirective();
8015 return parseSetFeature(Mips::FeatureCRC);
8016 if (IdVal ==
"nocrc")
8017 return parseSetNoCRCDirective();
8018 if (IdVal ==
"virt")
8019 return parseSetFeature(Mips::FeatureVirt);
8020 if (IdVal ==
"novirt")
8021 return parseSetNoVirtDirective();
8022 if (IdVal ==
"ginv")
8023 return parseSetFeature(Mips::FeatureGINV);
8024 if (IdVal ==
"noginv")
8025 return parseSetNoGINVDirective();
8028 return parseSetAssignment();
8033bool MipsAsmParser::parseDirectiveGpWord() {
8034 const MCExpr *
Value;
8035 if (getParser().parseExpression(
Value))
8037 getTargetStreamer().emitGPRel32Value(
Value);
8043bool MipsAsmParser::parseDirectiveGpDWord() {
8044 const MCExpr *
Value;
8045 if (getParser().parseExpression(
Value))
8047 getTargetStreamer().emitGPRel64Value(
Value);
8053bool MipsAsmParser::parseDirectiveDtpRelWord() {
8054 const MCExpr *
Value;
8055 if (getParser().parseExpression(
Value))
8057 getTargetStreamer().emitDTPRel32Value(
Value);
8063bool MipsAsmParser::parseDirectiveDtpRelDWord() {
8064 const MCExpr *
Value;
8065 if (getParser().parseExpression(
Value))
8067 getTargetStreamer().emitDTPRel64Value(
Value);
8073bool MipsAsmParser::parseDirectiveTpRelWord() {
8074 const MCExpr *
Value;
8075 if (getParser().parseExpression(
Value))
8077 getTargetStreamer().emitTPRel32Value(
Value);
8083bool MipsAsmParser::parseDirectiveTpRelDWord() {
8084 const MCExpr *
Value;
8085 if (getParser().parseExpression(
Value))
8087 getTargetStreamer().emitTPRel64Value(
Value);
8091bool MipsAsmParser::parseDirectiveOption() {
8092 MCAsmParser &Parser = getParser();
8094 AsmToken Tok = Parser.
getTok();
8098 "unexpected token, expected identifier");
8103 if (Option ==
"pic0") {
8105 IsPicEnabled =
false;
8107 getTargetStreamer().emitDirectiveOptionPic0();
8111 "unexpected token, expected end of statement");
8116 if (Option ==
"pic2") {
8118 IsPicEnabled =
true;
8120 getTargetStreamer().emitDirectiveOptionPic2();
8124 "unexpected token, expected end of statement");
8131 "unknown option, expected 'pic0' or 'pic2'");
8138bool MipsAsmParser::parseInsnDirective() {
8141 reportParseError(
"unexpected token, expected end of statement");
8147 getTargetStreamer().emitDirectiveInsn();
8155bool MipsAsmParser::parseRSectionDirective(StringRef Section) {
8158 reportParseError(
"unexpected token, expected end of statement");
8162 MCSection *ELFSection =
getContext().getELFSection(
8164 getParser().getStreamer().switchSection(ELFSection);
8173bool MipsAsmParser::parseSSectionDirective(StringRef Section,
unsigned Type) {
8176 reportParseError(
"unexpected token, expected end of statement");
8180 MCSection *ELFSection =
getContext().getELFSection(
8182 getParser().getStreamer().switchSection(ELFSection);
8201bool MipsAsmParser::parseDirectiveModule() {
8202 MCAsmParser &Parser = getParser();
8203 AsmLexer &Lexer = getLexer();
8206 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
8208 reportParseError(
".module directive must appear before any code");
8214 reportParseError(
"expected .module option identifier");
8218 if (Option ==
"oddspreg") {
8219 clearModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
8223 getTargetStreamer().updateABIInfo(*
this);
8228 getTargetStreamer().emitDirectiveModuleOddSPReg();
8232 reportParseError(
"unexpected token, expected end of statement");
8237 }
else if (Option ==
"nooddspreg") {
8239 return Error(L,
"'.module nooddspreg' requires the O32 ABI");
8242 setModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
8246 getTargetStreamer().updateABIInfo(*
this);
8251 getTargetStreamer().emitDirectiveModuleOddSPReg();
8255 reportParseError(
"unexpected token, expected end of statement");
8260 }
else if (Option ==
"fp") {
8261 return parseDirectiveModuleFP();
8262 }
else if (Option ==
"softfloat") {
8263 setModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
8267 getTargetStreamer().updateABIInfo(*
this);
8272 getTargetStreamer().emitDirectiveModuleSoftFloat();
8276 reportParseError(
"unexpected token, expected end of statement");
8281 }
else if (Option ==
"hardfloat") {
8282 clearModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
8286 getTargetStreamer().updateABIInfo(*
this);
8291 getTargetStreamer().emitDirectiveModuleHardFloat();
8295 reportParseError(
"unexpected token, expected end of statement");
8300 }
else if (Option ==
"mt") {
8301 setModuleFeatureBits(Mips::FeatureMT,
"mt");
8305 getTargetStreamer().updateABIInfo(*
this);
8310 getTargetStreamer().emitDirectiveModuleMT();
8314 reportParseError(
"unexpected token, expected end of statement");
8319 }
else if (Option ==
"crc") {
8320 setModuleFeatureBits(Mips::FeatureCRC,
"crc");
8324 getTargetStreamer().updateABIInfo(*
this);
8329 getTargetStreamer().emitDirectiveModuleCRC();
8333 reportParseError(
"unexpected token, expected end of statement");
8338 }
else if (Option ==
"nocrc") {
8339 clearModuleFeatureBits(Mips::FeatureCRC,
"crc");
8343 getTargetStreamer().updateABIInfo(*
this);
8348 getTargetStreamer().emitDirectiveModuleNoCRC();
8352 reportParseError(
"unexpected token, expected end of statement");
8357 }
else if (Option ==
"virt") {
8358 setModuleFeatureBits(Mips::FeatureVirt,
"virt");
8362 getTargetStreamer().updateABIInfo(*
this);
8367 getTargetStreamer().emitDirectiveModuleVirt();
8371 reportParseError(
"unexpected token, expected end of statement");
8376 }
else if (Option ==
"novirt") {
8377 clearModuleFeatureBits(Mips::FeatureVirt,
"virt");
8381 getTargetStreamer().updateABIInfo(*
this);
8386 getTargetStreamer().emitDirectiveModuleNoVirt();
8390 reportParseError(
"unexpected token, expected end of statement");
8395 }
else if (Option ==
"ginv") {
8396 setModuleFeatureBits(Mips::FeatureGINV,
"ginv");
8400 getTargetStreamer().updateABIInfo(*
this);
8405 getTargetStreamer().emitDirectiveModuleGINV();
8409 reportParseError(
"unexpected token, expected end of statement");
8414 }
else if (Option ==
"noginv") {
8415 clearModuleFeatureBits(Mips::FeatureGINV,
"ginv");
8419 getTargetStreamer().updateABIInfo(*
this);
8424 getTargetStreamer().emitDirectiveModuleNoGINV();
8428 reportParseError(
"unexpected token, expected end of statement");
8434 return Error(L,
"'" + Twine(Option) +
"' is not a valid .module option.");
8442bool MipsAsmParser::parseDirectiveModuleFP() {
8443 MCAsmParser &Parser = getParser();
8444 AsmLexer &Lexer = getLexer();
8447 reportParseError(
"unexpected token, expected equals sign '='");
8453 if (!parseFpABIValue(FpABI,
".module"))
8457 reportParseError(
"unexpected token, expected end of statement");
8463 getTargetStreamer().updateABIInfo(*
this);
8468 getTargetStreamer().emitDirectiveModuleFP();
8475 StringRef Directive) {
8476 MCAsmParser &Parser = getParser();
8477 AsmLexer &Lexer = getLexer();
8478 bool ModuleLevelOptions = Directive ==
".module";
8484 if (
Value !=
"xx") {
8485 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
8490 reportParseError(
"'" + Directive +
" fp=xx' requires the O32 ABI");
8494 FpABI = MipsABIFlagsSection::FpABIKind::XX;
8495 if (ModuleLevelOptions) {
8496 setModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8497 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8499 setFeatureBits(Mips::FeatureFPXX,
"fpxx");
8500 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8510 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
8516 reportParseError(
"'" + Directive +
" fp=32' requires the O32 ABI");
8520 FpABI = MipsABIFlagsSection::FpABIKind::S32;
8521 if (ModuleLevelOptions) {
8522 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8523 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8525 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
8526 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8529 FpABI = MipsABIFlagsSection::FpABIKind::S64;
8530 if (ModuleLevelOptions) {
8531 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8532 setModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8534 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
8535 setFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8545bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
8551 MCAsmParser &Parser = getParser();
8552 StringRef IDVal = DirectiveID.
getString();
8554 if (IDVal ==
".cpadd") {
8555 parseDirectiveCpAdd(DirectiveID.
getLoc());
8558 if (IDVal ==
".cpload") {
8559 parseDirectiveCpLoad(DirectiveID.
getLoc());
8562 if (IDVal ==
".cprestore") {
8563 parseDirectiveCpRestore(DirectiveID.
getLoc());
8566 if (IDVal ==
".cplocal") {
8567 parseDirectiveCpLocal(DirectiveID.
getLoc());
8570 if (IDVal ==
".ent") {
8574 reportParseError(
"expected identifier after .ent");
8588 reportParseError(
"unexpected token, expected end of statement");
8592 const MCExpr *DummyNumber;
8593 int64_t DummyNumberVal;
8597 reportParseError(
"expected number after comma");
8600 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
8601 reportParseError(
"expected an absolute expression after comma");
8608 reportParseError(
"unexpected token, expected end of statement");
8614 getTargetStreamer().emitDirectiveEnt(*Sym);
8616 IsCpRestoreSet =
false;
8620 if (IDVal ==
".end") {
8624 reportParseError(
"expected identifier after .end");
8629 reportParseError(
"unexpected token, expected end of statement");
8633 if (CurrentFn ==
nullptr) {
8634 reportParseError(
".end used without .ent");
8638 if ((SymbolName != CurrentFn->
getName())) {
8639 reportParseError(
".end symbol does not match .ent symbol");
8643 getTargetStreamer().emitDirectiveEnd(SymbolName);
8644 CurrentFn =
nullptr;
8645 IsCpRestoreSet =
false;
8649 if (IDVal ==
".frame") {
8652 ParseStatus Res = parseAnyRegister(TmpReg);
8654 reportParseError(
"expected stack register");
8658 MipsOperand &StackRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
8659 if (!StackRegOpnd.isGPRAsmReg()) {
8660 reportParseError(StackRegOpnd.getStartLoc(),
8661 "expected general purpose register");
8664 MCRegister StackReg = StackRegOpnd.getGPR32Reg();
8669 reportParseError(
"unexpected token, expected comma");
8674 const MCExpr *FrameSize;
8675 int64_t FrameSizeVal;
8678 reportParseError(
"expected frame size value");
8682 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
8683 reportParseError(
"frame size not an absolute expression");
8690 reportParseError(
"unexpected token, expected comma");
8696 Res = parseAnyRegister(TmpReg);
8698 reportParseError(
"expected return register");
8702 MipsOperand &ReturnRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
8703 if (!ReturnRegOpnd.isGPRAsmReg()) {
8704 reportParseError(ReturnRegOpnd.getStartLoc(),
8705 "expected general purpose register");
8711 reportParseError(
"unexpected token, expected end of statement");
8715 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
8716 ReturnRegOpnd.getGPR32Reg());
8717 IsCpRestoreSet =
false;
8721 if (IDVal ==
".set") {
8722 parseDirectiveSet();
8726 if (IDVal ==
".mask" || IDVal ==
".fmask") {
8737 const MCExpr *BitMask;
8741 reportParseError(
"expected bitmask value");
8745 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
8746 reportParseError(
"bitmask not an absolute expression");
8753 reportParseError(
"unexpected token, expected comma");
8758 const MCExpr *FrameOffset;
8759 int64_t FrameOffsetVal;
8762 reportParseError(
"expected frame offset value");
8766 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
8767 reportParseError(
"frame offset not an absolute expression");
8773 reportParseError(
"unexpected token, expected end of statement");
8777 if (IDVal ==
".mask")
8778 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
8780 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
8784 if (IDVal ==
".nan")
8785 return parseDirectiveNaN();
8787 if (IDVal ==
".gpword") {
8788 parseDirectiveGpWord();
8792 if (IDVal ==
".gpdword") {
8793 parseDirectiveGpDWord();
8797 if (IDVal ==
".dtprelword") {
8798 parseDirectiveDtpRelWord();
8802 if (IDVal ==
".dtpreldword") {
8803 parseDirectiveDtpRelDWord();
8807 if (IDVal ==
".tprelword") {
8808 parseDirectiveTpRelWord();
8812 if (IDVal ==
".tpreldword") {
8813 parseDirectiveTpRelDWord();
8817 if (IDVal ==
".option") {
8818 parseDirectiveOption();
8822 if (IDVal ==
".abicalls") {
8823 getTargetStreamer().emitDirectiveAbiCalls();
8826 "unexpected token, expected end of statement");
8831 if (IDVal ==
".cpsetup") {
8832 parseDirectiveCPSetup();
8835 if (IDVal ==
".cpreturn") {
8836 parseDirectiveCPReturn();
8839 if (IDVal ==
".module") {
8840 parseDirectiveModule();
8843 if (IDVal ==
".llvm_internal_mips_reallow_module_directive") {
8844 parseInternalDirectiveReallowModule();
8847 if (IDVal ==
".insn") {
8848 parseInsnDirective();
8851 if (IDVal ==
".rdata") {
8852 parseRSectionDirective(
".rodata");
8855 if (IDVal ==
".sbss") {
8859 if (IDVal ==
".sdata") {
8867bool MipsAsmParser::parseInternalDirectiveReallowModule() {
8870 reportParseError(
"unexpected token, expected end of statement");
8874 getTargetStreamer().reallowModuleDirective();
8888#define GET_REGISTER_MATCHER
8889#define GET_MATCHER_IMPLEMENTATION
8890#define GET_MNEMONIC_SPELL_CHECKER
8891#include "MipsGenAsmMatcher.inc"
8893bool MipsAsmParser::mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID) {
8895 const MatchEntry *Start, *End;
8896 switch (VariantID) {
8898 case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0);
break;
8901 auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
8902 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,...