64#define DEBUG_TYPE "mips-asm-parser"
74class MipsAssemblerOptions {
76 MipsAssemblerOptions(
const FeatureBitset &Features_) : Features(Features_) {}
78 MipsAssemblerOptions(
const MipsAssemblerOptions *Opts) {
79 ATReg = Opts->getATRegIndex();
80 Reorder = Opts->isReorder();
81 Macro = Opts->isMacro();
82 Features = Opts->getFeatures();
85 unsigned getATRegIndex()
const {
return ATReg; }
86 bool setATRegIndex(
unsigned Reg) {
94 bool isReorder()
const {
return Reorder; }
95 void setReorder() { Reorder =
true; }
96 void setNoReorder() { Reorder =
false; }
98 bool isMacro()
const {
return Macro; }
99 void setMacro() {
Macro =
true; }
100 void setNoMacro() {
Macro =
false; }
102 const FeatureBitset &
getFeatures()
const {
return Features; }
103 void setFeatures(
const FeatureBitset &Features_) { Features = Features_; }
110 static const FeatureBitset AllArchRelatedMask;
116 FeatureBitset Features;
121const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
122 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
123 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
124 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
125 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
126 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
127 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
128 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
129 Mips::FeatureCnMipsP, Mips::FeatureFP64Bit, Mips::FeatureGP64Bit,
136 MipsTargetStreamer &getTargetStreamer() {
137 assert(getParser().getStreamer().getTargetStreamer() &&
138 "do not have a target streamer");
139 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
140 return static_cast<MipsTargetStreamer &
>(TS);
143 const MipsMCOptions &CLOpts;
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);
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;
200 const MCExpr *parseMemOffset();
210 const MCExpr *parseRelocExpr();
211 bool parsePrimaryExpr(
const MCExpr *&Res,
SMLoc &EndLoc)
override;
217 enum MacroExpanderResultTy {
224 MacroExpanderResultTy tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
226 const MCSubtargetInfo *STI);
228 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
229 const MCSubtargetInfo *STI);
231 bool loadImmediate(int64_t ImmValue, MCRegister DstReg, MCRegister SrcReg,
232 bool Is32BitImm,
bool IsAddress, SMLoc IDLoc,
233 MCStreamer &Out,
const MCSubtargetInfo *STI);
235 bool loadAndAddSymbolAddress(
const MCExpr *SymExpr, MCRegister DstReg,
236 MCRegister SrcReg,
bool Is32BitSym, SMLoc IDLoc,
237 MCStreamer &Out,
const MCSubtargetInfo *STI);
239 bool emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc, MCSymbol *Sym);
241 bool expandLoadImm(MCInst &Inst,
bool Is32BitImm, SMLoc IDLoc,
242 MCStreamer &Out,
const MCSubtargetInfo *STI);
244 bool expandLoadSingleImmToGPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
245 const MCSubtargetInfo *STI);
246 bool expandLoadSingleImmToFPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
247 const MCSubtargetInfo *STI);
248 bool expandLoadDoubleImmToGPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
249 const MCSubtargetInfo *STI);
250 bool expandLoadDoubleImmToFPR(MCInst &Inst,
bool Is64FPU, SMLoc IDLoc,
251 MCStreamer &Out,
const MCSubtargetInfo *STI);
253 bool expandLoadAddress(MCRegister DstReg, MCRegister BaseReg,
254 const MCOperand &
Offset,
bool Is32BitAddress,
255 SMLoc IDLoc, MCStreamer &Out,
256 const MCSubtargetInfo *STI);
258 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
259 const MCSubtargetInfo *STI);
261 void expandMem16Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
262 const MCSubtargetInfo *STI,
bool IsLoad);
263 void expandMem9Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
264 const MCSubtargetInfo *STI,
bool IsLoad);
266 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
267 const MCSubtargetInfo *STI);
269 bool expandAliasImmediate(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
270 const MCSubtargetInfo *STI);
272 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
273 const MCSubtargetInfo *STI);
275 bool expandCondBranches(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
276 const MCSubtargetInfo *STI);
278 bool expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
279 const MCSubtargetInfo *STI,
const bool IsMips64,
282 bool expandTrunc(MCInst &Inst,
bool IsDouble,
bool Is64FPU, SMLoc IDLoc,
283 MCStreamer &Out,
const MCSubtargetInfo *STI);
285 bool expandUlh(MCInst &Inst,
bool Signed, SMLoc IDLoc, MCStreamer &Out,
286 const MCSubtargetInfo *STI);
288 bool expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
289 const MCSubtargetInfo *STI);
291 bool expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
292 const MCSubtargetInfo *STI);
294 bool expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
295 const MCSubtargetInfo *STI);
297 bool expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
298 const MCSubtargetInfo *STI);
300 bool expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
301 const MCSubtargetInfo *STI);
303 bool expandSle(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
304 const MCSubtargetInfo *STI);
306 bool expandSleImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
307 const MCSubtargetInfo *STI);
309 bool expandRotation(MCInst &Inst, SMLoc IDLoc,
310 MCStreamer &Out,
const MCSubtargetInfo *STI);
311 bool expandRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
312 const MCSubtargetInfo *STI);
313 bool expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
314 const MCSubtargetInfo *STI);
315 bool expandDRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
316 const MCSubtargetInfo *STI);
318 bool expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
319 const MCSubtargetInfo *STI);
321 bool expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
322 const MCSubtargetInfo *STI);
324 bool expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
325 const MCSubtargetInfo *STI);
327 bool expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
328 const MCSubtargetInfo *STI);
330 bool expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
331 const MCSubtargetInfo *STI);
333 bool expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
334 const MCSubtargetInfo *STI,
bool IsLoad);
336 bool expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
337 const MCSubtargetInfo *STI);
339 bool expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
340 const MCSubtargetInfo *STI);
342 bool expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
343 const MCSubtargetInfo *STI);
345 bool expandSne(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
346 const MCSubtargetInfo *STI);
348 bool expandSneI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
349 const MCSubtargetInfo *STI);
351 bool expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
352 const MCSubtargetInfo *STI);
354 bool expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
355 const MCSubtargetInfo *STI);
357 bool reportParseError(
const Twine &ErrorMsg);
358 bool reportParseError(SMLoc Loc,
const Twine &ErrorMsg);
360 bool parseSetMips0Directive();
361 bool parseSetArchDirective();
362 bool parseSetFeature(
uint64_t Feature);
363 bool isPicAndNotNxxAbi();
364 bool parseDirectiveCpAdd(SMLoc Loc);
365 bool parseDirectiveCpLoad(SMLoc Loc);
366 bool parseDirectiveCpLocal(SMLoc Loc);
367 bool parseDirectiveCpRestore(SMLoc Loc);
368 bool parseDirectiveCPSetup();
369 bool parseDirectiveCPReturn();
370 bool parseDirectiveNaN();
371 bool parseDirectiveSet();
372 bool parseDirectiveOption();
373 bool parseInsnDirective();
374 bool parseRSectionDirective(StringRef Section);
375 bool parseSSectionDirective(StringRef Section,
unsigned Type);
377 bool parseSetAtDirective();
378 bool parseSetNoAtDirective();
379 bool parseSetMacroDirective();
380 bool parseSetNoMacroDirective();
381 bool parseSetMsaDirective();
382 bool parseSetNoMsaDirective();
383 bool parseSetNoDspDirective();
384 bool parseSetNoMips3DDirective();
385 bool parseSetReorderDirective();
386 bool parseSetNoReorderDirective();
387 bool parseSetMips16Directive();
388 bool parseSetNoMips16Directive();
389 bool parseSetFpDirective();
390 bool parseSetOddSPRegDirective();
391 bool parseSetNoOddSPRegDirective();
392 bool parseSetPopDirective();
393 bool parseSetPushDirective();
394 bool parseSetSoftFloatDirective();
395 bool parseSetHardFloatDirective();
396 bool parseSetMtDirective();
397 bool parseSetNoMtDirective();
398 bool parseSetNoCRCDirective();
399 bool parseSetNoVirtDirective();
400 bool parseSetNoGINVDirective();
401 bool parseSetNoEVADirective();
403 bool parseSetAssignment();
405 bool parseDirectiveGpWord();
406 bool parseDirectiveGpDWord();
407 bool parseDirectiveDtpRelWord();
408 bool parseDirectiveDtpRelDWord();
409 bool parseDirectiveTpRelWord();
410 bool parseDirectiveTpRelDWord();
411 bool parseDirectiveModule();
412 bool parseDirectiveModuleFP();
414 StringRef Directive);
416 bool parseInternalDirectiveReallowModule();
418 bool eatComma(StringRef ErrorStr);
420 int matchCPURegisterName(StringRef Symbol);
422 int matchHWRegsRegisterName(StringRef Symbol);
424 int matchFPURegisterName(StringRef Name);
426 int matchFCCRegisterName(StringRef Name);
428 int matchACRegisterName(StringRef Name);
430 int matchMSA128RegisterName(StringRef Name);
432 int matchMSA128CtrlRegisterName(StringRef Name);
434 MCRegister
getReg(
int RC,
int RegNo);
439 MCRegister getATReg(SMLoc Loc);
443 bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
444 const MCSubtargetInfo *STI);
468 void selectArch(StringRef ArchFeature) {
469 MCSubtargetInfo &STI = copySTI();
471 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
473 setAvailableFeatures(
478 void setFeatureBits(
uint64_t Feature, StringRef FeatureString) {
480 MCSubtargetInfo &STI = copySTI();
481 setAvailableFeatures(
487 void clearFeatureBits(
uint64_t Feature, StringRef FeatureString) {
489 MCSubtargetInfo &STI = copySTI();
490 setAvailableFeatures(
496 void setModuleFeatureBits(
uint64_t Feature, StringRef FeatureString) {
497 setFeatureBits(Feature, FeatureString);
498 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
501 void clearModuleFeatureBits(
uint64_t Feature, StringRef FeatureString) {
502 clearFeatureBits(Feature, FeatureString);
503 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
507 enum MipsMatchResultTy {
508 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
509 Match_RequiresDifferentOperands,
510 Match_RequiresNoZeroRegister,
511 Match_RequiresSameSrcAndDst,
512 Match_NoFCCRegisterForCurrentISA,
513 Match_NonZeroOperandForSync,
514 Match_NonZeroOperandForMTCX,
515 Match_RequiresPosSizeRange0_32,
516 Match_RequiresPosSizeRange33_64,
517 Match_RequiresPosSizeUImm6,
518#define GET_OPERAND_DIAGNOSTIC_TYPES
519#include "MipsGenAsmMatcher.inc"
520#undef GET_OPERAND_DIAGNOSTIC_TYPES
523 MipsAsmParser(
const MCSubtargetInfo &sti, MCAsmParser &parser,
524 const MCInstrInfo &MII)
525 : MCTargetAsmParser(sti, MII),
528 sti.getTargetTriple(),
538 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
541 AssemblerOptions.push_back(
542 std::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
545 AssemblerOptions.push_back(
546 std::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
548 getTargetStreamer().updateABIInfo(*
this);
550 if (!isABI_O32() && !useOddSPReg() != 0)
555 CurForbiddenSlotAttr =
false;
556 IsPicEnabled =
getContext().getObjectFileInfo()->isPositionIndependent();
558 IsCpRestoreSet =
false;
559 CpRestoreOffset = -1;
560 GPReg = ABI.GetGlobalPtr();
565 if (getSTI().
getCPU() ==
"mips64r6" && inMicroMipsMode())
568 if (!isABI_O32() && inMicroMipsMode())
573 bool hasEightFccRegisters()
const {
return hasMips4() || hasMips32(); }
575 bool isGP64bit()
const {
576 return getSTI().hasFeature(Mips::FeatureGP64Bit);
579 bool isFP64bit()
const {
580 return getSTI().hasFeature(Mips::FeatureFP64Bit);
583 bool isJalrRelocAvailable(
const MCExpr *JalExpr) {
584 if (!CLOpts.jalr_reloc)
592 return ABI.IsN32() || ABI.IsN64();
596 const MipsABIInfo &
getABI()
const {
return ABI; }
597 bool isABI_N32()
const {
return ABI.IsN32(); }
598 bool isABI_N64()
const {
return ABI.IsN64(); }
599 bool isABI_O32()
const {
return ABI.IsO32(); }
600 bool isABI_FPXX()
const {
601 return getSTI().hasFeature(Mips::FeatureFPXX);
604 bool useOddSPReg()
const {
605 return !(getSTI().hasFeature(Mips::FeatureNoOddSPReg));
608 bool inMicroMipsMode()
const {
609 return getSTI().hasFeature(Mips::FeatureMicroMips);
612 bool hasMips1()
const {
613 return getSTI().hasFeature(Mips::FeatureMips1);
616 bool hasMips2()
const {
617 return getSTI().hasFeature(Mips::FeatureMips2);
620 bool hasMips3()
const {
621 return getSTI().hasFeature(Mips::FeatureMips3);
624 bool hasMips4()
const {
625 return getSTI().hasFeature(Mips::FeatureMips4);
628 bool hasMips5()
const {
629 return getSTI().hasFeature(Mips::FeatureMips5);
632 bool hasMips32()
const {
633 return getSTI().hasFeature(Mips::FeatureMips32);
636 bool hasMips64()
const {
637 return getSTI().hasFeature(Mips::FeatureMips64);
640 bool hasMips32r2()
const {
641 return getSTI().hasFeature(Mips::FeatureMips32r2);
644 bool hasMips64r2()
const {
645 return getSTI().hasFeature(Mips::FeatureMips64r2);
648 bool hasMips32r3()
const {
649 return (getSTI().
hasFeature(Mips::FeatureMips32r3));
652 bool hasMips64r3()
const {
653 return (getSTI().
hasFeature(Mips::FeatureMips64r3));
656 bool hasMips32r5()
const {
657 return (getSTI().
hasFeature(Mips::FeatureMips32r5));
660 bool hasMips64r5()
const {
661 return (getSTI().
hasFeature(Mips::FeatureMips64r5));
664 bool hasMips32r6()
const {
665 return getSTI().hasFeature(Mips::FeatureMips32r6);
668 bool hasMips64r6()
const {
669 return getSTI().hasFeature(Mips::FeatureMips64r6);
672 bool hasDSP()
const {
673 return getSTI().hasFeature(Mips::FeatureDSP);
676 bool hasDSPR2()
const {
677 return getSTI().hasFeature(Mips::FeatureDSPR2);
680 bool hasDSPR3()
const {
681 return getSTI().hasFeature(Mips::FeatureDSPR3);
684 bool hasMSA()
const {
685 return getSTI().hasFeature(Mips::FeatureMSA);
688 bool hasCnMips()
const {
689 return (getSTI().
hasFeature(Mips::FeatureCnMips));
692 bool hasCnMipsP()
const {
693 return (getSTI().
hasFeature(Mips::FeatureCnMipsP));
696 bool isR5900()
const {
return (getSTI().
hasFeature(Mips::FeatureR5900)); }
702 bool inMips16Mode()
const {
703 return getSTI().hasFeature(Mips::FeatureMips16);
706 bool useTraps()
const {
707 return getSTI().hasFeature(Mips::FeatureUseTCCInDIV);
710 bool useSoftFloat()
const {
711 return getSTI().hasFeature(Mips::FeatureSoftFloat);
714 bool isSingleFloat()
const {
715 return getSTI().hasFeature(Mips::FeatureSingleFloat);
719 return getSTI().hasFeature(Mips::FeatureMT);
722 bool hasCRC()
const {
723 return getSTI().hasFeature(Mips::FeatureCRC);
726 bool hasVirt()
const {
727 return getSTI().hasFeature(Mips::FeatureVirt);
730 bool hasGINV()
const {
731 return getSTI().hasFeature(Mips::FeatureGINV);
734 bool hasForbiddenSlot(
const MCInstrDesc &MCID)
const {
738 bool SafeInForbiddenSlot(
const MCInstrDesc &MCID)
const {
742 void onEndOfFile()
override;
745 void warnIfRegIndexIsAT(MCRegister RegIndex, SMLoc Loc);
747 void warnIfNoMacro(SMLoc Loc);
749 bool isLittle()
const {
return IsLittleEndian; }
751 bool areEqualRegs(
const MCParsedAsmOperand &Op1,
752 const MCParsedAsmOperand &Op2)
const override;
767 RegKind_MSACtrl = 16,
772 RegKind_HWRegs = 256,
776 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
777 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
778 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
791 MipsOperand(KindTy K, MipsAsmParser &Parser) : Kind(
K), AsmParser(Parser) {}
793 ~MipsOperand()
override {
802 case k_RegisterIndex:
810 MipsAsmParser &AsmParser;
821 const MCRegisterInfo *RegInfo;
839 struct RegIdxOp RegIdx;
842 struct RegListOp RegList;
845 SMLoc StartLoc, EndLoc;
848 static std::unique_ptr<MipsOperand> CreateReg(
unsigned Index, StringRef Str,
850 const MCRegisterInfo *RegInfo,
852 MipsAsmParser &Parser) {
853 auto Op = std::make_unique<MipsOperand>(k_RegisterIndex, Parser);
855 Op->RegIdx.RegInfo = RegInfo;
856 Op->RegIdx.Kind = RegKind;
857 Op->RegIdx.Tok.Data = Str.data();
858 Op->RegIdx.Tok.Length = Str.size();
867 MCRegister getGPR32Reg()
const {
868 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
869 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
870 unsigned ClassID = Mips::GPR32RegClassID;
871 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
876 MCRegister getGPRMM16Reg()
const {
877 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
878 unsigned ClassID = Mips::GPR32RegClassID;
879 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
884 MCRegister getGPR64Reg()
const {
885 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
886 unsigned ClassID = Mips::GPR64RegClassID;
887 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
893 MCRegister getAFGR64Reg()
const {
894 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
895 if (RegIdx.Index % 2 != 0)
896 AsmParser.Warning(StartLoc,
"Float register should be even.");
897 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
898 .getRegister(RegIdx.Index / 2);
903 MCRegister getFGR64Reg()
const {
904 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
905 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
906 .getRegister(RegIdx.Index);
911 MCRegister getFGR32Reg()
const {
912 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
913 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
914 .getRegister(RegIdx.Index);
919 MCRegister getFCCReg()
const {
920 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) &&
"Invalid access!");
921 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
922 .getRegister(RegIdx.Index);
927 MCRegister getMSA128Reg()
const {
928 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) &&
"Invalid access!");
931 unsigned ClassID = Mips::MSA128BRegClassID;
932 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
937 MCRegister getMSACtrlReg()
const {
938 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) &&
"Invalid access!");
939 unsigned ClassID = Mips::MSACtrlRegClassID;
940 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
945 MCRegister getCOP0Reg()
const {
946 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) &&
"Invalid access!");
947 unsigned ClassID = Mips::COP0RegClassID;
948 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
953 MCRegister getCOP2Reg()
const {
954 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) &&
"Invalid access!");
955 unsigned ClassID = Mips::COP2RegClassID;
956 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
961 MCRegister getCOP3Reg()
const {
962 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) &&
"Invalid access!");
963 unsigned ClassID = Mips::COP3RegClassID;
964 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
969 MCRegister getACC64DSPReg()
const {
970 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
971 unsigned ClassID = Mips::ACC64DSPRegClassID;
972 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
977 MCRegister getHI32DSPReg()
const {
978 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
979 unsigned ClassID = Mips::HI32DSPRegClassID;
980 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
985 MCRegister getLO32DSPReg()
const {
986 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
987 unsigned ClassID = Mips::LO32DSPRegClassID;
988 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
993 MCRegister getCCRReg()
const {
994 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) &&
"Invalid access!");
995 unsigned ClassID = Mips::CCRRegClassID;
996 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1001 MCRegister getHWRegsReg()
const {
1002 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) &&
"Invalid access!");
1003 unsigned ClassID = Mips::HWRegsRegClassID;
1004 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1008 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const {
1018 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1025 void addGPR32ZeroAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1026 assert(
N == 1 &&
"Invalid number of operands!");
1030 void addGPR32NonZeroAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1031 assert(
N == 1 &&
"Invalid number of operands!");
1035 void addGPR32AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1036 assert(
N == 1 &&
"Invalid number of operands!");
1040 void addGPRMM16AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1041 assert(
N == 1 &&
"Invalid number of operands!");
1045 void addGPRMM16AsmRegZeroOperands(MCInst &Inst,
unsigned N)
const {
1046 assert(
N == 1 &&
"Invalid number of operands!");
1050 void addGPRMM16AsmRegMovePOperands(MCInst &Inst,
unsigned N)
const {
1051 assert(
N == 1 &&
"Invalid number of operands!");
1055 void addGPRMM16AsmRegMovePPairFirstOperands(MCInst &Inst,
unsigned N)
const {
1056 assert(
N == 1 &&
"Invalid number of operands!");
1060 void addGPRMM16AsmRegMovePPairSecondOperands(MCInst &Inst,
1062 assert(
N == 1 &&
"Invalid number of operands!");
1069 void addGPR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1070 assert(
N == 1 &&
"Invalid number of operands!");
1074 void addAFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1075 assert(
N == 1 &&
"Invalid number of operands!");
1079 void addStrictlyAFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1080 assert(
N == 1 &&
"Invalid number of operands!");
1084 void addStrictlyFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1085 assert(
N == 1 &&
"Invalid number of operands!");
1089 void addFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1090 assert(
N == 1 &&
"Invalid number of operands!");
1094 void addFGR32AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1095 assert(
N == 1 &&
"Invalid number of operands!");
1099 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1100 AsmParser.getParser().printError(
1101 StartLoc,
"-mno-odd-spreg prohibits the use of odd FPU "
1105 void addStrictlyFGR32AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1106 assert(
N == 1 &&
"Invalid number of operands!");
1109 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1110 AsmParser.Error(StartLoc,
"-mno-odd-spreg prohibits the use of odd FPU "
1114 void addFCCAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1115 assert(
N == 1 &&
"Invalid number of operands!");
1119 void addMSA128AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1120 assert(
N == 1 &&
"Invalid number of operands!");
1124 void addMSACtrlAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1125 assert(
N == 1 &&
"Invalid number of operands!");
1129 void addCOP0AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1130 assert(
N == 1 &&
"Invalid number of operands!");
1134 void addCOP2AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1135 assert(
N == 1 &&
"Invalid number of operands!");
1139 void addCOP3AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1140 assert(
N == 1 &&
"Invalid number of operands!");
1144 void addACC64DSPAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1145 assert(
N == 1 &&
"Invalid number of operands!");
1149 void addHI32DSPAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1150 assert(
N == 1 &&
"Invalid number of operands!");
1154 void addLO32DSPAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1155 assert(
N == 1 &&
"Invalid number of operands!");
1159 void addCCRAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1160 assert(
N == 1 &&
"Invalid number of operands!");
1164 void addHWRegsAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1165 assert(
N == 1 &&
"Invalid number of operands!");
1169 template <
unsigned Bits,
int Offset = 0,
int AdjustOffset = 0>
1170 void addConstantUImmOperands(MCInst &Inst,
unsigned N)
const {
1171 assert(
N == 1 &&
"Invalid number of operands!");
1175 Imm += AdjustOffset;
1179 template <
unsigned Bits>
1180 void addSImmOperands(MCInst &Inst,
unsigned N)
const {
1181 if (isImm() && !isConstantImm()) {
1185 addConstantSImmOperands<Bits, 0, 0>(Inst,
N);
1188 template <
unsigned Bits>
1189 void addUImmOperands(MCInst &Inst,
unsigned N)
const {
1190 if (isImm() && !isConstantImm()) {
1194 addConstantUImmOperands<Bits, 0, 0>(Inst,
N);
1197 template <
unsigned Bits,
int Offset = 0,
int AdjustOffset = 0>
1198 void addConstantSImmOperands(MCInst &Inst,
unsigned N)
const {
1199 assert(
N == 1 &&
"Invalid number of operands!");
1200 int64_t
Imm = getConstantImm() -
Offset;
1203 Imm += AdjustOffset;
1207 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1208 assert(
N == 1 &&
"Invalid number of operands!");
1209 const MCExpr *Expr =
getImm();
1210 addExpr(Inst, Expr);
1213 void addPtrRegOperands(MCInst &Inst,
unsigned N)
const {
1214 assert(
N == 1 &&
"Invalid number of operands!");
1216 AsmParser.getABI().ArePtrs64bit() ? getGPR64Reg() : getGPR32Reg()));
1219 void addMemOperands(MCInst &Inst,
unsigned N)
const {
1220 assert(
N == 2 &&
"Invalid number of operands!");
1221 getMemBase()->addPtrRegOperands(Inst, 1);
1222 addExpr(Inst, getMemOff());
1225 bool isSPAsmReg()
const {
return isGPRAsmReg() && RegIdx.Index == 29; }
1226 bool isGPAsmReg()
const {
return isGPRAsmReg() && RegIdx.Index == 28; }
1228 bool isSImmPtr()
const {
1229 return AsmParser.getABI().ArePtrs64bit() ? isScaledSImm<64, 0>()
1230 : isScaledSImm<32, 0>();
1233 void addRegListOperands(MCInst &Inst,
unsigned N)
const {
1234 assert(
N == 1 &&
"Invalid number of operands!");
1236 for (
auto RegNo : getRegList())
1240 bool isReg()
const override {
1243 return isGPRAsmReg() && RegIdx.Index == 0;
1246 bool isRegIdx()
const {
return Kind == k_RegisterIndex; }
1247 bool isImm()
const override {
return Kind == k_Immediate; }
1249 bool isConstantImm()
const {
1251 return isImm() &&
getImm()->evaluateAsAbsolute(Res);
1254 bool isConstantImmz()
const {
1255 return isConstantImm() && getConstantImm() == 0;
1258 template <
unsigned Bits,
int Offset = 0>
bool isConstantUImm()
const {
1262 template <
unsigned Bits>
bool isSImm()
const {
1266 if (
getImm()->evaluateAsAbsolute(Res))
1272 template <
unsigned Bits>
bool isUImm()
const {
1276 if (
getImm()->evaluateAsAbsolute(Res))
1282 template <
unsigned Bits>
bool isAnyImm()
const {
1283 return isConstantImm() ? (
isInt<Bits>(getConstantImm()) ||
1288 template <
unsigned Bits,
int Offset = 0>
bool isConstantSImm()
const {
1292 template <
unsigned Bottom,
unsigned Top>
bool isConstantUImmRange()
const {
1293 return isConstantImm() && getConstantImm() >= Bottom &&
1294 getConstantImm() <= Top;
1297 bool isToken()
const override {
1300 return Kind == k_Token;
1303 bool isMem()
const override {
return Kind == k_Memory; }
1308 template <
unsigned Bits,
unsigned ShiftLeftAmount,
int Bias = 0>
1309 bool isScaledUImm()
const {
1311 uint64_t(getConstantImm()) - Bias);
1314 template <
unsigned Bits,
unsigned ShiftLeftAmount>
1315 bool isScaledSImm()
const {
1316 if (isConstantImm() &&
1321 if (Kind != k_Immediate)
1326 bool Success =
getImm()->evaluateAsRelocatable(Res,
nullptr);
1330 bool isRegList16()
const {
1334 int Size = RegList.List->size();
1338 MCRegister R0 = RegList.List->front();
1339 MCRegister R1 = RegList.List->back();
1340 if (!((R0 == Mips::R16 && R1 ==
Mips::RA) ||
1344 MCRegister PrevReg = RegList.List->front();
1345 for (
int i = 1; i <
Size - 1; i++) {
1346 MCRegister
Reg = (*(RegList.List))[i];
1347 if (
Reg != PrevReg + 1)
1355 bool isInvNum()
const {
return Kind == k_Immediate; }
1357 bool isLSAImm()
const {
1358 if (!isConstantImm())
1360 int64_t Val = getConstantImm();
1361 return 1 <= Val && Val <= 4;
1364 bool isRegList()
const {
return Kind == k_RegList; }
1367 assert(Kind == k_Token &&
"Invalid access!");
1368 return StringRef(Tok.Data, Tok.Length);
1371 MCRegister
getReg()
const override {
1374 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1375 RegIdx.Kind & RegKind_GPR)
1376 return getGPR32Reg();
1382 const MCExpr *
getImm()
const {
1383 assert((Kind == k_Immediate) &&
"Invalid access!");
1387 int64_t getConstantImm()
const {
1388 const MCExpr *Val =
getImm();
1390 (void)Val->evaluateAsAbsolute(
Value);
1394 MipsOperand *getMemBase()
const {
1395 assert((Kind == k_Memory) &&
"Invalid access!");
1399 const MCExpr *getMemOff()
const {
1400 assert((Kind == k_Memory) &&
"Invalid access!");
1404 const SmallVectorImpl<MCRegister> &getRegList()
const {
1405 assert((Kind == k_RegList) &&
"Invalid access!");
1406 return *(RegList.List);
1409 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1410 MipsAsmParser &Parser) {
1411 auto Op = std::make_unique<MipsOperand>(k_Token, Parser);
1412 Op->Tok.Data = Str.data();
1413 Op->Tok.Length = Str.size();
1421 static std::unique_ptr<MipsOperand>
1422 createNumericReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1423 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1424 LLVM_DEBUG(
dbgs() <<
"createNumericReg(" << Index <<
", ...)\n");
1425 return CreateReg(Index, Str, RegKind_Numeric, RegInfo, S,
E, Parser);
1430 static std::unique_ptr<MipsOperand>
1431 createGPRReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1432 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1433 return CreateReg(Index, Str, RegKind_GPR, RegInfo, S,
E, Parser);
1438 static std::unique_ptr<MipsOperand>
1439 createFGRReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1440 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1441 return CreateReg(Index, Str, RegKind_FGR, RegInfo, S,
E, Parser);
1446 static std::unique_ptr<MipsOperand>
1447 createHWRegsReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1448 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1449 return CreateReg(Index, Str, RegKind_HWRegs, RegInfo, S,
E, Parser);
1454 static std::unique_ptr<MipsOperand>
1455 createFCCReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1456 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1457 return CreateReg(Index, Str, RegKind_FCC, RegInfo, S,
E, Parser);
1462 static std::unique_ptr<MipsOperand>
1463 createACCReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1464 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1465 return CreateReg(Index, Str, RegKind_ACC, RegInfo, S,
E, Parser);
1470 static std::unique_ptr<MipsOperand>
1471 createMSA128Reg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1472 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1473 return CreateReg(Index, Str, RegKind_MSA128, RegInfo, S,
E, Parser);
1478 static std::unique_ptr<MipsOperand>
1479 createMSACtrlReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1480 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1481 return CreateReg(Index, Str, RegKind_MSACtrl, RegInfo, S,
E, Parser);
1484 static std::unique_ptr<MipsOperand>
1485 CreateImm(
const MCExpr *Val, SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1486 auto Op = std::make_unique<MipsOperand>(k_Immediate, Parser);
1493 static std::unique_ptr<MipsOperand>
1494 CreateMem(std::unique_ptr<MipsOperand>
Base,
const MCExpr *
Off, SMLoc S,
1495 SMLoc
E, MipsAsmParser &Parser) {
1496 auto Op = std::make_unique<MipsOperand>(k_Memory, Parser);
1497 Op->Mem.Base =
Base.release();
1504 static std::unique_ptr<MipsOperand>
1505 CreateRegList(SmallVectorImpl<MCRegister> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1506 MipsAsmParser &Parser) {
1507 assert(!Regs.
empty() &&
"Empty list not allowed");
1509 auto Op = std::make_unique<MipsOperand>(k_RegList, Parser);
1512 Op->StartLoc = StartLoc;
1513 Op->EndLoc = EndLoc;
1517 bool isGPRZeroAsmReg()
const {
1518 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
1521 bool isGPRNonZeroAsmReg()
const {
1522 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index > 0 &&
1526 bool isGPRAsmReg()
const {
1527 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1530 bool isMM16AsmReg()
const {
1533 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1534 || RegIdx.Index == 16 || RegIdx.Index == 17);
1537 bool isMM16AsmRegZero()
const {
1540 return (RegIdx.Index == 0 ||
1541 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1542 RegIdx.Index == 17);
1545 bool isMM16AsmRegMoveP()
const {
1546 if (!(isRegIdx() && RegIdx.Kind))
1548 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1549 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1552 bool isMM16AsmRegMovePPairFirst()
const {
1553 if (!(isRegIdx() && RegIdx.Kind))
1555 return RegIdx.Index >= 4 && RegIdx.Index <= 6;
1558 bool isMM16AsmRegMovePPairSecond()
const {
1559 if (!(isRegIdx() && RegIdx.Kind))
1561 return (RegIdx.Index == 21 || RegIdx.Index == 22 ||
1562 (RegIdx.Index >= 5 && RegIdx.Index <= 7));
1565 bool isFGRAsmReg()
const {
1567 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1570 bool isStrictlyFGRAsmReg()
const {
1572 return isRegIdx() && RegIdx.Kind == RegKind_FGR && RegIdx.Index <= 31;
1575 bool isHWRegsAsmReg()
const {
1576 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1579 bool isCCRAsmReg()
const {
1580 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1583 bool isFCCAsmReg()
const {
1584 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1586 return RegIdx.Index <= 7;
1589 bool isACCAsmReg()
const {
1590 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1593 bool isCOP0AsmReg()
const {
1594 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1597 bool isCOP2AsmReg()
const {
1598 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1601 bool isCOP3AsmReg()
const {
1602 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1605 bool isMSA128AsmReg()
const {
1606 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1609 bool isMSACtrlAsmReg()
const {
1610 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1614 SMLoc getStartLoc()
const override {
return StartLoc; }
1616 SMLoc getEndLoc()
const override {
return EndLoc; }
1618 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1627 Mem.Base->print(OS, MAI);
1632 case k_RegisterIndex:
1633 OS <<
"RegIdx<" << RegIdx.Index <<
":" << RegIdx.Kind <<
", "
1634 << StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) <<
">";
1641 for (
auto Reg : (*RegList.List))
1642 OS <<
Reg.
id() <<
" ";
1648 bool isValidForTie(
const MipsOperand &
Other)
const {
1649 if (Kind !=
Other.Kind)
1656 case k_RegisterIndex: {
1657 StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length);
1658 StringRef OtherToken(
Other.RegIdx.Tok.Data,
Other.RegIdx.Tok.Length);
1659 return Token == OtherToken;
1675 case Mips::JRC16_MM:
1677 case Mips::JALRS_MM:
1678 case Mips::JALRS16_MM:
1679 case Mips::BGEZALS_MM:
1680 case Mips::BLTZALS_MM:
1691 return &SRExpr->getSymbol();
1750 unsigned NumOp =
MCID.getNumOperands();
1751 if (NumOp != 3 && NumOp != 4)
1781bool MipsAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
1784 MipsTargetStreamer &TOut = getTargetStreamer();
1785 const unsigned Opcode = Inst.
getOpcode();
1786 const MCInstrDesc &MCID = MII.get(Opcode);
1787 bool ExpandedJalSym =
false;
1801 assert(hasCnMips() &&
"instruction only valid for octeon cpus");
1812 if (!
isIntN(inMicroMipsMode() ? 17 : 18,
Offset.getImm()))
1813 return Error(IDLoc,
"branch target out of range");
1816 return Error(IDLoc,
"branch to misaligned address");
1830 case Mips::BGEZAL_MM:
1831 case Mips::BLTZAL_MM:
1834 case Mips::BC1EQZC_MMR6:
1835 case Mips::BC1NEZC_MMR6:
1836 case Mips::BC2EQZC_MMR6:
1837 case Mips::BC2NEZC_MMR6:
1842 if (!
isIntN(inMicroMipsMode() ? 17 : 18,
Offset.getImm()))
1843 return Error(IDLoc,
"branch target out of range");
1846 return Error(IDLoc,
"branch to misaligned address");
1848 case Mips::BGEC:
case Mips::BGEC_MMR6:
1849 case Mips::BLTC:
case Mips::BLTC_MMR6:
1850 case Mips::BGEUC:
case Mips::BGEUC_MMR6:
1851 case Mips::BLTUC:
case Mips::BLTUC_MMR6:
1852 case Mips::BEQC:
case Mips::BEQC_MMR6:
1853 case Mips::BNEC:
case Mips::BNEC_MMR6:
1859 return Error(IDLoc,
"branch target out of range");
1861 return Error(IDLoc,
"branch to misaligned address");
1863 case Mips::BLEZC:
case Mips::BLEZC_MMR6:
1864 case Mips::BGEZC:
case Mips::BGEZC_MMR6:
1865 case Mips::BGTZC:
case Mips::BGTZC_MMR6:
1866 case Mips::BLTZC:
case Mips::BLTZC_MMR6:
1872 return Error(IDLoc,
"branch target out of range");
1874 return Error(IDLoc,
"branch to misaligned address");
1876 case Mips::BEQZC:
case Mips::BEQZC_MMR6:
1877 case Mips::BNEZC:
case Mips::BNEZC_MMR6:
1883 return Error(IDLoc,
"branch target out of range");
1885 return Error(IDLoc,
"branch to misaligned address");
1887 case Mips::BEQZ16_MM:
1888 case Mips::BEQZC16_MMR6:
1889 case Mips::BNEZ16_MM:
1890 case Mips::BNEZC16_MMR6:
1896 return Error(IDLoc,
"branch target out of range");
1898 return Error(IDLoc,
"branch to misaligned address");
1905 if (hasMips32r6() && Opcode == Mips::SSNOP) {
1906 std::string
ISA = hasMips64r6() ?
"MIPS64r6" :
"MIPS32r6";
1907 Warning(IDLoc,
"ssnop is deprecated for " + ISA +
" and is equivalent to a "
1927 return Error(IDLoc,
"expected immediate operand kind");
1930 Opcode == Mips::BBIT1 ? 63 : 31))
1931 return Error(IDLoc,
"immediate operand value out of range");
1933 Inst.
setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1944 return Error(IDLoc,
"expected immediate operand kind");
1947 return Error(IDLoc,
"immediate operand value out of range");
1959 unsigned FirstOp = 1;
1960 unsigned SecondOp = 2;
1964 case Mips::SDivIMacro:
1965 case Mips::UDivIMacro:
1966 case Mips::DSDivIMacro:
1967 case Mips::DUDivIMacro:
1969 return Error(IDLoc,
"expected immediate operand kind");
1973 Warning(IDLoc,
"dividing zero by zero");
1975 Warning(IDLoc,
"division by zero");
1987 case Mips::SDivMacro:
1988 case Mips::DSDivMacro:
1989 case Mips::UDivMacro:
1990 case Mips::DUDivMacro:
1995 case Mips::DIVU_MMR6:
1996 case Mips::DIV_MMR6:
2001 Warning(IDLoc,
"dividing zero by zero");
2003 Warning(IDLoc,
"division by zero");
2009 if ((Opcode == Mips::J || Opcode == Mips::J_MM) && inPicMode()) {
2011 BInst.
setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
2020 if ((Opcode == Mips::JAL || Opcode == Mips::JAL_MM) && inPicMode()) {
2021 warnIfNoMacro(IDLoc);
2024 return Error(IDLoc,
"unsupported constant in relocation");
2032 return Error(IDLoc,
"jal doesn't support multiple symbols in PIC mode");
2038 if (expandLoadAddress(
getABI().getTempReg(9), MCRegister(),
2039 Inst.
getOperand(0), !isGP64bit(), IDLoc, Out, STI))
2043 if (inMicroMipsMode())
2044 JalrInst.
setOpcode(IsCpRestoreSet ? Mips::JALRS_MM : Mips::JALR_MM);
2050 if (isJalrRelocAvailable(JalExpr)) {
2056 const MCExpr *RelocJalrExpr =
2060 *TmpExpr, inMicroMipsMode() ?
"R_MICROMIPS_JALR" :
"R_MIPS_JALR",
2066 ExpandedJalSym =
true;
2075 expandMem9Inst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2078 expandMem16Inst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2081 return getParser().hasPendingError();
2085 if (inMicroMipsMode()) {
2086 if (Opcode == Mips::LW_MM || Opcode == Mips::LW_MMR6) {
2089 const MCOperandInfo &OpInfo = MCID.
operands()[i];
2094 int MemOffset =
Op.getImm();
2097 if (
isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
2120 case Mips::ADDIUSP_MM:
2123 return Error(IDLoc,
"expected immediate operand kind");
2127 return Error(IDLoc,
"immediate operand value out of range");
2129 case Mips::SLL16_MM:
2130 case Mips::SRL16_MM:
2133 return Error(IDLoc,
"expected immediate operand kind");
2136 return Error(IDLoc,
"immediate operand value out of range");
2141 return Error(IDLoc,
"expected immediate operand kind");
2144 return Error(IDLoc,
"immediate operand value out of range");
2146 case Mips::ADDIUR2_MM:
2149 return Error(IDLoc,
"expected immediate operand kind");
2151 if (!(
Imm == 1 ||
Imm == -1 ||
2153 return Error(IDLoc,
"immediate operand value out of range");
2155 case Mips::ANDI16_MM:
2158 return Error(IDLoc,
"expected immediate operand kind");
2162 Imm == 64 ||
Imm == 255 ||
Imm == 32768 ||
Imm == 65535))
2163 return Error(IDLoc,
"immediate operand value out of range");
2165 case Mips::LBU16_MM:
2168 return Error(IDLoc,
"expected immediate operand kind");
2171 return Error(IDLoc,
"immediate operand value out of range");
2174 case Mips::SB16_MMR6:
2177 return Error(IDLoc,
"expected immediate operand kind");
2180 return Error(IDLoc,
"immediate operand value out of range");
2182 case Mips::LHU16_MM:
2184 case Mips::SH16_MMR6:
2187 return Error(IDLoc,
"expected immediate operand kind");
2190 return Error(IDLoc,
"immediate operand value out of range");
2194 case Mips::SW16_MMR6:
2197 return Error(IDLoc,
"expected immediate operand kind");
2200 return Error(IDLoc,
"immediate operand value out of range");
2202 case Mips::ADDIUPC_MM:
2205 return Error(IDLoc,
"expected immediate operand kind");
2208 return Error(IDLoc,
"immediate operand value out of range");
2213 return Error(IDLoc,
"invalid operand for instruction");
2215 case Mips::MOVEP_MM:
2216 case Mips::MOVEP_MMR6: {
2219 bool RegPair = ((R0 == Mips::R5 && R1 == Mips::R6) ||
2220 (R0 == Mips::R5 && R1 == Mips::R7) ||
2221 (R0 == Mips::R6 && R1 == Mips::R7) ||
2222 (R0 == Mips::R4 && R1 == Mips::R21) ||
2223 (R0 == Mips::R4 && R1 == Mips::R22) ||
2224 (R0 == Mips::R4 && R1 == Mips::R5) ||
2225 (R0 == Mips::R4 && R1 == Mips::R6) ||
2226 (R0 == Mips::R4 && R1 == Mips::R7));
2228 return Error(IDLoc,
"invalid operand for instruction");
2234 bool FillDelaySlot =
2239 bool PrevForbiddenSlotAttr = CurForbiddenSlotAttr;
2242 bool SetReorderAfterNop =
false;
2247 if (PrevForbiddenSlotAttr && !SafeInForbiddenSlot(MCID)) {
2257 if (AssemblerOptions.
back()->isReorder() && !FillDelaySlot) {
2258 SetReorderAfterNop =
true;
2267 CurForbiddenSlotAttr =
2268 hasForbiddenSlot(MCID) && AssemblerOptions.
back()->isReorder();
2270 if (FillDelaySlot || CurForbiddenSlotAttr)
2273 MacroExpanderResultTy ExpandResult =
2274 tryExpandInstruction(Inst, IDLoc, Out, STI);
2275 switch (ExpandResult) {
2277 Out.emitInstruction(Inst, *STI);
2291 if (PrevForbiddenSlotAttr && !SetReorderAfterNop && !FillDelaySlot &&
2292 AssemblerOptions.
back()->isReorder()) {
2298 if (inMicroMipsMode()) {
2313 if (FillDelaySlot) {
2318 if ((Opcode == Mips::JalOneReg || Opcode == Mips::JalTwoReg ||
2320 isPicAndNotNxxAbi()) {
2321 if (IsCpRestoreSet) {
2325 if (!AssemblerOptions.
back()->isReorder())
2332 Warning(IDLoc,
"no .cprestore used in PIC mode");
2338void MipsAsmParser::onEndOfFile() {
2339 MipsTargetStreamer &TOut = getTargetStreamer();
2340 SMLoc IDLoc = SMLoc();
2342 if (CurForbiddenSlotAttr) {
2344 if (AssemblerOptions.
back()->isReorder())
2349MipsAsmParser::MacroExpanderResultTy
2350MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2351 const MCSubtargetInfo *STI) {
2354 return MER_NotAMacro;
2355 case Mips::LoadImm32:
2356 return expandLoadImm(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2357 case Mips::LoadImm64:
2358 return expandLoadImm(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2359 case Mips::LoadAddrImm32:
2360 case Mips::LoadAddrImm64:
2363 "expected immediate operand kind");
2365 return expandLoadAddress(
2367 Inst.
getOpcode() == Mips::LoadAddrImm32, IDLoc, Out, STI)
2370 case Mips::LoadAddrReg32:
2371 case Mips::LoadAddrReg64:
2375 "expected immediate operand kind");
2379 Inst.
getOpcode() == Mips::LoadAddrReg32, IDLoc,
2383 case Mips::B_MM_Pseudo:
2384 case Mips::B_MMR6_Pseudo:
2385 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2389 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2391 case Mips::JalOneReg:
2392 case Mips::JalTwoReg:
2393 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2396 case Mips::BEQLImmMacro:
2397 case Mips::BNELImmMacro:
2398 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2415 case Mips::BLTImmMacro:
2416 case Mips::BLEImmMacro:
2417 case Mips::BGEImmMacro:
2418 case Mips::BGTImmMacro:
2419 case Mips::BLTUImmMacro:
2420 case Mips::BLEUImmMacro:
2421 case Mips::BGEUImmMacro:
2422 case Mips::BGTUImmMacro:
2423 case Mips::BLTLImmMacro:
2424 case Mips::BLELImmMacro:
2425 case Mips::BGELImmMacro:
2426 case Mips::BGTLImmMacro:
2427 case Mips::BLTULImmMacro:
2428 case Mips::BLEULImmMacro:
2429 case Mips::BGEULImmMacro:
2430 case Mips::BGTULImmMacro:
2431 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2432 case Mips::SDivMacro:
2433 case Mips::SDivIMacro:
2434 case Mips::SRemMacro:
2435 case Mips::SRemIMacro:
2436 return expandDivRem(Inst, IDLoc, Out, STI,
false,
true) ? MER_Fail
2438 case Mips::DSDivMacro:
2439 case Mips::DSDivIMacro:
2440 case Mips::DSRemMacro:
2441 case Mips::DSRemIMacro:
2442 return expandDivRem(Inst, IDLoc, Out, STI,
true,
true) ? MER_Fail
2444 case Mips::UDivMacro:
2445 case Mips::UDivIMacro:
2446 case Mips::URemMacro:
2447 case Mips::URemIMacro:
2448 return expandDivRem(Inst, IDLoc, Out, STI,
false,
false) ? MER_Fail
2450 case Mips::DUDivMacro:
2451 case Mips::DUDivIMacro:
2452 case Mips::DURemMacro:
2453 case Mips::DURemIMacro:
2454 return expandDivRem(Inst, IDLoc, Out, STI,
true,
false) ? MER_Fail
2456 case Mips::PseudoTRUNC_W_S:
2457 return expandTrunc(Inst,
false,
false, IDLoc, Out, STI) ? MER_Fail
2459 case Mips::PseudoTRUNC_W_D32:
2460 return expandTrunc(Inst,
true,
false, IDLoc, Out, STI) ? MER_Fail
2462 case Mips::PseudoTRUNC_W_D:
2463 return expandTrunc(Inst,
true,
true, IDLoc, Out, STI) ? MER_Fail
2466 case Mips::LoadImmSingleGPR:
2467 return expandLoadSingleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2469 case Mips::LoadImmSingleFGR:
2470 return expandLoadSingleImmToFPR(Inst, IDLoc, Out, STI) ? MER_Fail
2472 case Mips::LoadImmDoubleGPR:
2473 return expandLoadDoubleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2475 case Mips::LoadImmDoubleFGR:
2476 return expandLoadDoubleImmToFPR(Inst,
true, IDLoc, Out, STI) ? MER_Fail
2478 case Mips::LoadImmDoubleFGR_32:
2479 return expandLoadDoubleImmToFPR(Inst,
false, IDLoc, Out, STI) ? MER_Fail
2483 return expandUlh(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2485 return expandUlh(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2487 return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2490 return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2492 case Mips::NORImm64:
2493 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2496 return expandSge(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2499 case Mips::SGEImm64:
2500 case Mips::SGEUImm64:
2501 return expandSgeImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2504 case Mips::SGTImm64:
2505 case Mips::SGTUImm64:
2506 return expandSgtImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2509 return expandSle(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2512 case Mips::SLEImm64:
2513 case Mips::SLEUImm64:
2514 return expandSleImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2515 case Mips::SLTImm64:
2518 return MER_NotAMacro;
2520 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2521 case Mips::SLTUImm64:
2524 return MER_NotAMacro;
2526 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2527 case Mips::ADDi:
case Mips::ADDi_MM:
2528 case Mips::ADDiu:
case Mips::ADDiu_MM:
2529 case Mips::SLTi:
case Mips::SLTi_MM:
2530 case Mips::SLTiu:
case Mips::SLTiu_MM:
2535 return MER_NotAMacro;
2536 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2539 return MER_NotAMacro;
2540 case Mips::ANDi:
case Mips::ANDi_MM:
case Mips::ANDi64:
2541 case Mips::ORi:
case Mips::ORi_MM:
case Mips::ORi64:
2542 case Mips::XORi:
case Mips::XORi_MM:
case Mips::XORi64:
2547 return MER_NotAMacro;
2548 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2551 return MER_NotAMacro;
2554 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2557 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2560 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2563 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2564 case Mips::ABSMacro:
2565 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2566 case Mips::MULImmMacro:
2567 case Mips::DMULImmMacro:
2568 return expandMulImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2569 case Mips::MULOMacro:
2570 case Mips::DMULOMacro:
2571 return expandMulO(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2572 case Mips::MULOUMacro:
2573 case Mips::DMULOUMacro:
2574 return expandMulOU(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2575 case Mips::DMULMacro:
2576 return expandDMULMacro(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2579 return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2584 return expandStoreDM1Macro(Inst, IDLoc, Out, STI)
2587 case Mips::SEQMacro:
2588 return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2589 case Mips::SEQIMacro:
2590 return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2591 case Mips::SNEMacro:
2592 return expandSne(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2593 case Mips::SNEIMacro:
2594 return expandSneI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2595 case Mips::MFTC0:
case Mips::MTTC0:
2596 case Mips::MFTGPR:
case Mips::MTTGPR:
2597 case Mips::MFTLO:
case Mips::MTTLO:
2598 case Mips::MFTHI:
case Mips::MTTHI:
2599 case Mips::MFTACX:
case Mips::MTTACX:
2600 case Mips::MFTDSP:
case Mips::MTTDSP:
2601 case Mips::MFTC1:
case Mips::MTTC1:
2602 case Mips::MFTHC1:
case Mips::MTTHC1:
2603 case Mips::CFTC1:
case Mips::CTTC1:
2604 return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2606 case Mips::SaadAddr:
2607 return expandSaaAddr(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2611bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2613 const MCSubtargetInfo *STI) {
2614 MipsTargetStreamer &TOut = getTargetStreamer();
2619 const MCOperand FirstRegOp = Inst.
getOperand(0);
2620 const unsigned Opcode = Inst.
getOpcode();
2622 if (Opcode == Mips::JalOneReg) {
2624 if (IsCpRestoreSet && inMicroMipsMode()) {
2627 }
else if (inMicroMipsMode()) {
2628 JalrInst.
setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2635 }
else if (Opcode == Mips::JalTwoReg) {
2637 if (IsCpRestoreSet && inMicroMipsMode())
2640 JalrInst.
setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2642 const MCOperand SecondRegOp = Inst.
getOperand(1);
2645 Out.emitInstruction(JalrInst, *STI);
2649 const MCInstrDesc &MCID = MII.get(JalrInst.
getOpcode());
2672bool MipsAsmParser::loadImmediate(int64_t ImmValue, MCRegister DstReg,
2673 MCRegister SrcReg,
bool Is32BitImm,
2674 bool IsAddress, SMLoc IDLoc, MCStreamer &Out,
2675 const MCSubtargetInfo *STI) {
2676 MipsTargetStreamer &TOut = getTargetStreamer();
2678 if (!Is32BitImm && !isGP64bit()) {
2679 Error(IDLoc,
"instruction requires a 64-bit architecture");
2690 Error(IDLoc,
"instruction requires a 32-bit immediate");
2695 MCRegister ZeroReg = IsAddress ?
ABI.GetNullPtr() :
ABI.GetZeroReg();
2696 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2698 bool UseSrcReg =
false;
2702 MCRegister TmpReg = DstReg;
2704 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2707 MCRegister ATReg = getATReg(IDLoc);
2720 if (IsAddress && !Is32BitImm) {
2721 TOut.
emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2725 TOut.
emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2730 MCRegister TmpReg = DstReg;
2731 if (SrcReg == DstReg) {
2732 TmpReg = getATReg(IDLoc);
2737 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2739 TOut.
emitRRR(
ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2744 warnIfNoMacro(IDLoc);
2746 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2747 uint16_t Bits15To0 = ImmValue & 0xffff;
2748 if (!Is32BitImm && !
isInt<32>(ImmValue)) {
2751 if (ImmValue == 0xffffffff) {
2752 TOut.
emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2753 TOut.
emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2755 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2761 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2762 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2764 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2766 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2770 TOut.
emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2772 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2774 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2780 Error(IDLoc,
"instruction requires a 32-bit immediate");
2787 assert(
BitWidth >= 17 &&
"ImmValue must be at least 17-bit wide");
2791 unsigned ShiftAmount =
BitWidth - 16;
2792 uint16_t
Bits = (ImmValue >> ShiftAmount) & 0xffff;
2793 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2794 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2797 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2802 warnIfNoMacro(IDLoc);
2809 if (loadImmediate(ImmValue >> 32, TmpReg, MCRegister(),
true,
false, IDLoc,
2815 unsigned ShiftCarriedForwards = 16;
2816 for (
int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2817 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2819 if (ImmChunk != 0) {
2820 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2821 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2822 ShiftCarriedForwards = 0;
2825 ShiftCarriedForwards += 16;
2827 ShiftCarriedForwards -= 16;
2830 if (ShiftCarriedForwards)
2831 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2834 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2839bool MipsAsmParser::expandLoadImm(MCInst &Inst,
bool Is32BitImm, SMLoc IDLoc,
2840 MCStreamer &Out,
const MCSubtargetInfo *STI) {
2842 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
2843 const MCOperand &DstRegOp = Inst.
getOperand(0);
2844 assert(DstRegOp.
isReg() &&
"expected register operand kind");
2846 if (loadImmediate(ImmOp.
getImm(), DstRegOp.
getReg(), MCRegister(), Is32BitImm,
2847 false, IDLoc, Out, STI))
2853bool MipsAsmParser::expandLoadAddress(MCRegister DstReg, MCRegister BaseReg,
2855 bool Is32BitAddress, SMLoc IDLoc,
2857 const MCSubtargetInfo *STI) {
2859 if (Is32BitAddress &&
ABI.ArePtrs64bit()) {
2860 Warning(IDLoc,
"la used to load 64-bit address");
2862 Is32BitAddress =
false;
2866 if (!Is32BitAddress && !hasMips3()) {
2867 Error(IDLoc,
"instruction requires a 64-bit architecture");
2872 return loadAndAddSymbolAddress(
Offset.getExpr(), DstReg, BaseReg,
2873 Is32BitAddress, IDLoc, Out, STI);
2875 if (!
ABI.ArePtrs64bit()) {
2877 Is32BitAddress =
true;
2880 return loadImmediate(
Offset.getImm(), DstReg, BaseReg, Is32BitAddress,
true,
2884bool MipsAsmParser::loadAndAddSymbolAddress(
const MCExpr *SymExpr,
2886 MCRegister SrcReg,
bool Is32BitSym,
2887 SMLoc IDLoc, MCStreamer &Out,
2888 const MCSubtargetInfo *STI) {
2889 MipsTargetStreamer &TOut = getTargetStreamer();
2891 SrcReg.
isValid() && SrcReg != Mips::R0 && SrcReg != Mips::R0_64;
2892 warnIfNoMacro(IDLoc);
2897 Error(IDLoc,
"expected relocatable expression");
2901 Error(IDLoc,
"expected relocatable expression with only one symbol");
2905 bool IsPtr64 =
ABI.ArePtrs64bit();
2908 ?
static_cast<const MCSymbolELF *
>(Res.
getAddSym())
2916 bool UseXGOT = STI->
hasFeature(Mips::FeatureXGOT) && !IsLocalSym;
2922 if ((DstReg ==
getABI().getTempReg(9,
false) ||
2923 DstReg ==
getABI().getTempReg(9,
true)) &&
2924 !UseSrcReg && Res.
getConstant() == 0 && !IsLocalSym) {
2926 const MCExpr *CallHiExpr =
2928 const MCExpr *CallLoExpr =
2932 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, DstReg, GPReg,
2934 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, DstReg,
2937 const MCExpr *CallExpr =
2939 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, GPReg,
2945 MCRegister TmpReg = DstReg;
2947 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2951 MCRegister ATReg = getATReg(IDLoc);
2970 const MCExpr *CallHiExpr =
2977 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg, GPReg,
2979 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, TmpReg,
2983 TOut.
emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
2989 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
2994 const MCSpecifierExpr *GotExpr =
nullptr;
2995 const MCExpr *LoExpr =
nullptr;
2996 if (
ABI.IsN32() ||
ABI.IsN64()) {
3015 Error(IDLoc,
"macro instruction uses large offset, which is not "
3016 "currently supported");
3045 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, GPReg,
3049 TOut.
emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3053 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3059 const auto *HiExpr =
3061 const auto *LoExpr =
3065 if (
ABI.ArePtrs64bit() && isGP64bit()) {
3073 const auto *HighestExpr =
3075 const auto *HigherExpr =
3080 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
3082 if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
3083 MCRegister ATReg = getATReg(IDLoc);
3095 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3097 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3100 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3103 TOut.
emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
3106 }
else if (canUseATReg() && !RdRegIsRsReg && DstReg != getATReg(IDLoc)) {
3107 MCRegister ATReg = getATReg(IDLoc);
3123 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3127 TOut.
emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3128 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3130 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3133 }
else if ((!canUseATReg() && !RdRegIsRsReg) ||
3134 (canUseATReg() && DstReg == getATReg(IDLoc))) {
3145 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3147 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3148 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3150 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3151 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3154 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3160 assert(SrcReg == DstReg && !canUseATReg() &&
3161 "Could have expanded dla but didn't?");
3162 reportParseError(IDLoc,
3163 "pseudo-instruction requires $at, which is not available");
3177 MCRegister TmpReg = DstReg;
3179 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
3182 MCRegister ATReg = getATReg(IDLoc);
3193 TOut.
emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3196 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
3205 if (getMipsMCRegisterClass(Mips::FGR32RegClassID).
contains(
Reg))
3206 return Reg == (
unsigned)Mips::F31 ? (
unsigned)Mips::F0 :
Reg + 1;
3208 default:
llvm_unreachable(
"Unknown register in assembly macro expansion!");
3273 case Mips::D0:
return Mips::F1;
3274 case Mips::D1:
return Mips::F3;
3275 case Mips::D2:
return Mips::F5;
3276 case Mips::D3:
return Mips::F7;
3277 case Mips::D4:
return Mips::F9;
3278 case Mips::D5:
return Mips::F11;
3279 case Mips::D6:
return Mips::F13;
3280 case Mips::D7:
return Mips::F15;
3281 case Mips::D8:
return Mips::F17;
3282 case Mips::D9:
return Mips::F19;
3304bool MipsAsmParser::emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc,
3306 MCRegister ATReg = getATReg(IDLoc);
3312 const auto *GotExpr =
3315 if(isABI_O32() || isABI_N32()) {
3324 const auto *HiExpr =
3333 if(isABI_O32() || isABI_N32()) {
3337 const auto *HighestExpr =
3340 const auto *HigherExpr =
3345 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3347 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3350 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3359 if ((
Hi_32(ImmOp64) & 0x7ff00000) == 0) {
3370 float TmpFloat =
static_cast<float>(DoubleImm);
3374bool MipsAsmParser::expandLoadSingleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3376 const MCSubtargetInfo *STI) {
3379 "Invalid instruction operand.");
3386 return loadImmediate(ImmOp32, FirstReg, MCRegister(),
true,
false, IDLoc, Out,
3390bool MipsAsmParser::expandLoadSingleImmToFPR(MCInst &Inst, SMLoc IDLoc,
3392 const MCSubtargetInfo *STI) {
3393 MipsTargetStreamer &TOut = getTargetStreamer();
3396 "Invalid instruction operand.");
3405 MCRegister TmpReg = Mips::R0;
3407 TmpReg = getATReg(IDLoc);
3412 if (
Lo_32(ImmOp64) == 0) {
3413 if (TmpReg != Mips::R0 && loadImmediate(ImmOp32, TmpReg, MCRegister(),
true,
3414 false, IDLoc, Out, STI))
3416 TOut.
emitRR(Mips::MTC1, FirstReg, TmpReg, IDLoc, STI);
3420 MCSection *CS = getStreamer().getCurrentSectionOnly();
3423 MCSection *ReadOnlySection =
3430 getStreamer().switchSection(ReadOnlySection);
3431 getStreamer().emitLabel(Sym, IDLoc);
3432 getStreamer().emitInt32(ImmOp32);
3433 getStreamer().switchSection(CS);
3435 if (emitPartialAddress(TOut, IDLoc, Sym))
3442bool MipsAsmParser::expandLoadDoubleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3444 const MCSubtargetInfo *STI) {
3445 MipsTargetStreamer &TOut = getTargetStreamer();
3448 "Invalid instruction operand.");
3455 if (
Lo_32(ImmOp64) == 0) {
3457 if (loadImmediate(ImmOp64, FirstReg, MCRegister(),
false,
false, IDLoc,
3461 if (loadImmediate(
Hi_32(ImmOp64), FirstReg, MCRegister(),
true,
false,
3465 if (loadImmediate(0,
nextReg(FirstReg), MCRegister(),
true,
false, IDLoc,
3472 MCSection *CS = getStreamer().getCurrentSectionOnly();
3473 MCSection *ReadOnlySection =
3480 getStreamer().switchSection(ReadOnlySection);
3481 getStreamer().emitLabel(Sym, IDLoc);
3482 getStreamer().emitValueToAlignment(
Align(8));
3483 getStreamer().emitIntValue(ImmOp64, 8);
3484 getStreamer().switchSection(CS);
3486 MCRegister TmpReg = getATReg(IDLoc);
3490 if (emitPartialAddress(TOut, IDLoc, Sym))
3493 TOut.
emitRRX(isABI_N64() ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3497 TOut.
emitRRI(Mips::LD, FirstReg, TmpReg, 0, IDLoc, STI);
3499 TOut.
emitRRI(Mips::LW, FirstReg, TmpReg, 0, IDLoc, STI);
3500 TOut.
emitRRI(Mips::LW,
nextReg(FirstReg), TmpReg, 4, IDLoc, STI);
3505bool MipsAsmParser::expandLoadDoubleImmToFPR(MCInst &Inst,
bool Is64FPU,
3506 SMLoc IDLoc, MCStreamer &Out,
3507 const MCSubtargetInfo *STI) {
3508 MipsTargetStreamer &TOut = getTargetStreamer();
3511 "Invalid instruction operand.");
3518 MCRegister TmpReg = Mips::R0;
3520 TmpReg = getATReg(IDLoc);
3525 if ((
Lo_32(ImmOp64) == 0) &&
3526 !((
Hi_32(ImmOp64) & 0xffff0000) && (
Hi_32(ImmOp64) & 0x0000ffff))) {
3528 if (TmpReg != Mips::R0 && loadImmediate(ImmOp64, TmpReg, MCRegister(),
3529 false,
false, IDLoc, Out, STI))
3531 TOut.
emitRR(Mips::DMTC1, FirstReg, TmpReg, IDLoc, STI);
3535 if (TmpReg != Mips::R0 &&
3536 loadImmediate(
Hi_32(ImmOp64), TmpReg, MCRegister(),
true,
false, IDLoc,
3540 if (hasMips32r2()) {
3541 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::R0, IDLoc, STI);
3542 TOut.
emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, TmpReg, IDLoc, STI);
3544 TOut.
emitRR(Mips::MTC1,
nextReg(FirstReg), TmpReg, IDLoc, STI);
3545 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::R0, IDLoc, STI);
3550 MCSection *CS = getStreamer().getCurrentSectionOnly();
3553 MCSection *ReadOnlySection =
3560 getStreamer().switchSection(ReadOnlySection);
3561 getStreamer().emitLabel(Sym, IDLoc);
3562 getStreamer().emitValueToAlignment(
Align(8));
3563 getStreamer().emitIntValue(ImmOp64, 8);
3564 getStreamer().switchSection(CS);
3566 if (emitPartialAddress(TOut, IDLoc, Sym))
3569 TOut.
emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, TmpReg,
3575bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
3577 const MCSubtargetInfo *STI) {
3578 MipsTargetStreamer &TOut = getTargetStreamer();
3581 "unexpected number of operands");
3591 assert(
Offset.isImm() &&
"expected immediate operand kind");
3595 if (inMicroMipsMode())
3596 Inst.
setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3599 return Error(IDLoc,
"branch target out of range");
3601 return Error(IDLoc,
"branch to misaligned address");
3609 Out.emitInstruction(Inst, *STI);
3613 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
3620bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3621 const MCSubtargetInfo *STI) {
3622 MipsTargetStreamer &TOut = getTargetStreamer();
3623 const MCOperand &DstRegOp = Inst.
getOperand(0);
3624 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3627 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
3629 const MCOperand &MemOffsetOp = Inst.
getOperand(2);
3631 "expected immediate or expression operand");
3633 bool IsLikely =
false;
3643 case Mips::BEQLImmMacro:
3647 case Mips::BNELImmMacro:
3656 int64_t ImmValue = ImmOp.
getImm();
3657 if (ImmValue == 0) {
3661 TOut.
emitRRI(Mips::SLL, Mips::R0, Mips::R0, 0, IDLoc, STI);
3663 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), Mips::R0, MemOffsetOp, IDLoc,
3666 warnIfNoMacro(IDLoc);
3668 MCRegister ATReg = getATReg(IDLoc);
3672 if (loadImmediate(ImmValue, ATReg, MCRegister(), !isGP64bit(),
true, IDLoc,
3676 if (IsLikely && MemOffsetOp.
isExpr()) {
3679 TOut.
emitRRI(Mips::SLL, Mips::R0, Mips::R0, 0, IDLoc, STI);
3681 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3686void MipsAsmParser::expandMem16Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3687 const MCSubtargetInfo *STI,
bool IsLoad) {
3689 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3690 unsigned StartOp = NumOp == 3 ? 0 : 1;
3692 const MCOperand &DstRegOp = Inst.
getOperand(StartOp);
3693 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3694 const MCOperand &BaseRegOp = Inst.
getOperand(StartOp + 1);
3695 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3698 MipsTargetStreamer &TOut = getTargetStreamer();
3700 MCRegister DstReg = DstRegOp.
getReg();
3702 MCRegister TmpReg = DstReg;
3704 const MCInstrDesc &
Desc = MII.get(OpCode);
3705 int16_t DstRegClass =
3706 MII.getOpRegClassID(
Desc.operands()[StartOp],
3708 unsigned DstRegClassID =
3709 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3710 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3711 (DstRegClassID == Mips::GPR64RegClassID);
3713 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3716 TmpReg = getATReg(IDLoc);
3721 auto emitInstWithOffset = [&](
const MCOperand &
Off) {
3723 TOut.
emitRRX(OpCode, DstReg, TmpReg,
Off, IDLoc, STI);
3725 TOut.
emitRRRX(OpCode, DstReg, DstReg, TmpReg,
Off, IDLoc, STI);
3729 int64_t LoOffset =
OffsetOp.getImm() & 0xffff;
3730 int64_t HiOffset =
OffsetOp.getImm() & ~0xffff;
3734 if (LoOffset & 0x8000)
3735 HiOffset += 0x10000;
3737 bool IsLargeOffset = HiOffset != 0;
3739 if (IsLargeOffset) {
3741 if (loadImmediate(HiOffset, TmpReg, MCRegister(), Is32BitImm,
true, IDLoc,
3746 if (BaseReg != Mips::R0 && BaseReg != Mips::R0_64)
3747 TOut.
emitRRR(
ABI.ArePtrs64bit() ? Mips::DADDu : Mips::ADDu, TmpReg,
3748 TmpReg, BaseReg, IDLoc, STI);
3762 if (!
OffsetOp.getExpr()->evaluateAsRelocatable(Res,
nullptr)) {
3763 Error(IDLoc,
"expected relocatable expression");
3767 Error(IDLoc,
"expected relocatable expression with only one symbol");
3771 loadAndAddSymbolAddress(
3773 BaseReg, !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3781 const MCExpr *OffExpr =
OffsetOp.getExpr();
3793 TOut.
emitRX(Mips::LUi, TmpReg, HighestOperand, IDLoc, STI);
3794 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HigherOperand, IDLoc, STI);
3795 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3796 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HiOperand, IDLoc, STI);
3797 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3798 if (BaseReg != Mips::R0 && BaseReg != Mips::R0_64)
3799 TOut.
emitRRR(Mips::DADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3800 emitInstWithOffset(LoOperand);
3803 TOut.
emitRX(Mips::LUi, TmpReg, HiOperand, IDLoc, STI);
3804 if (BaseReg != Mips::R0)
3805 TOut.
emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3807 emitInstWithOffset(LoOperand);
3816void MipsAsmParser::expandMem9Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3817 const MCSubtargetInfo *STI,
bool IsLoad) {
3819 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3820 unsigned StartOp = NumOp == 3 ? 0 : 1;
3822 const MCOperand &DstRegOp = Inst.
getOperand(StartOp);
3823 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3824 const MCOperand &BaseRegOp = Inst.
getOperand(StartOp + 1);
3825 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3828 MipsTargetStreamer &TOut = getTargetStreamer();
3830 MCRegister DstReg = DstRegOp.
getReg();
3832 MCRegister TmpReg = DstReg;
3834 const MCInstrDesc &
Desc = MII.get(OpCode);
3835 int16_t DstRegClass =
3836 MII.getOpRegClassID(
Desc.operands()[StartOp],
3839 unsigned DstRegClassID =
3840 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3841 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3842 (DstRegClassID == Mips::GPR64RegClassID);
3844 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3847 TmpReg = getATReg(IDLoc);
3852 auto emitInst = [&]() {
3861 loadImmediate(
OffsetOp.getImm(), TmpReg, BaseReg, !
ABI.ArePtrs64bit(),
true,
3868 loadAndAddSymbolAddress(
OffsetOp.getExpr(), TmpReg, BaseReg,
3869 !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3877bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
3879 const MCSubtargetInfo *STI) {
3882 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3886 Inst.
getOperand(OpNum - 3).
isReg() &&
"Invalid instruction operand.");
3895 if (inMicroMipsMode() && hasMips32r6())
3896 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3898 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3902 Out.emitInstruction(Inst, *STI);
3906bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
3908 const MCSubtargetInfo *STI) {
3909 MipsTargetStreamer &TOut = getTargetStreamer();
3910 bool EmittedNoMacroWarning =
false;
3911 unsigned PseudoOpcode = Inst.
getOpcode();
3916 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3917 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3922 else if (TrgOp.
isImm()) {
3923 warnIfNoMacro(IDLoc);
3924 EmittedNoMacroWarning =
true;
3926 TrgReg = getATReg(IDLoc);
3930 switch(PseudoOpcode) {
3933 case Mips::BLTImmMacro:
3934 PseudoOpcode = Mips::BLT;
3936 case Mips::BLEImmMacro:
3937 PseudoOpcode = Mips::BLE;
3939 case Mips::BGEImmMacro:
3940 PseudoOpcode = Mips::BGE;
3942 case Mips::BGTImmMacro:
3943 PseudoOpcode = Mips::BGT;
3945 case Mips::BLTUImmMacro:
3946 PseudoOpcode = Mips::BLTU;
3948 case Mips::BLEUImmMacro:
3949 PseudoOpcode = Mips::BLEU;
3951 case Mips::BGEUImmMacro:
3952 PseudoOpcode = Mips::BGEU;
3954 case Mips::BGTUImmMacro:
3955 PseudoOpcode = Mips::BGTU;
3957 case Mips::BLTLImmMacro:
3958 PseudoOpcode = Mips::BLTL;
3960 case Mips::BLELImmMacro:
3961 PseudoOpcode = Mips::BLEL;
3963 case Mips::BGELImmMacro:
3964 PseudoOpcode = Mips::BGEL;
3966 case Mips::BGTLImmMacro:
3967 PseudoOpcode = Mips::BGTL;
3969 case Mips::BLTULImmMacro:
3970 PseudoOpcode = Mips::BLTUL;
3972 case Mips::BLEULImmMacro:
3973 PseudoOpcode = Mips::BLEUL;
3975 case Mips::BGEULImmMacro:
3976 PseudoOpcode = Mips::BGEUL;
3978 case Mips::BGTULImmMacro:
3979 PseudoOpcode = Mips::BGTUL;
3983 if (loadImmediate(TrgOp.
getImm(), TrgReg, MCRegister(), !isGP64bit(),
false,
3988 switch (PseudoOpcode) {
3993 AcceptsEquality =
false;
3994 ReverseOrderSLT =
false;
3996 ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
3997 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
3998 ZeroSrcOpcode = Mips::BGTZ;
3999 ZeroTrgOpcode = Mips::BLTZ;
4005 AcceptsEquality =
true;
4006 ReverseOrderSLT =
true;
4008 ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
4009 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
4010 ZeroSrcOpcode = Mips::BGEZ;
4011 ZeroTrgOpcode = Mips::BLEZ;
4017 AcceptsEquality =
true;
4018 ReverseOrderSLT =
false;
4020 ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
4021 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
4022 ZeroSrcOpcode = Mips::BLEZ;
4023 ZeroTrgOpcode = Mips::BGEZ;
4029 AcceptsEquality =
false;
4030 ReverseOrderSLT =
true;
4032 ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
4033 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
4034 ZeroSrcOpcode = Mips::BLTZ;
4035 ZeroTrgOpcode = Mips::BGTZ;
4041 bool IsTrgRegZero = (TrgReg == Mips::R0);
4042 bool IsSrcRegZero = (SrcReg == Mips::R0);
4043 if (IsSrcRegZero && IsTrgRegZero) {
4047 if (PseudoOpcode == Mips::BLT) {
4052 if (PseudoOpcode == Mips::BLE) {
4055 Warning(IDLoc,
"branch is always taken");
4058 if (PseudoOpcode == Mips::BGE) {
4061 Warning(IDLoc,
"branch is always taken");
4064 if (PseudoOpcode == Mips::BGT) {
4069 if (PseudoOpcode == Mips::BGTU) {
4070 TOut.
emitRRX(Mips::BNE, Mips::R0, Mips::R0,
4074 if (AcceptsEquality) {
4077 TOut.
emitRRX(Mips::BEQ, Mips::R0, Mips::R0,
4079 Warning(IDLoc,
"branch is always taken");
4086 if (IsSrcRegZero || IsTrgRegZero) {
4087 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
4088 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
4095 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
4096 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
4102 TOut.
emitRRX(Mips::BEQ, Mips::R0, Mips::R0,
4104 Warning(IDLoc,
"branch is always taken");
4120 TOut.
emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
4121 IsSrcRegZero ? TrgReg : SrcReg, Mips::R0,
4128 TOut.
emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
4129 IsSrcRegZero ? TrgReg : SrcReg,
4136 MCRegister ATRegNum = getATReg(IDLoc);
4140 if (!EmittedNoMacroWarning)
4141 warnIfNoMacro(IDLoc);
4158 TOut.
emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
4159 ReverseOrderSLT ? TrgReg : SrcReg,
4160 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
4162 TOut.
emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
4163 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
4177bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4178 const MCSubtargetInfo *STI,
4179 const bool IsMips64,
const bool Signed) {
4180 MipsTargetStreamer &TOut = getTargetStreamer();
4182 warnIfNoMacro(IDLoc);
4184 const MCOperand &RdRegOp = Inst.
getOperand(0);
4185 assert(RdRegOp.
isReg() &&
"expected register operand kind");
4186 MCRegister RdReg = RdRegOp.
getReg();
4188 const MCOperand &RsRegOp = Inst.
getOperand(1);
4189 assert(RsRegOp.
isReg() &&
"expected register operand kind");
4190 MCRegister RsReg = RsRegOp.
getReg();
4197 "expected register or immediate operand kind");
4201 ImmValue = RtOp.
getImm();
4208 DivOp =
Signed ? Mips::DSDIV : Mips::DUDIV;
4209 ZeroReg = Mips::R0_64;
4212 DivOp =
Signed ? Mips::SDIV : Mips::UDIV;
4217 bool UseTraps = useTraps();
4220 bool isDiv = Opcode == Mips::SDivMacro || Opcode == Mips::SDivIMacro ||
4221 Opcode == Mips::UDivMacro || Opcode == Mips::UDivIMacro ||
4222 Opcode == Mips::DSDivMacro || Opcode == Mips::DSDivIMacro ||
4223 Opcode == Mips::DUDivMacro || Opcode == Mips::DUDivIMacro;
4225 bool isRem = Opcode == Mips::SRemMacro || Opcode == Mips::SRemIMacro ||
4226 Opcode == Mips::URemMacro || Opcode == Mips::URemIMacro ||
4227 Opcode == Mips::DSRemMacro || Opcode == Mips::DSRemIMacro ||
4228 Opcode == Mips::DURemMacro || Opcode == Mips::DURemIMacro;
4231 MCRegister ATReg = getATReg(IDLoc);
4235 if (!CLOpts.mno_check_zero_division && ImmValue == 0) {
4237 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4239 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4243 if (isRem && (ImmValue == 1 || (
Signed && (ImmValue == -1)))) {
4244 TOut.
emitRRR(Mips::OR, RdReg, ZeroReg, ZeroReg, IDLoc, STI);
4246 }
else if (isDiv && ImmValue == 1) {
4247 TOut.
emitRRR(Mips::OR, RdReg, RsReg, Mips::R0, IDLoc, STI);
4249 }
else if (isDiv &&
Signed && ImmValue == -1) {
4250 TOut.
emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
4253 if (loadImmediate(ImmValue, ATReg, MCRegister(),
isInt<32>(ImmValue),
4254 false, Inst.
getLoc(), Out, STI))
4256 TOut.
emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
4257 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4267 if (!CLOpts.mno_check_zero_division &&
4268 (RtReg == Mips::R0 || RtReg == Mips::R0_64)) {
4270 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4273 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4279 if (isRem && (RdReg == Mips::R0 || RdReg == Mips::R0_64)) {
4280 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4289 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4290 if (!CLOpts.mno_check_zero_division) {
4292 TOut.
emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4295 BrTarget =
Context.createTempSymbol();
4298 TOut.
emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4303 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4309 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4313bool MipsAsmParser::expandTrunc(MCInst &Inst,
bool IsDouble,
bool Is64FPU,
4314 SMLoc IDLoc, MCStreamer &Out,
4315 const MCSubtargetInfo *STI) {
4316 MipsTargetStreamer &TOut = getTargetStreamer();
4326 if (hasMips1() && !hasMips2()) {
4327 MCRegister ATReg = getATReg(IDLoc);
4333 TOut.
emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4334 TOut.
emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4337 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4339 FirstReg, SecondReg, IDLoc, STI);
4345 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4347 FirstReg, SecondReg, IDLoc, STI);
4352bool MipsAsmParser::expandUlh(MCInst &Inst,
bool Signed, SMLoc IDLoc,
4353 MCStreamer &Out,
const MCSubtargetInfo *STI) {
4354 if (hasMips32r6() || hasMips64r6()) {
4355 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4358 const MCOperand &DstRegOp = Inst.
getOperand(0);
4359 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4360 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4361 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4362 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4363 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4365 MipsTargetStreamer &TOut = getTargetStreamer();
4366 MCRegister DstReg = DstRegOp.
getReg();
4367 MCRegister SrcReg = SrcRegOp.
getReg();
4368 int64_t OffsetValue = OffsetImmOp.
getImm();
4372 warnIfNoMacro(IDLoc);
4373 MCRegister ATReg = getATReg(IDLoc);
4378 if (IsLargeOffset) {
4379 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4384 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4385 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4389 MCRegister FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4390 MCRegister SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4392 MCRegister LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4393 MCRegister SllReg = IsLargeOffset ? DstReg : ATReg;
4395 TOut.
emitRRI(
Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4396 FirstOffset, IDLoc, STI);
4397 TOut.
emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4398 TOut.
emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4399 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4404bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4405 const MCSubtargetInfo *STI) {
4406 if (hasMips32r6() || hasMips64r6()) {
4407 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4410 const MCOperand &DstRegOp = Inst.
getOperand(0);
4411 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4412 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4413 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4414 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4415 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4417 MipsTargetStreamer &TOut = getTargetStreamer();
4418 MCRegister DstReg = DstRegOp.
getReg();
4419 MCRegister SrcReg = SrcRegOp.
getReg();
4420 int64_t OffsetValue = OffsetImmOp.
getImm();
4422 warnIfNoMacro(IDLoc);
4423 MCRegister ATReg = getATReg(IDLoc);
4428 if (IsLargeOffset) {
4429 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4434 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4435 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4439 if (IsLargeOffset) {
4440 TOut.
emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4441 TOut.
emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4442 TOut.
emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4443 TOut.
emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4444 TOut.
emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4445 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4447 TOut.
emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4448 TOut.
emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4449 TOut.
emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4455bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4456 const MCSubtargetInfo *STI) {
4457 if (hasMips32r6() || hasMips64r6()) {
4458 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4461 const MCOperand &DstRegOp = Inst.
getOperand(0);
4462 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4463 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4464 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4465 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4466 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4468 MipsTargetStreamer &TOut = getTargetStreamer();
4469 MCRegister DstReg = DstRegOp.
getReg();
4470 MCRegister SrcReg = SrcRegOp.
getReg();
4471 int64_t OffsetValue = OffsetImmOp.
getImm();
4475 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4476 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4480 bool IsLoadInst = (Inst.
getOpcode() == Mips::Ulw);
4481 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4482 MCRegister TmpReg = SrcReg;
4483 if (IsLargeOffset || DoMove) {
4484 warnIfNoMacro(IDLoc);
4485 TmpReg = getATReg(IDLoc);
4490 if (IsLargeOffset) {
4491 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4499 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4500 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4501 TOut.
emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4502 TOut.
emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4505 TOut.
emitRRR(Mips::OR, TmpReg, DstReg, Mips::R0, IDLoc, STI);
4510bool MipsAsmParser::expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4511 const MCSubtargetInfo *STI) {
4512 MipsTargetStreamer &TOut = getTargetStreamer();
4524 warnIfNoMacro(IDLoc);
4538 TOut.
emitRRR(OpCode, DstReg, SrcReg, OpReg, IDLoc, STI);
4539 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4544bool MipsAsmParser::expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4545 const MCSubtargetInfo *STI) {
4546 MipsTargetStreamer &TOut = getTargetStreamer();
4556 unsigned OpRegCode, OpImmCode;
4558 warnIfNoMacro(IDLoc);
4562 case Mips::SGEImm64:
4563 OpRegCode = Mips::SLT;
4564 OpImmCode = Mips::SLTi;
4567 case Mips::SGEUImm64:
4568 OpRegCode = Mips::SLTu;
4569 OpImmCode = Mips::SLTiu;
4578 TOut.
emitRRI(OpImmCode, DstReg, SrcReg, ImmValue, IDLoc, STI);
4579 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4581 MCRegister ImmReg = DstReg;
4582 if (DstReg == SrcReg) {
4583 MCRegister ATReg = getATReg(Inst.
getLoc());
4589 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
4590 false, IDLoc, Out, STI))
4593 TOut.
emitRRR(OpRegCode, DstReg, SrcReg, ImmReg, IDLoc, STI);
4594 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4600bool MipsAsmParser::expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4601 const MCSubtargetInfo *STI) {
4602 MipsTargetStreamer &TOut = getTargetStreamer();
4611 MCRegister ImmReg = DstReg;
4615 warnIfNoMacro(IDLoc);
4619 case Mips::SGTImm64:
4623 case Mips::SGTUImm64:
4630 if (DstReg == SrcReg) {
4631 MCRegister ATReg = getATReg(Inst.
getLoc());
4637 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
false,
4642 TOut.
emitRRR(OpCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4647bool MipsAsmParser::expandSle(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4648 const MCSubtargetInfo *STI) {
4649 MipsTargetStreamer &TOut = getTargetStreamer();
4661 warnIfNoMacro(IDLoc);
4675 TOut.
emitRRR(OpCode, DstReg, OpReg, SrcReg, IDLoc, STI);
4676 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4681bool MipsAsmParser::expandSleImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4682 const MCSubtargetInfo *STI) {
4683 MipsTargetStreamer &TOut = getTargetStreamer();
4695 warnIfNoMacro(IDLoc);
4699 case Mips::SLEImm64:
4700 OpRegCode = Mips::SLT;
4703 case Mips::SLEUImm64:
4704 OpRegCode = Mips::SLTu;
4711 MCRegister ImmReg = DstReg;
4712 if (DstReg == SrcReg) {
4713 MCRegister ATReg = getATReg(Inst.
getLoc());
4719 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
false,
4723 TOut.
emitRRR(OpRegCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4724 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4729bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
4731 const MCSubtargetInfo *STI) {
4732 MipsTargetStreamer &TOut = getTargetStreamer();
4740 MCRegister FinalDstReg;
4747 unsigned FinalOpcode = Inst.
getOpcode();
4749 if (DstReg == SrcReg) {
4750 ATReg = getATReg(Inst.
getLoc());
4753 FinalDstReg = DstReg;
4757 if (!loadImmediate(ImmValue, DstReg, MCRegister(), Is32Bit,
false,
4758 Inst.
getLoc(), Out, STI)) {
4759 switch (FinalOpcode) {
4763 FinalOpcode = Mips::ADD;
4766 FinalOpcode = Mips::ADDu;
4769 FinalOpcode = Mips::AND;
4772 FinalOpcode = Mips::NOR;
4775 FinalOpcode = Mips::OR;
4778 FinalOpcode = Mips::SLT;
4781 FinalOpcode = Mips::SLTu;
4784 FinalOpcode = Mips::XOR;
4787 FinalOpcode = Mips::ADD_MM;
4789 case Mips::ADDiu_MM:
4790 FinalOpcode = Mips::ADDu_MM;
4793 FinalOpcode = Mips::AND_MM;
4796 FinalOpcode = Mips::OR_MM;
4799 FinalOpcode = Mips::SLT_MM;
4801 case Mips::SLTiu_MM:
4802 FinalOpcode = Mips::SLTu_MM;
4805 FinalOpcode = Mips::XOR_MM;
4808 FinalOpcode = Mips::AND64;
4810 case Mips::NORImm64:
4811 FinalOpcode = Mips::NOR64;
4814 FinalOpcode = Mips::OR64;
4816 case Mips::SLTImm64:
4817 FinalOpcode = Mips::SLT64;
4819 case Mips::SLTUImm64:
4820 FinalOpcode = Mips::SLTu64;
4823 FinalOpcode = Mips::XOR64;
4828 TOut.
emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4830 TOut.
emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4836bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4837 const MCSubtargetInfo *STI) {
4838 MipsTargetStreamer &TOut = getTargetStreamer();
4843 MCRegister TmpReg =
DReg;
4845 unsigned FirstShift = Mips::NOP;
4846 unsigned SecondShift = Mips::NOP;
4848 if (hasMips32r2()) {
4850 TmpReg = getATReg(Inst.
getLoc());
4856 TOut.
emitRRR(Mips::SUBu, TmpReg, Mips::R0, TReg, Inst.
getLoc(), STI);
4857 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
4862 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
4874 FirstShift = Mips::SRLV;
4875 SecondShift = Mips::SLLV;
4878 FirstShift = Mips::SLLV;
4879 SecondShift = Mips::SRLV;
4883 ATReg = getATReg(Inst.
getLoc());
4887 TOut.
emitRRR(Mips::SUBu, ATReg, Mips::R0, TReg, Inst.
getLoc(), STI);
4888 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
4889 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
4890 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
4898bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
4900 const MCSubtargetInfo *STI) {
4901 MipsTargetStreamer &TOut = getTargetStreamer();
4907 unsigned FirstShift = Mips::NOP;
4908 unsigned SecondShift = Mips::NOP;
4910 if (hasMips32r2()) {
4915 ShiftValue = MaxShift - ImmValue;
4916 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
4921 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.
getLoc(), STI);
4929 if (ImmValue == 0) {
4938 FirstShift = Mips::SLL;
4939 SecondShift = Mips::SRL;
4942 FirstShift = Mips::SRL;
4943 SecondShift = Mips::SLL;
4947 ATReg = getATReg(Inst.
getLoc());
4951 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.
getLoc(), STI);
4952 TOut.
emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.
getLoc(), STI);
4953 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
4961bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4962 const MCSubtargetInfo *STI) {
4963 MipsTargetStreamer &TOut = getTargetStreamer();
4968 MCRegister TmpReg =
DReg;
4970 unsigned FirstShift = Mips::NOP;
4971 unsigned SecondShift = Mips::NOP;
4973 if (hasMips64r2()) {
4974 if (TmpReg == SReg) {
4975 TmpReg = getATReg(Inst.
getLoc());
4981 TOut.
emitRRR(Mips::DSUBu, TmpReg, Mips::R0, TReg, Inst.
getLoc(), STI);
4982 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
4987 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
4999 FirstShift = Mips::DSRLV;
5000 SecondShift = Mips::DSLLV;
5003 FirstShift = Mips::DSLLV;
5004 SecondShift = Mips::DSRLV;
5008 ATReg = getATReg(Inst.
getLoc());
5012 TOut.
emitRRR(Mips::DSUBu, ATReg, Mips::R0, TReg, Inst.
getLoc(), STI);
5013 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
5014 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
5015 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5023bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
5025 const MCSubtargetInfo *STI) {
5026 MipsTargetStreamer &TOut = getTargetStreamer();
5032 unsigned FirstShift = Mips::NOP;
5033 unsigned SecondShift = Mips::NOP;
5037 if (hasMips64r2()) {
5038 unsigned FinalOpcode = Mips::NOP;
5040 FinalOpcode = Mips::DROTR;
5041 else if (ImmValue % 32 == 0)
5042 FinalOpcode = Mips::DROTR32;
5043 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
5045 FinalOpcode = Mips::DROTR32;
5047 FinalOpcode = Mips::DROTR;
5048 }
else if (ImmValue >= 33) {
5050 FinalOpcode = Mips::DROTR;
5052 FinalOpcode = Mips::DROTR32;
5055 uint64_t ShiftValue = ImmValue % 32;
5057 ShiftValue = (32 - ImmValue % 32) % 32;
5059 TOut.
emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
5065 if (ImmValue == 0) {
5066 TOut.
emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.
getLoc(), STI);
5074 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5075 FirstShift = Mips::DSLL;
5076 SecondShift = Mips::DSRL32;
5078 if (ImmValue == 32) {
5079 FirstShift = Mips::DSLL32;
5080 SecondShift = Mips::DSRL32;
5082 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5083 FirstShift = Mips::DSLL32;
5084 SecondShift = Mips::DSRL;
5088 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5089 FirstShift = Mips::DSRL;
5090 SecondShift = Mips::DSLL32;
5092 if (ImmValue == 32) {
5093 FirstShift = Mips::DSRL32;
5094 SecondShift = Mips::DSLL32;
5096 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5097 FirstShift = Mips::DSRL32;
5098 SecondShift = Mips::DSLL;
5103 ATReg = getATReg(Inst.
getLoc());
5107 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.
getLoc(), STI);
5108 TOut.
emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
5110 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5118bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5119 const MCSubtargetInfo *STI) {
5120 MipsTargetStreamer &TOut = getTargetStreamer();
5124 TOut.
emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
5125 if (FirstRegOp != SecondRegOp)
5126 TOut.
emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::R0, IDLoc, STI);
5129 TOut.
emitRRR(Mips::SUB, FirstRegOp, Mips::R0, SecondRegOp, IDLoc, STI);
5134bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5135 const MCSubtargetInfo *STI) {
5136 MipsTargetStreamer &TOut = getTargetStreamer();
5142 ATReg = getATReg(IDLoc);
5146 loadImmediate(ImmValue, ATReg, MCRegister(),
true,
false, IDLoc, Out, STI);
5148 TOut.
emitRR(Inst.
getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
5149 SrcReg, ATReg, IDLoc, STI);
5151 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5156bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5157 const MCSubtargetInfo *STI) {
5158 MipsTargetStreamer &TOut = getTargetStreamer();
5164 ATReg = getATReg(Inst.
getLoc());
5168 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
5169 SrcReg, TmpReg, IDLoc, STI);
5171 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5173 TOut.
emitRRI(Inst.
getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
5174 DstReg, DstReg, 0x1F, IDLoc, STI);
5176 TOut.
emitR(Mips::MFHI, ATReg, IDLoc, STI);
5179 TOut.
emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
5186 TOut.
emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
5187 if (AssemblerOptions.
back()->isReorder())
5189 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5193 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5198bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5199 const MCSubtargetInfo *STI) {
5200 MipsTargetStreamer &TOut = getTargetStreamer();
5206 ATReg = getATReg(IDLoc);
5210 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
5211 SrcReg, TmpReg, IDLoc, STI);
5213 TOut.
emitR(Mips::MFHI, ATReg, IDLoc, STI);
5214 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5216 TOut.
emitRRI(Mips::TNE, ATReg, Mips::R0, 6, IDLoc, STI);
5223 TOut.
emitRRX(Mips::BEQ, ATReg, Mips::R0, LabelOp, IDLoc, STI);
5224 if (AssemblerOptions.
back()->isReorder())
5226 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5234bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5235 const MCSubtargetInfo *STI) {
5236 MipsTargetStreamer &TOut = getTargetStreamer();
5241 TOut.
emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
5242 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5252bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
5254 const MCSubtargetInfo *STI,
5259 warnIfNoMacro(IDLoc);
5261 MipsTargetStreamer &TOut = getTargetStreamer();
5262 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
5264 MCRegister SecondReg =
nextReg(FirstReg);
5269 warnIfRegIndexIsAT(FirstReg, IDLoc);
5272 "Offset for load macro is not immediate!");
5275 signed NextOffset = FirstOffset.
getImm() + 4;
5283 if (FirstReg != BaseReg || !IsLoad) {
5284 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5285 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5287 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5288 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5300bool MipsAsmParser::expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc,
5302 const MCSubtargetInfo *STI) {
5306 warnIfNoMacro(IDLoc);
5308 MipsTargetStreamer &TOut = getTargetStreamer();
5309 unsigned Opcode = Mips::SWC1;
5311 MCRegister SecondReg =
nextReg(FirstReg);
5316 warnIfRegIndexIsAT(FirstReg, IDLoc);
5319 "Offset for macro is not immediate!");
5322 signed NextOffset = FirstOffset.
getImm() + 4;
5328 if (!IsLittleEndian)
5331 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5332 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5337bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5338 const MCSubtargetInfo *STI) {
5339 MipsTargetStreamer &TOut = getTargetStreamer();
5350 warnIfNoMacro(IDLoc);
5352 if (SrcReg != Mips::R0 && OpReg != Mips::R0) {
5353 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5354 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5358 MCRegister
Reg = SrcReg == Mips::R0 ? OpReg : SrcReg;
5359 TOut.
emitRRI(Mips::SLTiu, DstReg,
Reg, 1, IDLoc, STI);
5363bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5364 const MCSubtargetInfo *STI) {
5365 MipsTargetStreamer &TOut = getTargetStreamer();
5376 warnIfNoMacro(IDLoc);
5379 TOut.
emitRRI(Mips::SLTiu, DstReg, SrcReg, 1, IDLoc, STI);
5383 if (SrcReg == Mips::R0) {
5384 Warning(IDLoc,
"comparison is always false");
5385 TOut.
emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
5386 DstReg, SrcReg, SrcReg, IDLoc, STI);
5391 if (
Imm > -0x8000 &&
Imm < 0) {
5393 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5399 MCRegister ATReg = getATReg(IDLoc);
5403 if (loadImmediate(
Imm, ATReg, MCRegister(),
true, isGP64bit(), IDLoc, Out,
5407 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5408 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5413 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5417bool MipsAsmParser::expandSne(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5418 const MCSubtargetInfo *STI) {
5420 MipsTargetStreamer &TOut = getTargetStreamer();
5431 warnIfNoMacro(IDLoc);
5433 if (SrcReg != Mips::R0 && OpReg != Mips::R0) {
5434 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5435 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::R0, DstReg, IDLoc, STI);
5439 MCRegister
Reg = SrcReg == Mips::R0 ? OpReg : SrcReg;
5440 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::R0,
Reg, IDLoc, STI);
5444bool MipsAsmParser::expandSneI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5445 const MCSubtargetInfo *STI) {
5446 MipsTargetStreamer &TOut = getTargetStreamer();
5457 warnIfNoMacro(IDLoc);
5459 if (ImmValue == 0) {
5460 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::R0, SrcReg, IDLoc, STI);
5464 if (SrcReg == Mips::R0) {
5465 Warning(IDLoc,
"comparison is always true");
5466 if (loadImmediate(1, DstReg, MCRegister(),
true,
false, IDLoc, Out, STI))
5472 if (ImmValue > -0x8000 && ImmValue < 0) {
5473 ImmValue = -ImmValue;
5474 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5480 TOut.
emitRRI(
Opc, DstReg, SrcReg, ImmValue, IDLoc, STI);
5481 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::R0, DstReg, IDLoc, STI);
5485 MCRegister ATReg = getATReg(IDLoc);
5489 if (loadImmediate(ImmValue, ATReg, MCRegister(),
isInt<32>(ImmValue),
false,
5493 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5494 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::R0, DstReg, IDLoc, STI);
5700bool MipsAsmParser::expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5701 const MCSubtargetInfo *STI) {
5702 MipsTargetStreamer &TOut = getTargetStreamer();
5707 bool IsMFTR =
false;
5761 IsMFTR ? MCRegister(rd)
5763 : Inst.getOperand(0).
getReg());
5765 TOut.
emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, u, sel, h, IDLoc,
5770bool MipsAsmParser::expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5771 const MCSubtargetInfo *STI) {
5776 warnIfNoMacro(IDLoc);
5778 MipsTargetStreamer &TOut = getTargetStreamer();
5779 unsigned Opcode = Inst.
getOpcode() == Mips::SaaAddr ? Mips::SAA : Mips::SAAD;
5782 const MCOperand &BaseOp = Inst.
getOperand(2);
5784 if (BaseOp.
isImm()) {
5785 int64_t ImmValue = BaseOp.
getImm();
5786 if (ImmValue == 0) {
5787 TOut.
emitRR(Opcode, RtReg, BaseReg, IDLoc, STI);
5792 MCRegister ATReg = getATReg(IDLoc);
5796 if (expandLoadAddress(ATReg, BaseReg, BaseOp, !isGP64bit(), IDLoc, Out, STI))
5799 TOut.
emitRR(Opcode, RtReg, ATReg, IDLoc, STI);
5804MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
5808 return Match_Success;
5811 if (
static_cast<MipsOperand &
>(*
Operands[1])
5812 .isValidForTie(
static_cast<MipsOperand &
>(*
Operands[2])))
5813 return Match_Success;
5814 return Match_RequiresSameSrcAndDst;
5818unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
5825 return Match_RequiresNoZeroRegister;
5826 return Match_Success;
5832 case Mips::JALR_HB64:
5833 case Mips::JALRC_HB_MMR6:
5834 case Mips::JALRC_MMR6:
5836 return Match_RequiresDifferentSrcAndDst;
5837 return Match_Success;
5840 return Match_RequiresDifferentSrcAndDst;
5841 return Match_Success;
5844 return Match_NonZeroOperandForSync;
5845 return Match_Success;
5851 return Match_NonZeroOperandForMTCX;
5852 return Match_Success;
5865 case Mips::BLEZC:
case Mips::BLEZC_MMR6:
5866 case Mips::BGEZC:
case Mips::BGEZC_MMR6:
5867 case Mips::BGTZC:
case Mips::BGTZC_MMR6:
5868 case Mips::BLTZC:
case Mips::BLTZC_MMR6:
5869 case Mips::BEQZC:
case Mips::BEQZC_MMR6:
5870 case Mips::BNEZC:
case Mips::BNEZC_MMR6:
5879 return Match_RequiresNoZeroRegister;
5880 return Match_Success;
5881 case Mips::BGEC:
case Mips::BGEC_MMR6:
5882 case Mips::BLTC:
case Mips::BLTC_MMR6:
5883 case Mips::BGEUC:
case Mips::BGEUC_MMR6:
5884 case Mips::BLTUC:
case Mips::BLTUC_MMR6:
5885 case Mips::BEQC:
case Mips::BEQC_MMR6:
5886 case Mips::BNEC:
case Mips::BNEC_MMR6:
5895 return Match_RequiresNoZeroRegister;
5898 return Match_RequiresNoZeroRegister;
5900 return Match_RequiresDifferentOperands;
5901 return Match_Success;
5904 "Operands must be immediates for dins!");
5907 if ((0 > (Pos +
Size)) || ((Pos +
Size) > 32))
5908 return Match_RequiresPosSizeRange0_32;
5909 return Match_Success;
5914 "Operands must be immediates for dinsm/dinsu!");
5917 if ((32 >= (Pos +
Size)) || ((Pos +
Size) > 64))
5918 return Match_RequiresPosSizeRange33_64;
5919 return Match_Success;
5923 "Operands must be immediates for DEXTM!");
5926 if ((1 > (Pos +
Size)) || ((Pos +
Size) > 63))
5927 return Match_RequiresPosSizeUImm6;
5928 return Match_Success;
5933 "Operands must be immediates for dextm/dextu!");
5936 if ((32 > (Pos +
Size)) || ((Pos +
Size) > 64))
5937 return Match_RequiresPosSizeRange33_64;
5938 return Match_Success;
5940 case Mips::CRC32B:
case Mips::CRC32CB:
5941 case Mips::CRC32H:
case Mips::CRC32CH:
5942 case Mips::CRC32W:
case Mips::CRC32CW:
5943 case Mips::CRC32D:
case Mips::CRC32CD:
5945 return Match_RequiresSameSrcAndDst;
5946 return Match_Success;
5952 return Match_NoFCCRegisterForCurrentISA;
5954 return Match_Success;
5962 if (ErrorLoc ==
SMLoc())
5969bool MipsAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
5973 bool MatchingInlineAsm) {
5975 unsigned MatchResult =
5976 MatchInstructionImpl(
Operands, Inst, ErrorInfo, MatchingInlineAsm);
5978 switch (MatchResult) {
5980 if (processInstruction(Inst, IDLoc, Out, STI))
5983 case Match_MissingFeature:
5984 Error(IDLoc,
"instruction requires a CPU feature not currently enabled");
5986 case Match_InvalidTiedOperand:
5987 Error(IDLoc,
"operand must match destination register");
5989 case Match_InvalidOperand: {
5990 SMLoc ErrorLoc = IDLoc;
5991 if (ErrorInfo != ~0ULL) {
5993 return Error(IDLoc,
"too few operands for instruction");
5995 ErrorLoc =
Operands[ErrorInfo]->getStartLoc();
5997 ErrorLoc =
static_cast<MipsOperand &
>(*
Operands[ErrorInfo])
6000 if (ErrorLoc == SMLoc())
6004 return Error(ErrorLoc,
"invalid operand for instruction");
6006 case Match_NonZeroOperandForSync:
6008 "s-type must be zero or unspecified for pre-MIPS32 ISAs");
6009 case Match_NonZeroOperandForMTCX:
6010 return Error(IDLoc,
"selector must be zero for pre-MIPS32 ISAs");
6011 case Match_MnemonicFail:
6012 return Error(IDLoc,
"invalid instruction");
6013 case Match_RequiresDifferentSrcAndDst:
6014 return Error(IDLoc,
"source and destination must be different");
6015 case Match_RequiresDifferentOperands:
6016 return Error(IDLoc,
"registers must be different");
6017 case Match_RequiresNoZeroRegister:
6018 return Error(IDLoc,
"invalid operand ($zero) for instruction");
6019 case Match_RequiresSameSrcAndDst:
6020 return Error(IDLoc,
"source and destination must match");
6021 case Match_NoFCCRegisterForCurrentISA:
6023 "non-zero fcc register doesn't exist in current ISA level");
6028 "expected 1-bit unsigned immediate");
6031 "expected 2-bit unsigned immediate");
6034 "expected immediate in range 1 .. 4");
6037 "expected 3-bit unsigned immediate");
6040 "expected 4-bit unsigned immediate");
6043 "expected 4-bit signed immediate");
6046 "expected 5-bit unsigned immediate");
6049 "expected 5-bit signed immediate");
6052 "expected immediate in range 1 .. 32");
6053 case Match_UImm5_32:
6055 "expected immediate in range 32 .. 63");
6056 case Match_UImm5_33:
6058 "expected immediate in range 33 .. 64");
6059 case Match_UImm5_0_Report_UImm6:
6063 "expected 6-bit unsigned immediate");
6064 case Match_ConstantMemOffset:
6066 !
static_cast<MipsOperand &
>(*
Operands[ErrorInfo]).isConstantImm())
6068 "expected immediate operand kind");
6070 "immediate operand value out of range");
6071 case Match_UImm5_Lsl2:
6073 "expected both 7-bit unsigned immediate and multiple of 4");
6074 case Match_UImmRange2_64:
6076 "expected immediate in range 2 .. 64");
6079 "expected 6-bit unsigned immediate");
6080 case Match_UImm6_Lsl2:
6082 "expected both 8-bit unsigned immediate and multiple of 4");
6085 "expected 6-bit signed immediate");
6088 "expected 7-bit unsigned immediate");
6089 case Match_UImm7_N1:
6091 "expected immediate in range -1 .. 126");
6092 case Match_SImm7_Lsl2:
6094 "expected both 9-bit signed immediate and multiple of 4");
6097 "expected 8-bit unsigned immediate");
6098 case Match_UImm10_0:
6100 "expected 10-bit unsigned immediate");
6101 case Match_SImm10_0:
6103 "expected 10-bit signed immediate");
6104 case Match_SImm11_0:
6106 "expected 11-bit signed immediate");
6108 case Match_UImm16_Relaxed:
6109 case Match_UImm16_AltRelaxed:
6111 "expected 16-bit unsigned immediate");
6113 case Match_SImm16_Relaxed:
6115 "expected 16-bit signed immediate");
6116 case Match_SImm18_Lsl3:
6118 "expected both 18-bit signed immediate and multiple of 8");
6119 case Match_SImm19_Lsl2:
6121 "expected both 19-bit signed immediate and multiple of 4");
6122 case Match_UImm20_0:
6124 "expected 20-bit unsigned immediate");
6125 case Match_UImm26_0:
6127 "expected 26-bit unsigned immediate");
6129 case Match_SImm32_Relaxed:
6131 "expected 32-bit signed immediate");
6132 case Match_UImm32_Coerced:
6134 "expected 32-bit immediate");
6135 case Match_MemSImm9:
6137 "expected memory with 9-bit signed offset");
6138 case Match_MemSImm10:
6140 "expected memory with 10-bit signed offset");
6141 case Match_MemSImm10Lsl1:
6143 "expected memory with 11-bit signed offset and multiple of 2");
6144 case Match_MemSImm10Lsl2:
6146 "expected memory with 12-bit signed offset and multiple of 4");
6147 case Match_MemSImm10Lsl3:
6149 "expected memory with 13-bit signed offset and multiple of 8");
6150 case Match_MemSImm11:
6152 "expected memory with 11-bit signed offset");
6153 case Match_MemSImm12:
6155 "expected memory with 12-bit signed offset");
6156 case Match_MemSImm16:
6158 "expected memory with 16-bit signed offset");
6159 case Match_MemSImmPtr:
6161 "expected memory with 32-bit signed offset");
6162 case Match_RequiresPosSizeRange0_32: {
6163 SMLoc ErrorStart =
Operands[3]->getStartLoc();
6164 SMLoc ErrorEnd =
Operands[4]->getEndLoc();
6165 return Error(ErrorStart,
"size plus position are not in the range 0 .. 32",
6166 SMRange(ErrorStart, ErrorEnd));
6168 case Match_RequiresPosSizeUImm6: {
6169 SMLoc ErrorStart =
Operands[3]->getStartLoc();
6170 SMLoc ErrorEnd =
Operands[4]->getEndLoc();
6171 return Error(ErrorStart,
"size plus position are not in the range 1 .. 63",
6172 SMRange(ErrorStart, ErrorEnd));
6174 case Match_RequiresPosSizeRange33_64: {
6175 SMLoc ErrorStart =
Operands[3]->getStartLoc();
6176 SMLoc ErrorEnd =
Operands[4]->getEndLoc();
6177 return Error(ErrorStart,
"size plus position are not in the range 33 .. 64",
6178 SMRange(ErrorStart, ErrorEnd));
6185void MipsAsmParser::warnIfRegIndexIsAT(MCRegister RegIndex, SMLoc Loc) {
6186 if (RegIndex && AssemblerOptions.
back()->getATRegIndex() == RegIndex)
6187 Warning(Loc,
"used $at (currently $" + Twine(RegIndex.
id()) +
6188 ") without \".set noat\"");
6191void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
6192 if (!AssemblerOptions.
back()->isMacro())
6193 Warning(Loc,
"macro instruction expanded into multiple instructions");
6196void MipsAsmParser::ConvertXWPOperands(MCInst &Inst,
6200 "Unexpected instruction!");
6201 ((MipsOperand &)*
Operands[1]).addGPR32ZeroAsmRegOperands(Inst, 1);
6202 MCRegister NextReg =
nextReg(((MipsOperand &)*
Operands[1]).getGPR32Reg());
6204 static_cast<MipsOperand &
>(*
Operands[4]).addPtrRegOperands(Inst, 1);
6205 static_cast<MipsOperand &
>(*
Operands[2]).addImmOperands(Inst, 1);
6209MipsAsmParser::printWarningWithFixIt(
const Twine &
Msg,
const Twine &FixMsg,
6210 SMRange
Range,
bool ShowColors) {
6216int MipsAsmParser::matchCPURegisterName(StringRef Name) {
6217 const MCRegisterInfo &MRI = *
getContext().getRegisterInfo();
6223 AsmToken RegTok = getLexer().peekTok();
6224 StringRef FixedName =
6226 printWarningWithFixIt(
"register names $t4-$t7 are only available in O32.",
6227 "Did you mean $" + FixedName +
"?",
6233int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
6234 const MCRegisterInfo &MRI = *
getContext().getRegisterInfo();
6236 Mips::RegAliasName);
6240int MipsAsmParser::matchFPURegisterName(StringRef Name) {
6241 if (Name[0] ==
'f') {
6242 StringRef NumString =
Name.substr(1);
6253int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
6254 if (
Name.starts_with(
"fcc")) {
6255 StringRef NumString =
Name.substr(3);
6266int MipsAsmParser::matchACRegisterName(StringRef Name) {
6267 if (
Name.starts_with(
"ac")) {
6268 StringRef NumString =
Name.substr(2);
6279int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
6282 if (
Name.front() !=
'w' ||
Name.drop_front(1).getAsInteger(10, IntVal))
6291int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
6292 const MCRegisterInfo &MRI = *
getContext().getRegisterInfo();
6294 Name, MRI, Mips::MSACtrlRegClassID, Mips::RegAliasName);
6298bool MipsAsmParser::canUseATReg() {
6299 return AssemblerOptions.
back()->getATRegIndex() != 0;
6302MCRegister MipsAsmParser::getATReg(SMLoc Loc) {
6303 unsigned ATIndex = AssemblerOptions.
back()->getATRegIndex();
6305 reportParseError(Loc,
6306 "pseudo-instruction requires $at, which is not available");
6310 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
6314MCRegister MipsAsmParser::getReg(
int RC,
int RegNo) {
6315 return getContext().getRegisterInfo()->getRegClass(RC).getRegister(RegNo);
6320bool MipsAsmParser::parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
6322 return getParser().parsePrimaryExpr(Res, EndLoc);
6323 Res = parseRelocExpr();
6324 EndLoc = getLexer().getLoc();
6330const MCExpr *MipsAsmParser::parseRelocExpr() {
6331 auto getOp = [](StringRef
Op) {
6332 return StringSwitch<Mips::Specifier>(
Op)
6360 MCAsmParser &Parser = getParser();
6362 const MCExpr *Res =
nullptr;
6368 auto Op = getOp(Name);
6377 while (
Ops.size()) {
6386 MCAsmParser &Parser = getParser();
6396 ParseStatus Res = MatchOperandParserImpl(
Operands, Mnemonic,
true);
6407 switch (getLexer().getKind()) {
6417 if (!parseAnyRegister(
Operands).isNoMatch())
6430 Operands.push_back(MipsOperand::CreateImm(SymRef, S,
E, *
this));
6435 const MCExpr *Expr = parseRelocExpr();
6439 Operands.push_back(MipsOperand::CreateImm(Expr, S,
E, *
this));
6446bool MipsAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
6448 return !tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess();
6451ParseStatus MipsAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
6454 ParseStatus Res = parseAnyRegister(
Operands);
6457 MipsOperand &Operand =
static_cast<MipsOperand &
>(*
Operands.front());
6458 StartLoc = Operand.getStartLoc();
6459 EndLoc = Operand.getEndLoc();
6465 if (Operand.isGPRAsmReg()) {
6467 Reg = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
6477const MCExpr *MipsAsmParser::parseMemOffset() {
6484 if (getParser().parseExpression(
Offset))
6493 SMLoc S = getLexer().getLoc();
6494 const MCExpr *
Offset = parseMemOffset();
6498 SMLoc
E = getLexer().getLoc();
6510 Operands.push_back(MipsOperand::CreateToken(
"(",
E, *
this));
6511 Operands.push_back(MipsOperand::createGPRReg(
6513 Operands.push_back(MipsOperand::CreateToken(
")",
E, *
this));
6518 MCAsmParser &Parser = getParser();
6520 const MCExpr *
Address = parseMemOffset();
6537 std::unique_ptr<MipsOperand>
Base(
6538 static_cast<MipsOperand *
>(
Operands.back().release()));
6540 E =
Base->getEndLoc();
6542 MipsOperand::CreateMem(std::move(
Base),
Address, S,
E, *
this));
6547 MCAsmParser &Parser = getParser();
6556 const MCSymbolRefExpr *
Ref =
static_cast<const MCSymbolRefExpr *
>(Expr);
6557 StringRef DefSymbol =
Ref->getSymbol().getName();
6560 matchAnyRegisterNameWithoutDollar(
Operands, DefSymbol.
substr(1), S);
6574 if (Entry != RegisterSets.
end()) {
6576 matchAnyRegisterWithoutDollar(
Operands,
Entry->getValue(), S);
6587ParseStatus MipsAsmParser::matchAnyRegisterNameWithoutDollar(
6589 int Index = matchCPURegisterName(Identifier);
6591 Operands.push_back(MipsOperand::createGPRReg(
6592 Index, Identifier,
getContext().getRegisterInfo(), S,
6593 getLexer().getLoc(), *
this));
6597 Index = matchHWRegsRegisterName(Identifier);
6599 Operands.push_back(MipsOperand::createHWRegsReg(
6600 Index, Identifier,
getContext().getRegisterInfo(), S,
6601 getLexer().getLoc(), *
this));
6605 Index = matchFPURegisterName(Identifier);
6607 Operands.push_back(MipsOperand::createFGRReg(
6608 Index, Identifier,
getContext().getRegisterInfo(), S,
6609 getLexer().getLoc(), *
this));
6613 Index = matchFCCRegisterName(Identifier);
6615 Operands.push_back(MipsOperand::createFCCReg(
6616 Index, Identifier,
getContext().getRegisterInfo(), S,
6617 getLexer().getLoc(), *
this));
6621 Index = matchACRegisterName(Identifier);
6623 Operands.push_back(MipsOperand::createACCReg(
6624 Index, Identifier,
getContext().getRegisterInfo(), S,
6625 getLexer().getLoc(), *
this));
6629 Index = matchMSA128RegisterName(Identifier);
6631 Operands.push_back(MipsOperand::createMSA128Reg(
6632 Index, Identifier,
getContext().getRegisterInfo(), S,
6633 getLexer().getLoc(), *
this));
6637 Index = matchMSA128CtrlRegisterName(Identifier);
6639 Operands.push_back(MipsOperand::createMSACtrlReg(
6640 Index, Identifier,
getContext().getRegisterInfo(), S,
6641 getLexer().getLoc(), *
this));
6650 const AsmToken &Token, SMLoc S) {
6654 return matchAnyRegisterNameWithoutDollar(
Operands, Identifier, S);
6659 if (RegNum < 0 || RegNum > 31) {
6663 Error(getLexer().getLoc(),
"invalid register number");
6665 Operands.push_back(MipsOperand::createNumericReg(
6678 auto Token = getLexer().peekTok(
false);
6679 return matchAnyRegisterWithoutDollar(
Operands, Token, S);
6683 MCAsmParser &Parser = getParser();
6686 auto Token = Parser.
getTok();
6688 SMLoc S = Token.
getLoc();
6701 ParseStatus Res = matchAnyRegisterWithoutDollar(
Operands, S);
6710 MCAsmParser &Parser = getParser();
6713 SMLoc S = getLexer().getLoc();
6716 ParseStatus Res = parseAnyRegister(
Operands);
6721 const MCExpr *Expr =
nullptr;
6727 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *
this));
6732 MCAsmParser &Parser = getParser();
6733 const MCExpr *IdVal;
6744 if (getParser().parseExpression(IdVal))
6751 Operands.push_back(MipsOperand::CreateImm(
6757 MCAsmParser &Parser = getParser();
6761 bool RegRange =
false;
6768 while (parseAnyRegister(TmpOperands).isSuccess()) {
6769 SMLoc
E = getLexer().getLoc();
6770 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*TmpOperands.
back());
6771 Reg = isGP64bit() ? RegOpnd.getGPR64Reg() : RegOpnd.getGPR32Reg();
6779 MCRegister TmpReg = PrevReg + 1;
6780 while (TmpReg <=
Reg) {
6781 if ((((TmpReg < Mips::R16) || (TmpReg > Mips::R23)) &&
6783 (((TmpReg < Mips::R16_64) || (TmpReg > Mips::R23_64)) &&
6785 return Error(
E,
"invalid register operand");
6789 TmpReg = TmpReg.
id() + 1;
6798 return Error(
E,
"$16 or $31 expected");
6800 (
Reg >= Mips::R16 &&
Reg <= Mips::R23)) &&
6803 (
Reg >= Mips::R16_64 &&
Reg <= Mips::R23_64)) &&
6805 return Error(
E,
"invalid register operand");
6806 if (PrevReg.
isValid() && (
Reg != PrevReg + 1) &&
6809 return Error(
E,
"consecutive register numbers expected");
6819 return Error(
E,
"',' or '-' expected");
6829 Operands.push_back(MipsOperand::CreateRegList(Regs, S,
E, *
this));
6830 return parseMemOffsetOperand(
Operands);
6839 MCAsmParser &Parser = getParser();
6842 MipsOperand::CreateToken(
"(", getLexer().getLoc(), *
this));
6844 if (parseOperand(
Operands, Name)) {
6845 SMLoc Loc = getLexer().getLoc();
6846 return Error(Loc,
"unexpected token in argument list");
6849 SMLoc Loc = getLexer().getLoc();
6850 return Error(Loc,
"unexpected token, expected ')'");
6853 MipsOperand::CreateToken(
")", getLexer().getLoc(), *
this));
6865bool MipsAsmParser::parseBracketSuffix(StringRef Name,
6867 MCAsmParser &Parser = getParser();
6870 MipsOperand::CreateToken(
"[", getLexer().getLoc(), *
this));
6872 if (parseOperand(
Operands, Name)) {
6873 SMLoc Loc = getLexer().getLoc();
6874 return Error(Loc,
"unexpected token in argument list");
6877 SMLoc Loc = getLexer().getLoc();
6878 return Error(Loc,
"unexpected token, expected ']'");
6881 MipsOperand::CreateToken(
"]", getLexer().getLoc(), *
this));
6888 unsigned VariantID = 0);
6903bool MipsAsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
6905 MCAsmParser &Parser = getParser();
6909 getTargetStreamer().forbidModuleDirective();
6912 if (!mnemonicIsValid(Name, 0)) {
6913 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
6915 return Error(NameLoc,
"unknown instruction" + Suggestion);
6918 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *
this));
6923 bool IsFirstOperand =
Operands.size() == 1;
6925 if (parseOperand(
Operands, Name)) {
6926 SMLoc Loc = getLexer().getLoc();
6927 return Error(Loc,
"unexpected token in argument list");
6932 if (parseBracketSuffix(Name,
Operands))
6940 SMLoc Loc = getLexer().getLoc();
6941 return Error(Loc,
"unexpected token in argument list");
6949bool MipsAsmParser::reportParseError(
const Twine &ErrorMsg) {
6950 SMLoc Loc = getLexer().getLoc();
6951 return Error(Loc, ErrorMsg);
6954bool MipsAsmParser::reportParseError(SMLoc Loc,
const Twine &ErrorMsg) {
6955 return Error(Loc, ErrorMsg);
6958bool MipsAsmParser::parseSetNoAtDirective() {
6959 MCAsmParser &Parser = getParser();
6963 AssemblerOptions.
back()->setATRegIndex(0);
6969 reportParseError(
"unexpected token, expected end of statement");
6973 getTargetStreamer().emitDirectiveSetNoAt();
6978bool MipsAsmParser::parseSetAtDirective() {
6981 MCAsmParser &Parser = getParser();
6986 AssemblerOptions.
back()->setATRegIndex(1);
6988 getTargetStreamer().emitDirectiveSetAt();
6994 reportParseError(
"unexpected token, expected equals sign");
7001 reportParseError(
"no register specified");
7004 reportParseError(
"unexpected token, expected dollar sign '$'");
7014 AtRegNo = matchCPURegisterName(
Reg.getIdentifier());
7016 AtRegNo =
Reg.getIntVal();
7018 reportParseError(
"unexpected token, expected identifier or integer");
7023 if (!AssemblerOptions.
back()->setATRegIndex(AtRegNo)) {
7024 reportParseError(
"invalid register");
7031 reportParseError(
"unexpected token, expected end of statement");
7035 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
7041bool MipsAsmParser::parseSetReorderDirective() {
7042 MCAsmParser &Parser = getParser();
7046 reportParseError(
"unexpected token, expected end of statement");
7049 AssemblerOptions.
back()->setReorder();
7050 getTargetStreamer().emitDirectiveSetReorder();
7055bool MipsAsmParser::parseSetNoReorderDirective() {
7056 MCAsmParser &Parser = getParser();
7060 reportParseError(
"unexpected token, expected end of statement");
7063 AssemblerOptions.
back()->setNoReorder();
7064 getTargetStreamer().emitDirectiveSetNoReorder();
7069bool MipsAsmParser::parseSetMacroDirective() {
7070 MCAsmParser &Parser = getParser();
7074 reportParseError(
"unexpected token, expected end of statement");
7077 AssemblerOptions.
back()->setMacro();
7078 getTargetStreamer().emitDirectiveSetMacro();
7083bool MipsAsmParser::parseSetNoMacroDirective() {
7084 MCAsmParser &Parser = getParser();
7088 reportParseError(
"unexpected token, expected end of statement");
7091 if (AssemblerOptions.
back()->isReorder()) {
7092 reportParseError(
"`noreorder' must be set before `nomacro'");
7095 AssemblerOptions.
back()->setNoMacro();
7096 getTargetStreamer().emitDirectiveSetNoMacro();
7101bool MipsAsmParser::parseSetMsaDirective() {
7102 MCAsmParser &Parser = getParser();
7107 return reportParseError(
"unexpected token, expected end of statement");
7109 setFeatureBits(Mips::FeatureMSA,
"msa");
7110 getTargetStreamer().emitDirectiveSetMsa();
7114bool MipsAsmParser::parseSetNoMsaDirective() {
7115 MCAsmParser &Parser = getParser();
7120 return reportParseError(
"unexpected token, expected end of statement");
7122 clearFeatureBits(Mips::FeatureMSA,
"msa");
7123 getTargetStreamer().emitDirectiveSetNoMsa();
7127bool MipsAsmParser::parseSetNoDspDirective() {
7128 MCAsmParser &Parser = getParser();
7133 reportParseError(
"unexpected token, expected end of statement");
7137 clearFeatureBits(Mips::FeatureDSP,
"dsp");
7138 getTargetStreamer().emitDirectiveSetNoDsp();
7142bool MipsAsmParser::parseSetNoMips3DDirective() {
7143 MCAsmParser &Parser = getParser();
7148 reportParseError(
"unexpected token, expected end of statement");
7152 clearFeatureBits(Mips::FeatureMips3D,
"mips3d");
7153 getTargetStreamer().emitDirectiveSetNoMips3D();
7157bool MipsAsmParser::parseSetMips16Directive() {
7158 MCAsmParser &Parser = getParser();
7163 reportParseError(
"unexpected token, expected end of statement");
7167 clearFeatureBits(Mips::FeatureMicroMips,
"micromips");
7168 setFeatureBits(Mips::FeatureMips16,
"mips16");
7169 getTargetStreamer().emitDirectiveSetMips16();
7174bool MipsAsmParser::parseSetNoMips16Directive() {
7175 MCAsmParser &Parser = getParser();
7180 reportParseError(
"unexpected token, expected end of statement");
7184 clearFeatureBits(Mips::FeatureMips16,
"mips16");
7185 getTargetStreamer().emitDirectiveSetNoMips16();
7190bool MipsAsmParser::parseSetFpDirective() {
7191 MCAsmParser &Parser = getParser();
7197 AsmToken Tok = Parser.
getTok();
7199 reportParseError(
"unexpected token, expected equals sign '='");
7205 if (!parseFpABIValue(FpAbiVal,
".set"))
7209 reportParseError(
"unexpected token, expected end of statement");
7212 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
7217bool MipsAsmParser::parseSetOddSPRegDirective() {
7218 MCAsmParser &Parser = getParser();
7222 reportParseError(
"unexpected token, expected end of statement");
7226 clearFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
7227 getTargetStreamer().emitDirectiveSetOddSPReg();
7231bool MipsAsmParser::parseSetNoOddSPRegDirective() {
7232 MCAsmParser &Parser = getParser();
7236 reportParseError(
"unexpected token, expected end of statement");
7240 setFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
7241 getTargetStreamer().emitDirectiveSetNoOddSPReg();
7245bool MipsAsmParser::parseSetMtDirective() {
7246 MCAsmParser &Parser = getParser();
7251 reportParseError(
"unexpected token, expected end of statement");
7255 setFeatureBits(Mips::FeatureMT,
"mt");
7256 getTargetStreamer().emitDirectiveSetMt();
7261bool MipsAsmParser::parseSetNoMtDirective() {
7262 MCAsmParser &Parser = getParser();
7267 reportParseError(
"unexpected token, expected end of statement");
7271 clearFeatureBits(Mips::FeatureMT,
"mt");
7273 getTargetStreamer().emitDirectiveSetNoMt();
7278bool MipsAsmParser::parseSetNoCRCDirective() {
7279 MCAsmParser &Parser = getParser();
7284 reportParseError(
"unexpected token, expected end of statement");
7288 clearFeatureBits(Mips::FeatureCRC,
"crc");
7290 getTargetStreamer().emitDirectiveSetNoCRC();
7295bool MipsAsmParser::parseSetNoVirtDirective() {
7296 MCAsmParser &Parser = getParser();
7301 reportParseError(
"unexpected token, expected end of statement");
7305 clearFeatureBits(Mips::FeatureVirt,
"virt");
7307 getTargetStreamer().emitDirectiveSetNoVirt();
7312bool MipsAsmParser::parseSetNoGINVDirective() {
7313 MCAsmParser &Parser = getParser();
7318 reportParseError(
"unexpected token, expected end of statement");
7322 clearFeatureBits(Mips::FeatureGINV,
"ginv");
7324 getTargetStreamer().emitDirectiveSetNoGINV();
7329bool MipsAsmParser::parseSetNoEVADirective() {
7330 MCAsmParser &Parser = getParser();
7335 reportParseError(
"unexpected token, expected end of statement");
7339 clearFeatureBits(Mips::FeatureEVA,
"eva");
7341 getTargetStreamer().emitDirectiveSetNoEVA();
7346bool MipsAsmParser::parseSetPopDirective() {
7347 MCAsmParser &Parser = getParser();
7348 SMLoc Loc = getLexer().getLoc();
7352 return reportParseError(
"unexpected token, expected end of statement");
7356 if (AssemblerOptions.
size() == 2)
7357 return reportParseError(Loc,
".set pop with no .set push");
7359 MCSubtargetInfo &STI = copySTI();
7361 setAvailableFeatures(
7362 ComputeAvailableFeatures(AssemblerOptions.
back()->getFeatures()));
7365 getTargetStreamer().emitDirectiveSetPop();
7369bool MipsAsmParser::parseSetPushDirective() {
7370 MCAsmParser &Parser = getParser();
7373 return reportParseError(
"unexpected token, expected end of statement");
7377 std::make_unique<MipsAssemblerOptions>(AssemblerOptions.
back().get()));
7379 getTargetStreamer().emitDirectiveSetPush();
7383bool MipsAsmParser::parseSetSoftFloatDirective() {
7384 MCAsmParser &Parser = getParser();
7387 return reportParseError(
"unexpected token, expected end of statement");
7389 setFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
7390 getTargetStreamer().emitDirectiveSetSoftFloat();
7394bool MipsAsmParser::parseSetHardFloatDirective() {
7395 MCAsmParser &Parser = getParser();
7398 return reportParseError(
"unexpected token, expected end of statement");
7400 clearFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
7401 getTargetStreamer().emitDirectiveSetHardFloat();
7405bool MipsAsmParser::parseSetAssignment() {
7407 MCAsmParser &Parser = getParser();
7410 return reportParseError(
"expected identifier after .set");
7413 return reportParseError(
"unexpected token, expected comma");
7428 const MCExpr *
Value;
7430 Parser, Sym,
Value))
7432 getStreamer().emitAssignment(Sym,
Value);
7437bool MipsAsmParser::parseSetMips0Directive() {
7438 MCAsmParser &Parser = getParser();
7441 return reportParseError(
"unexpected token, expected end of statement");
7444 MCSubtargetInfo &STI = copySTI();
7445 setAvailableFeatures(
7446 ComputeAvailableFeatures(AssemblerOptions.
front()->getFeatures()));
7448 AssemblerOptions.
back()->setFeatures(AssemblerOptions.
front()->getFeatures());
7450 getTargetStreamer().emitDirectiveSetMips0();
7454bool MipsAsmParser::parseSetArchDirective() {
7455 MCAsmParser &Parser = getParser();
7458 return reportParseError(
"unexpected token, expected equals sign");
7461 StringRef Arch = getParser().parseStringToEndOfStatement().trim();
7463 return reportParseError(
"expected arch identifier");
7465 StringRef ArchFeatureName =
7466 StringSwitch<StringRef>(Arch)
7467 .Case(
"mips1",
"mips1")
7468 .Case(
"mips2",
"mips2")
7469 .Case(
"mips3",
"mips3")
7470 .Case(
"mips4",
"mips4")
7471 .Case(
"mips5",
"mips5")
7472 .Case(
"mips32",
"mips32")
7473 .Case(
"mips32r2",
"mips32r2")
7474 .Case(
"mips32r3",
"mips32r3")
7475 .Case(
"mips32r5",
"mips32r5")
7476 .Case(
"mips32r6",
"mips32r6")
7477 .Case(
"mips64",
"mips64")
7478 .Case(
"mips64r2",
"mips64r2")
7479 .Case(
"mips64r3",
"mips64r3")
7480 .Case(
"mips64r5",
"mips64r5")
7481 .Case(
"mips64r6",
"mips64r6")
7482 .Case(
"octeon",
"cnmips")
7483 .Case(
"octeon+",
"cnmipsp")
7484 .Case(
"r4000",
"mips3")
7487 if (ArchFeatureName.
empty())
7488 return reportParseError(
"unsupported architecture");
7490 if (ArchFeatureName ==
"mips64r6" && inMicroMipsMode())
7491 return reportParseError(
"mips64r6 does not support microMIPS");
7493 selectArch(ArchFeatureName);
7494 getTargetStreamer().emitDirectiveSetArch(Arch);
7498bool MipsAsmParser::parseSetFeature(
uint64_t Feature) {
7499 MCAsmParser &Parser = getParser();
7502 return reportParseError(
"unexpected token, expected end of statement");
7507 case Mips::FeatureMips3D:
7508 setFeatureBits(Mips::FeatureMips3D,
"mips3d");
7509 getTargetStreamer().emitDirectiveSetMips3D();
7511 case Mips::FeatureDSP:
7512 setFeatureBits(Mips::FeatureDSP,
"dsp");
7513 getTargetStreamer().emitDirectiveSetDsp();
7515 case Mips::FeatureDSPR2:
7516 setFeatureBits(Mips::FeatureDSPR2,
"dspr2");
7517 getTargetStreamer().emitDirectiveSetDspr2();
7519 case Mips::FeatureMicroMips:
7520 clearFeatureBits(Mips::FeatureMips16,
"mips16");
7521 setFeatureBits(Mips::FeatureMicroMips,
"micromips");
7522 getTargetStreamer().emitDirectiveSetMicroMips();
7524 case Mips::FeatureMips1:
7525 selectArch(
"mips1");
7526 getTargetStreamer().emitDirectiveSetMips1();
7528 case Mips::FeatureMips2:
7529 selectArch(
"mips2");
7530 getTargetStreamer().emitDirectiveSetMips2();
7532 case Mips::FeatureMips3:
7533 selectArch(
"mips3");
7534 getTargetStreamer().emitDirectiveSetMips3();
7536 case Mips::FeatureMips4:
7537 selectArch(
"mips4");
7538 getTargetStreamer().emitDirectiveSetMips4();
7540 case Mips::FeatureMips5:
7541 selectArch(
"mips5");
7542 getTargetStreamer().emitDirectiveSetMips5();
7544 case Mips::FeatureMips32:
7545 selectArch(
"mips32");
7546 getTargetStreamer().emitDirectiveSetMips32();
7548 case Mips::FeatureMips32r2:
7549 selectArch(
"mips32r2");
7550 getTargetStreamer().emitDirectiveSetMips32R2();
7552 case Mips::FeatureMips32r3:
7553 selectArch(
"mips32r3");
7554 getTargetStreamer().emitDirectiveSetMips32R3();
7556 case Mips::FeatureMips32r5:
7557 selectArch(
"mips32r5");
7558 getTargetStreamer().emitDirectiveSetMips32R5();
7560 case Mips::FeatureMips32r6:
7561 selectArch(
"mips32r6");
7562 getTargetStreamer().emitDirectiveSetMips32R6();
7564 case Mips::FeatureMips64:
7565 selectArch(
"mips64");
7566 getTargetStreamer().emitDirectiveSetMips64();
7568 case Mips::FeatureMips64r2:
7569 selectArch(
"mips64r2");
7570 getTargetStreamer().emitDirectiveSetMips64R2();
7572 case Mips::FeatureMips64r3:
7573 selectArch(
"mips64r3");
7574 getTargetStreamer().emitDirectiveSetMips64R3();
7576 case Mips::FeatureMips64r5:
7577 selectArch(
"mips64r5");
7578 getTargetStreamer().emitDirectiveSetMips64R5();
7580 case Mips::FeatureMips64r6:
7581 selectArch(
"mips64r6");
7582 getTargetStreamer().emitDirectiveSetMips64R6();
7584 case Mips::FeatureCRC:
7585 setFeatureBits(Mips::FeatureCRC,
"crc");
7586 getTargetStreamer().emitDirectiveSetCRC();
7588 case Mips::FeatureVirt:
7589 setFeatureBits(Mips::FeatureVirt,
"virt");
7590 getTargetStreamer().emitDirectiveSetVirt();
7592 case Mips::FeatureGINV:
7593 setFeatureBits(Mips::FeatureGINV,
"ginv");
7594 getTargetStreamer().emitDirectiveSetGINV();
7596 case Mips::FeatureEVA:
7597 setFeatureBits(Mips::FeatureEVA,
"eva");
7598 getTargetStreamer().emitDirectiveSetEVA();
7604bool MipsAsmParser::eatComma(StringRef ErrorStr) {
7605 MCAsmParser &Parser = getParser();
7607 SMLoc Loc = getLexer().getLoc();
7608 return Error(Loc, ErrorStr);
7619bool MipsAsmParser::isPicAndNotNxxAbi() {
7620 return inPicMode() && !(isABI_N32() || isABI_N64());
7623bool MipsAsmParser::parseDirectiveCpAdd(SMLoc Loc) {
7625 ParseStatus Res = parseAnyRegister(
Reg);
7627 reportParseError(
"expected register");
7631 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7632 if (!RegOpnd.isGPRAsmReg()) {
7633 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7639 reportParseError(
"unexpected token, expected end of statement");
7644 getTargetStreamer().emitDirectiveCpAdd(RegOpnd.getGPR32Reg());
7648bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
7649 if (AssemblerOptions.
back()->isReorder())
7650 Warning(Loc,
".cpload should be inside a noreorder section");
7652 if (inMips16Mode()) {
7653 reportParseError(
".cpload is not supported in Mips16 mode");
7658 ParseStatus Res = parseAnyRegister(
Reg);
7660 reportParseError(
"expected register containing function address");
7664 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7665 if (!RegOpnd.isGPRAsmReg()) {
7666 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7672 reportParseError(
"unexpected token, expected end of statement");
7676 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
7680bool MipsAsmParser::parseDirectiveCpLocal(SMLoc Loc) {
7681 if (!isABI_N32() && !isABI_N64()) {
7682 reportParseError(
".cplocal is allowed only in N32 or N64 mode");
7687 ParseStatus Res = parseAnyRegister(
Reg);
7689 reportParseError(
"expected register containing global pointer");
7693 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7694 if (!RegOpnd.isGPRAsmReg()) {
7695 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7701 reportParseError(
"unexpected token, expected end of statement");
7706 MCRegister NewReg = RegOpnd.getGPR32Reg();
7710 getTargetStreamer().emitDirectiveCpLocal(NewReg);
7714bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
7715 MCAsmParser &Parser = getParser();
7720 if (inMips16Mode()) {
7721 reportParseError(
".cprestore is not supported in Mips16 mode");
7726 const MCExpr *StackOffset;
7727 int64_t StackOffsetVal;
7729 reportParseError(
"expected stack offset value");
7733 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
7734 reportParseError(
"stack offset is not an absolute expression");
7738 if (StackOffsetVal < 0) {
7739 Warning(Loc,
".cprestore with negative stack offset has no effect");
7740 IsCpRestoreSet =
false;
7742 IsCpRestoreSet =
true;
7743 CpRestoreOffset = StackOffsetVal;
7748 reportParseError(
"unexpected token, expected end of statement");
7752 if (!getTargetStreamer().emitDirectiveCpRestore(
7753 CpRestoreOffset, [&]() {
return getATReg(Loc); }, Loc, STI))
7759bool MipsAsmParser::parseDirectiveCPSetup() {
7760 MCAsmParser &Parser = getParser();
7762 bool SaveIsReg =
true;
7765 ParseStatus Res = parseAnyRegister(TmpReg);
7767 reportParseError(
"expected register containing function address");
7771 MipsOperand &FuncRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7772 if (!FuncRegOpnd.isGPRAsmReg()) {
7773 reportParseError(FuncRegOpnd.getStartLoc(),
"invalid register");
7777 MCRegister FuncReg = FuncRegOpnd.getGPR32Reg();
7780 if (!eatComma(
"unexpected token, expected comma"))
7783 Res = parseAnyRegister(TmpReg);
7785 const MCExpr *OffsetExpr;
7787 SMLoc ExprLoc = getLexer().
getLoc();
7790 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
7791 reportParseError(ExprLoc,
"expected save register or stack offset");
7798 MipsOperand &SaveOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7799 if (!SaveOpnd.isGPRAsmReg()) {
7800 reportParseError(SaveOpnd.getStartLoc(),
"invalid register");
7803 Save = SaveOpnd.getGPR32Reg().id();
7806 if (!eatComma(
"unexpected token, expected comma"))
7811 reportParseError(
"expected expression");
7816 reportParseError(
"expected symbol");
7819 const MCSymbolRefExpr *
Ref =
static_cast<const MCSymbolRefExpr *
>(Expr);
7821 CpSaveLocation = Save;
7822 CpSaveLocationIsRegister = SaveIsReg;
7824 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save,
Ref->getSymbol(),
7829bool MipsAsmParser::parseDirectiveCPReturn() {
7830 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
7831 CpSaveLocationIsRegister);
7835bool MipsAsmParser::parseDirectiveNaN() {
7836 MCAsmParser &Parser = getParser();
7838 const AsmToken &Tok = Parser.
getTok();
7842 getTargetStreamer().emitDirectiveNaN2008();
7844 }
else if (Tok.
getString() ==
"legacy") {
7846 getTargetStreamer().emitDirectiveNaNLegacy();
7852 reportParseError(
"invalid option in .nan directive");
7856bool MipsAsmParser::parseDirectiveSet() {
7857 const AsmToken &Tok = getParser().getTok();
7859 SMLoc Loc = Tok.
getLoc();
7861 if (IdVal ==
"noat")
7862 return parseSetNoAtDirective();
7864 return parseSetAtDirective();
7865 if (IdVal ==
"arch")
7866 return parseSetArchDirective();
7867 if (IdVal ==
"bopt") {
7868 Warning(Loc,
"'bopt' feature is unsupported");
7872 if (IdVal ==
"nobopt") {
7878 return parseSetFpDirective();
7879 if (IdVal ==
"oddspreg")
7880 return parseSetOddSPRegDirective();
7881 if (IdVal ==
"nooddspreg")
7882 return parseSetNoOddSPRegDirective();
7884 return parseSetPopDirective();
7885 if (IdVal ==
"push")
7886 return parseSetPushDirective();
7887 if (IdVal ==
"reorder")
7888 return parseSetReorderDirective();
7889 if (IdVal ==
"noreorder")
7890 return parseSetNoReorderDirective();
7891 if (IdVal ==
"macro")
7892 return parseSetMacroDirective();
7893 if (IdVal ==
"nomacro")
7894 return parseSetNoMacroDirective();
7895 if (IdVal ==
"mips16")
7896 return parseSetMips16Directive();
7897 if (IdVal ==
"nomips16")
7898 return parseSetNoMips16Directive();
7899 if (IdVal ==
"nomicromips") {
7900 clearFeatureBits(Mips::FeatureMicroMips,
"micromips");
7901 getTargetStreamer().emitDirectiveSetNoMicroMips();
7902 getParser().eatToEndOfStatement();
7905 if (IdVal ==
"micromips") {
7906 if (hasMips64r6()) {
7907 Error(Loc,
".set micromips directive is not supported with MIPS64R6");
7910 return parseSetFeature(Mips::FeatureMicroMips);
7912 if (IdVal ==
"mips0")
7913 return parseSetMips0Directive();
7914 if (IdVal ==
"mips1")
7915 return parseSetFeature(Mips::FeatureMips1);
7916 if (IdVal ==
"mips2")
7917 return parseSetFeature(Mips::FeatureMips2);
7918 if (IdVal ==
"mips3")
7919 return parseSetFeature(Mips::FeatureMips3);
7920 if (IdVal ==
"mips4")
7921 return parseSetFeature(Mips::FeatureMips4);
7922 if (IdVal ==
"mips5")
7923 return parseSetFeature(Mips::FeatureMips5);
7924 if (IdVal ==
"mips32")
7925 return parseSetFeature(Mips::FeatureMips32);
7926 if (IdVal ==
"mips32r2")
7927 return parseSetFeature(Mips::FeatureMips32r2);
7928 if (IdVal ==
"mips32r3")
7929 return parseSetFeature(Mips::FeatureMips32r3);
7930 if (IdVal ==
"mips32r5")
7931 return parseSetFeature(Mips::FeatureMips32r5);
7932 if (IdVal ==
"mips32r6")
7933 return parseSetFeature(Mips::FeatureMips32r6);
7934 if (IdVal ==
"mips64")
7935 return parseSetFeature(Mips::FeatureMips64);
7936 if (IdVal ==
"mips64r2")
7937 return parseSetFeature(Mips::FeatureMips64r2);
7938 if (IdVal ==
"mips64r3")
7939 return parseSetFeature(Mips::FeatureMips64r3);
7940 if (IdVal ==
"mips64r5")
7941 return parseSetFeature(Mips::FeatureMips64r5);
7942 if (IdVal ==
"mips64r6") {
7943 if (inMicroMipsMode()) {
7944 Error(Loc,
"MIPS64R6 is not supported with microMIPS");
7947 return parseSetFeature(Mips::FeatureMips64r6);
7950 return parseSetFeature(Mips::FeatureDSP);
7951 if (IdVal ==
"dspr2")
7952 return parseSetFeature(Mips::FeatureDSPR2);
7953 if (IdVal ==
"nodsp")
7954 return parseSetNoDspDirective();
7955 if (IdVal ==
"mips3d")
7956 return parseSetFeature(Mips::FeatureMips3D);
7957 if (IdVal ==
"nomips3d")
7958 return parseSetNoMips3DDirective();
7960 return parseSetMsaDirective();
7961 if (IdVal ==
"nomsa")
7962 return parseSetNoMsaDirective();
7964 return parseSetMtDirective();
7965 if (IdVal ==
"nomt")
7966 return parseSetNoMtDirective();
7967 if (IdVal ==
"softfloat")
7968 return parseSetSoftFloatDirective();
7969 if (IdVal ==
"hardfloat")
7970 return parseSetHardFloatDirective();
7972 return parseSetFeature(Mips::FeatureCRC);
7973 if (IdVal ==
"nocrc")
7974 return parseSetNoCRCDirective();
7975 if (IdVal ==
"virt")
7976 return parseSetFeature(Mips::FeatureVirt);
7977 if (IdVal ==
"novirt")
7978 return parseSetNoVirtDirective();
7979 if (IdVal ==
"ginv")
7980 return parseSetFeature(Mips::FeatureGINV);
7981 if (IdVal ==
"noginv")
7982 return parseSetNoGINVDirective();
7984 return parseSetFeature(Mips::FeatureEVA);
7985 if (IdVal ==
"noeva")
7986 return parseSetNoEVADirective();
7989 return parseSetAssignment();
7994bool MipsAsmParser::parseDirectiveGpWord() {
7995 const MCExpr *
Value;
7996 if (getParser().parseExpression(
Value))
7998 getTargetStreamer().emitGPRel32Value(
Value);
8004bool MipsAsmParser::parseDirectiveGpDWord() {
8005 const MCExpr *
Value;
8006 if (getParser().parseExpression(
Value))
8008 getTargetStreamer().emitGPRel64Value(
Value);
8014bool MipsAsmParser::parseDirectiveDtpRelWord() {
8015 const MCExpr *
Value;
8016 if (getParser().parseExpression(
Value))
8018 getTargetStreamer().emitDTPRel32Value(
Value);
8024bool MipsAsmParser::parseDirectiveDtpRelDWord() {
8025 const MCExpr *
Value;
8026 if (getParser().parseExpression(
Value))
8028 getTargetStreamer().emitDTPRel64Value(
Value);
8034bool MipsAsmParser::parseDirectiveTpRelWord() {
8035 const MCExpr *
Value;
8036 if (getParser().parseExpression(
Value))
8038 getTargetStreamer().emitTPRel32Value(
Value);
8044bool MipsAsmParser::parseDirectiveTpRelDWord() {
8045 const MCExpr *
Value;
8046 if (getParser().parseExpression(
Value))
8048 getTargetStreamer().emitTPRel64Value(
Value);
8052bool MipsAsmParser::parseDirectiveOption() {
8053 MCAsmParser &Parser = getParser();
8055 AsmToken Tok = Parser.
getTok();
8059 "unexpected token, expected identifier");
8064 if (Option ==
"pic0") {
8066 IsPicEnabled =
false;
8068 getTargetStreamer().emitDirectiveOptionPic0();
8072 "unexpected token, expected end of statement");
8077 if (Option ==
"pic2") {
8079 IsPicEnabled =
true;
8081 getTargetStreamer().emitDirectiveOptionPic2();
8085 "unexpected token, expected end of statement");
8092 "unknown option, expected 'pic0' or 'pic2'");
8099bool MipsAsmParser::parseInsnDirective() {
8102 reportParseError(
"unexpected token, expected end of statement");
8108 getTargetStreamer().emitDirectiveInsn();
8116bool MipsAsmParser::parseRSectionDirective(StringRef Section) {
8119 reportParseError(
"unexpected token, expected end of statement");
8123 MCSection *ELFSection =
getContext().getELFSection(
8125 getParser().getStreamer().switchSection(ELFSection);
8134bool MipsAsmParser::parseSSectionDirective(StringRef Section,
unsigned Type) {
8137 reportParseError(
"unexpected token, expected end of statement");
8141 MCSection *ELFSection =
getContext().getELFSection(
8143 getParser().getStreamer().switchSection(ELFSection);
8162bool MipsAsmParser::parseDirectiveModule() {
8163 MCAsmParser &Parser = getParser();
8164 AsmLexer &Lexer = getLexer();
8167 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
8169 reportParseError(
".module directive must appear before any code");
8175 reportParseError(
"expected .module option identifier");
8179 if (Option ==
"oddspreg") {
8180 clearModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
8184 getTargetStreamer().updateABIInfo(*
this);
8189 getTargetStreamer().emitDirectiveModuleOddSPReg();
8193 reportParseError(
"unexpected token, expected end of statement");
8198 }
else if (Option ==
"nooddspreg") {
8200 return Error(L,
"'.module nooddspreg' requires the O32 ABI");
8203 setModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
8207 getTargetStreamer().updateABIInfo(*
this);
8212 getTargetStreamer().emitDirectiveModuleOddSPReg();
8216 reportParseError(
"unexpected token, expected end of statement");
8221 }
else if (Option ==
"fp") {
8222 return parseDirectiveModuleFP();
8223 }
else if (Option ==
"softfloat") {
8224 setModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
8228 getTargetStreamer().updateABIInfo(*
this);
8233 getTargetStreamer().emitDirectiveModuleSoftFloat();
8237 reportParseError(
"unexpected token, expected end of statement");
8242 }
else if (Option ==
"hardfloat") {
8243 clearModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
8247 getTargetStreamer().updateABIInfo(*
this);
8252 getTargetStreamer().emitDirectiveModuleHardFloat();
8256 reportParseError(
"unexpected token, expected end of statement");
8261 }
else if (Option ==
"mt") {
8262 setModuleFeatureBits(Mips::FeatureMT,
"mt");
8266 getTargetStreamer().updateABIInfo(*
this);
8271 getTargetStreamer().emitDirectiveModuleMT();
8275 reportParseError(
"unexpected token, expected end of statement");
8280 }
else if (Option ==
"crc") {
8281 setModuleFeatureBits(Mips::FeatureCRC,
"crc");
8285 getTargetStreamer().updateABIInfo(*
this);
8290 getTargetStreamer().emitDirectiveModuleCRC();
8294 reportParseError(
"unexpected token, expected end of statement");
8299 }
else if (Option ==
"nocrc") {
8300 clearModuleFeatureBits(Mips::FeatureCRC,
"crc");
8304 getTargetStreamer().updateABIInfo(*
this);
8309 getTargetStreamer().emitDirectiveModuleNoCRC();
8313 reportParseError(
"unexpected token, expected end of statement");
8318 }
else if (Option ==
"virt") {
8319 setModuleFeatureBits(Mips::FeatureVirt,
"virt");
8323 getTargetStreamer().updateABIInfo(*
this);
8328 getTargetStreamer().emitDirectiveModuleVirt();
8332 reportParseError(
"unexpected token, expected end of statement");
8337 }
else if (Option ==
"novirt") {
8338 clearModuleFeatureBits(Mips::FeatureVirt,
"virt");
8342 getTargetStreamer().updateABIInfo(*
this);
8347 getTargetStreamer().emitDirectiveModuleNoVirt();
8351 reportParseError(
"unexpected token, expected end of statement");
8356 }
else if (Option ==
"ginv") {
8357 setModuleFeatureBits(Mips::FeatureGINV,
"ginv");
8361 getTargetStreamer().updateABIInfo(*
this);
8366 getTargetStreamer().emitDirectiveModuleGINV();
8370 reportParseError(
"unexpected token, expected end of statement");
8375 }
else if (Option ==
"noginv") {
8376 clearModuleFeatureBits(Mips::FeatureGINV,
"ginv");
8380 getTargetStreamer().updateABIInfo(*
this);
8385 getTargetStreamer().emitDirectiveModuleNoGINV();
8389 reportParseError(
"unexpected token, expected end of statement");
8395 return Error(L,
"'" + Twine(Option) +
"' is not a valid .module option.");
8403bool MipsAsmParser::parseDirectiveModuleFP() {
8404 MCAsmParser &Parser = getParser();
8405 AsmLexer &Lexer = getLexer();
8408 reportParseError(
"unexpected token, expected equals sign '='");
8414 if (!parseFpABIValue(FpABI,
".module"))
8418 reportParseError(
"unexpected token, expected end of statement");
8424 getTargetStreamer().updateABIInfo(*
this);
8429 getTargetStreamer().emitDirectiveModuleFP();
8436 StringRef Directive) {
8437 MCAsmParser &Parser = getParser();
8438 AsmLexer &Lexer = getLexer();
8439 bool ModuleLevelOptions = Directive ==
".module";
8445 if (
Value !=
"xx") {
8446 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
8451 reportParseError(
"'" + Directive +
" fp=xx' requires the O32 ABI");
8455 FpABI = MipsABIFlagsSection::FpABIKind::XX;
8456 if (ModuleLevelOptions) {
8457 setModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8458 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8460 setFeatureBits(Mips::FeatureFPXX,
"fpxx");
8461 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8471 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
8477 reportParseError(
"'" + Directive +
" fp=32' requires the O32 ABI");
8481 FpABI = MipsABIFlagsSection::FpABIKind::S32;
8482 if (ModuleLevelOptions) {
8483 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8484 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8486 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
8487 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8490 FpABI = MipsABIFlagsSection::FpABIKind::S64;
8491 if (ModuleLevelOptions) {
8492 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8493 setModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8495 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
8496 setFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8506bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
8512 MCAsmParser &Parser = getParser();
8513 StringRef IDVal = DirectiveID.
getString();
8515 if (IDVal ==
".cpadd") {
8516 parseDirectiveCpAdd(DirectiveID.
getLoc());
8519 if (IDVal ==
".cpload") {
8520 parseDirectiveCpLoad(DirectiveID.
getLoc());
8523 if (IDVal ==
".cprestore") {
8524 parseDirectiveCpRestore(DirectiveID.
getLoc());
8527 if (IDVal ==
".cplocal") {
8528 parseDirectiveCpLocal(DirectiveID.
getLoc());
8531 if (IDVal ==
".ent") {
8535 reportParseError(
"expected identifier after .ent");
8549 reportParseError(
"unexpected token, expected end of statement");
8553 const MCExpr *DummyNumber;
8554 int64_t DummyNumberVal;
8558 reportParseError(
"expected number after comma");
8561 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
8562 reportParseError(
"expected an absolute expression after comma");
8569 reportParseError(
"unexpected token, expected end of statement");
8575 getTargetStreamer().emitDirectiveEnt(*Sym);
8577 IsCpRestoreSet =
false;
8581 if (IDVal ==
".end") {
8585 reportParseError(
"expected identifier after .end");
8590 reportParseError(
"unexpected token, expected end of statement");
8594 if (CurrentFn ==
nullptr) {
8595 reportParseError(
".end used without .ent");
8599 if ((SymbolName != CurrentFn->
getName())) {
8600 reportParseError(
".end symbol does not match .ent symbol");
8604 getTargetStreamer().emitDirectiveEnd(SymbolName);
8605 CurrentFn =
nullptr;
8606 IsCpRestoreSet =
false;
8610 if (IDVal ==
".frame") {
8613 ParseStatus Res = parseAnyRegister(TmpReg);
8615 reportParseError(
"expected stack register");
8619 MipsOperand &StackRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
8620 if (!StackRegOpnd.isGPRAsmReg()) {
8621 reportParseError(StackRegOpnd.getStartLoc(),
8622 "expected general purpose register");
8625 MCRegister StackReg = StackRegOpnd.getGPR32Reg();
8630 reportParseError(
"unexpected token, expected comma");
8635 const MCExpr *FrameSize;
8636 int64_t FrameSizeVal;
8639 reportParseError(
"expected frame size value");
8643 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
8644 reportParseError(
"frame size not an absolute expression");
8651 reportParseError(
"unexpected token, expected comma");
8657 Res = parseAnyRegister(TmpReg);
8659 reportParseError(
"expected return register");
8663 MipsOperand &ReturnRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
8664 if (!ReturnRegOpnd.isGPRAsmReg()) {
8665 reportParseError(ReturnRegOpnd.getStartLoc(),
8666 "expected general purpose register");
8672 reportParseError(
"unexpected token, expected end of statement");
8676 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
8677 ReturnRegOpnd.getGPR32Reg());
8678 IsCpRestoreSet =
false;
8682 if (IDVal ==
".set") {
8683 parseDirectiveSet();
8687 if (IDVal ==
".mask" || IDVal ==
".fmask") {
8698 const MCExpr *BitMask;
8702 reportParseError(
"expected bitmask value");
8706 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
8707 reportParseError(
"bitmask not an absolute expression");
8714 reportParseError(
"unexpected token, expected comma");
8719 const MCExpr *FrameOffset;
8720 int64_t FrameOffsetVal;
8723 reportParseError(
"expected frame offset value");
8727 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
8728 reportParseError(
"frame offset not an absolute expression");
8734 reportParseError(
"unexpected token, expected end of statement");
8738 if (IDVal ==
".mask")
8739 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
8741 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
8745 if (IDVal ==
".nan")
8746 return parseDirectiveNaN();
8748 if (IDVal ==
".gpword") {
8749 parseDirectiveGpWord();
8753 if (IDVal ==
".gpdword") {
8754 parseDirectiveGpDWord();
8758 if (IDVal ==
".dtprelword") {
8759 parseDirectiveDtpRelWord();
8763 if (IDVal ==
".dtpreldword") {
8764 parseDirectiveDtpRelDWord();
8768 if (IDVal ==
".tprelword") {
8769 parseDirectiveTpRelWord();
8773 if (IDVal ==
".tpreldword") {
8774 parseDirectiveTpRelDWord();
8778 if (IDVal ==
".option") {
8779 parseDirectiveOption();
8783 if (IDVal ==
".abicalls") {
8784 getTargetStreamer().emitDirectiveAbiCalls();
8787 "unexpected token, expected end of statement");
8792 if (IDVal ==
".cpsetup") {
8793 parseDirectiveCPSetup();
8796 if (IDVal ==
".cpreturn") {
8797 parseDirectiveCPReturn();
8800 if (IDVal ==
".module") {
8801 parseDirectiveModule();
8804 if (IDVal ==
".llvm_internal_mips_reallow_module_directive") {
8805 parseInternalDirectiveReallowModule();
8808 if (IDVal ==
".insn") {
8809 parseInsnDirective();
8812 if (IDVal ==
".rdata") {
8813 parseRSectionDirective(
".rodata");
8816 if (IDVal ==
".sbss") {
8820 if (IDVal ==
".sdata") {
8828bool MipsAsmParser::parseInternalDirectiveReallowModule() {
8831 reportParseError(
"unexpected token, expected end of statement");
8835 getTargetStreamer().reallowModuleDirective();
8849#define GET_REGISTER_MATCHER
8850#define GET_MATCHER_IMPLEMENTATION
8851#define GET_MNEMONIC_SPELL_CHECKER
8852#include "MipsGenAsmMatcher.inc"
8854bool MipsAsmParser::mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID) {
8856 const MatchEntry *Start, *
End;
8857 switch (VariantID) {
8859 case 0: Start = std::begin(MatchTable0);
End = std::end(MatchTable0);
break;
8862 auto MnemonicRange = std::equal_range(Start,
End, Mnemonic, LessOpcode());
8863 return MnemonicRange.first != MnemonicRange.second;
static const TargetRegisterClass * getRegClass(const MachineInstr &MI, Register Reg)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
This file declares a class to represent arbitrary precision floating point values and provide a varie...
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
static Value * expandAbs(CallInst *Orig)
std::pair< Instruction::BinaryOps, Value * > OffsetOp
Find all possible pairs (BinOp, RHS) that BinOp V, RHS can be simplified.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static FeatureBitset getFeatures(MCSubtargetInfo &STI, StringRef CPU, StringRef TuneCPU, StringRef FS, 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)
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)
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))
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 bool isMemOperand(const MCInst &MI, unsigned Op, unsigned RegClassID)
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 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
MCRegister getRegister(unsigned i) const
getRegister - Return the specified register in the class.
uint16_t getEncodingValue(MCRegister Reg) const
Returns the encoding for Reg.
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
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 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
static const char * getRegisterName(MCRegister Reg, unsigned AltIdx=Mips::NoRegAltName)
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.
const AArch64MCOptions & getCLOpts(const MCTargetOptions &Options)
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
LLVM_ABI LLVM_READONLY ARMABI computeTargetABI(const Triple &TT, StringRef ABIName="")
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.
MCRegister matchRegisterName(StringRef Name, const MCRegisterInfo &MRI, unsigned RegClassID, unsigned AltIdx)
Match a symbolic name in RegClassID, or return an invalid register.
int getCPURegisterIndex(StringRef Name, const MCRegisterInfo &MRI, unsigned AltIdx, bool *IsDeprecated=nullptr)
Return a GPR name's hardware index, or -1 if unknown.
constexpr MCPhysReg FP_64
constexpr MCPhysReg GP_64
constexpr MCPhysReg RA_64
constexpr MCPhysReg SP_64
WebAssemblyABI getABI(StringRef Name)
Parse an ABI name into the corresponding enum.
@ 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()
@ End
Run the machine verifier once, at the end of the pipeline.
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,...