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) {
482 MCSubtargetInfo &STI = copySTI();
483 setAvailableFeatures(
489 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
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:
2024 return Error(IDLoc,
"expected immediate operand kind");
2028 Warning(IDLoc,
"dividing zero by zero");
2030 Warning(IDLoc,
"division by zero");
2042 case Mips::SDivMacro:
2043 case Mips::DSDivMacro:
2044 case Mips::UDivMacro:
2045 case Mips::DUDivMacro:
2050 case Mips::DIVU_MMR6:
2051 case Mips::DIV_MMR6:
2056 Warning(IDLoc,
"dividing zero by zero");
2058 Warning(IDLoc,
"division by zero");
2064 if ((Opcode == Mips::J || Opcode == Mips::J_MM) && inPicMode()) {
2066 BInst.
setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
2075 if ((Opcode == Mips::JAL || Opcode == Mips::JAL_MM) && inPicMode()) {
2076 warnIfNoMacro(IDLoc);
2079 return Error(IDLoc,
"unsupported constant in relocation");
2087 return Error(IDLoc,
"jal doesn't support multiple symbols in PIC mode");
2093 if (expandLoadAddress(Mips::T9, MCRegister(), Inst.
getOperand(0),
2094 !isGP64bit(), IDLoc, Out, STI))
2098 if (inMicroMipsMode())
2099 JalrInst.
setOpcode(IsCpRestoreSet ? Mips::JALRS_MM : Mips::JALR_MM);
2105 if (isJalrRelocAvailable(JalExpr)) {
2111 const MCExpr *RelocJalrExpr =
2115 *TmpExpr, inMicroMipsMode() ?
"R_MICROMIPS_JALR" :
"R_MIPS_JALR",
2121 ExpandedJalSym =
true;
2130 expandMem9Inst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2133 expandMem16Inst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2136 return getParser().hasPendingError();
2140 if (inMicroMipsMode()) {
2141 if (MCID.
mayLoad() && Opcode != Mips::LWP_MM) {
2144 const MCOperandInfo &OpInfo = MCID.
operands()[i];
2149 int MemOffset =
Op.getImm();
2152 if (
isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
2155 (
BaseReg.getReg() == Mips::GP ||
2156 BaseReg.getReg() == Mips::GP_64)) {
2158 TOut.
emitRRI(Mips::LWGP_MM, DstReg.
getReg(), Mips::GP, MemOffset,
2175 case Mips::ADDIUSP_MM:
2178 return Error(IDLoc,
"expected immediate operand kind");
2180 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
2182 return Error(IDLoc,
"immediate operand value out of range");
2184 case Mips::SLL16_MM:
2185 case Mips::SRL16_MM:
2188 return Error(IDLoc,
"expected immediate operand kind");
2190 if (Imm < 1 || Imm > 8)
2191 return Error(IDLoc,
"immediate operand value out of range");
2196 return Error(IDLoc,
"expected immediate operand kind");
2198 if (Imm < -1 || Imm > 126)
2199 return Error(IDLoc,
"immediate operand value out of range");
2201 case Mips::ADDIUR2_MM:
2204 return Error(IDLoc,
"expected immediate operand kind");
2206 if (!(Imm == 1 || Imm == -1 ||
2207 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
2208 return Error(IDLoc,
"immediate operand value out of range");
2210 case Mips::ANDI16_MM:
2213 return Error(IDLoc,
"expected immediate operand kind");
2215 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
2216 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
2217 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
2218 return Error(IDLoc,
"immediate operand value out of range");
2220 case Mips::LBU16_MM:
2223 return Error(IDLoc,
"expected immediate operand kind");
2225 if (Imm < -1 || Imm > 14)
2226 return Error(IDLoc,
"immediate operand value out of range");
2229 case Mips::SB16_MMR6:
2232 return Error(IDLoc,
"expected immediate operand kind");
2234 if (Imm < 0 || Imm > 15)
2235 return Error(IDLoc,
"immediate operand value out of range");
2237 case Mips::LHU16_MM:
2239 case Mips::SH16_MMR6:
2242 return Error(IDLoc,
"expected immediate operand kind");
2244 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
2245 return Error(IDLoc,
"immediate operand value out of range");
2249 case Mips::SW16_MMR6:
2252 return Error(IDLoc,
"expected immediate operand kind");
2254 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
2255 return Error(IDLoc,
"immediate operand value out of range");
2257 case Mips::ADDIUPC_MM:
2260 return Error(IDLoc,
"expected immediate operand kind");
2263 return Error(IDLoc,
"immediate operand value out of range");
2268 return Error(IDLoc,
"invalid operand for instruction");
2270 case Mips::MOVEP_MM:
2271 case Mips::MOVEP_MMR6: {
2274 bool RegPair = ((R0 == Mips::A1 && R1 == Mips::A2) ||
2275 (R0 == Mips::A1 && R1 == Mips::A3) ||
2276 (R0 == Mips::A2 && R1 == Mips::A3) ||
2277 (R0 == Mips::A0 && R1 == Mips::S5) ||
2278 (R0 == Mips::A0 && R1 == Mips::S6) ||
2279 (R0 == Mips::A0 && R1 == Mips::A1) ||
2280 (R0 == Mips::A0 && R1 == Mips::A2) ||
2281 (R0 == Mips::A0 && R1 == Mips::A3));
2283 return Error(IDLoc,
"invalid operand for instruction");
2289 bool FillDelaySlot =
2294 bool PrevForbiddenSlotAttr = CurForbiddenSlotAttr;
2297 bool SetReorderAfterNop =
false;
2302 if (PrevForbiddenSlotAttr && !SafeInForbiddenSlot(MCID)) {
2312 if (AssemblerOptions.
back()->isReorder() && !FillDelaySlot) {
2313 SetReorderAfterNop =
true;
2322 CurForbiddenSlotAttr =
2323 hasForbiddenSlot(MCID) && AssemblerOptions.
back()->isReorder();
2325 if (FillDelaySlot || CurForbiddenSlotAttr)
2328 MacroExpanderResultTy ExpandResult =
2329 tryExpandInstruction(Inst, IDLoc, Out, STI);
2330 switch (ExpandResult) {
2346 if (PrevForbiddenSlotAttr && !SetReorderAfterNop && !FillDelaySlot &&
2347 AssemblerOptions.
back()->isReorder()) {
2353 if (inMicroMipsMode()) {
2368 if (FillDelaySlot) {
2373 if ((Opcode == Mips::JalOneReg || Opcode == Mips::JalTwoReg ||
2375 isPicAndNotNxxAbi()) {
2376 if (IsCpRestoreSet) {
2380 if (!AssemblerOptions.
back()->isReorder())
2387 Warning(IDLoc,
"no .cprestore used in PIC mode");
2393void MipsAsmParser::onEndOfFile() {
2394 MipsTargetStreamer &TOut = getTargetStreamer();
2395 SMLoc IDLoc = SMLoc();
2397 if (CurForbiddenSlotAttr) {
2399 if (AssemblerOptions.
back()->isReorder())
2404MipsAsmParser::MacroExpanderResultTy
2405MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2406 const MCSubtargetInfo *STI) {
2409 return MER_NotAMacro;
2410 case Mips::LoadImm32:
2411 return expandLoadImm(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2412 case Mips::LoadImm64:
2413 return expandLoadImm(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2414 case Mips::LoadAddrImm32:
2415 case Mips::LoadAddrImm64:
2418 "expected immediate operand kind");
2420 return expandLoadAddress(
2422 Inst.
getOpcode() == Mips::LoadAddrImm32, IDLoc, Out, STI)
2425 case Mips::LoadAddrReg32:
2426 case Mips::LoadAddrReg64:
2430 "expected immediate operand kind");
2434 Inst.
getOpcode() == Mips::LoadAddrReg32, IDLoc,
2438 case Mips::B_MM_Pseudo:
2439 case Mips::B_MMR6_Pseudo:
2440 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2444 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2446 case Mips::JalOneReg:
2447 case Mips::JalTwoReg:
2448 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2451 case Mips::BEQLImmMacro:
2452 case Mips::BNELImmMacro:
2453 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2470 case Mips::BLTImmMacro:
2471 case Mips::BLEImmMacro:
2472 case Mips::BGEImmMacro:
2473 case Mips::BGTImmMacro:
2474 case Mips::BLTUImmMacro:
2475 case Mips::BLEUImmMacro:
2476 case Mips::BGEUImmMacro:
2477 case Mips::BGTUImmMacro:
2478 case Mips::BLTLImmMacro:
2479 case Mips::BLELImmMacro:
2480 case Mips::BGELImmMacro:
2481 case Mips::BGTLImmMacro:
2482 case Mips::BLTULImmMacro:
2483 case Mips::BLEULImmMacro:
2484 case Mips::BGEULImmMacro:
2485 case Mips::BGTULImmMacro:
2486 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2487 case Mips::SDivMacro:
2488 case Mips::SDivIMacro:
2489 case Mips::SRemMacro:
2490 case Mips::SRemIMacro:
2491 return expandDivRem(Inst, IDLoc, Out, STI,
false,
true) ? MER_Fail
2493 case Mips::DSDivMacro:
2494 case Mips::DSDivIMacro:
2495 case Mips::DSRemMacro:
2496 case Mips::DSRemIMacro:
2497 return expandDivRem(Inst, IDLoc, Out, STI,
true,
true) ? MER_Fail
2499 case Mips::UDivMacro:
2500 case Mips::UDivIMacro:
2501 case Mips::URemMacro:
2502 case Mips::URemIMacro:
2503 return expandDivRem(Inst, IDLoc, Out, STI,
false,
false) ? MER_Fail
2505 case Mips::DUDivMacro:
2506 case Mips::DUDivIMacro:
2507 case Mips::DURemMacro:
2508 case Mips::DURemIMacro:
2509 return expandDivRem(Inst, IDLoc, Out, STI,
true,
false) ? MER_Fail
2511 case Mips::PseudoTRUNC_W_S:
2512 return expandTrunc(Inst,
false,
false, IDLoc, Out, STI) ? MER_Fail
2514 case Mips::PseudoTRUNC_W_D32:
2515 return expandTrunc(Inst,
true,
false, IDLoc, Out, STI) ? MER_Fail
2517 case Mips::PseudoTRUNC_W_D:
2518 return expandTrunc(Inst,
true,
true, IDLoc, Out, STI) ? MER_Fail
2521 case Mips::LoadImmSingleGPR:
2522 return expandLoadSingleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2524 case Mips::LoadImmSingleFGR:
2525 return expandLoadSingleImmToFPR(Inst, IDLoc, Out, STI) ? MER_Fail
2527 case Mips::LoadImmDoubleGPR:
2528 return expandLoadDoubleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2530 case Mips::LoadImmDoubleFGR:
2531 return expandLoadDoubleImmToFPR(Inst,
true, IDLoc, Out, STI) ? MER_Fail
2533 case Mips::LoadImmDoubleFGR_32:
2534 return expandLoadDoubleImmToFPR(Inst,
false, IDLoc, Out, STI) ? MER_Fail
2538 return expandUlh(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2540 return expandUlh(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2542 return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2545 return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2547 case Mips::NORImm64:
2548 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2551 return expandSge(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2554 case Mips::SGEImm64:
2555 case Mips::SGEUImm64:
2556 return expandSgeImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2559 case Mips::SGTImm64:
2560 case Mips::SGTUImm64:
2561 return expandSgtImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2564 return expandSle(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2567 case Mips::SLEImm64:
2568 case Mips::SLEUImm64:
2569 return expandSleImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2570 case Mips::SLTImm64:
2573 return MER_NotAMacro;
2575 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2576 case Mips::SLTUImm64:
2579 return MER_NotAMacro;
2581 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2582 case Mips::ADDi:
case Mips::ADDi_MM:
2583 case Mips::ADDiu:
case Mips::ADDiu_MM:
2584 case Mips::SLTi:
case Mips::SLTi_MM:
2585 case Mips::SLTiu:
case Mips::SLTiu_MM:
2590 return MER_NotAMacro;
2591 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2594 return MER_NotAMacro;
2595 case Mips::ANDi:
case Mips::ANDi_MM:
case Mips::ANDi64:
2596 case Mips::ORi:
case Mips::ORi_MM:
case Mips::ORi64:
2597 case Mips::XORi:
case Mips::XORi_MM:
case Mips::XORi64:
2602 return MER_NotAMacro;
2603 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2606 return MER_NotAMacro;
2609 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2612 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2615 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2618 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2619 case Mips::ABSMacro:
2620 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2621 case Mips::MULImmMacro:
2622 case Mips::DMULImmMacro:
2623 return expandMulImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2624 case Mips::MULOMacro:
2625 case Mips::DMULOMacro:
2626 return expandMulO(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2627 case Mips::MULOUMacro:
2628 case Mips::DMULOUMacro:
2629 return expandMulOU(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2630 case Mips::DMULMacro:
2631 return expandDMULMacro(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2634 return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2639 return expandStoreDM1Macro(Inst, IDLoc, Out, STI)
2642 case Mips::SEQMacro:
2643 return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2644 case Mips::SEQIMacro:
2645 return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2646 case Mips::SNEMacro:
2647 return expandSne(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2648 case Mips::SNEIMacro:
2649 return expandSneI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2650 case Mips::MFTC0:
case Mips::MTTC0:
2651 case Mips::MFTGPR:
case Mips::MTTGPR:
2652 case Mips::MFTLO:
case Mips::MTTLO:
2653 case Mips::MFTHI:
case Mips::MTTHI:
2654 case Mips::MFTACX:
case Mips::MTTACX:
2655 case Mips::MFTDSP:
case Mips::MTTDSP:
2656 case Mips::MFTC1:
case Mips::MTTC1:
2657 case Mips::MFTHC1:
case Mips::MTTHC1:
2658 case Mips::CFTC1:
case Mips::CTTC1:
2659 return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2661 case Mips::SaadAddr:
2662 return expandSaaAddr(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2666bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2668 const MCSubtargetInfo *STI) {
2669 MipsTargetStreamer &TOut = getTargetStreamer();
2674 const MCOperand FirstRegOp = Inst.
getOperand(0);
2675 const unsigned Opcode = Inst.
getOpcode();
2677 if (Opcode == Mips::JalOneReg) {
2679 if (IsCpRestoreSet && inMicroMipsMode()) {
2682 }
else if (inMicroMipsMode()) {
2683 JalrInst.
setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2690 }
else if (Opcode == Mips::JalTwoReg) {
2692 if (IsCpRestoreSet && inMicroMipsMode())
2695 JalrInst.
setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2697 const MCOperand SecondRegOp = Inst.
getOperand(1);
2704 const MCInstrDesc &MCID = MII.get(JalrInst.
getOpcode());
2727bool MipsAsmParser::loadImmediate(int64_t ImmValue, MCRegister DstReg,
2728 MCRegister SrcReg,
bool Is32BitImm,
2729 bool IsAddress, SMLoc IDLoc, MCStreamer &Out,
2730 const MCSubtargetInfo *STI) {
2731 MipsTargetStreamer &TOut = getTargetStreamer();
2733 if (!Is32BitImm && !isGP64bit()) {
2734 Error(IDLoc,
"instruction requires a 64-bit architecture");
2745 Error(IDLoc,
"instruction requires a 32-bit immediate");
2750 MCRegister ZeroReg = IsAddress ?
ABI.GetNullPtr() :
ABI.GetZeroReg();
2751 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2753 bool UseSrcReg =
false;
2757 MCRegister TmpReg = DstReg;
2759 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2762 MCRegister ATReg = getATReg(IDLoc);
2775 if (IsAddress && !Is32BitImm) {
2776 TOut.
emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2780 TOut.
emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2785 MCRegister TmpReg = DstReg;
2786 if (SrcReg == DstReg) {
2787 TmpReg = getATReg(IDLoc);
2792 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2794 TOut.
emitRRR(
ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2799 warnIfNoMacro(IDLoc);
2801 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2802 uint16_t Bits15To0 = ImmValue & 0xffff;
2803 if (!Is32BitImm && !
isInt<32>(ImmValue)) {
2806 if (ImmValue == 0xffffffff) {
2807 TOut.
emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2808 TOut.
emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2810 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2816 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2817 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2819 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2821 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2825 TOut.
emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2827 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2829 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2835 Error(IDLoc,
"instruction requires a 32-bit immediate");
2842 assert(
BitWidth >= 17 &&
"ImmValue must be at least 17-bit wide");
2846 unsigned ShiftAmount =
BitWidth - 16;
2847 uint16_t
Bits = (ImmValue >> ShiftAmount) & 0xffff;
2848 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2849 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2852 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2857 warnIfNoMacro(IDLoc);
2864 if (loadImmediate(ImmValue >> 32, TmpReg, MCRegister(),
true,
false, IDLoc,
2870 unsigned ShiftCarriedForwards = 16;
2871 for (
int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2872 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2874 if (ImmChunk != 0) {
2875 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2876 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2877 ShiftCarriedForwards = 0;
2880 ShiftCarriedForwards += 16;
2882 ShiftCarriedForwards -= 16;
2885 if (ShiftCarriedForwards)
2886 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2889 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2894bool MipsAsmParser::expandLoadImm(MCInst &Inst,
bool Is32BitImm, SMLoc IDLoc,
2895 MCStreamer &Out,
const MCSubtargetInfo *STI) {
2897 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
2898 const MCOperand &DstRegOp = Inst.
getOperand(0);
2899 assert(DstRegOp.
isReg() &&
"expected register operand kind");
2901 if (loadImmediate(ImmOp.
getImm(), DstRegOp.
getReg(), MCRegister(), Is32BitImm,
2902 false, IDLoc, Out, STI))
2908bool MipsAsmParser::expandLoadAddress(MCRegister DstReg, MCRegister BaseReg,
2910 bool Is32BitAddress, SMLoc IDLoc,
2912 const MCSubtargetInfo *STI) {
2914 if (Is32BitAddress &&
ABI.ArePtrs64bit()) {
2915 Warning(IDLoc,
"la used to load 64-bit address");
2917 Is32BitAddress =
false;
2921 if (!Is32BitAddress && !hasMips3()) {
2922 Error(IDLoc,
"instruction requires a 64-bit architecture");
2927 return loadAndAddSymbolAddress(
Offset.getExpr(), DstReg, BaseReg,
2928 Is32BitAddress, IDLoc, Out, STI);
2930 if (!
ABI.ArePtrs64bit()) {
2932 Is32BitAddress =
true;
2935 return loadImmediate(
Offset.getImm(), DstReg, BaseReg, Is32BitAddress,
true,
2939bool MipsAsmParser::loadAndAddSymbolAddress(
const MCExpr *SymExpr,
2941 MCRegister SrcReg,
bool Is32BitSym,
2942 SMLoc IDLoc, MCStreamer &Out,
2943 const MCSubtargetInfo *STI) {
2944 MipsTargetStreamer &TOut = getTargetStreamer();
2946 SrcReg.
isValid() && SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64;
2947 warnIfNoMacro(IDLoc);
2952 Error(IDLoc,
"expected relocatable expression");
2956 Error(IDLoc,
"expected relocatable expression with only one symbol");
2960 bool IsPtr64 =
ABI.ArePtrs64bit();
2964 static_cast<const MCSymbolELF *
>(Res.
getAddSym())->getBinding() ==
2971 bool UseXGOT = STI->
hasFeature(Mips::FeatureXGOT) && !IsLocalSym;
2977 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2980 const MCExpr *CallHiExpr =
2982 const MCExpr *CallLoExpr =
2986 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, DstReg, GPReg,
2988 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, DstReg,
2991 const MCExpr *CallExpr =
2993 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, GPReg,
2999 MCRegister TmpReg = DstReg;
3001 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
3005 MCRegister ATReg = getATReg(IDLoc);
3024 const MCExpr *CallHiExpr =
3031 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg, GPReg,
3033 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, TmpReg,
3037 TOut.
emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3043 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3048 const MCSpecifierExpr *GotExpr =
nullptr;
3049 const MCExpr *LoExpr =
nullptr;
3050 if (
ABI.IsN32() ||
ABI.IsN64()) {
3069 Error(IDLoc,
"macro instruction uses large offset, which is not "
3070 "currently supported");
3099 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, GPReg,
3103 TOut.
emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3107 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3113 const auto *HiExpr =
3115 const auto *LoExpr =
3119 if (
ABI.ArePtrs64bit() && isGP64bit()) {
3127 const auto *HighestExpr =
3129 const auto *HigherExpr =
3134 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
3136 if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
3137 MCRegister ATReg = getATReg(IDLoc);
3149 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3151 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3154 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3157 TOut.
emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
3160 }
else if (canUseATReg() && !RdRegIsRsReg && DstReg != getATReg(IDLoc)) {
3161 MCRegister ATReg = getATReg(IDLoc);
3177 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3181 TOut.
emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3182 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3184 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3187 }
else if ((!canUseATReg() && !RdRegIsRsReg) ||
3188 (canUseATReg() && DstReg == getATReg(IDLoc))) {
3199 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3201 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3202 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3204 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3205 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3208 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3214 assert(SrcReg == DstReg && !canUseATReg() &&
3215 "Could have expanded dla but didn't?");
3216 reportParseError(IDLoc,
3217 "pseudo-instruction requires $at, which is not available");
3231 MCRegister TmpReg = DstReg;
3233 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
3236 MCRegister ATReg = getATReg(IDLoc);
3247 TOut.
emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3250 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
3259 if (getMipsMCRegisterClass(Mips::FGR32RegClassID).
contains(
Reg))
3260 return Reg == (
unsigned)Mips::F31 ? (
unsigned)Mips::F0 :
Reg + 1;
3262 default:
llvm_unreachable(
"Unknown register in assembly macro expansion!");
3263 case Mips::ZERO:
return Mips::AT;
3264 case Mips::AT:
return Mips::V0;
3265 case Mips::V0:
return Mips::V1;
3266 case Mips::V1:
return Mips::A0;
3267 case Mips::A0:
return Mips::A1;
3268 case Mips::A1:
return Mips::A2;
3269 case Mips::A2:
return Mips::A3;
3270 case Mips::A3:
return Mips::T0;
3271 case Mips::T0:
return Mips::T1;
3272 case Mips::T1:
return Mips::T2;
3273 case Mips::T2:
return Mips::T3;
3274 case Mips::T3:
return Mips::T4;
3275 case Mips::T4:
return Mips::T5;
3276 case Mips::T5:
return Mips::T6;
3277 case Mips::T6:
return Mips::T7;
3278 case Mips::T7:
return Mips::S0;
3279 case Mips::S0:
return Mips::S1;
3280 case Mips::S1:
return Mips::S2;
3281 case Mips::S2:
return Mips::S3;
3282 case Mips::S3:
return Mips::S4;
3283 case Mips::S4:
return Mips::S5;
3284 case Mips::S5:
return Mips::S6;
3285 case Mips::S6:
return Mips::S7;
3286 case Mips::S7:
return Mips::T8;
3287 case Mips::T8:
return Mips::T9;
3288 case Mips::T9:
return Mips::K0;
3289 case Mips::K0:
return Mips::K1;
3290 case Mips::K1:
return Mips::GP;
3291 case Mips::GP:
return Mips::SP;
3292 case Mips::SP:
return Mips::FP;
3293 case Mips::FP:
return Mips::RA;
3294 case Mips::RA:
return Mips::ZERO;
3295 case Mips::D0:
return Mips::F1;
3296 case Mips::D1:
return Mips::F3;
3297 case Mips::D2:
return Mips::F5;
3298 case Mips::D3:
return Mips::F7;
3299 case Mips::D4:
return Mips::F9;
3300 case Mips::D5:
return Mips::F11;
3301 case Mips::D6:
return Mips::F13;
3302 case Mips::D7:
return Mips::F15;
3303 case Mips::D8:
return Mips::F17;
3304 case Mips::D9:
return Mips::F19;
3305 case Mips::D10:
return Mips::F21;
3306 case Mips::D11:
return Mips::F23;
3307 case Mips::D12:
return Mips::F25;
3308 case Mips::D13:
return Mips::F27;
3309 case Mips::D14:
return Mips::F29;
3310 case Mips::D15:
return Mips::F31;
3320bool MipsAsmParser::emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc,
3322 MCRegister ATReg = getATReg(IDLoc);
3328 const auto *GotExpr =
3331 if(isABI_O32() || isABI_N32()) {
3340 const auto *HiExpr =
3349 if(isABI_O32() || isABI_N32()) {
3353 const auto *HighestExpr =
3356 const auto *HigherExpr =
3361 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3363 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3366 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3375 if ((
Hi_32(ImmOp64) & 0x7ff00000) == 0) {
3386 float TmpFloat =
static_cast<float>(DoubleImm);
3390bool MipsAsmParser::expandLoadSingleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3392 const MCSubtargetInfo *STI) {
3395 "Invalid instruction operand.");
3402 return loadImmediate(ImmOp32, FirstReg, MCRegister(),
true,
false, IDLoc, Out,
3406bool MipsAsmParser::expandLoadSingleImmToFPR(MCInst &Inst, SMLoc IDLoc,
3408 const MCSubtargetInfo *STI) {
3409 MipsTargetStreamer &TOut = getTargetStreamer();
3412 "Invalid instruction operand.");
3421 MCRegister TmpReg = Mips::ZERO;
3423 TmpReg = getATReg(IDLoc);
3428 if (
Lo_32(ImmOp64) == 0) {
3429 if (TmpReg != Mips::ZERO && loadImmediate(ImmOp32, TmpReg, MCRegister(),
3430 true,
false, IDLoc, Out, STI))
3432 TOut.
emitRR(Mips::MTC1, FirstReg, TmpReg, IDLoc, STI);
3436 MCSection *
CS = getStreamer().getCurrentSectionOnly();
3439 MCSection *ReadOnlySection =
3446 getStreamer().switchSection(ReadOnlySection);
3447 getStreamer().emitLabel(Sym, IDLoc);
3448 getStreamer().emitInt32(ImmOp32);
3449 getStreamer().switchSection(
CS);
3451 if (emitPartialAddress(TOut, IDLoc, Sym))
3458bool MipsAsmParser::expandLoadDoubleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3460 const MCSubtargetInfo *STI) {
3461 MipsTargetStreamer &TOut = getTargetStreamer();
3464 "Invalid instruction operand.");
3471 if (
Lo_32(ImmOp64) == 0) {
3473 if (loadImmediate(ImmOp64, FirstReg, MCRegister(),
false,
false, IDLoc,
3477 if (loadImmediate(
Hi_32(ImmOp64), FirstReg, MCRegister(),
true,
false,
3481 if (loadImmediate(0,
nextReg(FirstReg), MCRegister(),
true,
false, IDLoc,
3488 MCSection *
CS = getStreamer().getCurrentSectionOnly();
3489 MCSection *ReadOnlySection =
3496 getStreamer().switchSection(ReadOnlySection);
3497 getStreamer().emitLabel(Sym, IDLoc);
3498 getStreamer().emitValueToAlignment(
Align(8));
3499 getStreamer().emitIntValue(ImmOp64, 8);
3500 getStreamer().switchSection(
CS);
3502 MCRegister TmpReg = getATReg(IDLoc);
3506 if (emitPartialAddress(TOut, IDLoc, Sym))
3509 TOut.
emitRRX(isABI_N64() ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3513 TOut.
emitRRI(Mips::LD, FirstReg, TmpReg, 0, IDLoc, STI);
3515 TOut.
emitRRI(Mips::LW, FirstReg, TmpReg, 0, IDLoc, STI);
3516 TOut.
emitRRI(Mips::LW,
nextReg(FirstReg), TmpReg, 4, IDLoc, STI);
3521bool MipsAsmParser::expandLoadDoubleImmToFPR(MCInst &Inst,
bool Is64FPU,
3522 SMLoc IDLoc, MCStreamer &Out,
3523 const MCSubtargetInfo *STI) {
3524 MipsTargetStreamer &TOut = getTargetStreamer();
3527 "Invalid instruction operand.");
3534 MCRegister TmpReg = Mips::ZERO;
3536 TmpReg = getATReg(IDLoc);
3541 if ((
Lo_32(ImmOp64) == 0) &&
3542 !((
Hi_32(ImmOp64) & 0xffff0000) && (
Hi_32(ImmOp64) & 0x0000ffff))) {
3544 if (TmpReg != Mips::ZERO && loadImmediate(ImmOp64, TmpReg, MCRegister(),
3545 false,
false, IDLoc, Out, STI))
3547 TOut.
emitRR(Mips::DMTC1, FirstReg, TmpReg, IDLoc, STI);
3551 if (TmpReg != Mips::ZERO &&
3552 loadImmediate(
Hi_32(ImmOp64), TmpReg, MCRegister(),
true,
false, IDLoc,
3556 if (hasMips32r2()) {
3557 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3558 TOut.
emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, TmpReg, IDLoc, STI);
3560 TOut.
emitRR(Mips::MTC1,
nextReg(FirstReg), TmpReg, IDLoc, STI);
3561 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3566 MCSection *
CS = getStreamer().getCurrentSectionOnly();
3569 MCSection *ReadOnlySection =
3576 getStreamer().switchSection(ReadOnlySection);
3577 getStreamer().emitLabel(Sym, IDLoc);
3578 getStreamer().emitValueToAlignment(
Align(8));
3579 getStreamer().emitIntValue(ImmOp64, 8);
3580 getStreamer().switchSection(
CS);
3582 if (emitPartialAddress(TOut, IDLoc, Sym))
3585 TOut.
emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, TmpReg,
3591bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
3593 const MCSubtargetInfo *STI) {
3594 MipsTargetStreamer &TOut = getTargetStreamer();
3597 "unexpected number of operands");
3607 assert(
Offset.isImm() &&
"expected immediate operand kind");
3611 if (inMicroMipsMode())
3612 Inst.
setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3615 return Error(IDLoc,
"branch target out of range");
3617 return Error(IDLoc,
"branch to misaligned address");
3629 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
3636bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3637 const MCSubtargetInfo *STI) {
3638 MipsTargetStreamer &TOut = getTargetStreamer();
3639 const MCOperand &DstRegOp = Inst.
getOperand(0);
3640 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3643 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
3645 const MCOperand &MemOffsetOp = Inst.
getOperand(2);
3647 "expected immediate or expression operand");
3649 bool IsLikely =
false;
3659 case Mips::BEQLImmMacro:
3663 case Mips::BNELImmMacro:
3672 int64_t ImmValue = ImmOp.
getImm();
3673 if (ImmValue == 0) {
3677 TOut.
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3679 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3682 warnIfNoMacro(IDLoc);
3684 MCRegister ATReg = getATReg(IDLoc);
3688 if (loadImmediate(ImmValue, ATReg, MCRegister(), !isGP64bit(),
true, IDLoc,
3692 if (IsLikely && MemOffsetOp.
isExpr()) {
3695 TOut.
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3697 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3702void MipsAsmParser::expandMem16Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3703 const MCSubtargetInfo *STI,
bool IsLoad) {
3705 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3706 unsigned StartOp = NumOp == 3 ? 0 : 1;
3708 const MCOperand &DstRegOp = Inst.
getOperand(StartOp);
3709 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3710 const MCOperand &BaseRegOp = Inst.
getOperand(StartOp + 1);
3711 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3714 MipsTargetStreamer &TOut = getTargetStreamer();
3716 MCRegister DstReg = DstRegOp.
getReg();
3718 MCRegister TmpReg = DstReg;
3720 const MCInstrDesc &
Desc = MII.get(OpCode);
3721 int16_t DstRegClass =
3722 MII.getOpRegClassID(
Desc.operands()[StartOp],
3724 unsigned DstRegClassID =
3725 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3726 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3727 (DstRegClassID == Mips::GPR64RegClassID);
3729 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3732 TmpReg = getATReg(IDLoc);
3737 auto emitInstWithOffset = [&](
const MCOperand &
Off) {
3739 TOut.
emitRRX(OpCode, DstReg, TmpReg, Off, IDLoc, STI);
3741 TOut.
emitRRRX(OpCode, DstReg, DstReg, TmpReg, Off, IDLoc, STI);
3745 int64_t LoOffset =
OffsetOp.getImm() & 0xffff;
3746 int64_t HiOffset =
OffsetOp.getImm() & ~0xffff;
3750 if (LoOffset & 0x8000)
3751 HiOffset += 0x10000;
3753 bool IsLargeOffset = HiOffset != 0;
3755 if (IsLargeOffset) {
3757 if (loadImmediate(HiOffset, TmpReg, MCRegister(), Is32BitImm,
true, IDLoc,
3762 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3763 TOut.
emitRRR(
ABI.ArePtrs64bit() ? Mips::DADDu : Mips::ADDu, TmpReg,
3764 TmpReg, BaseReg, IDLoc, STI);
3778 if (!
OffsetOp.getExpr()->evaluateAsRelocatable(Res,
nullptr)) {
3779 Error(IDLoc,
"expected relocatable expression");
3783 Error(IDLoc,
"expected relocatable expression with only one symbol");
3787 loadAndAddSymbolAddress(
3789 BaseReg, !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3797 const MCExpr *OffExpr =
OffsetOp.getExpr();
3809 TOut.
emitRX(Mips::LUi, TmpReg, HighestOperand, IDLoc, STI);
3810 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HigherOperand, IDLoc, STI);
3811 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3812 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HiOperand, IDLoc, STI);
3813 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3814 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3815 TOut.
emitRRR(Mips::DADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3816 emitInstWithOffset(LoOperand);
3819 TOut.
emitRX(Mips::LUi, TmpReg, HiOperand, IDLoc, STI);
3820 if (BaseReg != Mips::ZERO)
3821 TOut.
emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3823 emitInstWithOffset(LoOperand);
3832void MipsAsmParser::expandMem9Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3833 const MCSubtargetInfo *STI,
bool IsLoad) {
3835 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3836 unsigned StartOp = NumOp == 3 ? 0 : 1;
3838 const MCOperand &DstRegOp = Inst.
getOperand(StartOp);
3839 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3840 const MCOperand &BaseRegOp = Inst.
getOperand(StartOp + 1);
3841 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3844 MipsTargetStreamer &TOut = getTargetStreamer();
3846 MCRegister DstReg = DstRegOp.
getReg();
3848 MCRegister TmpReg = DstReg;
3850 const MCInstrDesc &
Desc = MII.get(OpCode);
3851 int16_t DstRegClass =
3852 MII.getOpRegClassID(
Desc.operands()[StartOp],
3855 unsigned DstRegClassID =
3856 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3857 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3858 (DstRegClassID == Mips::GPR64RegClassID);
3860 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3863 TmpReg = getATReg(IDLoc);
3868 auto emitInst = [&]() {
3877 loadImmediate(
OffsetOp.getImm(), TmpReg, BaseReg, !
ABI.ArePtrs64bit(),
true,
3884 loadAndAddSymbolAddress(
OffsetOp.getExpr(), TmpReg, BaseReg,
3885 !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3893bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
3895 const MCSubtargetInfo *STI) {
3898 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3902 Inst.
getOperand(OpNum - 3).
isReg() &&
"Invalid instruction operand.");
3911 if (inMicroMipsMode() && hasMips32r6())
3912 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3914 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3922bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
3924 const MCSubtargetInfo *STI) {
3925 MipsTargetStreamer &TOut = getTargetStreamer();
3926 bool EmittedNoMacroWarning =
false;
3927 unsigned PseudoOpcode = Inst.
getOpcode();
3932 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3933 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3938 else if (TrgOp.
isImm()) {
3939 warnIfNoMacro(IDLoc);
3940 EmittedNoMacroWarning =
true;
3942 TrgReg = getATReg(IDLoc);
3946 switch(PseudoOpcode) {
3949 case Mips::BLTImmMacro:
3950 PseudoOpcode = Mips::BLT;
3952 case Mips::BLEImmMacro:
3953 PseudoOpcode = Mips::BLE;
3955 case Mips::BGEImmMacro:
3956 PseudoOpcode = Mips::BGE;
3958 case Mips::BGTImmMacro:
3959 PseudoOpcode = Mips::BGT;
3961 case Mips::BLTUImmMacro:
3962 PseudoOpcode = Mips::BLTU;
3964 case Mips::BLEUImmMacro:
3965 PseudoOpcode = Mips::BLEU;
3967 case Mips::BGEUImmMacro:
3968 PseudoOpcode = Mips::BGEU;
3970 case Mips::BGTUImmMacro:
3971 PseudoOpcode = Mips::BGTU;
3973 case Mips::BLTLImmMacro:
3974 PseudoOpcode = Mips::BLTL;
3976 case Mips::BLELImmMacro:
3977 PseudoOpcode = Mips::BLEL;
3979 case Mips::BGELImmMacro:
3980 PseudoOpcode = Mips::BGEL;
3982 case Mips::BGTLImmMacro:
3983 PseudoOpcode = Mips::BGTL;
3985 case Mips::BLTULImmMacro:
3986 PseudoOpcode = Mips::BLTUL;
3988 case Mips::BLEULImmMacro:
3989 PseudoOpcode = Mips::BLEUL;
3991 case Mips::BGEULImmMacro:
3992 PseudoOpcode = Mips::BGEUL;
3994 case Mips::BGTULImmMacro:
3995 PseudoOpcode = Mips::BGTUL;
3999 if (loadImmediate(TrgOp.
getImm(), TrgReg, MCRegister(), !isGP64bit(),
false,
4004 switch (PseudoOpcode) {
4009 AcceptsEquality =
false;
4010 ReverseOrderSLT =
false;
4012 ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
4013 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
4014 ZeroSrcOpcode = Mips::BGTZ;
4015 ZeroTrgOpcode = Mips::BLTZ;
4021 AcceptsEquality =
true;
4022 ReverseOrderSLT =
true;
4024 ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
4025 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
4026 ZeroSrcOpcode = Mips::BGEZ;
4027 ZeroTrgOpcode = Mips::BLEZ;
4033 AcceptsEquality =
true;
4034 ReverseOrderSLT =
false;
4036 ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
4037 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
4038 ZeroSrcOpcode = Mips::BLEZ;
4039 ZeroTrgOpcode = Mips::BGEZ;
4045 AcceptsEquality =
false;
4046 ReverseOrderSLT =
true;
4048 ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
4049 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
4050 ZeroSrcOpcode = Mips::BLTZ;
4051 ZeroTrgOpcode = Mips::BGTZ;
4057 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
4058 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
4059 if (IsSrcRegZero && IsTrgRegZero) {
4063 if (PseudoOpcode == Mips::BLT) {
4068 if (PseudoOpcode == Mips::BLE) {
4071 Warning(IDLoc,
"branch is always taken");
4074 if (PseudoOpcode == Mips::BGE) {
4077 Warning(IDLoc,
"branch is always taken");
4080 if (PseudoOpcode == Mips::BGT) {
4085 if (PseudoOpcode == Mips::BGTU) {
4086 TOut.
emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
4090 if (AcceptsEquality) {
4093 TOut.
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4095 Warning(IDLoc,
"branch is always taken");
4102 if (IsSrcRegZero || IsTrgRegZero) {
4103 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
4104 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
4111 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
4112 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
4118 TOut.
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4120 Warning(IDLoc,
"branch is always taken");
4136 TOut.
emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
4137 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
4144 TOut.
emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
4145 IsSrcRegZero ? TrgReg : SrcReg,
4152 MCRegister ATRegNum = getATReg(IDLoc);
4156 if (!EmittedNoMacroWarning)
4157 warnIfNoMacro(IDLoc);
4174 TOut.
emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
4175 ReverseOrderSLT ? TrgReg : SrcReg,
4176 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
4178 TOut.
emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
4179 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
4193bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4194 const MCSubtargetInfo *STI,
4195 const bool IsMips64,
const bool Signed) {
4196 MipsTargetStreamer &TOut = getTargetStreamer();
4198 warnIfNoMacro(IDLoc);
4200 const MCOperand &RdRegOp = Inst.
getOperand(0);
4201 assert(RdRegOp.
isReg() &&
"expected register operand kind");
4202 MCRegister RdReg = RdRegOp.
getReg();
4204 const MCOperand &RsRegOp = Inst.
getOperand(1);
4205 assert(RsRegOp.
isReg() &&
"expected register operand kind");
4206 MCRegister RsReg = RsRegOp.
getReg();
4213 "expected register or immediate operand kind");
4217 ImmValue = RtOp.
getImm();
4224 DivOp =
Signed ? Mips::DSDIV : Mips::DUDIV;
4225 ZeroReg = Mips::ZERO_64;
4228 DivOp =
Signed ? Mips::SDIV : Mips::UDIV;
4229 ZeroReg = Mips::ZERO;
4233 bool UseTraps = useTraps();
4236 bool isDiv = Opcode == Mips::SDivMacro || Opcode == Mips::SDivIMacro ||
4237 Opcode == Mips::UDivMacro || Opcode == Mips::UDivIMacro ||
4238 Opcode == Mips::DSDivMacro || Opcode == Mips::DSDivIMacro ||
4239 Opcode == Mips::DUDivMacro || Opcode == Mips::DUDivIMacro;
4241 bool isRem = Opcode == Mips::SRemMacro || Opcode == Mips::SRemIMacro ||
4242 Opcode == Mips::URemMacro || Opcode == Mips::URemIMacro ||
4243 Opcode == Mips::DSRemMacro || Opcode == Mips::DSRemIMacro ||
4244 Opcode == Mips::DURemMacro || Opcode == Mips::DURemIMacro;
4247 MCRegister ATReg = getATReg(IDLoc);
4253 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4255 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4259 if (isRem && (ImmValue == 1 || (
Signed && (ImmValue == -1)))) {
4260 TOut.
emitRRR(Mips::OR, RdReg, ZeroReg, ZeroReg, IDLoc, STI);
4262 }
else if (isDiv && ImmValue == 1) {
4263 TOut.
emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI);
4265 }
else if (isDiv &&
Signed && ImmValue == -1) {
4266 TOut.
emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
4269 if (loadImmediate(ImmValue, ATReg, MCRegister(),
isInt<32>(ImmValue),
4270 false, Inst.
getLoc(), Out, STI))
4272 TOut.
emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
4273 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4283 if (!
NoZeroDivCheck && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
4285 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4288 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4294 if (isRem && (RdReg == Mips::ZERO || RdReg == Mips::ZERO_64)) {
4295 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4304 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4307 TOut.
emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4310 BrTarget =
Context.createTempSymbol();
4313 TOut.
emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4318 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4324 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4328bool MipsAsmParser::expandTrunc(MCInst &Inst,
bool IsDouble,
bool Is64FPU,
4329 SMLoc IDLoc, MCStreamer &Out,
4330 const MCSubtargetInfo *STI) {
4331 MipsTargetStreamer &TOut = getTargetStreamer();
4341 if (hasMips1() && !hasMips2()) {
4342 MCRegister ATReg = getATReg(IDLoc);
4345 TOut.
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4346 TOut.
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4348 TOut.
emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4349 TOut.
emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4350 TOut.
emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4352 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4354 FirstReg, SecondReg, IDLoc, STI);
4355 TOut.
emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4360 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4362 FirstReg, SecondReg, IDLoc, STI);
4367bool MipsAsmParser::expandUlh(MCInst &Inst,
bool Signed, SMLoc IDLoc,
4368 MCStreamer &Out,
const MCSubtargetInfo *STI) {
4369 if (hasMips32r6() || hasMips64r6()) {
4370 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4373 const MCOperand &DstRegOp = Inst.
getOperand(0);
4374 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4375 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4376 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4377 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4378 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4380 MipsTargetStreamer &TOut = getTargetStreamer();
4381 MCRegister DstReg = DstRegOp.
getReg();
4382 MCRegister SrcReg = SrcRegOp.
getReg();
4383 int64_t OffsetValue = OffsetImmOp.
getImm();
4387 warnIfNoMacro(IDLoc);
4388 MCRegister ATReg = getATReg(IDLoc);
4393 if (IsLargeOffset) {
4394 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4399 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4400 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4404 MCRegister FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4405 MCRegister SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4407 MCRegister LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4408 MCRegister SllReg = IsLargeOffset ? DstReg : ATReg;
4410 TOut.
emitRRI(
Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4411 FirstOffset, IDLoc, STI);
4412 TOut.
emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4413 TOut.
emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4414 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4419bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4420 const MCSubtargetInfo *STI) {
4421 if (hasMips32r6() || hasMips64r6()) {
4422 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4425 const MCOperand &DstRegOp = Inst.
getOperand(0);
4426 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4427 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4428 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4429 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4430 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4432 MipsTargetStreamer &TOut = getTargetStreamer();
4433 MCRegister DstReg = DstRegOp.
getReg();
4434 MCRegister SrcReg = SrcRegOp.
getReg();
4435 int64_t OffsetValue = OffsetImmOp.
getImm();
4437 warnIfNoMacro(IDLoc);
4438 MCRegister ATReg = getATReg(IDLoc);
4443 if (IsLargeOffset) {
4444 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4449 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4450 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4454 if (IsLargeOffset) {
4455 TOut.
emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4456 TOut.
emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4457 TOut.
emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4458 TOut.
emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4459 TOut.
emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4460 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4462 TOut.
emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4463 TOut.
emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4464 TOut.
emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4470bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4471 const MCSubtargetInfo *STI) {
4472 if (hasMips32r6() || hasMips64r6()) {
4473 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4476 const MCOperand &DstRegOp = Inst.
getOperand(0);
4477 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4478 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4479 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4480 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4481 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4483 MipsTargetStreamer &TOut = getTargetStreamer();
4484 MCRegister DstReg = DstRegOp.
getReg();
4485 MCRegister SrcReg = SrcRegOp.
getReg();
4486 int64_t OffsetValue = OffsetImmOp.
getImm();
4490 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4491 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4495 bool IsLoadInst = (Inst.
getOpcode() == Mips::Ulw);
4496 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4497 MCRegister TmpReg = SrcReg;
4498 if (IsLargeOffset || DoMove) {
4499 warnIfNoMacro(IDLoc);
4500 TmpReg = getATReg(IDLoc);
4505 if (IsLargeOffset) {
4506 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4514 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4515 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4516 TOut.
emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4517 TOut.
emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4520 TOut.
emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4525bool MipsAsmParser::expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4526 const MCSubtargetInfo *STI) {
4527 MipsTargetStreamer &TOut = getTargetStreamer();
4539 warnIfNoMacro(IDLoc);
4553 TOut.
emitRRR(OpCode, DstReg, SrcReg, OpReg, IDLoc, STI);
4554 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4559bool MipsAsmParser::expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4560 const MCSubtargetInfo *STI) {
4561 MipsTargetStreamer &TOut = getTargetStreamer();
4571 unsigned OpRegCode, OpImmCode;
4573 warnIfNoMacro(IDLoc);
4577 case Mips::SGEImm64:
4578 OpRegCode = Mips::SLT;
4579 OpImmCode = Mips::SLTi;
4582 case Mips::SGEUImm64:
4583 OpRegCode = Mips::SLTu;
4584 OpImmCode = Mips::SLTiu;
4593 TOut.
emitRRI(OpImmCode, DstReg, SrcReg, ImmValue, IDLoc, STI);
4594 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4596 MCRegister ImmReg = DstReg;
4597 if (DstReg == SrcReg) {
4598 MCRegister ATReg = getATReg(Inst.
getLoc());
4604 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
4605 false, IDLoc, Out, STI))
4608 TOut.
emitRRR(OpRegCode, DstReg, SrcReg, ImmReg, IDLoc, STI);
4609 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4615bool MipsAsmParser::expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4616 const MCSubtargetInfo *STI) {
4617 MipsTargetStreamer &TOut = getTargetStreamer();
4626 MCRegister ImmReg = DstReg;
4630 warnIfNoMacro(IDLoc);
4634 case Mips::SGTImm64:
4638 case Mips::SGTUImm64:
4645 if (DstReg == SrcReg) {
4646 MCRegister ATReg = getATReg(Inst.
getLoc());
4652 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
false,
4657 TOut.
emitRRR(OpCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4662bool MipsAsmParser::expandSle(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4663 const MCSubtargetInfo *STI) {
4664 MipsTargetStreamer &TOut = getTargetStreamer();
4676 warnIfNoMacro(IDLoc);
4690 TOut.
emitRRR(OpCode, DstReg, OpReg, SrcReg, IDLoc, STI);
4691 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4696bool MipsAsmParser::expandSleImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4697 const MCSubtargetInfo *STI) {
4698 MipsTargetStreamer &TOut = getTargetStreamer();
4710 warnIfNoMacro(IDLoc);
4714 case Mips::SLEImm64:
4715 OpRegCode = Mips::SLT;
4718 case Mips::SLEUImm64:
4719 OpRegCode = Mips::SLTu;
4726 MCRegister ImmReg = DstReg;
4727 if (DstReg == SrcReg) {
4728 MCRegister ATReg = getATReg(Inst.
getLoc());
4734 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
false,
4738 TOut.
emitRRR(OpRegCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4739 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4744bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
4746 const MCSubtargetInfo *STI) {
4747 MipsTargetStreamer &TOut = getTargetStreamer();
4755 MCRegister FinalDstReg;
4762 unsigned FinalOpcode = Inst.
getOpcode();
4764 if (DstReg == SrcReg) {
4765 ATReg = getATReg(Inst.
getLoc());
4768 FinalDstReg = DstReg;
4772 if (!loadImmediate(ImmValue, DstReg, MCRegister(), Is32Bit,
false,
4773 Inst.
getLoc(), Out, STI)) {
4774 switch (FinalOpcode) {
4778 FinalOpcode = Mips::ADD;
4781 FinalOpcode = Mips::ADDu;
4784 FinalOpcode = Mips::AND;
4787 FinalOpcode = Mips::NOR;
4790 FinalOpcode = Mips::OR;
4793 FinalOpcode = Mips::SLT;
4796 FinalOpcode = Mips::SLTu;
4799 FinalOpcode = Mips::XOR;
4802 FinalOpcode = Mips::ADD_MM;
4804 case Mips::ADDiu_MM:
4805 FinalOpcode = Mips::ADDu_MM;
4808 FinalOpcode = Mips::AND_MM;
4811 FinalOpcode = Mips::OR_MM;
4814 FinalOpcode = Mips::SLT_MM;
4816 case Mips::SLTiu_MM:
4817 FinalOpcode = Mips::SLTu_MM;
4820 FinalOpcode = Mips::XOR_MM;
4823 FinalOpcode = Mips::AND64;
4825 case Mips::NORImm64:
4826 FinalOpcode = Mips::NOR64;
4829 FinalOpcode = Mips::OR64;
4831 case Mips::SLTImm64:
4832 FinalOpcode = Mips::SLT64;
4834 case Mips::SLTUImm64:
4835 FinalOpcode = Mips::SLTu64;
4838 FinalOpcode = Mips::XOR64;
4843 TOut.
emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4845 TOut.
emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4851bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4852 const MCSubtargetInfo *STI) {
4853 MipsTargetStreamer &TOut = getTargetStreamer();
4858 MCRegister TmpReg =
DReg;
4860 unsigned FirstShift = Mips::NOP;
4861 unsigned SecondShift = Mips::NOP;
4863 if (hasMips32r2()) {
4865 TmpReg = getATReg(Inst.
getLoc());
4871 TOut.
emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4872 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
4877 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
4889 FirstShift = Mips::SRLV;
4890 SecondShift = Mips::SLLV;
4893 FirstShift = Mips::SLLV;
4894 SecondShift = Mips::SRLV;
4898 ATReg = getATReg(Inst.
getLoc());
4902 TOut.
emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4903 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
4904 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
4905 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
4913bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
4915 const MCSubtargetInfo *STI) {
4916 MipsTargetStreamer &TOut = getTargetStreamer();
4922 unsigned FirstShift = Mips::NOP;
4923 unsigned SecondShift = Mips::NOP;
4925 if (hasMips32r2()) {
4927 uint64_t MaxShift = 32;
4928 uint64_t ShiftValue = ImmValue;
4930 ShiftValue = MaxShift - ImmValue;
4931 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
4936 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.
getLoc(), STI);
4944 if (ImmValue == 0) {
4953 FirstShift = Mips::SLL;
4954 SecondShift = Mips::SRL;
4957 FirstShift = Mips::SRL;
4958 SecondShift = Mips::SLL;
4962 ATReg = getATReg(Inst.
getLoc());
4966 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.
getLoc(), STI);
4967 TOut.
emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.
getLoc(), STI);
4968 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
4976bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4977 const MCSubtargetInfo *STI) {
4978 MipsTargetStreamer &TOut = getTargetStreamer();
4983 MCRegister TmpReg =
DReg;
4985 unsigned FirstShift = Mips::NOP;
4986 unsigned SecondShift = Mips::NOP;
4988 if (hasMips64r2()) {
4989 if (TmpReg == SReg) {
4990 TmpReg = getATReg(Inst.
getLoc());
4996 TOut.
emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4997 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
5002 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
5014 FirstShift = Mips::DSRLV;
5015 SecondShift = Mips::DSLLV;
5018 FirstShift = Mips::DSLLV;
5019 SecondShift = Mips::DSRLV;
5023 ATReg = getATReg(Inst.
getLoc());
5027 TOut.
emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
5028 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
5029 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
5030 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5038bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
5040 const MCSubtargetInfo *STI) {
5041 MipsTargetStreamer &TOut = getTargetStreamer();
5047 unsigned FirstShift = Mips::NOP;
5048 unsigned SecondShift = Mips::NOP;
5052 if (hasMips64r2()) {
5053 unsigned FinalOpcode = Mips::NOP;
5055 FinalOpcode = Mips::DROTR;
5056 else if (ImmValue % 32 == 0)
5057 FinalOpcode = Mips::DROTR32;
5058 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
5060 FinalOpcode = Mips::DROTR32;
5062 FinalOpcode = Mips::DROTR;
5063 }
else if (ImmValue >= 33) {
5065 FinalOpcode = Mips::DROTR;
5067 FinalOpcode = Mips::DROTR32;
5070 uint64_t ShiftValue = ImmValue % 32;
5072 ShiftValue = (32 - ImmValue % 32) % 32;
5074 TOut.
emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
5080 if (ImmValue == 0) {
5081 TOut.
emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.
getLoc(), STI);
5089 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5090 FirstShift = Mips::DSLL;
5091 SecondShift = Mips::DSRL32;
5093 if (ImmValue == 32) {
5094 FirstShift = Mips::DSLL32;
5095 SecondShift = Mips::DSRL32;
5097 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5098 FirstShift = Mips::DSLL32;
5099 SecondShift = Mips::DSRL;
5103 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5104 FirstShift = Mips::DSRL;
5105 SecondShift = Mips::DSLL32;
5107 if (ImmValue == 32) {
5108 FirstShift = Mips::DSRL32;
5109 SecondShift = Mips::DSLL32;
5111 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5112 FirstShift = Mips::DSRL32;
5113 SecondShift = Mips::DSLL;
5118 ATReg = getATReg(Inst.
getLoc());
5122 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.
getLoc(), STI);
5123 TOut.
emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
5125 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5133bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5134 const MCSubtargetInfo *STI) {
5135 MipsTargetStreamer &TOut = getTargetStreamer();
5139 TOut.
emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
5140 if (FirstRegOp != SecondRegOp)
5141 TOut.
emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
5144 TOut.
emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
5149bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5150 const MCSubtargetInfo *STI) {
5151 MipsTargetStreamer &TOut = getTargetStreamer();
5157 ATReg = getATReg(IDLoc);
5161 loadImmediate(ImmValue, ATReg, MCRegister(),
true,
false, IDLoc, Out, STI);
5163 TOut.
emitRR(Inst.
getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
5164 SrcReg, ATReg, IDLoc, STI);
5166 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5171bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5172 const MCSubtargetInfo *STI) {
5173 MipsTargetStreamer &TOut = getTargetStreamer();
5179 ATReg = getATReg(Inst.
getLoc());
5183 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
5184 SrcReg, TmpReg, IDLoc, STI);
5186 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5188 TOut.
emitRRI(Inst.
getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
5189 DstReg, DstReg, 0x1F, IDLoc, STI);
5191 TOut.
emitR(Mips::MFHI, ATReg, IDLoc, STI);
5194 TOut.
emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
5201 TOut.
emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
5202 if (AssemblerOptions.
back()->isReorder())
5204 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5208 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5213bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5214 const MCSubtargetInfo *STI) {
5215 MipsTargetStreamer &TOut = getTargetStreamer();
5221 ATReg = getATReg(IDLoc);
5225 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
5226 SrcReg, TmpReg, IDLoc, STI);
5228 TOut.
emitR(Mips::MFHI, ATReg, IDLoc, STI);
5229 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5231 TOut.
emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);
5238 TOut.
emitRRX(Mips::BEQ, ATReg, Mips::ZERO, LabelOp, IDLoc, STI);
5239 if (AssemblerOptions.
back()->isReorder())
5241 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5249bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5250 const MCSubtargetInfo *STI) {
5251 MipsTargetStreamer &TOut = getTargetStreamer();
5256 TOut.
emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
5257 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5267bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
5269 const MCSubtargetInfo *STI,
5274 warnIfNoMacro(IDLoc);
5276 MipsTargetStreamer &TOut = getTargetStreamer();
5277 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
5279 MCRegister SecondReg =
nextReg(FirstReg);
5284 warnIfRegIndexIsAT(FirstReg, IDLoc);
5287 "Offset for load macro is not immediate!");
5290 signed NextOffset = FirstOffset.
getImm() + 4;
5298 if (FirstReg != BaseReg || !IsLoad) {
5299 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5300 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5302 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5303 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5315bool MipsAsmParser::expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc,
5317 const MCSubtargetInfo *STI) {
5321 warnIfNoMacro(IDLoc);
5323 MipsTargetStreamer &TOut = getTargetStreamer();
5324 unsigned Opcode = Mips::SWC1;
5326 MCRegister SecondReg =
nextReg(FirstReg);
5331 warnIfRegIndexIsAT(FirstReg, IDLoc);
5334 "Offset for macro is not immediate!");
5337 signed NextOffset = FirstOffset.
getImm() + 4;
5343 if (!IsLittleEndian)
5346 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5347 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5352bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5353 const MCSubtargetInfo *STI) {
5354 MipsTargetStreamer &TOut = getTargetStreamer();
5365 warnIfNoMacro(IDLoc);
5367 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5368 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5369 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5373 MCRegister
Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5374 TOut.
emitRRI(Mips::SLTiu, DstReg,
Reg, 1, IDLoc, STI);
5378bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5379 const MCSubtargetInfo *STI) {
5380 MipsTargetStreamer &TOut = getTargetStreamer();
5391 warnIfNoMacro(IDLoc);
5394 TOut.
emitRRI(Mips::SLTiu, DstReg, SrcReg, 1, IDLoc, STI);
5398 if (SrcReg == Mips::ZERO) {
5399 Warning(IDLoc,
"comparison is always false");
5400 TOut.
emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
5401 DstReg, SrcReg, SrcReg, IDLoc, STI);
5406 if (Imm > -0x8000 && Imm < 0) {
5408 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5414 MCRegister ATReg = getATReg(IDLoc);
5418 if (loadImmediate(Imm, ATReg, MCRegister(),
true, isGP64bit(), IDLoc, Out,
5422 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5423 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5427 TOut.
emitRRI(
Opc, DstReg, SrcReg, Imm, IDLoc, STI);
5428 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5432bool MipsAsmParser::expandSne(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5433 const MCSubtargetInfo *STI) {
5435 MipsTargetStreamer &TOut = getTargetStreamer();
5446 warnIfNoMacro(IDLoc);
5448 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5449 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5450 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5454 MCRegister
Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5455 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO,
Reg, IDLoc, STI);
5459bool MipsAsmParser::expandSneI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5460 const MCSubtargetInfo *STI) {
5461 MipsTargetStreamer &TOut = getTargetStreamer();
5472 warnIfNoMacro(IDLoc);
5474 if (ImmValue == 0) {
5475 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, SrcReg, IDLoc, STI);
5479 if (SrcReg == Mips::ZERO) {
5480 Warning(IDLoc,
"comparison is always true");
5481 if (loadImmediate(1, DstReg, MCRegister(),
true,
false, IDLoc, Out, STI))
5487 if (ImmValue > -0x8000 && ImmValue < 0) {
5488 ImmValue = -ImmValue;
5489 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5495 TOut.
emitRRI(
Opc, DstReg, SrcReg, ImmValue, IDLoc, STI);
5496 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5500 MCRegister ATReg = getATReg(IDLoc);
5504 if (loadImmediate(ImmValue, ATReg, MCRegister(),
isInt<32>(ImmValue),
false,
5508 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5509 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5572 case Mips::F0:
return Mips::ZERO;
5573 case Mips::F1:
return Mips::AT;
5574 case Mips::F2:
return Mips::V0;
5575 case Mips::F3:
return Mips::V1;
5576 case Mips::F4:
return Mips::A0;
5577 case Mips::F5:
return Mips::A1;
5578 case Mips::F6:
return Mips::A2;
5579 case Mips::F7:
return Mips::A3;
5580 case Mips::F8:
return Mips::T0;
5581 case Mips::F9:
return Mips::T1;
5582 case Mips::F10:
return Mips::T2;
5583 case Mips::F11:
return Mips::T3;
5584 case Mips::F12:
return Mips::T4;
5585 case Mips::F13:
return Mips::T5;
5586 case Mips::F14:
return Mips::T6;
5587 case Mips::F15:
return Mips::T7;
5588 case Mips::F16:
return Mips::S0;
5589 case Mips::F17:
return Mips::S1;
5590 case Mips::F18:
return Mips::S2;
5591 case Mips::F19:
return Mips::S3;
5592 case Mips::F20:
return Mips::S4;
5593 case Mips::F21:
return Mips::S5;
5594 case Mips::F22:
return Mips::S6;
5595 case Mips::F23:
return Mips::S7;
5596 case Mips::F24:
return Mips::T8;
5597 case Mips::F25:
return Mips::T9;
5598 case Mips::F26:
return Mips::K0;
5599 case Mips::F27:
return Mips::K1;
5600 case Mips::F28:
return Mips::GP;
5601 case Mips::F29:
return Mips::SP;
5602 case Mips::F30:
return Mips::FP;
5603 case Mips::F31:
return Mips::RA;
5611 case Mips::COP00:
return Mips::ZERO;
5612 case Mips::COP01:
return Mips::AT;
5613 case Mips::COP02:
return Mips::V0;
5614 case Mips::COP03:
return Mips::V1;
5615 case Mips::COP04:
return Mips::A0;
5616 case Mips::COP05:
return Mips::A1;
5617 case Mips::COP06:
return Mips::A2;
5618 case Mips::COP07:
return Mips::A3;
5619 case Mips::COP08:
return Mips::T0;
5620 case Mips::COP09:
return Mips::T1;
5621 case Mips::COP010:
return Mips::T2;
5622 case Mips::COP011:
return Mips::T3;
5623 case Mips::COP012:
return Mips::T4;
5624 case Mips::COP013:
return Mips::T5;
5625 case Mips::COP014:
return Mips::T6;
5626 case Mips::COP015:
return Mips::T7;
5627 case Mips::COP016:
return Mips::S0;
5628 case Mips::COP017:
return Mips::S1;
5629 case Mips::COP018:
return Mips::S2;
5630 case Mips::COP019:
return Mips::S3;
5631 case Mips::COP020:
return Mips::S4;
5632 case Mips::COP021:
return Mips::S5;
5633 case Mips::COP022:
return Mips::S6;
5634 case Mips::COP023:
return Mips::S7;
5635 case Mips::COP024:
return Mips::T8;
5636 case Mips::COP025:
return Mips::T9;
5637 case Mips::COP026:
return Mips::K0;
5638 case Mips::COP027:
return Mips::K1;
5639 case Mips::COP028:
return Mips::GP;
5640 case Mips::COP029:
return Mips::SP;
5641 case Mips::COP030:
return Mips::FP;
5642 case Mips::COP031:
return Mips::RA;
5649bool MipsAsmParser::expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5650 const MCSubtargetInfo *STI) {
5651 MipsTargetStreamer &TOut = getTargetStreamer();
5656 bool IsMFTR =
false;
5710 IsMFTR ? MCRegister(rd)
5712 : Inst.getOperand(0).
getReg());
5714 TOut.
emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, u, sel, h, IDLoc,
5719bool MipsAsmParser::expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5720 const MCSubtargetInfo *STI) {
5725 warnIfNoMacro(IDLoc);
5727 MipsTargetStreamer &TOut = getTargetStreamer();
5728 unsigned Opcode = Inst.
getOpcode() == Mips::SaaAddr ? Mips::SAA : Mips::SAAD;
5731 const MCOperand &BaseOp = Inst.
getOperand(2);
5733 if (BaseOp.
isImm()) {
5734 int64_t ImmValue = BaseOp.
getImm();
5735 if (ImmValue == 0) {
5736 TOut.
emitRR(Opcode, RtReg, BaseReg, IDLoc, STI);
5741 MCRegister ATReg = getATReg(IDLoc);
5745 if (expandLoadAddress(ATReg, BaseReg, BaseOp, !isGP64bit(), IDLoc, Out, STI))
5748 TOut.
emitRR(Opcode, RtReg, ATReg, IDLoc, STI);
5753MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
5757 return Match_Success;
5760 if (
static_cast<MipsOperand &
>(*Operands[1])
5761 .isValidForTie(
static_cast<MipsOperand &
>(*Operands[2])))
5762 return Match_Success;
5763 return Match_RequiresSameSrcAndDst;
5767unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
5774 return Match_RequiresNoZeroRegister;
5775 return Match_Success;
5781 case Mips::JALR_HB64:
5782 case Mips::JALRC_HB_MMR6:
5783 case Mips::JALRC_MMR6:
5785 return Match_RequiresDifferentSrcAndDst;
5786 return Match_Success;
5789 return Match_RequiresDifferentSrcAndDst;
5790 return Match_Success;
5793 return Match_NonZeroOperandForSync;
5794 return Match_Success;
5800 return Match_NonZeroOperandForMTCX;
5801 return Match_Success;
5814 case Mips::BLEZC:
case Mips::BLEZC_MMR6:
5815 case Mips::BGEZC:
case Mips::BGEZC_MMR6:
5816 case Mips::BGTZC:
case Mips::BGTZC_MMR6:
5817 case Mips::BLTZC:
case Mips::BLTZC_MMR6:
5818 case Mips::BEQZC:
case Mips::BEQZC_MMR6:
5819 case Mips::BNEZC:
case Mips::BNEZC_MMR6:
5828 return Match_RequiresNoZeroRegister;
5829 return Match_Success;
5830 case Mips::BGEC:
case Mips::BGEC_MMR6:
5831 case Mips::BLTC:
case Mips::BLTC_MMR6:
5832 case Mips::BGEUC:
case Mips::BGEUC_MMR6:
5833 case Mips::BLTUC:
case Mips::BLTUC_MMR6:
5834 case Mips::BEQC:
case Mips::BEQC_MMR6:
5835 case Mips::BNEC:
case Mips::BNEC_MMR6:
5844 return Match_RequiresNoZeroRegister;
5847 return Match_RequiresNoZeroRegister;
5849 return Match_RequiresDifferentOperands;
5850 return Match_Success;
5853 "Operands must be immediates for dins!");
5856 if ((0 > (Pos +
Size)) || ((Pos +
Size) > 32))
5857 return Match_RequiresPosSizeRange0_32;
5858 return Match_Success;
5863 "Operands must be immediates for dinsm/dinsu!");
5866 if ((32 >= (Pos +
Size)) || ((Pos +
Size) > 64))
5867 return Match_RequiresPosSizeRange33_64;
5868 return Match_Success;
5872 "Operands must be immediates for DEXTM!");
5875 if ((1 > (Pos +
Size)) || ((Pos +
Size) > 63))
5876 return Match_RequiresPosSizeUImm6;
5877 return Match_Success;
5882 "Operands must be immediates for dextm/dextu!");
5885 if ((32 > (Pos +
Size)) || ((Pos +
Size) > 64))
5886 return Match_RequiresPosSizeRange33_64;
5887 return Match_Success;
5889 case Mips::CRC32B:
case Mips::CRC32CB:
5890 case Mips::CRC32H:
case Mips::CRC32CH:
5891 case Mips::CRC32W:
case Mips::CRC32CW:
5892 case Mips::CRC32D:
case Mips::CRC32CD:
5894 return Match_RequiresSameSrcAndDst;
5895 return Match_Success;
5898 uint64_t TSFlags = MII.get(Inst.
getOpcode()).TSFlags;
5901 return Match_NoFCCRegisterForCurrentISA;
5903 return Match_Success;
5911 if (ErrorLoc ==
SMLoc())
5918bool MipsAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
5921 uint64_t &ErrorInfo,
5922 bool MatchingInlineAsm) {
5924 unsigned MatchResult =
5925 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
5927 switch (MatchResult) {
5929 if (processInstruction(Inst, IDLoc, Out, STI))
5932 case Match_MissingFeature:
5933 Error(IDLoc,
"instruction requires a CPU feature not currently enabled");
5935 case Match_InvalidTiedOperand:
5936 Error(IDLoc,
"operand must match destination register");
5938 case Match_InvalidOperand: {
5939 SMLoc ErrorLoc = IDLoc;
5940 if (ErrorInfo != ~0ULL) {
5941 if (ErrorInfo >= Operands.
size())
5942 return Error(IDLoc,
"too few operands for instruction");
5944 ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5945 if (ErrorLoc == SMLoc())
5949 return Error(ErrorLoc,
"invalid operand for instruction");
5951 case Match_NonZeroOperandForSync:
5953 "s-type must be zero or unspecified for pre-MIPS32 ISAs");
5954 case Match_NonZeroOperandForMTCX:
5955 return Error(IDLoc,
"selector must be zero for pre-MIPS32 ISAs");
5956 case Match_MnemonicFail:
5957 return Error(IDLoc,
"invalid instruction");
5958 case Match_RequiresDifferentSrcAndDst:
5959 return Error(IDLoc,
"source and destination must be different");
5960 case Match_RequiresDifferentOperands:
5961 return Error(IDLoc,
"registers must be different");
5962 case Match_RequiresNoZeroRegister:
5963 return Error(IDLoc,
"invalid operand ($zero) for instruction");
5964 case Match_RequiresSameSrcAndDst:
5965 return Error(IDLoc,
"source and destination must match");
5966 case Match_NoFCCRegisterForCurrentISA:
5968 "non-zero fcc register doesn't exist in current ISA level");
5973 "expected 1-bit unsigned immediate");
5976 "expected 2-bit unsigned immediate");
5979 "expected immediate in range 1 .. 4");
5982 "expected 3-bit unsigned immediate");
5985 "expected 4-bit unsigned immediate");
5988 "expected 4-bit signed immediate");
5991 "expected 5-bit unsigned immediate");
5994 "expected 5-bit signed immediate");
5997 "expected immediate in range 1 .. 32");
5998 case Match_UImm5_32:
6000 "expected immediate in range 32 .. 63");
6001 case Match_UImm5_33:
6003 "expected immediate in range 33 .. 64");
6004 case Match_UImm5_0_Report_UImm6:
6008 "expected 6-bit unsigned immediate");
6009 case Match_UImm5_Lsl2:
6011 "expected both 7-bit unsigned immediate and multiple of 4");
6012 case Match_UImmRange2_64:
6014 "expected immediate in range 2 .. 64");
6017 "expected 6-bit unsigned immediate");
6018 case Match_UImm6_Lsl2:
6020 "expected both 8-bit unsigned immediate and multiple of 4");
6023 "expected 6-bit signed immediate");
6026 "expected 7-bit unsigned immediate");
6027 case Match_UImm7_N1:
6029 "expected immediate in range -1 .. 126");
6030 case Match_SImm7_Lsl2:
6032 "expected both 9-bit signed immediate and multiple of 4");
6035 "expected 8-bit unsigned immediate");
6036 case Match_UImm10_0:
6038 "expected 10-bit unsigned immediate");
6039 case Match_SImm10_0:
6041 "expected 10-bit signed immediate");
6042 case Match_SImm11_0:
6044 "expected 11-bit signed immediate");
6046 case Match_UImm16_Relaxed:
6047 case Match_UImm16_AltRelaxed:
6049 "expected 16-bit unsigned immediate");
6051 case Match_SImm16_Relaxed:
6053 "expected 16-bit signed immediate");
6054 case Match_SImm18_Lsl3:
6056 "expected both 18-bit signed immediate and multiple of 8");
6057 case Match_SImm19_Lsl2:
6059 "expected both 19-bit signed immediate and multiple of 4");
6060 case Match_UImm20_0:
6062 "expected 20-bit unsigned immediate");
6063 case Match_UImm26_0:
6065 "expected 26-bit unsigned immediate");
6067 case Match_SImm32_Relaxed:
6069 "expected 32-bit signed immediate");
6070 case Match_UImm32_Coerced:
6072 "expected 32-bit immediate");
6073 case Match_MemSImm9:
6075 "expected memory with 9-bit signed offset");
6076 case Match_MemSImm10:
6078 "expected memory with 10-bit signed offset");
6079 case Match_MemSImm10Lsl1:
6081 "expected memory with 11-bit signed offset and multiple of 2");
6082 case Match_MemSImm10Lsl2:
6084 "expected memory with 12-bit signed offset and multiple of 4");
6085 case Match_MemSImm10Lsl3:
6087 "expected memory with 13-bit signed offset and multiple of 8");
6088 case Match_MemSImm11:
6090 "expected memory with 11-bit signed offset");
6091 case Match_MemSImm12:
6093 "expected memory with 12-bit signed offset");
6094 case Match_MemSImm16:
6096 "expected memory with 16-bit signed offset");
6097 case Match_MemSImmPtr:
6099 "expected memory with 32-bit signed offset");
6100 case Match_RequiresPosSizeRange0_32: {
6101 SMLoc ErrorStart = Operands[3]->getStartLoc();
6102 SMLoc ErrorEnd = Operands[4]->getEndLoc();
6103 return Error(ErrorStart,
"size plus position are not in the range 0 .. 32",
6104 SMRange(ErrorStart, ErrorEnd));
6106 case Match_RequiresPosSizeUImm6: {
6107 SMLoc ErrorStart = Operands[3]->getStartLoc();
6108 SMLoc ErrorEnd = Operands[4]->getEndLoc();
6109 return Error(ErrorStart,
"size plus position are not in the range 1 .. 63",
6110 SMRange(ErrorStart, ErrorEnd));
6112 case Match_RequiresPosSizeRange33_64: {
6113 SMLoc ErrorStart = Operands[3]->getStartLoc();
6114 SMLoc ErrorEnd = Operands[4]->getEndLoc();
6115 return Error(ErrorStart,
"size plus position are not in the range 33 .. 64",
6116 SMRange(ErrorStart, ErrorEnd));
6123void MipsAsmParser::warnIfRegIndexIsAT(MCRegister RegIndex, SMLoc Loc) {
6124 if (RegIndex && AssemblerOptions.
back()->getATRegIndex() == RegIndex)
6125 Warning(Loc,
"used $at (currently $" + Twine(RegIndex.
id()) +
6126 ") without \".set noat\"");
6129void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
6130 if (!AssemblerOptions.
back()->isMacro())
6131 Warning(Loc,
"macro instruction expanded into multiple instructions");
6134void MipsAsmParser::ConvertXWPOperands(MCInst &Inst,
6138 "Unexpected instruction!");
6139 ((MipsOperand &)*Operands[1]).addGPR32ZeroAsmRegOperands(Inst, 1);
6140 MCRegister NextReg =
nextReg(((MipsOperand &)*Operands[1]).getGPR32Reg());
6142 ((MipsOperand &)*Operands[2]).addMemOperands(Inst, 2);
6146MipsAsmParser::printWarningWithFixIt(
const Twine &
Msg,
const Twine &FixMsg,
6147 SMRange
Range,
bool ShowColors) {
6153int MipsAsmParser::matchCPURegisterName(StringRef Name) {
6156 CC = StringSwitch<unsigned>(Name)
6158 .Cases({
"at",
"AT"}, 1)
6192 if (!(isABI_N32() || isABI_N64()))
6195 if (12 <= CC && CC <= 15) {
6197 AsmToken RegTok = getLexer().peekTok();
6200 StringRef FixedName = StringSwitch<StringRef>(Name)
6206 assert(FixedName !=
"" &&
"Register name is not one of t4-t7.");
6208 printWarningWithFixIt(
"register names $t4-$t7 are only available in O32.",
6209 "Did you mean $" + FixedName +
"?", RegRange);
6215 if (8 <= CC && CC <= 11)
6219 CC = StringSwitch<unsigned>(Name)
6231int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
6234 CC = StringSwitch<unsigned>(Name)
6235 .Case(
"hwr_cpunum", 0)
6236 .Case(
"hwr_synci_step", 1)
6238 .Case(
"hwr_ccres", 3)
6239 .Case(
"hwr_ulr", 29)
6245int MipsAsmParser::matchFPURegisterName(StringRef Name) {
6246 if (Name[0] ==
'f') {
6247 StringRef NumString =
Name.substr(1);
6258int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
6259 if (
Name.starts_with(
"fcc")) {
6260 StringRef NumString =
Name.substr(3);
6271int MipsAsmParser::matchACRegisterName(StringRef Name) {
6272 if (
Name.starts_with(
"ac")) {
6273 StringRef NumString =
Name.substr(2);
6284int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
6287 if (
Name.front() !=
'w' ||
Name.drop_front(1).getAsInteger(10, IntVal))
6296int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
6299 CC = StringSwitch<unsigned>(Name)
6302 .Case(
"msaaccess", 2)
6304 .Case(
"msamodify", 4)
6305 .Case(
"msarequest", 5)
6307 .Case(
"msaunmap", 7)
6313bool MipsAsmParser::canUseATReg() {
6314 return AssemblerOptions.
back()->getATRegIndex() != 0;
6317MCRegister MipsAsmParser::getATReg(SMLoc Loc) {
6318 unsigned ATIndex = AssemblerOptions.
back()->getATRegIndex();
6320 reportParseError(Loc,
6321 "pseudo-instruction requires $at, which is not available");
6325 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
6329MCRegister MipsAsmParser::getReg(
int RC,
int RegNo) {
6330 return getContext().getRegisterInfo()->getRegClass(RC).getRegister(RegNo);
6336const MCExpr *MipsAsmParser::parseRelocExpr() {
6337 auto getOp = [](StringRef
Op) {
6338 return StringSwitch<Mips::Specifier>(
Op)
6366 MCAsmParser &Parser = getParser();
6368 const MCExpr *Res =
nullptr;
6374 auto Op = getOp(Name);
6383 while (
Ops.size()) {
6391bool MipsAsmParser::parseOperand(
OperandVector &Operands, StringRef Mnemonic) {
6392 MCAsmParser &Parser = getParser();
6402 ParseStatus Res = MatchOperandParserImpl(Operands, Mnemonic,
true);
6413 switch (getLexer().getKind()) {
6423 if (!parseAnyRegister(Operands).isNoMatch())
6436 Operands.
push_back(MipsOperand::CreateImm(SymRef, S,
E, *
this));
6441 const MCExpr *Expr = parseRelocExpr();
6445 Operands.
push_back(MipsOperand::CreateImm(Expr, S,
E, *
this));
6452bool MipsAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
6454 return !tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess();
6457ParseStatus MipsAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
6460 ParseStatus Res = parseAnyRegister(Operands);
6463 MipsOperand &Operand =
static_cast<MipsOperand &
>(*Operands.
front());
6464 StartLoc = Operand.getStartLoc();
6465 EndLoc = Operand.getEndLoc();
6471 if (Operand.isGPRAsmReg()) {
6473 Reg = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
6483ParseStatus MipsAsmParser::parseMemOperand(
OperandVector &Operands) {
6484 MCAsmParser &Parser = getParser();
6486 const MCExpr *IdVal =
nullptr;
6488 bool isParenExpr =
false;
6499 IdVal = parseRelocExpr();
6505 const AsmToken &Tok = Parser.
getTok();
6507 MipsOperand &Mnemonic =
static_cast<MipsOperand &
>(*Operands[0]);
6508 if (Mnemonic.getToken() ==
"la" || Mnemonic.getToken() ==
"dla") {
6511 Operands.
push_back(MipsOperand::CreateImm(IdVal, S,
E, *
this));
6520 auto Base = MipsOperand::createGPRReg(
6521 0,
"0",
getContext().getRegisterInfo(), S,
E, *
this);
6523 MipsOperand::CreateMem(std::move(
Base), IdVal, S,
E, *
this));
6575 const MCExpr * NextExpr;
6576 if (getParser().parseExpression(NextExpr))
6584 Res = parseAnyRegister(Operands);
6599 std::unique_ptr<MipsOperand>
op(
6600 static_cast<MipsOperand *
>(Operands.
back().release()));
6607 if (IdVal->evaluateAsAbsolute(Imm))
6614 Operands.
push_back(MipsOperand::CreateMem(std::move(
op), IdVal, S,
E, *
this));
6618bool MipsAsmParser::searchSymbolAlias(
OperandVector &Operands) {
6619 MCAsmParser &Parser = getParser();
6628 const MCSymbolRefExpr *
Ref =
static_cast<const MCSymbolRefExpr *
>(Expr);
6629 StringRef DefSymbol =
Ref->getSymbol().getName();
6632 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.
substr(1), S);
6646 if (Entry != RegisterSets.
end()) {
6648 matchAnyRegisterWithoutDollar(Operands,
Entry->getValue(), S);
6659ParseStatus MipsAsmParser::matchAnyRegisterNameWithoutDollar(
6661 int Index = matchCPURegisterName(Identifier);
6663 Operands.
push_back(MipsOperand::createGPRReg(
6664 Index, Identifier,
getContext().getRegisterInfo(), S,
6665 getLexer().getLoc(), *
this));
6669 Index = matchHWRegsRegisterName(Identifier);
6671 Operands.
push_back(MipsOperand::createHWRegsReg(
6672 Index, Identifier,
getContext().getRegisterInfo(), S,
6673 getLexer().getLoc(), *
this));
6677 Index = matchFPURegisterName(Identifier);
6679 Operands.
push_back(MipsOperand::createFGRReg(
6680 Index, Identifier,
getContext().getRegisterInfo(), S,
6681 getLexer().getLoc(), *
this));
6685 Index = matchFCCRegisterName(Identifier);
6687 Operands.
push_back(MipsOperand::createFCCReg(
6688 Index, Identifier,
getContext().getRegisterInfo(), S,
6689 getLexer().getLoc(), *
this));
6693 Index = matchACRegisterName(Identifier);
6695 Operands.
push_back(MipsOperand::createACCReg(
6696 Index, Identifier,
getContext().getRegisterInfo(), S,
6697 getLexer().getLoc(), *
this));
6701 Index = matchMSA128RegisterName(Identifier);
6703 Operands.
push_back(MipsOperand::createMSA128Reg(
6704 Index, Identifier,
getContext().getRegisterInfo(), S,
6705 getLexer().getLoc(), *
this));
6709 Index = matchMSA128CtrlRegisterName(Identifier);
6711 Operands.
push_back(MipsOperand::createMSACtrlReg(
6712 Index, Identifier,
getContext().getRegisterInfo(), S,
6713 getLexer().getLoc(), *
this));
6721MipsAsmParser::matchAnyRegisterWithoutDollar(
OperandVector &Operands,
6722 const AsmToken &Token, SMLoc S) {
6726 return matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
6731 if (RegNum < 0 || RegNum > 31) {
6735 Error(getLexer().getLoc(),
"invalid register number");
6737 Operands.
push_back(MipsOperand::createNumericReg(
6749MipsAsmParser::matchAnyRegisterWithoutDollar(
OperandVector &Operands, SMLoc S) {
6750 auto Token = getLexer().peekTok(
false);
6751 return matchAnyRegisterWithoutDollar(Operands, Token, S);
6754ParseStatus MipsAsmParser::parseAnyRegister(
OperandVector &Operands) {
6755 MCAsmParser &Parser = getParser();
6758 auto Token = Parser.
getTok();
6760 SMLoc S = Token.
getLoc();
6765 if (searchSymbolAlias(Operands))
6773 ParseStatus Res = matchAnyRegisterWithoutDollar(Operands, S);
6781ParseStatus MipsAsmParser::parseJumpTarget(
OperandVector &Operands) {
6782 MCAsmParser &Parser = getParser();
6785 SMLoc S = getLexer().getLoc();
6788 ParseStatus Res = parseAnyRegister(Operands);
6793 const MCExpr *Expr =
nullptr;
6799 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *
this));
6803ParseStatus MipsAsmParser::parseInvNum(
OperandVector &Operands) {
6804 MCAsmParser &Parser = getParser();
6805 const MCExpr *IdVal;
6816 if (getParser().parseExpression(IdVal))
6823 Operands.
push_back(MipsOperand::CreateImm(
6828ParseStatus MipsAsmParser::parseRegisterList(
OperandVector &Operands) {
6829 MCAsmParser &Parser = getParser();
6833 bool RegRange =
false;
6840 while (parseAnyRegister(TmpOperands).isSuccess()) {
6841 SMLoc
E = getLexer().getLoc();
6842 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*TmpOperands.
back());
6843 Reg = isGP64bit() ? RegOpnd.getGPR64Reg() : RegOpnd.getGPR32Reg();
6847 if ((isGP64bit() &&
Reg == Mips::RA_64) ||
6848 (!isGP64bit() &&
Reg == Mips::RA)) {
6851 MCRegister TmpReg = PrevReg + 1;
6852 while (TmpReg <=
Reg) {
6853 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
6854 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
6856 return Error(
E,
"invalid register operand");
6860 TmpReg = TmpReg.
id() + 1;
6867 ((isGP64bit() && (
Reg != Mips::S0_64) && (
Reg != Mips::RA_64)) ||
6868 (!isGP64bit() && (
Reg != Mips::S0) && (
Reg != Mips::RA))))
6869 return Error(
E,
"$16 or $31 expected");
6870 if (!(((
Reg == Mips::FP ||
Reg == Mips::RA ||
6871 (
Reg >= Mips::S0 &&
Reg <= Mips::S7)) &&
6873 ((
Reg == Mips::FP_64 ||
Reg == Mips::RA_64 ||
6874 (
Reg >= Mips::S0_64 &&
Reg <= Mips::S7_64)) &&
6876 return Error(
E,
"invalid register operand");
6877 if (PrevReg.
isValid() && (
Reg != PrevReg + 1) &&
6878 ((
Reg != Mips::FP &&
Reg != Mips::RA && !isGP64bit()) ||
6879 (
Reg != Mips::FP_64 &&
Reg != Mips::RA_64 && isGP64bit())))
6880 return Error(
E,
"consecutive register numbers expected");
6890 return Error(
E,
"',' or '-' expected");
6900 Operands.
push_back(MipsOperand::CreateRegList(Regs, S,
E, *
this));
6901 parseMemOperand(Operands);
6910bool MipsAsmParser::parseParenSuffix(StringRef Name,
OperandVector &Operands) {
6911 MCAsmParser &Parser = getParser();
6914 MipsOperand::CreateToken(
"(", getLexer().getLoc(), *
this));
6916 if (parseOperand(Operands, Name)) {
6917 SMLoc Loc = getLexer().getLoc();
6918 return Error(Loc,
"unexpected token in argument list");
6921 SMLoc Loc = getLexer().getLoc();
6922 return Error(Loc,
"unexpected token, expected ')'");
6925 MipsOperand::CreateToken(
")", getLexer().getLoc(), *
this));
6937bool MipsAsmParser::parseBracketSuffix(StringRef Name,
6939 MCAsmParser &Parser = getParser();
6942 MipsOperand::CreateToken(
"[", getLexer().getLoc(), *
this));
6944 if (parseOperand(Operands, Name)) {
6945 SMLoc Loc = getLexer().getLoc();
6946 return Error(Loc,
"unexpected token in argument list");
6949 SMLoc Loc = getLexer().getLoc();
6950 return Error(Loc,
"unexpected token, expected ']'");
6953 MipsOperand::CreateToken(
"]", getLexer().getLoc(), *
this));
6960 unsigned VariantID = 0);
6975bool MipsAsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
6977 MCAsmParser &Parser = getParser();
6981 getTargetStreamer().forbidModuleDirective();
6984 if (!mnemonicIsValid(Name, 0)) {
6985 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
6987 return Error(NameLoc,
"unknown instruction" + Suggestion);
6990 Operands.
push_back(MipsOperand::CreateToken(Name, NameLoc, *
this));
6995 if (parseOperand(Operands, Name)) {
6996 SMLoc Loc = getLexer().getLoc();
6997 return Error(Loc,
"unexpected token in argument list");
6999 if (getLexer().is(
AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
7006 if (parseOperand(Operands, Name)) {
7007 SMLoc Loc = getLexer().getLoc();
7008 return Error(Loc,
"unexpected token in argument list");
7012 if (parseBracketSuffix(Name, Operands))
7015 parseParenSuffix(Name, Operands))
7020 SMLoc Loc = getLexer().getLoc();
7021 return Error(Loc,
"unexpected token in argument list");
7029bool MipsAsmParser::reportParseError(
const Twine &ErrorMsg) {
7030 SMLoc Loc = getLexer().getLoc();
7031 return Error(Loc, ErrorMsg);
7034bool MipsAsmParser::reportParseError(SMLoc Loc,
const Twine &ErrorMsg) {
7035 return Error(Loc, ErrorMsg);
7038bool MipsAsmParser::parseSetNoAtDirective() {
7039 MCAsmParser &Parser = getParser();
7043 AssemblerOptions.
back()->setATRegIndex(0);
7049 reportParseError(
"unexpected token, expected end of statement");
7053 getTargetStreamer().emitDirectiveSetNoAt();
7058bool MipsAsmParser::parseSetAtDirective() {
7061 MCAsmParser &Parser = getParser();
7066 AssemblerOptions.
back()->setATRegIndex(1);
7068 getTargetStreamer().emitDirectiveSetAt();
7074 reportParseError(
"unexpected token, expected equals sign");
7081 reportParseError(
"no register specified");
7084 reportParseError(
"unexpected token, expected dollar sign '$'");
7094 AtRegNo = matchCPURegisterName(
Reg.getIdentifier());
7096 AtRegNo =
Reg.getIntVal();
7098 reportParseError(
"unexpected token, expected identifier or integer");
7103 if (!AssemblerOptions.
back()->setATRegIndex(AtRegNo)) {
7104 reportParseError(
"invalid register");
7111 reportParseError(
"unexpected token, expected end of statement");
7115 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
7121bool MipsAsmParser::parseSetReorderDirective() {
7122 MCAsmParser &Parser = getParser();
7126 reportParseError(
"unexpected token, expected end of statement");
7129 AssemblerOptions.
back()->setReorder();
7130 getTargetStreamer().emitDirectiveSetReorder();
7135bool MipsAsmParser::parseSetNoReorderDirective() {
7136 MCAsmParser &Parser = getParser();
7140 reportParseError(
"unexpected token, expected end of statement");
7143 AssemblerOptions.
back()->setNoReorder();
7144 getTargetStreamer().emitDirectiveSetNoReorder();
7149bool MipsAsmParser::parseSetMacroDirective() {
7150 MCAsmParser &Parser = getParser();
7154 reportParseError(
"unexpected token, expected end of statement");
7157 AssemblerOptions.
back()->setMacro();
7158 getTargetStreamer().emitDirectiveSetMacro();
7163bool MipsAsmParser::parseSetNoMacroDirective() {
7164 MCAsmParser &Parser = getParser();
7168 reportParseError(
"unexpected token, expected end of statement");
7171 if (AssemblerOptions.
back()->isReorder()) {
7172 reportParseError(
"`noreorder' must be set before `nomacro'");
7175 AssemblerOptions.
back()->setNoMacro();
7176 getTargetStreamer().emitDirectiveSetNoMacro();
7181bool MipsAsmParser::parseSetMsaDirective() {
7182 MCAsmParser &Parser = getParser();
7187 return reportParseError(
"unexpected token, expected end of statement");
7189 setFeatureBits(Mips::FeatureMSA,
"msa");
7190 getTargetStreamer().emitDirectiveSetMsa();
7194bool MipsAsmParser::parseSetNoMsaDirective() {
7195 MCAsmParser &Parser = getParser();
7200 return reportParseError(
"unexpected token, expected end of statement");
7202 clearFeatureBits(Mips::FeatureMSA,
"msa");
7203 getTargetStreamer().emitDirectiveSetNoMsa();
7207bool MipsAsmParser::parseSetNoDspDirective() {
7208 MCAsmParser &Parser = getParser();
7213 reportParseError(
"unexpected token, expected end of statement");
7217 clearFeatureBits(Mips::FeatureDSP,
"dsp");
7218 getTargetStreamer().emitDirectiveSetNoDsp();
7222bool MipsAsmParser::parseSetNoMips3DDirective() {
7223 MCAsmParser &Parser = getParser();
7228 reportParseError(
"unexpected token, expected end of statement");
7232 clearFeatureBits(Mips::FeatureMips3D,
"mips3d");
7233 getTargetStreamer().emitDirectiveSetNoMips3D();
7237bool MipsAsmParser::parseSetMips16Directive() {
7238 MCAsmParser &Parser = getParser();
7243 reportParseError(
"unexpected token, expected end of statement");
7247 setFeatureBits(Mips::FeatureMips16,
"mips16");
7248 getTargetStreamer().emitDirectiveSetMips16();
7253bool MipsAsmParser::parseSetNoMips16Directive() {
7254 MCAsmParser &Parser = getParser();
7259 reportParseError(
"unexpected token, expected end of statement");
7263 clearFeatureBits(Mips::FeatureMips16,
"mips16");
7264 getTargetStreamer().emitDirectiveSetNoMips16();
7269bool MipsAsmParser::parseSetFpDirective() {
7270 MCAsmParser &Parser = getParser();
7276 AsmToken Tok = Parser.
getTok();
7278 reportParseError(
"unexpected token, expected equals sign '='");
7284 if (!parseFpABIValue(FpAbiVal,
".set"))
7288 reportParseError(
"unexpected token, expected end of statement");
7291 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
7296bool MipsAsmParser::parseSetOddSPRegDirective() {
7297 MCAsmParser &Parser = getParser();
7301 reportParseError(
"unexpected token, expected end of statement");
7305 clearFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
7306 getTargetStreamer().emitDirectiveSetOddSPReg();
7310bool MipsAsmParser::parseSetNoOddSPRegDirective() {
7311 MCAsmParser &Parser = getParser();
7315 reportParseError(
"unexpected token, expected end of statement");
7319 setFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
7320 getTargetStreamer().emitDirectiveSetNoOddSPReg();
7324bool MipsAsmParser::parseSetMtDirective() {
7325 MCAsmParser &Parser = getParser();
7330 reportParseError(
"unexpected token, expected end of statement");
7334 setFeatureBits(Mips::FeatureMT,
"mt");
7335 getTargetStreamer().emitDirectiveSetMt();
7340bool MipsAsmParser::parseSetNoMtDirective() {
7341 MCAsmParser &Parser = getParser();
7346 reportParseError(
"unexpected token, expected end of statement");
7350 clearFeatureBits(Mips::FeatureMT,
"mt");
7352 getTargetStreamer().emitDirectiveSetNoMt();
7357bool MipsAsmParser::parseSetNoCRCDirective() {
7358 MCAsmParser &Parser = getParser();
7363 reportParseError(
"unexpected token, expected end of statement");
7367 clearFeatureBits(Mips::FeatureCRC,
"crc");
7369 getTargetStreamer().emitDirectiveSetNoCRC();
7374bool MipsAsmParser::parseSetNoVirtDirective() {
7375 MCAsmParser &Parser = getParser();
7380 reportParseError(
"unexpected token, expected end of statement");
7384 clearFeatureBits(Mips::FeatureVirt,
"virt");
7386 getTargetStreamer().emitDirectiveSetNoVirt();
7391bool MipsAsmParser::parseSetNoGINVDirective() {
7392 MCAsmParser &Parser = getParser();
7397 reportParseError(
"unexpected token, expected end of statement");
7401 clearFeatureBits(Mips::FeatureGINV,
"ginv");
7403 getTargetStreamer().emitDirectiveSetNoGINV();
7408bool MipsAsmParser::parseSetPopDirective() {
7409 MCAsmParser &Parser = getParser();
7410 SMLoc Loc = getLexer().getLoc();
7414 return reportParseError(
"unexpected token, expected end of statement");
7418 if (AssemblerOptions.
size() == 2)
7419 return reportParseError(Loc,
".set pop with no .set push");
7421 MCSubtargetInfo &STI = copySTI();
7423 setAvailableFeatures(
7424 ComputeAvailableFeatures(AssemblerOptions.
back()->getFeatures()));
7427 getTargetStreamer().emitDirectiveSetPop();
7431bool MipsAsmParser::parseSetPushDirective() {
7432 MCAsmParser &Parser = getParser();
7435 return reportParseError(
"unexpected token, expected end of statement");
7439 std::make_unique<MipsAssemblerOptions>(AssemblerOptions.
back().get()));
7441 getTargetStreamer().emitDirectiveSetPush();
7445bool MipsAsmParser::parseSetSoftFloatDirective() {
7446 MCAsmParser &Parser = getParser();
7449 return reportParseError(
"unexpected token, expected end of statement");
7451 setFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
7452 getTargetStreamer().emitDirectiveSetSoftFloat();
7456bool MipsAsmParser::parseSetHardFloatDirective() {
7457 MCAsmParser &Parser = getParser();
7460 return reportParseError(
"unexpected token, expected end of statement");
7462 clearFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
7463 getTargetStreamer().emitDirectiveSetHardFloat();
7467bool MipsAsmParser::parseSetAssignment() {
7469 MCAsmParser &Parser = getParser();
7472 return reportParseError(
"expected identifier after .set");
7475 return reportParseError(
"unexpected token, expected comma");
7490 const MCExpr *
Value;
7492 Parser, Sym,
Value))
7494 getStreamer().emitAssignment(Sym,
Value);
7499bool MipsAsmParser::parseSetMips0Directive() {
7500 MCAsmParser &Parser = getParser();
7503 return reportParseError(
"unexpected token, expected end of statement");
7506 MCSubtargetInfo &STI = copySTI();
7507 setAvailableFeatures(
7508 ComputeAvailableFeatures(AssemblerOptions.
front()->getFeatures()));
7510 AssemblerOptions.
back()->setFeatures(AssemblerOptions.
front()->getFeatures());
7512 getTargetStreamer().emitDirectiveSetMips0();
7516bool MipsAsmParser::parseSetArchDirective() {
7517 MCAsmParser &Parser = getParser();
7520 return reportParseError(
"unexpected token, expected equals sign");
7523 StringRef Arch = getParser().parseStringToEndOfStatement().trim();
7525 return reportParseError(
"expected arch identifier");
7527 StringRef ArchFeatureName =
7528 StringSwitch<StringRef>(Arch)
7529 .Case(
"mips1",
"mips1")
7530 .Case(
"mips2",
"mips2")
7531 .Case(
"mips3",
"mips3")
7532 .Case(
"mips4",
"mips4")
7533 .Case(
"mips5",
"mips5")
7534 .Case(
"mips32",
"mips32")
7535 .Case(
"mips32r2",
"mips32r2")
7536 .Case(
"mips32r3",
"mips32r3")
7537 .Case(
"mips32r5",
"mips32r5")
7538 .Case(
"mips32r6",
"mips32r6")
7539 .Case(
"mips64",
"mips64")
7540 .Case(
"mips64r2",
"mips64r2")
7541 .Case(
"mips64r3",
"mips64r3")
7542 .Case(
"mips64r5",
"mips64r5")
7543 .Case(
"mips64r6",
"mips64r6")
7544 .Case(
"octeon",
"cnmips")
7545 .Case(
"octeon+",
"cnmipsp")
7546 .Case(
"r4000",
"mips3")
7549 if (ArchFeatureName.
empty())
7550 return reportParseError(
"unsupported architecture");
7552 if (ArchFeatureName ==
"mips64r6" && inMicroMipsMode())
7553 return reportParseError(
"mips64r6 does not support microMIPS");
7555 selectArch(ArchFeatureName);
7556 getTargetStreamer().emitDirectiveSetArch(Arch);
7560bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
7561 MCAsmParser &Parser = getParser();
7564 return reportParseError(
"unexpected token, expected end of statement");
7569 case Mips::FeatureMips3D:
7570 setFeatureBits(Mips::FeatureMips3D,
"mips3d");
7571 getTargetStreamer().emitDirectiveSetMips3D();
7573 case Mips::FeatureDSP:
7574 setFeatureBits(Mips::FeatureDSP,
"dsp");
7575 getTargetStreamer().emitDirectiveSetDsp();
7577 case Mips::FeatureDSPR2:
7578 setFeatureBits(Mips::FeatureDSPR2,
"dspr2");
7579 getTargetStreamer().emitDirectiveSetDspr2();
7581 case Mips::FeatureMicroMips:
7582 setFeatureBits(Mips::FeatureMicroMips,
"micromips");
7583 getTargetStreamer().emitDirectiveSetMicroMips();
7585 case Mips::FeatureMips1:
7586 selectArch(
"mips1");
7587 getTargetStreamer().emitDirectiveSetMips1();
7589 case Mips::FeatureMips2:
7590 selectArch(
"mips2");
7591 getTargetStreamer().emitDirectiveSetMips2();
7593 case Mips::FeatureMips3:
7594 selectArch(
"mips3");
7595 getTargetStreamer().emitDirectiveSetMips3();
7597 case Mips::FeatureMips4:
7598 selectArch(
"mips4");
7599 getTargetStreamer().emitDirectiveSetMips4();
7601 case Mips::FeatureMips5:
7602 selectArch(
"mips5");
7603 getTargetStreamer().emitDirectiveSetMips5();
7605 case Mips::FeatureMips32:
7606 selectArch(
"mips32");
7607 getTargetStreamer().emitDirectiveSetMips32();
7609 case Mips::FeatureMips32r2:
7610 selectArch(
"mips32r2");
7611 getTargetStreamer().emitDirectiveSetMips32R2();
7613 case Mips::FeatureMips32r3:
7614 selectArch(
"mips32r3");
7615 getTargetStreamer().emitDirectiveSetMips32R3();
7617 case Mips::FeatureMips32r5:
7618 selectArch(
"mips32r5");
7619 getTargetStreamer().emitDirectiveSetMips32R5();
7621 case Mips::FeatureMips32r6:
7622 selectArch(
"mips32r6");
7623 getTargetStreamer().emitDirectiveSetMips32R6();
7625 case Mips::FeatureMips64:
7626 selectArch(
"mips64");
7627 getTargetStreamer().emitDirectiveSetMips64();
7629 case Mips::FeatureMips64r2:
7630 selectArch(
"mips64r2");
7631 getTargetStreamer().emitDirectiveSetMips64R2();
7633 case Mips::FeatureMips64r3:
7634 selectArch(
"mips64r3");
7635 getTargetStreamer().emitDirectiveSetMips64R3();
7637 case Mips::FeatureMips64r5:
7638 selectArch(
"mips64r5");
7639 getTargetStreamer().emitDirectiveSetMips64R5();
7641 case Mips::FeatureMips64r6:
7642 selectArch(
"mips64r6");
7643 getTargetStreamer().emitDirectiveSetMips64R6();
7645 case Mips::FeatureCRC:
7646 setFeatureBits(Mips::FeatureCRC,
"crc");
7647 getTargetStreamer().emitDirectiveSetCRC();
7649 case Mips::FeatureVirt:
7650 setFeatureBits(Mips::FeatureVirt,
"virt");
7651 getTargetStreamer().emitDirectiveSetVirt();
7653 case Mips::FeatureGINV:
7654 setFeatureBits(Mips::FeatureGINV,
"ginv");
7655 getTargetStreamer().emitDirectiveSetGINV();
7661bool MipsAsmParser::eatComma(StringRef ErrorStr) {
7662 MCAsmParser &Parser = getParser();
7664 SMLoc Loc = getLexer().getLoc();
7665 return Error(Loc, ErrorStr);
7676bool MipsAsmParser::isPicAndNotNxxAbi() {
7677 return inPicMode() && !(isABI_N32() || isABI_N64());
7680bool MipsAsmParser::parseDirectiveCpAdd(SMLoc Loc) {
7682 ParseStatus Res = parseAnyRegister(
Reg);
7684 reportParseError(
"expected register");
7688 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7689 if (!RegOpnd.isGPRAsmReg()) {
7690 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7696 reportParseError(
"unexpected token, expected end of statement");
7701 getTargetStreamer().emitDirectiveCpAdd(RegOpnd.getGPR32Reg());
7705bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
7706 if (AssemblerOptions.
back()->isReorder())
7707 Warning(Loc,
".cpload should be inside a noreorder section");
7709 if (inMips16Mode()) {
7710 reportParseError(
".cpload is not supported in Mips16 mode");
7715 ParseStatus Res = parseAnyRegister(
Reg);
7717 reportParseError(
"expected register containing function address");
7721 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7722 if (!RegOpnd.isGPRAsmReg()) {
7723 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7729 reportParseError(
"unexpected token, expected end of statement");
7733 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
7737bool MipsAsmParser::parseDirectiveCpLocal(SMLoc Loc) {
7738 if (!isABI_N32() && !isABI_N64()) {
7739 reportParseError(
".cplocal is allowed only in N32 or N64 mode");
7744 ParseStatus Res = parseAnyRegister(
Reg);
7746 reportParseError(
"expected register containing global pointer");
7750 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7751 if (!RegOpnd.isGPRAsmReg()) {
7752 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7758 reportParseError(
"unexpected token, expected end of statement");
7763 MCRegister NewReg = RegOpnd.getGPR32Reg();
7767 getTargetStreamer().emitDirectiveCpLocal(NewReg);
7771bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
7772 MCAsmParser &Parser = getParser();
7777 if (inMips16Mode()) {
7778 reportParseError(
".cprestore is not supported in Mips16 mode");
7783 const MCExpr *StackOffset;
7784 int64_t StackOffsetVal;
7786 reportParseError(
"expected stack offset value");
7790 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
7791 reportParseError(
"stack offset is not an absolute expression");
7795 if (StackOffsetVal < 0) {
7796 Warning(Loc,
".cprestore with negative stack offset has no effect");
7797 IsCpRestoreSet =
false;
7799 IsCpRestoreSet =
true;
7800 CpRestoreOffset = StackOffsetVal;
7805 reportParseError(
"unexpected token, expected end of statement");
7809 if (!getTargetStreamer().emitDirectiveCpRestore(
7810 CpRestoreOffset, [&]() {
return getATReg(Loc); }, Loc, STI))
7816bool MipsAsmParser::parseDirectiveCPSetup() {
7817 MCAsmParser &Parser = getParser();
7819 bool SaveIsReg =
true;
7822 ParseStatus Res = parseAnyRegister(TmpReg);
7824 reportParseError(
"expected register containing function address");
7828 MipsOperand &FuncRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7829 if (!FuncRegOpnd.isGPRAsmReg()) {
7830 reportParseError(FuncRegOpnd.getStartLoc(),
"invalid register");
7834 MCRegister FuncReg = FuncRegOpnd.getGPR32Reg();
7837 if (!eatComma(
"unexpected token, expected comma"))
7840 Res = parseAnyRegister(TmpReg);
7842 const MCExpr *OffsetExpr;
7844 SMLoc ExprLoc = getLexer().
getLoc();
7847 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
7848 reportParseError(ExprLoc,
"expected save register or stack offset");
7855 MipsOperand &SaveOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7856 if (!SaveOpnd.isGPRAsmReg()) {
7857 reportParseError(SaveOpnd.getStartLoc(),
"invalid register");
7860 Save = SaveOpnd.getGPR32Reg().id();
7863 if (!eatComma(
"unexpected token, expected comma"))
7868 reportParseError(
"expected expression");
7873 reportParseError(
"expected symbol");
7876 const MCSymbolRefExpr *
Ref =
static_cast<const MCSymbolRefExpr *
>(Expr);
7878 CpSaveLocation = Save;
7879 CpSaveLocationIsRegister = SaveIsReg;
7881 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save,
Ref->getSymbol(),
7886bool MipsAsmParser::parseDirectiveCPReturn() {
7887 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
7888 CpSaveLocationIsRegister);
7892bool MipsAsmParser::parseDirectiveNaN() {
7893 MCAsmParser &Parser = getParser();
7895 const AsmToken &Tok = Parser.
getTok();
7899 getTargetStreamer().emitDirectiveNaN2008();
7901 }
else if (Tok.
getString() ==
"legacy") {
7903 getTargetStreamer().emitDirectiveNaNLegacy();
7909 reportParseError(
"invalid option in .nan directive");
7913bool MipsAsmParser::parseDirectiveSet() {
7914 const AsmToken &Tok = getParser().getTok();
7916 SMLoc Loc = Tok.
getLoc();
7918 if (IdVal ==
"noat")
7919 return parseSetNoAtDirective();
7921 return parseSetAtDirective();
7922 if (IdVal ==
"arch")
7923 return parseSetArchDirective();
7924 if (IdVal ==
"bopt") {
7925 Warning(Loc,
"'bopt' feature is unsupported");
7929 if (IdVal ==
"nobopt") {
7935 return parseSetFpDirective();
7936 if (IdVal ==
"oddspreg")
7937 return parseSetOddSPRegDirective();
7938 if (IdVal ==
"nooddspreg")
7939 return parseSetNoOddSPRegDirective();
7941 return parseSetPopDirective();
7942 if (IdVal ==
"push")
7943 return parseSetPushDirective();
7944 if (IdVal ==
"reorder")
7945 return parseSetReorderDirective();
7946 if (IdVal ==
"noreorder")
7947 return parseSetNoReorderDirective();
7948 if (IdVal ==
"macro")
7949 return parseSetMacroDirective();
7950 if (IdVal ==
"nomacro")
7951 return parseSetNoMacroDirective();
7952 if (IdVal ==
"mips16")
7953 return parseSetMips16Directive();
7954 if (IdVal ==
"nomips16")
7955 return parseSetNoMips16Directive();
7956 if (IdVal ==
"nomicromips") {
7957 clearFeatureBits(Mips::FeatureMicroMips,
"micromips");
7958 getTargetStreamer().emitDirectiveSetNoMicroMips();
7959 getParser().eatToEndOfStatement();
7962 if (IdVal ==
"micromips") {
7963 if (hasMips64r6()) {
7964 Error(Loc,
".set micromips directive is not supported with MIPS64R6");
7967 return parseSetFeature(Mips::FeatureMicroMips);
7969 if (IdVal ==
"mips0")
7970 return parseSetMips0Directive();
7971 if (IdVal ==
"mips1")
7972 return parseSetFeature(Mips::FeatureMips1);
7973 if (IdVal ==
"mips2")
7974 return parseSetFeature(Mips::FeatureMips2);
7975 if (IdVal ==
"mips3")
7976 return parseSetFeature(Mips::FeatureMips3);
7977 if (IdVal ==
"mips4")
7978 return parseSetFeature(Mips::FeatureMips4);
7979 if (IdVal ==
"mips5")
7980 return parseSetFeature(Mips::FeatureMips5);
7981 if (IdVal ==
"mips32")
7982 return parseSetFeature(Mips::FeatureMips32);
7983 if (IdVal ==
"mips32r2")
7984 return parseSetFeature(Mips::FeatureMips32r2);
7985 if (IdVal ==
"mips32r3")
7986 return parseSetFeature(Mips::FeatureMips32r3);
7987 if (IdVal ==
"mips32r5")
7988 return parseSetFeature(Mips::FeatureMips32r5);
7989 if (IdVal ==
"mips32r6")
7990 return parseSetFeature(Mips::FeatureMips32r6);
7991 if (IdVal ==
"mips64")
7992 return parseSetFeature(Mips::FeatureMips64);
7993 if (IdVal ==
"mips64r2")
7994 return parseSetFeature(Mips::FeatureMips64r2);
7995 if (IdVal ==
"mips64r3")
7996 return parseSetFeature(Mips::FeatureMips64r3);
7997 if (IdVal ==
"mips64r5")
7998 return parseSetFeature(Mips::FeatureMips64r5);
7999 if (IdVal ==
"mips64r6") {
8000 if (inMicroMipsMode()) {
8001 Error(Loc,
"MIPS64R6 is not supported with microMIPS");
8004 return parseSetFeature(Mips::FeatureMips64r6);
8007 return parseSetFeature(Mips::FeatureDSP);
8008 if (IdVal ==
"dspr2")
8009 return parseSetFeature(Mips::FeatureDSPR2);
8010 if (IdVal ==
"nodsp")
8011 return parseSetNoDspDirective();
8012 if (IdVal ==
"mips3d")
8013 return parseSetFeature(Mips::FeatureMips3D);
8014 if (IdVal ==
"nomips3d")
8015 return parseSetNoMips3DDirective();
8017 return parseSetMsaDirective();
8018 if (IdVal ==
"nomsa")
8019 return parseSetNoMsaDirective();
8021 return parseSetMtDirective();
8022 if (IdVal ==
"nomt")
8023 return parseSetNoMtDirective();
8024 if (IdVal ==
"softfloat")
8025 return parseSetSoftFloatDirective();
8026 if (IdVal ==
"hardfloat")
8027 return parseSetHardFloatDirective();
8029 return parseSetFeature(Mips::FeatureCRC);
8030 if (IdVal ==
"nocrc")
8031 return parseSetNoCRCDirective();
8032 if (IdVal ==
"virt")
8033 return parseSetFeature(Mips::FeatureVirt);
8034 if (IdVal ==
"novirt")
8035 return parseSetNoVirtDirective();
8036 if (IdVal ==
"ginv")
8037 return parseSetFeature(Mips::FeatureGINV);
8038 if (IdVal ==
"noginv")
8039 return parseSetNoGINVDirective();
8042 return parseSetAssignment();
8047bool MipsAsmParser::parseDirectiveGpWord() {
8048 const MCExpr *
Value;
8049 if (getParser().parseExpression(
Value))
8051 getTargetStreamer().emitGPRel32Value(
Value);
8057bool MipsAsmParser::parseDirectiveGpDWord() {
8058 const MCExpr *
Value;
8059 if (getParser().parseExpression(
Value))
8061 getTargetStreamer().emitGPRel64Value(
Value);
8067bool MipsAsmParser::parseDirectiveDtpRelWord() {
8068 const MCExpr *
Value;
8069 if (getParser().parseExpression(
Value))
8071 getTargetStreamer().emitDTPRel32Value(
Value);
8077bool MipsAsmParser::parseDirectiveDtpRelDWord() {
8078 const MCExpr *
Value;
8079 if (getParser().parseExpression(
Value))
8081 getTargetStreamer().emitDTPRel64Value(
Value);
8087bool MipsAsmParser::parseDirectiveTpRelWord() {
8088 const MCExpr *
Value;
8089 if (getParser().parseExpression(
Value))
8091 getTargetStreamer().emitTPRel32Value(
Value);
8097bool MipsAsmParser::parseDirectiveTpRelDWord() {
8098 const MCExpr *
Value;
8099 if (getParser().parseExpression(
Value))
8101 getTargetStreamer().emitTPRel64Value(
Value);
8105bool MipsAsmParser::parseDirectiveOption() {
8106 MCAsmParser &Parser = getParser();
8108 AsmToken Tok = Parser.
getTok();
8112 "unexpected token, expected identifier");
8117 if (Option ==
"pic0") {
8119 IsPicEnabled =
false;
8121 getTargetStreamer().emitDirectiveOptionPic0();
8125 "unexpected token, expected end of statement");
8130 if (Option ==
"pic2") {
8132 IsPicEnabled =
true;
8134 getTargetStreamer().emitDirectiveOptionPic2();
8138 "unexpected token, expected end of statement");
8145 "unknown option, expected 'pic0' or 'pic2'");
8152bool MipsAsmParser::parseInsnDirective() {
8155 reportParseError(
"unexpected token, expected end of statement");
8161 getTargetStreamer().emitDirectiveInsn();
8169bool MipsAsmParser::parseRSectionDirective(StringRef Section) {
8172 reportParseError(
"unexpected token, expected end of statement");
8176 MCSection *ELFSection =
getContext().getELFSection(
8178 getParser().getStreamer().switchSection(ELFSection);
8187bool MipsAsmParser::parseSSectionDirective(StringRef Section,
unsigned Type) {
8190 reportParseError(
"unexpected token, expected end of statement");
8194 MCSection *ELFSection =
getContext().getELFSection(
8196 getParser().getStreamer().switchSection(ELFSection);
8215bool MipsAsmParser::parseDirectiveModule() {
8216 MCAsmParser &Parser = getParser();
8217 AsmLexer &Lexer = getLexer();
8220 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
8222 reportParseError(
".module directive must appear before any code");
8228 reportParseError(
"expected .module option identifier");
8232 if (Option ==
"oddspreg") {
8233 clearModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
8237 getTargetStreamer().updateABIInfo(*
this);
8242 getTargetStreamer().emitDirectiveModuleOddSPReg();
8246 reportParseError(
"unexpected token, expected end of statement");
8251 }
else if (Option ==
"nooddspreg") {
8253 return Error(L,
"'.module nooddspreg' requires the O32 ABI");
8256 setModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
8260 getTargetStreamer().updateABIInfo(*
this);
8265 getTargetStreamer().emitDirectiveModuleOddSPReg();
8269 reportParseError(
"unexpected token, expected end of statement");
8274 }
else if (Option ==
"fp") {
8275 return parseDirectiveModuleFP();
8276 }
else if (Option ==
"softfloat") {
8277 setModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
8281 getTargetStreamer().updateABIInfo(*
this);
8286 getTargetStreamer().emitDirectiveModuleSoftFloat();
8290 reportParseError(
"unexpected token, expected end of statement");
8295 }
else if (Option ==
"hardfloat") {
8296 clearModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
8300 getTargetStreamer().updateABIInfo(*
this);
8305 getTargetStreamer().emitDirectiveModuleHardFloat();
8309 reportParseError(
"unexpected token, expected end of statement");
8314 }
else if (Option ==
"mt") {
8315 setModuleFeatureBits(Mips::FeatureMT,
"mt");
8319 getTargetStreamer().updateABIInfo(*
this);
8324 getTargetStreamer().emitDirectiveModuleMT();
8328 reportParseError(
"unexpected token, expected end of statement");
8333 }
else if (Option ==
"crc") {
8334 setModuleFeatureBits(Mips::FeatureCRC,
"crc");
8338 getTargetStreamer().updateABIInfo(*
this);
8343 getTargetStreamer().emitDirectiveModuleCRC();
8347 reportParseError(
"unexpected token, expected end of statement");
8352 }
else if (Option ==
"nocrc") {
8353 clearModuleFeatureBits(Mips::FeatureCRC,
"crc");
8357 getTargetStreamer().updateABIInfo(*
this);
8362 getTargetStreamer().emitDirectiveModuleNoCRC();
8366 reportParseError(
"unexpected token, expected end of statement");
8371 }
else if (Option ==
"virt") {
8372 setModuleFeatureBits(Mips::FeatureVirt,
"virt");
8376 getTargetStreamer().updateABIInfo(*
this);
8381 getTargetStreamer().emitDirectiveModuleVirt();
8385 reportParseError(
"unexpected token, expected end of statement");
8390 }
else if (Option ==
"novirt") {
8391 clearModuleFeatureBits(Mips::FeatureVirt,
"virt");
8395 getTargetStreamer().updateABIInfo(*
this);
8400 getTargetStreamer().emitDirectiveModuleNoVirt();
8404 reportParseError(
"unexpected token, expected end of statement");
8409 }
else if (Option ==
"ginv") {
8410 setModuleFeatureBits(Mips::FeatureGINV,
"ginv");
8414 getTargetStreamer().updateABIInfo(*
this);
8419 getTargetStreamer().emitDirectiveModuleGINV();
8423 reportParseError(
"unexpected token, expected end of statement");
8428 }
else if (Option ==
"noginv") {
8429 clearModuleFeatureBits(Mips::FeatureGINV,
"ginv");
8433 getTargetStreamer().updateABIInfo(*
this);
8438 getTargetStreamer().emitDirectiveModuleNoGINV();
8442 reportParseError(
"unexpected token, expected end of statement");
8448 return Error(L,
"'" + Twine(Option) +
"' is not a valid .module option.");
8456bool MipsAsmParser::parseDirectiveModuleFP() {
8457 MCAsmParser &Parser = getParser();
8458 AsmLexer &Lexer = getLexer();
8461 reportParseError(
"unexpected token, expected equals sign '='");
8467 if (!parseFpABIValue(FpABI,
".module"))
8471 reportParseError(
"unexpected token, expected end of statement");
8477 getTargetStreamer().updateABIInfo(*
this);
8482 getTargetStreamer().emitDirectiveModuleFP();
8489 StringRef Directive) {
8490 MCAsmParser &Parser = getParser();
8491 AsmLexer &Lexer = getLexer();
8492 bool ModuleLevelOptions = Directive ==
".module";
8498 if (
Value !=
"xx") {
8499 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
8504 reportParseError(
"'" + Directive +
" fp=xx' requires the O32 ABI");
8508 FpABI = MipsABIFlagsSection::FpABIKind::XX;
8509 if (ModuleLevelOptions) {
8510 setModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8511 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8513 setFeatureBits(Mips::FeatureFPXX,
"fpxx");
8514 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8524 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
8530 reportParseError(
"'" + Directive +
" fp=32' requires the O32 ABI");
8534 FpABI = MipsABIFlagsSection::FpABIKind::S32;
8535 if (ModuleLevelOptions) {
8536 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8537 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8539 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
8540 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8543 FpABI = MipsABIFlagsSection::FpABIKind::S64;
8544 if (ModuleLevelOptions) {
8545 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8546 setModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8548 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
8549 setFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8559bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
8565 MCAsmParser &Parser = getParser();
8566 StringRef IDVal = DirectiveID.
getString();
8568 if (IDVal ==
".cpadd") {
8569 parseDirectiveCpAdd(DirectiveID.
getLoc());
8572 if (IDVal ==
".cpload") {
8573 parseDirectiveCpLoad(DirectiveID.
getLoc());
8576 if (IDVal ==
".cprestore") {
8577 parseDirectiveCpRestore(DirectiveID.
getLoc());
8580 if (IDVal ==
".cplocal") {
8581 parseDirectiveCpLocal(DirectiveID.
getLoc());
8584 if (IDVal ==
".ent") {
8588 reportParseError(
"expected identifier after .ent");
8602 reportParseError(
"unexpected token, expected end of statement");
8606 const MCExpr *DummyNumber;
8607 int64_t DummyNumberVal;
8611 reportParseError(
"expected number after comma");
8614 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
8615 reportParseError(
"expected an absolute expression after comma");
8622 reportParseError(
"unexpected token, expected end of statement");
8628 getTargetStreamer().emitDirectiveEnt(*Sym);
8630 IsCpRestoreSet =
false;
8634 if (IDVal ==
".end") {
8638 reportParseError(
"expected identifier after .end");
8643 reportParseError(
"unexpected token, expected end of statement");
8647 if (CurrentFn ==
nullptr) {
8648 reportParseError(
".end used without .ent");
8652 if ((SymbolName != CurrentFn->
getName())) {
8653 reportParseError(
".end symbol does not match .ent symbol");
8657 getTargetStreamer().emitDirectiveEnd(SymbolName);
8658 CurrentFn =
nullptr;
8659 IsCpRestoreSet =
false;
8663 if (IDVal ==
".frame") {
8666 ParseStatus Res = parseAnyRegister(TmpReg);
8668 reportParseError(
"expected stack register");
8672 MipsOperand &StackRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
8673 if (!StackRegOpnd.isGPRAsmReg()) {
8674 reportParseError(StackRegOpnd.getStartLoc(),
8675 "expected general purpose register");
8678 MCRegister StackReg = StackRegOpnd.getGPR32Reg();
8683 reportParseError(
"unexpected token, expected comma");
8688 const MCExpr *FrameSize;
8689 int64_t FrameSizeVal;
8692 reportParseError(
"expected frame size value");
8696 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
8697 reportParseError(
"frame size not an absolute expression");
8704 reportParseError(
"unexpected token, expected comma");
8710 Res = parseAnyRegister(TmpReg);
8712 reportParseError(
"expected return register");
8716 MipsOperand &ReturnRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
8717 if (!ReturnRegOpnd.isGPRAsmReg()) {
8718 reportParseError(ReturnRegOpnd.getStartLoc(),
8719 "expected general purpose register");
8725 reportParseError(
"unexpected token, expected end of statement");
8729 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
8730 ReturnRegOpnd.getGPR32Reg());
8731 IsCpRestoreSet =
false;
8735 if (IDVal ==
".set") {
8736 parseDirectiveSet();
8740 if (IDVal ==
".mask" || IDVal ==
".fmask") {
8751 const MCExpr *BitMask;
8755 reportParseError(
"expected bitmask value");
8759 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
8760 reportParseError(
"bitmask not an absolute expression");
8767 reportParseError(
"unexpected token, expected comma");
8772 const MCExpr *FrameOffset;
8773 int64_t FrameOffsetVal;
8776 reportParseError(
"expected frame offset value");
8780 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
8781 reportParseError(
"frame offset not an absolute expression");
8787 reportParseError(
"unexpected token, expected end of statement");
8791 if (IDVal ==
".mask")
8792 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
8794 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
8798 if (IDVal ==
".nan")
8799 return parseDirectiveNaN();
8801 if (IDVal ==
".gpword") {
8802 parseDirectiveGpWord();
8806 if (IDVal ==
".gpdword") {
8807 parseDirectiveGpDWord();
8811 if (IDVal ==
".dtprelword") {
8812 parseDirectiveDtpRelWord();
8816 if (IDVal ==
".dtpreldword") {
8817 parseDirectiveDtpRelDWord();
8821 if (IDVal ==
".tprelword") {
8822 parseDirectiveTpRelWord();
8826 if (IDVal ==
".tpreldword") {
8827 parseDirectiveTpRelDWord();
8831 if (IDVal ==
".option") {
8832 parseDirectiveOption();
8836 if (IDVal ==
".abicalls") {
8837 getTargetStreamer().emitDirectiveAbiCalls();
8840 "unexpected token, expected end of statement");
8845 if (IDVal ==
".cpsetup") {
8846 parseDirectiveCPSetup();
8849 if (IDVal ==
".cpreturn") {
8850 parseDirectiveCPReturn();
8853 if (IDVal ==
".module") {
8854 parseDirectiveModule();
8857 if (IDVal ==
".llvm_internal_mips_reallow_module_directive") {
8858 parseInternalDirectiveReallowModule();
8861 if (IDVal ==
".insn") {
8862 parseInsnDirective();
8865 if (IDVal ==
".rdata") {
8866 parseRSectionDirective(
".rodata");
8869 if (IDVal ==
".sbss") {
8873 if (IDVal ==
".sdata") {
8881bool MipsAsmParser::parseInternalDirectiveReallowModule() {
8884 reportParseError(
"unexpected token, expected end of statement");
8888 getTargetStreamer().reallowModuleDirective();
8902#define GET_REGISTER_MATCHER
8903#define GET_MATCHER_IMPLEMENTATION
8904#define GET_MNEMONIC_SPELL_CHECKER
8905#include "MipsGenAsmMatcher.inc"
8907bool MipsAsmParser::mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID) {
8909 const MatchEntry *Start, *End;
8910 switch (VariantID) {
8912 case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0);
break;
8915 auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
8916 return MnemonicRange.first != MnemonicRange.second;
static const TargetRegisterClass * getRegClass(const MachineInstr &MI, Register Reg)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
This file declares a class to represent arbitrary precision floating point values and provide a varie...
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
static Value * expandAbs(CallInst *Orig)
std::pair< Instruction::BinaryOps, Value * > OffsetOp
Find all possible pairs (BinOp, RHS) that BinOp V, RHS can be simplified.
static constexpr Value * getValue(Ty &ValueOrUse)
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static FeatureBitset getFeatures(MCSubtargetInfo &STI, StringRef CPU, StringRef TuneCPU, StringRef FS, StringTable ProcNames, ArrayRef< SubtargetSubTypeKV > ProcDesc, ArrayRef< SubtargetFeatureKV > ProcFeatures)
static bool hasFeature(StringRef Feature, const FeatureBitset &FeatureBits, 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)
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static const fltSemantics & IEEEdouble()
APInt bitcastToAPInt() const
uint64_t getZExtValue() const
Get zero extended value.
SMLoc getLoc() const
Get the current source location.
const AsmToken peekTok(bool ShouldSkipSpace=true)
Look ahead at the next token to be lexed.
bool is(AsmToken::TokenKind K) const
Check if the current token has kind K.
bool isNot(AsmToken::TokenKind K) const
Check if the current token has kind K.
Target independent representation for an assembler token.
LLVM_ABI SMLoc getLoc() const
int64_t getIntVal() const
bool isNot(TokenKind K) const
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
bool is(TokenKind K) const
TokenKind getKind() const
LLVM_ABI SMRange getLocRange() const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
Base class for user error types.
Container class for subtarget features.
void printExpr(raw_ostream &, const MCExpr &) const
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
bool parseToken(AsmToken::TokenKind T, const Twine &Msg="unexpected token")
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
Binary assembler expressions.
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
static LLVM_ABI const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
@ LShr
Logical shift right.
@ Xor
Bitwise exclusive or.
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Base class for the full range of assembler expressions which are needed for parsing.
LLVM_ABI bool evaluateAsRelocatable(MCValue &Res, const MCAssembler *Asm) const
Try to evaluate the expression to a relocatable value, i.e.
@ Unary
Unary expressions.
@ Constant
Constant expressions.
@ SymbolRef
References to labels and assigned expressions.
@ Target
Target specific expression.
@ Specifier
Expression with a relocation specifier.
@ Binary
Binary expressions.
Instances of this class represent a single low-level machine instruction.
unsigned getNumOperands() const
unsigned getOpcode() const
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
const MCOperand & getOperand(unsigned i) const
Describe properties that are true of each instruction in the target description file.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
ArrayRef< MCOperandInfo > operands() const
bool mayStore() const
Return true if this instruction could possibly modify memory.
bool mayLoad() const
Return true if this instruction could possibly read memory.
bool isBranch() const
Returns true if this is a conditional, unconditional, or indirect branch.
bool isCall() const
Return true if the instruction is a call.
bool hasDelaySlot() const
Returns true if the specified instruction has a delay slot which must be filled by the code generator...
Interface to description of machine instruction set.
This holds information about one operand of a machine instruction, indicating the register class for ...
uint8_t OperandType
Information about the type of the operand.
Instances of this class represent operands of the MCInst class.
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
MCRegister getReg() const
Returns the register number.
const MCExpr * getExpr() const
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual bool isReg() const =0
isReg - Is this a register operand?
virtual MCRegister getReg() const =0
Wrapper class representing physical registers. Should be passed by value.
constexpr bool isValid() const
constexpr unsigned id() const
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
Streaming machine code generation interface.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
virtual void emitRelocDirective(const MCExpr &Offset, StringRef Name, const MCExpr *Expr, SMLoc Loc={})
Record a relocation described by the .reloc directive.
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
void setFeatureBits(const FeatureBitset &FeatureBits_)
const Triple & getTargetTriple() const
const FeatureBitset & getFeatureBits() const
const FeatureBitset & ToggleFeature(uint64_t FB)
Toggle a feature and return the re-computed feature bits.
virtual unsigned getHwMode(enum HwModeType type=HwMode_Default) const
HwMode ID corresponding to the 'type' parameter is retrieved from the HwMode bit set of the current s...
Represent a reference to a symbol from inside an expression.
uint16_t getSpecifier() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
bool isInSection() const
isInSection - Check if this symbol is defined in some section (i.e., it is defined but not absolute).
bool isUndefined() const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).
StringRef getName() const
getName - Get the symbol name.
bool isVariable() const
isVariable - Check if this is a variable symbol.
const MCExpr * getVariableValue() const
Get the expression of the variable symbol.
bool isTemporary() const
isTemporary - Check if this is an assembler temporary symbol.
MCTargetAsmParser - Generic interface to target specific assembly parsers.
MCStreamer & getStreamer()
Unary assembler expressions.
const MCSymbol * getAddSym() const
int64_t getConstant() const
const MCSymbol * getSubSym() const
void emitRRX(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, MCOperand Op2, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveSetReorder()
void emitRRRX(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, MCRegister Reg2, MCOperand Op3, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRX(unsigned Opcode, MCRegister Reg0, MCOperand Op1, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitR(unsigned Opcode, MCRegister Reg0, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void setUsesMicroMips()
void emitRRI(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, int16_t Imm, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitEmptyDelaySlot(bool hasShortDelaySlot, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRI(unsigned Opcode, MCRegister Reg0, int32_t Imm, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRR(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, SMLoc IDLoc, const MCSubtargetInfo *STI)
void updateABIInfo(const PredicateLibrary &P)
void emitRRIII(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, int16_t Imm0, int16_t Imm1, int16_t Imm2, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitDSLL(MCRegister DstReg, MCRegister SrcReg, int16_t ShiftAmount, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitGPRestore(int Offset, SMLoc IDLoc, const MCSubtargetInfo *STI)
Emit the $gp restore operation for .cprestore.
void emitNop(SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRRR(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, MCRegister Reg2, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveSetNoReorder()
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
static constexpr StatusTy Failure
constexpr bool isSuccess() const
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
constexpr bool isNoMatch() const
constexpr unsigned id() const
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
void push_back(const T &Elt)
iterator find(StringRef Key)
Represent a constant reference to a string, i.e.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
Check if the string is empty.
LLVM_ABI bool isLittleEndian() const
Tests whether the target triple is little endian.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
LLVM_ABI bool parseAssignmentExpression(StringRef Name, bool allow_redef, MCAsmParser &Parser, MCSymbol *&Symbol, const MCExpr *&Value)
Parse a value expression and return whether it can be assigned to a symbol with the given name.
@ CE
Windows NT (Windows on ARM)
LLVM_ABI StringRef getABIName()
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
unsigned getOpcode(const VPValue *V)
Return the instruction opcode for the recipe defining V or 0 for unsupported recipes and VPValues not...
This is an optimization pass for GlobalISel generic memory operations.
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.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
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,...