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)
527 : MCTargetAsmParser(sti, MII),
529 sti.getTargetTriple(),
539 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
542 AssemblerOptions.push_back(
543 std::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
546 AssemblerOptions.push_back(
547 std::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
549 getTargetStreamer().updateABIInfo(*
this);
551 if (!isABI_O32() && !useOddSPReg() != 0)
556 CurForbiddenSlotAttr =
false;
557 IsPicEnabled =
getContext().getObjectFileInfo()->isPositionIndependent();
559 IsCpRestoreSet =
false;
560 CpRestoreOffset = -1;
561 GPReg = ABI.GetGlobalPtr();
566 if (getSTI().
getCPU() ==
"mips64r6" && inMicroMipsMode())
569 if (!isABI_O32() && inMicroMipsMode())
574 bool hasEightFccRegisters()
const {
return hasMips4() || hasMips32(); }
576 bool isGP64bit()
const {
577 return getSTI().hasFeature(Mips::FeatureGP64Bit);
580 bool isFP64bit()
const {
581 return getSTI().hasFeature(Mips::FeatureFP64Bit);
584 bool isJalrRelocAvailable(
const MCExpr *JalExpr) {
593 return ABI.IsN32() || ABI.IsN64();
597 const MipsABIInfo &getABI()
const {
return ABI; }
598 bool isABI_N32()
const {
return ABI.IsN32(); }
599 bool isABI_N64()
const {
return ABI.IsN64(); }
600 bool isABI_O32()
const {
return ABI.IsO32(); }
601 bool isABI_FPXX()
const {
602 return getSTI().hasFeature(Mips::FeatureFPXX);
605 bool useOddSPReg()
const {
606 return !(getSTI().hasFeature(Mips::FeatureNoOddSPReg));
609 bool inMicroMipsMode()
const {
610 return getSTI().hasFeature(Mips::FeatureMicroMips);
613 bool hasMips1()
const {
614 return getSTI().hasFeature(Mips::FeatureMips1);
617 bool hasMips2()
const {
618 return getSTI().hasFeature(Mips::FeatureMips2);
621 bool hasMips3()
const {
622 return getSTI().hasFeature(Mips::FeatureMips3);
625 bool hasMips4()
const {
626 return getSTI().hasFeature(Mips::FeatureMips4);
629 bool hasMips5()
const {
630 return getSTI().hasFeature(Mips::FeatureMips5);
633 bool hasMips32()
const {
634 return getSTI().hasFeature(Mips::FeatureMips32);
637 bool hasMips64()
const {
638 return getSTI().hasFeature(Mips::FeatureMips64);
641 bool hasMips32r2()
const {
642 return getSTI().hasFeature(Mips::FeatureMips32r2);
645 bool hasMips64r2()
const {
646 return getSTI().hasFeature(Mips::FeatureMips64r2);
649 bool hasMips32r3()
const {
650 return (getSTI().hasFeature(Mips::FeatureMips32r3));
653 bool hasMips64r3()
const {
654 return (getSTI().hasFeature(Mips::FeatureMips64r3));
657 bool hasMips32r5()
const {
658 return (getSTI().hasFeature(Mips::FeatureMips32r5));
661 bool hasMips64r5()
const {
662 return (getSTI().hasFeature(Mips::FeatureMips64r5));
665 bool hasMips32r6()
const {
666 return getSTI().hasFeature(Mips::FeatureMips32r6);
669 bool hasMips64r6()
const {
670 return getSTI().hasFeature(Mips::FeatureMips64r6);
673 bool hasDSP()
const {
674 return getSTI().hasFeature(Mips::FeatureDSP);
677 bool hasDSPR2()
const {
678 return getSTI().hasFeature(Mips::FeatureDSPR2);
681 bool hasDSPR3()
const {
682 return getSTI().hasFeature(Mips::FeatureDSPR3);
685 bool hasMSA()
const {
686 return getSTI().hasFeature(Mips::FeatureMSA);
689 bool hasCnMips()
const {
690 return (getSTI().hasFeature(Mips::FeatureCnMips));
693 bool hasCnMipsP()
const {
694 return (getSTI().hasFeature(Mips::FeatureCnMipsP));
697 bool isR5900()
const {
return (getSTI().hasFeature(Mips::FeatureR5900)); }
703 bool inMips16Mode()
const {
704 return getSTI().hasFeature(Mips::FeatureMips16);
707 bool useTraps()
const {
708 return getSTI().hasFeature(Mips::FeatureUseTCCInDIV);
711 bool useSoftFloat()
const {
712 return getSTI().hasFeature(Mips::FeatureSoftFloat);
715 bool isSingleFloat()
const {
716 return getSTI().hasFeature(Mips::FeatureSingleFloat);
720 return getSTI().hasFeature(Mips::FeatureMT);
723 bool hasCRC()
const {
724 return getSTI().hasFeature(Mips::FeatureCRC);
727 bool hasVirt()
const {
728 return getSTI().hasFeature(Mips::FeatureVirt);
731 bool hasGINV()
const {
732 return getSTI().hasFeature(Mips::FeatureGINV);
735 bool hasForbiddenSlot(
const MCInstrDesc &MCID)
const {
739 bool SafeInForbiddenSlot(
const MCInstrDesc &MCID)
const {
743 void onEndOfFile()
override;
746 void warnIfRegIndexIsAT(MCRegister RegIndex, SMLoc Loc);
748 void warnIfNoMacro(SMLoc Loc);
750 bool isLittle()
const {
return IsLittleEndian; }
752 bool areEqualRegs(
const MCParsedAsmOperand &Op1,
753 const MCParsedAsmOperand &Op2)
const override;
768 RegKind_MSACtrl = 16,
773 RegKind_HWRegs = 256,
777 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
778 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
779 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
792 MipsOperand(KindTy K, MipsAsmParser &Parser) : Kind(
K), AsmParser(Parser) {}
794 ~MipsOperand()
override {
803 case k_RegisterIndex:
811 MipsAsmParser &AsmParser;
822 const MCRegisterInfo *RegInfo;
840 struct RegIdxOp RegIdx;
843 struct RegListOp RegList;
846 SMLoc StartLoc, EndLoc;
849 static std::unique_ptr<MipsOperand> CreateReg(
unsigned Index, StringRef Str,
851 const MCRegisterInfo *RegInfo,
853 MipsAsmParser &Parser) {
854 auto Op = std::make_unique<MipsOperand>(k_RegisterIndex, Parser);
856 Op->RegIdx.RegInfo = RegInfo;
857 Op->RegIdx.Kind = RegKind;
858 Op->RegIdx.Tok.Data = Str.data();
859 Op->RegIdx.Tok.Length = Str.size();
868 MCRegister getGPR32Reg()
const {
869 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
870 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
871 unsigned ClassID = Mips::GPR32RegClassID;
872 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
877 MCRegister getGPRMM16Reg()
const {
878 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
879 unsigned ClassID = Mips::GPR32RegClassID;
880 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
885 MCRegister getGPR64Reg()
const {
886 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
887 unsigned ClassID = Mips::GPR64RegClassID;
888 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
894 MCRegister getAFGR64Reg()
const {
895 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
896 if (RegIdx.Index % 2 != 0)
897 AsmParser.Warning(StartLoc,
"Float register should be even.");
898 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
899 .getRegister(RegIdx.Index / 2);
904 MCRegister getFGR64Reg()
const {
905 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
906 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
907 .getRegister(RegIdx.Index);
912 MCRegister getFGR32Reg()
const {
913 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
914 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
915 .getRegister(RegIdx.Index);
920 MCRegister getFCCReg()
const {
921 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) &&
"Invalid access!");
922 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
923 .getRegister(RegIdx.Index);
928 MCRegister getMSA128Reg()
const {
929 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) &&
"Invalid access!");
932 unsigned ClassID = Mips::MSA128BRegClassID;
933 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
938 MCRegister getMSACtrlReg()
const {
939 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) &&
"Invalid access!");
940 unsigned ClassID = Mips::MSACtrlRegClassID;
941 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
946 MCRegister getCOP0Reg()
const {
947 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) &&
"Invalid access!");
948 unsigned ClassID = Mips::COP0RegClassID;
949 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
954 MCRegister getCOP2Reg()
const {
955 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) &&
"Invalid access!");
956 unsigned ClassID = Mips::COP2RegClassID;
957 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
962 MCRegister getCOP3Reg()
const {
963 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) &&
"Invalid access!");
964 unsigned ClassID = Mips::COP3RegClassID;
965 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
970 MCRegister getACC64DSPReg()
const {
971 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
972 unsigned ClassID = Mips::ACC64DSPRegClassID;
973 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
978 MCRegister getHI32DSPReg()
const {
979 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
980 unsigned ClassID = Mips::HI32DSPRegClassID;
981 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
986 MCRegister getLO32DSPReg()
const {
987 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
988 unsigned ClassID = Mips::LO32DSPRegClassID;
989 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
994 MCRegister getCCRReg()
const {
995 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) &&
"Invalid access!");
996 unsigned ClassID = Mips::CCRRegClassID;
997 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1002 MCRegister getHWRegsReg()
const {
1003 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) &&
"Invalid access!");
1004 unsigned ClassID = Mips::HWRegsRegClassID;
1005 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1009 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const {
1019 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1026 void addGPR32ZeroAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1027 assert(
N == 1 &&
"Invalid number of operands!");
1031 void addGPR32NonZeroAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1032 assert(
N == 1 &&
"Invalid number of operands!");
1036 void addGPR32AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1037 assert(
N == 1 &&
"Invalid number of operands!");
1041 void addGPRMM16AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1042 assert(
N == 1 &&
"Invalid number of operands!");
1046 void addGPRMM16AsmRegZeroOperands(MCInst &Inst,
unsigned N)
const {
1047 assert(
N == 1 &&
"Invalid number of operands!");
1051 void addGPRMM16AsmRegMovePOperands(MCInst &Inst,
unsigned N)
const {
1052 assert(
N == 1 &&
"Invalid number of operands!");
1056 void addGPRMM16AsmRegMovePPairFirstOperands(MCInst &Inst,
unsigned N)
const {
1057 assert(
N == 1 &&
"Invalid number of operands!");
1061 void addGPRMM16AsmRegMovePPairSecondOperands(MCInst &Inst,
1063 assert(
N == 1 &&
"Invalid number of operands!");
1070 void addGPR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1071 assert(
N == 1 &&
"Invalid number of operands!");
1075 void addAFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1076 assert(
N == 1 &&
"Invalid number of operands!");
1080 void addStrictlyAFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1081 assert(
N == 1 &&
"Invalid number of operands!");
1085 void addStrictlyFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1086 assert(
N == 1 &&
"Invalid number of operands!");
1090 void addFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1091 assert(
N == 1 &&
"Invalid number of operands!");
1095 void addFGR32AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1096 assert(
N == 1 &&
"Invalid number of operands!");
1100 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1101 AsmParser.getParser().printError(
1102 StartLoc,
"-mno-odd-spreg prohibits the use of odd FPU "
1106 void addStrictlyFGR32AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1107 assert(
N == 1 &&
"Invalid number of operands!");
1110 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1111 AsmParser.Error(StartLoc,
"-mno-odd-spreg prohibits the use of odd FPU "
1115 void addFCCAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1116 assert(
N == 1 &&
"Invalid number of operands!");
1120 void addMSA128AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1121 assert(
N == 1 &&
"Invalid number of operands!");
1125 void addMSACtrlAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1126 assert(
N == 1 &&
"Invalid number of operands!");
1130 void addCOP0AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1131 assert(
N == 1 &&
"Invalid number of operands!");
1135 void addCOP2AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1136 assert(
N == 1 &&
"Invalid number of operands!");
1140 void addCOP3AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1141 assert(
N == 1 &&
"Invalid number of operands!");
1145 void addACC64DSPAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1146 assert(
N == 1 &&
"Invalid number of operands!");
1150 void addHI32DSPAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1151 assert(
N == 1 &&
"Invalid number of operands!");
1155 void addLO32DSPAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1156 assert(
N == 1 &&
"Invalid number of operands!");
1160 void addCCRAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1161 assert(
N == 1 &&
"Invalid number of operands!");
1165 void addHWRegsAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1166 assert(
N == 1 &&
"Invalid number of operands!");
1170 template <
unsigned Bits,
int Offset = 0,
int AdjustOffset = 0>
1171 void addConstantUImmOperands(MCInst &Inst,
unsigned N)
const {
1172 assert(
N == 1 &&
"Invalid number of operands!");
1173 uint64_t
Imm = getConstantImm() -
Offset;
1176 Imm += AdjustOffset;
1180 template <
unsigned Bits>
1181 void addSImmOperands(MCInst &Inst,
unsigned N)
const {
1182 if (isImm() && !isConstantImm()) {
1186 addConstantSImmOperands<Bits, 0, 0>(Inst,
N);
1189 template <
unsigned Bits>
1190 void addUImmOperands(MCInst &Inst,
unsigned N)
const {
1191 if (isImm() && !isConstantImm()) {
1195 addConstantUImmOperands<Bits, 0, 0>(Inst,
N);
1198 template <
unsigned Bits,
int Offset = 0,
int AdjustOffset = 0>
1199 void addConstantSImmOperands(MCInst &Inst,
unsigned N)
const {
1200 assert(
N == 1 &&
"Invalid number of operands!");
1201 int64_t
Imm = getConstantImm() -
Offset;
1204 Imm += AdjustOffset;
1208 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1209 assert(
N == 1 &&
"Invalid number of operands!");
1210 const MCExpr *Expr =
getImm();
1211 addExpr(Inst, Expr);
1214 void addMemOperands(MCInst &Inst,
unsigned N)
const {
1215 assert(
N == 2 &&
"Invalid number of operands!");
1218 ? getMemBase()->getGPR64Reg()
1219 : getMemBase()->getGPR32Reg()));
1221 const MCExpr *Expr = getMemOff();
1222 addExpr(Inst, Expr);
1225 void addMicroMipsMemOperands(MCInst &Inst,
unsigned N)
const {
1226 assert(
N == 2 &&
"Invalid number of operands!");
1230 const MCExpr *Expr = getMemOff();
1231 addExpr(Inst, Expr);
1234 void addRegListOperands(MCInst &Inst,
unsigned N)
const {
1235 assert(
N == 1 &&
"Invalid number of operands!");
1237 for (
auto RegNo : getRegList())
1241 bool isReg()
const override {
1244 return isGPRAsmReg() && RegIdx.Index == 0;
1247 bool isRegIdx()
const {
return Kind == k_RegisterIndex; }
1248 bool isImm()
const override {
return Kind == k_Immediate; }
1250 bool isConstantImm()
const {
1252 return isImm() &&
getImm()->evaluateAsAbsolute(Res);
1255 bool isConstantImmz()
const {
1256 return isConstantImm() && getConstantImm() == 0;
1259 template <
unsigned Bits,
int Offset = 0>
bool isConstantUImm()
const {
1263 template <
unsigned Bits>
bool isSImm()
const {
1267 if (
getImm()->evaluateAsAbsolute(Res))
1273 template <
unsigned Bits>
bool isUImm()
const {
1277 if (
getImm()->evaluateAsAbsolute(Res))
1283 template <
unsigned Bits>
bool isAnyImm()
const {
1284 return isConstantImm() ? (
isInt<Bits>(getConstantImm()) ||
1289 template <
unsigned Bits,
int Offset = 0>
bool isConstantSImm()
const {
1293 template <
unsigned Bottom,
unsigned Top>
bool isConstantUImmRange()
const {
1294 return isConstantImm() && getConstantImm() >= Bottom &&
1295 getConstantImm() <= Top;
1298 bool isToken()
const override {
1301 return Kind == k_Token;
1304 bool isMem()
const override {
return Kind == k_Memory; }
1306 bool isConstantMemOff()
const {
1311 template <
unsigned Bits,
unsigned ShiftAmount = 0>
1312 bool isMemWithSimmOffset()
const {
1315 if (!getMemBase()->isGPRAsmReg())
1318 (isConstantMemOff() &&
1322 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res,
nullptr);
1326 bool isMemWithPtrSizeOffset()
const {
1329 if (!getMemBase()->isGPRAsmReg())
1331 const unsigned PtrBits = AsmParser.getABI().ArePtrs64bit() ? 64 : 32;
1333 (isConstantMemOff() &&
isIntN(PtrBits, getConstantMemOff())))
1336 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res,
nullptr);
1340 bool isMemWithGRPMM16Base()
const {
1341 return isMem() && getMemBase()->isMM16AsmReg();
1344 template <
unsigned Bits>
bool isMemWithUimmOffsetSP()
const {
1346 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1349 template <
unsigned Bits>
bool isMemWithUimmWordAlignedOffsetSP()
const {
1351 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1352 && (getMemBase()->getGPR32Reg() == Mips::SP);
1355 template <
unsigned Bits>
bool isMemWithSimmWordAlignedOffsetGP()
const {
1357 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1358 && (getMemBase()->getGPR32Reg() == Mips::GP);
1361 template <
unsigned Bits,
unsigned ShiftLeftAmount>
1362 bool isScaledUImm()
const {
1363 return isConstantImm() &&
1367 template <
unsigned Bits,
unsigned ShiftLeftAmount>
1368 bool isScaledSImm()
const {
1369 if (isConstantImm() &&
1374 if (Kind != k_Immediate)
1377 bool Success =
getImm()->evaluateAsRelocatable(Res,
nullptr);
1381 bool isRegList16()
const {
1385 int Size = RegList.List->size();
1389 MCRegister R0 = RegList.List->front();
1390 MCRegister R1 = RegList.List->back();
1391 if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1392 (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1395 MCRegister PrevReg = RegList.List->front();
1396 for (
int i = 1; i <
Size - 1; i++) {
1397 MCRegister
Reg = (*(RegList.List))[i];
1398 if (
Reg != PrevReg + 1)
1406 bool isInvNum()
const {
return Kind == k_Immediate; }
1408 bool isLSAImm()
const {
1409 if (!isConstantImm())
1411 int64_t Val = getConstantImm();
1412 return 1 <= Val && Val <= 4;
1415 bool isRegList()
const {
return Kind == k_RegList; }
1418 assert(Kind == k_Token &&
"Invalid access!");
1419 return StringRef(Tok.Data, Tok.Length);
1422 MCRegister
getReg()
const override {
1425 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1426 RegIdx.Kind & RegKind_GPR)
1427 return getGPR32Reg();
1433 const MCExpr *
getImm()
const {
1434 assert((Kind == k_Immediate) &&
"Invalid access!");
1438 int64_t getConstantImm()
const {
1439 const MCExpr *Val =
getImm();
1441 (void)Val->evaluateAsAbsolute(
Value);
1445 MipsOperand *getMemBase()
const {
1446 assert((Kind == k_Memory) &&
"Invalid access!");
1450 const MCExpr *getMemOff()
const {
1451 assert((Kind == k_Memory) &&
"Invalid access!");
1455 int64_t getConstantMemOff()
const {
1456 return static_cast<const MCConstantExpr *
>(getMemOff())->
getValue();
1459 const SmallVectorImpl<MCRegister> &getRegList()
const {
1460 assert((Kind == k_RegList) &&
"Invalid access!");
1461 return *(RegList.List);
1464 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1465 MipsAsmParser &Parser) {
1466 auto Op = std::make_unique<MipsOperand>(k_Token, Parser);
1467 Op->Tok.Data = Str.data();
1468 Op->Tok.Length = Str.size();
1476 static std::unique_ptr<MipsOperand>
1477 createNumericReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1478 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1479 LLVM_DEBUG(
dbgs() <<
"createNumericReg(" << Index <<
", ...)\n");
1480 return CreateReg(Index, Str, RegKind_Numeric, RegInfo, S,
E, Parser);
1485 static std::unique_ptr<MipsOperand>
1486 createGPRReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1487 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1488 return CreateReg(Index, Str, RegKind_GPR, RegInfo, S,
E, Parser);
1493 static std::unique_ptr<MipsOperand>
1494 createFGRReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1495 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1496 return CreateReg(Index, Str, RegKind_FGR, RegInfo, S,
E, Parser);
1501 static std::unique_ptr<MipsOperand>
1502 createHWRegsReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1503 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1504 return CreateReg(Index, Str, RegKind_HWRegs, RegInfo, S,
E, Parser);
1509 static std::unique_ptr<MipsOperand>
1510 createFCCReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1511 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1512 return CreateReg(Index, Str, RegKind_FCC, RegInfo, S,
E, Parser);
1517 static std::unique_ptr<MipsOperand>
1518 createACCReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1519 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1520 return CreateReg(Index, Str, RegKind_ACC, RegInfo, S,
E, Parser);
1525 static std::unique_ptr<MipsOperand>
1526 createMSA128Reg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1527 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1528 return CreateReg(Index, Str, RegKind_MSA128, RegInfo, S,
E, Parser);
1533 static std::unique_ptr<MipsOperand>
1534 createMSACtrlReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1535 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1536 return CreateReg(Index, Str, RegKind_MSACtrl, RegInfo, S,
E, Parser);
1539 static std::unique_ptr<MipsOperand>
1540 CreateImm(
const MCExpr *Val, SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1541 auto Op = std::make_unique<MipsOperand>(k_Immediate, Parser);
1548 static std::unique_ptr<MipsOperand>
1549 CreateMem(std::unique_ptr<MipsOperand>
Base,
const MCExpr *Off, SMLoc S,
1550 SMLoc
E, MipsAsmParser &Parser) {
1551 auto Op = std::make_unique<MipsOperand>(k_Memory, Parser);
1552 Op->Mem.Base =
Base.release();
1559 static std::unique_ptr<MipsOperand>
1560 CreateRegList(SmallVectorImpl<MCRegister> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1561 MipsAsmParser &Parser) {
1562 assert(!Regs.
empty() &&
"Empty list not allowed");
1564 auto Op = std::make_unique<MipsOperand>(k_RegList, Parser);
1567 Op->StartLoc = StartLoc;
1568 Op->EndLoc = EndLoc;
1572 bool isGPRZeroAsmReg()
const {
1573 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
1576 bool isGPRNonZeroAsmReg()
const {
1577 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index > 0 &&
1581 bool isGPRAsmReg()
const {
1582 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1585 bool isMM16AsmReg()
const {
1586 if (!(isRegIdx() && RegIdx.Kind))
1588 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1589 || RegIdx.Index == 16 || RegIdx.Index == 17);
1592 bool isMM16AsmRegZero()
const {
1593 if (!(isRegIdx() && RegIdx.Kind))
1595 return (RegIdx.Index == 0 ||
1596 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1597 RegIdx.Index == 17);
1600 bool isMM16AsmRegMoveP()
const {
1601 if (!(isRegIdx() && RegIdx.Kind))
1603 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1604 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1607 bool isMM16AsmRegMovePPairFirst()
const {
1608 if (!(isRegIdx() && RegIdx.Kind))
1610 return RegIdx.Index >= 4 && RegIdx.Index <= 6;
1613 bool isMM16AsmRegMovePPairSecond()
const {
1614 if (!(isRegIdx() && RegIdx.Kind))
1616 return (RegIdx.Index == 21 || RegIdx.Index == 22 ||
1617 (RegIdx.Index >= 5 && RegIdx.Index <= 7));
1620 bool isFGRAsmReg()
const {
1622 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1625 bool isStrictlyFGRAsmReg()
const {
1627 return isRegIdx() && RegIdx.Kind == RegKind_FGR && RegIdx.Index <= 31;
1630 bool isHWRegsAsmReg()
const {
1631 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1634 bool isCCRAsmReg()
const {
1635 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1638 bool isFCCAsmReg()
const {
1639 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1641 return RegIdx.Index <= 7;
1644 bool isACCAsmReg()
const {
1645 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1648 bool isCOP0AsmReg()
const {
1649 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1652 bool isCOP2AsmReg()
const {
1653 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1656 bool isCOP3AsmReg()
const {
1657 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1660 bool isMSA128AsmReg()
const {
1661 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1664 bool isMSACtrlAsmReg()
const {
1665 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1669 SMLoc getStartLoc()
const override {
return StartLoc; }
1671 SMLoc getEndLoc()
const override {
return EndLoc; }
1673 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1682 Mem.Base->print(OS, MAI);
1687 case k_RegisterIndex:
1688 OS <<
"RegIdx<" << RegIdx.Index <<
":" << RegIdx.Kind <<
", "
1689 << StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) <<
">";
1696 for (
auto Reg : (*RegList.List))
1697 OS <<
Reg.
id() <<
" ";
1703 bool isValidForTie(
const MipsOperand &
Other)
const {
1704 if (Kind !=
Other.Kind)
1711 case k_RegisterIndex: {
1712 StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length);
1713 StringRef OtherToken(
Other.RegIdx.Tok.Data,
Other.RegIdx.Tok.Length);
1714 return Token == OtherToken;
1730 case Mips::JRC16_MM:
1732 case Mips::JALRS_MM:
1733 case Mips::JALRS16_MM:
1734 case Mips::BGEZALS_MM:
1735 case Mips::BLTZALS_MM:
1746 return &SRExpr->getSymbol();
1805 unsigned NumOp =
MCID.getNumOperands();
1806 if (NumOp != 3 && NumOp != 4)
1836bool MipsAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
1839 MipsTargetStreamer &TOut = getTargetStreamer();
1840 const unsigned Opcode = Inst.
getOpcode();
1841 const MCInstrDesc &MCID = MII.get(Opcode);
1842 bool ExpandedJalSym =
false;
1856 assert(hasCnMips() &&
"instruction only valid for octeon cpus");
1867 if (!
isIntN(inMicroMipsMode() ? 17 : 18,
Offset.getImm()))
1868 return Error(IDLoc,
"branch target out of range");
1871 return Error(IDLoc,
"branch to misaligned address");
1885 case Mips::BGEZAL_MM:
1886 case Mips::BLTZAL_MM:
1889 case Mips::BC1EQZC_MMR6:
1890 case Mips::BC1NEZC_MMR6:
1891 case Mips::BC2EQZC_MMR6:
1892 case Mips::BC2NEZC_MMR6:
1897 if (!
isIntN(inMicroMipsMode() ? 17 : 18,
Offset.getImm()))
1898 return Error(IDLoc,
"branch target out of range");
1901 return Error(IDLoc,
"branch to misaligned address");
1903 case Mips::BGEC:
case Mips::BGEC_MMR6:
1904 case Mips::BLTC:
case Mips::BLTC_MMR6:
1905 case Mips::BGEUC:
case Mips::BGEUC_MMR6:
1906 case Mips::BLTUC:
case Mips::BLTUC_MMR6:
1907 case Mips::BEQC:
case Mips::BEQC_MMR6:
1908 case Mips::BNEC:
case Mips::BNEC_MMR6:
1914 return Error(IDLoc,
"branch target out of range");
1916 return Error(IDLoc,
"branch to misaligned address");
1918 case Mips::BLEZC:
case Mips::BLEZC_MMR6:
1919 case Mips::BGEZC:
case Mips::BGEZC_MMR6:
1920 case Mips::BGTZC:
case Mips::BGTZC_MMR6:
1921 case Mips::BLTZC:
case Mips::BLTZC_MMR6:
1927 return Error(IDLoc,
"branch target out of range");
1929 return Error(IDLoc,
"branch to misaligned address");
1931 case Mips::BEQZC:
case Mips::BEQZC_MMR6:
1932 case Mips::BNEZC:
case Mips::BNEZC_MMR6:
1938 return Error(IDLoc,
"branch target out of range");
1940 return Error(IDLoc,
"branch to misaligned address");
1942 case Mips::BEQZ16_MM:
1943 case Mips::BEQZC16_MMR6:
1944 case Mips::BNEZ16_MM:
1945 case Mips::BNEZC16_MMR6:
1951 return Error(IDLoc,
"branch target out of range");
1953 return Error(IDLoc,
"branch to misaligned address");
1960 if (hasMips32r6() && Opcode == Mips::SSNOP) {
1961 std::string
ISA = hasMips64r6() ?
"MIPS64r6" :
"MIPS32r6";
1962 Warning(IDLoc,
"ssnop is deprecated for " + ISA +
" and is equivalent to a "
1982 return Error(IDLoc,
"expected immediate operand kind");
1984 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1985 Opcode == Mips::BBIT1 ? 63 : 31))
1986 return Error(IDLoc,
"immediate operand value out of range");
1988 Inst.
setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1999 return Error(IDLoc,
"expected immediate operand kind");
2002 return Error(IDLoc,
"immediate operand value out of range");
2014 unsigned FirstOp = 1;
2015 unsigned SecondOp = 2;
2019 case Mips::SDivIMacro:
2020 case Mips::UDivIMacro:
2021 case Mips::DSDivIMacro:
2022 case Mips::DUDivIMacro:
2026 Warning(IDLoc,
"dividing zero by zero");
2028 Warning(IDLoc,
"division by zero");
2040 case Mips::SDivMacro:
2041 case Mips::DSDivMacro:
2042 case Mips::UDivMacro:
2043 case Mips::DUDivMacro:
2048 case Mips::DIVU_MMR6:
2049 case Mips::DIV_MMR6:
2054 Warning(IDLoc,
"dividing zero by zero");
2056 Warning(IDLoc,
"division by zero");
2062 if ((Opcode == Mips::J || Opcode == Mips::J_MM) && inPicMode()) {
2064 BInst.
setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
2073 if ((Opcode == Mips::JAL || Opcode == Mips::JAL_MM) && inPicMode()) {
2074 warnIfNoMacro(IDLoc);
2077 return Error(IDLoc,
"unsupported constant in relocation");
2085 return Error(IDLoc,
"jal doesn't support multiple symbols in PIC mode");
2091 if (expandLoadAddress(Mips::T9, MCRegister(), Inst.
getOperand(0),
2092 !isGP64bit(), IDLoc, Out, STI))
2096 if (inMicroMipsMode())
2097 JalrInst.
setOpcode(IsCpRestoreSet ? Mips::JALRS_MM : Mips::JALR_MM);
2103 if (isJalrRelocAvailable(JalExpr)) {
2109 const MCExpr *RelocJalrExpr =
2113 *TmpExpr, inMicroMipsMode() ?
"R_MICROMIPS_JALR" :
"R_MIPS_JALR",
2119 ExpandedJalSym =
true;
2128 expandMem9Inst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2131 expandMem16Inst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2134 return getParser().hasPendingError();
2138 if (inMicroMipsMode()) {
2139 if (MCID.
mayLoad() && Opcode != Mips::LWP_MM) {
2142 const MCOperandInfo &OpInfo = MCID.
operands()[i];
2147 int MemOffset =
Op.getImm();
2150 if (
isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
2153 (
BaseReg.getReg() == Mips::GP ||
2154 BaseReg.getReg() == Mips::GP_64)) {
2156 TOut.
emitRRI(Mips::LWGP_MM, DstReg.
getReg(), Mips::GP, MemOffset,
2173 case Mips::ADDIUSP_MM:
2176 return Error(IDLoc,
"expected immediate operand kind");
2178 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
2180 return Error(IDLoc,
"immediate operand value out of range");
2182 case Mips::SLL16_MM:
2183 case Mips::SRL16_MM:
2186 return Error(IDLoc,
"expected immediate operand kind");
2188 if (Imm < 1 || Imm > 8)
2189 return Error(IDLoc,
"immediate operand value out of range");
2194 return Error(IDLoc,
"expected immediate operand kind");
2196 if (Imm < -1 || Imm > 126)
2197 return Error(IDLoc,
"immediate operand value out of range");
2199 case Mips::ADDIUR2_MM:
2202 return Error(IDLoc,
"expected immediate operand kind");
2204 if (!(Imm == 1 || Imm == -1 ||
2205 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
2206 return Error(IDLoc,
"immediate operand value out of range");
2208 case Mips::ANDI16_MM:
2211 return Error(IDLoc,
"expected immediate operand kind");
2213 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
2214 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
2215 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
2216 return Error(IDLoc,
"immediate operand value out of range");
2218 case Mips::LBU16_MM:
2221 return Error(IDLoc,
"expected immediate operand kind");
2223 if (Imm < -1 || Imm > 14)
2224 return Error(IDLoc,
"immediate operand value out of range");
2227 case Mips::SB16_MMR6:
2230 return Error(IDLoc,
"expected immediate operand kind");
2232 if (Imm < 0 || Imm > 15)
2233 return Error(IDLoc,
"immediate operand value out of range");
2235 case Mips::LHU16_MM:
2237 case Mips::SH16_MMR6:
2240 return Error(IDLoc,
"expected immediate operand kind");
2242 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
2243 return Error(IDLoc,
"immediate operand value out of range");
2247 case Mips::SW16_MMR6:
2250 return Error(IDLoc,
"expected immediate operand kind");
2252 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
2253 return Error(IDLoc,
"immediate operand value out of range");
2255 case Mips::ADDIUPC_MM:
2258 return Error(IDLoc,
"expected immediate operand kind");
2261 return Error(IDLoc,
"immediate operand value out of range");
2266 return Error(IDLoc,
"invalid operand for instruction");
2268 case Mips::MOVEP_MM:
2269 case Mips::MOVEP_MMR6: {
2272 bool RegPair = ((R0 == Mips::A1 && R1 == Mips::A2) ||
2273 (R0 == Mips::A1 && R1 == Mips::A3) ||
2274 (R0 == Mips::A2 && R1 == Mips::A3) ||
2275 (R0 == Mips::A0 && R1 == Mips::S5) ||
2276 (R0 == Mips::A0 && R1 == Mips::S6) ||
2277 (R0 == Mips::A0 && R1 == Mips::A1) ||
2278 (R0 == Mips::A0 && R1 == Mips::A2) ||
2279 (R0 == Mips::A0 && R1 == Mips::A3));
2281 return Error(IDLoc,
"invalid operand for instruction");
2287 bool FillDelaySlot =
2292 bool PrevForbiddenSlotAttr = CurForbiddenSlotAttr;
2295 bool SetReorderAfterNop =
false;
2300 if (PrevForbiddenSlotAttr && !SafeInForbiddenSlot(MCID)) {
2310 if (AssemblerOptions.
back()->isReorder() && !FillDelaySlot) {
2311 SetReorderAfterNop =
true;
2320 CurForbiddenSlotAttr =
2321 hasForbiddenSlot(MCID) && AssemblerOptions.
back()->isReorder();
2323 if (FillDelaySlot || CurForbiddenSlotAttr)
2326 MacroExpanderResultTy ExpandResult =
2327 tryExpandInstruction(Inst, IDLoc, Out, STI);
2328 switch (ExpandResult) {
2344 if (PrevForbiddenSlotAttr && !SetReorderAfterNop && !FillDelaySlot &&
2345 AssemblerOptions.
back()->isReorder()) {
2351 if (inMicroMipsMode()) {
2366 if (FillDelaySlot) {
2371 if ((Opcode == Mips::JalOneReg || Opcode == Mips::JalTwoReg ||
2373 isPicAndNotNxxAbi()) {
2374 if (IsCpRestoreSet) {
2378 if (!AssemblerOptions.
back()->isReorder())
2385 Warning(IDLoc,
"no .cprestore used in PIC mode");
2391void MipsAsmParser::onEndOfFile() {
2392 MipsTargetStreamer &TOut = getTargetStreamer();
2393 SMLoc IDLoc = SMLoc();
2395 if (CurForbiddenSlotAttr) {
2397 if (AssemblerOptions.
back()->isReorder())
2402MipsAsmParser::MacroExpanderResultTy
2403MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2404 const MCSubtargetInfo *STI) {
2407 return MER_NotAMacro;
2408 case Mips::LoadImm32:
2409 return expandLoadImm(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2410 case Mips::LoadImm64:
2411 return expandLoadImm(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2412 case Mips::LoadAddrImm32:
2413 case Mips::LoadAddrImm64:
2416 "expected immediate operand kind");
2418 return expandLoadAddress(
2420 Inst.
getOpcode() == Mips::LoadAddrImm32, IDLoc, Out, STI)
2423 case Mips::LoadAddrReg32:
2424 case Mips::LoadAddrReg64:
2428 "expected immediate operand kind");
2432 Inst.
getOpcode() == Mips::LoadAddrReg32, IDLoc,
2436 case Mips::B_MM_Pseudo:
2437 case Mips::B_MMR6_Pseudo:
2438 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2442 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2444 case Mips::JalOneReg:
2445 case Mips::JalTwoReg:
2446 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2449 case Mips::BEQLImmMacro:
2450 case Mips::BNELImmMacro:
2451 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2468 case Mips::BLTImmMacro:
2469 case Mips::BLEImmMacro:
2470 case Mips::BGEImmMacro:
2471 case Mips::BGTImmMacro:
2472 case Mips::BLTUImmMacro:
2473 case Mips::BLEUImmMacro:
2474 case Mips::BGEUImmMacro:
2475 case Mips::BGTUImmMacro:
2476 case Mips::BLTLImmMacro:
2477 case Mips::BLELImmMacro:
2478 case Mips::BGELImmMacro:
2479 case Mips::BGTLImmMacro:
2480 case Mips::BLTULImmMacro:
2481 case Mips::BLEULImmMacro:
2482 case Mips::BGEULImmMacro:
2483 case Mips::BGTULImmMacro:
2484 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2485 case Mips::SDivMacro:
2486 case Mips::SDivIMacro:
2487 case Mips::SRemMacro:
2488 case Mips::SRemIMacro:
2489 return expandDivRem(Inst, IDLoc, Out, STI,
false,
true) ? MER_Fail
2491 case Mips::DSDivMacro:
2492 case Mips::DSDivIMacro:
2493 case Mips::DSRemMacro:
2494 case Mips::DSRemIMacro:
2495 return expandDivRem(Inst, IDLoc, Out, STI,
true,
true) ? MER_Fail
2497 case Mips::UDivMacro:
2498 case Mips::UDivIMacro:
2499 case Mips::URemMacro:
2500 case Mips::URemIMacro:
2501 return expandDivRem(Inst, IDLoc, Out, STI,
false,
false) ? MER_Fail
2503 case Mips::DUDivMacro:
2504 case Mips::DUDivIMacro:
2505 case Mips::DURemMacro:
2506 case Mips::DURemIMacro:
2507 return expandDivRem(Inst, IDLoc, Out, STI,
true,
false) ? MER_Fail
2509 case Mips::PseudoTRUNC_W_S:
2510 return expandTrunc(Inst,
false,
false, IDLoc, Out, STI) ? MER_Fail
2512 case Mips::PseudoTRUNC_W_D32:
2513 return expandTrunc(Inst,
true,
false, IDLoc, Out, STI) ? MER_Fail
2515 case Mips::PseudoTRUNC_W_D:
2516 return expandTrunc(Inst,
true,
true, IDLoc, Out, STI) ? MER_Fail
2519 case Mips::LoadImmSingleGPR:
2520 return expandLoadSingleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2522 case Mips::LoadImmSingleFGR:
2523 return expandLoadSingleImmToFPR(Inst, IDLoc, Out, STI) ? MER_Fail
2525 case Mips::LoadImmDoubleGPR:
2526 return expandLoadDoubleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2528 case Mips::LoadImmDoubleFGR:
2529 return expandLoadDoubleImmToFPR(Inst,
true, IDLoc, Out, STI) ? MER_Fail
2531 case Mips::LoadImmDoubleFGR_32:
2532 return expandLoadDoubleImmToFPR(Inst,
false, IDLoc, Out, STI) ? MER_Fail
2536 return expandUlh(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2538 return expandUlh(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2540 return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2543 return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2545 case Mips::NORImm64:
2546 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2549 return expandSge(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2552 case Mips::SGEImm64:
2553 case Mips::SGEUImm64:
2554 return expandSgeImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2557 case Mips::SGTImm64:
2558 case Mips::SGTUImm64:
2559 return expandSgtImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2562 return expandSle(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2565 case Mips::SLEImm64:
2566 case Mips::SLEUImm64:
2567 return expandSleImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2568 case Mips::SLTImm64:
2571 return MER_NotAMacro;
2573 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2574 case Mips::SLTUImm64:
2577 return MER_NotAMacro;
2579 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2580 case Mips::ADDi:
case Mips::ADDi_MM:
2581 case Mips::ADDiu:
case Mips::ADDiu_MM:
2582 case Mips::SLTi:
case Mips::SLTi_MM:
2583 case Mips::SLTiu:
case Mips::SLTiu_MM:
2588 return MER_NotAMacro;
2589 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2592 return MER_NotAMacro;
2593 case Mips::ANDi:
case Mips::ANDi_MM:
case Mips::ANDi64:
2594 case Mips::ORi:
case Mips::ORi_MM:
case Mips::ORi64:
2595 case Mips::XORi:
case Mips::XORi_MM:
case Mips::XORi64:
2600 return MER_NotAMacro;
2601 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2604 return MER_NotAMacro;
2607 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2610 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2613 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2616 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2617 case Mips::ABSMacro:
2618 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2619 case Mips::MULImmMacro:
2620 case Mips::DMULImmMacro:
2621 return expandMulImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2622 case Mips::MULOMacro:
2623 case Mips::DMULOMacro:
2624 return expandMulO(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2625 case Mips::MULOUMacro:
2626 case Mips::DMULOUMacro:
2627 return expandMulOU(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2628 case Mips::DMULMacro:
2629 return expandDMULMacro(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2632 return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2637 return expandStoreDM1Macro(Inst, IDLoc, Out, STI)
2640 case Mips::SEQMacro:
2641 return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2642 case Mips::SEQIMacro:
2643 return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2644 case Mips::SNEMacro:
2645 return expandSne(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2646 case Mips::SNEIMacro:
2647 return expandSneI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2648 case Mips::MFTC0:
case Mips::MTTC0:
2649 case Mips::MFTGPR:
case Mips::MTTGPR:
2650 case Mips::MFTLO:
case Mips::MTTLO:
2651 case Mips::MFTHI:
case Mips::MTTHI:
2652 case Mips::MFTACX:
case Mips::MTTACX:
2653 case Mips::MFTDSP:
case Mips::MTTDSP:
2654 case Mips::MFTC1:
case Mips::MTTC1:
2655 case Mips::MFTHC1:
case Mips::MTTHC1:
2656 case Mips::CFTC1:
case Mips::CTTC1:
2657 return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2659 case Mips::SaadAddr:
2660 return expandSaaAddr(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2664bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2666 const MCSubtargetInfo *STI) {
2667 MipsTargetStreamer &TOut = getTargetStreamer();
2672 const MCOperand FirstRegOp = Inst.
getOperand(0);
2673 const unsigned Opcode = Inst.
getOpcode();
2675 if (Opcode == Mips::JalOneReg) {
2677 if (IsCpRestoreSet && inMicroMipsMode()) {
2680 }
else if (inMicroMipsMode()) {
2681 JalrInst.
setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2688 }
else if (Opcode == Mips::JalTwoReg) {
2690 if (IsCpRestoreSet && inMicroMipsMode())
2693 JalrInst.
setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2695 const MCOperand SecondRegOp = Inst.
getOperand(1);
2702 const MCInstrDesc &MCID = MII.get(JalrInst.
getOpcode());
2725bool MipsAsmParser::loadImmediate(int64_t ImmValue, MCRegister DstReg,
2726 MCRegister SrcReg,
bool Is32BitImm,
2727 bool IsAddress, SMLoc IDLoc, MCStreamer &Out,
2728 const MCSubtargetInfo *STI) {
2729 MipsTargetStreamer &TOut = getTargetStreamer();
2731 if (!Is32BitImm && !isGP64bit()) {
2732 Error(IDLoc,
"instruction requires a 64-bit architecture");
2743 Error(IDLoc,
"instruction requires a 32-bit immediate");
2748 MCRegister ZeroReg = IsAddress ?
ABI.GetNullPtr() :
ABI.GetZeroReg();
2749 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2751 bool UseSrcReg =
false;
2755 MCRegister TmpReg = DstReg;
2757 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2760 MCRegister ATReg = getATReg(IDLoc);
2773 if (IsAddress && !Is32BitImm) {
2774 TOut.
emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2778 TOut.
emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2783 MCRegister TmpReg = DstReg;
2784 if (SrcReg == DstReg) {
2785 TmpReg = getATReg(IDLoc);
2790 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2792 TOut.
emitRRR(
ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2797 warnIfNoMacro(IDLoc);
2799 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2800 uint16_t Bits15To0 = ImmValue & 0xffff;
2801 if (!Is32BitImm && !
isInt<32>(ImmValue)) {
2804 if (ImmValue == 0xffffffff) {
2805 TOut.
emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2806 TOut.
emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2808 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2814 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2815 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2817 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2819 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2823 TOut.
emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2825 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2827 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2833 Error(IDLoc,
"instruction requires a 32-bit immediate");
2840 assert(
BitWidth >= 17 &&
"ImmValue must be at least 17-bit wide");
2844 unsigned ShiftAmount =
BitWidth - 16;
2845 uint16_t
Bits = (ImmValue >> ShiftAmount) & 0xffff;
2846 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2847 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2850 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2855 warnIfNoMacro(IDLoc);
2862 if (loadImmediate(ImmValue >> 32, TmpReg, MCRegister(),
true,
false, IDLoc,
2868 unsigned ShiftCarriedForwards = 16;
2869 for (
int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2870 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2872 if (ImmChunk != 0) {
2873 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2874 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2875 ShiftCarriedForwards = 0;
2878 ShiftCarriedForwards += 16;
2880 ShiftCarriedForwards -= 16;
2883 if (ShiftCarriedForwards)
2884 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2887 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2892bool MipsAsmParser::expandLoadImm(MCInst &Inst,
bool Is32BitImm, SMLoc IDLoc,
2893 MCStreamer &Out,
const MCSubtargetInfo *STI) {
2895 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
2896 const MCOperand &DstRegOp = Inst.
getOperand(0);
2897 assert(DstRegOp.
isReg() &&
"expected register operand kind");
2899 if (loadImmediate(ImmOp.
getImm(), DstRegOp.
getReg(), MCRegister(), Is32BitImm,
2900 false, IDLoc, Out, STI))
2906bool MipsAsmParser::expandLoadAddress(MCRegister DstReg, MCRegister BaseReg,
2908 bool Is32BitAddress, SMLoc IDLoc,
2910 const MCSubtargetInfo *STI) {
2912 if (Is32BitAddress &&
ABI.ArePtrs64bit()) {
2913 Warning(IDLoc,
"la used to load 64-bit address");
2915 Is32BitAddress =
false;
2919 if (!Is32BitAddress && !hasMips3()) {
2920 Error(IDLoc,
"instruction requires a 64-bit architecture");
2925 return loadAndAddSymbolAddress(
Offset.getExpr(), DstReg, BaseReg,
2926 Is32BitAddress, IDLoc, Out, STI);
2928 if (!
ABI.ArePtrs64bit()) {
2930 Is32BitAddress =
true;
2933 return loadImmediate(
Offset.getImm(), DstReg, BaseReg, Is32BitAddress,
true,
2937bool MipsAsmParser::loadAndAddSymbolAddress(
const MCExpr *SymExpr,
2939 MCRegister SrcReg,
bool Is32BitSym,
2940 SMLoc IDLoc, MCStreamer &Out,
2941 const MCSubtargetInfo *STI) {
2942 MipsTargetStreamer &TOut = getTargetStreamer();
2944 SrcReg.
isValid() && SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64;
2945 warnIfNoMacro(IDLoc);
2950 Error(IDLoc,
"expected relocatable expression");
2954 Error(IDLoc,
"expected relocatable expression with only one symbol");
2958 bool IsPtr64 =
ABI.ArePtrs64bit();
2962 static_cast<const MCSymbolELF *
>(Res.
getAddSym())->getBinding() ==
2969 bool UseXGOT = STI->
hasFeature(Mips::FeatureXGOT) && !IsLocalSym;
2975 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2978 const MCExpr *CallHiExpr =
2980 const MCExpr *CallLoExpr =
2984 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, DstReg, GPReg,
2986 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, DstReg,
2989 const MCExpr *CallExpr =
2991 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, GPReg,
2997 MCRegister TmpReg = DstReg;
2999 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
3003 MCRegister ATReg = getATReg(IDLoc);
3022 const MCExpr *CallHiExpr =
3029 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg, GPReg,
3031 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, TmpReg,
3035 TOut.
emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3041 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3046 const MCSpecifierExpr *GotExpr =
nullptr;
3047 const MCExpr *LoExpr =
nullptr;
3048 if (
ABI.IsN32() ||
ABI.IsN64()) {
3067 Error(IDLoc,
"macro instruction uses large offset, which is not "
3068 "currently supported");
3097 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, GPReg,
3101 TOut.
emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3105 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3111 const auto *HiExpr =
3113 const auto *LoExpr =
3117 if (
ABI.ArePtrs64bit() && isGP64bit()) {
3125 const auto *HighestExpr =
3127 const auto *HigherExpr =
3132 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
3134 if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
3135 MCRegister ATReg = getATReg(IDLoc);
3147 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3149 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3152 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3155 TOut.
emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
3158 }
else if (canUseATReg() && !RdRegIsRsReg && DstReg != getATReg(IDLoc)) {
3159 MCRegister ATReg = getATReg(IDLoc);
3175 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3179 TOut.
emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3180 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3182 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3185 }
else if ((!canUseATReg() && !RdRegIsRsReg) ||
3186 (canUseATReg() && DstReg == getATReg(IDLoc))) {
3197 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3199 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3200 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3202 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3203 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3206 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3212 assert(SrcReg == DstReg && !canUseATReg() &&
3213 "Could have expanded dla but didn't?");
3214 reportParseError(IDLoc,
3215 "pseudo-instruction requires $at, which is not available");
3229 MCRegister TmpReg = DstReg;
3231 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
3234 MCRegister ATReg = getATReg(IDLoc);
3245 TOut.
emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3248 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
3257 if (MipsMCRegisterClasses[Mips::FGR32RegClassID].
contains(
Reg))
3258 return Reg == (
unsigned)Mips::F31 ? (
unsigned)Mips::F0 :
Reg + 1;
3260 default:
llvm_unreachable(
"Unknown register in assembly macro expansion!");
3261 case Mips::ZERO:
return Mips::AT;
3262 case Mips::AT:
return Mips::V0;
3263 case Mips::V0:
return Mips::V1;
3264 case Mips::V1:
return Mips::A0;
3265 case Mips::A0:
return Mips::A1;
3266 case Mips::A1:
return Mips::A2;
3267 case Mips::A2:
return Mips::A3;
3268 case Mips::A3:
return Mips::T0;
3269 case Mips::T0:
return Mips::T1;
3270 case Mips::T1:
return Mips::T2;
3271 case Mips::T2:
return Mips::T3;
3272 case Mips::T3:
return Mips::T4;
3273 case Mips::T4:
return Mips::T5;
3274 case Mips::T5:
return Mips::T6;
3275 case Mips::T6:
return Mips::T7;
3276 case Mips::T7:
return Mips::S0;
3277 case Mips::S0:
return Mips::S1;
3278 case Mips::S1:
return Mips::S2;
3279 case Mips::S2:
return Mips::S3;
3280 case Mips::S3:
return Mips::S4;
3281 case Mips::S4:
return Mips::S5;
3282 case Mips::S5:
return Mips::S6;
3283 case Mips::S6:
return Mips::S7;
3284 case Mips::S7:
return Mips::T8;
3285 case Mips::T8:
return Mips::T9;
3286 case Mips::T9:
return Mips::K0;
3287 case Mips::K0:
return Mips::K1;
3288 case Mips::K1:
return Mips::GP;
3289 case Mips::GP:
return Mips::SP;
3290 case Mips::SP:
return Mips::FP;
3291 case Mips::FP:
return Mips::RA;
3292 case Mips::RA:
return Mips::ZERO;
3293 case Mips::D0:
return Mips::F1;
3294 case Mips::D1:
return Mips::F3;
3295 case Mips::D2:
return Mips::F5;
3296 case Mips::D3:
return Mips::F7;
3297 case Mips::D4:
return Mips::F9;
3298 case Mips::D5:
return Mips::F11;
3299 case Mips::D6:
return Mips::F13;
3300 case Mips::D7:
return Mips::F15;
3301 case Mips::D8:
return Mips::F17;
3302 case Mips::D9:
return Mips::F19;
3303 case Mips::D10:
return Mips::F21;
3304 case Mips::D11:
return Mips::F23;
3305 case Mips::D12:
return Mips::F25;
3306 case Mips::D13:
return Mips::F27;
3307 case Mips::D14:
return Mips::F29;
3308 case Mips::D15:
return Mips::F31;
3318bool MipsAsmParser::emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc,
3320 MCRegister ATReg = getATReg(IDLoc);
3326 const auto *GotExpr =
3329 if(isABI_O32() || isABI_N32()) {
3338 const auto *HiExpr =
3347 if(isABI_O32() || isABI_N32()) {
3351 const auto *HighestExpr =
3354 const auto *HigherExpr =
3359 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3361 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3364 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3373 if ((
Hi_32(ImmOp64) & 0x7ff00000) == 0) {
3384 float TmpFloat =
static_cast<float>(DoubleImm);
3388bool MipsAsmParser::expandLoadSingleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3390 const MCSubtargetInfo *STI) {
3393 "Invalid instruction operand.");
3400 return loadImmediate(ImmOp32, FirstReg, MCRegister(),
true,
false, IDLoc, Out,
3404bool MipsAsmParser::expandLoadSingleImmToFPR(MCInst &Inst, SMLoc IDLoc,
3406 const MCSubtargetInfo *STI) {
3407 MipsTargetStreamer &TOut = getTargetStreamer();
3410 "Invalid instruction operand.");
3419 MCRegister TmpReg = Mips::ZERO;
3421 TmpReg = getATReg(IDLoc);
3426 if (
Lo_32(ImmOp64) == 0) {
3427 if (TmpReg != Mips::ZERO && loadImmediate(ImmOp32, TmpReg, MCRegister(),
3428 true,
false, IDLoc, Out, STI))
3430 TOut.
emitRR(Mips::MTC1, FirstReg, TmpReg, IDLoc, STI);
3434 MCSection *CS = getStreamer().getCurrentSectionOnly();
3437 MCSection *ReadOnlySection =
3444 getStreamer().switchSection(ReadOnlySection);
3445 getStreamer().emitLabel(Sym, IDLoc);
3446 getStreamer().emitInt32(ImmOp32);
3447 getStreamer().switchSection(CS);
3449 if (emitPartialAddress(TOut, IDLoc, Sym))
3456bool MipsAsmParser::expandLoadDoubleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3458 const MCSubtargetInfo *STI) {
3459 MipsTargetStreamer &TOut = getTargetStreamer();
3462 "Invalid instruction operand.");
3469 if (
Lo_32(ImmOp64) == 0) {
3471 if (loadImmediate(ImmOp64, FirstReg, MCRegister(),
false,
false, IDLoc,
3475 if (loadImmediate(
Hi_32(ImmOp64), FirstReg, MCRegister(),
true,
false,
3479 if (loadImmediate(0,
nextReg(FirstReg), MCRegister(),
true,
false, IDLoc,
3486 MCSection *CS = getStreamer().getCurrentSectionOnly();
3487 MCSection *ReadOnlySection =
3494 getStreamer().switchSection(ReadOnlySection);
3495 getStreamer().emitLabel(Sym, IDLoc);
3496 getStreamer().emitValueToAlignment(
Align(8));
3497 getStreamer().emitIntValue(ImmOp64, 8);
3498 getStreamer().switchSection(CS);
3500 MCRegister TmpReg = getATReg(IDLoc);
3504 if (emitPartialAddress(TOut, IDLoc, Sym))
3507 TOut.
emitRRX(isABI_N64() ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3511 TOut.
emitRRI(Mips::LD, FirstReg, TmpReg, 0, IDLoc, STI);
3513 TOut.
emitRRI(Mips::LW, FirstReg, TmpReg, 0, IDLoc, STI);
3514 TOut.
emitRRI(Mips::LW,
nextReg(FirstReg), TmpReg, 4, IDLoc, STI);
3519bool MipsAsmParser::expandLoadDoubleImmToFPR(MCInst &Inst,
bool Is64FPU,
3520 SMLoc IDLoc, MCStreamer &Out,
3521 const MCSubtargetInfo *STI) {
3522 MipsTargetStreamer &TOut = getTargetStreamer();
3525 "Invalid instruction operand.");
3532 MCRegister TmpReg = Mips::ZERO;
3534 TmpReg = getATReg(IDLoc);
3539 if ((
Lo_32(ImmOp64) == 0) &&
3540 !((
Hi_32(ImmOp64) & 0xffff0000) && (
Hi_32(ImmOp64) & 0x0000ffff))) {
3542 if (TmpReg != Mips::ZERO && loadImmediate(ImmOp64, TmpReg, MCRegister(),
3543 false,
false, IDLoc, Out, STI))
3545 TOut.
emitRR(Mips::DMTC1, FirstReg, TmpReg, IDLoc, STI);
3549 if (TmpReg != Mips::ZERO &&
3550 loadImmediate(
Hi_32(ImmOp64), TmpReg, MCRegister(),
true,
false, IDLoc,
3554 if (hasMips32r2()) {
3555 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3556 TOut.
emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, TmpReg, IDLoc, STI);
3558 TOut.
emitRR(Mips::MTC1,
nextReg(FirstReg), TmpReg, IDLoc, STI);
3559 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3564 MCSection *CS = getStreamer().getCurrentSectionOnly();
3567 MCSection *ReadOnlySection =
3574 getStreamer().switchSection(ReadOnlySection);
3575 getStreamer().emitLabel(Sym, IDLoc);
3576 getStreamer().emitValueToAlignment(
Align(8));
3577 getStreamer().emitIntValue(ImmOp64, 8);
3578 getStreamer().switchSection(CS);
3580 if (emitPartialAddress(TOut, IDLoc, Sym))
3583 TOut.
emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, TmpReg,
3589bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
3591 const MCSubtargetInfo *STI) {
3592 MipsTargetStreamer &TOut = getTargetStreamer();
3595 "unexpected number of operands");
3605 assert(
Offset.isImm() &&
"expected immediate operand kind");
3609 if (inMicroMipsMode())
3610 Inst.
setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3613 return Error(IDLoc,
"branch target out of range");
3615 return Error(IDLoc,
"branch to misaligned address");
3627 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
3634bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3635 const MCSubtargetInfo *STI) {
3636 MipsTargetStreamer &TOut = getTargetStreamer();
3637 const MCOperand &DstRegOp = Inst.
getOperand(0);
3638 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3641 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
3643 const MCOperand &MemOffsetOp = Inst.
getOperand(2);
3645 "expected immediate or expression operand");
3647 bool IsLikely =
false;
3657 case Mips::BEQLImmMacro:
3661 case Mips::BNELImmMacro:
3670 int64_t ImmValue = ImmOp.
getImm();
3671 if (ImmValue == 0) {
3675 TOut.
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3677 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3680 warnIfNoMacro(IDLoc);
3682 MCRegister ATReg = getATReg(IDLoc);
3686 if (loadImmediate(ImmValue, ATReg, MCRegister(), !isGP64bit(),
true, IDLoc,
3690 if (IsLikely && MemOffsetOp.
isExpr()) {
3693 TOut.
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3695 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3700void MipsAsmParser::expandMem16Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3701 const MCSubtargetInfo *STI,
bool IsLoad) {
3703 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3704 unsigned StartOp = NumOp == 3 ? 0 : 1;
3706 const MCOperand &DstRegOp = Inst.
getOperand(StartOp);
3707 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3708 const MCOperand &BaseRegOp = Inst.
getOperand(StartOp + 1);
3709 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3712 MipsTargetStreamer &TOut = getTargetStreamer();
3714 MCRegister DstReg = DstRegOp.
getReg();
3716 MCRegister TmpReg = DstReg;
3718 const MCInstrDesc &
Desc = MII.get(OpCode);
3719 int16_t DstRegClass =
3720 MII.getOpRegClassID(
Desc.operands()[StartOp],
3722 unsigned DstRegClassID =
3723 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3724 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3725 (DstRegClassID == Mips::GPR64RegClassID);
3727 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3730 TmpReg = getATReg(IDLoc);
3735 auto emitInstWithOffset = [&](
const MCOperand &
Off) {
3737 TOut.
emitRRX(OpCode, DstReg, TmpReg, Off, IDLoc, STI);
3739 TOut.
emitRRRX(OpCode, DstReg, DstReg, TmpReg, Off, IDLoc, STI);
3743 int64_t LoOffset =
OffsetOp.getImm() & 0xffff;
3744 int64_t HiOffset =
OffsetOp.getImm() & ~0xffff;
3748 if (LoOffset & 0x8000)
3749 HiOffset += 0x10000;
3751 bool IsLargeOffset = HiOffset != 0;
3753 if (IsLargeOffset) {
3755 if (loadImmediate(HiOffset, TmpReg, MCRegister(), Is32BitImm,
true, IDLoc,
3760 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3761 TOut.
emitRRR(
ABI.ArePtrs64bit() ? Mips::DADDu : Mips::ADDu, TmpReg,
3762 TmpReg, BaseReg, IDLoc, STI);
3776 if (!
OffsetOp.getExpr()->evaluateAsRelocatable(Res,
nullptr)) {
3777 Error(IDLoc,
"expected relocatable expression");
3781 Error(IDLoc,
"expected relocatable expression with only one symbol");
3785 loadAndAddSymbolAddress(
3787 BaseReg, !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3795 const MCExpr *OffExpr =
OffsetOp.getExpr();
3807 TOut.
emitRX(Mips::LUi, TmpReg, HighestOperand, IDLoc, STI);
3808 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HigherOperand, IDLoc, STI);
3809 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3810 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HiOperand, IDLoc, STI);
3811 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3812 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3813 TOut.
emitRRR(Mips::DADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3814 emitInstWithOffset(LoOperand);
3817 TOut.
emitRX(Mips::LUi, TmpReg, HiOperand, IDLoc, STI);
3818 if (BaseReg != Mips::ZERO)
3819 TOut.
emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3821 emitInstWithOffset(LoOperand);
3830void MipsAsmParser::expandMem9Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3831 const MCSubtargetInfo *STI,
bool IsLoad) {
3833 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3834 unsigned StartOp = NumOp == 3 ? 0 : 1;
3836 const MCOperand &DstRegOp = Inst.
getOperand(StartOp);
3837 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3838 const MCOperand &BaseRegOp = Inst.
getOperand(StartOp + 1);
3839 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3842 MipsTargetStreamer &TOut = getTargetStreamer();
3844 MCRegister DstReg = DstRegOp.
getReg();
3846 MCRegister TmpReg = DstReg;
3848 const MCInstrDesc &
Desc = MII.get(OpCode);
3849 int16_t DstRegClass =
3850 MII.getOpRegClassID(
Desc.operands()[StartOp],
3853 unsigned DstRegClassID =
3854 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3855 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3856 (DstRegClassID == Mips::GPR64RegClassID);
3858 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3861 TmpReg = getATReg(IDLoc);
3866 auto emitInst = [&]() {
3875 loadImmediate(
OffsetOp.getImm(), TmpReg, BaseReg, !
ABI.ArePtrs64bit(),
true,
3882 loadAndAddSymbolAddress(
OffsetOp.getExpr(), TmpReg, BaseReg,
3883 !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3891bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
3893 const MCSubtargetInfo *STI) {
3896 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3900 Inst.
getOperand(OpNum - 3).
isReg() &&
"Invalid instruction operand.");
3909 if (inMicroMipsMode() && hasMips32r6())
3910 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3912 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3920bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
3922 const MCSubtargetInfo *STI) {
3923 MipsTargetStreamer &TOut = getTargetStreamer();
3924 bool EmittedNoMacroWarning =
false;
3925 unsigned PseudoOpcode = Inst.
getOpcode();
3930 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3931 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3936 else if (TrgOp.
isImm()) {
3937 warnIfNoMacro(IDLoc);
3938 EmittedNoMacroWarning =
true;
3940 TrgReg = getATReg(IDLoc);
3944 switch(PseudoOpcode) {
3947 case Mips::BLTImmMacro:
3948 PseudoOpcode = Mips::BLT;
3950 case Mips::BLEImmMacro:
3951 PseudoOpcode = Mips::BLE;
3953 case Mips::BGEImmMacro:
3954 PseudoOpcode = Mips::BGE;
3956 case Mips::BGTImmMacro:
3957 PseudoOpcode = Mips::BGT;
3959 case Mips::BLTUImmMacro:
3960 PseudoOpcode = Mips::BLTU;
3962 case Mips::BLEUImmMacro:
3963 PseudoOpcode = Mips::BLEU;
3965 case Mips::BGEUImmMacro:
3966 PseudoOpcode = Mips::BGEU;
3968 case Mips::BGTUImmMacro:
3969 PseudoOpcode = Mips::BGTU;
3971 case Mips::BLTLImmMacro:
3972 PseudoOpcode = Mips::BLTL;
3974 case Mips::BLELImmMacro:
3975 PseudoOpcode = Mips::BLEL;
3977 case Mips::BGELImmMacro:
3978 PseudoOpcode = Mips::BGEL;
3980 case Mips::BGTLImmMacro:
3981 PseudoOpcode = Mips::BGTL;
3983 case Mips::BLTULImmMacro:
3984 PseudoOpcode = Mips::BLTUL;
3986 case Mips::BLEULImmMacro:
3987 PseudoOpcode = Mips::BLEUL;
3989 case Mips::BGEULImmMacro:
3990 PseudoOpcode = Mips::BGEUL;
3992 case Mips::BGTULImmMacro:
3993 PseudoOpcode = Mips::BGTUL;
3997 if (loadImmediate(TrgOp.
getImm(), TrgReg, MCRegister(), !isGP64bit(),
false,
4002 switch (PseudoOpcode) {
4007 AcceptsEquality =
false;
4008 ReverseOrderSLT =
false;
4010 ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
4011 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
4012 ZeroSrcOpcode = Mips::BGTZ;
4013 ZeroTrgOpcode = Mips::BLTZ;
4019 AcceptsEquality =
true;
4020 ReverseOrderSLT =
true;
4022 ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
4023 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
4024 ZeroSrcOpcode = Mips::BGEZ;
4025 ZeroTrgOpcode = Mips::BLEZ;
4031 AcceptsEquality =
true;
4032 ReverseOrderSLT =
false;
4034 ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
4035 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
4036 ZeroSrcOpcode = Mips::BLEZ;
4037 ZeroTrgOpcode = Mips::BGEZ;
4043 AcceptsEquality =
false;
4044 ReverseOrderSLT =
true;
4046 ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
4047 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
4048 ZeroSrcOpcode = Mips::BLTZ;
4049 ZeroTrgOpcode = Mips::BGTZ;
4055 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
4056 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
4057 if (IsSrcRegZero && IsTrgRegZero) {
4061 if (PseudoOpcode == Mips::BLT) {
4066 if (PseudoOpcode == Mips::BLE) {
4069 Warning(IDLoc,
"branch is always taken");
4072 if (PseudoOpcode == Mips::BGE) {
4075 Warning(IDLoc,
"branch is always taken");
4078 if (PseudoOpcode == Mips::BGT) {
4083 if (PseudoOpcode == Mips::BGTU) {
4084 TOut.
emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
4088 if (AcceptsEquality) {
4091 TOut.
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4093 Warning(IDLoc,
"branch is always taken");
4100 if (IsSrcRegZero || IsTrgRegZero) {
4101 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
4102 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
4109 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
4110 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
4116 TOut.
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4118 Warning(IDLoc,
"branch is always taken");
4134 TOut.
emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
4135 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
4142 TOut.
emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
4143 IsSrcRegZero ? TrgReg : SrcReg,
4150 MCRegister ATRegNum = getATReg(IDLoc);
4154 if (!EmittedNoMacroWarning)
4155 warnIfNoMacro(IDLoc);
4172 TOut.
emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
4173 ReverseOrderSLT ? TrgReg : SrcReg,
4174 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
4176 TOut.
emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
4177 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
4191bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4192 const MCSubtargetInfo *STI,
4193 const bool IsMips64,
const bool Signed) {
4194 MipsTargetStreamer &TOut = getTargetStreamer();
4196 warnIfNoMacro(IDLoc);
4198 const MCOperand &RdRegOp = Inst.
getOperand(0);
4199 assert(RdRegOp.
isReg() &&
"expected register operand kind");
4200 MCRegister RdReg = RdRegOp.
getReg();
4202 const MCOperand &RsRegOp = Inst.
getOperand(1);
4203 assert(RsRegOp.
isReg() &&
"expected register operand kind");
4204 MCRegister RsReg = RsRegOp.
getReg();
4211 "expected register or immediate operand kind");
4215 ImmValue = RtOp.
getImm();
4222 DivOp =
Signed ? Mips::DSDIV : Mips::DUDIV;
4223 ZeroReg = Mips::ZERO_64;
4226 DivOp =
Signed ? Mips::SDIV : Mips::UDIV;
4227 ZeroReg = Mips::ZERO;
4231 bool UseTraps = useTraps();
4234 bool isDiv = Opcode == Mips::SDivMacro || Opcode == Mips::SDivIMacro ||
4235 Opcode == Mips::UDivMacro || Opcode == Mips::UDivIMacro ||
4236 Opcode == Mips::DSDivMacro || Opcode == Mips::DSDivIMacro ||
4237 Opcode == Mips::DUDivMacro || Opcode == Mips::DUDivIMacro;
4239 bool isRem = Opcode == Mips::SRemMacro || Opcode == Mips::SRemIMacro ||
4240 Opcode == Mips::URemMacro || Opcode == Mips::URemIMacro ||
4241 Opcode == Mips::DSRemMacro || Opcode == Mips::DSRemIMacro ||
4242 Opcode == Mips::DURemMacro || Opcode == Mips::DURemIMacro;
4245 MCRegister ATReg = getATReg(IDLoc);
4251 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4253 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4257 if (isRem && (ImmValue == 1 || (
Signed && (ImmValue == -1)))) {
4258 TOut.
emitRRR(Mips::OR, RdReg, ZeroReg, ZeroReg, IDLoc, STI);
4260 }
else if (isDiv && ImmValue == 1) {
4261 TOut.
emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI);
4263 }
else if (isDiv &&
Signed && ImmValue == -1) {
4264 TOut.
emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
4267 if (loadImmediate(ImmValue, ATReg, MCRegister(),
isInt<32>(ImmValue),
4268 false, Inst.
getLoc(), Out, STI))
4270 TOut.
emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
4271 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4281 if (!
NoZeroDivCheck && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
4283 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4286 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4292 if (isRem && (RdReg == Mips::ZERO || RdReg == Mips::ZERO_64)) {
4293 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4302 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4305 TOut.
emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4308 BrTarget =
Context.createTempSymbol();
4311 TOut.
emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4316 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4322 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4326bool MipsAsmParser::expandTrunc(MCInst &Inst,
bool IsDouble,
bool Is64FPU,
4327 SMLoc IDLoc, MCStreamer &Out,
4328 const MCSubtargetInfo *STI) {
4329 MipsTargetStreamer &TOut = getTargetStreamer();
4339 if (hasMips1() && !hasMips2()) {
4340 MCRegister ATReg = getATReg(IDLoc);
4343 TOut.
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4344 TOut.
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4346 TOut.
emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4347 TOut.
emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4348 TOut.
emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4350 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4352 FirstReg, SecondReg, IDLoc, STI);
4353 TOut.
emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4358 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4360 FirstReg, SecondReg, IDLoc, STI);
4365bool MipsAsmParser::expandUlh(MCInst &Inst,
bool Signed, SMLoc IDLoc,
4366 MCStreamer &Out,
const MCSubtargetInfo *STI) {
4367 if (hasMips32r6() || hasMips64r6()) {
4368 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4371 const MCOperand &DstRegOp = Inst.
getOperand(0);
4372 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4373 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4374 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4375 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4376 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4378 MipsTargetStreamer &TOut = getTargetStreamer();
4379 MCRegister DstReg = DstRegOp.
getReg();
4380 MCRegister SrcReg = SrcRegOp.
getReg();
4381 int64_t OffsetValue = OffsetImmOp.
getImm();
4385 warnIfNoMacro(IDLoc);
4386 MCRegister ATReg = getATReg(IDLoc);
4391 if (IsLargeOffset) {
4392 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4397 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4398 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4402 MCRegister FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4403 MCRegister SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4405 MCRegister LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4406 MCRegister SllReg = IsLargeOffset ? DstReg : ATReg;
4408 TOut.
emitRRI(
Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4409 FirstOffset, IDLoc, STI);
4410 TOut.
emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4411 TOut.
emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4412 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4417bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4418 const MCSubtargetInfo *STI) {
4419 if (hasMips32r6() || hasMips64r6()) {
4420 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4423 const MCOperand &DstRegOp = Inst.
getOperand(0);
4424 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4425 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4426 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4427 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4428 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4430 MipsTargetStreamer &TOut = getTargetStreamer();
4431 MCRegister DstReg = DstRegOp.
getReg();
4432 MCRegister SrcReg = SrcRegOp.
getReg();
4433 int64_t OffsetValue = OffsetImmOp.
getImm();
4435 warnIfNoMacro(IDLoc);
4436 MCRegister ATReg = getATReg(IDLoc);
4441 if (IsLargeOffset) {
4442 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4447 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4448 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4452 if (IsLargeOffset) {
4453 TOut.
emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4454 TOut.
emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4455 TOut.
emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4456 TOut.
emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4457 TOut.
emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4458 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4460 TOut.
emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4461 TOut.
emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4462 TOut.
emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4468bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4469 const MCSubtargetInfo *STI) {
4470 if (hasMips32r6() || hasMips64r6()) {
4471 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4474 const MCOperand &DstRegOp = Inst.
getOperand(0);
4475 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4476 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4477 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4478 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4479 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4481 MipsTargetStreamer &TOut = getTargetStreamer();
4482 MCRegister DstReg = DstRegOp.
getReg();
4483 MCRegister SrcReg = SrcRegOp.
getReg();
4484 int64_t OffsetValue = OffsetImmOp.
getImm();
4488 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4489 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4493 bool IsLoadInst = (Inst.
getOpcode() == Mips::Ulw);
4494 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4495 MCRegister TmpReg = SrcReg;
4496 if (IsLargeOffset || DoMove) {
4497 warnIfNoMacro(IDLoc);
4498 TmpReg = getATReg(IDLoc);
4503 if (IsLargeOffset) {
4504 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4512 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4513 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4514 TOut.
emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4515 TOut.
emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4518 TOut.
emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4523bool MipsAsmParser::expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4524 const MCSubtargetInfo *STI) {
4525 MipsTargetStreamer &TOut = getTargetStreamer();
4537 warnIfNoMacro(IDLoc);
4551 TOut.
emitRRR(OpCode, DstReg, SrcReg, OpReg, IDLoc, STI);
4552 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4557bool MipsAsmParser::expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4558 const MCSubtargetInfo *STI) {
4559 MipsTargetStreamer &TOut = getTargetStreamer();
4569 unsigned OpRegCode, OpImmCode;
4571 warnIfNoMacro(IDLoc);
4575 case Mips::SGEImm64:
4576 OpRegCode = Mips::SLT;
4577 OpImmCode = Mips::SLTi;
4580 case Mips::SGEUImm64:
4581 OpRegCode = Mips::SLTu;
4582 OpImmCode = Mips::SLTiu;
4591 TOut.
emitRRI(OpImmCode, DstReg, SrcReg, ImmValue, IDLoc, STI);
4592 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4594 MCRegister ImmReg = DstReg;
4595 if (DstReg == SrcReg) {
4596 MCRegister ATReg = getATReg(Inst.
getLoc());
4602 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
4603 false, IDLoc, Out, STI))
4606 TOut.
emitRRR(OpRegCode, DstReg, SrcReg, ImmReg, IDLoc, STI);
4607 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4613bool MipsAsmParser::expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4614 const MCSubtargetInfo *STI) {
4615 MipsTargetStreamer &TOut = getTargetStreamer();
4624 MCRegister ImmReg = DstReg;
4628 warnIfNoMacro(IDLoc);
4632 case Mips::SGTImm64:
4636 case Mips::SGTUImm64:
4643 if (DstReg == SrcReg) {
4644 MCRegister ATReg = getATReg(Inst.
getLoc());
4650 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
false,
4655 TOut.
emitRRR(OpCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4660bool MipsAsmParser::expandSle(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4661 const MCSubtargetInfo *STI) {
4662 MipsTargetStreamer &TOut = getTargetStreamer();
4674 warnIfNoMacro(IDLoc);
4688 TOut.
emitRRR(OpCode, DstReg, OpReg, SrcReg, IDLoc, STI);
4689 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4694bool MipsAsmParser::expandSleImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4695 const MCSubtargetInfo *STI) {
4696 MipsTargetStreamer &TOut = getTargetStreamer();
4708 warnIfNoMacro(IDLoc);
4712 case Mips::SLEImm64:
4713 OpRegCode = Mips::SLT;
4716 case Mips::SLEUImm64:
4717 OpRegCode = Mips::SLTu;
4724 MCRegister ImmReg = DstReg;
4725 if (DstReg == SrcReg) {
4726 MCRegister ATReg = getATReg(Inst.
getLoc());
4732 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
false,
4736 TOut.
emitRRR(OpRegCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4737 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4742bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
4744 const MCSubtargetInfo *STI) {
4745 MipsTargetStreamer &TOut = getTargetStreamer();
4753 MCRegister FinalDstReg;
4760 unsigned FinalOpcode = Inst.
getOpcode();
4762 if (DstReg == SrcReg) {
4763 ATReg = getATReg(Inst.
getLoc());
4766 FinalDstReg = DstReg;
4770 if (!loadImmediate(ImmValue, DstReg, MCRegister(), Is32Bit,
false,
4771 Inst.
getLoc(), Out, STI)) {
4772 switch (FinalOpcode) {
4776 FinalOpcode = Mips::ADD;
4779 FinalOpcode = Mips::ADDu;
4782 FinalOpcode = Mips::AND;
4785 FinalOpcode = Mips::NOR;
4788 FinalOpcode = Mips::OR;
4791 FinalOpcode = Mips::SLT;
4794 FinalOpcode = Mips::SLTu;
4797 FinalOpcode = Mips::XOR;
4800 FinalOpcode = Mips::ADD_MM;
4802 case Mips::ADDiu_MM:
4803 FinalOpcode = Mips::ADDu_MM;
4806 FinalOpcode = Mips::AND_MM;
4809 FinalOpcode = Mips::OR_MM;
4812 FinalOpcode = Mips::SLT_MM;
4814 case Mips::SLTiu_MM:
4815 FinalOpcode = Mips::SLTu_MM;
4818 FinalOpcode = Mips::XOR_MM;
4821 FinalOpcode = Mips::AND64;
4823 case Mips::NORImm64:
4824 FinalOpcode = Mips::NOR64;
4827 FinalOpcode = Mips::OR64;
4829 case Mips::SLTImm64:
4830 FinalOpcode = Mips::SLT64;
4832 case Mips::SLTUImm64:
4833 FinalOpcode = Mips::SLTu64;
4836 FinalOpcode = Mips::XOR64;
4841 TOut.
emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4843 TOut.
emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4849bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4850 const MCSubtargetInfo *STI) {
4851 MipsTargetStreamer &TOut = getTargetStreamer();
4856 MCRegister TmpReg =
DReg;
4858 unsigned FirstShift = Mips::NOP;
4859 unsigned SecondShift = Mips::NOP;
4861 if (hasMips32r2()) {
4863 TmpReg = getATReg(Inst.
getLoc());
4869 TOut.
emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4870 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
4875 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
4887 FirstShift = Mips::SRLV;
4888 SecondShift = Mips::SLLV;
4891 FirstShift = Mips::SLLV;
4892 SecondShift = Mips::SRLV;
4896 ATReg = getATReg(Inst.
getLoc());
4900 TOut.
emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4901 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
4902 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
4903 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
4911bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
4913 const MCSubtargetInfo *STI) {
4914 MipsTargetStreamer &TOut = getTargetStreamer();
4920 unsigned FirstShift = Mips::NOP;
4921 unsigned SecondShift = Mips::NOP;
4923 if (hasMips32r2()) {
4925 uint64_t MaxShift = 32;
4926 uint64_t ShiftValue = ImmValue;
4928 ShiftValue = MaxShift - ImmValue;
4929 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
4934 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.
getLoc(), STI);
4942 if (ImmValue == 0) {
4951 FirstShift = Mips::SLL;
4952 SecondShift = Mips::SRL;
4955 FirstShift = Mips::SRL;
4956 SecondShift = Mips::SLL;
4960 ATReg = getATReg(Inst.
getLoc());
4964 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.
getLoc(), STI);
4965 TOut.
emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.
getLoc(), STI);
4966 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
4974bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4975 const MCSubtargetInfo *STI) {
4976 MipsTargetStreamer &TOut = getTargetStreamer();
4981 MCRegister TmpReg =
DReg;
4983 unsigned FirstShift = Mips::NOP;
4984 unsigned SecondShift = Mips::NOP;
4986 if (hasMips64r2()) {
4987 if (TmpReg == SReg) {
4988 TmpReg = getATReg(Inst.
getLoc());
4994 TOut.
emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4995 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
5000 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
5012 FirstShift = Mips::DSRLV;
5013 SecondShift = Mips::DSLLV;
5016 FirstShift = Mips::DSLLV;
5017 SecondShift = Mips::DSRLV;
5021 ATReg = getATReg(Inst.
getLoc());
5025 TOut.
emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
5026 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
5027 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
5028 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5036bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
5038 const MCSubtargetInfo *STI) {
5039 MipsTargetStreamer &TOut = getTargetStreamer();
5045 unsigned FirstShift = Mips::NOP;
5046 unsigned SecondShift = Mips::NOP;
5050 if (hasMips64r2()) {
5051 unsigned FinalOpcode = Mips::NOP;
5053 FinalOpcode = Mips::DROTR;
5054 else if (ImmValue % 32 == 0)
5055 FinalOpcode = Mips::DROTR32;
5056 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
5058 FinalOpcode = Mips::DROTR32;
5060 FinalOpcode = Mips::DROTR;
5061 }
else if (ImmValue >= 33) {
5063 FinalOpcode = Mips::DROTR;
5065 FinalOpcode = Mips::DROTR32;
5068 uint64_t ShiftValue = ImmValue % 32;
5070 ShiftValue = (32 - ImmValue % 32) % 32;
5072 TOut.
emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
5078 if (ImmValue == 0) {
5079 TOut.
emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.
getLoc(), STI);
5087 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5088 FirstShift = Mips::DSLL;
5089 SecondShift = Mips::DSRL32;
5091 if (ImmValue == 32) {
5092 FirstShift = Mips::DSLL32;
5093 SecondShift = Mips::DSRL32;
5095 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5096 FirstShift = Mips::DSLL32;
5097 SecondShift = Mips::DSRL;
5101 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5102 FirstShift = Mips::DSRL;
5103 SecondShift = Mips::DSLL32;
5105 if (ImmValue == 32) {
5106 FirstShift = Mips::DSRL32;
5107 SecondShift = Mips::DSLL32;
5109 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5110 FirstShift = Mips::DSRL32;
5111 SecondShift = Mips::DSLL;
5116 ATReg = getATReg(Inst.
getLoc());
5120 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.
getLoc(), STI);
5121 TOut.
emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
5123 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5131bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5132 const MCSubtargetInfo *STI) {
5133 MipsTargetStreamer &TOut = getTargetStreamer();
5137 TOut.
emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
5138 if (FirstRegOp != SecondRegOp)
5139 TOut.
emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
5142 TOut.
emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
5147bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5148 const MCSubtargetInfo *STI) {
5149 MipsTargetStreamer &TOut = getTargetStreamer();
5155 ATReg = getATReg(IDLoc);
5159 loadImmediate(ImmValue, ATReg, MCRegister(),
true,
false, IDLoc, Out, STI);
5161 TOut.
emitRR(Inst.
getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
5162 SrcReg, ATReg, IDLoc, STI);
5164 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5169bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5170 const MCSubtargetInfo *STI) {
5171 MipsTargetStreamer &TOut = getTargetStreamer();
5177 ATReg = getATReg(Inst.
getLoc());
5181 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
5182 SrcReg, TmpReg, IDLoc, STI);
5184 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5186 TOut.
emitRRI(Inst.
getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
5187 DstReg, DstReg, 0x1F, IDLoc, STI);
5189 TOut.
emitR(Mips::MFHI, ATReg, IDLoc, STI);
5192 TOut.
emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
5199 TOut.
emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
5200 if (AssemblerOptions.
back()->isReorder())
5202 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5206 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5211bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5212 const MCSubtargetInfo *STI) {
5213 MipsTargetStreamer &TOut = getTargetStreamer();
5219 ATReg = getATReg(IDLoc);
5223 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
5224 SrcReg, TmpReg, IDLoc, STI);
5226 TOut.
emitR(Mips::MFHI, ATReg, IDLoc, STI);
5227 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5229 TOut.
emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);
5236 TOut.
emitRRX(Mips::BEQ, ATReg, Mips::ZERO, LabelOp, IDLoc, STI);
5237 if (AssemblerOptions.
back()->isReorder())
5239 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5247bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5248 const MCSubtargetInfo *STI) {
5249 MipsTargetStreamer &TOut = getTargetStreamer();
5254 TOut.
emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
5255 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5265bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
5267 const MCSubtargetInfo *STI,
5272 warnIfNoMacro(IDLoc);
5274 MipsTargetStreamer &TOut = getTargetStreamer();
5275 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
5277 MCRegister SecondReg =
nextReg(FirstReg);
5282 warnIfRegIndexIsAT(FirstReg, IDLoc);
5285 "Offset for load macro is not immediate!");
5288 signed NextOffset = FirstOffset.
getImm() + 4;
5296 if (FirstReg != BaseReg || !IsLoad) {
5297 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5298 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5300 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5301 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5313bool MipsAsmParser::expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc,
5315 const MCSubtargetInfo *STI) {
5319 warnIfNoMacro(IDLoc);
5321 MipsTargetStreamer &TOut = getTargetStreamer();
5322 unsigned Opcode = Mips::SWC1;
5324 MCRegister SecondReg =
nextReg(FirstReg);
5329 warnIfRegIndexIsAT(FirstReg, IDLoc);
5332 "Offset for macro is not immediate!");
5335 signed NextOffset = FirstOffset.
getImm() + 4;
5341 if (!IsLittleEndian)
5344 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5345 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5350bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5351 const MCSubtargetInfo *STI) {
5352 MipsTargetStreamer &TOut = getTargetStreamer();
5363 warnIfNoMacro(IDLoc);
5365 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5366 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5367 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5371 MCRegister
Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5372 TOut.
emitRRI(Mips::SLTiu, DstReg,
Reg, 1, IDLoc, STI);
5376bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5377 const MCSubtargetInfo *STI) {
5378 MipsTargetStreamer &TOut = getTargetStreamer();
5389 warnIfNoMacro(IDLoc);
5392 TOut.
emitRRI(Mips::SLTiu, DstReg, SrcReg, 1, IDLoc, STI);
5396 if (SrcReg == Mips::ZERO) {
5397 Warning(IDLoc,
"comparison is always false");
5398 TOut.
emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
5399 DstReg, SrcReg, SrcReg, IDLoc, STI);
5404 if (Imm > -0x8000 && Imm < 0) {
5406 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5412 MCRegister ATReg = getATReg(IDLoc);
5416 if (loadImmediate(Imm, ATReg, MCRegister(),
true, isGP64bit(), IDLoc, Out,
5420 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5421 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5425 TOut.
emitRRI(
Opc, DstReg, SrcReg, Imm, IDLoc, STI);
5426 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5430bool MipsAsmParser::expandSne(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5431 const MCSubtargetInfo *STI) {
5433 MipsTargetStreamer &TOut = getTargetStreamer();
5444 warnIfNoMacro(IDLoc);
5446 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5447 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5448 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5452 MCRegister
Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5453 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO,
Reg, IDLoc, STI);
5457bool MipsAsmParser::expandSneI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5458 const MCSubtargetInfo *STI) {
5459 MipsTargetStreamer &TOut = getTargetStreamer();
5470 warnIfNoMacro(IDLoc);
5472 if (ImmValue == 0) {
5473 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, SrcReg, IDLoc, STI);
5477 if (SrcReg == Mips::ZERO) {
5478 Warning(IDLoc,
"comparison is always true");
5479 if (loadImmediate(1, DstReg, MCRegister(),
true,
false, IDLoc, Out, STI))
5485 if (ImmValue > -0x8000 && ImmValue < 0) {
5486 ImmValue = -ImmValue;
5487 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5493 TOut.
emitRRI(
Opc, DstReg, SrcReg, ImmValue, IDLoc, STI);
5494 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5498 MCRegister ATReg = getATReg(IDLoc);
5502 if (loadImmediate(ImmValue, ATReg, MCRegister(),
isInt<32>(ImmValue),
false,
5506 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5507 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5570 case Mips::F0:
return Mips::ZERO;
5571 case Mips::F1:
return Mips::AT;
5572 case Mips::F2:
return Mips::V0;
5573 case Mips::F3:
return Mips::V1;
5574 case Mips::F4:
return Mips::A0;
5575 case Mips::F5:
return Mips::A1;
5576 case Mips::F6:
return Mips::A2;
5577 case Mips::F7:
return Mips::A3;
5578 case Mips::F8:
return Mips::T0;
5579 case Mips::F9:
return Mips::T1;
5580 case Mips::F10:
return Mips::T2;
5581 case Mips::F11:
return Mips::T3;
5582 case Mips::F12:
return Mips::T4;
5583 case Mips::F13:
return Mips::T5;
5584 case Mips::F14:
return Mips::T6;
5585 case Mips::F15:
return Mips::T7;
5586 case Mips::F16:
return Mips::S0;
5587 case Mips::F17:
return Mips::S1;
5588 case Mips::F18:
return Mips::S2;
5589 case Mips::F19:
return Mips::S3;
5590 case Mips::F20:
return Mips::S4;
5591 case Mips::F21:
return Mips::S5;
5592 case Mips::F22:
return Mips::S6;
5593 case Mips::F23:
return Mips::S7;
5594 case Mips::F24:
return Mips::T8;
5595 case Mips::F25:
return Mips::T9;
5596 case Mips::F26:
return Mips::K0;
5597 case Mips::F27:
return Mips::K1;
5598 case Mips::F28:
return Mips::GP;
5599 case Mips::F29:
return Mips::SP;
5600 case Mips::F30:
return Mips::FP;
5601 case Mips::F31:
return Mips::RA;
5609 case Mips::COP00:
return Mips::ZERO;
5610 case Mips::COP01:
return Mips::AT;
5611 case Mips::COP02:
return Mips::V0;
5612 case Mips::COP03:
return Mips::V1;
5613 case Mips::COP04:
return Mips::A0;
5614 case Mips::COP05:
return Mips::A1;
5615 case Mips::COP06:
return Mips::A2;
5616 case Mips::COP07:
return Mips::A3;
5617 case Mips::COP08:
return Mips::T0;
5618 case Mips::COP09:
return Mips::T1;
5619 case Mips::COP010:
return Mips::T2;
5620 case Mips::COP011:
return Mips::T3;
5621 case Mips::COP012:
return Mips::T4;
5622 case Mips::COP013:
return Mips::T5;
5623 case Mips::COP014:
return Mips::T6;
5624 case Mips::COP015:
return Mips::T7;
5625 case Mips::COP016:
return Mips::S0;
5626 case Mips::COP017:
return Mips::S1;
5627 case Mips::COP018:
return Mips::S2;
5628 case Mips::COP019:
return Mips::S3;
5629 case Mips::COP020:
return Mips::S4;
5630 case Mips::COP021:
return Mips::S5;
5631 case Mips::COP022:
return Mips::S6;
5632 case Mips::COP023:
return Mips::S7;
5633 case Mips::COP024:
return Mips::T8;
5634 case Mips::COP025:
return Mips::T9;
5635 case Mips::COP026:
return Mips::K0;
5636 case Mips::COP027:
return Mips::K1;
5637 case Mips::COP028:
return Mips::GP;
5638 case Mips::COP029:
return Mips::SP;
5639 case Mips::COP030:
return Mips::FP;
5640 case Mips::COP031:
return Mips::RA;
5647bool MipsAsmParser::expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5648 const MCSubtargetInfo *STI) {
5649 MipsTargetStreamer &TOut = getTargetStreamer();
5654 bool IsMFTR =
false;
5708 IsMFTR ? MCRegister(rd)
5710 : Inst.getOperand(0).
getReg());
5712 TOut.
emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, u, sel, h, IDLoc,
5717bool MipsAsmParser::expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5718 const MCSubtargetInfo *STI) {
5723 warnIfNoMacro(IDLoc);
5725 MipsTargetStreamer &TOut = getTargetStreamer();
5726 unsigned Opcode = Inst.
getOpcode() == Mips::SaaAddr ? Mips::SAA : Mips::SAAD;
5729 const MCOperand &BaseOp = Inst.
getOperand(2);
5731 if (BaseOp.
isImm()) {
5732 int64_t ImmValue = BaseOp.
getImm();
5733 if (ImmValue == 0) {
5734 TOut.
emitRR(Opcode, RtReg, BaseReg, IDLoc, STI);
5739 MCRegister ATReg = getATReg(IDLoc);
5743 if (expandLoadAddress(ATReg, BaseReg, BaseOp, !isGP64bit(), IDLoc, Out, STI))
5746 TOut.
emitRR(Opcode, RtReg, ATReg, IDLoc, STI);
5751MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
5755 return Match_Success;
5758 if (
static_cast<MipsOperand &
>(*Operands[1])
5759 .isValidForTie(
static_cast<MipsOperand &
>(*Operands[2])))
5760 return Match_Success;
5761 return Match_RequiresSameSrcAndDst;
5765unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
5772 return Match_RequiresNoZeroRegister;
5773 return Match_Success;
5779 case Mips::JALR_HB64:
5780 case Mips::JALRC_HB_MMR6:
5781 case Mips::JALRC_MMR6:
5783 return Match_RequiresDifferentSrcAndDst;
5784 return Match_Success;
5787 return Match_RequiresDifferentSrcAndDst;
5788 return Match_Success;
5791 return Match_NonZeroOperandForSync;
5792 return Match_Success;
5798 return Match_NonZeroOperandForMTCX;
5799 return Match_Success;
5812 case Mips::BLEZC:
case Mips::BLEZC_MMR6:
5813 case Mips::BGEZC:
case Mips::BGEZC_MMR6:
5814 case Mips::BGTZC:
case Mips::BGTZC_MMR6:
5815 case Mips::BLTZC:
case Mips::BLTZC_MMR6:
5816 case Mips::BEQZC:
case Mips::BEQZC_MMR6:
5817 case Mips::BNEZC:
case Mips::BNEZC_MMR6:
5826 return Match_RequiresNoZeroRegister;
5827 return Match_Success;
5828 case Mips::BGEC:
case Mips::BGEC_MMR6:
5829 case Mips::BLTC:
case Mips::BLTC_MMR6:
5830 case Mips::BGEUC:
case Mips::BGEUC_MMR6:
5831 case Mips::BLTUC:
case Mips::BLTUC_MMR6:
5832 case Mips::BEQC:
case Mips::BEQC_MMR6:
5833 case Mips::BNEC:
case Mips::BNEC_MMR6:
5842 return Match_RequiresNoZeroRegister;
5845 return Match_RequiresNoZeroRegister;
5847 return Match_RequiresDifferentOperands;
5848 return Match_Success;
5851 "Operands must be immediates for dins!");
5854 if ((0 > (Pos +
Size)) || ((Pos +
Size) > 32))
5855 return Match_RequiresPosSizeRange0_32;
5856 return Match_Success;
5861 "Operands must be immediates for dinsm/dinsu!");
5864 if ((32 >= (Pos +
Size)) || ((Pos +
Size) > 64))
5865 return Match_RequiresPosSizeRange33_64;
5866 return Match_Success;
5870 "Operands must be immediates for DEXTM!");
5873 if ((1 > (Pos +
Size)) || ((Pos +
Size) > 63))
5874 return Match_RequiresPosSizeUImm6;
5875 return Match_Success;
5880 "Operands must be immediates for dextm/dextu!");
5883 if ((32 > (Pos +
Size)) || ((Pos +
Size) > 64))
5884 return Match_RequiresPosSizeRange33_64;
5885 return Match_Success;
5887 case Mips::CRC32B:
case Mips::CRC32CB:
5888 case Mips::CRC32H:
case Mips::CRC32CH:
5889 case Mips::CRC32W:
case Mips::CRC32CW:
5890 case Mips::CRC32D:
case Mips::CRC32CD:
5892 return Match_RequiresSameSrcAndDst;
5893 return Match_Success;
5896 uint64_t TSFlags = MII.get(Inst.
getOpcode()).TSFlags;
5899 return Match_NoFCCRegisterForCurrentISA;
5901 return Match_Success;
5909 if (ErrorLoc ==
SMLoc())
5916bool MipsAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
5919 uint64_t &ErrorInfo,
5920 bool MatchingInlineAsm) {
5922 unsigned MatchResult =
5923 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
5925 switch (MatchResult) {
5927 if (processInstruction(Inst, IDLoc, Out, STI))
5930 case Match_MissingFeature:
5931 Error(IDLoc,
"instruction requires a CPU feature not currently enabled");
5933 case Match_InvalidTiedOperand:
5934 Error(IDLoc,
"operand must match destination register");
5936 case Match_InvalidOperand: {
5937 SMLoc ErrorLoc = IDLoc;
5938 if (ErrorInfo != ~0ULL) {
5939 if (ErrorInfo >= Operands.
size())
5940 return Error(IDLoc,
"too few operands for instruction");
5942 ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5943 if (ErrorLoc == SMLoc())
5947 return Error(ErrorLoc,
"invalid operand for instruction");
5949 case Match_NonZeroOperandForSync:
5951 "s-type must be zero or unspecified for pre-MIPS32 ISAs");
5952 case Match_NonZeroOperandForMTCX:
5953 return Error(IDLoc,
"selector must be zero for pre-MIPS32 ISAs");
5954 case Match_MnemonicFail:
5955 return Error(IDLoc,
"invalid instruction");
5956 case Match_RequiresDifferentSrcAndDst:
5957 return Error(IDLoc,
"source and destination must be different");
5958 case Match_RequiresDifferentOperands:
5959 return Error(IDLoc,
"registers must be different");
5960 case Match_RequiresNoZeroRegister:
5961 return Error(IDLoc,
"invalid operand ($zero) for instruction");
5962 case Match_RequiresSameSrcAndDst:
5963 return Error(IDLoc,
"source and destination must match");
5964 case Match_NoFCCRegisterForCurrentISA:
5966 "non-zero fcc register doesn't exist in current ISA level");
5971 "expected 1-bit unsigned immediate");
5974 "expected 2-bit unsigned immediate");
5977 "expected immediate in range 1 .. 4");
5980 "expected 3-bit unsigned immediate");
5983 "expected 4-bit unsigned immediate");
5986 "expected 4-bit signed immediate");
5989 "expected 5-bit unsigned immediate");
5992 "expected 5-bit signed immediate");
5995 "expected immediate in range 1 .. 32");
5996 case Match_UImm5_32:
5998 "expected immediate in range 32 .. 63");
5999 case Match_UImm5_33:
6001 "expected immediate in range 33 .. 64");
6002 case Match_UImm5_0_Report_UImm6:
6006 "expected 6-bit unsigned immediate");
6007 case Match_UImm5_Lsl2:
6009 "expected both 7-bit unsigned immediate and multiple of 4");
6010 case Match_UImmRange2_64:
6012 "expected immediate in range 2 .. 64");
6015 "expected 6-bit unsigned immediate");
6016 case Match_UImm6_Lsl2:
6018 "expected both 8-bit unsigned immediate and multiple of 4");
6021 "expected 6-bit signed immediate");
6024 "expected 7-bit unsigned immediate");
6025 case Match_UImm7_N1:
6027 "expected immediate in range -1 .. 126");
6028 case Match_SImm7_Lsl2:
6030 "expected both 9-bit signed immediate and multiple of 4");
6033 "expected 8-bit unsigned immediate");
6034 case Match_UImm10_0:
6036 "expected 10-bit unsigned immediate");
6037 case Match_SImm10_0:
6039 "expected 10-bit signed immediate");
6040 case Match_SImm11_0:
6042 "expected 11-bit signed immediate");
6044 case Match_UImm16_Relaxed:
6045 case Match_UImm16_AltRelaxed:
6047 "expected 16-bit unsigned immediate");
6049 case Match_SImm16_Relaxed:
6051 "expected 16-bit signed immediate");
6052 case Match_SImm18_Lsl3:
6054 "expected both 18-bit signed immediate and multiple of 8");
6055 case Match_SImm19_Lsl2:
6057 "expected both 19-bit signed immediate and multiple of 4");
6058 case Match_UImm20_0:
6060 "expected 20-bit unsigned immediate");
6061 case Match_UImm26_0:
6063 "expected 26-bit unsigned immediate");
6065 case Match_SImm32_Relaxed:
6067 "expected 32-bit signed immediate");
6068 case Match_UImm32_Coerced:
6070 "expected 32-bit immediate");
6071 case Match_MemSImm9:
6073 "expected memory with 9-bit signed offset");
6074 case Match_MemSImm10:
6076 "expected memory with 10-bit signed offset");
6077 case Match_MemSImm10Lsl1:
6079 "expected memory with 11-bit signed offset and multiple of 2");
6080 case Match_MemSImm10Lsl2:
6082 "expected memory with 12-bit signed offset and multiple of 4");
6083 case Match_MemSImm10Lsl3:
6085 "expected memory with 13-bit signed offset and multiple of 8");
6086 case Match_MemSImm11:
6088 "expected memory with 11-bit signed offset");
6089 case Match_MemSImm12:
6091 "expected memory with 12-bit signed offset");
6092 case Match_MemSImm16:
6094 "expected memory with 16-bit signed offset");
6095 case Match_MemSImmPtr:
6097 "expected memory with 32-bit signed offset");
6098 case Match_RequiresPosSizeRange0_32: {
6099 SMLoc ErrorStart = Operands[3]->getStartLoc();
6100 SMLoc ErrorEnd = Operands[4]->getEndLoc();
6101 return Error(ErrorStart,
"size plus position are not in the range 0 .. 32",
6102 SMRange(ErrorStart, ErrorEnd));
6104 case Match_RequiresPosSizeUImm6: {
6105 SMLoc ErrorStart = Operands[3]->getStartLoc();
6106 SMLoc ErrorEnd = Operands[4]->getEndLoc();
6107 return Error(ErrorStart,
"size plus position are not in the range 1 .. 63",
6108 SMRange(ErrorStart, ErrorEnd));
6110 case Match_RequiresPosSizeRange33_64: {
6111 SMLoc ErrorStart = Operands[3]->getStartLoc();
6112 SMLoc ErrorEnd = Operands[4]->getEndLoc();
6113 return Error(ErrorStart,
"size plus position are not in the range 33 .. 64",
6114 SMRange(ErrorStart, ErrorEnd));
6121void MipsAsmParser::warnIfRegIndexIsAT(MCRegister RegIndex, SMLoc Loc) {
6122 if (RegIndex && AssemblerOptions.
back()->getATRegIndex() == RegIndex)
6123 Warning(Loc,
"used $at (currently $" + Twine(RegIndex.
id()) +
6124 ") without \".set noat\"");
6127void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
6128 if (!AssemblerOptions.
back()->isMacro())
6129 Warning(Loc,
"macro instruction expanded into multiple instructions");
6132void MipsAsmParser::ConvertXWPOperands(MCInst &Inst,
6136 "Unexpected instruction!");
6137 ((MipsOperand &)*Operands[1]).addGPR32ZeroAsmRegOperands(Inst, 1);
6138 MCRegister NextReg =
nextReg(((MipsOperand &)*Operands[1]).getGPR32Reg());
6140 ((MipsOperand &)*Operands[2]).addMemOperands(Inst, 2);
6144MipsAsmParser::printWarningWithFixIt(
const Twine &Msg,
const Twine &FixMsg,
6145 SMRange
Range,
bool ShowColors) {
6151int MipsAsmParser::matchCPURegisterName(StringRef Name) {
6154 CC = StringSwitch<unsigned>(Name)
6156 .Cases({
"at",
"AT"}, 1)
6190 if (!(isABI_N32() || isABI_N64()))
6193 if (12 <= CC && CC <= 15) {
6195 AsmToken RegTok = getLexer().peekTok();
6198 StringRef FixedName = StringSwitch<StringRef>(Name)
6204 assert(FixedName !=
"" &&
"Register name is not one of t4-t7.");
6206 printWarningWithFixIt(
"register names $t4-$t7 are only available in O32.",
6207 "Did you mean $" + FixedName +
"?", RegRange);
6213 if (8 <= CC && CC <= 11)
6217 CC = StringSwitch<unsigned>(Name)
6229int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
6232 CC = StringSwitch<unsigned>(Name)
6233 .Case(
"hwr_cpunum", 0)
6234 .Case(
"hwr_synci_step", 1)
6236 .Case(
"hwr_ccres", 3)
6237 .Case(
"hwr_ulr", 29)
6243int MipsAsmParser::matchFPURegisterName(StringRef Name) {
6244 if (Name[0] ==
'f') {
6245 StringRef NumString =
Name.substr(1);
6256int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
6257 if (
Name.starts_with(
"fcc")) {
6258 StringRef NumString =
Name.substr(3);
6269int MipsAsmParser::matchACRegisterName(StringRef Name) {
6270 if (
Name.starts_with(
"ac")) {
6271 StringRef NumString =
Name.substr(2);
6282int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
6285 if (
Name.front() !=
'w' ||
Name.drop_front(1).getAsInteger(10, IntVal))
6294int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
6297 CC = StringSwitch<unsigned>(Name)
6300 .Case(
"msaaccess", 2)
6302 .Case(
"msamodify", 4)
6303 .Case(
"msarequest", 5)
6305 .Case(
"msaunmap", 7)
6311bool MipsAsmParser::canUseATReg() {
6312 return AssemblerOptions.
back()->getATRegIndex() != 0;
6315MCRegister MipsAsmParser::getATReg(SMLoc Loc) {
6316 unsigned ATIndex = AssemblerOptions.
back()->getATRegIndex();
6318 reportParseError(Loc,
6319 "pseudo-instruction requires $at, which is not available");
6323 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
6327MCRegister MipsAsmParser::getReg(
int RC,
int RegNo) {
6328 return getContext().getRegisterInfo()->getRegClass(RC).getRegister(RegNo);
6334const MCExpr *MipsAsmParser::parseRelocExpr() {
6335 auto getOp = [](StringRef
Op) {
6336 return StringSwitch<Mips::Specifier>(
Op)
6364 MCAsmParser &Parser = getParser();
6366 const MCExpr *Res =
nullptr;
6372 auto Op = getOp(Name);
6381 while (
Ops.size()) {
6389bool MipsAsmParser::parseOperand(
OperandVector &Operands, StringRef Mnemonic) {
6390 MCAsmParser &Parser = getParser();
6400 ParseStatus Res = MatchOperandParserImpl(Operands, Mnemonic,
true);
6411 switch (getLexer().getKind()) {
6421 if (!parseAnyRegister(Operands).isNoMatch())
6434 Operands.
push_back(MipsOperand::CreateImm(SymRef, S,
E, *
this));
6439 const MCExpr *Expr = parseRelocExpr();
6443 Operands.
push_back(MipsOperand::CreateImm(Expr, S,
E, *
this));
6450bool MipsAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
6452 return !tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess();
6455ParseStatus MipsAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
6458 ParseStatus Res = parseAnyRegister(Operands);
6461 MipsOperand &Operand =
static_cast<MipsOperand &
>(*Operands.
front());
6462 StartLoc = Operand.getStartLoc();
6463 EndLoc = Operand.getEndLoc();
6469 if (Operand.isGPRAsmReg()) {
6471 Reg = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
6481ParseStatus MipsAsmParser::parseMemOperand(
OperandVector &Operands) {
6482 MCAsmParser &Parser = getParser();
6484 const MCExpr *IdVal =
nullptr;
6486 bool isParenExpr =
false;
6497 IdVal = parseRelocExpr();
6503 const AsmToken &Tok = Parser.
getTok();
6505 MipsOperand &Mnemonic =
static_cast<MipsOperand &
>(*Operands[0]);
6506 if (Mnemonic.getToken() ==
"la" || Mnemonic.getToken() ==
"dla") {
6509 Operands.
push_back(MipsOperand::CreateImm(IdVal, S,
E, *
this));
6518 auto Base = MipsOperand::createGPRReg(
6519 0,
"0",
getContext().getRegisterInfo(), S,
E, *
this);
6521 MipsOperand::CreateMem(std::move(
Base), IdVal, S,
E, *
this));
6573 const MCExpr * NextExpr;
6574 if (getParser().parseExpression(NextExpr))
6582 Res = parseAnyRegister(Operands);
6597 std::unique_ptr<MipsOperand>
op(
6598 static_cast<MipsOperand *
>(Operands.
back().release()));
6605 if (IdVal->evaluateAsAbsolute(Imm))
6612 Operands.
push_back(MipsOperand::CreateMem(std::move(
op), IdVal, S,
E, *
this));
6616bool MipsAsmParser::searchSymbolAlias(
OperandVector &Operands) {
6617 MCAsmParser &Parser = getParser();
6626 const MCSymbolRefExpr *
Ref =
static_cast<const MCSymbolRefExpr *
>(Expr);
6627 StringRef DefSymbol =
Ref->getSymbol().getName();
6630 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.
substr(1), S);
6644 if (Entry != RegisterSets.
end()) {
6646 matchAnyRegisterWithoutDollar(Operands,
Entry->getValue(), S);
6657ParseStatus MipsAsmParser::matchAnyRegisterNameWithoutDollar(
6659 int Index = matchCPURegisterName(Identifier);
6661 Operands.
push_back(MipsOperand::createGPRReg(
6662 Index, Identifier,
getContext().getRegisterInfo(), S,
6663 getLexer().getLoc(), *
this));
6667 Index = matchHWRegsRegisterName(Identifier);
6669 Operands.
push_back(MipsOperand::createHWRegsReg(
6670 Index, Identifier,
getContext().getRegisterInfo(), S,
6671 getLexer().getLoc(), *
this));
6675 Index = matchFPURegisterName(Identifier);
6677 Operands.
push_back(MipsOperand::createFGRReg(
6678 Index, Identifier,
getContext().getRegisterInfo(), S,
6679 getLexer().getLoc(), *
this));
6683 Index = matchFCCRegisterName(Identifier);
6685 Operands.
push_back(MipsOperand::createFCCReg(
6686 Index, Identifier,
getContext().getRegisterInfo(), S,
6687 getLexer().getLoc(), *
this));
6691 Index = matchACRegisterName(Identifier);
6693 Operands.
push_back(MipsOperand::createACCReg(
6694 Index, Identifier,
getContext().getRegisterInfo(), S,
6695 getLexer().getLoc(), *
this));
6699 Index = matchMSA128RegisterName(Identifier);
6701 Operands.
push_back(MipsOperand::createMSA128Reg(
6702 Index, Identifier,
getContext().getRegisterInfo(), S,
6703 getLexer().getLoc(), *
this));
6707 Index = matchMSA128CtrlRegisterName(Identifier);
6709 Operands.
push_back(MipsOperand::createMSACtrlReg(
6710 Index, Identifier,
getContext().getRegisterInfo(), S,
6711 getLexer().getLoc(), *
this));
6719MipsAsmParser::matchAnyRegisterWithoutDollar(
OperandVector &Operands,
6720 const AsmToken &Token, SMLoc S) {
6724 return matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
6729 if (RegNum < 0 || RegNum > 31) {
6733 Error(getLexer().getLoc(),
"invalid register number");
6735 Operands.
push_back(MipsOperand::createNumericReg(
6747MipsAsmParser::matchAnyRegisterWithoutDollar(
OperandVector &Operands, SMLoc S) {
6748 auto Token = getLexer().peekTok(
false);
6749 return matchAnyRegisterWithoutDollar(Operands, Token, S);
6752ParseStatus MipsAsmParser::parseAnyRegister(
OperandVector &Operands) {
6753 MCAsmParser &Parser = getParser();
6756 auto Token = Parser.
getTok();
6758 SMLoc S = Token.
getLoc();
6763 if (searchSymbolAlias(Operands))
6771 ParseStatus Res = matchAnyRegisterWithoutDollar(Operands, S);
6779ParseStatus MipsAsmParser::parseJumpTarget(
OperandVector &Operands) {
6780 MCAsmParser &Parser = getParser();
6783 SMLoc S = getLexer().getLoc();
6786 ParseStatus Res = parseAnyRegister(Operands);
6791 const MCExpr *Expr =
nullptr;
6797 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *
this));
6801ParseStatus MipsAsmParser::parseInvNum(
OperandVector &Operands) {
6802 MCAsmParser &Parser = getParser();
6803 const MCExpr *IdVal;
6814 if (getParser().parseExpression(IdVal))
6821 Operands.
push_back(MipsOperand::CreateImm(
6826ParseStatus MipsAsmParser::parseRegisterList(
OperandVector &Operands) {
6827 MCAsmParser &Parser = getParser();
6831 bool RegRange =
false;
6838 while (parseAnyRegister(TmpOperands).isSuccess()) {
6839 SMLoc
E = getLexer().getLoc();
6840 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*TmpOperands.
back());
6841 Reg = isGP64bit() ? RegOpnd.getGPR64Reg() : RegOpnd.getGPR32Reg();
6845 if ((isGP64bit() &&
Reg == Mips::RA_64) ||
6846 (!isGP64bit() &&
Reg == Mips::RA)) {
6849 MCRegister TmpReg = PrevReg + 1;
6850 while (TmpReg <=
Reg) {
6851 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
6852 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
6854 return Error(
E,
"invalid register operand");
6858 TmpReg = TmpReg.
id() + 1;
6865 ((isGP64bit() && (
Reg != Mips::S0_64) && (
Reg != Mips::RA_64)) ||
6866 (!isGP64bit() && (
Reg != Mips::S0) && (
Reg != Mips::RA))))
6867 return Error(
E,
"$16 or $31 expected");
6868 if (!(((
Reg == Mips::FP ||
Reg == Mips::RA ||
6869 (
Reg >= Mips::S0 &&
Reg <= Mips::S7)) &&
6871 ((
Reg == Mips::FP_64 ||
Reg == Mips::RA_64 ||
6872 (
Reg >= Mips::S0_64 &&
Reg <= Mips::S7_64)) &&
6874 return Error(
E,
"invalid register operand");
6875 if (PrevReg.
isValid() && (
Reg != PrevReg + 1) &&
6876 ((
Reg != Mips::FP &&
Reg != Mips::RA && !isGP64bit()) ||
6877 (
Reg != Mips::FP_64 &&
Reg != Mips::RA_64 && isGP64bit())))
6878 return Error(
E,
"consecutive register numbers expected");
6888 return Error(
E,
"',' or '-' expected");
6898 Operands.
push_back(MipsOperand::CreateRegList(Regs, S,
E, *
this));
6899 parseMemOperand(Operands);
6908bool MipsAsmParser::parseParenSuffix(StringRef Name,
OperandVector &Operands) {
6909 MCAsmParser &Parser = getParser();
6912 MipsOperand::CreateToken(
"(", getLexer().getLoc(), *
this));
6914 if (parseOperand(Operands, Name)) {
6915 SMLoc Loc = getLexer().getLoc();
6916 return Error(Loc,
"unexpected token in argument list");
6919 SMLoc Loc = getLexer().getLoc();
6920 return Error(Loc,
"unexpected token, expected ')'");
6923 MipsOperand::CreateToken(
")", getLexer().getLoc(), *
this));
6935bool MipsAsmParser::parseBracketSuffix(StringRef Name,
6937 MCAsmParser &Parser = getParser();
6940 MipsOperand::CreateToken(
"[", getLexer().getLoc(), *
this));
6942 if (parseOperand(Operands, Name)) {
6943 SMLoc Loc = getLexer().getLoc();
6944 return Error(Loc,
"unexpected token in argument list");
6947 SMLoc Loc = getLexer().getLoc();
6948 return Error(Loc,
"unexpected token, expected ']'");
6951 MipsOperand::CreateToken(
"]", getLexer().getLoc(), *
this));
6958 unsigned VariantID = 0);
6973bool MipsAsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
6975 MCAsmParser &Parser = getParser();
6979 getTargetStreamer().forbidModuleDirective();
6982 if (!mnemonicIsValid(Name, 0)) {
6983 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
6985 return Error(NameLoc,
"unknown instruction" + Suggestion);
6988 Operands.
push_back(MipsOperand::CreateToken(Name, NameLoc, *
this));
6993 if (parseOperand(Operands, Name)) {
6994 SMLoc Loc = getLexer().getLoc();
6995 return Error(Loc,
"unexpected token in argument list");
6997 if (getLexer().is(
AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
7004 if (parseOperand(Operands, Name)) {
7005 SMLoc Loc = getLexer().getLoc();
7006 return Error(Loc,
"unexpected token in argument list");
7010 if (parseBracketSuffix(Name, Operands))
7013 parseParenSuffix(Name, Operands))
7018 SMLoc Loc = getLexer().getLoc();
7019 return Error(Loc,
"unexpected token in argument list");
7027bool MipsAsmParser::reportParseError(
const Twine &ErrorMsg) {
7028 SMLoc Loc = getLexer().getLoc();
7029 return Error(Loc, ErrorMsg);
7032bool MipsAsmParser::reportParseError(SMLoc Loc,
const Twine &ErrorMsg) {
7033 return Error(Loc, ErrorMsg);
7036bool MipsAsmParser::parseSetNoAtDirective() {
7037 MCAsmParser &Parser = getParser();
7041 AssemblerOptions.
back()->setATRegIndex(0);
7047 reportParseError(
"unexpected token, expected end of statement");
7051 getTargetStreamer().emitDirectiveSetNoAt();
7056bool MipsAsmParser::parseSetAtDirective() {
7059 MCAsmParser &Parser = getParser();
7064 AssemblerOptions.
back()->setATRegIndex(1);
7066 getTargetStreamer().emitDirectiveSetAt();
7072 reportParseError(
"unexpected token, expected equals sign");
7079 reportParseError(
"no register specified");
7082 reportParseError(
"unexpected token, expected dollar sign '$'");
7092 AtRegNo = matchCPURegisterName(
Reg.getIdentifier());
7094 AtRegNo =
Reg.getIntVal();
7096 reportParseError(
"unexpected token, expected identifier or integer");
7101 if (!AssemblerOptions.
back()->setATRegIndex(AtRegNo)) {
7102 reportParseError(
"invalid register");
7109 reportParseError(
"unexpected token, expected end of statement");
7113 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
7119bool MipsAsmParser::parseSetReorderDirective() {
7120 MCAsmParser &Parser = getParser();
7124 reportParseError(
"unexpected token, expected end of statement");
7127 AssemblerOptions.
back()->setReorder();
7128 getTargetStreamer().emitDirectiveSetReorder();
7133bool MipsAsmParser::parseSetNoReorderDirective() {
7134 MCAsmParser &Parser = getParser();
7138 reportParseError(
"unexpected token, expected end of statement");
7141 AssemblerOptions.
back()->setNoReorder();
7142 getTargetStreamer().emitDirectiveSetNoReorder();
7147bool MipsAsmParser::parseSetMacroDirective() {
7148 MCAsmParser &Parser = getParser();
7152 reportParseError(
"unexpected token, expected end of statement");
7155 AssemblerOptions.
back()->setMacro();
7156 getTargetStreamer().emitDirectiveSetMacro();
7161bool MipsAsmParser::parseSetNoMacroDirective() {
7162 MCAsmParser &Parser = getParser();
7166 reportParseError(
"unexpected token, expected end of statement");
7169 if (AssemblerOptions.
back()->isReorder()) {
7170 reportParseError(
"`noreorder' must be set before `nomacro'");
7173 AssemblerOptions.
back()->setNoMacro();
7174 getTargetStreamer().emitDirectiveSetNoMacro();
7179bool MipsAsmParser::parseSetMsaDirective() {
7180 MCAsmParser &Parser = getParser();
7185 return reportParseError(
"unexpected token, expected end of statement");
7187 setFeatureBits(Mips::FeatureMSA,
"msa");
7188 getTargetStreamer().emitDirectiveSetMsa();
7192bool MipsAsmParser::parseSetNoMsaDirective() {
7193 MCAsmParser &Parser = getParser();
7198 return reportParseError(
"unexpected token, expected end of statement");
7200 clearFeatureBits(Mips::FeatureMSA,
"msa");
7201 getTargetStreamer().emitDirectiveSetNoMsa();
7205bool MipsAsmParser::parseSetNoDspDirective() {
7206 MCAsmParser &Parser = getParser();
7211 reportParseError(
"unexpected token, expected end of statement");
7215 clearFeatureBits(Mips::FeatureDSP,
"dsp");
7216 getTargetStreamer().emitDirectiveSetNoDsp();
7220bool MipsAsmParser::parseSetNoMips3DDirective() {
7221 MCAsmParser &Parser = getParser();
7226 reportParseError(
"unexpected token, expected end of statement");
7230 clearFeatureBits(Mips::FeatureMips3D,
"mips3d");
7231 getTargetStreamer().emitDirectiveSetNoMips3D();
7235bool MipsAsmParser::parseSetMips16Directive() {
7236 MCAsmParser &Parser = getParser();
7241 reportParseError(
"unexpected token, expected end of statement");
7245 setFeatureBits(Mips::FeatureMips16,
"mips16");
7246 getTargetStreamer().emitDirectiveSetMips16();
7251bool MipsAsmParser::parseSetNoMips16Directive() {
7252 MCAsmParser &Parser = getParser();
7257 reportParseError(
"unexpected token, expected end of statement");
7261 clearFeatureBits(Mips::FeatureMips16,
"mips16");
7262 getTargetStreamer().emitDirectiveSetNoMips16();
7267bool MipsAsmParser::parseSetFpDirective() {
7268 MCAsmParser &Parser = getParser();
7274 AsmToken Tok = Parser.
getTok();
7276 reportParseError(
"unexpected token, expected equals sign '='");
7282 if (!parseFpABIValue(FpAbiVal,
".set"))
7286 reportParseError(
"unexpected token, expected end of statement");
7289 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
7294bool MipsAsmParser::parseSetOddSPRegDirective() {
7295 MCAsmParser &Parser = getParser();
7299 reportParseError(
"unexpected token, expected end of statement");
7303 clearFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
7304 getTargetStreamer().emitDirectiveSetOddSPReg();
7308bool MipsAsmParser::parseSetNoOddSPRegDirective() {
7309 MCAsmParser &Parser = getParser();
7313 reportParseError(
"unexpected token, expected end of statement");
7317 setFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
7318 getTargetStreamer().emitDirectiveSetNoOddSPReg();
7322bool MipsAsmParser::parseSetMtDirective() {
7323 MCAsmParser &Parser = getParser();
7328 reportParseError(
"unexpected token, expected end of statement");
7332 setFeatureBits(Mips::FeatureMT,
"mt");
7333 getTargetStreamer().emitDirectiveSetMt();
7338bool MipsAsmParser::parseSetNoMtDirective() {
7339 MCAsmParser &Parser = getParser();
7344 reportParseError(
"unexpected token, expected end of statement");
7348 clearFeatureBits(Mips::FeatureMT,
"mt");
7350 getTargetStreamer().emitDirectiveSetNoMt();
7355bool MipsAsmParser::parseSetNoCRCDirective() {
7356 MCAsmParser &Parser = getParser();
7361 reportParseError(
"unexpected token, expected end of statement");
7365 clearFeatureBits(Mips::FeatureCRC,
"crc");
7367 getTargetStreamer().emitDirectiveSetNoCRC();
7372bool MipsAsmParser::parseSetNoVirtDirective() {
7373 MCAsmParser &Parser = getParser();
7378 reportParseError(
"unexpected token, expected end of statement");
7382 clearFeatureBits(Mips::FeatureVirt,
"virt");
7384 getTargetStreamer().emitDirectiveSetNoVirt();
7389bool MipsAsmParser::parseSetNoGINVDirective() {
7390 MCAsmParser &Parser = getParser();
7395 reportParseError(
"unexpected token, expected end of statement");
7399 clearFeatureBits(Mips::FeatureGINV,
"ginv");
7401 getTargetStreamer().emitDirectiveSetNoGINV();
7406bool MipsAsmParser::parseSetPopDirective() {
7407 MCAsmParser &Parser = getParser();
7408 SMLoc Loc = getLexer().getLoc();
7412 return reportParseError(
"unexpected token, expected end of statement");
7416 if (AssemblerOptions.
size() == 2)
7417 return reportParseError(Loc,
".set pop with no .set push");
7419 MCSubtargetInfo &STI = copySTI();
7421 setAvailableFeatures(
7422 ComputeAvailableFeatures(AssemblerOptions.
back()->getFeatures()));
7425 getTargetStreamer().emitDirectiveSetPop();
7429bool MipsAsmParser::parseSetPushDirective() {
7430 MCAsmParser &Parser = getParser();
7433 return reportParseError(
"unexpected token, expected end of statement");
7437 std::make_unique<MipsAssemblerOptions>(AssemblerOptions.
back().get()));
7439 getTargetStreamer().emitDirectiveSetPush();
7443bool MipsAsmParser::parseSetSoftFloatDirective() {
7444 MCAsmParser &Parser = getParser();
7447 return reportParseError(
"unexpected token, expected end of statement");
7449 setFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
7450 getTargetStreamer().emitDirectiveSetSoftFloat();
7454bool MipsAsmParser::parseSetHardFloatDirective() {
7455 MCAsmParser &Parser = getParser();
7458 return reportParseError(
"unexpected token, expected end of statement");
7460 clearFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
7461 getTargetStreamer().emitDirectiveSetHardFloat();
7465bool MipsAsmParser::parseSetAssignment() {
7467 MCAsmParser &Parser = getParser();
7470 return reportParseError(
"expected identifier after .set");
7473 return reportParseError(
"unexpected token, expected comma");
7488 const MCExpr *
Value;
7490 Parser, Sym,
Value))
7492 getStreamer().emitAssignment(Sym,
Value);
7497bool MipsAsmParser::parseSetMips0Directive() {
7498 MCAsmParser &Parser = getParser();
7501 return reportParseError(
"unexpected token, expected end of statement");
7504 MCSubtargetInfo &STI = copySTI();
7505 setAvailableFeatures(
7506 ComputeAvailableFeatures(AssemblerOptions.
front()->getFeatures()));
7508 AssemblerOptions.
back()->setFeatures(AssemblerOptions.
front()->getFeatures());
7510 getTargetStreamer().emitDirectiveSetMips0();
7514bool MipsAsmParser::parseSetArchDirective() {
7515 MCAsmParser &Parser = getParser();
7518 return reportParseError(
"unexpected token, expected equals sign");
7521 StringRef Arch = getParser().parseStringToEndOfStatement().trim();
7523 return reportParseError(
"expected arch identifier");
7525 StringRef ArchFeatureName =
7526 StringSwitch<StringRef>(Arch)
7527 .Case(
"mips1",
"mips1")
7528 .Case(
"mips2",
"mips2")
7529 .Case(
"mips3",
"mips3")
7530 .Case(
"mips4",
"mips4")
7531 .Case(
"mips5",
"mips5")
7532 .Case(
"mips32",
"mips32")
7533 .Case(
"mips32r2",
"mips32r2")
7534 .Case(
"mips32r3",
"mips32r3")
7535 .Case(
"mips32r5",
"mips32r5")
7536 .Case(
"mips32r6",
"mips32r6")
7537 .Case(
"mips64",
"mips64")
7538 .Case(
"mips64r2",
"mips64r2")
7539 .Case(
"mips64r3",
"mips64r3")
7540 .Case(
"mips64r5",
"mips64r5")
7541 .Case(
"mips64r6",
"mips64r6")
7542 .Case(
"octeon",
"cnmips")
7543 .Case(
"octeon+",
"cnmipsp")
7544 .Case(
"r4000",
"mips3")
7547 if (ArchFeatureName.
empty())
7548 return reportParseError(
"unsupported architecture");
7550 if (ArchFeatureName ==
"mips64r6" && inMicroMipsMode())
7551 return reportParseError(
"mips64r6 does not support microMIPS");
7553 selectArch(ArchFeatureName);
7554 getTargetStreamer().emitDirectiveSetArch(Arch);
7558bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
7559 MCAsmParser &Parser = getParser();
7562 return reportParseError(
"unexpected token, expected end of statement");
7567 case Mips::FeatureMips3D:
7568 setFeatureBits(Mips::FeatureMips3D,
"mips3d");
7569 getTargetStreamer().emitDirectiveSetMips3D();
7571 case Mips::FeatureDSP:
7572 setFeatureBits(Mips::FeatureDSP,
"dsp");
7573 getTargetStreamer().emitDirectiveSetDsp();
7575 case Mips::FeatureDSPR2:
7576 setFeatureBits(Mips::FeatureDSPR2,
"dspr2");
7577 getTargetStreamer().emitDirectiveSetDspr2();
7579 case Mips::FeatureMicroMips:
7580 setFeatureBits(Mips::FeatureMicroMips,
"micromips");
7581 getTargetStreamer().emitDirectiveSetMicroMips();
7583 case Mips::FeatureMips1:
7584 selectArch(
"mips1");
7585 getTargetStreamer().emitDirectiveSetMips1();
7587 case Mips::FeatureMips2:
7588 selectArch(
"mips2");
7589 getTargetStreamer().emitDirectiveSetMips2();
7591 case Mips::FeatureMips3:
7592 selectArch(
"mips3");
7593 getTargetStreamer().emitDirectiveSetMips3();
7595 case Mips::FeatureMips4:
7596 selectArch(
"mips4");
7597 getTargetStreamer().emitDirectiveSetMips4();
7599 case Mips::FeatureMips5:
7600 selectArch(
"mips5");
7601 getTargetStreamer().emitDirectiveSetMips5();
7603 case Mips::FeatureMips32:
7604 selectArch(
"mips32");
7605 getTargetStreamer().emitDirectiveSetMips32();
7607 case Mips::FeatureMips32r2:
7608 selectArch(
"mips32r2");
7609 getTargetStreamer().emitDirectiveSetMips32R2();
7611 case Mips::FeatureMips32r3:
7612 selectArch(
"mips32r3");
7613 getTargetStreamer().emitDirectiveSetMips32R3();
7615 case Mips::FeatureMips32r5:
7616 selectArch(
"mips32r5");
7617 getTargetStreamer().emitDirectiveSetMips32R5();
7619 case Mips::FeatureMips32r6:
7620 selectArch(
"mips32r6");
7621 getTargetStreamer().emitDirectiveSetMips32R6();
7623 case Mips::FeatureMips64:
7624 selectArch(
"mips64");
7625 getTargetStreamer().emitDirectiveSetMips64();
7627 case Mips::FeatureMips64r2:
7628 selectArch(
"mips64r2");
7629 getTargetStreamer().emitDirectiveSetMips64R2();
7631 case Mips::FeatureMips64r3:
7632 selectArch(
"mips64r3");
7633 getTargetStreamer().emitDirectiveSetMips64R3();
7635 case Mips::FeatureMips64r5:
7636 selectArch(
"mips64r5");
7637 getTargetStreamer().emitDirectiveSetMips64R5();
7639 case Mips::FeatureMips64r6:
7640 selectArch(
"mips64r6");
7641 getTargetStreamer().emitDirectiveSetMips64R6();
7643 case Mips::FeatureCRC:
7644 setFeatureBits(Mips::FeatureCRC,
"crc");
7645 getTargetStreamer().emitDirectiveSetCRC();
7647 case Mips::FeatureVirt:
7648 setFeatureBits(Mips::FeatureVirt,
"virt");
7649 getTargetStreamer().emitDirectiveSetVirt();
7651 case Mips::FeatureGINV:
7652 setFeatureBits(Mips::FeatureGINV,
"ginv");
7653 getTargetStreamer().emitDirectiveSetGINV();
7659bool MipsAsmParser::eatComma(StringRef ErrorStr) {
7660 MCAsmParser &Parser = getParser();
7662 SMLoc Loc = getLexer().getLoc();
7663 return Error(Loc, ErrorStr);
7674bool MipsAsmParser::isPicAndNotNxxAbi() {
7675 return inPicMode() && !(isABI_N32() || isABI_N64());
7678bool MipsAsmParser::parseDirectiveCpAdd(SMLoc Loc) {
7680 ParseStatus Res = parseAnyRegister(
Reg);
7682 reportParseError(
"expected register");
7686 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7687 if (!RegOpnd.isGPRAsmReg()) {
7688 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7694 reportParseError(
"unexpected token, expected end of statement");
7699 getTargetStreamer().emitDirectiveCpAdd(RegOpnd.getGPR32Reg());
7703bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
7704 if (AssemblerOptions.
back()->isReorder())
7705 Warning(Loc,
".cpload should be inside a noreorder section");
7707 if (inMips16Mode()) {
7708 reportParseError(
".cpload is not supported in Mips16 mode");
7713 ParseStatus Res = parseAnyRegister(
Reg);
7715 reportParseError(
"expected register containing function address");
7719 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7720 if (!RegOpnd.isGPRAsmReg()) {
7721 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7727 reportParseError(
"unexpected token, expected end of statement");
7731 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
7735bool MipsAsmParser::parseDirectiveCpLocal(SMLoc Loc) {
7736 if (!isABI_N32() && !isABI_N64()) {
7737 reportParseError(
".cplocal is allowed only in N32 or N64 mode");
7742 ParseStatus Res = parseAnyRegister(
Reg);
7744 reportParseError(
"expected register containing global pointer");
7748 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7749 if (!RegOpnd.isGPRAsmReg()) {
7750 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7756 reportParseError(
"unexpected token, expected end of statement");
7761 MCRegister NewReg = RegOpnd.getGPR32Reg();
7765 getTargetStreamer().emitDirectiveCpLocal(NewReg);
7769bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
7770 MCAsmParser &Parser = getParser();
7775 if (inMips16Mode()) {
7776 reportParseError(
".cprestore is not supported in Mips16 mode");
7781 const MCExpr *StackOffset;
7782 int64_t StackOffsetVal;
7784 reportParseError(
"expected stack offset value");
7788 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
7789 reportParseError(
"stack offset is not an absolute expression");
7793 if (StackOffsetVal < 0) {
7794 Warning(Loc,
".cprestore with negative stack offset has no effect");
7795 IsCpRestoreSet =
false;
7797 IsCpRestoreSet =
true;
7798 CpRestoreOffset = StackOffsetVal;
7803 reportParseError(
"unexpected token, expected end of statement");
7807 if (!getTargetStreamer().emitDirectiveCpRestore(
7808 CpRestoreOffset, [&]() {
return getATReg(Loc); }, Loc, STI))
7814bool MipsAsmParser::parseDirectiveCPSetup() {
7815 MCAsmParser &Parser = getParser();
7817 bool SaveIsReg =
true;
7820 ParseStatus Res = parseAnyRegister(TmpReg);
7822 reportParseError(
"expected register containing function address");
7826 MipsOperand &FuncRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7827 if (!FuncRegOpnd.isGPRAsmReg()) {
7828 reportParseError(FuncRegOpnd.getStartLoc(),
"invalid register");
7832 MCRegister FuncReg = FuncRegOpnd.getGPR32Reg();
7835 if (!eatComma(
"unexpected token, expected comma"))
7838 Res = parseAnyRegister(TmpReg);
7840 const MCExpr *OffsetExpr;
7842 SMLoc ExprLoc = getLexer().
getLoc();
7845 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
7846 reportParseError(ExprLoc,
"expected save register or stack offset");
7853 MipsOperand &SaveOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7854 if (!SaveOpnd.isGPRAsmReg()) {
7855 reportParseError(SaveOpnd.getStartLoc(),
"invalid register");
7858 Save = SaveOpnd.getGPR32Reg().id();
7861 if (!eatComma(
"unexpected token, expected comma"))
7866 reportParseError(
"expected expression");
7871 reportParseError(
"expected symbol");
7874 const MCSymbolRefExpr *
Ref =
static_cast<const MCSymbolRefExpr *
>(Expr);
7876 CpSaveLocation = Save;
7877 CpSaveLocationIsRegister = SaveIsReg;
7879 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save,
Ref->getSymbol(),
7884bool MipsAsmParser::parseDirectiveCPReturn() {
7885 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
7886 CpSaveLocationIsRegister);
7890bool MipsAsmParser::parseDirectiveNaN() {
7891 MCAsmParser &Parser = getParser();
7893 const AsmToken &Tok = Parser.
getTok();
7897 getTargetStreamer().emitDirectiveNaN2008();
7899 }
else if (Tok.
getString() ==
"legacy") {
7901 getTargetStreamer().emitDirectiveNaNLegacy();
7907 reportParseError(
"invalid option in .nan directive");
7911bool MipsAsmParser::parseDirectiveSet() {
7912 const AsmToken &Tok = getParser().getTok();
7914 SMLoc Loc = Tok.
getLoc();
7916 if (IdVal ==
"noat")
7917 return parseSetNoAtDirective();
7919 return parseSetAtDirective();
7920 if (IdVal ==
"arch")
7921 return parseSetArchDirective();
7922 if (IdVal ==
"bopt") {
7923 Warning(Loc,
"'bopt' feature is unsupported");
7927 if (IdVal ==
"nobopt") {
7933 return parseSetFpDirective();
7934 if (IdVal ==
"oddspreg")
7935 return parseSetOddSPRegDirective();
7936 if (IdVal ==
"nooddspreg")
7937 return parseSetNoOddSPRegDirective();
7939 return parseSetPopDirective();
7940 if (IdVal ==
"push")
7941 return parseSetPushDirective();
7942 if (IdVal ==
"reorder")
7943 return parseSetReorderDirective();
7944 if (IdVal ==
"noreorder")
7945 return parseSetNoReorderDirective();
7946 if (IdVal ==
"macro")
7947 return parseSetMacroDirective();
7948 if (IdVal ==
"nomacro")
7949 return parseSetNoMacroDirective();
7950 if (IdVal ==
"mips16")
7951 return parseSetMips16Directive();
7952 if (IdVal ==
"nomips16")
7953 return parseSetNoMips16Directive();
7954 if (IdVal ==
"nomicromips") {
7955 clearFeatureBits(Mips::FeatureMicroMips,
"micromips");
7956 getTargetStreamer().emitDirectiveSetNoMicroMips();
7957 getParser().eatToEndOfStatement();
7960 if (IdVal ==
"micromips") {
7961 if (hasMips64r6()) {
7962 Error(Loc,
".set micromips directive is not supported with MIPS64R6");
7965 return parseSetFeature(Mips::FeatureMicroMips);
7967 if (IdVal ==
"mips0")
7968 return parseSetMips0Directive();
7969 if (IdVal ==
"mips1")
7970 return parseSetFeature(Mips::FeatureMips1);
7971 if (IdVal ==
"mips2")
7972 return parseSetFeature(Mips::FeatureMips2);
7973 if (IdVal ==
"mips3")
7974 return parseSetFeature(Mips::FeatureMips3);
7975 if (IdVal ==
"mips4")
7976 return parseSetFeature(Mips::FeatureMips4);
7977 if (IdVal ==
"mips5")
7978 return parseSetFeature(Mips::FeatureMips5);
7979 if (IdVal ==
"mips32")
7980 return parseSetFeature(Mips::FeatureMips32);
7981 if (IdVal ==
"mips32r2")
7982 return parseSetFeature(Mips::FeatureMips32r2);
7983 if (IdVal ==
"mips32r3")
7984 return parseSetFeature(Mips::FeatureMips32r3);
7985 if (IdVal ==
"mips32r5")
7986 return parseSetFeature(Mips::FeatureMips32r5);
7987 if (IdVal ==
"mips32r6")
7988 return parseSetFeature(Mips::FeatureMips32r6);
7989 if (IdVal ==
"mips64")
7990 return parseSetFeature(Mips::FeatureMips64);
7991 if (IdVal ==
"mips64r2")
7992 return parseSetFeature(Mips::FeatureMips64r2);
7993 if (IdVal ==
"mips64r3")
7994 return parseSetFeature(Mips::FeatureMips64r3);
7995 if (IdVal ==
"mips64r5")
7996 return parseSetFeature(Mips::FeatureMips64r5);
7997 if (IdVal ==
"mips64r6") {
7998 if (inMicroMipsMode()) {
7999 Error(Loc,
"MIPS64R6 is not supported with microMIPS");
8002 return parseSetFeature(Mips::FeatureMips64r6);
8005 return parseSetFeature(Mips::FeatureDSP);
8006 if (IdVal ==
"dspr2")
8007 return parseSetFeature(Mips::FeatureDSPR2);
8008 if (IdVal ==
"nodsp")
8009 return parseSetNoDspDirective();
8010 if (IdVal ==
"mips3d")
8011 return parseSetFeature(Mips::FeatureMips3D);
8012 if (IdVal ==
"nomips3d")
8013 return parseSetNoMips3DDirective();
8015 return parseSetMsaDirective();
8016 if (IdVal ==
"nomsa")
8017 return parseSetNoMsaDirective();
8019 return parseSetMtDirective();
8020 if (IdVal ==
"nomt")
8021 return parseSetNoMtDirective();
8022 if (IdVal ==
"softfloat")
8023 return parseSetSoftFloatDirective();
8024 if (IdVal ==
"hardfloat")
8025 return parseSetHardFloatDirective();
8027 return parseSetFeature(Mips::FeatureCRC);
8028 if (IdVal ==
"nocrc")
8029 return parseSetNoCRCDirective();
8030 if (IdVal ==
"virt")
8031 return parseSetFeature(Mips::FeatureVirt);
8032 if (IdVal ==
"novirt")
8033 return parseSetNoVirtDirective();
8034 if (IdVal ==
"ginv")
8035 return parseSetFeature(Mips::FeatureGINV);
8036 if (IdVal ==
"noginv")
8037 return parseSetNoGINVDirective();
8040 return parseSetAssignment();
8045bool MipsAsmParser::parseDirectiveGpWord() {
8046 const MCExpr *
Value;
8047 if (getParser().parseExpression(
Value))
8049 getTargetStreamer().emitGPRel32Value(
Value);
8055bool MipsAsmParser::parseDirectiveGpDWord() {
8056 const MCExpr *
Value;
8057 if (getParser().parseExpression(
Value))
8059 getTargetStreamer().emitGPRel64Value(
Value);
8065bool MipsAsmParser::parseDirectiveDtpRelWord() {
8066 const MCExpr *
Value;
8067 if (getParser().parseExpression(
Value))
8069 getTargetStreamer().emitDTPRel32Value(
Value);
8075bool MipsAsmParser::parseDirectiveDtpRelDWord() {
8076 const MCExpr *
Value;
8077 if (getParser().parseExpression(
Value))
8079 getTargetStreamer().emitDTPRel64Value(
Value);
8085bool MipsAsmParser::parseDirectiveTpRelWord() {
8086 const MCExpr *
Value;
8087 if (getParser().parseExpression(
Value))
8089 getTargetStreamer().emitTPRel32Value(
Value);
8095bool MipsAsmParser::parseDirectiveTpRelDWord() {
8096 const MCExpr *
Value;
8097 if (getParser().parseExpression(
Value))
8099 getTargetStreamer().emitTPRel64Value(
Value);
8103bool MipsAsmParser::parseDirectiveOption() {
8104 MCAsmParser &Parser = getParser();
8106 AsmToken Tok = Parser.
getTok();
8110 "unexpected token, expected identifier");
8115 if (Option ==
"pic0") {
8117 IsPicEnabled =
false;
8119 getTargetStreamer().emitDirectiveOptionPic0();
8123 "unexpected token, expected end of statement");
8128 if (Option ==
"pic2") {
8130 IsPicEnabled =
true;
8132 getTargetStreamer().emitDirectiveOptionPic2();
8136 "unexpected token, expected end of statement");
8143 "unknown option, expected 'pic0' or 'pic2'");
8150bool MipsAsmParser::parseInsnDirective() {
8153 reportParseError(
"unexpected token, expected end of statement");
8159 getTargetStreamer().emitDirectiveInsn();
8167bool MipsAsmParser::parseRSectionDirective(StringRef Section) {
8170 reportParseError(
"unexpected token, expected end of statement");
8174 MCSection *ELFSection =
getContext().getELFSection(
8176 getParser().getStreamer().switchSection(ELFSection);
8185bool MipsAsmParser::parseSSectionDirective(StringRef Section,
unsigned Type) {
8188 reportParseError(
"unexpected token, expected end of statement");
8192 MCSection *ELFSection =
getContext().getELFSection(
8194 getParser().getStreamer().switchSection(ELFSection);
8213bool MipsAsmParser::parseDirectiveModule() {
8214 MCAsmParser &Parser = getParser();
8215 AsmLexer &Lexer = getLexer();
8218 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
8220 reportParseError(
".module directive must appear before any code");
8226 reportParseError(
"expected .module option identifier");
8230 if (Option ==
"oddspreg") {
8231 clearModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
8235 getTargetStreamer().updateABIInfo(*
this);
8240 getTargetStreamer().emitDirectiveModuleOddSPReg();
8244 reportParseError(
"unexpected token, expected end of statement");
8249 }
else if (Option ==
"nooddspreg") {
8251 return Error(L,
"'.module nooddspreg' requires the O32 ABI");
8254 setModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
8258 getTargetStreamer().updateABIInfo(*
this);
8263 getTargetStreamer().emitDirectiveModuleOddSPReg();
8267 reportParseError(
"unexpected token, expected end of statement");
8272 }
else if (Option ==
"fp") {
8273 return parseDirectiveModuleFP();
8274 }
else if (Option ==
"softfloat") {
8275 setModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
8279 getTargetStreamer().updateABIInfo(*
this);
8284 getTargetStreamer().emitDirectiveModuleSoftFloat();
8288 reportParseError(
"unexpected token, expected end of statement");
8293 }
else if (Option ==
"hardfloat") {
8294 clearModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
8298 getTargetStreamer().updateABIInfo(*
this);
8303 getTargetStreamer().emitDirectiveModuleHardFloat();
8307 reportParseError(
"unexpected token, expected end of statement");
8312 }
else if (Option ==
"mt") {
8313 setModuleFeatureBits(Mips::FeatureMT,
"mt");
8317 getTargetStreamer().updateABIInfo(*
this);
8322 getTargetStreamer().emitDirectiveModuleMT();
8326 reportParseError(
"unexpected token, expected end of statement");
8331 }
else if (Option ==
"crc") {
8332 setModuleFeatureBits(Mips::FeatureCRC,
"crc");
8336 getTargetStreamer().updateABIInfo(*
this);
8341 getTargetStreamer().emitDirectiveModuleCRC();
8345 reportParseError(
"unexpected token, expected end of statement");
8350 }
else if (Option ==
"nocrc") {
8351 clearModuleFeatureBits(Mips::FeatureCRC,
"crc");
8355 getTargetStreamer().updateABIInfo(*
this);
8360 getTargetStreamer().emitDirectiveModuleNoCRC();
8364 reportParseError(
"unexpected token, expected end of statement");
8369 }
else if (Option ==
"virt") {
8370 setModuleFeatureBits(Mips::FeatureVirt,
"virt");
8374 getTargetStreamer().updateABIInfo(*
this);
8379 getTargetStreamer().emitDirectiveModuleVirt();
8383 reportParseError(
"unexpected token, expected end of statement");
8388 }
else if (Option ==
"novirt") {
8389 clearModuleFeatureBits(Mips::FeatureVirt,
"virt");
8393 getTargetStreamer().updateABIInfo(*
this);
8398 getTargetStreamer().emitDirectiveModuleNoVirt();
8402 reportParseError(
"unexpected token, expected end of statement");
8407 }
else if (Option ==
"ginv") {
8408 setModuleFeatureBits(Mips::FeatureGINV,
"ginv");
8412 getTargetStreamer().updateABIInfo(*
this);
8417 getTargetStreamer().emitDirectiveModuleGINV();
8421 reportParseError(
"unexpected token, expected end of statement");
8426 }
else if (Option ==
"noginv") {
8427 clearModuleFeatureBits(Mips::FeatureGINV,
"ginv");
8431 getTargetStreamer().updateABIInfo(*
this);
8436 getTargetStreamer().emitDirectiveModuleNoGINV();
8440 reportParseError(
"unexpected token, expected end of statement");
8446 return Error(L,
"'" + Twine(Option) +
"' is not a valid .module option.");
8454bool MipsAsmParser::parseDirectiveModuleFP() {
8455 MCAsmParser &Parser = getParser();
8456 AsmLexer &Lexer = getLexer();
8459 reportParseError(
"unexpected token, expected equals sign '='");
8465 if (!parseFpABIValue(FpABI,
".module"))
8469 reportParseError(
"unexpected token, expected end of statement");
8475 getTargetStreamer().updateABIInfo(*
this);
8480 getTargetStreamer().emitDirectiveModuleFP();
8487 StringRef Directive) {
8488 MCAsmParser &Parser = getParser();
8489 AsmLexer &Lexer = getLexer();
8490 bool ModuleLevelOptions = Directive ==
".module";
8496 if (
Value !=
"xx") {
8497 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
8502 reportParseError(
"'" + Directive +
" fp=xx' requires the O32 ABI");
8506 FpABI = MipsABIFlagsSection::FpABIKind::XX;
8507 if (ModuleLevelOptions) {
8508 setModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8509 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8511 setFeatureBits(Mips::FeatureFPXX,
"fpxx");
8512 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8522 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
8528 reportParseError(
"'" + Directive +
" fp=32' requires the O32 ABI");
8532 FpABI = MipsABIFlagsSection::FpABIKind::S32;
8533 if (ModuleLevelOptions) {
8534 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8535 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8537 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
8538 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8541 FpABI = MipsABIFlagsSection::FpABIKind::S64;
8542 if (ModuleLevelOptions) {
8543 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8544 setModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8546 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
8547 setFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8557bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
8563 MCAsmParser &Parser = getParser();
8564 StringRef IDVal = DirectiveID.
getString();
8566 if (IDVal ==
".cpadd") {
8567 parseDirectiveCpAdd(DirectiveID.
getLoc());
8570 if (IDVal ==
".cpload") {
8571 parseDirectiveCpLoad(DirectiveID.
getLoc());
8574 if (IDVal ==
".cprestore") {
8575 parseDirectiveCpRestore(DirectiveID.
getLoc());
8578 if (IDVal ==
".cplocal") {
8579 parseDirectiveCpLocal(DirectiveID.
getLoc());
8582 if (IDVal ==
".ent") {
8586 reportParseError(
"expected identifier after .ent");
8600 reportParseError(
"unexpected token, expected end of statement");
8604 const MCExpr *DummyNumber;
8605 int64_t DummyNumberVal;
8609 reportParseError(
"expected number after comma");
8612 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
8613 reportParseError(
"expected an absolute expression after comma");
8620 reportParseError(
"unexpected token, expected end of statement");
8626 getTargetStreamer().emitDirectiveEnt(*Sym);
8628 IsCpRestoreSet =
false;
8632 if (IDVal ==
".end") {
8636 reportParseError(
"expected identifier after .end");
8641 reportParseError(
"unexpected token, expected end of statement");
8645 if (CurrentFn ==
nullptr) {
8646 reportParseError(
".end used without .ent");
8650 if ((SymbolName != CurrentFn->
getName())) {
8651 reportParseError(
".end symbol does not match .ent symbol");
8655 getTargetStreamer().emitDirectiveEnd(SymbolName);
8656 CurrentFn =
nullptr;
8657 IsCpRestoreSet =
false;
8661 if (IDVal ==
".frame") {
8664 ParseStatus Res = parseAnyRegister(TmpReg);
8666 reportParseError(
"expected stack register");
8670 MipsOperand &StackRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
8671 if (!StackRegOpnd.isGPRAsmReg()) {
8672 reportParseError(StackRegOpnd.getStartLoc(),
8673 "expected general purpose register");
8676 MCRegister StackReg = StackRegOpnd.getGPR32Reg();
8681 reportParseError(
"unexpected token, expected comma");
8686 const MCExpr *FrameSize;
8687 int64_t FrameSizeVal;
8690 reportParseError(
"expected frame size value");
8694 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
8695 reportParseError(
"frame size not an absolute expression");
8702 reportParseError(
"unexpected token, expected comma");
8708 Res = parseAnyRegister(TmpReg);
8710 reportParseError(
"expected return register");
8714 MipsOperand &ReturnRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
8715 if (!ReturnRegOpnd.isGPRAsmReg()) {
8716 reportParseError(ReturnRegOpnd.getStartLoc(),
8717 "expected general purpose register");
8723 reportParseError(
"unexpected token, expected end of statement");
8727 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
8728 ReturnRegOpnd.getGPR32Reg());
8729 IsCpRestoreSet =
false;
8733 if (IDVal ==
".set") {
8734 parseDirectiveSet();
8738 if (IDVal ==
".mask" || IDVal ==
".fmask") {
8749 const MCExpr *BitMask;
8753 reportParseError(
"expected bitmask value");
8757 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
8758 reportParseError(
"bitmask not an absolute expression");
8765 reportParseError(
"unexpected token, expected comma");
8770 const MCExpr *FrameOffset;
8771 int64_t FrameOffsetVal;
8774 reportParseError(
"expected frame offset value");
8778 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
8779 reportParseError(
"frame offset not an absolute expression");
8785 reportParseError(
"unexpected token, expected end of statement");
8789 if (IDVal ==
".mask")
8790 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
8792 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
8796 if (IDVal ==
".nan")
8797 return parseDirectiveNaN();
8799 if (IDVal ==
".gpword") {
8800 parseDirectiveGpWord();
8804 if (IDVal ==
".gpdword") {
8805 parseDirectiveGpDWord();
8809 if (IDVal ==
".dtprelword") {
8810 parseDirectiveDtpRelWord();
8814 if (IDVal ==
".dtpreldword") {
8815 parseDirectiveDtpRelDWord();
8819 if (IDVal ==
".tprelword") {
8820 parseDirectiveTpRelWord();
8824 if (IDVal ==
".tpreldword") {
8825 parseDirectiveTpRelDWord();
8829 if (IDVal ==
".option") {
8830 parseDirectiveOption();
8834 if (IDVal ==
".abicalls") {
8835 getTargetStreamer().emitDirectiveAbiCalls();
8838 "unexpected token, expected end of statement");
8843 if (IDVal ==
".cpsetup") {
8844 parseDirectiveCPSetup();
8847 if (IDVal ==
".cpreturn") {
8848 parseDirectiveCPReturn();
8851 if (IDVal ==
".module") {
8852 parseDirectiveModule();
8855 if (IDVal ==
".llvm_internal_mips_reallow_module_directive") {
8856 parseInternalDirectiveReallowModule();
8859 if (IDVal ==
".insn") {
8860 parseInsnDirective();
8863 if (IDVal ==
".rdata") {
8864 parseRSectionDirective(
".rodata");
8867 if (IDVal ==
".sbss") {
8871 if (IDVal ==
".sdata") {
8879bool MipsAsmParser::parseInternalDirectiveReallowModule() {
8882 reportParseError(
"unexpected token, expected end of statement");
8886 getTargetStreamer().reallowModuleDirective();
8900#define GET_REGISTER_MATCHER
8901#define GET_MATCHER_IMPLEMENTATION
8902#define GET_MNEMONIC_SPELL_CHECKER
8903#include "MipsGenAsmMatcher.inc"
8905bool MipsAsmParser::mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID) {
8907 const MatchEntry *Start, *End;
8908 switch (VariantID) {
8910 case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0);
break;
8913 auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
8914 return MnemonicRange.first != MnemonicRange.second;
static const TargetRegisterClass * getRegClass(const MachineInstr &MI, Register Reg)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
This file declares a class to represent arbitrary precision floating point values and provide a varie...
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
static Value * expandAbs(CallInst *Orig)
std::pair< Instruction::BinaryOps, Value * > OffsetOp
Find all possible pairs (BinOp, RHS) that BinOp V, RHS can be simplified.
static constexpr Value * getValue(Ty &ValueOrUse)
static Value * getOpcode(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
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 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)
Represent a constant reference to a string, i.e.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
Check if the string is empty.
LLVM_ABI bool isLittleEndian() const
Tests whether the target triple is little endian.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
LLVM_ABI 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,...