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)
5709 : (Inst.getOpcode() != Mips::MTTDSP ? Inst.getOperand(1).
getReg()
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_SImm19_Lsl2:
6054 "expected both 19-bit signed immediate and multiple of 4");
6055 case Match_UImm20_0:
6057 "expected 20-bit unsigned immediate");
6058 case Match_UImm26_0:
6060 "expected 26-bit unsigned immediate");
6062 case Match_SImm32_Relaxed:
6064 "expected 32-bit signed immediate");
6065 case Match_UImm32_Coerced:
6067 "expected 32-bit immediate");
6068 case Match_MemSImm9:
6070 "expected memory with 9-bit signed offset");
6071 case Match_MemSImm10:
6073 "expected memory with 10-bit signed offset");
6074 case Match_MemSImm10Lsl1:
6076 "expected memory with 11-bit signed offset and multiple of 2");
6077 case Match_MemSImm10Lsl2:
6079 "expected memory with 12-bit signed offset and multiple of 4");
6080 case Match_MemSImm10Lsl3:
6082 "expected memory with 13-bit signed offset and multiple of 8");
6083 case Match_MemSImm11:
6085 "expected memory with 11-bit signed offset");
6086 case Match_MemSImm12:
6088 "expected memory with 12-bit signed offset");
6089 case Match_MemSImm16:
6091 "expected memory with 16-bit signed offset");
6092 case Match_MemSImmPtr:
6094 "expected memory with 32-bit signed offset");
6095 case Match_RequiresPosSizeRange0_32: {
6096 SMLoc ErrorStart = Operands[3]->getStartLoc();
6097 SMLoc ErrorEnd = Operands[4]->getEndLoc();
6098 return Error(ErrorStart,
"size plus position are not in the range 0 .. 32",
6099 SMRange(ErrorStart, ErrorEnd));
6101 case Match_RequiresPosSizeUImm6: {
6102 SMLoc ErrorStart = Operands[3]->getStartLoc();
6103 SMLoc ErrorEnd = Operands[4]->getEndLoc();
6104 return Error(ErrorStart,
"size plus position are not in the range 1 .. 63",
6105 SMRange(ErrorStart, ErrorEnd));
6107 case Match_RequiresPosSizeRange33_64: {
6108 SMLoc ErrorStart = Operands[3]->getStartLoc();
6109 SMLoc ErrorEnd = Operands[4]->getEndLoc();
6110 return Error(ErrorStart,
"size plus position are not in the range 33 .. 64",
6111 SMRange(ErrorStart, ErrorEnd));
6118void MipsAsmParser::warnIfRegIndexIsAT(MCRegister RegIndex, SMLoc Loc) {
6119 if (RegIndex && AssemblerOptions.
back()->getATRegIndex() == RegIndex)
6120 Warning(Loc,
"used $at (currently $" + Twine(RegIndex.
id()) +
6121 ") without \".set noat\"");
6124void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
6125 if (!AssemblerOptions.
back()->isMacro())
6126 Warning(Loc,
"macro instruction expanded into multiple instructions");
6129void MipsAsmParser::ConvertXWPOperands(MCInst &Inst,
6133 "Unexpected instruction!");
6134 ((MipsOperand &)*Operands[1]).addGPR32ZeroAsmRegOperands(Inst, 1);
6135 MCRegister NextReg =
nextReg(((MipsOperand &)*Operands[1]).getGPR32Reg());
6137 ((MipsOperand &)*Operands[2]).addMemOperands(Inst, 2);
6141MipsAsmParser::printWarningWithFixIt(
const Twine &Msg,
const Twine &FixMsg,
6142 SMRange
Range,
bool ShowColors) {
6148int MipsAsmParser::matchCPURegisterName(StringRef Name) {
6151 CC = StringSwitch<unsigned>(Name)
6153 .Cases({
"at",
"AT"}, 1)
6187 if (!(isABI_N32() || isABI_N64()))
6190 if (12 <= CC && CC <= 15) {
6192 AsmToken RegTok = getLexer().peekTok();
6195 StringRef FixedName = StringSwitch<StringRef>(Name)
6201 assert(FixedName !=
"" &&
"Register name is not one of t4-t7.");
6203 printWarningWithFixIt(
"register names $t4-$t7 are only available in O32.",
6204 "Did you mean $" + FixedName +
"?", RegRange);
6210 if (8 <= CC && CC <= 11)
6214 CC = StringSwitch<unsigned>(Name)
6226int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
6229 CC = StringSwitch<unsigned>(Name)
6230 .Case(
"hwr_cpunum", 0)
6231 .Case(
"hwr_synci_step", 1)
6233 .Case(
"hwr_ccres", 3)
6234 .Case(
"hwr_ulr", 29)
6240int MipsAsmParser::matchFPURegisterName(StringRef Name) {
6241 if (Name[0] ==
'f') {
6242 StringRef NumString =
Name.substr(1);
6253int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
6254 if (
Name.starts_with(
"fcc")) {
6255 StringRef NumString =
Name.substr(3);
6266int MipsAsmParser::matchACRegisterName(StringRef Name) {
6267 if (
Name.starts_with(
"ac")) {
6268 StringRef NumString =
Name.substr(2);
6279int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
6282 if (
Name.front() !=
'w' ||
Name.drop_front(1).getAsInteger(10, IntVal))
6291int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
6294 CC = StringSwitch<unsigned>(Name)
6297 .Case(
"msaaccess", 2)
6299 .Case(
"msamodify", 4)
6300 .Case(
"msarequest", 5)
6302 .Case(
"msaunmap", 7)
6308bool MipsAsmParser::canUseATReg() {
6309 return AssemblerOptions.
back()->getATRegIndex() != 0;
6312MCRegister MipsAsmParser::getATReg(SMLoc Loc) {
6313 unsigned ATIndex = AssemblerOptions.
back()->getATRegIndex();
6315 reportParseError(Loc,
6316 "pseudo-instruction requires $at, which is not available");
6320 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
6324MCRegister MipsAsmParser::getReg(
int RC,
int RegNo) {
6325 return getContext().getRegisterInfo()->getRegClass(RC).getRegister(RegNo);
6331const MCExpr *MipsAsmParser::parseRelocExpr() {
6332 auto getOp = [](StringRef
Op) {
6333 return StringSwitch<Mips::Specifier>(
Op)
6361 MCAsmParser &Parser = getParser();
6363 const MCExpr *Res =
nullptr;
6369 auto Op = getOp(Name);
6378 while (
Ops.size()) {
6386bool MipsAsmParser::parseOperand(
OperandVector &Operands, StringRef Mnemonic) {
6387 MCAsmParser &Parser = getParser();
6397 ParseStatus Res = MatchOperandParserImpl(Operands, Mnemonic,
true);
6408 switch (getLexer().getKind()) {
6418 if (!parseAnyRegister(Operands).isNoMatch())
6431 Operands.
push_back(MipsOperand::CreateImm(SymRef, S,
E, *
this));
6436 const MCExpr *Expr = parseRelocExpr();
6440 Operands.
push_back(MipsOperand::CreateImm(Expr, S,
E, *
this));
6447bool MipsAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
6449 return !tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess();
6452ParseStatus MipsAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
6455 ParseStatus Res = parseAnyRegister(Operands);
6458 MipsOperand &Operand =
static_cast<MipsOperand &
>(*Operands.
front());
6459 StartLoc = Operand.getStartLoc();
6460 EndLoc = Operand.getEndLoc();
6466 if (Operand.isGPRAsmReg()) {
6468 Reg = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
6478ParseStatus MipsAsmParser::parseMemOperand(
OperandVector &Operands) {
6479 MCAsmParser &Parser = getParser();
6481 const MCExpr *IdVal =
nullptr;
6483 bool isParenExpr =
false;
6494 IdVal = parseRelocExpr();
6500 const AsmToken &Tok = Parser.
getTok();
6502 MipsOperand &Mnemonic =
static_cast<MipsOperand &
>(*Operands[0]);
6503 if (Mnemonic.getToken() ==
"la" || Mnemonic.getToken() ==
"dla") {
6506 Operands.
push_back(MipsOperand::CreateImm(IdVal, S,
E, *
this));
6515 auto Base = MipsOperand::createGPRReg(
6516 0,
"0",
getContext().getRegisterInfo(), S,
E, *
this);
6518 MipsOperand::CreateMem(std::move(
Base), IdVal, S,
E, *
this));
6570 const MCExpr * NextExpr;
6571 if (getParser().parseExpression(NextExpr))
6579 Res = parseAnyRegister(Operands);
6594 std::unique_ptr<MipsOperand>
op(
6595 static_cast<MipsOperand *
>(Operands.
back().release()));
6602 if (IdVal->evaluateAsAbsolute(Imm))
6609 Operands.
push_back(MipsOperand::CreateMem(std::move(
op), IdVal, S,
E, *
this));
6613bool MipsAsmParser::searchSymbolAlias(
OperandVector &Operands) {
6614 MCAsmParser &Parser = getParser();
6623 const MCSymbolRefExpr *
Ref =
static_cast<const MCSymbolRefExpr *
>(Expr);
6624 StringRef DefSymbol =
Ref->getSymbol().getName();
6627 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.
substr(1), S);
6641 if (Entry != RegisterSets.
end()) {
6643 matchAnyRegisterWithoutDollar(Operands,
Entry->getValue(), S);
6654ParseStatus MipsAsmParser::matchAnyRegisterNameWithoutDollar(
6656 int Index = matchCPURegisterName(Identifier);
6658 Operands.
push_back(MipsOperand::createGPRReg(
6659 Index, Identifier,
getContext().getRegisterInfo(), S,
6660 getLexer().getLoc(), *
this));
6664 Index = matchHWRegsRegisterName(Identifier);
6666 Operands.
push_back(MipsOperand::createHWRegsReg(
6667 Index, Identifier,
getContext().getRegisterInfo(), S,
6668 getLexer().getLoc(), *
this));
6672 Index = matchFPURegisterName(Identifier);
6674 Operands.
push_back(MipsOperand::createFGRReg(
6675 Index, Identifier,
getContext().getRegisterInfo(), S,
6676 getLexer().getLoc(), *
this));
6680 Index = matchFCCRegisterName(Identifier);
6682 Operands.
push_back(MipsOperand::createFCCReg(
6683 Index, Identifier,
getContext().getRegisterInfo(), S,
6684 getLexer().getLoc(), *
this));
6688 Index = matchACRegisterName(Identifier);
6690 Operands.
push_back(MipsOperand::createACCReg(
6691 Index, Identifier,
getContext().getRegisterInfo(), S,
6692 getLexer().getLoc(), *
this));
6696 Index = matchMSA128RegisterName(Identifier);
6698 Operands.
push_back(MipsOperand::createMSA128Reg(
6699 Index, Identifier,
getContext().getRegisterInfo(), S,
6700 getLexer().getLoc(), *
this));
6704 Index = matchMSA128CtrlRegisterName(Identifier);
6706 Operands.
push_back(MipsOperand::createMSACtrlReg(
6707 Index, Identifier,
getContext().getRegisterInfo(), S,
6708 getLexer().getLoc(), *
this));
6716MipsAsmParser::matchAnyRegisterWithoutDollar(
OperandVector &Operands,
6717 const AsmToken &Token, SMLoc S) {
6721 return matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
6726 if (RegNum < 0 || RegNum > 31) {
6730 Error(getLexer().getLoc(),
"invalid register number");
6732 Operands.
push_back(MipsOperand::createNumericReg(
6744MipsAsmParser::matchAnyRegisterWithoutDollar(
OperandVector &Operands, SMLoc S) {
6745 auto Token = getLexer().peekTok(
false);
6746 return matchAnyRegisterWithoutDollar(Operands, Token, S);
6749ParseStatus MipsAsmParser::parseAnyRegister(
OperandVector &Operands) {
6750 MCAsmParser &Parser = getParser();
6753 auto Token = Parser.
getTok();
6755 SMLoc S = Token.
getLoc();
6760 if (searchSymbolAlias(Operands))
6768 ParseStatus Res = matchAnyRegisterWithoutDollar(Operands, S);
6776ParseStatus MipsAsmParser::parseJumpTarget(
OperandVector &Operands) {
6777 MCAsmParser &Parser = getParser();
6780 SMLoc S = getLexer().getLoc();
6783 ParseStatus Res = parseAnyRegister(Operands);
6788 const MCExpr *Expr =
nullptr;
6794 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *
this));
6798ParseStatus MipsAsmParser::parseInvNum(
OperandVector &Operands) {
6799 MCAsmParser &Parser = getParser();
6800 const MCExpr *IdVal;
6811 if (getParser().parseExpression(IdVal))
6818 Operands.
push_back(MipsOperand::CreateImm(
6823ParseStatus MipsAsmParser::parseRegisterList(
OperandVector &Operands) {
6824 MCAsmParser &Parser = getParser();
6828 bool RegRange =
false;
6835 while (parseAnyRegister(TmpOperands).isSuccess()) {
6836 SMLoc
E = getLexer().getLoc();
6837 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*TmpOperands.
back());
6838 Reg = isGP64bit() ? RegOpnd.getGPR64Reg() : RegOpnd.getGPR32Reg();
6842 if ((isGP64bit() &&
Reg == Mips::RA_64) ||
6843 (!isGP64bit() &&
Reg == Mips::RA)) {
6846 MCRegister TmpReg = PrevReg + 1;
6847 while (TmpReg <=
Reg) {
6848 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
6849 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
6851 return Error(
E,
"invalid register operand");
6855 TmpReg = TmpReg.
id() + 1;
6862 ((isGP64bit() && (
Reg != Mips::S0_64) && (
Reg != Mips::RA_64)) ||
6863 (!isGP64bit() && (
Reg != Mips::S0) && (
Reg != Mips::RA))))
6864 return Error(
E,
"$16 or $31 expected");
6865 if (!(((
Reg == Mips::FP ||
Reg == Mips::RA ||
6866 (
Reg >= Mips::S0 &&
Reg <= Mips::S7)) &&
6868 ((
Reg == Mips::FP_64 ||
Reg == Mips::RA_64 ||
6869 (
Reg >= Mips::S0_64 &&
Reg <= Mips::S7_64)) &&
6871 return Error(
E,
"invalid register operand");
6872 if (PrevReg.
isValid() && (
Reg != PrevReg + 1) &&
6873 ((
Reg != Mips::FP &&
Reg != Mips::RA && !isGP64bit()) ||
6874 (
Reg != Mips::FP_64 &&
Reg != Mips::RA_64 && isGP64bit())))
6875 return Error(
E,
"consecutive register numbers expected");
6885 return Error(
E,
"',' or '-' expected");
6895 Operands.
push_back(MipsOperand::CreateRegList(Regs, S,
E, *
this));
6896 parseMemOperand(Operands);
6905bool MipsAsmParser::parseParenSuffix(StringRef Name,
OperandVector &Operands) {
6906 MCAsmParser &Parser = getParser();
6909 MipsOperand::CreateToken(
"(", getLexer().getLoc(), *
this));
6911 if (parseOperand(Operands, Name)) {
6912 SMLoc Loc = getLexer().getLoc();
6913 return Error(Loc,
"unexpected token in argument list");
6916 SMLoc Loc = getLexer().getLoc();
6917 return Error(Loc,
"unexpected token, expected ')'");
6920 MipsOperand::CreateToken(
")", getLexer().getLoc(), *
this));
6932bool MipsAsmParser::parseBracketSuffix(StringRef Name,
6934 MCAsmParser &Parser = getParser();
6937 MipsOperand::CreateToken(
"[", getLexer().getLoc(), *
this));
6939 if (parseOperand(Operands, Name)) {
6940 SMLoc Loc = getLexer().getLoc();
6941 return Error(Loc,
"unexpected token in argument list");
6944 SMLoc Loc = getLexer().getLoc();
6945 return Error(Loc,
"unexpected token, expected ']'");
6948 MipsOperand::CreateToken(
"]", getLexer().getLoc(), *
this));
6955 unsigned VariantID = 0);
6970bool MipsAsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
6972 MCAsmParser &Parser = getParser();
6976 getTargetStreamer().forbidModuleDirective();
6979 if (!mnemonicIsValid(Name, 0)) {
6980 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
6982 return Error(NameLoc,
"unknown instruction" + Suggestion);
6985 Operands.
push_back(MipsOperand::CreateToken(Name, NameLoc, *
this));
6990 if (parseOperand(Operands, Name)) {
6991 SMLoc Loc = getLexer().getLoc();
6992 return Error(Loc,
"unexpected token in argument list");
6994 if (getLexer().is(
AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
7001 if (parseOperand(Operands, Name)) {
7002 SMLoc Loc = getLexer().getLoc();
7003 return Error(Loc,
"unexpected token in argument list");
7007 if (parseBracketSuffix(Name, Operands))
7010 parseParenSuffix(Name, Operands))
7015 SMLoc Loc = getLexer().getLoc();
7016 return Error(Loc,
"unexpected token in argument list");
7024bool MipsAsmParser::reportParseError(
const Twine &ErrorMsg) {
7025 SMLoc Loc = getLexer().getLoc();
7026 return Error(Loc, ErrorMsg);
7029bool MipsAsmParser::reportParseError(SMLoc Loc,
const Twine &ErrorMsg) {
7030 return Error(Loc, ErrorMsg);
7033bool MipsAsmParser::parseSetNoAtDirective() {
7034 MCAsmParser &Parser = getParser();
7038 AssemblerOptions.
back()->setATRegIndex(0);
7044 reportParseError(
"unexpected token, expected end of statement");
7048 getTargetStreamer().emitDirectiveSetNoAt();
7053bool MipsAsmParser::parseSetAtDirective() {
7056 MCAsmParser &Parser = getParser();
7061 AssemblerOptions.
back()->setATRegIndex(1);
7063 getTargetStreamer().emitDirectiveSetAt();
7069 reportParseError(
"unexpected token, expected equals sign");
7076 reportParseError(
"no register specified");
7079 reportParseError(
"unexpected token, expected dollar sign '$'");
7089 AtRegNo = matchCPURegisterName(
Reg.getIdentifier());
7091 AtRegNo =
Reg.getIntVal();
7093 reportParseError(
"unexpected token, expected identifier or integer");
7098 if (!AssemblerOptions.
back()->setATRegIndex(AtRegNo)) {
7099 reportParseError(
"invalid register");
7106 reportParseError(
"unexpected token, expected end of statement");
7110 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
7116bool MipsAsmParser::parseSetReorderDirective() {
7117 MCAsmParser &Parser = getParser();
7121 reportParseError(
"unexpected token, expected end of statement");
7124 AssemblerOptions.
back()->setReorder();
7125 getTargetStreamer().emitDirectiveSetReorder();
7130bool MipsAsmParser::parseSetNoReorderDirective() {
7131 MCAsmParser &Parser = getParser();
7135 reportParseError(
"unexpected token, expected end of statement");
7138 AssemblerOptions.
back()->setNoReorder();
7139 getTargetStreamer().emitDirectiveSetNoReorder();
7144bool MipsAsmParser::parseSetMacroDirective() {
7145 MCAsmParser &Parser = getParser();
7149 reportParseError(
"unexpected token, expected end of statement");
7152 AssemblerOptions.
back()->setMacro();
7153 getTargetStreamer().emitDirectiveSetMacro();
7158bool MipsAsmParser::parseSetNoMacroDirective() {
7159 MCAsmParser &Parser = getParser();
7163 reportParseError(
"unexpected token, expected end of statement");
7166 if (AssemblerOptions.
back()->isReorder()) {
7167 reportParseError(
"`noreorder' must be set before `nomacro'");
7170 AssemblerOptions.
back()->setNoMacro();
7171 getTargetStreamer().emitDirectiveSetNoMacro();
7176bool MipsAsmParser::parseSetMsaDirective() {
7177 MCAsmParser &Parser = getParser();
7182 return reportParseError(
"unexpected token, expected end of statement");
7184 setFeatureBits(Mips::FeatureMSA,
"msa");
7185 getTargetStreamer().emitDirectiveSetMsa();
7189bool MipsAsmParser::parseSetNoMsaDirective() {
7190 MCAsmParser &Parser = getParser();
7195 return reportParseError(
"unexpected token, expected end of statement");
7197 clearFeatureBits(Mips::FeatureMSA,
"msa");
7198 getTargetStreamer().emitDirectiveSetNoMsa();
7202bool MipsAsmParser::parseSetNoDspDirective() {
7203 MCAsmParser &Parser = getParser();
7208 reportParseError(
"unexpected token, expected end of statement");
7212 clearFeatureBits(Mips::FeatureDSP,
"dsp");
7213 getTargetStreamer().emitDirectiveSetNoDsp();
7217bool MipsAsmParser::parseSetNoMips3DDirective() {
7218 MCAsmParser &Parser = getParser();
7223 reportParseError(
"unexpected token, expected end of statement");
7227 clearFeatureBits(Mips::FeatureMips3D,
"mips3d");
7228 getTargetStreamer().emitDirectiveSetNoMips3D();
7232bool MipsAsmParser::parseSetMips16Directive() {
7233 MCAsmParser &Parser = getParser();
7238 reportParseError(
"unexpected token, expected end of statement");
7242 setFeatureBits(Mips::FeatureMips16,
"mips16");
7243 getTargetStreamer().emitDirectiveSetMips16();
7248bool MipsAsmParser::parseSetNoMips16Directive() {
7249 MCAsmParser &Parser = getParser();
7254 reportParseError(
"unexpected token, expected end of statement");
7258 clearFeatureBits(Mips::FeatureMips16,
"mips16");
7259 getTargetStreamer().emitDirectiveSetNoMips16();
7264bool MipsAsmParser::parseSetFpDirective() {
7265 MCAsmParser &Parser = getParser();
7271 AsmToken Tok = Parser.
getTok();
7273 reportParseError(
"unexpected token, expected equals sign '='");
7279 if (!parseFpABIValue(FpAbiVal,
".set"))
7283 reportParseError(
"unexpected token, expected end of statement");
7286 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
7291bool MipsAsmParser::parseSetOddSPRegDirective() {
7292 MCAsmParser &Parser = getParser();
7296 reportParseError(
"unexpected token, expected end of statement");
7300 clearFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
7301 getTargetStreamer().emitDirectiveSetOddSPReg();
7305bool MipsAsmParser::parseSetNoOddSPRegDirective() {
7306 MCAsmParser &Parser = getParser();
7310 reportParseError(
"unexpected token, expected end of statement");
7314 setFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
7315 getTargetStreamer().emitDirectiveSetNoOddSPReg();
7319bool MipsAsmParser::parseSetMtDirective() {
7320 MCAsmParser &Parser = getParser();
7325 reportParseError(
"unexpected token, expected end of statement");
7329 setFeatureBits(Mips::FeatureMT,
"mt");
7330 getTargetStreamer().emitDirectiveSetMt();
7335bool MipsAsmParser::parseSetNoMtDirective() {
7336 MCAsmParser &Parser = getParser();
7341 reportParseError(
"unexpected token, expected end of statement");
7345 clearFeatureBits(Mips::FeatureMT,
"mt");
7347 getTargetStreamer().emitDirectiveSetNoMt();
7352bool MipsAsmParser::parseSetNoCRCDirective() {
7353 MCAsmParser &Parser = getParser();
7358 reportParseError(
"unexpected token, expected end of statement");
7362 clearFeatureBits(Mips::FeatureCRC,
"crc");
7364 getTargetStreamer().emitDirectiveSetNoCRC();
7369bool MipsAsmParser::parseSetNoVirtDirective() {
7370 MCAsmParser &Parser = getParser();
7375 reportParseError(
"unexpected token, expected end of statement");
7379 clearFeatureBits(Mips::FeatureVirt,
"virt");
7381 getTargetStreamer().emitDirectiveSetNoVirt();
7386bool MipsAsmParser::parseSetNoGINVDirective() {
7387 MCAsmParser &Parser = getParser();
7392 reportParseError(
"unexpected token, expected end of statement");
7396 clearFeatureBits(Mips::FeatureGINV,
"ginv");
7398 getTargetStreamer().emitDirectiveSetNoGINV();
7403bool MipsAsmParser::parseSetPopDirective() {
7404 MCAsmParser &Parser = getParser();
7405 SMLoc Loc = getLexer().getLoc();
7409 return reportParseError(
"unexpected token, expected end of statement");
7413 if (AssemblerOptions.
size() == 2)
7414 return reportParseError(Loc,
".set pop with no .set push");
7416 MCSubtargetInfo &STI = copySTI();
7418 setAvailableFeatures(
7419 ComputeAvailableFeatures(AssemblerOptions.
back()->getFeatures()));
7422 getTargetStreamer().emitDirectiveSetPop();
7426bool MipsAsmParser::parseSetPushDirective() {
7427 MCAsmParser &Parser = getParser();
7430 return reportParseError(
"unexpected token, expected end of statement");
7434 std::make_unique<MipsAssemblerOptions>(AssemblerOptions.
back().get()));
7436 getTargetStreamer().emitDirectiveSetPush();
7440bool MipsAsmParser::parseSetSoftFloatDirective() {
7441 MCAsmParser &Parser = getParser();
7444 return reportParseError(
"unexpected token, expected end of statement");
7446 setFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
7447 getTargetStreamer().emitDirectiveSetSoftFloat();
7451bool MipsAsmParser::parseSetHardFloatDirective() {
7452 MCAsmParser &Parser = getParser();
7455 return reportParseError(
"unexpected token, expected end of statement");
7457 clearFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
7458 getTargetStreamer().emitDirectiveSetHardFloat();
7462bool MipsAsmParser::parseSetAssignment() {
7464 MCAsmParser &Parser = getParser();
7467 return reportParseError(
"expected identifier after .set");
7470 return reportParseError(
"unexpected token, expected comma");
7485 const MCExpr *
Value;
7487 Parser, Sym,
Value))
7489 getStreamer().emitAssignment(Sym,
Value);
7494bool MipsAsmParser::parseSetMips0Directive() {
7495 MCAsmParser &Parser = getParser();
7498 return reportParseError(
"unexpected token, expected end of statement");
7501 MCSubtargetInfo &STI = copySTI();
7502 setAvailableFeatures(
7503 ComputeAvailableFeatures(AssemblerOptions.
front()->getFeatures()));
7505 AssemblerOptions.
back()->setFeatures(AssemblerOptions.
front()->getFeatures());
7507 getTargetStreamer().emitDirectiveSetMips0();
7511bool MipsAsmParser::parseSetArchDirective() {
7512 MCAsmParser &Parser = getParser();
7515 return reportParseError(
"unexpected token, expected equals sign");
7518 StringRef Arch = getParser().parseStringToEndOfStatement().trim();
7520 return reportParseError(
"expected arch identifier");
7522 StringRef ArchFeatureName =
7523 StringSwitch<StringRef>(Arch)
7524 .Case(
"mips1",
"mips1")
7525 .Case(
"mips2",
"mips2")
7526 .Case(
"mips3",
"mips3")
7527 .Case(
"mips4",
"mips4")
7528 .Case(
"mips5",
"mips5")
7529 .Case(
"mips32",
"mips32")
7530 .Case(
"mips32r2",
"mips32r2")
7531 .Case(
"mips32r3",
"mips32r3")
7532 .Case(
"mips32r5",
"mips32r5")
7533 .Case(
"mips32r6",
"mips32r6")
7534 .Case(
"mips64",
"mips64")
7535 .Case(
"mips64r2",
"mips64r2")
7536 .Case(
"mips64r3",
"mips64r3")
7537 .Case(
"mips64r5",
"mips64r5")
7538 .Case(
"mips64r6",
"mips64r6")
7539 .Case(
"octeon",
"cnmips")
7540 .Case(
"octeon+",
"cnmipsp")
7541 .Case(
"r4000",
"mips3")
7544 if (ArchFeatureName.
empty())
7545 return reportParseError(
"unsupported architecture");
7547 if (ArchFeatureName ==
"mips64r6" && inMicroMipsMode())
7548 return reportParseError(
"mips64r6 does not support microMIPS");
7550 selectArch(ArchFeatureName);
7551 getTargetStreamer().emitDirectiveSetArch(Arch);
7555bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
7556 MCAsmParser &Parser = getParser();
7559 return reportParseError(
"unexpected token, expected end of statement");
7564 case Mips::FeatureMips3D:
7565 setFeatureBits(Mips::FeatureMips3D,
"mips3d");
7566 getTargetStreamer().emitDirectiveSetMips3D();
7568 case Mips::FeatureDSP:
7569 setFeatureBits(Mips::FeatureDSP,
"dsp");
7570 getTargetStreamer().emitDirectiveSetDsp();
7572 case Mips::FeatureDSPR2:
7573 setFeatureBits(Mips::FeatureDSPR2,
"dspr2");
7574 getTargetStreamer().emitDirectiveSetDspr2();
7576 case Mips::FeatureMicroMips:
7577 setFeatureBits(Mips::FeatureMicroMips,
"micromips");
7578 getTargetStreamer().emitDirectiveSetMicroMips();
7580 case Mips::FeatureMips1:
7581 selectArch(
"mips1");
7582 getTargetStreamer().emitDirectiveSetMips1();
7584 case Mips::FeatureMips2:
7585 selectArch(
"mips2");
7586 getTargetStreamer().emitDirectiveSetMips2();
7588 case Mips::FeatureMips3:
7589 selectArch(
"mips3");
7590 getTargetStreamer().emitDirectiveSetMips3();
7592 case Mips::FeatureMips4:
7593 selectArch(
"mips4");
7594 getTargetStreamer().emitDirectiveSetMips4();
7596 case Mips::FeatureMips5:
7597 selectArch(
"mips5");
7598 getTargetStreamer().emitDirectiveSetMips5();
7600 case Mips::FeatureMips32:
7601 selectArch(
"mips32");
7602 getTargetStreamer().emitDirectiveSetMips32();
7604 case Mips::FeatureMips32r2:
7605 selectArch(
"mips32r2");
7606 getTargetStreamer().emitDirectiveSetMips32R2();
7608 case Mips::FeatureMips32r3:
7609 selectArch(
"mips32r3");
7610 getTargetStreamer().emitDirectiveSetMips32R3();
7612 case Mips::FeatureMips32r5:
7613 selectArch(
"mips32r5");
7614 getTargetStreamer().emitDirectiveSetMips32R5();
7616 case Mips::FeatureMips32r6:
7617 selectArch(
"mips32r6");
7618 getTargetStreamer().emitDirectiveSetMips32R6();
7620 case Mips::FeatureMips64:
7621 selectArch(
"mips64");
7622 getTargetStreamer().emitDirectiveSetMips64();
7624 case Mips::FeatureMips64r2:
7625 selectArch(
"mips64r2");
7626 getTargetStreamer().emitDirectiveSetMips64R2();
7628 case Mips::FeatureMips64r3:
7629 selectArch(
"mips64r3");
7630 getTargetStreamer().emitDirectiveSetMips64R3();
7632 case Mips::FeatureMips64r5:
7633 selectArch(
"mips64r5");
7634 getTargetStreamer().emitDirectiveSetMips64R5();
7636 case Mips::FeatureMips64r6:
7637 selectArch(
"mips64r6");
7638 getTargetStreamer().emitDirectiveSetMips64R6();
7640 case Mips::FeatureCRC:
7641 setFeatureBits(Mips::FeatureCRC,
"crc");
7642 getTargetStreamer().emitDirectiveSetCRC();
7644 case Mips::FeatureVirt:
7645 setFeatureBits(Mips::FeatureVirt,
"virt");
7646 getTargetStreamer().emitDirectiveSetVirt();
7648 case Mips::FeatureGINV:
7649 setFeatureBits(Mips::FeatureGINV,
"ginv");
7650 getTargetStreamer().emitDirectiveSetGINV();
7656bool MipsAsmParser::eatComma(StringRef ErrorStr) {
7657 MCAsmParser &Parser = getParser();
7659 SMLoc Loc = getLexer().getLoc();
7660 return Error(Loc, ErrorStr);
7671bool MipsAsmParser::isPicAndNotNxxAbi() {
7672 return inPicMode() && !(isABI_N32() || isABI_N64());
7675bool MipsAsmParser::parseDirectiveCpAdd(SMLoc Loc) {
7677 ParseStatus Res = parseAnyRegister(
Reg);
7679 reportParseError(
"expected register");
7683 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7684 if (!RegOpnd.isGPRAsmReg()) {
7685 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7691 reportParseError(
"unexpected token, expected end of statement");
7696 getTargetStreamer().emitDirectiveCpAdd(RegOpnd.getGPR32Reg());
7700bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
7701 if (AssemblerOptions.
back()->isReorder())
7702 Warning(Loc,
".cpload should be inside a noreorder section");
7704 if (inMips16Mode()) {
7705 reportParseError(
".cpload is not supported in Mips16 mode");
7710 ParseStatus Res = parseAnyRegister(
Reg);
7712 reportParseError(
"expected register containing function address");
7716 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7717 if (!RegOpnd.isGPRAsmReg()) {
7718 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7724 reportParseError(
"unexpected token, expected end of statement");
7728 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
7732bool MipsAsmParser::parseDirectiveCpLocal(SMLoc Loc) {
7733 if (!isABI_N32() && !isABI_N64()) {
7734 reportParseError(
".cplocal is allowed only in N32 or N64 mode");
7739 ParseStatus Res = parseAnyRegister(
Reg);
7741 reportParseError(
"expected register containing global pointer");
7745 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7746 if (!RegOpnd.isGPRAsmReg()) {
7747 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7753 reportParseError(
"unexpected token, expected end of statement");
7758 MCRegister NewReg = RegOpnd.getGPR32Reg();
7762 getTargetStreamer().emitDirectiveCpLocal(NewReg);
7766bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
7767 MCAsmParser &Parser = getParser();
7772 if (inMips16Mode()) {
7773 reportParseError(
".cprestore is not supported in Mips16 mode");
7778 const MCExpr *StackOffset;
7779 int64_t StackOffsetVal;
7781 reportParseError(
"expected stack offset value");
7785 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
7786 reportParseError(
"stack offset is not an absolute expression");
7790 if (StackOffsetVal < 0) {
7791 Warning(Loc,
".cprestore with negative stack offset has no effect");
7792 IsCpRestoreSet =
false;
7794 IsCpRestoreSet =
true;
7795 CpRestoreOffset = StackOffsetVal;
7800 reportParseError(
"unexpected token, expected end of statement");
7804 if (!getTargetStreamer().emitDirectiveCpRestore(
7805 CpRestoreOffset, [&]() {
return getATReg(Loc); }, Loc, STI))
7811bool MipsAsmParser::parseDirectiveCPSetup() {
7812 MCAsmParser &Parser = getParser();
7814 bool SaveIsReg =
true;
7817 ParseStatus Res = parseAnyRegister(TmpReg);
7819 reportParseError(
"expected register containing function address");
7823 MipsOperand &FuncRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7824 if (!FuncRegOpnd.isGPRAsmReg()) {
7825 reportParseError(FuncRegOpnd.getStartLoc(),
"invalid register");
7829 MCRegister FuncReg = FuncRegOpnd.getGPR32Reg();
7832 if (!eatComma(
"unexpected token, expected comma"))
7835 Res = parseAnyRegister(TmpReg);
7837 const MCExpr *OffsetExpr;
7839 SMLoc ExprLoc = getLexer().
getLoc();
7842 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
7843 reportParseError(ExprLoc,
"expected save register or stack offset");
7850 MipsOperand &SaveOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7851 if (!SaveOpnd.isGPRAsmReg()) {
7852 reportParseError(SaveOpnd.getStartLoc(),
"invalid register");
7855 Save = SaveOpnd.getGPR32Reg().id();
7858 if (!eatComma(
"unexpected token, expected comma"))
7863 reportParseError(
"expected expression");
7868 reportParseError(
"expected symbol");
7871 const MCSymbolRefExpr *
Ref =
static_cast<const MCSymbolRefExpr *
>(Expr);
7873 CpSaveLocation = Save;
7874 CpSaveLocationIsRegister = SaveIsReg;
7876 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save,
Ref->getSymbol(),
7881bool MipsAsmParser::parseDirectiveCPReturn() {
7882 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
7883 CpSaveLocationIsRegister);
7887bool MipsAsmParser::parseDirectiveNaN() {
7888 MCAsmParser &Parser = getParser();
7890 const AsmToken &Tok = Parser.
getTok();
7894 getTargetStreamer().emitDirectiveNaN2008();
7896 }
else if (Tok.
getString() ==
"legacy") {
7898 getTargetStreamer().emitDirectiveNaNLegacy();
7904 reportParseError(
"invalid option in .nan directive");
7908bool MipsAsmParser::parseDirectiveSet() {
7909 const AsmToken &Tok = getParser().getTok();
7911 SMLoc Loc = Tok.
getLoc();
7913 if (IdVal ==
"noat")
7914 return parseSetNoAtDirective();
7916 return parseSetAtDirective();
7917 if (IdVal ==
"arch")
7918 return parseSetArchDirective();
7919 if (IdVal ==
"bopt") {
7920 Warning(Loc,
"'bopt' feature is unsupported");
7924 if (IdVal ==
"nobopt") {
7930 return parseSetFpDirective();
7931 if (IdVal ==
"oddspreg")
7932 return parseSetOddSPRegDirective();
7933 if (IdVal ==
"nooddspreg")
7934 return parseSetNoOddSPRegDirective();
7936 return parseSetPopDirective();
7937 if (IdVal ==
"push")
7938 return parseSetPushDirective();
7939 if (IdVal ==
"reorder")
7940 return parseSetReorderDirective();
7941 if (IdVal ==
"noreorder")
7942 return parseSetNoReorderDirective();
7943 if (IdVal ==
"macro")
7944 return parseSetMacroDirective();
7945 if (IdVal ==
"nomacro")
7946 return parseSetNoMacroDirective();
7947 if (IdVal ==
"mips16")
7948 return parseSetMips16Directive();
7949 if (IdVal ==
"nomips16")
7950 return parseSetNoMips16Directive();
7951 if (IdVal ==
"nomicromips") {
7952 clearFeatureBits(Mips::FeatureMicroMips,
"micromips");
7953 getTargetStreamer().emitDirectiveSetNoMicroMips();
7954 getParser().eatToEndOfStatement();
7957 if (IdVal ==
"micromips") {
7958 if (hasMips64r6()) {
7959 Error(Loc,
".set micromips directive is not supported with MIPS64R6");
7962 return parseSetFeature(Mips::FeatureMicroMips);
7964 if (IdVal ==
"mips0")
7965 return parseSetMips0Directive();
7966 if (IdVal ==
"mips1")
7967 return parseSetFeature(Mips::FeatureMips1);
7968 if (IdVal ==
"mips2")
7969 return parseSetFeature(Mips::FeatureMips2);
7970 if (IdVal ==
"mips3")
7971 return parseSetFeature(Mips::FeatureMips3);
7972 if (IdVal ==
"mips4")
7973 return parseSetFeature(Mips::FeatureMips4);
7974 if (IdVal ==
"mips5")
7975 return parseSetFeature(Mips::FeatureMips5);
7976 if (IdVal ==
"mips32")
7977 return parseSetFeature(Mips::FeatureMips32);
7978 if (IdVal ==
"mips32r2")
7979 return parseSetFeature(Mips::FeatureMips32r2);
7980 if (IdVal ==
"mips32r3")
7981 return parseSetFeature(Mips::FeatureMips32r3);
7982 if (IdVal ==
"mips32r5")
7983 return parseSetFeature(Mips::FeatureMips32r5);
7984 if (IdVal ==
"mips32r6")
7985 return parseSetFeature(Mips::FeatureMips32r6);
7986 if (IdVal ==
"mips64")
7987 return parseSetFeature(Mips::FeatureMips64);
7988 if (IdVal ==
"mips64r2")
7989 return parseSetFeature(Mips::FeatureMips64r2);
7990 if (IdVal ==
"mips64r3")
7991 return parseSetFeature(Mips::FeatureMips64r3);
7992 if (IdVal ==
"mips64r5")
7993 return parseSetFeature(Mips::FeatureMips64r5);
7994 if (IdVal ==
"mips64r6") {
7995 if (inMicroMipsMode()) {
7996 Error(Loc,
"MIPS64R6 is not supported with microMIPS");
7999 return parseSetFeature(Mips::FeatureMips64r6);
8002 return parseSetFeature(Mips::FeatureDSP);
8003 if (IdVal ==
"dspr2")
8004 return parseSetFeature(Mips::FeatureDSPR2);
8005 if (IdVal ==
"nodsp")
8006 return parseSetNoDspDirective();
8007 if (IdVal ==
"mips3d")
8008 return parseSetFeature(Mips::FeatureMips3D);
8009 if (IdVal ==
"nomips3d")
8010 return parseSetNoMips3DDirective();
8012 return parseSetMsaDirective();
8013 if (IdVal ==
"nomsa")
8014 return parseSetNoMsaDirective();
8016 return parseSetMtDirective();
8017 if (IdVal ==
"nomt")
8018 return parseSetNoMtDirective();
8019 if (IdVal ==
"softfloat")
8020 return parseSetSoftFloatDirective();
8021 if (IdVal ==
"hardfloat")
8022 return parseSetHardFloatDirective();
8024 return parseSetFeature(Mips::FeatureCRC);
8025 if (IdVal ==
"nocrc")
8026 return parseSetNoCRCDirective();
8027 if (IdVal ==
"virt")
8028 return parseSetFeature(Mips::FeatureVirt);
8029 if (IdVal ==
"novirt")
8030 return parseSetNoVirtDirective();
8031 if (IdVal ==
"ginv")
8032 return parseSetFeature(Mips::FeatureGINV);
8033 if (IdVal ==
"noginv")
8034 return parseSetNoGINVDirective();
8037 return parseSetAssignment();
8042bool MipsAsmParser::parseDirectiveGpWord() {
8043 const MCExpr *
Value;
8044 if (getParser().parseExpression(
Value))
8046 getTargetStreamer().emitGPRel32Value(
Value);
8052bool MipsAsmParser::parseDirectiveGpDWord() {
8053 const MCExpr *
Value;
8054 if (getParser().parseExpression(
Value))
8056 getTargetStreamer().emitGPRel64Value(
Value);
8062bool MipsAsmParser::parseDirectiveDtpRelWord() {
8063 const MCExpr *
Value;
8064 if (getParser().parseExpression(
Value))
8066 getTargetStreamer().emitDTPRel32Value(
Value);
8072bool MipsAsmParser::parseDirectiveDtpRelDWord() {
8073 const MCExpr *
Value;
8074 if (getParser().parseExpression(
Value))
8076 getTargetStreamer().emitDTPRel64Value(
Value);
8082bool MipsAsmParser::parseDirectiveTpRelWord() {
8083 const MCExpr *
Value;
8084 if (getParser().parseExpression(
Value))
8086 getTargetStreamer().emitTPRel32Value(
Value);
8092bool MipsAsmParser::parseDirectiveTpRelDWord() {
8093 const MCExpr *
Value;
8094 if (getParser().parseExpression(
Value))
8096 getTargetStreamer().emitTPRel64Value(
Value);
8100bool MipsAsmParser::parseDirectiveOption() {
8101 MCAsmParser &Parser = getParser();
8103 AsmToken Tok = Parser.
getTok();
8107 "unexpected token, expected identifier");
8112 if (Option ==
"pic0") {
8114 IsPicEnabled =
false;
8116 getTargetStreamer().emitDirectiveOptionPic0();
8120 "unexpected token, expected end of statement");
8125 if (Option ==
"pic2") {
8127 IsPicEnabled =
true;
8129 getTargetStreamer().emitDirectiveOptionPic2();
8133 "unexpected token, expected end of statement");
8140 "unknown option, expected 'pic0' or 'pic2'");
8147bool MipsAsmParser::parseInsnDirective() {
8150 reportParseError(
"unexpected token, expected end of statement");
8156 getTargetStreamer().emitDirectiveInsn();
8164bool MipsAsmParser::parseRSectionDirective(StringRef Section) {
8167 reportParseError(
"unexpected token, expected end of statement");
8171 MCSection *ELFSection =
getContext().getELFSection(
8173 getParser().getStreamer().switchSection(ELFSection);
8182bool MipsAsmParser::parseSSectionDirective(StringRef Section,
unsigned Type) {
8185 reportParseError(
"unexpected token, expected end of statement");
8189 MCSection *ELFSection =
getContext().getELFSection(
8191 getParser().getStreamer().switchSection(ELFSection);
8210bool MipsAsmParser::parseDirectiveModule() {
8211 MCAsmParser &Parser = getParser();
8212 AsmLexer &Lexer = getLexer();
8215 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
8217 reportParseError(
".module directive must appear before any code");
8223 reportParseError(
"expected .module option identifier");
8227 if (Option ==
"oddspreg") {
8228 clearModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
8232 getTargetStreamer().updateABIInfo(*
this);
8237 getTargetStreamer().emitDirectiveModuleOddSPReg();
8241 reportParseError(
"unexpected token, expected end of statement");
8246 }
else if (Option ==
"nooddspreg") {
8248 return Error(L,
"'.module nooddspreg' requires the O32 ABI");
8251 setModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
8255 getTargetStreamer().updateABIInfo(*
this);
8260 getTargetStreamer().emitDirectiveModuleOddSPReg();
8264 reportParseError(
"unexpected token, expected end of statement");
8269 }
else if (Option ==
"fp") {
8270 return parseDirectiveModuleFP();
8271 }
else if (Option ==
"softfloat") {
8272 setModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
8276 getTargetStreamer().updateABIInfo(*
this);
8281 getTargetStreamer().emitDirectiveModuleSoftFloat();
8285 reportParseError(
"unexpected token, expected end of statement");
8290 }
else if (Option ==
"hardfloat") {
8291 clearModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
8295 getTargetStreamer().updateABIInfo(*
this);
8300 getTargetStreamer().emitDirectiveModuleHardFloat();
8304 reportParseError(
"unexpected token, expected end of statement");
8309 }
else if (Option ==
"mt") {
8310 setModuleFeatureBits(Mips::FeatureMT,
"mt");
8314 getTargetStreamer().updateABIInfo(*
this);
8319 getTargetStreamer().emitDirectiveModuleMT();
8323 reportParseError(
"unexpected token, expected end of statement");
8328 }
else if (Option ==
"crc") {
8329 setModuleFeatureBits(Mips::FeatureCRC,
"crc");
8333 getTargetStreamer().updateABIInfo(*
this);
8338 getTargetStreamer().emitDirectiveModuleCRC();
8342 reportParseError(
"unexpected token, expected end of statement");
8347 }
else if (Option ==
"nocrc") {
8348 clearModuleFeatureBits(Mips::FeatureCRC,
"crc");
8352 getTargetStreamer().updateABIInfo(*
this);
8357 getTargetStreamer().emitDirectiveModuleNoCRC();
8361 reportParseError(
"unexpected token, expected end of statement");
8366 }
else if (Option ==
"virt") {
8367 setModuleFeatureBits(Mips::FeatureVirt,
"virt");
8371 getTargetStreamer().updateABIInfo(*
this);
8376 getTargetStreamer().emitDirectiveModuleVirt();
8380 reportParseError(
"unexpected token, expected end of statement");
8385 }
else if (Option ==
"novirt") {
8386 clearModuleFeatureBits(Mips::FeatureVirt,
"virt");
8390 getTargetStreamer().updateABIInfo(*
this);
8395 getTargetStreamer().emitDirectiveModuleNoVirt();
8399 reportParseError(
"unexpected token, expected end of statement");
8404 }
else if (Option ==
"ginv") {
8405 setModuleFeatureBits(Mips::FeatureGINV,
"ginv");
8409 getTargetStreamer().updateABIInfo(*
this);
8414 getTargetStreamer().emitDirectiveModuleGINV();
8418 reportParseError(
"unexpected token, expected end of statement");
8423 }
else if (Option ==
"noginv") {
8424 clearModuleFeatureBits(Mips::FeatureGINV,
"ginv");
8428 getTargetStreamer().updateABIInfo(*
this);
8433 getTargetStreamer().emitDirectiveModuleNoGINV();
8437 reportParseError(
"unexpected token, expected end of statement");
8443 return Error(L,
"'" + Twine(Option) +
"' is not a valid .module option.");
8451bool MipsAsmParser::parseDirectiveModuleFP() {
8452 MCAsmParser &Parser = getParser();
8453 AsmLexer &Lexer = getLexer();
8456 reportParseError(
"unexpected token, expected equals sign '='");
8462 if (!parseFpABIValue(FpABI,
".module"))
8466 reportParseError(
"unexpected token, expected end of statement");
8472 getTargetStreamer().updateABIInfo(*
this);
8477 getTargetStreamer().emitDirectiveModuleFP();
8484 StringRef Directive) {
8485 MCAsmParser &Parser = getParser();
8486 AsmLexer &Lexer = getLexer();
8487 bool ModuleLevelOptions = Directive ==
".module";
8493 if (
Value !=
"xx") {
8494 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
8499 reportParseError(
"'" + Directive +
" fp=xx' requires the O32 ABI");
8503 FpABI = MipsABIFlagsSection::FpABIKind::XX;
8504 if (ModuleLevelOptions) {
8505 setModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8506 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8508 setFeatureBits(Mips::FeatureFPXX,
"fpxx");
8509 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8519 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
8525 reportParseError(
"'" + Directive +
" fp=32' requires the O32 ABI");
8529 FpABI = MipsABIFlagsSection::FpABIKind::S32;
8530 if (ModuleLevelOptions) {
8531 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8532 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8534 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
8535 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8538 FpABI = MipsABIFlagsSection::FpABIKind::S64;
8539 if (ModuleLevelOptions) {
8540 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8541 setModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8543 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
8544 setFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8554bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
8560 MCAsmParser &Parser = getParser();
8561 StringRef IDVal = DirectiveID.
getString();
8563 if (IDVal ==
".cpadd") {
8564 parseDirectiveCpAdd(DirectiveID.
getLoc());
8567 if (IDVal ==
".cpload") {
8568 parseDirectiveCpLoad(DirectiveID.
getLoc());
8571 if (IDVal ==
".cprestore") {
8572 parseDirectiveCpRestore(DirectiveID.
getLoc());
8575 if (IDVal ==
".cplocal") {
8576 parseDirectiveCpLocal(DirectiveID.
getLoc());
8579 if (IDVal ==
".ent") {
8583 reportParseError(
"expected identifier after .ent");
8597 reportParseError(
"unexpected token, expected end of statement");
8601 const MCExpr *DummyNumber;
8602 int64_t DummyNumberVal;
8606 reportParseError(
"expected number after comma");
8609 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
8610 reportParseError(
"expected an absolute expression after comma");
8617 reportParseError(
"unexpected token, expected end of statement");
8623 getTargetStreamer().emitDirectiveEnt(*Sym);
8625 IsCpRestoreSet =
false;
8629 if (IDVal ==
".end") {
8633 reportParseError(
"expected identifier after .end");
8638 reportParseError(
"unexpected token, expected end of statement");
8642 if (CurrentFn ==
nullptr) {
8643 reportParseError(
".end used without .ent");
8647 if ((SymbolName != CurrentFn->
getName())) {
8648 reportParseError(
".end symbol does not match .ent symbol");
8652 getTargetStreamer().emitDirectiveEnd(SymbolName);
8653 CurrentFn =
nullptr;
8654 IsCpRestoreSet =
false;
8658 if (IDVal ==
".frame") {
8661 ParseStatus Res = parseAnyRegister(TmpReg);
8663 reportParseError(
"expected stack register");
8667 MipsOperand &StackRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
8668 if (!StackRegOpnd.isGPRAsmReg()) {
8669 reportParseError(StackRegOpnd.getStartLoc(),
8670 "expected general purpose register");
8673 MCRegister StackReg = StackRegOpnd.getGPR32Reg();
8678 reportParseError(
"unexpected token, expected comma");
8683 const MCExpr *FrameSize;
8684 int64_t FrameSizeVal;
8687 reportParseError(
"expected frame size value");
8691 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
8692 reportParseError(
"frame size not an absolute expression");
8699 reportParseError(
"unexpected token, expected comma");
8705 Res = parseAnyRegister(TmpReg);
8707 reportParseError(
"expected return register");
8711 MipsOperand &ReturnRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
8712 if (!ReturnRegOpnd.isGPRAsmReg()) {
8713 reportParseError(ReturnRegOpnd.getStartLoc(),
8714 "expected general purpose register");
8720 reportParseError(
"unexpected token, expected end of statement");
8724 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
8725 ReturnRegOpnd.getGPR32Reg());
8726 IsCpRestoreSet =
false;
8730 if (IDVal ==
".set") {
8731 parseDirectiveSet();
8735 if (IDVal ==
".mask" || IDVal ==
".fmask") {
8746 const MCExpr *BitMask;
8750 reportParseError(
"expected bitmask value");
8754 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
8755 reportParseError(
"bitmask not an absolute expression");
8762 reportParseError(
"unexpected token, expected comma");
8767 const MCExpr *FrameOffset;
8768 int64_t FrameOffsetVal;
8771 reportParseError(
"expected frame offset value");
8775 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
8776 reportParseError(
"frame offset not an absolute expression");
8782 reportParseError(
"unexpected token, expected end of statement");
8786 if (IDVal ==
".mask")
8787 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
8789 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
8793 if (IDVal ==
".nan")
8794 return parseDirectiveNaN();
8796 if (IDVal ==
".gpword") {
8797 parseDirectiveGpWord();
8801 if (IDVal ==
".gpdword") {
8802 parseDirectiveGpDWord();
8806 if (IDVal ==
".dtprelword") {
8807 parseDirectiveDtpRelWord();
8811 if (IDVal ==
".dtpreldword") {
8812 parseDirectiveDtpRelDWord();
8816 if (IDVal ==
".tprelword") {
8817 parseDirectiveTpRelWord();
8821 if (IDVal ==
".tpreldword") {
8822 parseDirectiveTpRelDWord();
8826 if (IDVal ==
".option") {
8827 parseDirectiveOption();
8831 if (IDVal ==
".abicalls") {
8832 getTargetStreamer().emitDirectiveAbiCalls();
8835 "unexpected token, expected end of statement");
8840 if (IDVal ==
".cpsetup") {
8841 parseDirectiveCPSetup();
8844 if (IDVal ==
".cpreturn") {
8845 parseDirectiveCPReturn();
8848 if (IDVal ==
".module") {
8849 parseDirectiveModule();
8852 if (IDVal ==
".llvm_internal_mips_reallow_module_directive") {
8853 parseInternalDirectiveReallowModule();
8856 if (IDVal ==
".insn") {
8857 parseInsnDirective();
8860 if (IDVal ==
".rdata") {
8861 parseRSectionDirective(
".rodata");
8864 if (IDVal ==
".sbss") {
8868 if (IDVal ==
".sdata") {
8876bool MipsAsmParser::parseInternalDirectiveReallowModule() {
8879 reportParseError(
"unexpected token, expected end of statement");
8883 getTargetStreamer().reallowModuleDirective();
8897#define GET_REGISTER_MATCHER
8898#define GET_MATCHER_IMPLEMENTATION
8899#define GET_MNEMONIC_SPELL_CHECKER
8900#include "MipsGenAsmMatcher.inc"
8902bool MipsAsmParser::mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID) {
8904 const MatchEntry *Start, *End;
8905 switch (VariantID) {
8907 case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0);
break;
8910 auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
8911 return MnemonicRange.first != MnemonicRange.second;
static const TargetRegisterClass * getRegClass(const MachineInstr &MI, Register Reg)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
This file declares a class to represent arbitrary precision floating point values and provide a varie...
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
static Value * expandAbs(CallInst *Orig)
std::pair< Instruction::BinaryOps, Value * > OffsetOp
Find all possible pairs (BinOp, RHS) that BinOp V, RHS can be simplified.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static FeatureBitset getFeatures(MCSubtargetInfo &STI, StringRef CPU, StringRef TuneCPU, StringRef FS, ArrayRef< StringRef > ProcNames, ArrayRef< SubtargetSubTypeKV > ProcDesc, ArrayRef< SubtargetFeatureKV > ProcFeatures)
static unsigned countMCSymbolRefExpr(const MCExpr *Expr)
static std::string MipsMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, unsigned VariantID=0)
static uint64_t convertIntToDoubleImm(uint64_t ImmOp64)
static uint32_t covertDoubleImmToSingleImm(uint64_t ImmOp64)
static unsigned getRegisterForMxtrDSP(MCInst &Inst, bool IsMFDSP)
static bool hasShortDelaySlot(MCInst &Inst)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsAsmParser()
static bool needsExpandMemInst(MCInst &Inst, const MCInstrDesc &MCID)
cl::opt< bool > EmitJalrReloc
static bool isShiftedUIntAtAnyPosition(uint64_t x)
Can the value be represented by a unsigned N-bit value and a shift left?
static bool isEvaluated(const MCExpr *Expr)
static unsigned getRegisterForMxtrC0(MCInst &Inst, bool IsMFTC0)
static const MCSymbol * getSingleMCSymbol(const MCExpr *Expr)
static MCRegister nextReg(MCRegister Reg)
static unsigned getRegisterForMxtrFP(MCInst &Inst, bool IsMFTC1)
cl::opt< bool > NoZeroDivCheck
static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands, uint64_t ErrorInfo)
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
static PPCTargetMachine::PPCABI computeTargetABI(const Triple &TT, const TargetOptions &Options)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static const fltSemantics & IEEEdouble()
APInt bitcastToAPInt() const
uint64_t getZExtValue() const
Get zero extended value.
SMLoc getLoc() const
Get the current source location.
const AsmToken peekTok(bool ShouldSkipSpace=true)
Look ahead at the next token to be lexed.
bool is(AsmToken::TokenKind K) const
Check if the current token has kind K.
bool isNot(AsmToken::TokenKind K) const
Check if the current token has kind K.
Target independent representation for an assembler token.
LLVM_ABI SMLoc getLoc() const
int64_t getIntVal() const
bool isNot(TokenKind K) const
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
bool is(TokenKind K) const
TokenKind getKind() const
LLVM_ABI SMRange getLocRange() const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
Base class for user error types.
Container class for subtarget features.
void printExpr(raw_ostream &, const MCExpr &) const
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
bool parseToken(AsmToken::TokenKind T, const Twine &Msg="unexpected token")
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
Binary assembler expressions.
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
static LLVM_ABI const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
@ LShr
Logical shift right.
@ Xor
Bitwise exclusive or.
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Base class for the full range of assembler expressions which are needed for parsing.
LLVM_ABI bool evaluateAsRelocatable(MCValue &Res, const MCAssembler *Asm) const
Try to evaluate the expression to a relocatable value, i.e.
@ Unary
Unary expressions.
@ Constant
Constant expressions.
@ SymbolRef
References to labels and assigned expressions.
@ Target
Target specific expression.
@ Specifier
Expression with a relocation specifier.
@ Binary
Binary expressions.
Instances of this class represent a single low-level machine instruction.
unsigned getNumOperands() const
unsigned getOpcode() const
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
const MCOperand & getOperand(unsigned i) const
Describe properties that are true of each instruction in the target description file.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
ArrayRef< MCOperandInfo > operands() const
bool mayStore() const
Return true if this instruction could possibly modify memory.
bool mayLoad() const
Return true if this instruction could possibly read memory.
bool isBranch() const
Returns true if this is a conditional, unconditional, or indirect branch.
bool isCall() const
Return true if the instruction is a call.
bool hasDelaySlot() const
Returns true if the specified instruction has a delay slot which must be filled by the code generator...
Interface to description of machine instruction set.
This holds information about one operand of a machine instruction, indicating the register class for ...
uint8_t OperandType
Information about the type of the operand.
Instances of this class represent operands of the MCInst class.
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
MCRegister getReg() const
Returns the register number.
const MCExpr * getExpr() const
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual bool isReg() const =0
isReg - Is this a register operand?
virtual MCRegister getReg() const =0
Wrapper class representing physical registers. Should be passed by value.
constexpr bool isValid() const
constexpr unsigned id() const
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
Streaming machine code generation interface.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
virtual void emitRelocDirective(const MCExpr &Offset, StringRef Name, const MCExpr *Expr, SMLoc Loc={})
Record a relocation described by the .reloc directive.
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
void setFeatureBits(const FeatureBitset &FeatureBits_)
const Triple & getTargetTriple() const
const FeatureBitset & getFeatureBits() const
const FeatureBitset & ToggleFeature(uint64_t FB)
Toggle a feature and return the re-computed feature bits.
virtual unsigned getHwMode(enum HwModeType type=HwMode_Default) const
HwMode ID corresponding to the 'type' parameter is retrieved from the HwMode bit set of the current s...
Represent a reference to a symbol from inside an expression.
uint16_t getSpecifier() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
bool isInSection() const
isInSection - Check if this symbol is defined in some section (i.e., it is defined but not absolute).
bool isUndefined() const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).
StringRef getName() const
getName - Get the symbol name.
bool isVariable() const
isVariable - Check if this is a variable symbol.
const MCExpr * getVariableValue() const
Get the expression of the variable symbol.
bool isTemporary() const
isTemporary - Check if this is an assembler temporary symbol.
MCTargetAsmParser - Generic interface to target specific assembly parsers.
MCStreamer & getStreamer()
Unary assembler expressions.
const MCSymbol * getAddSym() const
int64_t getConstant() const
const MCSymbol * getSubSym() const
void emitRRX(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, MCOperand Op2, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveSetReorder()
void emitRRRX(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, MCRegister Reg2, MCOperand Op3, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRX(unsigned Opcode, MCRegister Reg0, MCOperand Op1, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitR(unsigned Opcode, MCRegister Reg0, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void setUsesMicroMips()
void emitRRI(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, int16_t Imm, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitEmptyDelaySlot(bool hasShortDelaySlot, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRI(unsigned Opcode, MCRegister Reg0, int32_t Imm, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRR(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, SMLoc IDLoc, const MCSubtargetInfo *STI)
void updateABIInfo(const PredicateLibrary &P)
void emitRRIII(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, int16_t Imm0, int16_t Imm1, int16_t Imm2, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitDSLL(MCRegister DstReg, MCRegister SrcReg, int16_t ShiftAmount, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitGPRestore(int Offset, SMLoc IDLoc, const MCSubtargetInfo *STI)
Emit the $gp restore operation for .cprestore.
void emitNop(SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRRR(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, MCRegister Reg2, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveSetNoReorder()
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
static constexpr StatusTy Failure
constexpr bool isSuccess() const
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
constexpr bool isNoMatch() const
constexpr unsigned id() const
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
void push_back(const T &Elt)
iterator find(StringRef Key)
StringRef - Represent a constant reference to a string, i.e.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
empty - Check if the string is empty.
LLVM_ABI bool isLittleEndian() const
Tests whether the target triple is little endian.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
bool parseAssignmentExpression(StringRef Name, bool allow_redef, MCAsmParser &Parser, MCSymbol *&Symbol, const MCExpr *&Value)
Parse a value expression and return whether it can be assigned to a symbol with the given name.
@ CE
Windows NT (Windows on ARM)
LLVM_ABI StringRef getABIName()
Context & getContext() const
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Target & getTheMips64Target()
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
static StringRef getCPU(StringRef CPU)
Processes a CPU name.
int bit_width(T Value)
Returns the number of bits needed to represent Value if Value is nonzero.
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
@ Success
The lock was released successfully.
Target & getTheMips64elTarget()
uint64_t offsetToAlignment(uint64_t Value, Align Alignment)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
@ Ref
The access may reference the value stored in memory.
To bit_cast(const From &from) noexcept
Target & getTheMipselTarget()
DWARFExpression::Operation Op
constexpr bool isShiftedInt(int64_t x)
Checks if a signed integer is an N bit number shifted left by S.
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
static uint16_t getSpecifier(const MCSymbolRefExpr *SRE)
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
Target & getTheMipsTarget()
constexpr bool isShiftedUInt(uint64_t x)
Checks if a unsigned integer is an N bit number shifted left by S.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...