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;
5035 if (hasMips64r2()) {
5036 unsigned FinalOpcode = Mips::NOP;
5038 FinalOpcode = Mips::DROTR;
5039 else if (ImmValue % 32 == 0)
5040 FinalOpcode = Mips::DROTR32;
5041 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
5043 FinalOpcode = Mips::DROTR32;
5045 FinalOpcode = Mips::DROTR;
5046 }
else if (ImmValue >= 33) {
5048 FinalOpcode = Mips::DROTR;
5050 FinalOpcode = Mips::DROTR32;
5053 uint64_t ShiftValue = ImmValue % 32;
5055 ShiftValue = (32 - ImmValue % 32) % 32;
5057 TOut.
emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
5063 if (ImmValue == 0) {
5064 TOut.
emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.
getLoc(), STI);
5072 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5073 FirstShift = Mips::DSLL;
5074 SecondShift = Mips::DSRL32;
5076 if (ImmValue == 32) {
5077 FirstShift = Mips::DSLL32;
5078 SecondShift = Mips::DSRL32;
5080 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5081 FirstShift = Mips::DSLL32;
5082 SecondShift = Mips::DSRL;
5086 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5087 FirstShift = Mips::DSRL;
5088 SecondShift = Mips::DSLL32;
5090 if (ImmValue == 32) {
5091 FirstShift = Mips::DSRL32;
5092 SecondShift = Mips::DSLL32;
5094 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5095 FirstShift = Mips::DSRL32;
5096 SecondShift = Mips::DSLL;
5101 ATReg = getATReg(Inst.
getLoc());
5105 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.
getLoc(), STI);
5106 TOut.
emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
5108 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5116bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5117 const MCSubtargetInfo *STI) {
5118 MipsTargetStreamer &TOut = getTargetStreamer();
5122 TOut.
emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
5123 if (FirstRegOp != SecondRegOp)
5124 TOut.
emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::R0, IDLoc, STI);
5127 TOut.
emitRRR(Mips::SUB, FirstRegOp, Mips::R0, SecondRegOp, IDLoc, STI);
5132bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5133 const MCSubtargetInfo *STI) {
5134 MipsTargetStreamer &TOut = getTargetStreamer();
5140 ATReg = getATReg(IDLoc);
5144 loadImmediate(ImmValue, ATReg, MCRegister(),
true,
false, IDLoc, Out, STI);
5146 TOut.
emitRR(Inst.
getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
5147 SrcReg, ATReg, IDLoc, STI);
5149 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5154bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5155 const MCSubtargetInfo *STI) {
5156 MipsTargetStreamer &TOut = getTargetStreamer();
5162 ATReg = getATReg(Inst.
getLoc());
5166 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
5167 SrcReg, TmpReg, IDLoc, STI);
5169 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5171 TOut.
emitRRI(Inst.
getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
5172 DstReg, DstReg, 0x1F, IDLoc, STI);
5174 TOut.
emitR(Mips::MFHI, ATReg, IDLoc, STI);
5177 TOut.
emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
5184 TOut.
emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
5185 if (AssemblerOptions.
back()->isReorder())
5187 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5191 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5196bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5197 const MCSubtargetInfo *STI) {
5198 MipsTargetStreamer &TOut = getTargetStreamer();
5204 ATReg = getATReg(IDLoc);
5208 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
5209 SrcReg, TmpReg, IDLoc, STI);
5211 TOut.
emitR(Mips::MFHI, ATReg, IDLoc, STI);
5212 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5214 TOut.
emitRRI(Mips::TNE, ATReg, Mips::R0, 6, IDLoc, STI);
5221 TOut.
emitRRX(Mips::BEQ, ATReg, Mips::R0, LabelOp, IDLoc, STI);
5222 if (AssemblerOptions.
back()->isReorder())
5224 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5232bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5233 const MCSubtargetInfo *STI) {
5234 MipsTargetStreamer &TOut = getTargetStreamer();
5239 TOut.
emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
5240 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5250bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
5252 const MCSubtargetInfo *STI,
5257 warnIfNoMacro(IDLoc);
5259 MipsTargetStreamer &TOut = getTargetStreamer();
5260 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
5262 MCRegister SecondReg =
nextReg(FirstReg);
5267 warnIfRegIndexIsAT(FirstReg, IDLoc);
5270 "Offset for load macro is not immediate!");
5273 signed NextOffset = FirstOffset.
getImm() + 4;
5281 if (FirstReg != BaseReg || !IsLoad) {
5282 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5283 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5285 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5286 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5298bool MipsAsmParser::expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc,
5300 const MCSubtargetInfo *STI) {
5304 warnIfNoMacro(IDLoc);
5306 MipsTargetStreamer &TOut = getTargetStreamer();
5307 unsigned Opcode = Mips::SWC1;
5309 MCRegister SecondReg =
nextReg(FirstReg);
5314 warnIfRegIndexIsAT(FirstReg, IDLoc);
5317 "Offset for macro is not immediate!");
5320 signed NextOffset = FirstOffset.
getImm() + 4;
5326 if (!IsLittleEndian)
5329 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5330 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5335bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5336 const MCSubtargetInfo *STI) {
5337 MipsTargetStreamer &TOut = getTargetStreamer();
5348 warnIfNoMacro(IDLoc);
5350 if (SrcReg != Mips::R0 && OpReg != Mips::R0) {
5351 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5352 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5356 MCRegister
Reg = SrcReg == Mips::R0 ? OpReg : SrcReg;
5357 TOut.
emitRRI(Mips::SLTiu, DstReg,
Reg, 1, IDLoc, STI);
5361bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5362 const MCSubtargetInfo *STI) {
5363 MipsTargetStreamer &TOut = getTargetStreamer();
5374 warnIfNoMacro(IDLoc);
5377 TOut.
emitRRI(Mips::SLTiu, DstReg, SrcReg, 1, IDLoc, STI);
5381 if (SrcReg == Mips::R0) {
5382 Warning(IDLoc,
"comparison is always false");
5383 TOut.
emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
5384 DstReg, SrcReg, SrcReg, IDLoc, STI);
5389 if (
Imm > -0x8000 &&
Imm < 0) {
5391 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5397 MCRegister ATReg = getATReg(IDLoc);
5401 if (loadImmediate(
Imm, ATReg, MCRegister(),
true, isGP64bit(), IDLoc, Out,
5405 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5406 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5411 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5415bool MipsAsmParser::expandSne(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5416 const MCSubtargetInfo *STI) {
5418 MipsTargetStreamer &TOut = getTargetStreamer();
5429 warnIfNoMacro(IDLoc);
5431 if (SrcReg != Mips::R0 && OpReg != Mips::R0) {
5432 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5433 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::R0, DstReg, IDLoc, STI);
5437 MCRegister
Reg = SrcReg == Mips::R0 ? OpReg : SrcReg;
5438 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::R0,
Reg, IDLoc, STI);
5442bool MipsAsmParser::expandSneI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5443 const MCSubtargetInfo *STI) {
5444 MipsTargetStreamer &TOut = getTargetStreamer();
5455 warnIfNoMacro(IDLoc);
5457 if (ImmValue == 0) {
5458 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::R0, SrcReg, IDLoc, STI);
5462 if (SrcReg == Mips::R0) {
5463 Warning(IDLoc,
"comparison is always true");
5464 if (loadImmediate(1, DstReg, MCRegister(),
true,
false, IDLoc, Out, STI))
5470 if (ImmValue > -0x8000 && ImmValue < 0) {
5471 ImmValue = -ImmValue;
5472 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5478 TOut.
emitRRI(
Opc, DstReg, SrcReg, ImmValue, IDLoc, STI);
5479 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::R0, DstReg, IDLoc, STI);
5483 MCRegister ATReg = getATReg(IDLoc);
5487 if (loadImmediate(ImmValue, ATReg, MCRegister(),
isInt<32>(ImmValue),
false,
5491 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5492 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::R0, DstReg, IDLoc, STI);
5698bool MipsAsmParser::expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5699 const MCSubtargetInfo *STI) {
5700 MipsTargetStreamer &TOut = getTargetStreamer();
5705 bool IsMFTR =
false;
5759 IsMFTR ? MCRegister(rd)
5761 : Inst.getOperand(0).
getReg());
5763 TOut.
emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, u, sel, h, IDLoc,
5768bool MipsAsmParser::expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5769 const MCSubtargetInfo *STI) {
5774 warnIfNoMacro(IDLoc);
5776 MipsTargetStreamer &TOut = getTargetStreamer();
5777 unsigned Opcode = Inst.
getOpcode() == Mips::SaaAddr ? Mips::SAA : Mips::SAAD;
5780 const MCOperand &BaseOp = Inst.
getOperand(2);
5782 if (BaseOp.
isImm()) {
5783 int64_t ImmValue = BaseOp.
getImm();
5784 if (ImmValue == 0) {
5785 TOut.
emitRR(Opcode, RtReg, BaseReg, IDLoc, STI);
5790 MCRegister ATReg = getATReg(IDLoc);
5794 if (expandLoadAddress(ATReg, BaseReg, BaseOp, !isGP64bit(), IDLoc, Out, STI))
5797 TOut.
emitRR(Opcode, RtReg, ATReg, IDLoc, STI);
5802MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
5806 return Match_Success;
5809 if (
static_cast<MipsOperand &
>(*
Operands[1])
5810 .isValidForTie(
static_cast<MipsOperand &
>(*
Operands[2])))
5811 return Match_Success;
5812 return Match_RequiresSameSrcAndDst;
5816unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
5823 return Match_RequiresNoZeroRegister;
5824 return Match_Success;
5830 case Mips::JALR_HB64:
5831 case Mips::JALRC_HB_MMR6:
5832 case Mips::JALRC_MMR6:
5834 return Match_RequiresDifferentSrcAndDst;
5835 return Match_Success;
5838 return Match_RequiresDifferentSrcAndDst;
5839 return Match_Success;
5842 return Match_NonZeroOperandForSync;
5843 return Match_Success;
5849 return Match_NonZeroOperandForMTCX;
5850 return Match_Success;
5863 case Mips::BLEZC:
case Mips::BLEZC_MMR6:
5864 case Mips::BGEZC:
case Mips::BGEZC_MMR6:
5865 case Mips::BGTZC:
case Mips::BGTZC_MMR6:
5866 case Mips::BLTZC:
case Mips::BLTZC_MMR6:
5867 case Mips::BEQZC:
case Mips::BEQZC_MMR6:
5868 case Mips::BNEZC:
case Mips::BNEZC_MMR6:
5877 return Match_RequiresNoZeroRegister;
5878 return Match_Success;
5879 case Mips::BGEC:
case Mips::BGEC_MMR6:
5880 case Mips::BLTC:
case Mips::BLTC_MMR6:
5881 case Mips::BGEUC:
case Mips::BGEUC_MMR6:
5882 case Mips::BLTUC:
case Mips::BLTUC_MMR6:
5883 case Mips::BEQC:
case Mips::BEQC_MMR6:
5884 case Mips::BNEC:
case Mips::BNEC_MMR6:
5893 return Match_RequiresNoZeroRegister;
5896 return Match_RequiresNoZeroRegister;
5898 return Match_RequiresDifferentOperands;
5899 return Match_Success;
5902 "Operands must be immediates for dins!");
5905 if ((0 > (Pos +
Size)) || ((Pos +
Size) > 32))
5906 return Match_RequiresPosSizeRange0_32;
5907 return Match_Success;
5912 "Operands must be immediates for dinsm/dinsu!");
5915 if ((32 >= (Pos +
Size)) || ((Pos +
Size) > 64))
5916 return Match_RequiresPosSizeRange33_64;
5917 return Match_Success;
5921 "Operands must be immediates for DEXTM!");
5924 if ((1 > (Pos +
Size)) || ((Pos +
Size) > 63))
5925 return Match_RequiresPosSizeUImm6;
5926 return Match_Success;
5931 "Operands must be immediates for dextm/dextu!");
5934 if ((32 > (Pos +
Size)) || ((Pos +
Size) > 64))
5935 return Match_RequiresPosSizeRange33_64;
5936 return Match_Success;
5938 case Mips::CRC32B:
case Mips::CRC32CB:
5939 case Mips::CRC32H:
case Mips::CRC32CH:
5940 case Mips::CRC32W:
case Mips::CRC32CW:
5941 case Mips::CRC32D:
case Mips::CRC32CD:
5943 return Match_RequiresSameSrcAndDst;
5944 return Match_Success;
5950 return Match_NoFCCRegisterForCurrentISA;
5952 return Match_Success;
5960 if (ErrorLoc ==
SMLoc())
5967bool MipsAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
5971 bool MatchingInlineAsm) {
5973 unsigned MatchResult =
5974 MatchInstructionImpl(
Operands, Inst, ErrorInfo, MatchingInlineAsm);
5976 switch (MatchResult) {
5978 if (processInstruction(Inst, IDLoc, Out, STI))
5981 case Match_MissingFeature:
5982 Error(IDLoc,
"instruction requires a CPU feature not currently enabled");
5984 case Match_InvalidTiedOperand:
5985 Error(IDLoc,
"operand must match destination register");
5987 case Match_InvalidOperand: {
5988 SMLoc ErrorLoc = IDLoc;
5989 if (ErrorInfo != ~0ULL) {
5991 return Error(IDLoc,
"too few operands for instruction");
5993 ErrorLoc =
Operands[ErrorInfo]->getStartLoc();
5995 ErrorLoc =
static_cast<MipsOperand &
>(*
Operands[ErrorInfo])
5998 if (ErrorLoc == SMLoc())
6002 return Error(ErrorLoc,
"invalid operand for instruction");
6004 case Match_NonZeroOperandForSync:
6006 "s-type must be zero or unspecified for pre-MIPS32 ISAs");
6007 case Match_NonZeroOperandForMTCX:
6008 return Error(IDLoc,
"selector must be zero for pre-MIPS32 ISAs");
6009 case Match_MnemonicFail:
6010 return Error(IDLoc,
"invalid instruction");
6011 case Match_RequiresDifferentSrcAndDst:
6012 return Error(IDLoc,
"source and destination must be different");
6013 case Match_RequiresDifferentOperands:
6014 return Error(IDLoc,
"registers must be different");
6015 case Match_RequiresNoZeroRegister:
6016 return Error(IDLoc,
"invalid operand ($zero) for instruction");
6017 case Match_RequiresSameSrcAndDst:
6018 return Error(IDLoc,
"source and destination must match");
6019 case Match_NoFCCRegisterForCurrentISA:
6021 "non-zero fcc register doesn't exist in current ISA level");
6026 "expected 1-bit unsigned immediate");
6029 "expected 2-bit unsigned immediate");
6032 "expected immediate in range 1 .. 4");
6035 "expected 3-bit unsigned immediate");
6038 "expected 4-bit unsigned immediate");
6041 "expected 4-bit signed immediate");
6044 "expected 5-bit unsigned immediate");
6047 "expected 5-bit signed immediate");
6050 "expected immediate in range 1 .. 32");
6051 case Match_UImm5_32:
6053 "expected immediate in range 32 .. 63");
6054 case Match_UImm5_33:
6056 "expected immediate in range 33 .. 64");
6057 case Match_UImm5_0_Report_UImm6:
6061 "expected 6-bit unsigned immediate");
6062 case Match_ConstantMemOffset:
6064 !
static_cast<MipsOperand &
>(*
Operands[ErrorInfo]).isConstantImm())
6066 "expected immediate operand kind");
6068 "immediate operand value out of range");
6069 case Match_UImm5_Lsl2:
6071 "expected both 7-bit unsigned immediate and multiple of 4");
6072 case Match_UImmRange2_64:
6074 "expected immediate in range 2 .. 64");
6077 "expected 6-bit unsigned immediate");
6078 case Match_UImm6_Lsl2:
6080 "expected both 8-bit unsigned immediate and multiple of 4");
6083 "expected 6-bit signed immediate");
6086 "expected 7-bit unsigned immediate");
6087 case Match_UImm7_N1:
6089 "expected immediate in range -1 .. 126");
6090 case Match_SImm7_Lsl2:
6092 "expected both 9-bit signed immediate and multiple of 4");
6095 "expected 8-bit unsigned immediate");
6096 case Match_UImm10_0:
6098 "expected 10-bit unsigned immediate");
6099 case Match_SImm10_0:
6101 "expected 10-bit signed immediate");
6102 case Match_SImm11_0:
6104 "expected 11-bit signed immediate");
6106 case Match_UImm16_Relaxed:
6107 case Match_UImm16_AltRelaxed:
6109 "expected 16-bit unsigned immediate");
6111 case Match_SImm16_Relaxed:
6113 "expected 16-bit signed immediate");
6114 case Match_SImm18_Lsl3:
6116 "expected both 18-bit signed immediate and multiple of 8");
6117 case Match_SImm19_Lsl2:
6119 "expected both 19-bit signed immediate and multiple of 4");
6120 case Match_UImm20_0:
6122 "expected 20-bit unsigned immediate");
6123 case Match_UImm26_0:
6125 "expected 26-bit unsigned immediate");
6127 case Match_SImm32_Relaxed:
6129 "expected 32-bit signed immediate");
6130 case Match_UImm32_Coerced:
6132 "expected 32-bit immediate");
6133 case Match_MemSImm9:
6135 "expected memory with 9-bit signed offset");
6136 case Match_MemSImm10:
6138 "expected memory with 10-bit signed offset");
6139 case Match_MemSImm10Lsl1:
6141 "expected memory with 11-bit signed offset and multiple of 2");
6142 case Match_MemSImm10Lsl2:
6144 "expected memory with 12-bit signed offset and multiple of 4");
6145 case Match_MemSImm10Lsl3:
6147 "expected memory with 13-bit signed offset and multiple of 8");
6148 case Match_MemSImm11:
6150 "expected memory with 11-bit signed offset");
6151 case Match_MemSImm12:
6153 "expected memory with 12-bit signed offset");
6154 case Match_MemSImm16:
6156 "expected memory with 16-bit signed offset");
6157 case Match_MemSImmPtr:
6159 "expected memory with 32-bit signed offset");
6160 case Match_RequiresPosSizeRange0_32: {
6161 SMLoc ErrorStart =
Operands[3]->getStartLoc();
6162 SMLoc ErrorEnd =
Operands[4]->getEndLoc();
6163 return Error(ErrorStart,
"size plus position are not in the range 0 .. 32",
6164 SMRange(ErrorStart, ErrorEnd));
6166 case Match_RequiresPosSizeUImm6: {
6167 SMLoc ErrorStart =
Operands[3]->getStartLoc();
6168 SMLoc ErrorEnd =
Operands[4]->getEndLoc();
6169 return Error(ErrorStart,
"size plus position are not in the range 1 .. 63",
6170 SMRange(ErrorStart, ErrorEnd));
6172 case Match_RequiresPosSizeRange33_64: {
6173 SMLoc ErrorStart =
Operands[3]->getStartLoc();
6174 SMLoc ErrorEnd =
Operands[4]->getEndLoc();
6175 return Error(ErrorStart,
"size plus position are not in the range 33 .. 64",
6176 SMRange(ErrorStart, ErrorEnd));
6183void MipsAsmParser::warnIfRegIndexIsAT(MCRegister RegIndex, SMLoc Loc) {
6184 if (RegIndex && AssemblerOptions.
back()->getATRegIndex() == RegIndex)
6185 Warning(Loc,
"used $at (currently $" + Twine(RegIndex.
id()) +
6186 ") without \".set noat\"");
6189void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
6190 if (!AssemblerOptions.
back()->isMacro())
6191 Warning(Loc,
"macro instruction expanded into multiple instructions");
6194void MipsAsmParser::ConvertXWPOperands(MCInst &Inst,
6198 "Unexpected instruction!");
6199 ((MipsOperand &)*
Operands[1]).addGPR32ZeroAsmRegOperands(Inst, 1);
6200 MCRegister NextReg =
nextReg(((MipsOperand &)*
Operands[1]).getGPR32Reg());
6202 static_cast<MipsOperand &
>(*
Operands[4]).addPtrRegOperands(Inst, 1);
6203 static_cast<MipsOperand &
>(*
Operands[2]).addImmOperands(Inst, 1);
6207MipsAsmParser::printWarningWithFixIt(
const Twine &
Msg,
const Twine &FixMsg,
6208 SMRange
Range,
bool ShowColors) {
6214int MipsAsmParser::matchCPURegisterName(StringRef Name) {
6215 const MCRegisterInfo &
MRI = *
getContext().getRegisterInfo();
6221 AsmToken RegTok = getLexer().peekTok();
6222 StringRef FixedName =
6224 printWarningWithFixIt(
"register names $t4-$t7 are only available in O32.",
6225 "Did you mean $" + FixedName +
"?",
6231int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
6232 const MCRegisterInfo &
MRI = *
getContext().getRegisterInfo();
6234 Mips::RegAliasName);
6235 return Reg ?
MRI.getEncodingValue(
Reg) : -1;
6238int MipsAsmParser::matchFPURegisterName(StringRef Name) {
6239 if (Name[0] ==
'f') {
6240 StringRef NumString =
Name.substr(1);
6251int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
6252 if (
Name.starts_with(
"fcc")) {
6253 StringRef NumString =
Name.substr(3);
6264int MipsAsmParser::matchACRegisterName(StringRef Name) {
6265 if (
Name.starts_with(
"ac")) {
6266 StringRef NumString =
Name.substr(2);
6277int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
6280 if (
Name.front() !=
'w' ||
Name.drop_front(1).getAsInteger(10, IntVal))
6289int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
6290 const MCRegisterInfo &
MRI = *
getContext().getRegisterInfo();
6292 Name,
MRI, Mips::MSACtrlRegClassID, Mips::RegAliasName);
6293 return Reg ?
MRI.getEncodingValue(
Reg) : -1;
6296bool MipsAsmParser::canUseATReg() {
6297 return AssemblerOptions.
back()->getATRegIndex() != 0;
6300MCRegister MipsAsmParser::getATReg(SMLoc Loc) {
6301 unsigned ATIndex = AssemblerOptions.
back()->getATRegIndex();
6303 reportParseError(Loc,
6304 "pseudo-instruction requires $at, which is not available");
6308 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
6312MCRegister MipsAsmParser::getReg(
int RC,
int RegNo) {
6313 return getContext().getRegisterInfo()->getRegClass(RC).getRegister(RegNo);
6318bool MipsAsmParser::parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
6320 return getParser().parsePrimaryExpr(Res, EndLoc);
6321 Res = parseRelocExpr();
6322 EndLoc = getLexer().getLoc();
6328const MCExpr *MipsAsmParser::parseRelocExpr() {
6329 auto getOp = [](StringRef
Op) {
6330 return StringSwitch<Mips::Specifier>(
Op)
6358 MCAsmParser &Parser = getParser();
6360 const MCExpr *Res =
nullptr;
6366 auto Op = getOp(Name);
6375 while (
Ops.size()) {
6384 MCAsmParser &Parser = getParser();
6394 ParseStatus Res = MatchOperandParserImpl(
Operands, Mnemonic,
true);
6405 switch (getLexer().getKind()) {
6415 if (!parseAnyRegister(
Operands).isNoMatch())
6428 Operands.push_back(MipsOperand::CreateImm(SymRef, S,
E, *
this));
6433 const MCExpr *Expr = parseRelocExpr();
6437 Operands.push_back(MipsOperand::CreateImm(Expr, S,
E, *
this));
6444bool MipsAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
6446 return !tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess();
6449ParseStatus MipsAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
6452 ParseStatus Res = parseAnyRegister(
Operands);
6455 MipsOperand &Operand =
static_cast<MipsOperand &
>(*
Operands.front());
6456 StartLoc = Operand.getStartLoc();
6457 EndLoc = Operand.getEndLoc();
6463 if (Operand.isGPRAsmReg()) {
6465 Reg = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
6475const MCExpr *MipsAsmParser::parseMemOffset() {
6482 if (getParser().parseExpression(
Offset))
6491 SMLoc S = getLexer().getLoc();
6492 const MCExpr *
Offset = parseMemOffset();
6496 SMLoc
E = getLexer().getLoc();
6508 Operands.push_back(MipsOperand::CreateToken(
"(",
E, *
this));
6509 Operands.push_back(MipsOperand::createGPRReg(
6511 Operands.push_back(MipsOperand::CreateToken(
")",
E, *
this));
6516 MCAsmParser &Parser = getParser();
6518 const MCExpr *
Address = parseMemOffset();
6535 std::unique_ptr<MipsOperand>
Base(
6536 static_cast<MipsOperand *
>(
Operands.back().release()));
6538 E =
Base->getEndLoc();
6540 MipsOperand::CreateMem(std::move(
Base),
Address, S,
E, *
this));
6545 MCAsmParser &Parser = getParser();
6554 const MCSymbolRefExpr *
Ref =
static_cast<const MCSymbolRefExpr *
>(Expr);
6555 StringRef DefSymbol =
Ref->getSymbol().getName();
6558 matchAnyRegisterNameWithoutDollar(
Operands, DefSymbol.
substr(1), S);
6572 if (Entry != RegisterSets.
end()) {
6574 matchAnyRegisterWithoutDollar(
Operands,
Entry->getValue(), S);
6585ParseStatus MipsAsmParser::matchAnyRegisterNameWithoutDollar(
6587 int Index = matchCPURegisterName(Identifier);
6589 Operands.push_back(MipsOperand::createGPRReg(
6590 Index, Identifier,
getContext().getRegisterInfo(), S,
6591 getLexer().getLoc(), *
this));
6595 Index = matchHWRegsRegisterName(Identifier);
6597 Operands.push_back(MipsOperand::createHWRegsReg(
6598 Index, Identifier,
getContext().getRegisterInfo(), S,
6599 getLexer().getLoc(), *
this));
6603 Index = matchFPURegisterName(Identifier);
6605 Operands.push_back(MipsOperand::createFGRReg(
6606 Index, Identifier,
getContext().getRegisterInfo(), S,
6607 getLexer().getLoc(), *
this));
6611 Index = matchFCCRegisterName(Identifier);
6613 Operands.push_back(MipsOperand::createFCCReg(
6614 Index, Identifier,
getContext().getRegisterInfo(), S,
6615 getLexer().getLoc(), *
this));
6619 Index = matchACRegisterName(Identifier);
6621 Operands.push_back(MipsOperand::createACCReg(
6622 Index, Identifier,
getContext().getRegisterInfo(), S,
6623 getLexer().getLoc(), *
this));
6627 Index = matchMSA128RegisterName(Identifier);
6629 Operands.push_back(MipsOperand::createMSA128Reg(
6630 Index, Identifier,
getContext().getRegisterInfo(), S,
6631 getLexer().getLoc(), *
this));
6635 Index = matchMSA128CtrlRegisterName(Identifier);
6637 Operands.push_back(MipsOperand::createMSACtrlReg(
6638 Index, Identifier,
getContext().getRegisterInfo(), S,
6639 getLexer().getLoc(), *
this));
6648 const AsmToken &Token, SMLoc S) {
6652 return matchAnyRegisterNameWithoutDollar(
Operands, Identifier, S);
6657 if (RegNum < 0 || RegNum > 31) {
6661 Error(getLexer().getLoc(),
"invalid register number");
6663 Operands.push_back(MipsOperand::createNumericReg(
6676 auto Token = getLexer().peekTok(
false);
6677 return matchAnyRegisterWithoutDollar(
Operands, Token, S);
6681 MCAsmParser &Parser = getParser();
6684 auto Token = Parser.
getTok();
6686 SMLoc S = Token.
getLoc();
6699 ParseStatus Res = matchAnyRegisterWithoutDollar(
Operands, S);
6708 MCAsmParser &Parser = getParser();
6711 SMLoc S = getLexer().getLoc();
6714 ParseStatus Res = parseAnyRegister(
Operands);
6719 const MCExpr *Expr =
nullptr;
6725 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *
this));
6730 MCAsmParser &Parser = getParser();
6731 const MCExpr *IdVal;
6742 if (getParser().parseExpression(IdVal))
6749 Operands.push_back(MipsOperand::CreateImm(
6755 MCAsmParser &Parser = getParser();
6759 bool RegRange =
false;
6766 while (parseAnyRegister(TmpOperands).isSuccess()) {
6767 SMLoc
E = getLexer().getLoc();
6768 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*TmpOperands.
back());
6769 Reg = isGP64bit() ? RegOpnd.getGPR64Reg() : RegOpnd.getGPR32Reg();
6777 MCRegister TmpReg = PrevReg + 1;
6778 while (TmpReg <=
Reg) {
6779 if ((((TmpReg < Mips::R16) || (TmpReg > Mips::R23)) &&
6781 (((TmpReg < Mips::R16_64) || (TmpReg > Mips::R23_64)) &&
6783 return Error(
E,
"invalid register operand");
6787 TmpReg = TmpReg.
id() + 1;
6796 return Error(
E,
"$16 or $31 expected");
6798 (
Reg >= Mips::R16 &&
Reg <= Mips::R23)) &&
6801 (
Reg >= Mips::R16_64 &&
Reg <= Mips::R23_64)) &&
6803 return Error(
E,
"invalid register operand");
6804 if (PrevReg.
isValid() && (
Reg != PrevReg + 1) &&
6807 return Error(
E,
"consecutive register numbers expected");
6817 return Error(
E,
"',' or '-' expected");
6827 Operands.push_back(MipsOperand::CreateRegList(Regs, S,
E, *
this));
6828 return parseMemOffsetOperand(
Operands);
6837 MCAsmParser &Parser = getParser();
6840 MipsOperand::CreateToken(
"(", getLexer().getLoc(), *
this));
6842 if (parseOperand(
Operands, Name)) {
6843 SMLoc Loc = getLexer().getLoc();
6844 return Error(Loc,
"unexpected token in argument list");
6847 SMLoc Loc = getLexer().getLoc();
6848 return Error(Loc,
"unexpected token, expected ')'");
6851 MipsOperand::CreateToken(
")", getLexer().getLoc(), *
this));
6863bool MipsAsmParser::parseBracketSuffix(StringRef Name,
6865 MCAsmParser &Parser = getParser();
6868 MipsOperand::CreateToken(
"[", getLexer().getLoc(), *
this));
6870 if (parseOperand(
Operands, Name)) {
6871 SMLoc Loc = getLexer().getLoc();
6872 return Error(Loc,
"unexpected token in argument list");
6875 SMLoc Loc = getLexer().getLoc();
6876 return Error(Loc,
"unexpected token, expected ']'");
6879 MipsOperand::CreateToken(
"]", getLexer().getLoc(), *
this));
6886 unsigned VariantID = 0);
6901bool MipsAsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
6903 MCAsmParser &Parser = getParser();
6907 getTargetStreamer().forbidModuleDirective();
6910 if (!mnemonicIsValid(Name, 0)) {
6911 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
6913 return Error(NameLoc,
"unknown instruction" + Suggestion);
6916 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *
this));
6921 bool IsFirstOperand =
Operands.size() == 1;
6923 if (parseOperand(
Operands, Name)) {
6924 SMLoc Loc = getLexer().getLoc();
6925 return Error(Loc,
"unexpected token in argument list");
6930 if (parseBracketSuffix(Name,
Operands))
6938 SMLoc Loc = getLexer().getLoc();
6939 return Error(Loc,
"unexpected token in argument list");
6947bool MipsAsmParser::reportParseError(
const Twine &ErrorMsg) {
6948 SMLoc Loc = getLexer().getLoc();
6949 return Error(Loc, ErrorMsg);
6952bool MipsAsmParser::reportParseError(SMLoc Loc,
const Twine &ErrorMsg) {
6953 return Error(Loc, ErrorMsg);
6956bool MipsAsmParser::parseSetNoAtDirective() {
6957 MCAsmParser &Parser = getParser();
6961 AssemblerOptions.
back()->setATRegIndex(0);
6967 reportParseError(
"unexpected token, expected end of statement");
6971 getTargetStreamer().emitDirectiveSetNoAt();
6976bool MipsAsmParser::parseSetAtDirective() {
6979 MCAsmParser &Parser = getParser();
6984 AssemblerOptions.
back()->setATRegIndex(1);
6986 getTargetStreamer().emitDirectiveSetAt();
6992 reportParseError(
"unexpected token, expected equals sign");
6999 reportParseError(
"no register specified");
7002 reportParseError(
"unexpected token, expected dollar sign '$'");
7012 AtRegNo = matchCPURegisterName(
Reg.getIdentifier());
7014 AtRegNo =
Reg.getIntVal();
7016 reportParseError(
"unexpected token, expected identifier or integer");
7021 if (!AssemblerOptions.
back()->setATRegIndex(AtRegNo)) {
7022 reportParseError(
"invalid register");
7029 reportParseError(
"unexpected token, expected end of statement");
7033 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
7039bool MipsAsmParser::parseSetReorderDirective() {
7040 MCAsmParser &Parser = getParser();
7044 reportParseError(
"unexpected token, expected end of statement");
7047 AssemblerOptions.
back()->setReorder();
7048 getTargetStreamer().emitDirectiveSetReorder();
7053bool MipsAsmParser::parseSetNoReorderDirective() {
7054 MCAsmParser &Parser = getParser();
7058 reportParseError(
"unexpected token, expected end of statement");
7061 AssemblerOptions.
back()->setNoReorder();
7062 getTargetStreamer().emitDirectiveSetNoReorder();
7067bool MipsAsmParser::parseSetMacroDirective() {
7068 MCAsmParser &Parser = getParser();
7072 reportParseError(
"unexpected token, expected end of statement");
7075 AssemblerOptions.
back()->setMacro();
7076 getTargetStreamer().emitDirectiveSetMacro();
7081bool MipsAsmParser::parseSetNoMacroDirective() {
7082 MCAsmParser &Parser = getParser();
7086 reportParseError(
"unexpected token, expected end of statement");
7089 if (AssemblerOptions.
back()->isReorder()) {
7090 reportParseError(
"`noreorder' must be set before `nomacro'");
7093 AssemblerOptions.
back()->setNoMacro();
7094 getTargetStreamer().emitDirectiveSetNoMacro();
7099bool MipsAsmParser::parseSetMsaDirective() {
7100 MCAsmParser &Parser = getParser();
7105 return reportParseError(
"unexpected token, expected end of statement");
7107 setFeatureBits(Mips::FeatureMSA,
"msa");
7108 getTargetStreamer().emitDirectiveSetMsa();
7112bool MipsAsmParser::parseSetNoMsaDirective() {
7113 MCAsmParser &Parser = getParser();
7118 return reportParseError(
"unexpected token, expected end of statement");
7120 clearFeatureBits(Mips::FeatureMSA,
"msa");
7121 getTargetStreamer().emitDirectiveSetNoMsa();
7125bool MipsAsmParser::parseSetNoDspDirective() {
7126 MCAsmParser &Parser = getParser();
7131 reportParseError(
"unexpected token, expected end of statement");
7135 clearFeatureBits(Mips::FeatureDSP,
"dsp");
7136 getTargetStreamer().emitDirectiveSetNoDsp();
7140bool MipsAsmParser::parseSetNoMips3DDirective() {
7141 MCAsmParser &Parser = getParser();
7146 reportParseError(
"unexpected token, expected end of statement");
7150 clearFeatureBits(Mips::FeatureMips3D,
"mips3d");
7151 getTargetStreamer().emitDirectiveSetNoMips3D();
7155bool MipsAsmParser::parseSetMips16Directive() {
7156 MCAsmParser &Parser = getParser();
7161 reportParseError(
"unexpected token, expected end of statement");
7165 clearFeatureBits(Mips::FeatureMicroMips,
"micromips");
7166 setFeatureBits(Mips::FeatureMips16,
"mips16");
7167 getTargetStreamer().emitDirectiveSetMips16();
7172bool MipsAsmParser::parseSetNoMips16Directive() {
7173 MCAsmParser &Parser = getParser();
7178 reportParseError(
"unexpected token, expected end of statement");
7182 clearFeatureBits(Mips::FeatureMips16,
"mips16");
7183 getTargetStreamer().emitDirectiveSetNoMips16();
7188bool MipsAsmParser::parseSetFpDirective() {
7189 MCAsmParser &Parser = getParser();
7195 AsmToken Tok = Parser.
getTok();
7197 reportParseError(
"unexpected token, expected equals sign '='");
7203 if (!parseFpABIValue(FpAbiVal,
".set"))
7207 reportParseError(
"unexpected token, expected end of statement");
7210 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
7215bool MipsAsmParser::parseSetOddSPRegDirective() {
7216 MCAsmParser &Parser = getParser();
7220 reportParseError(
"unexpected token, expected end of statement");
7224 clearFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
7225 getTargetStreamer().emitDirectiveSetOddSPReg();
7229bool MipsAsmParser::parseSetNoOddSPRegDirective() {
7230 MCAsmParser &Parser = getParser();
7234 reportParseError(
"unexpected token, expected end of statement");
7238 setFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
7239 getTargetStreamer().emitDirectiveSetNoOddSPReg();
7243bool MipsAsmParser::parseSetMtDirective() {
7244 MCAsmParser &Parser = getParser();
7249 reportParseError(
"unexpected token, expected end of statement");
7253 setFeatureBits(Mips::FeatureMT,
"mt");
7254 getTargetStreamer().emitDirectiveSetMt();
7259bool MipsAsmParser::parseSetNoMtDirective() {
7260 MCAsmParser &Parser = getParser();
7265 reportParseError(
"unexpected token, expected end of statement");
7269 clearFeatureBits(Mips::FeatureMT,
"mt");
7271 getTargetStreamer().emitDirectiveSetNoMt();
7276bool MipsAsmParser::parseSetNoCRCDirective() {
7277 MCAsmParser &Parser = getParser();
7282 reportParseError(
"unexpected token, expected end of statement");
7286 clearFeatureBits(Mips::FeatureCRC,
"crc");
7288 getTargetStreamer().emitDirectiveSetNoCRC();
7293bool MipsAsmParser::parseSetNoVirtDirective() {
7294 MCAsmParser &Parser = getParser();
7299 reportParseError(
"unexpected token, expected end of statement");
7303 clearFeatureBits(Mips::FeatureVirt,
"virt");
7305 getTargetStreamer().emitDirectiveSetNoVirt();
7310bool MipsAsmParser::parseSetNoGINVDirective() {
7311 MCAsmParser &Parser = getParser();
7316 reportParseError(
"unexpected token, expected end of statement");
7320 clearFeatureBits(Mips::FeatureGINV,
"ginv");
7322 getTargetStreamer().emitDirectiveSetNoGINV();
7327bool MipsAsmParser::parseSetNoEVADirective() {
7328 MCAsmParser &Parser = getParser();
7333 reportParseError(
"unexpected token, expected end of statement");
7337 clearFeatureBits(Mips::FeatureEVA,
"eva");
7339 getTargetStreamer().emitDirectiveSetNoEVA();
7344bool MipsAsmParser::parseSetPopDirective() {
7345 MCAsmParser &Parser = getParser();
7346 SMLoc Loc = getLexer().getLoc();
7350 return reportParseError(
"unexpected token, expected end of statement");
7354 if (AssemblerOptions.
size() == 2)
7355 return reportParseError(Loc,
".set pop with no .set push");
7357 MCSubtargetInfo &STI = copySTI();
7359 setAvailableFeatures(
7360 ComputeAvailableFeatures(AssemblerOptions.
back()->getFeatures()));
7363 getTargetStreamer().emitDirectiveSetPop();
7367bool MipsAsmParser::parseSetPushDirective() {
7368 MCAsmParser &Parser = getParser();
7371 return reportParseError(
"unexpected token, expected end of statement");
7375 std::make_unique<MipsAssemblerOptions>(AssemblerOptions.
back().get()));
7377 getTargetStreamer().emitDirectiveSetPush();
7381bool MipsAsmParser::parseSetSoftFloatDirective() {
7382 MCAsmParser &Parser = getParser();
7385 return reportParseError(
"unexpected token, expected end of statement");
7387 setFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
7388 getTargetStreamer().emitDirectiveSetSoftFloat();
7392bool MipsAsmParser::parseSetHardFloatDirective() {
7393 MCAsmParser &Parser = getParser();
7396 return reportParseError(
"unexpected token, expected end of statement");
7398 clearFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
7399 getTargetStreamer().emitDirectiveSetHardFloat();
7403bool MipsAsmParser::parseSetAssignment() {
7405 MCAsmParser &Parser = getParser();
7408 return reportParseError(
"expected identifier after .set");
7411 return reportParseError(
"unexpected token, expected comma");
7426 const MCExpr *
Value;
7428 Parser, Sym,
Value))
7430 getStreamer().emitAssignment(Sym,
Value);
7435bool MipsAsmParser::parseSetMips0Directive() {
7436 MCAsmParser &Parser = getParser();
7439 return reportParseError(
"unexpected token, expected end of statement");
7442 MCSubtargetInfo &STI = copySTI();
7443 setAvailableFeatures(
7444 ComputeAvailableFeatures(AssemblerOptions.
front()->getFeatures()));
7446 AssemblerOptions.
back()->setFeatures(AssemblerOptions.
front()->getFeatures());
7448 getTargetStreamer().emitDirectiveSetMips0();
7452bool MipsAsmParser::parseSetArchDirective() {
7453 MCAsmParser &Parser = getParser();
7456 return reportParseError(
"unexpected token, expected equals sign");
7459 StringRef Arch = getParser().parseStringToEndOfStatement().trim();
7461 return reportParseError(
"expected arch identifier");
7463 StringRef ArchFeatureName =
7464 StringSwitch<StringRef>(Arch)
7465 .Case(
"mips1",
"mips1")
7466 .Case(
"mips2",
"mips2")
7467 .Case(
"mips3",
"mips3")
7468 .Case(
"mips4",
"mips4")
7469 .Case(
"mips5",
"mips5")
7470 .Case(
"mips32",
"mips32")
7471 .Case(
"mips32r2",
"mips32r2")
7472 .Case(
"mips32r3",
"mips32r3")
7473 .Case(
"mips32r5",
"mips32r5")
7474 .Case(
"mips32r6",
"mips32r6")
7475 .Case(
"mips64",
"mips64")
7476 .Case(
"mips64r2",
"mips64r2")
7477 .Case(
"mips64r3",
"mips64r3")
7478 .Case(
"mips64r5",
"mips64r5")
7479 .Case(
"mips64r6",
"mips64r6")
7480 .Case(
"octeon",
"cnmips")
7481 .Case(
"octeon+",
"cnmipsp")
7482 .Case(
"r4000",
"mips3")
7485 if (ArchFeatureName.
empty())
7486 return reportParseError(
"unsupported architecture");
7488 if (ArchFeatureName ==
"mips64r6" && inMicroMipsMode())
7489 return reportParseError(
"mips64r6 does not support microMIPS");
7491 selectArch(ArchFeatureName);
7492 getTargetStreamer().emitDirectiveSetArch(Arch);
7496bool MipsAsmParser::parseSetFeature(
uint64_t Feature) {
7497 MCAsmParser &Parser = getParser();
7500 return reportParseError(
"unexpected token, expected end of statement");
7505 case Mips::FeatureMips3D:
7506 setFeatureBits(Mips::FeatureMips3D,
"mips3d");
7507 getTargetStreamer().emitDirectiveSetMips3D();
7509 case Mips::FeatureDSP:
7510 setFeatureBits(Mips::FeatureDSP,
"dsp");
7511 getTargetStreamer().emitDirectiveSetDsp();
7513 case Mips::FeatureDSPR2:
7514 setFeatureBits(Mips::FeatureDSPR2,
"dspr2");
7515 getTargetStreamer().emitDirectiveSetDspr2();
7517 case Mips::FeatureMicroMips:
7518 clearFeatureBits(Mips::FeatureMips16,
"mips16");
7519 setFeatureBits(Mips::FeatureMicroMips,
"micromips");
7520 getTargetStreamer().emitDirectiveSetMicroMips();
7522 case Mips::FeatureMips1:
7523 selectArch(
"mips1");
7524 getTargetStreamer().emitDirectiveSetMips1();
7526 case Mips::FeatureMips2:
7527 selectArch(
"mips2");
7528 getTargetStreamer().emitDirectiveSetMips2();
7530 case Mips::FeatureMips3:
7531 selectArch(
"mips3");
7532 getTargetStreamer().emitDirectiveSetMips3();
7534 case Mips::FeatureMips4:
7535 selectArch(
"mips4");
7536 getTargetStreamer().emitDirectiveSetMips4();
7538 case Mips::FeatureMips5:
7539 selectArch(
"mips5");
7540 getTargetStreamer().emitDirectiveSetMips5();
7542 case Mips::FeatureMips32:
7543 selectArch(
"mips32");
7544 getTargetStreamer().emitDirectiveSetMips32();
7546 case Mips::FeatureMips32r2:
7547 selectArch(
"mips32r2");
7548 getTargetStreamer().emitDirectiveSetMips32R2();
7550 case Mips::FeatureMips32r3:
7551 selectArch(
"mips32r3");
7552 getTargetStreamer().emitDirectiveSetMips32R3();
7554 case Mips::FeatureMips32r5:
7555 selectArch(
"mips32r5");
7556 getTargetStreamer().emitDirectiveSetMips32R5();
7558 case Mips::FeatureMips32r6:
7559 selectArch(
"mips32r6");
7560 getTargetStreamer().emitDirectiveSetMips32R6();
7562 case Mips::FeatureMips64:
7563 selectArch(
"mips64");
7564 getTargetStreamer().emitDirectiveSetMips64();
7566 case Mips::FeatureMips64r2:
7567 selectArch(
"mips64r2");
7568 getTargetStreamer().emitDirectiveSetMips64R2();
7570 case Mips::FeatureMips64r3:
7571 selectArch(
"mips64r3");
7572 getTargetStreamer().emitDirectiveSetMips64R3();
7574 case Mips::FeatureMips64r5:
7575 selectArch(
"mips64r5");
7576 getTargetStreamer().emitDirectiveSetMips64R5();
7578 case Mips::FeatureMips64r6:
7579 selectArch(
"mips64r6");
7580 getTargetStreamer().emitDirectiveSetMips64R6();
7582 case Mips::FeatureCRC:
7583 setFeatureBits(Mips::FeatureCRC,
"crc");
7584 getTargetStreamer().emitDirectiveSetCRC();
7586 case Mips::FeatureVirt:
7587 setFeatureBits(Mips::FeatureVirt,
"virt");
7588 getTargetStreamer().emitDirectiveSetVirt();
7590 case Mips::FeatureGINV:
7591 setFeatureBits(Mips::FeatureGINV,
"ginv");
7592 getTargetStreamer().emitDirectiveSetGINV();
7594 case Mips::FeatureEVA:
7595 setFeatureBits(Mips::FeatureEVA,
"eva");
7596 getTargetStreamer().emitDirectiveSetEVA();
7602bool MipsAsmParser::eatComma(StringRef ErrorStr) {
7603 MCAsmParser &Parser = getParser();
7605 SMLoc Loc = getLexer().getLoc();
7606 return Error(Loc, ErrorStr);
7617bool MipsAsmParser::isPicAndNotNxxAbi() {
7618 return inPicMode() && !(isABI_N32() || isABI_N64());
7621bool MipsAsmParser::parseDirectiveCpAdd(SMLoc Loc) {
7623 ParseStatus Res = parseAnyRegister(
Reg);
7625 reportParseError(
"expected register");
7629 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7630 if (!RegOpnd.isGPRAsmReg()) {
7631 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7637 reportParseError(
"unexpected token, expected end of statement");
7642 getTargetStreamer().emitDirectiveCpAdd(RegOpnd.getGPR32Reg());
7646bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
7647 if (AssemblerOptions.
back()->isReorder())
7648 Warning(Loc,
".cpload should be inside a noreorder section");
7650 if (inMips16Mode()) {
7651 reportParseError(
".cpload is not supported in Mips16 mode");
7656 ParseStatus Res = parseAnyRegister(
Reg);
7658 reportParseError(
"expected register containing function address");
7662 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7663 if (!RegOpnd.isGPRAsmReg()) {
7664 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7670 reportParseError(
"unexpected token, expected end of statement");
7674 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
7678bool MipsAsmParser::parseDirectiveCpLocal(SMLoc Loc) {
7679 if (!isABI_N32() && !isABI_N64()) {
7680 reportParseError(
".cplocal is allowed only in N32 or N64 mode");
7685 ParseStatus Res = parseAnyRegister(
Reg);
7687 reportParseError(
"expected register containing global pointer");
7691 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7692 if (!RegOpnd.isGPRAsmReg()) {
7693 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7699 reportParseError(
"unexpected token, expected end of statement");
7704 MCRegister NewReg = RegOpnd.getGPR32Reg();
7708 getTargetStreamer().emitDirectiveCpLocal(NewReg);
7712bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
7713 MCAsmParser &Parser = getParser();
7718 if (inMips16Mode()) {
7719 reportParseError(
".cprestore is not supported in Mips16 mode");
7724 const MCExpr *StackOffset;
7725 int64_t StackOffsetVal;
7727 reportParseError(
"expected stack offset value");
7731 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
7732 reportParseError(
"stack offset is not an absolute expression");
7736 if (StackOffsetVal < 0) {
7737 Warning(Loc,
".cprestore with negative stack offset has no effect");
7738 IsCpRestoreSet =
false;
7740 IsCpRestoreSet =
true;
7741 CpRestoreOffset = StackOffsetVal;
7746 reportParseError(
"unexpected token, expected end of statement");
7750 if (!getTargetStreamer().emitDirectiveCpRestore(
7751 CpRestoreOffset, [&]() {
return getATReg(Loc); }, Loc, STI))
7757bool MipsAsmParser::parseDirectiveCPSetup() {
7758 MCAsmParser &Parser = getParser();
7760 bool SaveIsReg =
true;
7763 ParseStatus Res = parseAnyRegister(TmpReg);
7765 reportParseError(
"expected register containing function address");
7769 MipsOperand &FuncRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7770 if (!FuncRegOpnd.isGPRAsmReg()) {
7771 reportParseError(FuncRegOpnd.getStartLoc(),
"invalid register");
7775 MCRegister FuncReg = FuncRegOpnd.getGPR32Reg();
7778 if (!eatComma(
"unexpected token, expected comma"))
7781 Res = parseAnyRegister(TmpReg);
7783 const MCExpr *OffsetExpr;
7785 SMLoc ExprLoc = getLexer().
getLoc();
7788 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
7789 reportParseError(ExprLoc,
"expected save register or stack offset");
7796 MipsOperand &SaveOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7797 if (!SaveOpnd.isGPRAsmReg()) {
7798 reportParseError(SaveOpnd.getStartLoc(),
"invalid register");
7801 Save = SaveOpnd.getGPR32Reg().id();
7804 if (!eatComma(
"unexpected token, expected comma"))
7809 reportParseError(
"expected expression");
7814 reportParseError(
"expected symbol");
7817 const MCSymbolRefExpr *
Ref =
static_cast<const MCSymbolRefExpr *
>(Expr);
7819 CpSaveLocation = Save;
7820 CpSaveLocationIsRegister = SaveIsReg;
7822 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save,
Ref->getSymbol(),
7827bool MipsAsmParser::parseDirectiveCPReturn() {
7828 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
7829 CpSaveLocationIsRegister);
7833bool MipsAsmParser::parseDirectiveNaN() {
7834 MCAsmParser &Parser = getParser();
7836 const AsmToken &Tok = Parser.
getTok();
7840 getTargetStreamer().emitDirectiveNaN2008();
7842 }
else if (Tok.
getString() ==
"legacy") {
7844 getTargetStreamer().emitDirectiveNaNLegacy();
7850 reportParseError(
"invalid option in .nan directive");
7854bool MipsAsmParser::parseDirectiveSet() {
7855 const AsmToken &Tok = getParser().getTok();
7857 SMLoc Loc = Tok.
getLoc();
7859 if (IdVal ==
"noat")
7860 return parseSetNoAtDirective();
7862 return parseSetAtDirective();
7863 if (IdVal ==
"arch")
7864 return parseSetArchDirective();
7865 if (IdVal ==
"bopt") {
7866 Warning(Loc,
"'bopt' feature is unsupported");
7870 if (IdVal ==
"nobopt") {
7876 return parseSetFpDirective();
7877 if (IdVal ==
"oddspreg")
7878 return parseSetOddSPRegDirective();
7879 if (IdVal ==
"nooddspreg")
7880 return parseSetNoOddSPRegDirective();
7882 return parseSetPopDirective();
7883 if (IdVal ==
"push")
7884 return parseSetPushDirective();
7885 if (IdVal ==
"reorder")
7886 return parseSetReorderDirective();
7887 if (IdVal ==
"noreorder")
7888 return parseSetNoReorderDirective();
7889 if (IdVal ==
"macro")
7890 return parseSetMacroDirective();
7891 if (IdVal ==
"nomacro")
7892 return parseSetNoMacroDirective();
7893 if (IdVal ==
"mips16")
7894 return parseSetMips16Directive();
7895 if (IdVal ==
"nomips16")
7896 return parseSetNoMips16Directive();
7897 if (IdVal ==
"nomicromips") {
7898 clearFeatureBits(Mips::FeatureMicroMips,
"micromips");
7899 getTargetStreamer().emitDirectiveSetNoMicroMips();
7900 getParser().eatToEndOfStatement();
7903 if (IdVal ==
"micromips") {
7904 if (hasMips64r6()) {
7905 Error(Loc,
".set micromips directive is not supported with MIPS64R6");
7908 return parseSetFeature(Mips::FeatureMicroMips);
7910 if (IdVal ==
"mips0")
7911 return parseSetMips0Directive();
7912 if (IdVal ==
"mips1")
7913 return parseSetFeature(Mips::FeatureMips1);
7914 if (IdVal ==
"mips2")
7915 return parseSetFeature(Mips::FeatureMips2);
7916 if (IdVal ==
"mips3")
7917 return parseSetFeature(Mips::FeatureMips3);
7918 if (IdVal ==
"mips4")
7919 return parseSetFeature(Mips::FeatureMips4);
7920 if (IdVal ==
"mips5")
7921 return parseSetFeature(Mips::FeatureMips5);
7922 if (IdVal ==
"mips32")
7923 return parseSetFeature(Mips::FeatureMips32);
7924 if (IdVal ==
"mips32r2")
7925 return parseSetFeature(Mips::FeatureMips32r2);
7926 if (IdVal ==
"mips32r3")
7927 return parseSetFeature(Mips::FeatureMips32r3);
7928 if (IdVal ==
"mips32r5")
7929 return parseSetFeature(Mips::FeatureMips32r5);
7930 if (IdVal ==
"mips32r6")
7931 return parseSetFeature(Mips::FeatureMips32r6);
7932 if (IdVal ==
"mips64")
7933 return parseSetFeature(Mips::FeatureMips64);
7934 if (IdVal ==
"mips64r2")
7935 return parseSetFeature(Mips::FeatureMips64r2);
7936 if (IdVal ==
"mips64r3")
7937 return parseSetFeature(Mips::FeatureMips64r3);
7938 if (IdVal ==
"mips64r5")
7939 return parseSetFeature(Mips::FeatureMips64r5);
7940 if (IdVal ==
"mips64r6") {
7941 if (inMicroMipsMode()) {
7942 Error(Loc,
"MIPS64R6 is not supported with microMIPS");
7945 return parseSetFeature(Mips::FeatureMips64r6);
7948 return parseSetFeature(Mips::FeatureDSP);
7949 if (IdVal ==
"dspr2")
7950 return parseSetFeature(Mips::FeatureDSPR2);
7951 if (IdVal ==
"nodsp")
7952 return parseSetNoDspDirective();
7953 if (IdVal ==
"mips3d")
7954 return parseSetFeature(Mips::FeatureMips3D);
7955 if (IdVal ==
"nomips3d")
7956 return parseSetNoMips3DDirective();
7958 return parseSetMsaDirective();
7959 if (IdVal ==
"nomsa")
7960 return parseSetNoMsaDirective();
7962 return parseSetMtDirective();
7963 if (IdVal ==
"nomt")
7964 return parseSetNoMtDirective();
7965 if (IdVal ==
"softfloat")
7966 return parseSetSoftFloatDirective();
7967 if (IdVal ==
"hardfloat")
7968 return parseSetHardFloatDirective();
7970 return parseSetFeature(Mips::FeatureCRC);
7971 if (IdVal ==
"nocrc")
7972 return parseSetNoCRCDirective();
7973 if (IdVal ==
"virt")
7974 return parseSetFeature(Mips::FeatureVirt);
7975 if (IdVal ==
"novirt")
7976 return parseSetNoVirtDirective();
7977 if (IdVal ==
"ginv")
7978 return parseSetFeature(Mips::FeatureGINV);
7979 if (IdVal ==
"noginv")
7980 return parseSetNoGINVDirective();
7982 return parseSetFeature(Mips::FeatureEVA);
7983 if (IdVal ==
"noeva")
7984 return parseSetNoEVADirective();
7987 return parseSetAssignment();
7992bool MipsAsmParser::parseDirectiveGpWord() {
7993 const MCExpr *
Value;
7994 if (getParser().parseExpression(
Value))
7996 getTargetStreamer().emitGPRel32Value(
Value);
8002bool MipsAsmParser::parseDirectiveGpDWord() {
8003 const MCExpr *
Value;
8004 if (getParser().parseExpression(
Value))
8006 getTargetStreamer().emitGPRel64Value(
Value);
8012bool MipsAsmParser::parseDirectiveDtpRelWord() {
8013 const MCExpr *
Value;
8014 if (getParser().parseExpression(
Value))
8016 getTargetStreamer().emitDTPRel32Value(
Value);
8022bool MipsAsmParser::parseDirectiveDtpRelDWord() {
8023 const MCExpr *
Value;
8024 if (getParser().parseExpression(
Value))
8026 getTargetStreamer().emitDTPRel64Value(
Value);
8032bool MipsAsmParser::parseDirectiveTpRelWord() {
8033 const MCExpr *
Value;
8034 if (getParser().parseExpression(
Value))
8036 getTargetStreamer().emitTPRel32Value(
Value);
8042bool MipsAsmParser::parseDirectiveTpRelDWord() {
8043 const MCExpr *
Value;
8044 if (getParser().parseExpression(
Value))
8046 getTargetStreamer().emitTPRel64Value(
Value);
8050bool MipsAsmParser::parseDirectiveOption() {
8051 MCAsmParser &Parser = getParser();
8053 AsmToken Tok = Parser.
getTok();
8057 "unexpected token, expected identifier");
8062 if (Option ==
"pic0") {
8064 IsPicEnabled =
false;
8066 getTargetStreamer().emitDirectiveOptionPic0();
8070 "unexpected token, expected end of statement");
8075 if (Option ==
"pic2") {
8077 IsPicEnabled =
true;
8079 getTargetStreamer().emitDirectiveOptionPic2();
8083 "unexpected token, expected end of statement");
8090 "unknown option, expected 'pic0' or 'pic2'");
8097bool MipsAsmParser::parseInsnDirective() {
8100 reportParseError(
"unexpected token, expected end of statement");
8106 getTargetStreamer().emitDirectiveInsn();
8114bool MipsAsmParser::parseRSectionDirective(StringRef Section) {
8117 reportParseError(
"unexpected token, expected end of statement");
8121 MCSection *ELFSection =
getContext().getELFSection(
8123 getParser().getStreamer().switchSection(ELFSection);
8132bool MipsAsmParser::parseSSectionDirective(StringRef Section,
unsigned Type) {
8135 reportParseError(
"unexpected token, expected end of statement");
8139 MCSection *ELFSection =
getContext().getELFSection(
8141 getParser().getStreamer().switchSection(ELFSection);
8160bool MipsAsmParser::parseDirectiveModule() {
8161 MCAsmParser &Parser = getParser();
8162 AsmLexer &Lexer = getLexer();
8165 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
8167 reportParseError(
".module directive must appear before any code");
8173 reportParseError(
"expected .module option identifier");
8177 if (Option ==
"oddspreg") {
8178 clearModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
8182 getTargetStreamer().updateABIInfo(*
this);
8187 getTargetStreamer().emitDirectiveModuleOddSPReg();
8191 reportParseError(
"unexpected token, expected end of statement");
8196 }
else if (Option ==
"nooddspreg") {
8198 return Error(L,
"'.module nooddspreg' requires the O32 ABI");
8201 setModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
8205 getTargetStreamer().updateABIInfo(*
this);
8210 getTargetStreamer().emitDirectiveModuleOddSPReg();
8214 reportParseError(
"unexpected token, expected end of statement");
8219 }
else if (Option ==
"fp") {
8220 return parseDirectiveModuleFP();
8221 }
else if (Option ==
"softfloat") {
8222 setModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
8226 getTargetStreamer().updateABIInfo(*
this);
8231 getTargetStreamer().emitDirectiveModuleSoftFloat();
8235 reportParseError(
"unexpected token, expected end of statement");
8240 }
else if (Option ==
"hardfloat") {
8241 clearModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
8245 getTargetStreamer().updateABIInfo(*
this);
8250 getTargetStreamer().emitDirectiveModuleHardFloat();
8254 reportParseError(
"unexpected token, expected end of statement");
8259 }
else if (Option ==
"mt") {
8260 setModuleFeatureBits(Mips::FeatureMT,
"mt");
8264 getTargetStreamer().updateABIInfo(*
this);
8269 getTargetStreamer().emitDirectiveModuleMT();
8273 reportParseError(
"unexpected token, expected end of statement");
8278 }
else if (Option ==
"crc") {
8279 setModuleFeatureBits(Mips::FeatureCRC,
"crc");
8283 getTargetStreamer().updateABIInfo(*
this);
8288 getTargetStreamer().emitDirectiveModuleCRC();
8292 reportParseError(
"unexpected token, expected end of statement");
8297 }
else if (Option ==
"nocrc") {
8298 clearModuleFeatureBits(Mips::FeatureCRC,
"crc");
8302 getTargetStreamer().updateABIInfo(*
this);
8307 getTargetStreamer().emitDirectiveModuleNoCRC();
8311 reportParseError(
"unexpected token, expected end of statement");
8316 }
else if (Option ==
"virt") {
8317 setModuleFeatureBits(Mips::FeatureVirt,
"virt");
8321 getTargetStreamer().updateABIInfo(*
this);
8326 getTargetStreamer().emitDirectiveModuleVirt();
8330 reportParseError(
"unexpected token, expected end of statement");
8335 }
else if (Option ==
"novirt") {
8336 clearModuleFeatureBits(Mips::FeatureVirt,
"virt");
8340 getTargetStreamer().updateABIInfo(*
this);
8345 getTargetStreamer().emitDirectiveModuleNoVirt();
8349 reportParseError(
"unexpected token, expected end of statement");
8354 }
else if (Option ==
"ginv") {
8355 setModuleFeatureBits(Mips::FeatureGINV,
"ginv");
8359 getTargetStreamer().updateABIInfo(*
this);
8364 getTargetStreamer().emitDirectiveModuleGINV();
8368 reportParseError(
"unexpected token, expected end of statement");
8373 }
else if (Option ==
"noginv") {
8374 clearModuleFeatureBits(Mips::FeatureGINV,
"ginv");
8378 getTargetStreamer().updateABIInfo(*
this);
8383 getTargetStreamer().emitDirectiveModuleNoGINV();
8387 reportParseError(
"unexpected token, expected end of statement");
8393 return Error(L,
"'" + Twine(Option) +
"' is not a valid .module option.");
8401bool MipsAsmParser::parseDirectiveModuleFP() {
8402 MCAsmParser &Parser = getParser();
8403 AsmLexer &Lexer = getLexer();
8406 reportParseError(
"unexpected token, expected equals sign '='");
8412 if (!parseFpABIValue(FpABI,
".module"))
8416 reportParseError(
"unexpected token, expected end of statement");
8422 getTargetStreamer().updateABIInfo(*
this);
8427 getTargetStreamer().emitDirectiveModuleFP();
8434 StringRef Directive) {
8435 MCAsmParser &Parser = getParser();
8436 AsmLexer &Lexer = getLexer();
8437 bool ModuleLevelOptions = Directive ==
".module";
8443 if (
Value !=
"xx") {
8444 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
8449 reportParseError(
"'" + Directive +
" fp=xx' requires the O32 ABI");
8453 FpABI = MipsABIFlagsSection::FpABIKind::XX;
8454 if (ModuleLevelOptions) {
8455 setModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8456 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8458 setFeatureBits(Mips::FeatureFPXX,
"fpxx");
8459 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8469 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
8475 reportParseError(
"'" + Directive +
" fp=32' requires the O32 ABI");
8479 FpABI = MipsABIFlagsSection::FpABIKind::S32;
8480 if (ModuleLevelOptions) {
8481 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8482 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8484 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
8485 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8488 FpABI = MipsABIFlagsSection::FpABIKind::S64;
8489 if (ModuleLevelOptions) {
8490 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8491 setModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8493 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
8494 setFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8504bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
8510 MCAsmParser &Parser = getParser();
8511 StringRef IDVal = DirectiveID.
getString();
8513 if (IDVal ==
".cpadd") {
8514 parseDirectiveCpAdd(DirectiveID.
getLoc());
8517 if (IDVal ==
".cpload") {
8518 parseDirectiveCpLoad(DirectiveID.
getLoc());
8521 if (IDVal ==
".cprestore") {
8522 parseDirectiveCpRestore(DirectiveID.
getLoc());
8525 if (IDVal ==
".cplocal") {
8526 parseDirectiveCpLocal(DirectiveID.
getLoc());
8529 if (IDVal ==
".ent") {
8533 reportParseError(
"expected identifier after .ent");
8547 reportParseError(
"unexpected token, expected end of statement");
8551 const MCExpr *DummyNumber;
8552 int64_t DummyNumberVal;
8556 reportParseError(
"expected number after comma");
8559 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
8560 reportParseError(
"expected an absolute expression after comma");
8567 reportParseError(
"unexpected token, expected end of statement");
8573 getTargetStreamer().emitDirectiveEnt(*Sym);
8575 IsCpRestoreSet =
false;
8579 if (IDVal ==
".end") {
8583 reportParseError(
"expected identifier after .end");
8588 reportParseError(
"unexpected token, expected end of statement");
8592 if (CurrentFn ==
nullptr) {
8593 reportParseError(
".end used without .ent");
8597 if ((SymbolName != CurrentFn->
getName())) {
8598 reportParseError(
".end symbol does not match .ent symbol");
8602 getTargetStreamer().emitDirectiveEnd(SymbolName);
8603 CurrentFn =
nullptr;
8604 IsCpRestoreSet =
false;
8608 if (IDVal ==
".frame") {
8611 ParseStatus Res = parseAnyRegister(TmpReg);
8613 reportParseError(
"expected stack register");
8617 MipsOperand &StackRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
8618 if (!StackRegOpnd.isGPRAsmReg()) {
8619 reportParseError(StackRegOpnd.getStartLoc(),
8620 "expected general purpose register");
8623 MCRegister StackReg = StackRegOpnd.getGPR32Reg();
8628 reportParseError(
"unexpected token, expected comma");
8633 const MCExpr *FrameSize;
8634 int64_t FrameSizeVal;
8637 reportParseError(
"expected frame size value");
8641 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
8642 reportParseError(
"frame size not an absolute expression");
8649 reportParseError(
"unexpected token, expected comma");
8655 Res = parseAnyRegister(TmpReg);
8657 reportParseError(
"expected return register");
8661 MipsOperand &ReturnRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
8662 if (!ReturnRegOpnd.isGPRAsmReg()) {
8663 reportParseError(ReturnRegOpnd.getStartLoc(),
8664 "expected general purpose register");
8670 reportParseError(
"unexpected token, expected end of statement");
8674 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
8675 ReturnRegOpnd.getGPR32Reg());
8676 IsCpRestoreSet =
false;
8680 if (IDVal ==
".set") {
8681 parseDirectiveSet();
8685 if (IDVal ==
".mask" || IDVal ==
".fmask") {
8696 const MCExpr *BitMask;
8700 reportParseError(
"expected bitmask value");
8704 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
8705 reportParseError(
"bitmask not an absolute expression");
8712 reportParseError(
"unexpected token, expected comma");
8717 const MCExpr *FrameOffset;
8718 int64_t FrameOffsetVal;
8721 reportParseError(
"expected frame offset value");
8725 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
8726 reportParseError(
"frame offset not an absolute expression");
8732 reportParseError(
"unexpected token, expected end of statement");
8736 if (IDVal ==
".mask")
8737 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
8739 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
8743 if (IDVal ==
".nan")
8744 return parseDirectiveNaN();
8746 if (IDVal ==
".gpword") {
8747 parseDirectiveGpWord();
8751 if (IDVal ==
".gpdword") {
8752 parseDirectiveGpDWord();
8756 if (IDVal ==
".dtprelword") {
8757 parseDirectiveDtpRelWord();
8761 if (IDVal ==
".dtpreldword") {
8762 parseDirectiveDtpRelDWord();
8766 if (IDVal ==
".tprelword") {
8767 parseDirectiveTpRelWord();
8771 if (IDVal ==
".tpreldword") {
8772 parseDirectiveTpRelDWord();
8776 if (IDVal ==
".option") {
8777 parseDirectiveOption();
8781 if (IDVal ==
".abicalls") {
8782 getTargetStreamer().emitDirectiveAbiCalls();
8785 "unexpected token, expected end of statement");
8790 if (IDVal ==
".cpsetup") {
8791 parseDirectiveCPSetup();
8794 if (IDVal ==
".cpreturn") {
8795 parseDirectiveCPReturn();
8798 if (IDVal ==
".module") {
8799 parseDirectiveModule();
8802 if (IDVal ==
".llvm_internal_mips_reallow_module_directive") {
8803 parseInternalDirectiveReallowModule();
8806 if (IDVal ==
".insn") {
8807 parseInsnDirective();
8810 if (IDVal ==
".rdata") {
8811 parseRSectionDirective(
".rodata");
8814 if (IDVal ==
".sbss") {
8818 if (IDVal ==
".sdata") {
8826bool MipsAsmParser::parseInternalDirectiveReallowModule() {
8829 reportParseError(
"unexpected token, expected end of statement");
8833 getTargetStreamer().reallowModuleDirective();
8847#define GET_REGISTER_MATCHER
8848#define GET_MATCHER_IMPLEMENTATION
8849#define GET_MNEMONIC_SPELL_CHECKER
8850#include "MipsGenAsmMatcher.inc"
8852bool MipsAsmParser::mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID) {
8854 const MatchEntry *Start, *
End;
8855 switch (VariantID) {
8857 case 0: Start = std::begin(MatchTable0);
End = std::end(MatchTable0);
break;
8860 auto MnemonicRange = std::equal_range(Start,
End, Mnemonic, LessOpcode());
8861 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))
MachineRegisterInfo & MRI
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.
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
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
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,...