62#define DEBUG_TYPE "mips-asm-parser"
75class MipsAssemblerOptions {
77 MipsAssemblerOptions(
const FeatureBitset &Features_) : Features(Features_) {}
79 MipsAssemblerOptions(
const MipsAssemblerOptions *Opts) {
80 ATReg = Opts->getATRegIndex();
81 Reorder = Opts->isReorder();
82 Macro = Opts->isMacro();
83 Features = Opts->getFeatures();
86 unsigned getATRegIndex()
const {
return ATReg; }
87 bool setATRegIndex(
unsigned Reg) {
95 bool isReorder()
const {
return Reorder; }
96 void setReorder() { Reorder =
true; }
97 void setNoReorder() { Reorder =
false; }
99 bool isMacro()
const {
return Macro; }
100 void setMacro() {
Macro =
true; }
101 void setNoMacro() {
Macro =
false; }
103 const FeatureBitset &
getFeatures()
const {
return Features; }
104 void setFeatures(
const FeatureBitset &Features_) { Features = Features_; }
111 static const FeatureBitset AllArchRelatedMask;
117 FeatureBitset Features;
122const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
123 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
124 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
125 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
126 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
127 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
128 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
129 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
130 Mips::FeatureCnMipsP, Mips::FeatureFP64Bit, Mips::FeatureGP64Bit,
137 MipsTargetStreamer &getTargetStreamer() {
138 assert(getParser().getStreamer().getTargetStreamer() &&
139 "do not have a target streamer");
140 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
141 return static_cast<MipsTargetStreamer &
>(TS);
153 bool CurForbiddenSlotAttr;
156 unsigned CpSaveLocation;
158 bool CpSaveLocationIsRegister;
161 StringMap<AsmToken> RegisterSets;
164 void printWarningWithFixIt(
const Twine &Msg,
const Twine &FixMsg,
165 SMRange
Range,
bool ShowColors =
true);
167 void ConvertXWPOperands(MCInst &Inst,
const OperandVector &Operands);
169#define GET_ASSEMBLER_HEADER
170#include "MipsGenAsmMatcher.inc"
173 checkEarlyTargetMatchPredicate(
MCInst &Inst,
175 unsigned checkTargetMatchPredicate(
MCInst &Inst)
override;
177 bool matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
180 bool MatchingInlineAsm)
override;
185 SMLoc &EndLoc)
override;
191 bool mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID);
196 bool ParseDirective(
AsmToken DirectiveID)
override;
209 const MCExpr *parseRelocExpr();
215 enum MacroExpanderResultTy {
222 MacroExpanderResultTy tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
224 const MCSubtargetInfo *STI);
226 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
227 const MCSubtargetInfo *STI);
229 bool loadImmediate(int64_t ImmValue, MCRegister DstReg, MCRegister SrcReg,
230 bool Is32BitImm,
bool IsAddress, SMLoc IDLoc,
231 MCStreamer &Out,
const MCSubtargetInfo *STI);
233 bool loadAndAddSymbolAddress(
const MCExpr *SymExpr, MCRegister DstReg,
234 MCRegister SrcReg,
bool Is32BitSym, SMLoc IDLoc,
235 MCStreamer &Out,
const MCSubtargetInfo *STI);
237 bool emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc, MCSymbol *Sym);
239 bool expandLoadImm(MCInst &Inst,
bool Is32BitImm, SMLoc IDLoc,
240 MCStreamer &Out,
const MCSubtargetInfo *STI);
242 bool expandLoadSingleImmToGPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
243 const MCSubtargetInfo *STI);
244 bool expandLoadSingleImmToFPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
245 const MCSubtargetInfo *STI);
246 bool expandLoadDoubleImmToGPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
247 const MCSubtargetInfo *STI);
248 bool expandLoadDoubleImmToFPR(MCInst &Inst,
bool Is64FPU, SMLoc IDLoc,
249 MCStreamer &Out,
const MCSubtargetInfo *STI);
251 bool expandLoadAddress(MCRegister DstReg, MCRegister BaseReg,
252 const MCOperand &
Offset,
bool Is32BitAddress,
253 SMLoc IDLoc, MCStreamer &Out,
254 const MCSubtargetInfo *STI);
256 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
257 const MCSubtargetInfo *STI);
259 void expandMem16Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
260 const MCSubtargetInfo *STI,
bool IsLoad);
261 void expandMem9Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
262 const MCSubtargetInfo *STI,
bool IsLoad);
264 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
265 const MCSubtargetInfo *STI);
267 bool expandAliasImmediate(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
268 const MCSubtargetInfo *STI);
270 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
271 const MCSubtargetInfo *STI);
273 bool expandCondBranches(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
274 const MCSubtargetInfo *STI);
276 bool expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
277 const MCSubtargetInfo *STI,
const bool IsMips64,
280 bool expandTrunc(MCInst &Inst,
bool IsDouble,
bool Is64FPU, SMLoc IDLoc,
281 MCStreamer &Out,
const MCSubtargetInfo *STI);
283 bool expandUlh(MCInst &Inst,
bool Signed, SMLoc IDLoc, MCStreamer &Out,
284 const MCSubtargetInfo *STI);
286 bool expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
287 const MCSubtargetInfo *STI);
289 bool expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
290 const MCSubtargetInfo *STI);
292 bool expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
293 const MCSubtargetInfo *STI);
295 bool expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
296 const MCSubtargetInfo *STI);
298 bool expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
299 const MCSubtargetInfo *STI);
301 bool expandSle(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
302 const MCSubtargetInfo *STI);
304 bool expandSleImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
305 const MCSubtargetInfo *STI);
307 bool expandRotation(MCInst &Inst, SMLoc IDLoc,
308 MCStreamer &Out,
const MCSubtargetInfo *STI);
309 bool expandRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
310 const MCSubtargetInfo *STI);
311 bool expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
312 const MCSubtargetInfo *STI);
313 bool expandDRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
314 const MCSubtargetInfo *STI);
316 bool expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
317 const MCSubtargetInfo *STI);
319 bool expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
320 const MCSubtargetInfo *STI);
322 bool expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
323 const MCSubtargetInfo *STI);
325 bool expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
326 const MCSubtargetInfo *STI);
328 bool expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
329 const MCSubtargetInfo *STI);
331 bool expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
332 const MCSubtargetInfo *STI,
bool IsLoad);
334 bool expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
335 const MCSubtargetInfo *STI);
337 bool expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
338 const MCSubtargetInfo *STI);
340 bool expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
341 const MCSubtargetInfo *STI);
343 bool expandSne(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
344 const MCSubtargetInfo *STI);
346 bool expandSneI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
347 const MCSubtargetInfo *STI);
349 bool expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
350 const MCSubtargetInfo *STI);
352 bool expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
353 const MCSubtargetInfo *STI);
355 bool reportParseError(
const Twine &ErrorMsg);
356 bool reportParseError(SMLoc Loc,
const Twine &ErrorMsg);
358 bool parseSetMips0Directive();
359 bool parseSetArchDirective();
360 bool parseSetFeature(uint64_t Feature);
361 bool isPicAndNotNxxAbi();
362 bool parseDirectiveCpAdd(SMLoc Loc);
363 bool parseDirectiveCpLoad(SMLoc Loc);
364 bool parseDirectiveCpLocal(SMLoc Loc);
365 bool parseDirectiveCpRestore(SMLoc Loc);
366 bool parseDirectiveCPSetup();
367 bool parseDirectiveCPReturn();
368 bool parseDirectiveNaN();
369 bool parseDirectiveSet();
370 bool parseDirectiveOption();
371 bool parseInsnDirective();
372 bool parseRSectionDirective(StringRef Section);
373 bool parseSSectionDirective(StringRef Section,
unsigned Type);
375 bool parseSetAtDirective();
376 bool parseSetNoAtDirective();
377 bool parseSetMacroDirective();
378 bool parseSetNoMacroDirective();
379 bool parseSetMsaDirective();
380 bool parseSetNoMsaDirective();
381 bool parseSetNoDspDirective();
382 bool parseSetNoMips3DDirective();
383 bool parseSetReorderDirective();
384 bool parseSetNoReorderDirective();
385 bool parseSetMips16Directive();
386 bool parseSetNoMips16Directive();
387 bool parseSetFpDirective();
388 bool parseSetOddSPRegDirective();
389 bool parseSetNoOddSPRegDirective();
390 bool parseSetPopDirective();
391 bool parseSetPushDirective();
392 bool parseSetSoftFloatDirective();
393 bool parseSetHardFloatDirective();
394 bool parseSetMtDirective();
395 bool parseSetNoMtDirective();
396 bool parseSetNoCRCDirective();
397 bool parseSetNoVirtDirective();
398 bool parseSetNoGINVDirective();
400 bool parseSetAssignment();
402 bool parseDirectiveGpWord();
403 bool parseDirectiveGpDWord();
404 bool parseDirectiveDtpRelWord();
405 bool parseDirectiveDtpRelDWord();
406 bool parseDirectiveTpRelWord();
407 bool parseDirectiveTpRelDWord();
408 bool parseDirectiveModule();
409 bool parseDirectiveModuleFP();
411 StringRef Directive);
413 bool parseInternalDirectiveReallowModule();
415 bool eatComma(StringRef ErrorStr);
417 int matchCPURegisterName(StringRef Symbol);
419 int matchHWRegsRegisterName(StringRef Symbol);
421 int matchFPURegisterName(StringRef Name);
423 int matchFCCRegisterName(StringRef Name);
425 int matchACRegisterName(StringRef Name);
427 int matchMSA128RegisterName(StringRef Name);
429 int matchMSA128CtrlRegisterName(StringRef Name);
431 MCRegister
getReg(
int RC,
int RegNo);
436 MCRegister getATReg(SMLoc Loc);
440 bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
441 const MCSubtargetInfo *STI);
446 bool validateMSAIndex(
int Val,
int RegKind);
470 void selectArch(StringRef ArchFeature) {
471 MCSubtargetInfo &STI = copySTI();
473 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
475 setAvailableFeatures(
480 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
481 if (!(getSTI().hasFeature(Feature))) {
482 MCSubtargetInfo &STI = copySTI();
483 setAvailableFeatures(
489 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
490 if (getSTI().hasFeature(Feature)) {
491 MCSubtargetInfo &STI = copySTI();
492 setAvailableFeatures(
498 void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
499 setFeatureBits(Feature, FeatureString);
500 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
503 void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
504 clearFeatureBits(Feature, FeatureString);
505 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
509 enum MipsMatchResultTy {
510 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
511 Match_RequiresDifferentOperands,
512 Match_RequiresNoZeroRegister,
513 Match_RequiresSameSrcAndDst,
514 Match_NoFCCRegisterForCurrentISA,
515 Match_NonZeroOperandForSync,
516 Match_NonZeroOperandForMTCX,
517 Match_RequiresPosSizeRange0_32,
518 Match_RequiresPosSizeRange33_64,
519 Match_RequiresPosSizeUImm6,
520#define GET_OPERAND_DIAGNOSTIC_TYPES
521#include "MipsGenAsmMatcher.inc"
522#undef GET_OPERAND_DIAGNOSTIC_TYPES
525 MipsAsmParser(
const MCSubtargetInfo &sti, MCAsmParser &parser,
526 const MCInstrInfo &MII,
const MCTargetOptions &
Options)
527 : MCTargetAsmParser(
Options, sti, MII),
538 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
541 AssemblerOptions.push_back(
542 std::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
545 AssemblerOptions.push_back(
546 std::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
548 getTargetStreamer().updateABIInfo(*
this);
550 if (!isABI_O32() && !useOddSPReg() != 0)
555 CurForbiddenSlotAttr =
false;
556 IsPicEnabled =
getContext().getObjectFileInfo()->isPositionIndependent();
558 IsCpRestoreSet =
false;
559 CpRestoreOffset = -1;
560 GPReg = ABI.GetGlobalPtr();
565 if (getSTI().
getCPU() ==
"mips64r6" && inMicroMipsMode())
568 if (!isABI_O32() && inMicroMipsMode())
573 bool hasEightFccRegisters()
const {
return hasMips4() || hasMips32(); }
575 bool isGP64bit()
const {
576 return getSTI().hasFeature(Mips::FeatureGP64Bit);
579 bool isFP64bit()
const {
580 return getSTI().hasFeature(Mips::FeatureFP64Bit);
583 bool isJalrRelocAvailable(
const MCExpr *JalExpr) {
592 return ABI.IsN32() || ABI.IsN64();
596 const MipsABIInfo &getABI()
const {
return ABI; }
597 bool isABI_N32()
const {
return ABI.IsN32(); }
598 bool isABI_N64()
const {
return ABI.IsN64(); }
599 bool isABI_O32()
const {
return ABI.IsO32(); }
600 bool isABI_FPXX()
const {
601 return getSTI().hasFeature(Mips::FeatureFPXX);
604 bool useOddSPReg()
const {
605 return !(getSTI().hasFeature(Mips::FeatureNoOddSPReg));
608 bool inMicroMipsMode()
const {
609 return getSTI().hasFeature(Mips::FeatureMicroMips);
612 bool hasMips1()
const {
613 return getSTI().hasFeature(Mips::FeatureMips1);
616 bool hasMips2()
const {
617 return getSTI().hasFeature(Mips::FeatureMips2);
620 bool hasMips3()
const {
621 return getSTI().hasFeature(Mips::FeatureMips3);
624 bool hasMips4()
const {
625 return getSTI().hasFeature(Mips::FeatureMips4);
628 bool hasMips5()
const {
629 return getSTI().hasFeature(Mips::FeatureMips5);
632 bool hasMips32()
const {
633 return getSTI().hasFeature(Mips::FeatureMips32);
636 bool hasMips64()
const {
637 return getSTI().hasFeature(Mips::FeatureMips64);
640 bool hasMips32r2()
const {
641 return getSTI().hasFeature(Mips::FeatureMips32r2);
644 bool hasMips64r2()
const {
645 return getSTI().hasFeature(Mips::FeatureMips64r2);
648 bool hasMips32r3()
const {
649 return (getSTI().hasFeature(Mips::FeatureMips32r3));
652 bool hasMips64r3()
const {
653 return (getSTI().hasFeature(Mips::FeatureMips64r3));
656 bool hasMips32r5()
const {
657 return (getSTI().hasFeature(Mips::FeatureMips32r5));
660 bool hasMips64r5()
const {
661 return (getSTI().hasFeature(Mips::FeatureMips64r5));
664 bool hasMips32r6()
const {
665 return getSTI().hasFeature(Mips::FeatureMips32r6);
668 bool hasMips64r6()
const {
669 return getSTI().hasFeature(Mips::FeatureMips64r6);
672 bool hasDSP()
const {
673 return getSTI().hasFeature(Mips::FeatureDSP);
676 bool hasDSPR2()
const {
677 return getSTI().hasFeature(Mips::FeatureDSPR2);
680 bool hasDSPR3()
const {
681 return getSTI().hasFeature(Mips::FeatureDSPR3);
684 bool hasMSA()
const {
685 return getSTI().hasFeature(Mips::FeatureMSA);
688 bool hasCnMips()
const {
689 return (getSTI().hasFeature(Mips::FeatureCnMips));
692 bool hasCnMipsP()
const {
693 return (getSTI().hasFeature(Mips::FeatureCnMipsP));
696 bool isR5900()
const {
return (getSTI().hasFeature(Mips::FeatureR5900)); }
702 bool inMips16Mode()
const {
703 return getSTI().hasFeature(Mips::FeatureMips16);
706 bool useTraps()
const {
707 return getSTI().hasFeature(Mips::FeatureUseTCCInDIV);
710 bool useSoftFloat()
const {
711 return getSTI().hasFeature(Mips::FeatureSoftFloat);
714 bool isSingleFloat()
const {
715 return getSTI().hasFeature(Mips::FeatureSingleFloat);
719 return getSTI().hasFeature(Mips::FeatureMT);
722 bool hasCRC()
const {
723 return getSTI().hasFeature(Mips::FeatureCRC);
726 bool hasVirt()
const {
727 return getSTI().hasFeature(Mips::FeatureVirt);
730 bool hasGINV()
const {
731 return getSTI().hasFeature(Mips::FeatureGINV);
734 bool hasForbiddenSlot(
const MCInstrDesc &MCID)
const {
738 bool SafeInForbiddenSlot(
const MCInstrDesc &MCID)
const {
742 void onEndOfFile()
override;
745 void warnIfRegIndexIsAT(MCRegister RegIndex, SMLoc Loc);
747 void warnIfNoMacro(SMLoc Loc);
749 bool isLittle()
const {
return IsLittleEndian; }
751 bool areEqualRegs(
const MCParsedAsmOperand &Op1,
752 const MCParsedAsmOperand &Op2)
const override;
767 RegKind_MSACtrl = 16,
772 RegKind_HWRegs = 256,
776 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
777 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
778 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
791 MipsOperand(KindTy K, MipsAsmParser &Parser) : Kind(
K), AsmParser(Parser) {}
793 ~MipsOperand()
override {
802 case k_RegisterIndex:
810 MipsAsmParser &AsmParser;
821 const MCRegisterInfo *RegInfo;
839 struct RegIdxOp RegIdx;
842 struct RegListOp RegList;
845 SMLoc StartLoc, EndLoc;
848 static std::unique_ptr<MipsOperand> CreateReg(
unsigned Index, StringRef Str,
850 const MCRegisterInfo *RegInfo,
852 MipsAsmParser &Parser) {
853 auto Op = std::make_unique<MipsOperand>(k_RegisterIndex, Parser);
855 Op->RegIdx.RegInfo = RegInfo;
856 Op->RegIdx.Kind = RegKind;
857 Op->RegIdx.Tok.Data = Str.data();
858 Op->RegIdx.Tok.Length = Str.size();
867 MCRegister getGPR32Reg()
const {
868 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
869 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
870 unsigned ClassID = Mips::GPR32RegClassID;
871 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
876 MCRegister getGPRMM16Reg()
const {
877 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
878 unsigned ClassID = Mips::GPR32RegClassID;
879 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
884 MCRegister getGPR64Reg()
const {
885 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
886 unsigned ClassID = Mips::GPR64RegClassID;
887 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
893 MCRegister getAFGR64Reg()
const {
894 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
895 if (RegIdx.Index % 2 != 0)
896 AsmParser.Warning(StartLoc,
"Float register should be even.");
897 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
898 .getRegister(RegIdx.Index / 2);
903 MCRegister getFGR64Reg()
const {
904 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
905 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
906 .getRegister(RegIdx.Index);
911 MCRegister getFGR32Reg()
const {
912 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
913 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
914 .getRegister(RegIdx.Index);
919 MCRegister getFCCReg()
const {
920 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) &&
"Invalid access!");
921 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
922 .getRegister(RegIdx.Index);
927 MCRegister getMSA128Reg()
const {
928 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) &&
"Invalid access!");
931 unsigned ClassID = Mips::MSA128BRegClassID;
932 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
937 MCRegister getMSACtrlReg()
const {
938 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) &&
"Invalid access!");
939 unsigned ClassID = Mips::MSACtrlRegClassID;
940 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
945 MCRegister getCOP0Reg()
const {
946 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) &&
"Invalid access!");
947 unsigned ClassID = Mips::COP0RegClassID;
948 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
953 MCRegister getCOP2Reg()
const {
954 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) &&
"Invalid access!");
955 unsigned ClassID = Mips::COP2RegClassID;
956 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
961 MCRegister getCOP3Reg()
const {
962 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) &&
"Invalid access!");
963 unsigned ClassID = Mips::COP3RegClassID;
964 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
969 MCRegister getACC64DSPReg()
const {
970 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
971 unsigned ClassID = Mips::ACC64DSPRegClassID;
972 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
977 MCRegister getHI32DSPReg()
const {
978 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
979 unsigned ClassID = Mips::HI32DSPRegClassID;
980 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
985 MCRegister getLO32DSPReg()
const {
986 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
987 unsigned ClassID = Mips::LO32DSPRegClassID;
988 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
993 MCRegister getCCRReg()
const {
994 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) &&
"Invalid access!");
995 unsigned ClassID = Mips::CCRRegClassID;
996 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1001 MCRegister getHWRegsReg()
const {
1002 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) &&
"Invalid access!");
1003 unsigned ClassID = Mips::HWRegsRegClassID;
1004 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1008 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const {
1018 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1025 void addGPR32ZeroAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1026 assert(
N == 1 &&
"Invalid number of operands!");
1030 void addGPR32NonZeroAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1031 assert(
N == 1 &&
"Invalid number of operands!");
1035 void addGPR32AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1036 assert(
N == 1 &&
"Invalid number of operands!");
1040 void addGPRMM16AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1041 assert(
N == 1 &&
"Invalid number of operands!");
1045 void addGPRMM16AsmRegZeroOperands(MCInst &Inst,
unsigned N)
const {
1046 assert(
N == 1 &&
"Invalid number of operands!");
1050 void addGPRMM16AsmRegMovePOperands(MCInst &Inst,
unsigned N)
const {
1051 assert(
N == 1 &&
"Invalid number of operands!");
1055 void addGPRMM16AsmRegMovePPairFirstOperands(MCInst &Inst,
unsigned N)
const {
1056 assert(
N == 1 &&
"Invalid number of operands!");
1060 void addGPRMM16AsmRegMovePPairSecondOperands(MCInst &Inst,
1062 assert(
N == 1 &&
"Invalid number of operands!");
1069 void addGPR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1070 assert(
N == 1 &&
"Invalid number of operands!");
1074 void addAFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1075 assert(
N == 1 &&
"Invalid number of operands!");
1079 void addStrictlyAFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1080 assert(
N == 1 &&
"Invalid number of operands!");
1084 void addStrictlyFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1085 assert(
N == 1 &&
"Invalid number of operands!");
1089 void addFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1090 assert(
N == 1 &&
"Invalid number of operands!");
1094 void addFGR32AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1095 assert(
N == 1 &&
"Invalid number of operands!");
1099 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1100 AsmParser.getParser().printError(
1101 StartLoc,
"-mno-odd-spreg prohibits the use of odd FPU "
1105 void addStrictlyFGR32AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1106 assert(
N == 1 &&
"Invalid number of operands!");
1109 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1110 AsmParser.Error(StartLoc,
"-mno-odd-spreg prohibits the use of odd FPU "
1114 void addFCCAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1115 assert(
N == 1 &&
"Invalid number of operands!");
1119 void addMSA128AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1120 assert(
N == 1 &&
"Invalid number of operands!");
1124 void addMSACtrlAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1125 assert(
N == 1 &&
"Invalid number of operands!");
1129 void addCOP0AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1130 assert(
N == 1 &&
"Invalid number of operands!");
1134 void addCOP2AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1135 assert(
N == 1 &&
"Invalid number of operands!");
1139 void addCOP3AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1140 assert(
N == 1 &&
"Invalid number of operands!");
1144 void addACC64DSPAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1145 assert(
N == 1 &&
"Invalid number of operands!");
1149 void addHI32DSPAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1150 assert(
N == 1 &&
"Invalid number of operands!");
1154 void addLO32DSPAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1155 assert(
N == 1 &&
"Invalid number of operands!");
1159 void addCCRAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1160 assert(
N == 1 &&
"Invalid number of operands!");
1164 void addHWRegsAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1165 assert(
N == 1 &&
"Invalid number of operands!");
1169 template <
unsigned Bits,
int Offset = 0,
int AdjustOffset = 0>
1170 void addConstantUImmOperands(MCInst &Inst,
unsigned N)
const {
1171 assert(
N == 1 &&
"Invalid number of operands!");
1172 uint64_t
Imm = getConstantImm() -
Offset;
1175 Imm += AdjustOffset;
1179 template <
unsigned Bits>
1180 void addSImmOperands(MCInst &Inst,
unsigned N)
const {
1181 if (isImm() && !isConstantImm()) {
1185 addConstantSImmOperands<Bits, 0, 0>(Inst,
N);
1188 template <
unsigned Bits>
1189 void addUImmOperands(MCInst &Inst,
unsigned N)
const {
1190 if (isImm() && !isConstantImm()) {
1194 addConstantUImmOperands<Bits, 0, 0>(Inst,
N);
1197 template <
unsigned Bits,
int Offset = 0,
int AdjustOffset = 0>
1198 void addConstantSImmOperands(MCInst &Inst,
unsigned N)
const {
1199 assert(
N == 1 &&
"Invalid number of operands!");
1200 int64_t
Imm = getConstantImm() -
Offset;
1203 Imm += AdjustOffset;
1207 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1208 assert(
N == 1 &&
"Invalid number of operands!");
1209 const MCExpr *Expr =
getImm();
1210 addExpr(Inst, Expr);
1213 void addMemOperands(MCInst &Inst,
unsigned N)
const {
1214 assert(
N == 2 &&
"Invalid number of operands!");
1217 ? getMemBase()->getGPR64Reg()
1218 : getMemBase()->getGPR32Reg()));
1220 const MCExpr *Expr = getMemOff();
1221 addExpr(Inst, Expr);
1224 void addMicroMipsMemOperands(MCInst &Inst,
unsigned N)
const {
1225 assert(
N == 2 &&
"Invalid number of operands!");
1229 const MCExpr *Expr = getMemOff();
1230 addExpr(Inst, Expr);
1233 void addRegListOperands(MCInst &Inst,
unsigned N)
const {
1234 assert(
N == 1 &&
"Invalid number of operands!");
1236 for (
auto RegNo : getRegList())
1240 bool isReg()
const override {
1243 return isGPRAsmReg() && RegIdx.Index == 0;
1246 bool isRegIdx()
const {
return Kind == k_RegisterIndex; }
1247 bool isImm()
const override {
return Kind == k_Immediate; }
1249 bool isConstantImm()
const {
1251 return isImm() &&
getImm()->evaluateAsAbsolute(Res);
1254 bool isConstantImmz()
const {
1255 return isConstantImm() && getConstantImm() == 0;
1258 template <
unsigned Bits,
int Offset = 0>
bool isConstantUImm()
const {
1262 template <
unsigned Bits>
bool isSImm()
const {
1266 if (
getImm()->evaluateAsAbsolute(Res))
1272 template <
unsigned Bits>
bool isUImm()
const {
1276 if (
getImm()->evaluateAsAbsolute(Res))
1282 template <
unsigned Bits>
bool isAnyImm()
const {
1283 return isConstantImm() ? (
isInt<Bits>(getConstantImm()) ||
1288 template <
unsigned Bits,
int Offset = 0>
bool isConstantSImm()
const {
1292 template <
unsigned Bottom,
unsigned Top>
bool isConstantUImmRange()
const {
1293 return isConstantImm() && getConstantImm() >= Bottom &&
1294 getConstantImm() <= Top;
1297 bool isToken()
const override {
1300 return Kind == k_Token;
1303 bool isMem()
const override {
return Kind == k_Memory; }
1305 bool isConstantMemOff()
const {
1310 template <
unsigned Bits,
unsigned ShiftAmount = 0>
1311 bool isMemWithSimmOffset()
const {
1314 if (!getMemBase()->isGPRAsmReg())
1317 (isConstantMemOff() &&
1321 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res,
nullptr);
1325 bool isMemWithPtrSizeOffset()
const {
1328 if (!getMemBase()->isGPRAsmReg())
1330 const unsigned PtrBits = AsmParser.getABI().ArePtrs64bit() ? 64 : 32;
1332 (isConstantMemOff() &&
isIntN(PtrBits, getConstantMemOff())))
1335 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res,
nullptr);
1339 bool isMemWithGRPMM16Base()
const {
1340 return isMem() && getMemBase()->isMM16AsmReg();
1343 template <
unsigned Bits>
bool isMemWithUimmOffsetSP()
const {
1345 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1348 template <
unsigned Bits>
bool isMemWithUimmWordAlignedOffsetSP()
const {
1350 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1351 && (getMemBase()->getGPR32Reg() == Mips::SP);
1354 template <
unsigned Bits>
bool isMemWithSimmWordAlignedOffsetGP()
const {
1356 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1357 && (getMemBase()->getGPR32Reg() == Mips::GP);
1360 template <
unsigned Bits,
unsigned ShiftLeftAmount>
1361 bool isScaledUImm()
const {
1362 return isConstantImm() &&
1366 template <
unsigned Bits,
unsigned ShiftLeftAmount>
1367 bool isScaledSImm()
const {
1368 if (isConstantImm() &&
1373 if (Kind != k_Immediate)
1376 bool Success =
getImm()->evaluateAsRelocatable(Res,
nullptr);
1380 bool isRegList16()
const {
1384 int Size = RegList.List->size();
1388 MCRegister R0 = RegList.List->front();
1389 MCRegister R1 = RegList.List->back();
1390 if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1391 (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1394 MCRegister PrevReg = RegList.List->front();
1395 for (
int i = 1; i <
Size - 1; i++) {
1396 MCRegister
Reg = (*(RegList.List))[i];
1397 if (
Reg != PrevReg + 1)
1405 bool isInvNum()
const {
return Kind == k_Immediate; }
1407 bool isLSAImm()
const {
1408 if (!isConstantImm())
1410 int64_t Val = getConstantImm();
1411 return 1 <= Val && Val <= 4;
1414 bool isRegList()
const {
return Kind == k_RegList; }
1417 assert(Kind == k_Token &&
"Invalid access!");
1418 return StringRef(Tok.Data, Tok.Length);
1421 MCRegister
getReg()
const override {
1424 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1425 RegIdx.Kind & RegKind_GPR)
1426 return getGPR32Reg();
1432 const MCExpr *
getImm()
const {
1433 assert((Kind == k_Immediate) &&
"Invalid access!");
1437 int64_t getConstantImm()
const {
1438 const MCExpr *Val =
getImm();
1440 (void)Val->evaluateAsAbsolute(
Value);
1444 MipsOperand *getMemBase()
const {
1445 assert((Kind == k_Memory) &&
"Invalid access!");
1449 const MCExpr *getMemOff()
const {
1450 assert((Kind == k_Memory) &&
"Invalid access!");
1454 int64_t getConstantMemOff()
const {
1455 return static_cast<const MCConstantExpr *
>(getMemOff())->getValue();
1458 const SmallVectorImpl<MCRegister> &getRegList()
const {
1459 assert((Kind == k_RegList) &&
"Invalid access!");
1460 return *(RegList.List);
1463 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1464 MipsAsmParser &Parser) {
1465 auto Op = std::make_unique<MipsOperand>(k_Token, Parser);
1466 Op->Tok.Data = Str.data();
1467 Op->Tok.Length = Str.size();
1475 static std::unique_ptr<MipsOperand>
1476 createNumericReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1477 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1478 LLVM_DEBUG(
dbgs() <<
"createNumericReg(" << Index <<
", ...)\n");
1479 return CreateReg(Index, Str, RegKind_Numeric, RegInfo, S,
E, Parser);
1484 static std::unique_ptr<MipsOperand>
1485 createGPRReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1486 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1487 return CreateReg(Index, Str, RegKind_GPR, RegInfo, S,
E, Parser);
1492 static std::unique_ptr<MipsOperand>
1493 createFGRReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1494 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1495 return CreateReg(Index, Str, RegKind_FGR, RegInfo, S,
E, Parser);
1500 static std::unique_ptr<MipsOperand>
1501 createHWRegsReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1502 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1503 return CreateReg(Index, Str, RegKind_HWRegs, RegInfo, S,
E, Parser);
1508 static std::unique_ptr<MipsOperand>
1509 createFCCReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1510 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1511 return CreateReg(Index, Str, RegKind_FCC, RegInfo, S,
E, Parser);
1516 static std::unique_ptr<MipsOperand>
1517 createACCReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1518 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1519 return CreateReg(Index, Str, RegKind_ACC, RegInfo, S,
E, Parser);
1524 static std::unique_ptr<MipsOperand>
1525 createMSA128Reg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1526 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1527 return CreateReg(Index, Str, RegKind_MSA128, RegInfo, S,
E, Parser);
1532 static std::unique_ptr<MipsOperand>
1533 createMSACtrlReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1534 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1535 return CreateReg(Index, Str, RegKind_MSACtrl, RegInfo, S,
E, Parser);
1538 static std::unique_ptr<MipsOperand>
1539 CreateImm(
const MCExpr *Val, SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1540 auto Op = std::make_unique<MipsOperand>(k_Immediate, Parser);
1547 static std::unique_ptr<MipsOperand>
1548 CreateMem(std::unique_ptr<MipsOperand>
Base,
const MCExpr *Off, SMLoc S,
1549 SMLoc
E, MipsAsmParser &Parser) {
1550 auto Op = std::make_unique<MipsOperand>(k_Memory, Parser);
1551 Op->Mem.Base =
Base.release();
1558 static std::unique_ptr<MipsOperand>
1559 CreateRegList(SmallVectorImpl<MCRegister> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1560 MipsAsmParser &Parser) {
1561 assert(!Regs.
empty() &&
"Empty list not allowed");
1563 auto Op = std::make_unique<MipsOperand>(k_RegList, Parser);
1566 Op->StartLoc = StartLoc;
1567 Op->EndLoc = EndLoc;
1571 bool isGPRZeroAsmReg()
const {
1572 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
1575 bool isGPRNonZeroAsmReg()
const {
1576 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index > 0 &&
1580 bool isGPRAsmReg()
const {
1581 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1584 bool isMM16AsmReg()
const {
1585 if (!(isRegIdx() && RegIdx.Kind))
1587 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1588 || RegIdx.Index == 16 || RegIdx.Index == 17);
1591 bool isMM16AsmRegZero()
const {
1592 if (!(isRegIdx() && RegIdx.Kind))
1594 return (RegIdx.Index == 0 ||
1595 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1596 RegIdx.Index == 17);
1599 bool isMM16AsmRegMoveP()
const {
1600 if (!(isRegIdx() && RegIdx.Kind))
1602 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1603 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1606 bool isMM16AsmRegMovePPairFirst()
const {
1607 if (!(isRegIdx() && RegIdx.Kind))
1609 return RegIdx.Index >= 4 && RegIdx.Index <= 6;
1612 bool isMM16AsmRegMovePPairSecond()
const {
1613 if (!(isRegIdx() && RegIdx.Kind))
1615 return (RegIdx.Index == 21 || RegIdx.Index == 22 ||
1616 (RegIdx.Index >= 5 && RegIdx.Index <= 7));
1619 bool isFGRAsmReg()
const {
1621 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1624 bool isStrictlyFGRAsmReg()
const {
1626 return isRegIdx() && RegIdx.Kind == RegKind_FGR && RegIdx.Index <= 31;
1629 bool isHWRegsAsmReg()
const {
1630 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1633 bool isCCRAsmReg()
const {
1634 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1637 bool isFCCAsmReg()
const {
1638 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1640 return RegIdx.Index <= 7;
1643 bool isACCAsmReg()
const {
1644 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1647 bool isCOP0AsmReg()
const {
1648 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1651 bool isCOP2AsmReg()
const {
1652 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1655 bool isCOP3AsmReg()
const {
1656 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1659 bool isMSA128AsmReg()
const {
1660 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1663 bool isMSACtrlAsmReg()
const {
1664 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1668 SMLoc getStartLoc()
const override {
return StartLoc; }
1670 SMLoc getEndLoc()
const override {
return EndLoc; }
1672 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1681 Mem.Base->print(OS, MAI);
1686 case k_RegisterIndex:
1687 OS <<
"RegIdx<" << RegIdx.Index <<
":" << RegIdx.Kind <<
", "
1688 << StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) <<
">";
1695 for (
auto Reg : (*RegList.List))
1696 OS <<
Reg.
id() <<
" ";
1702 bool isValidForTie(
const MipsOperand &
Other)
const {
1703 if (Kind !=
Other.Kind)
1710 case k_RegisterIndex: {
1711 StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length);
1712 StringRef OtherToken(
Other.RegIdx.Tok.Data,
Other.RegIdx.Tok.Length);
1713 return Token == OtherToken;
1729 case Mips::JRC16_MM:
1731 case Mips::JALRS_MM:
1732 case Mips::JALRS16_MM:
1733 case Mips::BGEZALS_MM:
1734 case Mips::BLTZALS_MM:
1745 return &SRExpr->getSymbol();
1804 unsigned NumOp =
MCID.getNumOperands();
1805 if (NumOp != 3 && NumOp != 4)
1835bool MipsAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
1838 MipsTargetStreamer &TOut = getTargetStreamer();
1839 const unsigned Opcode = Inst.
getOpcode();
1840 const MCInstrDesc &MCID = MII.get(Opcode);
1841 bool ExpandedJalSym =
false;
1855 assert(hasCnMips() &&
"instruction only valid for octeon cpus");
1866 if (!
isIntN(inMicroMipsMode() ? 17 : 18,
Offset.getImm()))
1867 return Error(IDLoc,
"branch target out of range");
1870 return Error(IDLoc,
"branch to misaligned address");
1884 case Mips::BGEZAL_MM:
1885 case Mips::BLTZAL_MM:
1888 case Mips::BC1EQZC_MMR6:
1889 case Mips::BC1NEZC_MMR6:
1890 case Mips::BC2EQZC_MMR6:
1891 case Mips::BC2NEZC_MMR6:
1896 if (!
isIntN(inMicroMipsMode() ? 17 : 18,
Offset.getImm()))
1897 return Error(IDLoc,
"branch target out of range");
1900 return Error(IDLoc,
"branch to misaligned address");
1902 case Mips::BGEC:
case Mips::BGEC_MMR6:
1903 case Mips::BLTC:
case Mips::BLTC_MMR6:
1904 case Mips::BGEUC:
case Mips::BGEUC_MMR6:
1905 case Mips::BLTUC:
case Mips::BLTUC_MMR6:
1906 case Mips::BEQC:
case Mips::BEQC_MMR6:
1907 case Mips::BNEC:
case Mips::BNEC_MMR6:
1913 return Error(IDLoc,
"branch target out of range");
1915 return Error(IDLoc,
"branch to misaligned address");
1917 case Mips::BLEZC:
case Mips::BLEZC_MMR6:
1918 case Mips::BGEZC:
case Mips::BGEZC_MMR6:
1919 case Mips::BGTZC:
case Mips::BGTZC_MMR6:
1920 case Mips::BLTZC:
case Mips::BLTZC_MMR6:
1926 return Error(IDLoc,
"branch target out of range");
1928 return Error(IDLoc,
"branch to misaligned address");
1930 case Mips::BEQZC:
case Mips::BEQZC_MMR6:
1931 case Mips::BNEZC:
case Mips::BNEZC_MMR6:
1937 return Error(IDLoc,
"branch target out of range");
1939 return Error(IDLoc,
"branch to misaligned address");
1941 case Mips::BEQZ16_MM:
1942 case Mips::BEQZC16_MMR6:
1943 case Mips::BNEZ16_MM:
1944 case Mips::BNEZC16_MMR6:
1950 return Error(IDLoc,
"branch target out of range");
1952 return Error(IDLoc,
"branch to misaligned address");
1959 if (hasMips32r6() && Opcode == Mips::SSNOP) {
1960 std::string
ISA = hasMips64r6() ?
"MIPS64r6" :
"MIPS32r6";
1961 Warning(IDLoc,
"ssnop is deprecated for " + ISA +
" and is equivalent to a "
1981 return Error(IDLoc,
"expected immediate operand kind");
1983 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1984 Opcode == Mips::BBIT1 ? 63 : 31))
1985 return Error(IDLoc,
"immediate operand value out of range");
1987 Inst.
setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1998 return Error(IDLoc,
"expected immediate operand kind");
2001 return Error(IDLoc,
"immediate operand value out of range");
2013 unsigned FirstOp = 1;
2014 unsigned SecondOp = 2;
2018 case Mips::SDivIMacro:
2019 case Mips::UDivIMacro:
2020 case Mips::DSDivIMacro:
2021 case Mips::DUDivIMacro:
2025 Warning(IDLoc,
"dividing zero by zero");
2027 Warning(IDLoc,
"division by zero");
2039 case Mips::SDivMacro:
2040 case Mips::DSDivMacro:
2041 case Mips::UDivMacro:
2042 case Mips::DUDivMacro:
2047 case Mips::DIVU_MMR6:
2048 case Mips::DIV_MMR6:
2053 Warning(IDLoc,
"dividing zero by zero");
2055 Warning(IDLoc,
"division by zero");
2061 if ((Opcode == Mips::J || Opcode == Mips::J_MM) && inPicMode()) {
2063 BInst.
setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
2072 if ((Opcode == Mips::JAL || Opcode == Mips::JAL_MM) && inPicMode()) {
2073 warnIfNoMacro(IDLoc);
2076 return Error(IDLoc,
"unsupported constant in relocation");
2084 return Error(IDLoc,
"jal doesn't support multiple symbols in PIC mode");
2090 if (expandLoadAddress(Mips::T9, MCRegister(), Inst.
getOperand(0),
2091 !isGP64bit(), IDLoc, Out, STI))
2095 if (inMicroMipsMode())
2096 JalrInst.
setOpcode(IsCpRestoreSet ? Mips::JALRS_MM : Mips::JALR_MM);
2102 if (isJalrRelocAvailable(JalExpr)) {
2108 const MCExpr *RelocJalrExpr =
2112 *TmpExpr, inMicroMipsMode() ?
"R_MICROMIPS_JALR" :
"R_MIPS_JALR",
2118 ExpandedJalSym =
true;
2127 expandMem9Inst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2130 expandMem16Inst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2133 return getParser().hasPendingError();
2137 if (inMicroMipsMode()) {
2138 if (MCID.
mayLoad() && Opcode != Mips::LWP_MM) {
2141 const MCOperandInfo &OpInfo = MCID.
operands()[i];
2146 int MemOffset =
Op.getImm();
2149 if (
isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
2152 (
BaseReg.getReg() == Mips::GP ||
2153 BaseReg.getReg() == Mips::GP_64)) {
2155 TOut.
emitRRI(Mips::LWGP_MM, DstReg.
getReg(), Mips::GP, MemOffset,
2172 case Mips::ADDIUSP_MM:
2175 return Error(IDLoc,
"expected immediate operand kind");
2177 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
2179 return Error(IDLoc,
"immediate operand value out of range");
2181 case Mips::SLL16_MM:
2182 case Mips::SRL16_MM:
2185 return Error(IDLoc,
"expected immediate operand kind");
2187 if (Imm < 1 || Imm > 8)
2188 return Error(IDLoc,
"immediate operand value out of range");
2193 return Error(IDLoc,
"expected immediate operand kind");
2195 if (Imm < -1 || Imm > 126)
2196 return Error(IDLoc,
"immediate operand value out of range");
2198 case Mips::ADDIUR2_MM:
2201 return Error(IDLoc,
"expected immediate operand kind");
2203 if (!(Imm == 1 || Imm == -1 ||
2204 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
2205 return Error(IDLoc,
"immediate operand value out of range");
2207 case Mips::ANDI16_MM:
2210 return Error(IDLoc,
"expected immediate operand kind");
2212 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
2213 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
2214 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
2215 return Error(IDLoc,
"immediate operand value out of range");
2217 case Mips::LBU16_MM:
2220 return Error(IDLoc,
"expected immediate operand kind");
2222 if (Imm < -1 || Imm > 14)
2223 return Error(IDLoc,
"immediate operand value out of range");
2226 case Mips::SB16_MMR6:
2229 return Error(IDLoc,
"expected immediate operand kind");
2231 if (Imm < 0 || Imm > 15)
2232 return Error(IDLoc,
"immediate operand value out of range");
2234 case Mips::LHU16_MM:
2236 case Mips::SH16_MMR6:
2239 return Error(IDLoc,
"expected immediate operand kind");
2241 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
2242 return Error(IDLoc,
"immediate operand value out of range");
2246 case Mips::SW16_MMR6:
2249 return Error(IDLoc,
"expected immediate operand kind");
2251 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
2252 return Error(IDLoc,
"immediate operand value out of range");
2254 case Mips::ADDIUPC_MM:
2257 return Error(IDLoc,
"expected immediate operand kind");
2260 return Error(IDLoc,
"immediate operand value out of range");
2265 return Error(IDLoc,
"invalid operand for instruction");
2267 case Mips::MOVEP_MM:
2268 case Mips::MOVEP_MMR6: {
2271 bool RegPair = ((R0 == Mips::A1 && R1 == Mips::A2) ||
2272 (R0 == Mips::A1 && R1 == Mips::A3) ||
2273 (R0 == Mips::A2 && R1 == Mips::A3) ||
2274 (R0 == Mips::A0 && R1 == Mips::S5) ||
2275 (R0 == Mips::A0 && R1 == Mips::S6) ||
2276 (R0 == Mips::A0 && R1 == Mips::A1) ||
2277 (R0 == Mips::A0 && R1 == Mips::A2) ||
2278 (R0 == Mips::A0 && R1 == Mips::A3));
2280 return Error(IDLoc,
"invalid operand for instruction");
2286 bool FillDelaySlot =
2291 bool PrevForbiddenSlotAttr = CurForbiddenSlotAttr;
2294 bool SetReorderAfterNop =
false;
2299 if (PrevForbiddenSlotAttr && !SafeInForbiddenSlot(MCID)) {
2309 if (AssemblerOptions.
back()->isReorder() && !FillDelaySlot) {
2310 SetReorderAfterNop =
true;
2319 CurForbiddenSlotAttr =
2320 hasForbiddenSlot(MCID) && AssemblerOptions.
back()->isReorder();
2322 if (FillDelaySlot || CurForbiddenSlotAttr)
2325 MacroExpanderResultTy ExpandResult =
2326 tryExpandInstruction(Inst, IDLoc, Out, STI);
2327 switch (ExpandResult) {
2343 if (PrevForbiddenSlotAttr && !SetReorderAfterNop && !FillDelaySlot &&
2344 AssemblerOptions.
back()->isReorder()) {
2350 if (inMicroMipsMode()) {
2365 if (FillDelaySlot) {
2370 if ((Opcode == Mips::JalOneReg || Opcode == Mips::JalTwoReg ||
2372 isPicAndNotNxxAbi()) {
2373 if (IsCpRestoreSet) {
2377 if (!AssemblerOptions.
back()->isReorder())
2384 Warning(IDLoc,
"no .cprestore used in PIC mode");
2390void MipsAsmParser::onEndOfFile() {
2391 MipsTargetStreamer &TOut = getTargetStreamer();
2392 SMLoc IDLoc = SMLoc();
2394 if (CurForbiddenSlotAttr) {
2396 if (AssemblerOptions.
back()->isReorder())
2401MipsAsmParser::MacroExpanderResultTy
2402MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2403 const MCSubtargetInfo *STI) {
2406 return MER_NotAMacro;
2407 case Mips::LoadImm32:
2408 return expandLoadImm(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2409 case Mips::LoadImm64:
2410 return expandLoadImm(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2411 case Mips::LoadAddrImm32:
2412 case Mips::LoadAddrImm64:
2415 "expected immediate operand kind");
2417 return expandLoadAddress(
2419 Inst.
getOpcode() == Mips::LoadAddrImm32, IDLoc, Out, STI)
2422 case Mips::LoadAddrReg32:
2423 case Mips::LoadAddrReg64:
2427 "expected immediate operand kind");
2431 Inst.
getOpcode() == Mips::LoadAddrReg32, IDLoc,
2435 case Mips::B_MM_Pseudo:
2436 case Mips::B_MMR6_Pseudo:
2437 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2441 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2443 case Mips::JalOneReg:
2444 case Mips::JalTwoReg:
2445 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2448 case Mips::BEQLImmMacro:
2449 case Mips::BNELImmMacro:
2450 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2467 case Mips::BLTImmMacro:
2468 case Mips::BLEImmMacro:
2469 case Mips::BGEImmMacro:
2470 case Mips::BGTImmMacro:
2471 case Mips::BLTUImmMacro:
2472 case Mips::BLEUImmMacro:
2473 case Mips::BGEUImmMacro:
2474 case Mips::BGTUImmMacro:
2475 case Mips::BLTLImmMacro:
2476 case Mips::BLELImmMacro:
2477 case Mips::BGELImmMacro:
2478 case Mips::BGTLImmMacro:
2479 case Mips::BLTULImmMacro:
2480 case Mips::BLEULImmMacro:
2481 case Mips::BGEULImmMacro:
2482 case Mips::BGTULImmMacro:
2483 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2484 case Mips::SDivMacro:
2485 case Mips::SDivIMacro:
2486 case Mips::SRemMacro:
2487 case Mips::SRemIMacro:
2488 return expandDivRem(Inst, IDLoc, Out, STI,
false,
true) ? MER_Fail
2490 case Mips::DSDivMacro:
2491 case Mips::DSDivIMacro:
2492 case Mips::DSRemMacro:
2493 case Mips::DSRemIMacro:
2494 return expandDivRem(Inst, IDLoc, Out, STI,
true,
true) ? MER_Fail
2496 case Mips::UDivMacro:
2497 case Mips::UDivIMacro:
2498 case Mips::URemMacro:
2499 case Mips::URemIMacro:
2500 return expandDivRem(Inst, IDLoc, Out, STI,
false,
false) ? MER_Fail
2502 case Mips::DUDivMacro:
2503 case Mips::DUDivIMacro:
2504 case Mips::DURemMacro:
2505 case Mips::DURemIMacro:
2506 return expandDivRem(Inst, IDLoc, Out, STI,
true,
false) ? MER_Fail
2508 case Mips::PseudoTRUNC_W_S:
2509 return expandTrunc(Inst,
false,
false, IDLoc, Out, STI) ? MER_Fail
2511 case Mips::PseudoTRUNC_W_D32:
2512 return expandTrunc(Inst,
true,
false, IDLoc, Out, STI) ? MER_Fail
2514 case Mips::PseudoTRUNC_W_D:
2515 return expandTrunc(Inst,
true,
true, IDLoc, Out, STI) ? MER_Fail
2518 case Mips::LoadImmSingleGPR:
2519 return expandLoadSingleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2521 case Mips::LoadImmSingleFGR:
2522 return expandLoadSingleImmToFPR(Inst, IDLoc, Out, STI) ? MER_Fail
2524 case Mips::LoadImmDoubleGPR:
2525 return expandLoadDoubleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2527 case Mips::LoadImmDoubleFGR:
2528 return expandLoadDoubleImmToFPR(Inst,
true, IDLoc, Out, STI) ? MER_Fail
2530 case Mips::LoadImmDoubleFGR_32:
2531 return expandLoadDoubleImmToFPR(Inst,
false, IDLoc, Out, STI) ? MER_Fail
2535 return expandUlh(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2537 return expandUlh(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2539 return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2542 return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2544 case Mips::NORImm64:
2545 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2548 return expandSge(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2551 case Mips::SGEImm64:
2552 case Mips::SGEUImm64:
2553 return expandSgeImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2556 case Mips::SGTImm64:
2557 case Mips::SGTUImm64:
2558 return expandSgtImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2561 return expandSle(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2564 case Mips::SLEImm64:
2565 case Mips::SLEUImm64:
2566 return expandSleImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2567 case Mips::SLTImm64:
2570 return MER_NotAMacro;
2572 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2573 case Mips::SLTUImm64:
2576 return MER_NotAMacro;
2578 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2579 case Mips::ADDi:
case Mips::ADDi_MM:
2580 case Mips::ADDiu:
case Mips::ADDiu_MM:
2581 case Mips::SLTi:
case Mips::SLTi_MM:
2582 case Mips::SLTiu:
case Mips::SLTiu_MM:
2587 return MER_NotAMacro;
2588 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2591 return MER_NotAMacro;
2592 case Mips::ANDi:
case Mips::ANDi_MM:
case Mips::ANDi64:
2593 case Mips::ORi:
case Mips::ORi_MM:
case Mips::ORi64:
2594 case Mips::XORi:
case Mips::XORi_MM:
case Mips::XORi64:
2599 return MER_NotAMacro;
2600 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2603 return MER_NotAMacro;
2606 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2609 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2612 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2615 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2616 case Mips::ABSMacro:
2617 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2618 case Mips::MULImmMacro:
2619 case Mips::DMULImmMacro:
2620 return expandMulImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2621 case Mips::MULOMacro:
2622 case Mips::DMULOMacro:
2623 return expandMulO(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2624 case Mips::MULOUMacro:
2625 case Mips::DMULOUMacro:
2626 return expandMulOU(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2627 case Mips::DMULMacro:
2628 return expandDMULMacro(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2631 return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2636 return expandStoreDM1Macro(Inst, IDLoc, Out, STI)
2639 case Mips::SEQMacro:
2640 return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2641 case Mips::SEQIMacro:
2642 return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2643 case Mips::SNEMacro:
2644 return expandSne(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2645 case Mips::SNEIMacro:
2646 return expandSneI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2647 case Mips::MFTC0:
case Mips::MTTC0:
2648 case Mips::MFTGPR:
case Mips::MTTGPR:
2649 case Mips::MFTLO:
case Mips::MTTLO:
2650 case Mips::MFTHI:
case Mips::MTTHI:
2651 case Mips::MFTACX:
case Mips::MTTACX:
2652 case Mips::MFTDSP:
case Mips::MTTDSP:
2653 case Mips::MFTC1:
case Mips::MTTC1:
2654 case Mips::MFTHC1:
case Mips::MTTHC1:
2655 case Mips::CFTC1:
case Mips::CTTC1:
2656 return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2658 case Mips::SaadAddr:
2659 return expandSaaAddr(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2663bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2665 const MCSubtargetInfo *STI) {
2666 MipsTargetStreamer &TOut = getTargetStreamer();
2671 const MCOperand FirstRegOp = Inst.
getOperand(0);
2672 const unsigned Opcode = Inst.
getOpcode();
2674 if (Opcode == Mips::JalOneReg) {
2676 if (IsCpRestoreSet && inMicroMipsMode()) {
2679 }
else if (inMicroMipsMode()) {
2680 JalrInst.
setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2687 }
else if (Opcode == Mips::JalTwoReg) {
2689 if (IsCpRestoreSet && inMicroMipsMode())
2692 JalrInst.
setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2694 const MCOperand SecondRegOp = Inst.
getOperand(1);
2701 const MCInstrDesc &MCID = MII.get(JalrInst.
getOpcode());
2724bool MipsAsmParser::loadImmediate(int64_t ImmValue, MCRegister DstReg,
2725 MCRegister SrcReg,
bool Is32BitImm,
2726 bool IsAddress, SMLoc IDLoc, MCStreamer &Out,
2727 const MCSubtargetInfo *STI) {
2728 MipsTargetStreamer &TOut = getTargetStreamer();
2730 if (!Is32BitImm && !isGP64bit()) {
2731 Error(IDLoc,
"instruction requires a 64-bit architecture");
2742 Error(IDLoc,
"instruction requires a 32-bit immediate");
2747 MCRegister ZeroReg = IsAddress ?
ABI.GetNullPtr() :
ABI.GetZeroReg();
2748 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2750 bool UseSrcReg =
false;
2754 MCRegister TmpReg = DstReg;
2756 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2759 MCRegister ATReg = getATReg(IDLoc);
2772 if (IsAddress && !Is32BitImm) {
2773 TOut.
emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2777 TOut.
emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2782 MCRegister TmpReg = DstReg;
2783 if (SrcReg == DstReg) {
2784 TmpReg = getATReg(IDLoc);
2789 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2791 TOut.
emitRRR(
ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2796 warnIfNoMacro(IDLoc);
2798 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2799 uint16_t Bits15To0 = ImmValue & 0xffff;
2800 if (!Is32BitImm && !
isInt<32>(ImmValue)) {
2803 if (ImmValue == 0xffffffff) {
2804 TOut.
emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2805 TOut.
emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2807 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2813 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2814 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2816 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2818 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2822 TOut.
emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2824 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2826 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2832 Error(IDLoc,
"instruction requires a 32-bit immediate");
2839 assert(
BitWidth >= 17 &&
"ImmValue must be at least 17-bit wide");
2843 unsigned ShiftAmount =
BitWidth - 16;
2844 uint16_t
Bits = (ImmValue >> ShiftAmount) & 0xffff;
2845 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2846 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2849 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2854 warnIfNoMacro(IDLoc);
2861 if (loadImmediate(ImmValue >> 32, TmpReg, MCRegister(),
true,
false, IDLoc,
2867 unsigned ShiftCarriedForwards = 16;
2868 for (
int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2869 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2871 if (ImmChunk != 0) {
2872 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2873 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2874 ShiftCarriedForwards = 0;
2877 ShiftCarriedForwards += 16;
2879 ShiftCarriedForwards -= 16;
2882 if (ShiftCarriedForwards)
2883 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2886 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2891bool MipsAsmParser::expandLoadImm(MCInst &Inst,
bool Is32BitImm, SMLoc IDLoc,
2892 MCStreamer &Out,
const MCSubtargetInfo *STI) {
2894 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
2895 const MCOperand &DstRegOp = Inst.
getOperand(0);
2896 assert(DstRegOp.
isReg() &&
"expected register operand kind");
2898 if (loadImmediate(ImmOp.
getImm(), DstRegOp.
getReg(), MCRegister(), Is32BitImm,
2899 false, IDLoc, Out, STI))
2905bool MipsAsmParser::expandLoadAddress(MCRegister DstReg, MCRegister BaseReg,
2907 bool Is32BitAddress, SMLoc IDLoc,
2909 const MCSubtargetInfo *STI) {
2911 if (Is32BitAddress &&
ABI.ArePtrs64bit()) {
2912 Warning(IDLoc,
"la used to load 64-bit address");
2914 Is32BitAddress =
false;
2918 if (!Is32BitAddress && !hasMips3()) {
2919 Error(IDLoc,
"instruction requires a 64-bit architecture");
2924 return loadAndAddSymbolAddress(
Offset.getExpr(), DstReg, BaseReg,
2925 Is32BitAddress, IDLoc, Out, STI);
2927 if (!
ABI.ArePtrs64bit()) {
2929 Is32BitAddress =
true;
2932 return loadImmediate(
Offset.getImm(), DstReg, BaseReg, Is32BitAddress,
true,
2936bool MipsAsmParser::loadAndAddSymbolAddress(
const MCExpr *SymExpr,
2938 MCRegister SrcReg,
bool Is32BitSym,
2939 SMLoc IDLoc, MCStreamer &Out,
2940 const MCSubtargetInfo *STI) {
2941 MipsTargetStreamer &TOut = getTargetStreamer();
2943 SrcReg.
isValid() && SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64;
2944 warnIfNoMacro(IDLoc);
2949 Error(IDLoc,
"expected relocatable expression");
2953 Error(IDLoc,
"expected relocatable expression with only one symbol");
2957 bool IsPtr64 =
ABI.ArePtrs64bit();
2961 static_cast<const MCSymbolELF *
>(Res.
getAddSym())->getBinding() ==
2968 bool UseXGOT = STI->
hasFeature(Mips::FeatureXGOT) && !IsLocalSym;
2974 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2977 const MCExpr *CallHiExpr =
2979 const MCExpr *CallLoExpr =
2983 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, DstReg, GPReg,
2985 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, DstReg,
2988 const MCExpr *CallExpr =
2990 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, GPReg,
2996 MCRegister TmpReg = DstReg;
2998 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
3002 MCRegister ATReg = getATReg(IDLoc);
3021 const MCExpr *CallHiExpr =
3028 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg, GPReg,
3030 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, TmpReg,
3034 TOut.
emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3040 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3045 const MCSpecifierExpr *GotExpr =
nullptr;
3046 const MCExpr *LoExpr =
nullptr;
3047 if (
ABI.IsN32() ||
ABI.IsN64()) {
3066 Error(IDLoc,
"macro instruction uses large offset, which is not "
3067 "currently supported");
3096 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, GPReg,
3100 TOut.
emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3104 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3110 const auto *HiExpr =
3112 const auto *LoExpr =
3116 if (
ABI.ArePtrs64bit() && isGP64bit()) {
3124 const auto *HighestExpr =
3126 const auto *HigherExpr =
3131 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
3133 if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
3134 MCRegister ATReg = getATReg(IDLoc);
3146 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3148 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3151 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3154 TOut.
emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
3157 }
else if (canUseATReg() && !RdRegIsRsReg && DstReg != getATReg(IDLoc)) {
3158 MCRegister ATReg = getATReg(IDLoc);
3174 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3178 TOut.
emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3179 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3181 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3184 }
else if ((!canUseATReg() && !RdRegIsRsReg) ||
3185 (canUseATReg() && DstReg == getATReg(IDLoc))) {
3196 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3198 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3199 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3201 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3202 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3205 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3211 assert(SrcReg == DstReg && !canUseATReg() &&
3212 "Could have expanded dla but didn't?");
3213 reportParseError(IDLoc,
3214 "pseudo-instruction requires $at, which is not available");
3228 MCRegister TmpReg = DstReg;
3230 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
3233 MCRegister ATReg = getATReg(IDLoc);
3244 TOut.
emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3247 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
3256 if (MipsMCRegisterClasses[Mips::FGR32RegClassID].
contains(
Reg))
3257 return Reg == (
unsigned)Mips::F31 ? (
unsigned)Mips::F0 :
Reg + 1;
3259 default:
llvm_unreachable(
"Unknown register in assembly macro expansion!");
3260 case Mips::ZERO:
return Mips::AT;
3261 case Mips::AT:
return Mips::V0;
3262 case Mips::V0:
return Mips::V1;
3263 case Mips::V1:
return Mips::A0;
3264 case Mips::A0:
return Mips::A1;
3265 case Mips::A1:
return Mips::A2;
3266 case Mips::A2:
return Mips::A3;
3267 case Mips::A3:
return Mips::T0;
3268 case Mips::T0:
return Mips::T1;
3269 case Mips::T1:
return Mips::T2;
3270 case Mips::T2:
return Mips::T3;
3271 case Mips::T3:
return Mips::T4;
3272 case Mips::T4:
return Mips::T5;
3273 case Mips::T5:
return Mips::T6;
3274 case Mips::T6:
return Mips::T7;
3275 case Mips::T7:
return Mips::S0;
3276 case Mips::S0:
return Mips::S1;
3277 case Mips::S1:
return Mips::S2;
3278 case Mips::S2:
return Mips::S3;
3279 case Mips::S3:
return Mips::S4;
3280 case Mips::S4:
return Mips::S5;
3281 case Mips::S5:
return Mips::S6;
3282 case Mips::S6:
return Mips::S7;
3283 case Mips::S7:
return Mips::T8;
3284 case Mips::T8:
return Mips::T9;
3285 case Mips::T9:
return Mips::K0;
3286 case Mips::K0:
return Mips::K1;
3287 case Mips::K1:
return Mips::GP;
3288 case Mips::GP:
return Mips::SP;
3289 case Mips::SP:
return Mips::FP;
3290 case Mips::FP:
return Mips::RA;
3291 case Mips::RA:
return Mips::ZERO;
3292 case Mips::D0:
return Mips::F1;
3293 case Mips::D1:
return Mips::F3;
3294 case Mips::D2:
return Mips::F5;
3295 case Mips::D3:
return Mips::F7;
3296 case Mips::D4:
return Mips::F9;
3297 case Mips::D5:
return Mips::F11;
3298 case Mips::D6:
return Mips::F13;
3299 case Mips::D7:
return Mips::F15;
3300 case Mips::D8:
return Mips::F17;
3301 case Mips::D9:
return Mips::F19;
3302 case Mips::D10:
return Mips::F21;
3303 case Mips::D11:
return Mips::F23;
3304 case Mips::D12:
return Mips::F25;
3305 case Mips::D13:
return Mips::F27;
3306 case Mips::D14:
return Mips::F29;
3307 case Mips::D15:
return Mips::F31;
3317bool MipsAsmParser::emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc,
3319 MCRegister ATReg = getATReg(IDLoc);
3325 const auto *GotExpr =
3328 if(isABI_O32() || isABI_N32()) {
3337 const auto *HiExpr =
3346 if(isABI_O32() || isABI_N32()) {
3350 const auto *HighestExpr =
3353 const auto *HigherExpr =
3358 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3360 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3363 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3372 if ((
Hi_32(ImmOp64) & 0x7ff00000) == 0) {
3383 float TmpFloat =
static_cast<float>(DoubleImm);
3387bool MipsAsmParser::expandLoadSingleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3389 const MCSubtargetInfo *STI) {
3392 "Invalid instruction operand.");
3399 return loadImmediate(ImmOp32, FirstReg, MCRegister(),
true,
false, IDLoc, Out,
3403bool MipsAsmParser::expandLoadSingleImmToFPR(MCInst &Inst, SMLoc IDLoc,
3405 const MCSubtargetInfo *STI) {
3406 MipsTargetStreamer &TOut = getTargetStreamer();
3409 "Invalid instruction operand.");
3418 MCRegister TmpReg = Mips::ZERO;
3420 TmpReg = getATReg(IDLoc);
3425 if (
Lo_32(ImmOp64) == 0) {
3426 if (TmpReg != Mips::ZERO && loadImmediate(ImmOp32, TmpReg, MCRegister(),
3427 true,
false, IDLoc, Out, STI))
3429 TOut.
emitRR(Mips::MTC1, FirstReg, TmpReg, IDLoc, STI);
3433 MCSection *CS = getStreamer().getCurrentSectionOnly();
3436 MCSection *ReadOnlySection =
3443 getStreamer().switchSection(ReadOnlySection);
3444 getStreamer().emitLabel(Sym, IDLoc);
3445 getStreamer().emitInt32(ImmOp32);
3446 getStreamer().switchSection(CS);
3448 if (emitPartialAddress(TOut, IDLoc, Sym))
3455bool MipsAsmParser::expandLoadDoubleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3457 const MCSubtargetInfo *STI) {
3458 MipsTargetStreamer &TOut = getTargetStreamer();
3461 "Invalid instruction operand.");
3468 if (
Lo_32(ImmOp64) == 0) {
3470 if (loadImmediate(ImmOp64, FirstReg, MCRegister(),
false,
false, IDLoc,
3474 if (loadImmediate(
Hi_32(ImmOp64), FirstReg, MCRegister(),
true,
false,
3478 if (loadImmediate(0,
nextReg(FirstReg), MCRegister(),
true,
false, IDLoc,
3485 MCSection *CS = getStreamer().getCurrentSectionOnly();
3486 MCSection *ReadOnlySection =
3493 getStreamer().switchSection(ReadOnlySection);
3494 getStreamer().emitLabel(Sym, IDLoc);
3495 getStreamer().emitValueToAlignment(
Align(8));
3496 getStreamer().emitIntValue(ImmOp64, 8);
3497 getStreamer().switchSection(CS);
3499 MCRegister TmpReg = getATReg(IDLoc);
3503 if (emitPartialAddress(TOut, IDLoc, Sym))
3506 TOut.
emitRRX(isABI_N64() ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3510 TOut.
emitRRI(Mips::LD, FirstReg, TmpReg, 0, IDLoc, STI);
3512 TOut.
emitRRI(Mips::LW, FirstReg, TmpReg, 0, IDLoc, STI);
3513 TOut.
emitRRI(Mips::LW,
nextReg(FirstReg), TmpReg, 4, IDLoc, STI);
3518bool MipsAsmParser::expandLoadDoubleImmToFPR(MCInst &Inst,
bool Is64FPU,
3519 SMLoc IDLoc, MCStreamer &Out,
3520 const MCSubtargetInfo *STI) {
3521 MipsTargetStreamer &TOut = getTargetStreamer();
3524 "Invalid instruction operand.");
3531 MCRegister TmpReg = Mips::ZERO;
3533 TmpReg = getATReg(IDLoc);
3538 if ((
Lo_32(ImmOp64) == 0) &&
3539 !((
Hi_32(ImmOp64) & 0xffff0000) && (
Hi_32(ImmOp64) & 0x0000ffff))) {
3541 if (TmpReg != Mips::ZERO && loadImmediate(ImmOp64, TmpReg, MCRegister(),
3542 false,
false, IDLoc, Out, STI))
3544 TOut.
emitRR(Mips::DMTC1, FirstReg, TmpReg, IDLoc, STI);
3548 if (TmpReg != Mips::ZERO &&
3549 loadImmediate(
Hi_32(ImmOp64), TmpReg, MCRegister(),
true,
false, IDLoc,
3553 if (hasMips32r2()) {
3554 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3555 TOut.
emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, TmpReg, IDLoc, STI);
3557 TOut.
emitRR(Mips::MTC1,
nextReg(FirstReg), TmpReg, IDLoc, STI);
3558 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3563 MCSection *CS = getStreamer().getCurrentSectionOnly();
3566 MCSection *ReadOnlySection =
3573 getStreamer().switchSection(ReadOnlySection);
3574 getStreamer().emitLabel(Sym, IDLoc);
3575 getStreamer().emitValueToAlignment(
Align(8));
3576 getStreamer().emitIntValue(ImmOp64, 8);
3577 getStreamer().switchSection(CS);
3579 if (emitPartialAddress(TOut, IDLoc, Sym))
3582 TOut.
emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, TmpReg,
3588bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
3590 const MCSubtargetInfo *STI) {
3591 MipsTargetStreamer &TOut = getTargetStreamer();
3594 "unexpected number of operands");
3604 assert(
Offset.isImm() &&
"expected immediate operand kind");
3608 if (inMicroMipsMode())
3609 Inst.
setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3612 return Error(IDLoc,
"branch target out of range");
3614 return Error(IDLoc,
"branch to misaligned address");
3626 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
3633bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3634 const MCSubtargetInfo *STI) {
3635 MipsTargetStreamer &TOut = getTargetStreamer();
3636 const MCOperand &DstRegOp = Inst.
getOperand(0);
3637 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3640 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
3642 const MCOperand &MemOffsetOp = Inst.
getOperand(2);
3644 "expected immediate or expression operand");
3646 bool IsLikely =
false;
3656 case Mips::BEQLImmMacro:
3660 case Mips::BNELImmMacro:
3669 int64_t ImmValue = ImmOp.
getImm();
3670 if (ImmValue == 0) {
3674 TOut.
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3676 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3679 warnIfNoMacro(IDLoc);
3681 MCRegister ATReg = getATReg(IDLoc);
3685 if (loadImmediate(ImmValue, ATReg, MCRegister(), !isGP64bit(),
true, IDLoc,
3689 if (IsLikely && MemOffsetOp.
isExpr()) {
3692 TOut.
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3694 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3699void MipsAsmParser::expandMem16Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3700 const MCSubtargetInfo *STI,
bool IsLoad) {
3702 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3703 unsigned StartOp = NumOp == 3 ? 0 : 1;
3705 const MCOperand &DstRegOp = Inst.
getOperand(StartOp);
3706 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3707 const MCOperand &BaseRegOp = Inst.
getOperand(StartOp + 1);
3708 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3711 MipsTargetStreamer &TOut = getTargetStreamer();
3713 MCRegister DstReg = DstRegOp.
getReg();
3715 MCRegister TmpReg = DstReg;
3717 const MCInstrDesc &
Desc = MII.get(OpCode);
3718 int16_t DstRegClass =
3719 MII.getOpRegClassID(
Desc.operands()[StartOp],
3721 unsigned DstRegClassID =
3722 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3723 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3724 (DstRegClassID == Mips::GPR64RegClassID);
3726 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3729 TmpReg = getATReg(IDLoc);
3734 auto emitInstWithOffset = [&](
const MCOperand &
Off) {
3736 TOut.
emitRRX(OpCode, DstReg, TmpReg, Off, IDLoc, STI);
3738 TOut.
emitRRRX(OpCode, DstReg, DstReg, TmpReg, Off, IDLoc, STI);
3742 int64_t LoOffset =
OffsetOp.getImm() & 0xffff;
3743 int64_t HiOffset =
OffsetOp.getImm() & ~0xffff;
3747 if (LoOffset & 0x8000)
3748 HiOffset += 0x10000;
3750 bool IsLargeOffset = HiOffset != 0;
3752 if (IsLargeOffset) {
3754 if (loadImmediate(HiOffset, TmpReg, MCRegister(), Is32BitImm,
true, IDLoc,
3759 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3760 TOut.
emitRRR(
ABI.ArePtrs64bit() ? Mips::DADDu : Mips::ADDu, TmpReg,
3761 TmpReg, BaseReg, IDLoc, STI);
3775 if (!
OffsetOp.getExpr()->evaluateAsRelocatable(Res,
nullptr)) {
3776 Error(IDLoc,
"expected relocatable expression");
3780 Error(IDLoc,
"expected relocatable expression with only one symbol");
3784 loadAndAddSymbolAddress(
3786 BaseReg, !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3794 const MCExpr *OffExpr =
OffsetOp.getExpr();
3806 TOut.
emitRX(Mips::LUi, TmpReg, HighestOperand, IDLoc, STI);
3807 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HigherOperand, IDLoc, STI);
3808 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3809 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HiOperand, IDLoc, STI);
3810 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3811 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3812 TOut.
emitRRR(Mips::DADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3813 emitInstWithOffset(LoOperand);
3816 TOut.
emitRX(Mips::LUi, TmpReg, HiOperand, IDLoc, STI);
3817 if (BaseReg != Mips::ZERO)
3818 TOut.
emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3820 emitInstWithOffset(LoOperand);
3829void MipsAsmParser::expandMem9Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3830 const MCSubtargetInfo *STI,
bool IsLoad) {
3832 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3833 unsigned StartOp = NumOp == 3 ? 0 : 1;
3835 const MCOperand &DstRegOp = Inst.
getOperand(StartOp);
3836 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3837 const MCOperand &BaseRegOp = Inst.
getOperand(StartOp + 1);
3838 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3841 MipsTargetStreamer &TOut = getTargetStreamer();
3843 MCRegister DstReg = DstRegOp.
getReg();
3845 MCRegister TmpReg = DstReg;
3847 const MCInstrDesc &
Desc = MII.get(OpCode);
3848 int16_t DstRegClass =
3849 MII.getOpRegClassID(
Desc.operands()[StartOp],
3852 unsigned DstRegClassID =
3853 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3854 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3855 (DstRegClassID == Mips::GPR64RegClassID);
3857 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3860 TmpReg = getATReg(IDLoc);
3865 auto emitInst = [&]() {
3874 loadImmediate(
OffsetOp.getImm(), TmpReg, BaseReg, !
ABI.ArePtrs64bit(),
true,
3881 loadAndAddSymbolAddress(
OffsetOp.getExpr(), TmpReg, BaseReg,
3882 !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3890bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
3892 const MCSubtargetInfo *STI) {
3895 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3899 Inst.
getOperand(OpNum - 3).
isReg() &&
"Invalid instruction operand.");
3908 if (inMicroMipsMode() && hasMips32r6())
3909 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3911 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3919bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
3921 const MCSubtargetInfo *STI) {
3922 MipsTargetStreamer &TOut = getTargetStreamer();
3923 bool EmittedNoMacroWarning =
false;
3924 unsigned PseudoOpcode = Inst.
getOpcode();
3929 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3930 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3935 else if (TrgOp.
isImm()) {
3936 warnIfNoMacro(IDLoc);
3937 EmittedNoMacroWarning =
true;
3939 TrgReg = getATReg(IDLoc);
3943 switch(PseudoOpcode) {
3946 case Mips::BLTImmMacro:
3947 PseudoOpcode = Mips::BLT;
3949 case Mips::BLEImmMacro:
3950 PseudoOpcode = Mips::BLE;
3952 case Mips::BGEImmMacro:
3953 PseudoOpcode = Mips::BGE;
3955 case Mips::BGTImmMacro:
3956 PseudoOpcode = Mips::BGT;
3958 case Mips::BLTUImmMacro:
3959 PseudoOpcode = Mips::BLTU;
3961 case Mips::BLEUImmMacro:
3962 PseudoOpcode = Mips::BLEU;
3964 case Mips::BGEUImmMacro:
3965 PseudoOpcode = Mips::BGEU;
3967 case Mips::BGTUImmMacro:
3968 PseudoOpcode = Mips::BGTU;
3970 case Mips::BLTLImmMacro:
3971 PseudoOpcode = Mips::BLTL;
3973 case Mips::BLELImmMacro:
3974 PseudoOpcode = Mips::BLEL;
3976 case Mips::BGELImmMacro:
3977 PseudoOpcode = Mips::BGEL;
3979 case Mips::BGTLImmMacro:
3980 PseudoOpcode = Mips::BGTL;
3982 case Mips::BLTULImmMacro:
3983 PseudoOpcode = Mips::BLTUL;
3985 case Mips::BLEULImmMacro:
3986 PseudoOpcode = Mips::BLEUL;
3988 case Mips::BGEULImmMacro:
3989 PseudoOpcode = Mips::BGEUL;
3991 case Mips::BGTULImmMacro:
3992 PseudoOpcode = Mips::BGTUL;
3996 if (loadImmediate(TrgOp.
getImm(), TrgReg, MCRegister(), !isGP64bit(),
false,
4001 switch (PseudoOpcode) {
4006 AcceptsEquality =
false;
4007 ReverseOrderSLT =
false;
4009 ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
4010 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
4011 ZeroSrcOpcode = Mips::BGTZ;
4012 ZeroTrgOpcode = Mips::BLTZ;
4018 AcceptsEquality =
true;
4019 ReverseOrderSLT =
true;
4021 ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
4022 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
4023 ZeroSrcOpcode = Mips::BGEZ;
4024 ZeroTrgOpcode = Mips::BLEZ;
4030 AcceptsEquality =
true;
4031 ReverseOrderSLT =
false;
4033 ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
4034 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
4035 ZeroSrcOpcode = Mips::BLEZ;
4036 ZeroTrgOpcode = Mips::BGEZ;
4042 AcceptsEquality =
false;
4043 ReverseOrderSLT =
true;
4045 ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
4046 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
4047 ZeroSrcOpcode = Mips::BLTZ;
4048 ZeroTrgOpcode = Mips::BGTZ;
4054 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
4055 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
4056 if (IsSrcRegZero && IsTrgRegZero) {
4060 if (PseudoOpcode == Mips::BLT) {
4065 if (PseudoOpcode == Mips::BLE) {
4068 Warning(IDLoc,
"branch is always taken");
4071 if (PseudoOpcode == Mips::BGE) {
4074 Warning(IDLoc,
"branch is always taken");
4077 if (PseudoOpcode == Mips::BGT) {
4082 if (PseudoOpcode == Mips::BGTU) {
4083 TOut.
emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
4087 if (AcceptsEquality) {
4090 TOut.
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4092 Warning(IDLoc,
"branch is always taken");
4099 if (IsSrcRegZero || IsTrgRegZero) {
4100 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
4101 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
4108 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
4109 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
4115 TOut.
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4117 Warning(IDLoc,
"branch is always taken");
4133 TOut.
emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
4134 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
4141 TOut.
emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
4142 IsSrcRegZero ? TrgReg : SrcReg,
4149 MCRegister ATRegNum = getATReg(IDLoc);
4153 if (!EmittedNoMacroWarning)
4154 warnIfNoMacro(IDLoc);
4171 TOut.
emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
4172 ReverseOrderSLT ? TrgReg : SrcReg,
4173 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
4175 TOut.
emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
4176 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
4190bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4191 const MCSubtargetInfo *STI,
4192 const bool IsMips64,
const bool Signed) {
4193 MipsTargetStreamer &TOut = getTargetStreamer();
4195 warnIfNoMacro(IDLoc);
4197 const MCOperand &RdRegOp = Inst.
getOperand(0);
4198 assert(RdRegOp.
isReg() &&
"expected register operand kind");
4199 MCRegister RdReg = RdRegOp.
getReg();
4201 const MCOperand &RsRegOp = Inst.
getOperand(1);
4202 assert(RsRegOp.
isReg() &&
"expected register operand kind");
4203 MCRegister RsReg = RsRegOp.
getReg();
4210 "expected register or immediate operand kind");
4214 ImmValue = RtOp.
getImm();
4221 DivOp =
Signed ? Mips::DSDIV : Mips::DUDIV;
4222 ZeroReg = Mips::ZERO_64;
4225 DivOp =
Signed ? Mips::SDIV : Mips::UDIV;
4226 ZeroReg = Mips::ZERO;
4230 bool UseTraps = useTraps();
4233 bool isDiv = Opcode == Mips::SDivMacro || Opcode == Mips::SDivIMacro ||
4234 Opcode == Mips::UDivMacro || Opcode == Mips::UDivIMacro ||
4235 Opcode == Mips::DSDivMacro || Opcode == Mips::DSDivIMacro ||
4236 Opcode == Mips::DUDivMacro || Opcode == Mips::DUDivIMacro;
4238 bool isRem = Opcode == Mips::SRemMacro || Opcode == Mips::SRemIMacro ||
4239 Opcode == Mips::URemMacro || Opcode == Mips::URemIMacro ||
4240 Opcode == Mips::DSRemMacro || Opcode == Mips::DSRemIMacro ||
4241 Opcode == Mips::DURemMacro || Opcode == Mips::DURemIMacro;
4244 MCRegister ATReg = getATReg(IDLoc);
4250 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4252 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4256 if (isRem && (ImmValue == 1 || (
Signed && (ImmValue == -1)))) {
4257 TOut.
emitRRR(Mips::OR, RdReg, ZeroReg, ZeroReg, IDLoc, STI);
4259 }
else if (isDiv && ImmValue == 1) {
4260 TOut.
emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI);
4262 }
else if (isDiv &&
Signed && ImmValue == -1) {
4263 TOut.
emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
4266 if (loadImmediate(ImmValue, ATReg, MCRegister(),
isInt<32>(ImmValue),
4267 false, Inst.
getLoc(), Out, STI))
4269 TOut.
emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
4270 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4280 if (!
NoZeroDivCheck && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
4282 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4285 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4291 if (isRem && (RdReg == Mips::ZERO || RdReg == Mips::ZERO_64)) {
4292 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4301 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4304 TOut.
emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4307 BrTarget =
Context.createTempSymbol();
4310 TOut.
emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4315 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4321 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4325bool MipsAsmParser::expandTrunc(MCInst &Inst,
bool IsDouble,
bool Is64FPU,
4326 SMLoc IDLoc, MCStreamer &Out,
4327 const MCSubtargetInfo *STI) {
4328 MipsTargetStreamer &TOut = getTargetStreamer();
4338 if (hasMips1() && !hasMips2()) {
4339 MCRegister ATReg = getATReg(IDLoc);
4342 TOut.
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4343 TOut.
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4345 TOut.
emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4346 TOut.
emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4347 TOut.
emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4349 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4351 FirstReg, SecondReg, IDLoc, STI);
4352 TOut.
emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4357 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4359 FirstReg, SecondReg, IDLoc, STI);
4364bool MipsAsmParser::expandUlh(MCInst &Inst,
bool Signed, SMLoc IDLoc,
4365 MCStreamer &Out,
const MCSubtargetInfo *STI) {
4366 if (hasMips32r6() || hasMips64r6()) {
4367 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4370 const MCOperand &DstRegOp = Inst.
getOperand(0);
4371 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4372 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4373 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4374 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4375 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4377 MipsTargetStreamer &TOut = getTargetStreamer();
4378 MCRegister DstReg = DstRegOp.
getReg();
4379 MCRegister SrcReg = SrcRegOp.
getReg();
4380 int64_t OffsetValue = OffsetImmOp.
getImm();
4384 warnIfNoMacro(IDLoc);
4385 MCRegister ATReg = getATReg(IDLoc);
4390 if (IsLargeOffset) {
4391 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4396 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4397 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4401 MCRegister FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4402 MCRegister SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4404 MCRegister LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4405 MCRegister SllReg = IsLargeOffset ? DstReg : ATReg;
4407 TOut.
emitRRI(
Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4408 FirstOffset, IDLoc, STI);
4409 TOut.
emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4410 TOut.
emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4411 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4416bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4417 const MCSubtargetInfo *STI) {
4418 if (hasMips32r6() || hasMips64r6()) {
4419 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4422 const MCOperand &DstRegOp = Inst.
getOperand(0);
4423 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4424 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4425 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4426 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4427 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4429 MipsTargetStreamer &TOut = getTargetStreamer();
4430 MCRegister DstReg = DstRegOp.
getReg();
4431 MCRegister SrcReg = SrcRegOp.
getReg();
4432 int64_t OffsetValue = OffsetImmOp.
getImm();
4434 warnIfNoMacro(IDLoc);
4435 MCRegister ATReg = getATReg(IDLoc);
4440 if (IsLargeOffset) {
4441 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4446 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4447 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4451 if (IsLargeOffset) {
4452 TOut.
emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4453 TOut.
emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4454 TOut.
emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4455 TOut.
emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4456 TOut.
emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4457 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4459 TOut.
emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4460 TOut.
emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4461 TOut.
emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4467bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4468 const MCSubtargetInfo *STI) {
4469 if (hasMips32r6() || hasMips64r6()) {
4470 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4473 const MCOperand &DstRegOp = Inst.
getOperand(0);
4474 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4475 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4476 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4477 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4478 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4480 MipsTargetStreamer &TOut = getTargetStreamer();
4481 MCRegister DstReg = DstRegOp.
getReg();
4482 MCRegister SrcReg = SrcRegOp.
getReg();
4483 int64_t OffsetValue = OffsetImmOp.
getImm();
4487 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4488 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4492 bool IsLoadInst = (Inst.
getOpcode() == Mips::Ulw);
4493 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4494 MCRegister TmpReg = SrcReg;
4495 if (IsLargeOffset || DoMove) {
4496 warnIfNoMacro(IDLoc);
4497 TmpReg = getATReg(IDLoc);
4502 if (IsLargeOffset) {
4503 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4511 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4512 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4513 TOut.
emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4514 TOut.
emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4517 TOut.
emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4522bool MipsAsmParser::expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4523 const MCSubtargetInfo *STI) {
4524 MipsTargetStreamer &TOut = getTargetStreamer();
4536 warnIfNoMacro(IDLoc);
4550 TOut.
emitRRR(OpCode, DstReg, SrcReg, OpReg, IDLoc, STI);
4551 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4556bool MipsAsmParser::expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4557 const MCSubtargetInfo *STI) {
4558 MipsTargetStreamer &TOut = getTargetStreamer();
4568 unsigned OpRegCode, OpImmCode;
4570 warnIfNoMacro(IDLoc);
4574 case Mips::SGEImm64:
4575 OpRegCode = Mips::SLT;
4576 OpImmCode = Mips::SLTi;
4579 case Mips::SGEUImm64:
4580 OpRegCode = Mips::SLTu;
4581 OpImmCode = Mips::SLTiu;
4590 TOut.
emitRRI(OpImmCode, DstReg, SrcReg, ImmValue, IDLoc, STI);
4591 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4593 MCRegister ImmReg = DstReg;
4594 if (DstReg == SrcReg) {
4595 MCRegister ATReg = getATReg(Inst.
getLoc());
4601 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
4602 false, IDLoc, Out, STI))
4605 TOut.
emitRRR(OpRegCode, DstReg, SrcReg, ImmReg, IDLoc, STI);
4606 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4612bool MipsAsmParser::expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4613 const MCSubtargetInfo *STI) {
4614 MipsTargetStreamer &TOut = getTargetStreamer();
4623 MCRegister ImmReg = DstReg;
4627 warnIfNoMacro(IDLoc);
4631 case Mips::SGTImm64:
4635 case Mips::SGTUImm64:
4642 if (DstReg == SrcReg) {
4643 MCRegister ATReg = getATReg(Inst.
getLoc());
4649 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
false,
4654 TOut.
emitRRR(OpCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4659bool MipsAsmParser::expandSle(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4660 const MCSubtargetInfo *STI) {
4661 MipsTargetStreamer &TOut = getTargetStreamer();
4673 warnIfNoMacro(IDLoc);
4687 TOut.
emitRRR(OpCode, DstReg, OpReg, SrcReg, IDLoc, STI);
4688 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4693bool MipsAsmParser::expandSleImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4694 const MCSubtargetInfo *STI) {
4695 MipsTargetStreamer &TOut = getTargetStreamer();
4707 warnIfNoMacro(IDLoc);
4711 case Mips::SLEImm64:
4712 OpRegCode = Mips::SLT;
4715 case Mips::SLEUImm64:
4716 OpRegCode = Mips::SLTu;
4723 MCRegister ImmReg = DstReg;
4724 if (DstReg == SrcReg) {
4725 MCRegister ATReg = getATReg(Inst.
getLoc());
4731 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
false,
4735 TOut.
emitRRR(OpRegCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4736 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4741bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
4743 const MCSubtargetInfo *STI) {
4744 MipsTargetStreamer &TOut = getTargetStreamer();
4752 MCRegister FinalDstReg;
4759 unsigned FinalOpcode = Inst.
getOpcode();
4761 if (DstReg == SrcReg) {
4762 ATReg = getATReg(Inst.
getLoc());
4765 FinalDstReg = DstReg;
4769 if (!loadImmediate(ImmValue, DstReg, MCRegister(), Is32Bit,
false,
4770 Inst.
getLoc(), Out, STI)) {
4771 switch (FinalOpcode) {
4775 FinalOpcode = Mips::ADD;
4778 FinalOpcode = Mips::ADDu;
4781 FinalOpcode = Mips::AND;
4784 FinalOpcode = Mips::NOR;
4787 FinalOpcode = Mips::OR;
4790 FinalOpcode = Mips::SLT;
4793 FinalOpcode = Mips::SLTu;
4796 FinalOpcode = Mips::XOR;
4799 FinalOpcode = Mips::ADD_MM;
4801 case Mips::ADDiu_MM:
4802 FinalOpcode = Mips::ADDu_MM;
4805 FinalOpcode = Mips::AND_MM;
4808 FinalOpcode = Mips::OR_MM;
4811 FinalOpcode = Mips::SLT_MM;
4813 case Mips::SLTiu_MM:
4814 FinalOpcode = Mips::SLTu_MM;
4817 FinalOpcode = Mips::XOR_MM;
4820 FinalOpcode = Mips::AND64;
4822 case Mips::NORImm64:
4823 FinalOpcode = Mips::NOR64;
4826 FinalOpcode = Mips::OR64;
4828 case Mips::SLTImm64:
4829 FinalOpcode = Mips::SLT64;
4831 case Mips::SLTUImm64:
4832 FinalOpcode = Mips::SLTu64;
4835 FinalOpcode = Mips::XOR64;
4840 TOut.
emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4842 TOut.
emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4848bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4849 const MCSubtargetInfo *STI) {
4850 MipsTargetStreamer &TOut = getTargetStreamer();
4855 MCRegister TmpReg =
DReg;
4857 unsigned FirstShift = Mips::NOP;
4858 unsigned SecondShift = Mips::NOP;
4860 if (hasMips32r2()) {
4862 TmpReg = getATReg(Inst.
getLoc());
4868 TOut.
emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4869 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
4874 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
4886 FirstShift = Mips::SRLV;
4887 SecondShift = Mips::SLLV;
4890 FirstShift = Mips::SLLV;
4891 SecondShift = Mips::SRLV;
4895 ATReg = getATReg(Inst.
getLoc());
4899 TOut.
emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4900 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
4901 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
4902 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
4910bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
4912 const MCSubtargetInfo *STI) {
4913 MipsTargetStreamer &TOut = getTargetStreamer();
4919 unsigned FirstShift = Mips::NOP;
4920 unsigned SecondShift = Mips::NOP;
4922 if (hasMips32r2()) {
4924 uint64_t MaxShift = 32;
4925 uint64_t ShiftValue = ImmValue;
4927 ShiftValue = MaxShift - ImmValue;
4928 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
4933 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.
getLoc(), STI);
4941 if (ImmValue == 0) {
4950 FirstShift = Mips::SLL;
4951 SecondShift = Mips::SRL;
4954 FirstShift = Mips::SRL;
4955 SecondShift = Mips::SLL;
4959 ATReg = getATReg(Inst.
getLoc());
4963 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.
getLoc(), STI);
4964 TOut.
emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.
getLoc(), STI);
4965 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
4973bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4974 const MCSubtargetInfo *STI) {
4975 MipsTargetStreamer &TOut = getTargetStreamer();
4980 MCRegister TmpReg =
DReg;
4982 unsigned FirstShift = Mips::NOP;
4983 unsigned SecondShift = Mips::NOP;
4985 if (hasMips64r2()) {
4986 if (TmpReg == SReg) {
4987 TmpReg = getATReg(Inst.
getLoc());
4993 TOut.
emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4994 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
4999 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
5011 FirstShift = Mips::DSRLV;
5012 SecondShift = Mips::DSLLV;
5015 FirstShift = Mips::DSLLV;
5016 SecondShift = Mips::DSRLV;
5020 ATReg = getATReg(Inst.
getLoc());
5024 TOut.
emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
5025 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
5026 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
5027 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5035bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
5037 const MCSubtargetInfo *STI) {
5038 MipsTargetStreamer &TOut = getTargetStreamer();
5044 unsigned FirstShift = Mips::NOP;
5045 unsigned SecondShift = Mips::NOP;
5049 if (hasMips64r2()) {
5050 unsigned FinalOpcode = Mips::NOP;
5052 FinalOpcode = Mips::DROTR;
5053 else if (ImmValue % 32 == 0)
5054 FinalOpcode = Mips::DROTR32;
5055 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
5057 FinalOpcode = Mips::DROTR32;
5059 FinalOpcode = Mips::DROTR;
5060 }
else if (ImmValue >= 33) {
5062 FinalOpcode = Mips::DROTR;
5064 FinalOpcode = Mips::DROTR32;
5067 uint64_t ShiftValue = ImmValue % 32;
5069 ShiftValue = (32 - ImmValue % 32) % 32;
5071 TOut.
emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
5077 if (ImmValue == 0) {
5078 TOut.
emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.
getLoc(), STI);
5086 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5087 FirstShift = Mips::DSLL;
5088 SecondShift = Mips::DSRL32;
5090 if (ImmValue == 32) {
5091 FirstShift = Mips::DSLL32;
5092 SecondShift = Mips::DSRL32;
5094 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5095 FirstShift = Mips::DSLL32;
5096 SecondShift = Mips::DSRL;
5100 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5101 FirstShift = Mips::DSRL;
5102 SecondShift = Mips::DSLL32;
5104 if (ImmValue == 32) {
5105 FirstShift = Mips::DSRL32;
5106 SecondShift = Mips::DSLL32;
5108 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5109 FirstShift = Mips::DSRL32;
5110 SecondShift = Mips::DSLL;
5115 ATReg = getATReg(Inst.
getLoc());
5119 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.
getLoc(), STI);
5120 TOut.
emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
5122 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5130bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5131 const MCSubtargetInfo *STI) {
5132 MipsTargetStreamer &TOut = getTargetStreamer();
5136 TOut.
emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
5137 if (FirstRegOp != SecondRegOp)
5138 TOut.
emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
5141 TOut.
emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
5146bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5147 const MCSubtargetInfo *STI) {
5148 MipsTargetStreamer &TOut = getTargetStreamer();
5154 ATReg = getATReg(IDLoc);
5158 loadImmediate(ImmValue, ATReg, MCRegister(),
true,
false, IDLoc, Out, STI);
5160 TOut.
emitRR(Inst.
getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
5161 SrcReg, ATReg, IDLoc, STI);
5163 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5168bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5169 const MCSubtargetInfo *STI) {
5170 MipsTargetStreamer &TOut = getTargetStreamer();
5176 ATReg = getATReg(Inst.
getLoc());
5180 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
5181 SrcReg, TmpReg, IDLoc, STI);
5183 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5185 TOut.
emitRRI(Inst.
getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
5186 DstReg, DstReg, 0x1F, IDLoc, STI);
5188 TOut.
emitR(Mips::MFHI, ATReg, IDLoc, STI);
5191 TOut.
emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
5198 TOut.
emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
5199 if (AssemblerOptions.
back()->isReorder())
5201 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5205 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5210bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5211 const MCSubtargetInfo *STI) {
5212 MipsTargetStreamer &TOut = getTargetStreamer();
5218 ATReg = getATReg(IDLoc);
5222 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
5223 SrcReg, TmpReg, IDLoc, STI);
5225 TOut.
emitR(Mips::MFHI, ATReg, IDLoc, STI);
5226 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5228 TOut.
emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);
5235 TOut.
emitRRX(Mips::BEQ, ATReg, Mips::ZERO, LabelOp, IDLoc, STI);
5236 if (AssemblerOptions.
back()->isReorder())
5238 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5246bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5247 const MCSubtargetInfo *STI) {
5248 MipsTargetStreamer &TOut = getTargetStreamer();
5253 TOut.
emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
5254 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5264bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
5266 const MCSubtargetInfo *STI,
5271 warnIfNoMacro(IDLoc);
5273 MipsTargetStreamer &TOut = getTargetStreamer();
5274 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
5276 MCRegister SecondReg =
nextReg(FirstReg);
5281 warnIfRegIndexIsAT(FirstReg, IDLoc);
5284 "Offset for load macro is not immediate!");
5287 signed NextOffset = FirstOffset.
getImm() + 4;
5295 if (FirstReg != BaseReg || !IsLoad) {
5296 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5297 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5299 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5300 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5312bool MipsAsmParser::expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc,
5314 const MCSubtargetInfo *STI) {
5318 warnIfNoMacro(IDLoc);
5320 MipsTargetStreamer &TOut = getTargetStreamer();
5321 unsigned Opcode = Mips::SWC1;
5323 MCRegister SecondReg =
nextReg(FirstReg);
5328 warnIfRegIndexIsAT(FirstReg, IDLoc);
5331 "Offset for macro is not immediate!");
5334 signed NextOffset = FirstOffset.
getImm() + 4;
5340 if (!IsLittleEndian)
5343 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5344 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5349bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5350 const MCSubtargetInfo *STI) {
5351 MipsTargetStreamer &TOut = getTargetStreamer();
5362 warnIfNoMacro(IDLoc);
5364 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5365 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5366 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5370 MCRegister
Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5371 TOut.
emitRRI(Mips::SLTiu, DstReg,
Reg, 1, IDLoc, STI);
5375bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5376 const MCSubtargetInfo *STI) {
5377 MipsTargetStreamer &TOut = getTargetStreamer();
5388 warnIfNoMacro(IDLoc);
5391 TOut.
emitRRI(Mips::SLTiu, DstReg, SrcReg, 1, IDLoc, STI);
5395 if (SrcReg == Mips::ZERO) {
5396 Warning(IDLoc,
"comparison is always false");
5397 TOut.
emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
5398 DstReg, SrcReg, SrcReg, IDLoc, STI);
5403 if (Imm > -0x8000 && Imm < 0) {
5405 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5411 MCRegister ATReg = getATReg(IDLoc);
5415 if (loadImmediate(Imm, ATReg, MCRegister(),
true, isGP64bit(), IDLoc, Out,
5419 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5420 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5424 TOut.
emitRRI(
Opc, DstReg, SrcReg, Imm, IDLoc, STI);
5425 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5429bool MipsAsmParser::expandSne(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5430 const MCSubtargetInfo *STI) {
5432 MipsTargetStreamer &TOut = getTargetStreamer();
5443 warnIfNoMacro(IDLoc);
5445 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5446 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5447 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5451 MCRegister
Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5452 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO,
Reg, IDLoc, STI);
5456bool MipsAsmParser::expandSneI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5457 const MCSubtargetInfo *STI) {
5458 MipsTargetStreamer &TOut = getTargetStreamer();
5469 warnIfNoMacro(IDLoc);
5471 if (ImmValue == 0) {
5472 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, SrcReg, IDLoc, STI);
5476 if (SrcReg == Mips::ZERO) {
5477 Warning(IDLoc,
"comparison is always true");
5478 if (loadImmediate(1, DstReg, MCRegister(),
true,
false, IDLoc, Out, STI))
5484 if (ImmValue > -0x8000 && ImmValue < 0) {
5485 ImmValue = -ImmValue;
5486 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5492 TOut.
emitRRI(
Opc, DstReg, SrcReg, ImmValue, IDLoc, STI);
5493 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5497 MCRegister ATReg = getATReg(IDLoc);
5501 if (loadImmediate(ImmValue, ATReg, MCRegister(),
isInt<32>(ImmValue),
false,
5505 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5506 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5569 case Mips::F0:
return Mips::ZERO;
5570 case Mips::F1:
return Mips::AT;
5571 case Mips::F2:
return Mips::V0;
5572 case Mips::F3:
return Mips::V1;
5573 case Mips::F4:
return Mips::A0;
5574 case Mips::F5:
return Mips::A1;
5575 case Mips::F6:
return Mips::A2;
5576 case Mips::F7:
return Mips::A3;
5577 case Mips::F8:
return Mips::T0;
5578 case Mips::F9:
return Mips::T1;
5579 case Mips::F10:
return Mips::T2;
5580 case Mips::F11:
return Mips::T3;
5581 case Mips::F12:
return Mips::T4;
5582 case Mips::F13:
return Mips::T5;
5583 case Mips::F14:
return Mips::T6;
5584 case Mips::F15:
return Mips::T7;
5585 case Mips::F16:
return Mips::S0;
5586 case Mips::F17:
return Mips::S1;
5587 case Mips::F18:
return Mips::S2;
5588 case Mips::F19:
return Mips::S3;
5589 case Mips::F20:
return Mips::S4;
5590 case Mips::F21:
return Mips::S5;
5591 case Mips::F22:
return Mips::S6;
5592 case Mips::F23:
return Mips::S7;
5593 case Mips::F24:
return Mips::T8;
5594 case Mips::F25:
return Mips::T9;
5595 case Mips::F26:
return Mips::K0;
5596 case Mips::F27:
return Mips::K1;
5597 case Mips::F28:
return Mips::GP;
5598 case Mips::F29:
return Mips::SP;
5599 case Mips::F30:
return Mips::FP;
5600 case Mips::F31:
return Mips::RA;
5608 case Mips::COP00:
return Mips::ZERO;
5609 case Mips::COP01:
return Mips::AT;
5610 case Mips::COP02:
return Mips::V0;
5611 case Mips::COP03:
return Mips::V1;
5612 case Mips::COP04:
return Mips::A0;
5613 case Mips::COP05:
return Mips::A1;
5614 case Mips::COP06:
return Mips::A2;
5615 case Mips::COP07:
return Mips::A3;
5616 case Mips::COP08:
return Mips::T0;
5617 case Mips::COP09:
return Mips::T1;
5618 case Mips::COP010:
return Mips::T2;
5619 case Mips::COP011:
return Mips::T3;
5620 case Mips::COP012:
return Mips::T4;
5621 case Mips::COP013:
return Mips::T5;
5622 case Mips::COP014:
return Mips::T6;
5623 case Mips::COP015:
return Mips::T7;
5624 case Mips::COP016:
return Mips::S0;
5625 case Mips::COP017:
return Mips::S1;
5626 case Mips::COP018:
return Mips::S2;
5627 case Mips::COP019:
return Mips::S3;
5628 case Mips::COP020:
return Mips::S4;
5629 case Mips::COP021:
return Mips::S5;
5630 case Mips::COP022:
return Mips::S6;
5631 case Mips::COP023:
return Mips::S7;
5632 case Mips::COP024:
return Mips::T8;
5633 case Mips::COP025:
return Mips::T9;
5634 case Mips::COP026:
return Mips::K0;
5635 case Mips::COP027:
return Mips::K1;
5636 case Mips::COP028:
return Mips::GP;
5637 case Mips::COP029:
return Mips::SP;
5638 case Mips::COP030:
return Mips::FP;
5639 case Mips::COP031:
return Mips::RA;
5646bool MipsAsmParser::expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5647 const MCSubtargetInfo *STI) {
5648 MipsTargetStreamer &TOut = getTargetStreamer();
5653 bool IsMFTR =
false;
5707 IsMFTR ? MCRegister(rd)
5709 : Inst.getOperand(0).
getReg());
5711 TOut.
emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, u, sel, h, IDLoc,
5716bool MipsAsmParser::expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5717 const MCSubtargetInfo *STI) {
5722 warnIfNoMacro(IDLoc);
5724 MipsTargetStreamer &TOut = getTargetStreamer();
5725 unsigned Opcode = Inst.
getOpcode() == Mips::SaaAddr ? Mips::SAA : Mips::SAAD;
5728 const MCOperand &BaseOp = Inst.
getOperand(2);
5730 if (BaseOp.
isImm()) {
5731 int64_t ImmValue = BaseOp.
getImm();
5732 if (ImmValue == 0) {
5733 TOut.
emitRR(Opcode, RtReg, BaseReg, IDLoc, STI);
5738 MCRegister ATReg = getATReg(IDLoc);
5742 if (expandLoadAddress(ATReg, BaseReg, BaseOp, !isGP64bit(), IDLoc, Out, STI))
5745 TOut.
emitRR(Opcode, RtReg, ATReg, IDLoc, STI);
5750MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
5754 return Match_Success;
5757 if (
static_cast<MipsOperand &
>(*Operands[1])
5758 .isValidForTie(
static_cast<MipsOperand &
>(*Operands[2])))
5759 return Match_Success;
5760 return Match_RequiresSameSrcAndDst;
5764unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
5771 return Match_RequiresNoZeroRegister;
5772 return Match_Success;
5778 case Mips::JALR_HB64:
5779 case Mips::JALRC_HB_MMR6:
5780 case Mips::JALRC_MMR6:
5782 return Match_RequiresDifferentSrcAndDst;
5783 return Match_Success;
5786 return Match_RequiresDifferentSrcAndDst;
5787 return Match_Success;
5790 return Match_NonZeroOperandForSync;
5791 return Match_Success;
5797 return Match_NonZeroOperandForMTCX;
5798 return Match_Success;
5811 case Mips::BLEZC:
case Mips::BLEZC_MMR6:
5812 case Mips::BGEZC:
case Mips::BGEZC_MMR6:
5813 case Mips::BGTZC:
case Mips::BGTZC_MMR6:
5814 case Mips::BLTZC:
case Mips::BLTZC_MMR6:
5815 case Mips::BEQZC:
case Mips::BEQZC_MMR6:
5816 case Mips::BNEZC:
case Mips::BNEZC_MMR6:
5825 return Match_RequiresNoZeroRegister;
5826 return Match_Success;
5827 case Mips::BGEC:
case Mips::BGEC_MMR6:
5828 case Mips::BLTC:
case Mips::BLTC_MMR6:
5829 case Mips::BGEUC:
case Mips::BGEUC_MMR6:
5830 case Mips::BLTUC:
case Mips::BLTUC_MMR6:
5831 case Mips::BEQC:
case Mips::BEQC_MMR6:
5832 case Mips::BNEC:
case Mips::BNEC_MMR6:
5841 return Match_RequiresNoZeroRegister;
5844 return Match_RequiresNoZeroRegister;
5846 return Match_RequiresDifferentOperands;
5847 return Match_Success;
5850 "Operands must be immediates for dins!");
5853 if ((0 > (Pos +
Size)) || ((Pos +
Size) > 32))
5854 return Match_RequiresPosSizeRange0_32;
5855 return Match_Success;
5860 "Operands must be immediates for dinsm/dinsu!");
5863 if ((32 >= (Pos +
Size)) || ((Pos +
Size) > 64))
5864 return Match_RequiresPosSizeRange33_64;
5865 return Match_Success;
5869 "Operands must be immediates for DEXTM!");
5872 if ((1 > (Pos +
Size)) || ((Pos +
Size) > 63))
5873 return Match_RequiresPosSizeUImm6;
5874 return Match_Success;
5879 "Operands must be immediates for dextm/dextu!");
5882 if ((32 > (Pos +
Size)) || ((Pos +
Size) > 64))
5883 return Match_RequiresPosSizeRange33_64;
5884 return Match_Success;
5886 case Mips::CRC32B:
case Mips::CRC32CB:
5887 case Mips::CRC32H:
case Mips::CRC32CH:
5888 case Mips::CRC32W:
case Mips::CRC32CW:
5889 case Mips::CRC32D:
case Mips::CRC32CD:
5891 return Match_RequiresSameSrcAndDst;
5892 return Match_Success;
5895 uint64_t TSFlags = MII.get(Inst.
getOpcode()).TSFlags;
5898 return Match_NoFCCRegisterForCurrentISA;
5900 return Match_Success;
5908 if (ErrorLoc ==
SMLoc())
5915bool MipsAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
5918 uint64_t &ErrorInfo,
5919 bool MatchingInlineAsm) {
5921 unsigned MatchResult =
5922 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
5924 switch (MatchResult) {
5926 if (processInstruction(Inst, IDLoc, Out, STI))
5929 case Match_MissingFeature:
5930 Error(IDLoc,
"instruction requires a CPU feature not currently enabled");
5932 case Match_InvalidTiedOperand:
5933 Error(IDLoc,
"operand must match destination register");
5935 case Match_InvalidOperand: {
5936 SMLoc ErrorLoc = IDLoc;
5937 if (ErrorInfo != ~0ULL) {
5938 if (ErrorInfo >= Operands.
size())
5939 return Error(IDLoc,
"too few operands for instruction");
5941 ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5942 if (ErrorLoc == SMLoc())
5946 return Error(ErrorLoc,
"invalid operand for instruction");
5948 case Match_NonZeroOperandForSync:
5950 "s-type must be zero or unspecified for pre-MIPS32 ISAs");
5951 case Match_NonZeroOperandForMTCX:
5952 return Error(IDLoc,
"selector must be zero for pre-MIPS32 ISAs");
5953 case Match_MnemonicFail:
5954 return Error(IDLoc,
"invalid instruction");
5955 case Match_RequiresDifferentSrcAndDst:
5956 return Error(IDLoc,
"source and destination must be different");
5957 case Match_RequiresDifferentOperands:
5958 return Error(IDLoc,
"registers must be different");
5959 case Match_RequiresNoZeroRegister:
5960 return Error(IDLoc,
"invalid operand ($zero) for instruction");
5961 case Match_RequiresSameSrcAndDst:
5962 return Error(IDLoc,
"source and destination must match");
5963 case Match_NoFCCRegisterForCurrentISA:
5965 "non-zero fcc register doesn't exist in current ISA level");
5970 "expected 1-bit unsigned immediate");
5973 "expected 2-bit unsigned immediate");
5976 "expected immediate in range 1 .. 4");
5979 "expected 3-bit unsigned immediate");
5982 "expected 4-bit unsigned immediate");
5985 "expected 4-bit signed immediate");
5988 "expected 5-bit unsigned immediate");
5991 "expected 5-bit signed immediate");
5994 "expected immediate in range 1 .. 32");
5995 case Match_UImm5_32:
5997 "expected immediate in range 32 .. 63");
5998 case Match_UImm5_33:
6000 "expected immediate in range 33 .. 64");
6001 case Match_UImm5_0_Report_UImm6:
6005 "expected 6-bit unsigned immediate");
6006 case Match_UImm5_Lsl2:
6008 "expected both 7-bit unsigned immediate and multiple of 4");
6009 case Match_UImmRange2_64:
6011 "expected immediate in range 2 .. 64");
6014 "expected 6-bit unsigned immediate");
6015 case Match_UImm6_Lsl2:
6017 "expected both 8-bit unsigned immediate and multiple of 4");
6020 "expected 6-bit signed immediate");
6023 "expected 7-bit unsigned immediate");
6024 case Match_UImm7_N1:
6026 "expected immediate in range -1 .. 126");
6027 case Match_SImm7_Lsl2:
6029 "expected both 9-bit signed immediate and multiple of 4");
6032 "expected 8-bit unsigned immediate");
6033 case Match_UImm10_0:
6035 "expected 10-bit unsigned immediate");
6036 case Match_SImm10_0:
6038 "expected 10-bit signed immediate");
6039 case Match_SImm11_0:
6041 "expected 11-bit signed immediate");
6043 case Match_UImm16_Relaxed:
6044 case Match_UImm16_AltRelaxed:
6046 "expected 16-bit unsigned immediate");
6048 case Match_SImm16_Relaxed:
6050 "expected 16-bit signed immediate");
6051 case Match_SImm19_Lsl2:
6053 "expected both 19-bit signed immediate and multiple of 4");
6054 case Match_UImm20_0:
6056 "expected 20-bit unsigned immediate");
6057 case Match_UImm26_0:
6059 "expected 26-bit unsigned immediate");
6061 case Match_SImm32_Relaxed:
6063 "expected 32-bit signed immediate");
6064 case Match_UImm32_Coerced:
6066 "expected 32-bit immediate");
6067 case Match_MemSImm9:
6069 "expected memory with 9-bit signed offset");
6070 case Match_MemSImm10:
6072 "expected memory with 10-bit signed offset");
6073 case Match_MemSImm10Lsl1:
6075 "expected memory with 11-bit signed offset and multiple of 2");
6076 case Match_MemSImm10Lsl2:
6078 "expected memory with 12-bit signed offset and multiple of 4");
6079 case Match_MemSImm10Lsl3:
6081 "expected memory with 13-bit signed offset and multiple of 8");
6082 case Match_MemSImm11:
6084 "expected memory with 11-bit signed offset");
6085 case Match_MemSImm12:
6087 "expected memory with 12-bit signed offset");
6088 case Match_MemSImm16:
6090 "expected memory with 16-bit signed offset");
6091 case Match_MemSImmPtr:
6093 "expected memory with 32-bit signed offset");
6094 case Match_RequiresPosSizeRange0_32: {
6095 SMLoc ErrorStart = Operands[3]->getStartLoc();
6096 SMLoc ErrorEnd = Operands[4]->getEndLoc();
6097 return Error(ErrorStart,
"size plus position are not in the range 0 .. 32",
6098 SMRange(ErrorStart, ErrorEnd));
6100 case Match_RequiresPosSizeUImm6: {
6101 SMLoc ErrorStart = Operands[3]->getStartLoc();
6102 SMLoc ErrorEnd = Operands[4]->getEndLoc();
6103 return Error(ErrorStart,
"size plus position are not in the range 1 .. 63",
6104 SMRange(ErrorStart, ErrorEnd));
6106 case Match_RequiresPosSizeRange33_64: {
6107 SMLoc ErrorStart = Operands[3]->getStartLoc();
6108 SMLoc ErrorEnd = Operands[4]->getEndLoc();
6109 return Error(ErrorStart,
"size plus position are not in the range 33 .. 64",
6110 SMRange(ErrorStart, ErrorEnd));
6117void MipsAsmParser::warnIfRegIndexIsAT(MCRegister RegIndex, SMLoc Loc) {
6118 if (RegIndex && AssemblerOptions.
back()->getATRegIndex() == RegIndex)
6119 Warning(Loc,
"used $at (currently $" + Twine(RegIndex.
id()) +
6120 ") without \".set noat\"");
6123void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
6124 if (!AssemblerOptions.
back()->isMacro())
6125 Warning(Loc,
"macro instruction expanded into multiple instructions");
6128void MipsAsmParser::ConvertXWPOperands(MCInst &Inst,
6132 "Unexpected instruction!");
6133 ((MipsOperand &)*Operands[1]).addGPR32ZeroAsmRegOperands(Inst, 1);
6134 MCRegister NextReg =
nextReg(((MipsOperand &)*Operands[1]).getGPR32Reg());
6136 ((MipsOperand &)*Operands[2]).addMemOperands(Inst, 2);
6140MipsAsmParser::printWarningWithFixIt(
const Twine &Msg,
const Twine &FixMsg,
6141 SMRange
Range,
bool ShowColors) {
6147int MipsAsmParser::matchCPURegisterName(StringRef Name) {
6150 CC = StringSwitch<unsigned>(Name)
6152 .Cases({
"at",
"AT"}, 1)
6186 if (!(isABI_N32() || isABI_N64()))
6189 if (12 <= CC && CC <= 15) {
6191 AsmToken RegTok = getLexer().peekTok();
6194 StringRef FixedName = StringSwitch<StringRef>(Name)
6200 assert(FixedName !=
"" &&
"Register name is not one of t4-t7.");
6202 printWarningWithFixIt(
"register names $t4-$t7 are only available in O32.",
6203 "Did you mean $" + FixedName +
"?", RegRange);
6209 if (8 <= CC && CC <= 11)
6213 CC = StringSwitch<unsigned>(Name)
6225int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
6228 CC = StringSwitch<unsigned>(Name)
6229 .Case(
"hwr_cpunum", 0)
6230 .Case(
"hwr_synci_step", 1)
6232 .Case(
"hwr_ccres", 3)
6233 .Case(
"hwr_ulr", 29)
6239int MipsAsmParser::matchFPURegisterName(StringRef Name) {
6240 if (Name[0] ==
'f') {
6241 StringRef NumString =
Name.substr(1);
6252int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
6253 if (
Name.starts_with(
"fcc")) {
6254 StringRef NumString =
Name.substr(3);
6265int MipsAsmParser::matchACRegisterName(StringRef Name) {
6266 if (
Name.starts_with(
"ac")) {
6267 StringRef NumString =
Name.substr(2);
6278int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
6281 if (
Name.front() !=
'w' ||
Name.drop_front(1).getAsInteger(10, IntVal))
6290int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
6293 CC = StringSwitch<unsigned>(Name)
6296 .Case(
"msaaccess", 2)
6298 .Case(
"msamodify", 4)
6299 .Case(
"msarequest", 5)
6301 .Case(
"msaunmap", 7)
6307bool MipsAsmParser::canUseATReg() {
6308 return AssemblerOptions.
back()->getATRegIndex() != 0;
6311MCRegister MipsAsmParser::getATReg(SMLoc Loc) {
6312 unsigned ATIndex = AssemblerOptions.
back()->getATRegIndex();
6314 reportParseError(Loc,
6315 "pseudo-instruction requires $at, which is not available");
6319 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
6323MCRegister MipsAsmParser::getReg(
int RC,
int RegNo) {
6324 return getContext().getRegisterInfo()->getRegClass(RC).getRegister(RegNo);
6330const MCExpr *MipsAsmParser::parseRelocExpr() {
6331 auto getOp = [](StringRef
Op) {
6332 return StringSwitch<Mips::Specifier>(
Op)
6360 MCAsmParser &Parser = getParser();
6362 const MCExpr *Res =
nullptr;
6368 auto Op = getOp(Name);
6377 while (
Ops.size()) {
6385bool MipsAsmParser::parseOperand(
OperandVector &Operands, StringRef Mnemonic) {
6386 MCAsmParser &Parser = getParser();
6396 ParseStatus Res = MatchOperandParserImpl(Operands, Mnemonic,
true);
6407 switch (getLexer().getKind()) {
6417 if (!parseAnyRegister(Operands).isNoMatch())
6430 Operands.
push_back(MipsOperand::CreateImm(SymRef, S,
E, *
this));
6435 const MCExpr *Expr = parseRelocExpr();
6439 Operands.
push_back(MipsOperand::CreateImm(Expr, S,
E, *
this));
6446bool MipsAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
6448 return !tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess();
6451ParseStatus MipsAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
6454 ParseStatus Res = parseAnyRegister(Operands);
6457 MipsOperand &Operand =
static_cast<MipsOperand &
>(*Operands.
front());
6458 StartLoc = Operand.getStartLoc();
6459 EndLoc = Operand.getEndLoc();
6465 if (Operand.isGPRAsmReg()) {
6467 Reg = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
6477ParseStatus MipsAsmParser::parseMemOperand(
OperandVector &Operands) {
6478 MCAsmParser &Parser = getParser();
6480 const MCExpr *IdVal =
nullptr;
6482 bool isParenExpr =
false;
6493 IdVal = parseRelocExpr();
6499 const AsmToken &Tok = Parser.
getTok();
6501 MipsOperand &Mnemonic =
static_cast<MipsOperand &
>(*Operands[0]);
6502 if (Mnemonic.getToken() ==
"la" || Mnemonic.getToken() ==
"dla") {
6505 Operands.
push_back(MipsOperand::CreateImm(IdVal, S,
E, *
this));
6514 auto Base = MipsOperand::createGPRReg(
6515 0,
"0",
getContext().getRegisterInfo(), S,
E, *
this);
6517 MipsOperand::CreateMem(std::move(
Base), IdVal, S,
E, *
this));
6569 const MCExpr * NextExpr;
6570 if (getParser().parseExpression(NextExpr))
6578 Res = parseAnyRegister(Operands);
6593 std::unique_ptr<MipsOperand>
op(
6594 static_cast<MipsOperand *
>(Operands.
back().release()));
6601 if (IdVal->evaluateAsAbsolute(Imm))
6608 Operands.
push_back(MipsOperand::CreateMem(std::move(
op), IdVal, S,
E, *
this));
6612bool MipsAsmParser::searchSymbolAlias(
OperandVector &Operands) {
6613 MCAsmParser &Parser = getParser();
6622 const MCSymbolRefExpr *
Ref =
static_cast<const MCSymbolRefExpr *
>(Expr);
6623 StringRef DefSymbol =
Ref->getSymbol().getName();
6626 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.
substr(1), S);
6640 if (Entry != RegisterSets.
end()) {
6642 matchAnyRegisterWithoutDollar(Operands,
Entry->getValue(), S);
6653ParseStatus MipsAsmParser::matchAnyRegisterNameWithoutDollar(
6655 int Index = matchCPURegisterName(Identifier);
6657 Operands.
push_back(MipsOperand::createGPRReg(
6658 Index, Identifier,
getContext().getRegisterInfo(), S,
6659 getLexer().getLoc(), *
this));
6663 Index = matchHWRegsRegisterName(Identifier);
6665 Operands.
push_back(MipsOperand::createHWRegsReg(
6666 Index, Identifier,
getContext().getRegisterInfo(), S,
6667 getLexer().getLoc(), *
this));
6671 Index = matchFPURegisterName(Identifier);
6673 Operands.
push_back(MipsOperand::createFGRReg(
6674 Index, Identifier,
getContext().getRegisterInfo(), S,
6675 getLexer().getLoc(), *
this));
6679 Index = matchFCCRegisterName(Identifier);
6681 Operands.
push_back(MipsOperand::createFCCReg(
6682 Index, Identifier,
getContext().getRegisterInfo(), S,
6683 getLexer().getLoc(), *
this));
6687 Index = matchACRegisterName(Identifier);
6689 Operands.
push_back(MipsOperand::createACCReg(
6690 Index, Identifier,
getContext().getRegisterInfo(), S,
6691 getLexer().getLoc(), *
this));
6695 Index = matchMSA128RegisterName(Identifier);
6697 Operands.
push_back(MipsOperand::createMSA128Reg(
6698 Index, Identifier,
getContext().getRegisterInfo(), S,
6699 getLexer().getLoc(), *
this));
6703 Index = matchMSA128CtrlRegisterName(Identifier);
6705 Operands.
push_back(MipsOperand::createMSACtrlReg(
6706 Index, Identifier,
getContext().getRegisterInfo(), S,
6707 getLexer().getLoc(), *
this));
6715MipsAsmParser::matchAnyRegisterWithoutDollar(
OperandVector &Operands,
6716 const AsmToken &Token, SMLoc S) {
6720 return matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
6725 if (RegNum < 0 || RegNum > 31) {
6729 Error(getLexer().getLoc(),
"invalid register number");
6731 Operands.
push_back(MipsOperand::createNumericReg(
6743MipsAsmParser::matchAnyRegisterWithoutDollar(
OperandVector &Operands, SMLoc S) {
6744 auto Token = getLexer().peekTok(
false);
6745 return matchAnyRegisterWithoutDollar(Operands, Token, S);
6748ParseStatus MipsAsmParser::parseAnyRegister(
OperandVector &Operands) {
6749 MCAsmParser &Parser = getParser();
6752 auto Token = Parser.
getTok();
6754 SMLoc S = Token.
getLoc();
6759 if (searchSymbolAlias(Operands))
6767 ParseStatus Res = matchAnyRegisterWithoutDollar(Operands, S);
6775ParseStatus MipsAsmParser::parseJumpTarget(
OperandVector &Operands) {
6776 MCAsmParser &Parser = getParser();
6779 SMLoc S = getLexer().getLoc();
6782 ParseStatus Res = parseAnyRegister(Operands);
6787 const MCExpr *Expr =
nullptr;
6793 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *
this));
6797ParseStatus MipsAsmParser::parseInvNum(
OperandVector &Operands) {
6798 MCAsmParser &Parser = getParser();
6799 const MCExpr *IdVal;
6810 if (getParser().parseExpression(IdVal))
6817 Operands.
push_back(MipsOperand::CreateImm(
6822ParseStatus MipsAsmParser::parseRegisterList(
OperandVector &Operands) {
6823 MCAsmParser &Parser = getParser();
6827 bool RegRange =
false;
6834 while (parseAnyRegister(TmpOperands).isSuccess()) {
6835 SMLoc
E = getLexer().getLoc();
6836 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*TmpOperands.
back());
6837 Reg = isGP64bit() ? RegOpnd.getGPR64Reg() : RegOpnd.getGPR32Reg();
6841 if ((isGP64bit() &&
Reg == Mips::RA_64) ||
6842 (!isGP64bit() &&
Reg == Mips::RA)) {
6845 MCRegister TmpReg = PrevReg + 1;
6846 while (TmpReg <=
Reg) {
6847 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
6848 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
6850 return Error(
E,
"invalid register operand");
6854 TmpReg = TmpReg.
id() + 1;
6861 ((isGP64bit() && (
Reg != Mips::S0_64) && (
Reg != Mips::RA_64)) ||
6862 (!isGP64bit() && (
Reg != Mips::S0) && (
Reg != Mips::RA))))
6863 return Error(
E,
"$16 or $31 expected");
6864 if (!(((
Reg == Mips::FP ||
Reg == Mips::RA ||
6865 (
Reg >= Mips::S0 &&
Reg <= Mips::S7)) &&
6867 ((
Reg == Mips::FP_64 ||
Reg == Mips::RA_64 ||
6868 (
Reg >= Mips::S0_64 &&
Reg <= Mips::S7_64)) &&
6870 return Error(
E,
"invalid register operand");
6871 if (PrevReg.
isValid() && (
Reg != PrevReg + 1) &&
6872 ((
Reg != Mips::FP &&
Reg != Mips::RA && !isGP64bit()) ||
6873 (
Reg != Mips::FP_64 &&
Reg != Mips::RA_64 && isGP64bit())))
6874 return Error(
E,
"consecutive register numbers expected");
6884 return Error(
E,
"',' or '-' expected");
6894 Operands.
push_back(MipsOperand::CreateRegList(Regs, S,
E, *
this));
6895 parseMemOperand(Operands);
6904bool MipsAsmParser::parseParenSuffix(StringRef Name,
OperandVector &Operands) {
6905 MCAsmParser &Parser = getParser();
6908 MipsOperand::CreateToken(
"(", getLexer().getLoc(), *
this));
6910 if (parseOperand(Operands, Name)) {
6911 SMLoc Loc = getLexer().getLoc();
6912 return Error(Loc,
"unexpected token in argument list");
6915 SMLoc Loc = getLexer().getLoc();
6916 return Error(Loc,
"unexpected token, expected ')'");
6919 MipsOperand::CreateToken(
")", getLexer().getLoc(), *
this));
6931bool MipsAsmParser::parseBracketSuffix(StringRef Name,
6933 MCAsmParser &Parser = getParser();
6936 MipsOperand::CreateToken(
"[", getLexer().getLoc(), *
this));
6938 if (parseOperand(Operands, Name)) {
6939 SMLoc Loc = getLexer().getLoc();
6940 return Error(Loc,
"unexpected token in argument list");
6943 SMLoc Loc = getLexer().getLoc();
6944 return Error(Loc,
"unexpected token, expected ']'");
6947 MipsOperand::CreateToken(
"]", getLexer().getLoc(), *
this));
6954 unsigned VariantID = 0);
6969bool MipsAsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
6971 MCAsmParser &Parser = getParser();
6975 getTargetStreamer().forbidModuleDirective();
6978 if (!mnemonicIsValid(Name, 0)) {
6979 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
6981 return Error(NameLoc,
"unknown instruction" + Suggestion);
6984 Operands.
push_back(MipsOperand::CreateToken(Name, NameLoc, *
this));
6989 if (parseOperand(Operands, Name)) {
6990 SMLoc Loc = getLexer().getLoc();
6991 return Error(Loc,
"unexpected token in argument list");
6993 if (getLexer().is(
AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
7000 if (parseOperand(Operands, Name)) {
7001 SMLoc Loc = getLexer().getLoc();
7002 return Error(Loc,
"unexpected token in argument list");
7006 if (parseBracketSuffix(Name, Operands))
7009 parseParenSuffix(Name, Operands))
7014 SMLoc Loc = getLexer().getLoc();
7015 return Error(Loc,
"unexpected token in argument list");
7023bool MipsAsmParser::reportParseError(
const Twine &ErrorMsg) {
7024 SMLoc Loc = getLexer().getLoc();
7025 return Error(Loc, ErrorMsg);
7028bool MipsAsmParser::reportParseError(SMLoc Loc,
const Twine &ErrorMsg) {
7029 return Error(Loc, ErrorMsg);
7032bool MipsAsmParser::parseSetNoAtDirective() {
7033 MCAsmParser &Parser = getParser();
7037 AssemblerOptions.
back()->setATRegIndex(0);
7043 reportParseError(
"unexpected token, expected end of statement");
7047 getTargetStreamer().emitDirectiveSetNoAt();
7052bool MipsAsmParser::parseSetAtDirective() {
7055 MCAsmParser &Parser = getParser();
7060 AssemblerOptions.
back()->setATRegIndex(1);
7062 getTargetStreamer().emitDirectiveSetAt();
7068 reportParseError(
"unexpected token, expected equals sign");
7075 reportParseError(
"no register specified");
7078 reportParseError(
"unexpected token, expected dollar sign '$'");
7088 AtRegNo = matchCPURegisterName(
Reg.getIdentifier());
7090 AtRegNo =
Reg.getIntVal();
7092 reportParseError(
"unexpected token, expected identifier or integer");
7097 if (!AssemblerOptions.
back()->setATRegIndex(AtRegNo)) {
7098 reportParseError(
"invalid register");
7105 reportParseError(
"unexpected token, expected end of statement");
7109 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
7115bool MipsAsmParser::parseSetReorderDirective() {
7116 MCAsmParser &Parser = getParser();
7120 reportParseError(
"unexpected token, expected end of statement");
7123 AssemblerOptions.
back()->setReorder();
7124 getTargetStreamer().emitDirectiveSetReorder();
7129bool MipsAsmParser::parseSetNoReorderDirective() {
7130 MCAsmParser &Parser = getParser();
7134 reportParseError(
"unexpected token, expected end of statement");
7137 AssemblerOptions.
back()->setNoReorder();
7138 getTargetStreamer().emitDirectiveSetNoReorder();
7143bool MipsAsmParser::parseSetMacroDirective() {
7144 MCAsmParser &Parser = getParser();
7148 reportParseError(
"unexpected token, expected end of statement");
7151 AssemblerOptions.
back()->setMacro();
7152 getTargetStreamer().emitDirectiveSetMacro();
7157bool MipsAsmParser::parseSetNoMacroDirective() {
7158 MCAsmParser &Parser = getParser();
7162 reportParseError(
"unexpected token, expected end of statement");
7165 if (AssemblerOptions.
back()->isReorder()) {
7166 reportParseError(
"`noreorder' must be set before `nomacro'");
7169 AssemblerOptions.
back()->setNoMacro();
7170 getTargetStreamer().emitDirectiveSetNoMacro();
7175bool MipsAsmParser::parseSetMsaDirective() {
7176 MCAsmParser &Parser = getParser();
7181 return reportParseError(
"unexpected token, expected end of statement");
7183 setFeatureBits(Mips::FeatureMSA,
"msa");
7184 getTargetStreamer().emitDirectiveSetMsa();
7188bool MipsAsmParser::parseSetNoMsaDirective() {
7189 MCAsmParser &Parser = getParser();
7194 return reportParseError(
"unexpected token, expected end of statement");
7196 clearFeatureBits(Mips::FeatureMSA,
"msa");
7197 getTargetStreamer().emitDirectiveSetNoMsa();
7201bool MipsAsmParser::parseSetNoDspDirective() {
7202 MCAsmParser &Parser = getParser();
7207 reportParseError(
"unexpected token, expected end of statement");
7211 clearFeatureBits(Mips::FeatureDSP,
"dsp");
7212 getTargetStreamer().emitDirectiveSetNoDsp();
7216bool MipsAsmParser::parseSetNoMips3DDirective() {
7217 MCAsmParser &Parser = getParser();
7222 reportParseError(
"unexpected token, expected end of statement");
7226 clearFeatureBits(Mips::FeatureMips3D,
"mips3d");
7227 getTargetStreamer().emitDirectiveSetNoMips3D();
7231bool MipsAsmParser::parseSetMips16Directive() {
7232 MCAsmParser &Parser = getParser();
7237 reportParseError(
"unexpected token, expected end of statement");
7241 setFeatureBits(Mips::FeatureMips16,
"mips16");
7242 getTargetStreamer().emitDirectiveSetMips16();
7247bool MipsAsmParser::parseSetNoMips16Directive() {
7248 MCAsmParser &Parser = getParser();
7253 reportParseError(
"unexpected token, expected end of statement");
7257 clearFeatureBits(Mips::FeatureMips16,
"mips16");
7258 getTargetStreamer().emitDirectiveSetNoMips16();
7263bool MipsAsmParser::parseSetFpDirective() {
7264 MCAsmParser &Parser = getParser();
7270 AsmToken Tok = Parser.
getTok();
7272 reportParseError(
"unexpected token, expected equals sign '='");
7278 if (!parseFpABIValue(FpAbiVal,
".set"))
7282 reportParseError(
"unexpected token, expected end of statement");
7285 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
7290bool MipsAsmParser::parseSetOddSPRegDirective() {
7291 MCAsmParser &Parser = getParser();
7295 reportParseError(
"unexpected token, expected end of statement");
7299 clearFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
7300 getTargetStreamer().emitDirectiveSetOddSPReg();
7304bool MipsAsmParser::parseSetNoOddSPRegDirective() {
7305 MCAsmParser &Parser = getParser();
7309 reportParseError(
"unexpected token, expected end of statement");
7313 setFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
7314 getTargetStreamer().emitDirectiveSetNoOddSPReg();
7318bool MipsAsmParser::parseSetMtDirective() {
7319 MCAsmParser &Parser = getParser();
7324 reportParseError(
"unexpected token, expected end of statement");
7328 setFeatureBits(Mips::FeatureMT,
"mt");
7329 getTargetStreamer().emitDirectiveSetMt();
7334bool MipsAsmParser::parseSetNoMtDirective() {
7335 MCAsmParser &Parser = getParser();
7340 reportParseError(
"unexpected token, expected end of statement");
7344 clearFeatureBits(Mips::FeatureMT,
"mt");
7346 getTargetStreamer().emitDirectiveSetNoMt();
7351bool MipsAsmParser::parseSetNoCRCDirective() {
7352 MCAsmParser &Parser = getParser();
7357 reportParseError(
"unexpected token, expected end of statement");
7361 clearFeatureBits(Mips::FeatureCRC,
"crc");
7363 getTargetStreamer().emitDirectiveSetNoCRC();
7368bool MipsAsmParser::parseSetNoVirtDirective() {
7369 MCAsmParser &Parser = getParser();
7374 reportParseError(
"unexpected token, expected end of statement");
7378 clearFeatureBits(Mips::FeatureVirt,
"virt");
7380 getTargetStreamer().emitDirectiveSetNoVirt();
7385bool MipsAsmParser::parseSetNoGINVDirective() {
7386 MCAsmParser &Parser = getParser();
7391 reportParseError(
"unexpected token, expected end of statement");
7395 clearFeatureBits(Mips::FeatureGINV,
"ginv");
7397 getTargetStreamer().emitDirectiveSetNoGINV();
7402bool MipsAsmParser::parseSetPopDirective() {
7403 MCAsmParser &Parser = getParser();
7404 SMLoc Loc = getLexer().getLoc();
7408 return reportParseError(
"unexpected token, expected end of statement");
7412 if (AssemblerOptions.
size() == 2)
7413 return reportParseError(Loc,
".set pop with no .set push");
7415 MCSubtargetInfo &STI = copySTI();
7417 setAvailableFeatures(
7418 ComputeAvailableFeatures(AssemblerOptions.
back()->getFeatures()));
7421 getTargetStreamer().emitDirectiveSetPop();
7425bool MipsAsmParser::parseSetPushDirective() {
7426 MCAsmParser &Parser = getParser();
7429 return reportParseError(
"unexpected token, expected end of statement");
7433 std::make_unique<MipsAssemblerOptions>(AssemblerOptions.
back().get()));
7435 getTargetStreamer().emitDirectiveSetPush();
7439bool MipsAsmParser::parseSetSoftFloatDirective() {
7440 MCAsmParser &Parser = getParser();
7443 return reportParseError(
"unexpected token, expected end of statement");
7445 setFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
7446 getTargetStreamer().emitDirectiveSetSoftFloat();
7450bool MipsAsmParser::parseSetHardFloatDirective() {
7451 MCAsmParser &Parser = getParser();
7454 return reportParseError(
"unexpected token, expected end of statement");
7456 clearFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
7457 getTargetStreamer().emitDirectiveSetHardFloat();
7461bool MipsAsmParser::parseSetAssignment() {
7463 MCAsmParser &Parser = getParser();
7466 return reportParseError(
"expected identifier after .set");
7469 return reportParseError(
"unexpected token, expected comma");
7484 const MCExpr *
Value;
7486 Parser, Sym,
Value))
7488 getStreamer().emitAssignment(Sym,
Value);
7493bool MipsAsmParser::parseSetMips0Directive() {
7494 MCAsmParser &Parser = getParser();
7497 return reportParseError(
"unexpected token, expected end of statement");
7500 MCSubtargetInfo &STI = copySTI();
7501 setAvailableFeatures(
7502 ComputeAvailableFeatures(AssemblerOptions.
front()->getFeatures()));
7504 AssemblerOptions.
back()->setFeatures(AssemblerOptions.
front()->getFeatures());
7506 getTargetStreamer().emitDirectiveSetMips0();
7510bool MipsAsmParser::parseSetArchDirective() {
7511 MCAsmParser &Parser = getParser();
7514 return reportParseError(
"unexpected token, expected equals sign");
7517 StringRef Arch = getParser().parseStringToEndOfStatement().trim();
7519 return reportParseError(
"expected arch identifier");
7521 StringRef ArchFeatureName =
7522 StringSwitch<StringRef>(Arch)
7523 .Case(
"mips1",
"mips1")
7524 .Case(
"mips2",
"mips2")
7525 .Case(
"mips3",
"mips3")
7526 .Case(
"mips4",
"mips4")
7527 .Case(
"mips5",
"mips5")
7528 .Case(
"mips32",
"mips32")
7529 .Case(
"mips32r2",
"mips32r2")
7530 .Case(
"mips32r3",
"mips32r3")
7531 .Case(
"mips32r5",
"mips32r5")
7532 .Case(
"mips32r6",
"mips32r6")
7533 .Case(
"mips64",
"mips64")
7534 .Case(
"mips64r2",
"mips64r2")
7535 .Case(
"mips64r3",
"mips64r3")
7536 .Case(
"mips64r5",
"mips64r5")
7537 .Case(
"mips64r6",
"mips64r6")
7538 .Case(
"octeon",
"cnmips")
7539 .Case(
"octeon+",
"cnmipsp")
7540 .Case(
"r4000",
"mips3")
7543 if (ArchFeatureName.
empty())
7544 return reportParseError(
"unsupported architecture");
7546 if (ArchFeatureName ==
"mips64r6" && inMicroMipsMode())
7547 return reportParseError(
"mips64r6 does not support microMIPS");
7549 selectArch(ArchFeatureName);
7550 getTargetStreamer().emitDirectiveSetArch(Arch);
7554bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
7555 MCAsmParser &Parser = getParser();
7558 return reportParseError(
"unexpected token, expected end of statement");
7563 case Mips::FeatureMips3D:
7564 setFeatureBits(Mips::FeatureMips3D,
"mips3d");
7565 getTargetStreamer().emitDirectiveSetMips3D();
7567 case Mips::FeatureDSP:
7568 setFeatureBits(Mips::FeatureDSP,
"dsp");
7569 getTargetStreamer().emitDirectiveSetDsp();
7571 case Mips::FeatureDSPR2:
7572 setFeatureBits(Mips::FeatureDSPR2,
"dspr2");
7573 getTargetStreamer().emitDirectiveSetDspr2();
7575 case Mips::FeatureMicroMips:
7576 setFeatureBits(Mips::FeatureMicroMips,
"micromips");
7577 getTargetStreamer().emitDirectiveSetMicroMips();
7579 case Mips::FeatureMips1:
7580 selectArch(
"mips1");
7581 getTargetStreamer().emitDirectiveSetMips1();
7583 case Mips::FeatureMips2:
7584 selectArch(
"mips2");
7585 getTargetStreamer().emitDirectiveSetMips2();
7587 case Mips::FeatureMips3:
7588 selectArch(
"mips3");
7589 getTargetStreamer().emitDirectiveSetMips3();
7591 case Mips::FeatureMips4:
7592 selectArch(
"mips4");
7593 getTargetStreamer().emitDirectiveSetMips4();
7595 case Mips::FeatureMips5:
7596 selectArch(
"mips5");
7597 getTargetStreamer().emitDirectiveSetMips5();
7599 case Mips::FeatureMips32:
7600 selectArch(
"mips32");
7601 getTargetStreamer().emitDirectiveSetMips32();
7603 case Mips::FeatureMips32r2:
7604 selectArch(
"mips32r2");
7605 getTargetStreamer().emitDirectiveSetMips32R2();
7607 case Mips::FeatureMips32r3:
7608 selectArch(
"mips32r3");
7609 getTargetStreamer().emitDirectiveSetMips32R3();
7611 case Mips::FeatureMips32r5:
7612 selectArch(
"mips32r5");
7613 getTargetStreamer().emitDirectiveSetMips32R5();
7615 case Mips::FeatureMips32r6:
7616 selectArch(
"mips32r6");
7617 getTargetStreamer().emitDirectiveSetMips32R6();
7619 case Mips::FeatureMips64:
7620 selectArch(
"mips64");
7621 getTargetStreamer().emitDirectiveSetMips64();
7623 case Mips::FeatureMips64r2:
7624 selectArch(
"mips64r2");
7625 getTargetStreamer().emitDirectiveSetMips64R2();
7627 case Mips::FeatureMips64r3:
7628 selectArch(
"mips64r3");
7629 getTargetStreamer().emitDirectiveSetMips64R3();
7631 case Mips::FeatureMips64r5:
7632 selectArch(
"mips64r5");
7633 getTargetStreamer().emitDirectiveSetMips64R5();
7635 case Mips::FeatureMips64r6:
7636 selectArch(
"mips64r6");
7637 getTargetStreamer().emitDirectiveSetMips64R6();
7639 case Mips::FeatureCRC:
7640 setFeatureBits(Mips::FeatureCRC,
"crc");
7641 getTargetStreamer().emitDirectiveSetCRC();
7643 case Mips::FeatureVirt:
7644 setFeatureBits(Mips::FeatureVirt,
"virt");
7645 getTargetStreamer().emitDirectiveSetVirt();
7647 case Mips::FeatureGINV:
7648 setFeatureBits(Mips::FeatureGINV,
"ginv");
7649 getTargetStreamer().emitDirectiveSetGINV();
7655bool MipsAsmParser::eatComma(StringRef ErrorStr) {
7656 MCAsmParser &Parser = getParser();
7658 SMLoc Loc = getLexer().getLoc();
7659 return Error(Loc, ErrorStr);
7670bool MipsAsmParser::isPicAndNotNxxAbi() {
7671 return inPicMode() && !(isABI_N32() || isABI_N64());
7674bool MipsAsmParser::parseDirectiveCpAdd(SMLoc Loc) {
7676 ParseStatus Res = parseAnyRegister(
Reg);
7678 reportParseError(
"expected register");
7682 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7683 if (!RegOpnd.isGPRAsmReg()) {
7684 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7690 reportParseError(
"unexpected token, expected end of statement");
7695 getTargetStreamer().emitDirectiveCpAdd(RegOpnd.getGPR32Reg());
7699bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
7700 if (AssemblerOptions.
back()->isReorder())
7701 Warning(Loc,
".cpload should be inside a noreorder section");
7703 if (inMips16Mode()) {
7704 reportParseError(
".cpload is not supported in Mips16 mode");
7709 ParseStatus Res = parseAnyRegister(
Reg);
7711 reportParseError(
"expected register containing function address");
7715 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7716 if (!RegOpnd.isGPRAsmReg()) {
7717 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7723 reportParseError(
"unexpected token, expected end of statement");
7727 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
7731bool MipsAsmParser::parseDirectiveCpLocal(SMLoc Loc) {
7732 if (!isABI_N32() && !isABI_N64()) {
7733 reportParseError(
".cplocal is allowed only in N32 or N64 mode");
7738 ParseStatus Res = parseAnyRegister(
Reg);
7740 reportParseError(
"expected register containing global pointer");
7744 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7745 if (!RegOpnd.isGPRAsmReg()) {
7746 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7752 reportParseError(
"unexpected token, expected end of statement");
7757 MCRegister NewReg = RegOpnd.getGPR32Reg();
7761 getTargetStreamer().emitDirectiveCpLocal(NewReg);
7765bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
7766 MCAsmParser &Parser = getParser();
7771 if (inMips16Mode()) {
7772 reportParseError(
".cprestore is not supported in Mips16 mode");
7777 const MCExpr *StackOffset;
7778 int64_t StackOffsetVal;
7780 reportParseError(
"expected stack offset value");
7784 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
7785 reportParseError(
"stack offset is not an absolute expression");
7789 if (StackOffsetVal < 0) {
7790 Warning(Loc,
".cprestore with negative stack offset has no effect");
7791 IsCpRestoreSet =
false;
7793 IsCpRestoreSet =
true;
7794 CpRestoreOffset = StackOffsetVal;
7799 reportParseError(
"unexpected token, expected end of statement");
7803 if (!getTargetStreamer().emitDirectiveCpRestore(
7804 CpRestoreOffset, [&]() {
return getATReg(Loc); }, Loc, STI))
7810bool MipsAsmParser::parseDirectiveCPSetup() {
7811 MCAsmParser &Parser = getParser();
7813 bool SaveIsReg =
true;
7816 ParseStatus Res = parseAnyRegister(TmpReg);
7818 reportParseError(
"expected register containing function address");
7822 MipsOperand &FuncRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7823 if (!FuncRegOpnd.isGPRAsmReg()) {
7824 reportParseError(FuncRegOpnd.getStartLoc(),
"invalid register");
7828 MCRegister FuncReg = FuncRegOpnd.getGPR32Reg();
7831 if (!eatComma(
"unexpected token, expected comma"))
7834 Res = parseAnyRegister(TmpReg);
7836 const MCExpr *OffsetExpr;
7838 SMLoc ExprLoc = getLexer().
getLoc();
7841 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
7842 reportParseError(ExprLoc,
"expected save register or stack offset");
7849 MipsOperand &SaveOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7850 if (!SaveOpnd.isGPRAsmReg()) {
7851 reportParseError(SaveOpnd.getStartLoc(),
"invalid register");
7854 Save = SaveOpnd.getGPR32Reg().id();
7857 if (!eatComma(
"unexpected token, expected comma"))
7862 reportParseError(
"expected expression");
7867 reportParseError(
"expected symbol");
7870 const MCSymbolRefExpr *
Ref =
static_cast<const MCSymbolRefExpr *
>(Expr);
7872 CpSaveLocation = Save;
7873 CpSaveLocationIsRegister = SaveIsReg;
7875 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save,
Ref->getSymbol(),
7880bool MipsAsmParser::parseDirectiveCPReturn() {
7881 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
7882 CpSaveLocationIsRegister);
7886bool MipsAsmParser::parseDirectiveNaN() {
7887 MCAsmParser &Parser = getParser();
7889 const AsmToken &Tok = Parser.
getTok();
7893 getTargetStreamer().emitDirectiveNaN2008();
7895 }
else if (Tok.
getString() ==
"legacy") {
7897 getTargetStreamer().emitDirectiveNaNLegacy();
7903 reportParseError(
"invalid option in .nan directive");
7907bool MipsAsmParser::parseDirectiveSet() {
7908 const AsmToken &Tok = getParser().getTok();
7910 SMLoc Loc = Tok.
getLoc();
7912 if (IdVal ==
"noat")
7913 return parseSetNoAtDirective();
7915 return parseSetAtDirective();
7916 if (IdVal ==
"arch")
7917 return parseSetArchDirective();
7918 if (IdVal ==
"bopt") {
7919 Warning(Loc,
"'bopt' feature is unsupported");
7923 if (IdVal ==
"nobopt") {
7929 return parseSetFpDirective();
7930 if (IdVal ==
"oddspreg")
7931 return parseSetOddSPRegDirective();
7932 if (IdVal ==
"nooddspreg")
7933 return parseSetNoOddSPRegDirective();
7935 return parseSetPopDirective();
7936 if (IdVal ==
"push")
7937 return parseSetPushDirective();
7938 if (IdVal ==
"reorder")
7939 return parseSetReorderDirective();
7940 if (IdVal ==
"noreorder")
7941 return parseSetNoReorderDirective();
7942 if (IdVal ==
"macro")
7943 return parseSetMacroDirective();
7944 if (IdVal ==
"nomacro")
7945 return parseSetNoMacroDirective();
7946 if (IdVal ==
"mips16")
7947 return parseSetMips16Directive();
7948 if (IdVal ==
"nomips16")
7949 return parseSetNoMips16Directive();
7950 if (IdVal ==
"nomicromips") {
7951 clearFeatureBits(Mips::FeatureMicroMips,
"micromips");
7952 getTargetStreamer().emitDirectiveSetNoMicroMips();
7953 getParser().eatToEndOfStatement();
7956 if (IdVal ==
"micromips") {
7957 if (hasMips64r6()) {
7958 Error(Loc,
".set micromips directive is not supported with MIPS64R6");
7961 return parseSetFeature(Mips::FeatureMicroMips);
7963 if (IdVal ==
"mips0")
7964 return parseSetMips0Directive();
7965 if (IdVal ==
"mips1")
7966 return parseSetFeature(Mips::FeatureMips1);
7967 if (IdVal ==
"mips2")
7968 return parseSetFeature(Mips::FeatureMips2);
7969 if (IdVal ==
"mips3")
7970 return parseSetFeature(Mips::FeatureMips3);
7971 if (IdVal ==
"mips4")
7972 return parseSetFeature(Mips::FeatureMips4);
7973 if (IdVal ==
"mips5")
7974 return parseSetFeature(Mips::FeatureMips5);
7975 if (IdVal ==
"mips32")
7976 return parseSetFeature(Mips::FeatureMips32);
7977 if (IdVal ==
"mips32r2")
7978 return parseSetFeature(Mips::FeatureMips32r2);
7979 if (IdVal ==
"mips32r3")
7980 return parseSetFeature(Mips::FeatureMips32r3);
7981 if (IdVal ==
"mips32r5")
7982 return parseSetFeature(Mips::FeatureMips32r5);
7983 if (IdVal ==
"mips32r6")
7984 return parseSetFeature(Mips::FeatureMips32r6);
7985 if (IdVal ==
"mips64")
7986 return parseSetFeature(Mips::FeatureMips64);
7987 if (IdVal ==
"mips64r2")
7988 return parseSetFeature(Mips::FeatureMips64r2);
7989 if (IdVal ==
"mips64r3")
7990 return parseSetFeature(Mips::FeatureMips64r3);
7991 if (IdVal ==
"mips64r5")
7992 return parseSetFeature(Mips::FeatureMips64r5);
7993 if (IdVal ==
"mips64r6") {
7994 if (inMicroMipsMode()) {
7995 Error(Loc,
"MIPS64R6 is not supported with microMIPS");
7998 return parseSetFeature(Mips::FeatureMips64r6);
8001 return parseSetFeature(Mips::FeatureDSP);
8002 if (IdVal ==
"dspr2")
8003 return parseSetFeature(Mips::FeatureDSPR2);
8004 if (IdVal ==
"nodsp")
8005 return parseSetNoDspDirective();
8006 if (IdVal ==
"mips3d")
8007 return parseSetFeature(Mips::FeatureMips3D);
8008 if (IdVal ==
"nomips3d")
8009 return parseSetNoMips3DDirective();
8011 return parseSetMsaDirective();
8012 if (IdVal ==
"nomsa")
8013 return parseSetNoMsaDirective();
8015 return parseSetMtDirective();
8016 if (IdVal ==
"nomt")
8017 return parseSetNoMtDirective();
8018 if (IdVal ==
"softfloat")
8019 return parseSetSoftFloatDirective();
8020 if (IdVal ==
"hardfloat")
8021 return parseSetHardFloatDirective();
8023 return parseSetFeature(Mips::FeatureCRC);
8024 if (IdVal ==
"nocrc")
8025 return parseSetNoCRCDirective();
8026 if (IdVal ==
"virt")
8027 return parseSetFeature(Mips::FeatureVirt);
8028 if (IdVal ==
"novirt")
8029 return parseSetNoVirtDirective();
8030 if (IdVal ==
"ginv")
8031 return parseSetFeature(Mips::FeatureGINV);
8032 if (IdVal ==
"noginv")
8033 return parseSetNoGINVDirective();
8036 return parseSetAssignment();
8041bool MipsAsmParser::parseDirectiveGpWord() {
8042 const MCExpr *
Value;
8043 if (getParser().parseExpression(
Value))
8045 getTargetStreamer().emitGPRel32Value(
Value);
8051bool MipsAsmParser::parseDirectiveGpDWord() {
8052 const MCExpr *
Value;
8053 if (getParser().parseExpression(
Value))
8055 getTargetStreamer().emitGPRel64Value(
Value);
8061bool MipsAsmParser::parseDirectiveDtpRelWord() {
8062 const MCExpr *
Value;
8063 if (getParser().parseExpression(
Value))
8065 getTargetStreamer().emitDTPRel32Value(
Value);
8071bool MipsAsmParser::parseDirectiveDtpRelDWord() {
8072 const MCExpr *
Value;
8073 if (getParser().parseExpression(
Value))
8075 getTargetStreamer().emitDTPRel64Value(
Value);
8081bool MipsAsmParser::parseDirectiveTpRelWord() {
8082 const MCExpr *
Value;
8083 if (getParser().parseExpression(
Value))
8085 getTargetStreamer().emitTPRel32Value(
Value);
8091bool MipsAsmParser::parseDirectiveTpRelDWord() {
8092 const MCExpr *
Value;
8093 if (getParser().parseExpression(
Value))
8095 getTargetStreamer().emitTPRel64Value(
Value);
8099bool MipsAsmParser::parseDirectiveOption() {
8100 MCAsmParser &Parser = getParser();
8102 AsmToken Tok = Parser.
getTok();
8106 "unexpected token, expected identifier");
8111 if (Option ==
"pic0") {
8113 IsPicEnabled =
false;
8115 getTargetStreamer().emitDirectiveOptionPic0();
8119 "unexpected token, expected end of statement");
8124 if (Option ==
"pic2") {
8126 IsPicEnabled =
true;
8128 getTargetStreamer().emitDirectiveOptionPic2();
8132 "unexpected token, expected end of statement");
8139 "unknown option, expected 'pic0' or 'pic2'");
8146bool MipsAsmParser::parseInsnDirective() {
8149 reportParseError(
"unexpected token, expected end of statement");
8155 getTargetStreamer().emitDirectiveInsn();
8163bool MipsAsmParser::parseRSectionDirective(StringRef Section) {
8166 reportParseError(
"unexpected token, expected end of statement");
8170 MCSection *ELFSection =
getContext().getELFSection(
8172 getParser().getStreamer().switchSection(ELFSection);
8181bool MipsAsmParser::parseSSectionDirective(StringRef Section,
unsigned Type) {
8184 reportParseError(
"unexpected token, expected end of statement");
8188 MCSection *ELFSection =
getContext().getELFSection(
8190 getParser().getStreamer().switchSection(ELFSection);
8209bool MipsAsmParser::parseDirectiveModule() {
8210 MCAsmParser &Parser = getParser();
8211 AsmLexer &Lexer = getLexer();
8214 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
8216 reportParseError(
".module directive must appear before any code");
8222 reportParseError(
"expected .module option identifier");
8226 if (Option ==
"oddspreg") {
8227 clearModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
8231 getTargetStreamer().updateABIInfo(*
this);
8236 getTargetStreamer().emitDirectiveModuleOddSPReg();
8240 reportParseError(
"unexpected token, expected end of statement");
8245 }
else if (Option ==
"nooddspreg") {
8247 return Error(L,
"'.module nooddspreg' requires the O32 ABI");
8250 setModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
8254 getTargetStreamer().updateABIInfo(*
this);
8259 getTargetStreamer().emitDirectiveModuleOddSPReg();
8263 reportParseError(
"unexpected token, expected end of statement");
8268 }
else if (Option ==
"fp") {
8269 return parseDirectiveModuleFP();
8270 }
else if (Option ==
"softfloat") {
8271 setModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
8275 getTargetStreamer().updateABIInfo(*
this);
8280 getTargetStreamer().emitDirectiveModuleSoftFloat();
8284 reportParseError(
"unexpected token, expected end of statement");
8289 }
else if (Option ==
"hardfloat") {
8290 clearModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
8294 getTargetStreamer().updateABIInfo(*
this);
8299 getTargetStreamer().emitDirectiveModuleHardFloat();
8303 reportParseError(
"unexpected token, expected end of statement");
8308 }
else if (Option ==
"mt") {
8309 setModuleFeatureBits(Mips::FeatureMT,
"mt");
8313 getTargetStreamer().updateABIInfo(*
this);
8318 getTargetStreamer().emitDirectiveModuleMT();
8322 reportParseError(
"unexpected token, expected end of statement");
8327 }
else if (Option ==
"crc") {
8328 setModuleFeatureBits(Mips::FeatureCRC,
"crc");
8332 getTargetStreamer().updateABIInfo(*
this);
8337 getTargetStreamer().emitDirectiveModuleCRC();
8341 reportParseError(
"unexpected token, expected end of statement");
8346 }
else if (Option ==
"nocrc") {
8347 clearModuleFeatureBits(Mips::FeatureCRC,
"crc");
8351 getTargetStreamer().updateABIInfo(*
this);
8356 getTargetStreamer().emitDirectiveModuleNoCRC();
8360 reportParseError(
"unexpected token, expected end of statement");
8365 }
else if (Option ==
"virt") {
8366 setModuleFeatureBits(Mips::FeatureVirt,
"virt");
8370 getTargetStreamer().updateABIInfo(*
this);
8375 getTargetStreamer().emitDirectiveModuleVirt();
8379 reportParseError(
"unexpected token, expected end of statement");
8384 }
else if (Option ==
"novirt") {
8385 clearModuleFeatureBits(Mips::FeatureVirt,
"virt");
8389 getTargetStreamer().updateABIInfo(*
this);
8394 getTargetStreamer().emitDirectiveModuleNoVirt();
8398 reportParseError(
"unexpected token, expected end of statement");
8403 }
else if (Option ==
"ginv") {
8404 setModuleFeatureBits(Mips::FeatureGINV,
"ginv");
8408 getTargetStreamer().updateABIInfo(*
this);
8413 getTargetStreamer().emitDirectiveModuleGINV();
8417 reportParseError(
"unexpected token, expected end of statement");
8422 }
else if (Option ==
"noginv") {
8423 clearModuleFeatureBits(Mips::FeatureGINV,
"ginv");
8427 getTargetStreamer().updateABIInfo(*
this);
8432 getTargetStreamer().emitDirectiveModuleNoGINV();
8436 reportParseError(
"unexpected token, expected end of statement");
8442 return Error(L,
"'" + Twine(Option) +
"' is not a valid .module option.");
8450bool MipsAsmParser::parseDirectiveModuleFP() {
8451 MCAsmParser &Parser = getParser();
8452 AsmLexer &Lexer = getLexer();
8455 reportParseError(
"unexpected token, expected equals sign '='");
8461 if (!parseFpABIValue(FpABI,
".module"))
8465 reportParseError(
"unexpected token, expected end of statement");
8471 getTargetStreamer().updateABIInfo(*
this);
8476 getTargetStreamer().emitDirectiveModuleFP();
8483 StringRef Directive) {
8484 MCAsmParser &Parser = getParser();
8485 AsmLexer &Lexer = getLexer();
8486 bool ModuleLevelOptions = Directive ==
".module";
8492 if (
Value !=
"xx") {
8493 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
8498 reportParseError(
"'" + Directive +
" fp=xx' requires the O32 ABI");
8502 FpABI = MipsABIFlagsSection::FpABIKind::XX;
8503 if (ModuleLevelOptions) {
8504 setModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8505 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8507 setFeatureBits(Mips::FeatureFPXX,
"fpxx");
8508 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8518 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
8524 reportParseError(
"'" + Directive +
" fp=32' requires the O32 ABI");
8528 FpABI = MipsABIFlagsSection::FpABIKind::S32;
8529 if (ModuleLevelOptions) {
8530 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8531 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8533 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
8534 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8537 FpABI = MipsABIFlagsSection::FpABIKind::S64;
8538 if (ModuleLevelOptions) {
8539 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8540 setModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8542 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
8543 setFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8553bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
8559 MCAsmParser &Parser = getParser();
8560 StringRef IDVal = DirectiveID.
getString();
8562 if (IDVal ==
".cpadd") {
8563 parseDirectiveCpAdd(DirectiveID.
getLoc());
8566 if (IDVal ==
".cpload") {
8567 parseDirectiveCpLoad(DirectiveID.
getLoc());
8570 if (IDVal ==
".cprestore") {
8571 parseDirectiveCpRestore(DirectiveID.
getLoc());
8574 if (IDVal ==
".cplocal") {
8575 parseDirectiveCpLocal(DirectiveID.
getLoc());
8578 if (IDVal ==
".ent") {
8582 reportParseError(
"expected identifier after .ent");
8596 reportParseError(
"unexpected token, expected end of statement");
8600 const MCExpr *DummyNumber;
8601 int64_t DummyNumberVal;
8605 reportParseError(
"expected number after comma");
8608 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
8609 reportParseError(
"expected an absolute expression after comma");
8616 reportParseError(
"unexpected token, expected end of statement");
8622 getTargetStreamer().emitDirectiveEnt(*Sym);
8624 IsCpRestoreSet =
false;
8628 if (IDVal ==
".end") {
8632 reportParseError(
"expected identifier after .end");
8637 reportParseError(
"unexpected token, expected end of statement");
8641 if (CurrentFn ==
nullptr) {
8642 reportParseError(
".end used without .ent");
8646 if ((SymbolName != CurrentFn->
getName())) {
8647 reportParseError(
".end symbol does not match .ent symbol");
8651 getTargetStreamer().emitDirectiveEnd(SymbolName);
8652 CurrentFn =
nullptr;
8653 IsCpRestoreSet =
false;
8657 if (IDVal ==
".frame") {
8660 ParseStatus Res = parseAnyRegister(TmpReg);
8662 reportParseError(
"expected stack register");
8666 MipsOperand &StackRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
8667 if (!StackRegOpnd.isGPRAsmReg()) {
8668 reportParseError(StackRegOpnd.getStartLoc(),
8669 "expected general purpose register");
8672 MCRegister StackReg = StackRegOpnd.getGPR32Reg();
8677 reportParseError(
"unexpected token, expected comma");
8682 const MCExpr *FrameSize;
8683 int64_t FrameSizeVal;
8686 reportParseError(
"expected frame size value");
8690 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
8691 reportParseError(
"frame size not an absolute expression");
8698 reportParseError(
"unexpected token, expected comma");
8704 Res = parseAnyRegister(TmpReg);
8706 reportParseError(
"expected return register");
8710 MipsOperand &ReturnRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
8711 if (!ReturnRegOpnd.isGPRAsmReg()) {
8712 reportParseError(ReturnRegOpnd.getStartLoc(),
8713 "expected general purpose register");
8719 reportParseError(
"unexpected token, expected end of statement");
8723 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
8724 ReturnRegOpnd.getGPR32Reg());
8725 IsCpRestoreSet =
false;
8729 if (IDVal ==
".set") {
8730 parseDirectiveSet();
8734 if (IDVal ==
".mask" || IDVal ==
".fmask") {
8745 const MCExpr *BitMask;
8749 reportParseError(
"expected bitmask value");
8753 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
8754 reportParseError(
"bitmask not an absolute expression");
8761 reportParseError(
"unexpected token, expected comma");
8766 const MCExpr *FrameOffset;
8767 int64_t FrameOffsetVal;
8770 reportParseError(
"expected frame offset value");
8774 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
8775 reportParseError(
"frame offset not an absolute expression");
8781 reportParseError(
"unexpected token, expected end of statement");
8785 if (IDVal ==
".mask")
8786 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
8788 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
8792 if (IDVal ==
".nan")
8793 return parseDirectiveNaN();
8795 if (IDVal ==
".gpword") {
8796 parseDirectiveGpWord();
8800 if (IDVal ==
".gpdword") {
8801 parseDirectiveGpDWord();
8805 if (IDVal ==
".dtprelword") {
8806 parseDirectiveDtpRelWord();
8810 if (IDVal ==
".dtpreldword") {
8811 parseDirectiveDtpRelDWord();
8815 if (IDVal ==
".tprelword") {
8816 parseDirectiveTpRelWord();
8820 if (IDVal ==
".tpreldword") {
8821 parseDirectiveTpRelDWord();
8825 if (IDVal ==
".option") {
8826 parseDirectiveOption();
8830 if (IDVal ==
".abicalls") {
8831 getTargetStreamer().emitDirectiveAbiCalls();
8834 "unexpected token, expected end of statement");
8839 if (IDVal ==
".cpsetup") {
8840 parseDirectiveCPSetup();
8843 if (IDVal ==
".cpreturn") {
8844 parseDirectiveCPReturn();
8847 if (IDVal ==
".module") {
8848 parseDirectiveModule();
8851 if (IDVal ==
".llvm_internal_mips_reallow_module_directive") {
8852 parseInternalDirectiveReallowModule();
8855 if (IDVal ==
".insn") {
8856 parseInsnDirective();
8859 if (IDVal ==
".rdata") {
8860 parseRSectionDirective(
".rodata");
8863 if (IDVal ==
".sbss") {
8867 if (IDVal ==
".sdata") {
8875bool MipsAsmParser::parseInternalDirectiveReallowModule() {
8878 reportParseError(
"unexpected token, expected end of statement");
8882 getTargetStreamer().reallowModuleDirective();
8896#define GET_REGISTER_MATCHER
8897#define GET_MATCHER_IMPLEMENTATION
8898#define GET_MNEMONIC_SPELL_CHECKER
8899#include "MipsGenAsmMatcher.inc"
8901bool MipsAsmParser::mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID) {
8903 const MatchEntry *Start, *End;
8904 switch (VariantID) {
8906 case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0);
break;
8909 auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
8910 return MnemonicRange.first != MnemonicRange.second;
static const TargetRegisterClass * getRegClass(const MachineInstr &MI, Register Reg)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
This file declares a class to represent arbitrary precision floating point values and provide a varie...
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
static Value * expandAbs(CallInst *Orig)
std::pair< Instruction::BinaryOps, Value * > OffsetOp
Find all possible pairs (BinOp, RHS) that BinOp V, RHS can be simplified.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static FeatureBitset getFeatures(MCSubtargetInfo &STI, StringRef CPU, StringRef TuneCPU, StringRef FS, ArrayRef< StringRef > ProcNames, ArrayRef< SubtargetSubTypeKV > ProcDesc, ArrayRef< SubtargetFeatureKV > ProcFeatures)
static unsigned countMCSymbolRefExpr(const MCExpr *Expr)
static std::string MipsMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, unsigned VariantID=0)
static uint64_t convertIntToDoubleImm(uint64_t ImmOp64)
static uint32_t covertDoubleImmToSingleImm(uint64_t ImmOp64)
static unsigned getRegisterForMxtrDSP(MCInst &Inst, bool IsMFDSP)
static bool hasShortDelaySlot(MCInst &Inst)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsAsmParser()
static bool needsExpandMemInst(MCInst &Inst, const MCInstrDesc &MCID)
cl::opt< bool > EmitJalrReloc
static bool isShiftedUIntAtAnyPosition(uint64_t x)
Can the value be represented by a unsigned N-bit value and a shift left?
static bool isEvaluated(const MCExpr *Expr)
static unsigned getRegisterForMxtrC0(MCInst &Inst, bool IsMFTC0)
static const MCSymbol * getSingleMCSymbol(const MCExpr *Expr)
static MCRegister nextReg(MCRegister Reg)
static unsigned getRegisterForMxtrFP(MCInst &Inst, bool IsMFTC1)
cl::opt< bool > NoZeroDivCheck
static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands, uint64_t ErrorInfo)
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
static PPCTargetMachine::PPCABI computeTargetABI(const Triple &TT, const TargetOptions &Options)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static 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
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,...