64#define DEBUG_TYPE "mips-asm-parser"
77class MipsAssemblerOptions {
79 MipsAssemblerOptions(
const FeatureBitset &Features_) : Features(Features_) {}
81 MipsAssemblerOptions(
const MipsAssemblerOptions *Opts) {
82 ATReg = Opts->getATRegIndex();
83 Reorder = Opts->isReorder();
84 Macro = Opts->isMacro();
85 Features = Opts->getFeatures();
88 unsigned getATRegIndex()
const {
return ATReg; }
89 bool setATRegIndex(
unsigned Reg) {
97 bool isReorder()
const {
return Reorder; }
98 void setReorder() { Reorder =
true; }
99 void setNoReorder() { Reorder =
false; }
101 bool isMacro()
const {
return Macro; }
102 void setMacro() {
Macro =
true; }
103 void setNoMacro() {
Macro =
false; }
105 const FeatureBitset &
getFeatures()
const {
return Features; }
106 void setFeatures(
const FeatureBitset &Features_) { Features = Features_; }
113 static const FeatureBitset AllArchRelatedMask;
119 FeatureBitset Features;
124const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
125 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
126 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
127 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
128 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
129 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
130 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
131 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
132 Mips::FeatureCnMipsP, Mips::FeatureFP64Bit, Mips::FeatureGP64Bit,
139 MipsTargetStreamer &getTargetStreamer() {
140 assert(getParser().getStreamer().getTargetStreamer() &&
141 "do not have a target streamer");
142 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
143 return static_cast<MipsTargetStreamer &
>(TS);
155 bool CurForbiddenSlotAttr;
158 unsigned CpSaveLocation;
160 bool CpSaveLocationIsRegister;
163 StringMap<AsmToken> RegisterSets;
166 void printWarningWithFixIt(
const Twine &
Msg,
const Twine &FixMsg,
167 SMRange
Range,
bool ShowColors =
true);
171#define GET_ASSEMBLER_HEADER
172#include "MipsGenAsmMatcher.inc"
175 checkEarlyTargetMatchPredicate(
MCInst &Inst,
177 unsigned checkTargetMatchPredicate(
MCInst &Inst)
override;
179 bool matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
182 bool MatchingInlineAsm)
override;
187 SMLoc &EndLoc)
override;
193 bool mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID);
198 bool ParseDirective(
AsmToken DirectiveID)
override;
210 const MCExpr *parseRelocExpr();
216 enum MacroExpanderResultTy {
223 MacroExpanderResultTy tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
225 const MCSubtargetInfo *STI);
227 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
228 const MCSubtargetInfo *STI);
230 bool loadImmediate(int64_t ImmValue, MCRegister DstReg, MCRegister SrcReg,
231 bool Is32BitImm,
bool IsAddress, SMLoc IDLoc,
232 MCStreamer &Out,
const MCSubtargetInfo *STI);
234 bool loadAndAddSymbolAddress(
const MCExpr *SymExpr, MCRegister DstReg,
235 MCRegister SrcReg,
bool Is32BitSym, SMLoc IDLoc,
236 MCStreamer &Out,
const MCSubtargetInfo *STI);
238 bool emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc, MCSymbol *Sym);
240 bool expandLoadImm(MCInst &Inst,
bool Is32BitImm, SMLoc IDLoc,
241 MCStreamer &Out,
const MCSubtargetInfo *STI);
243 bool expandLoadSingleImmToGPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
244 const MCSubtargetInfo *STI);
245 bool expandLoadSingleImmToFPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
246 const MCSubtargetInfo *STI);
247 bool expandLoadDoubleImmToGPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
248 const MCSubtargetInfo *STI);
249 bool expandLoadDoubleImmToFPR(MCInst &Inst,
bool Is64FPU, SMLoc IDLoc,
250 MCStreamer &Out,
const MCSubtargetInfo *STI);
252 bool expandLoadAddress(MCRegister DstReg, MCRegister BaseReg,
253 const MCOperand &
Offset,
bool Is32BitAddress,
254 SMLoc IDLoc, MCStreamer &Out,
255 const MCSubtargetInfo *STI);
257 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
258 const MCSubtargetInfo *STI);
260 void expandMem16Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
261 const MCSubtargetInfo *STI,
bool IsLoad);
262 void expandMem9Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
263 const MCSubtargetInfo *STI,
bool IsLoad);
265 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
266 const MCSubtargetInfo *STI);
268 bool expandAliasImmediate(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
269 const MCSubtargetInfo *STI);
271 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
272 const MCSubtargetInfo *STI);
274 bool expandCondBranches(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
275 const MCSubtargetInfo *STI);
277 bool expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
278 const MCSubtargetInfo *STI,
const bool IsMips64,
281 bool expandTrunc(MCInst &Inst,
bool IsDouble,
bool Is64FPU, SMLoc IDLoc,
282 MCStreamer &Out,
const MCSubtargetInfo *STI);
284 bool expandUlh(MCInst &Inst,
bool Signed, SMLoc IDLoc, MCStreamer &Out,
285 const MCSubtargetInfo *STI);
287 bool expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
288 const MCSubtargetInfo *STI);
290 bool expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
291 const MCSubtargetInfo *STI);
293 bool expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
294 const MCSubtargetInfo *STI);
296 bool expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
297 const MCSubtargetInfo *STI);
299 bool expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
300 const MCSubtargetInfo *STI);
302 bool expandSle(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
303 const MCSubtargetInfo *STI);
305 bool expandSleImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
306 const MCSubtargetInfo *STI);
308 bool expandRotation(MCInst &Inst, SMLoc IDLoc,
309 MCStreamer &Out,
const MCSubtargetInfo *STI);
310 bool expandRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
311 const MCSubtargetInfo *STI);
312 bool expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
313 const MCSubtargetInfo *STI);
314 bool expandDRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
315 const MCSubtargetInfo *STI);
317 bool expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
318 const MCSubtargetInfo *STI);
320 bool expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
321 const MCSubtargetInfo *STI);
323 bool expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
324 const MCSubtargetInfo *STI);
326 bool expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
327 const MCSubtargetInfo *STI);
329 bool expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
330 const MCSubtargetInfo *STI);
332 bool expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
333 const MCSubtargetInfo *STI,
bool IsLoad);
335 bool expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
336 const MCSubtargetInfo *STI);
338 bool expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
339 const MCSubtargetInfo *STI);
341 bool expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
342 const MCSubtargetInfo *STI);
344 bool expandSne(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
345 const MCSubtargetInfo *STI);
347 bool expandSneI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
348 const MCSubtargetInfo *STI);
350 bool expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
351 const MCSubtargetInfo *STI);
353 bool expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
354 const MCSubtargetInfo *STI);
356 bool reportParseError(
const Twine &ErrorMsg);
357 bool reportParseError(SMLoc Loc,
const Twine &ErrorMsg);
359 bool parseSetMips0Directive();
360 bool parseSetArchDirective();
361 bool parseSetFeature(
uint64_t Feature);
362 bool isPicAndNotNxxAbi();
363 bool parseDirectiveCpAdd(SMLoc Loc);
364 bool parseDirectiveCpLoad(SMLoc Loc);
365 bool parseDirectiveCpLocal(SMLoc Loc);
366 bool parseDirectiveCpRestore(SMLoc Loc);
367 bool parseDirectiveCPSetup();
368 bool parseDirectiveCPReturn();
369 bool parseDirectiveNaN();
370 bool parseDirectiveSet();
371 bool parseDirectiveOption();
372 bool parseInsnDirective();
373 bool parseRSectionDirective(StringRef Section);
374 bool parseSSectionDirective(StringRef Section,
unsigned Type);
376 bool parseSetAtDirective();
377 bool parseSetNoAtDirective();
378 bool parseSetMacroDirective();
379 bool parseSetNoMacroDirective();
380 bool parseSetMsaDirective();
381 bool parseSetNoMsaDirective();
382 bool parseSetNoDspDirective();
383 bool parseSetNoMips3DDirective();
384 bool parseSetReorderDirective();
385 bool parseSetNoReorderDirective();
386 bool parseSetMips16Directive();
387 bool parseSetNoMips16Directive();
388 bool parseSetFpDirective();
389 bool parseSetOddSPRegDirective();
390 bool parseSetNoOddSPRegDirective();
391 bool parseSetPopDirective();
392 bool parseSetPushDirective();
393 bool parseSetSoftFloatDirective();
394 bool parseSetHardFloatDirective();
395 bool parseSetMtDirective();
396 bool parseSetNoMtDirective();
397 bool parseSetNoCRCDirective();
398 bool parseSetNoVirtDirective();
399 bool parseSetNoGINVDirective();
401 bool parseSetAssignment();
403 bool parseDirectiveGpWord();
404 bool parseDirectiveGpDWord();
405 bool parseDirectiveDtpRelWord();
406 bool parseDirectiveDtpRelDWord();
407 bool parseDirectiveTpRelWord();
408 bool parseDirectiveTpRelDWord();
409 bool parseDirectiveModule();
410 bool parseDirectiveModuleFP();
412 StringRef Directive);
414 bool parseInternalDirectiveReallowModule();
416 bool eatComma(StringRef ErrorStr);
418 int matchCPURegisterName(StringRef Symbol);
420 int matchHWRegsRegisterName(StringRef Symbol);
422 int matchFPURegisterName(StringRef Name);
424 int matchFCCRegisterName(StringRef Name);
426 int matchACRegisterName(StringRef Name);
428 int matchMSA128RegisterName(StringRef Name);
430 int matchMSA128CtrlRegisterName(StringRef Name);
432 MCRegister
getReg(
int RC,
int RegNo);
437 MCRegister getATReg(SMLoc Loc);
441 bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
442 const MCSubtargetInfo *STI);
466 void selectArch(StringRef ArchFeature) {
467 MCSubtargetInfo &STI = copySTI();
469 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
471 setAvailableFeatures(
476 void setFeatureBits(
uint64_t Feature, StringRef FeatureString) {
478 MCSubtargetInfo &STI = copySTI();
479 setAvailableFeatures(
485 void clearFeatureBits(
uint64_t Feature, StringRef FeatureString) {
487 MCSubtargetInfo &STI = copySTI();
488 setAvailableFeatures(
494 void setModuleFeatureBits(
uint64_t Feature, StringRef FeatureString) {
495 setFeatureBits(Feature, FeatureString);
496 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
499 void clearModuleFeatureBits(
uint64_t Feature, StringRef FeatureString) {
500 clearFeatureBits(Feature, FeatureString);
501 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
505 enum MipsMatchResultTy {
506 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
507 Match_RequiresDifferentOperands,
508 Match_RequiresNoZeroRegister,
509 Match_RequiresSameSrcAndDst,
510 Match_NoFCCRegisterForCurrentISA,
511 Match_NonZeroOperandForSync,
512 Match_NonZeroOperandForMTCX,
513 Match_RequiresPosSizeRange0_32,
514 Match_RequiresPosSizeRange33_64,
515 Match_RequiresPosSizeUImm6,
516#define GET_OPERAND_DIAGNOSTIC_TYPES
517#include "MipsGenAsmMatcher.inc"
518#undef GET_OPERAND_DIAGNOSTIC_TYPES
521 MipsAsmParser(
const MCSubtargetInfo &sti, MCAsmParser &parser,
522 const MCInstrInfo &MII)
523 : MCTargetAsmParser(sti, MII),
525 sti.getTargetTriple(),
535 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
538 AssemblerOptions.push_back(
539 std::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
542 AssemblerOptions.push_back(
543 std::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
545 getTargetStreamer().updateABIInfo(*
this);
547 if (!isABI_O32() && !useOddSPReg() != 0)
552 CurForbiddenSlotAttr =
false;
553 IsPicEnabled =
getContext().getObjectFileInfo()->isPositionIndependent();
555 IsCpRestoreSet =
false;
556 CpRestoreOffset = -1;
557 GPReg = ABI.GetGlobalPtr();
562 if (getSTI().
getCPU() ==
"mips64r6" && inMicroMipsMode())
565 if (!isABI_O32() && inMicroMipsMode())
570 bool hasEightFccRegisters()
const {
return hasMips4() || hasMips32(); }
572 bool isGP64bit()
const {
573 return getSTI().hasFeature(Mips::FeatureGP64Bit);
576 bool isFP64bit()
const {
577 return getSTI().hasFeature(Mips::FeatureFP64Bit);
580 bool isJalrRelocAvailable(
const MCExpr *JalExpr) {
589 return ABI.IsN32() || ABI.IsN64();
593 const MipsABIInfo &
getABI()
const {
return ABI; }
594 bool isABI_N32()
const {
return ABI.IsN32(); }
595 bool isABI_N64()
const {
return ABI.IsN64(); }
596 bool isABI_O32()
const {
return ABI.IsO32(); }
597 bool isABI_FPXX()
const {
598 return getSTI().hasFeature(Mips::FeatureFPXX);
601 bool useOddSPReg()
const {
602 return !(getSTI().hasFeature(Mips::FeatureNoOddSPReg));
605 bool inMicroMipsMode()
const {
606 return getSTI().hasFeature(Mips::FeatureMicroMips);
609 bool hasMips1()
const {
610 return getSTI().hasFeature(Mips::FeatureMips1);
613 bool hasMips2()
const {
614 return getSTI().hasFeature(Mips::FeatureMips2);
617 bool hasMips3()
const {
618 return getSTI().hasFeature(Mips::FeatureMips3);
621 bool hasMips4()
const {
622 return getSTI().hasFeature(Mips::FeatureMips4);
625 bool hasMips5()
const {
626 return getSTI().hasFeature(Mips::FeatureMips5);
629 bool hasMips32()
const {
630 return getSTI().hasFeature(Mips::FeatureMips32);
633 bool hasMips64()
const {
634 return getSTI().hasFeature(Mips::FeatureMips64);
637 bool hasMips32r2()
const {
638 return getSTI().hasFeature(Mips::FeatureMips32r2);
641 bool hasMips64r2()
const {
642 return getSTI().hasFeature(Mips::FeatureMips64r2);
645 bool hasMips32r3()
const {
646 return (getSTI().
hasFeature(Mips::FeatureMips32r3));
649 bool hasMips64r3()
const {
650 return (getSTI().
hasFeature(Mips::FeatureMips64r3));
653 bool hasMips32r5()
const {
654 return (getSTI().
hasFeature(Mips::FeatureMips32r5));
657 bool hasMips64r5()
const {
658 return (getSTI().
hasFeature(Mips::FeatureMips64r5));
661 bool hasMips32r6()
const {
662 return getSTI().hasFeature(Mips::FeatureMips32r6);
665 bool hasMips64r6()
const {
666 return getSTI().hasFeature(Mips::FeatureMips64r6);
669 bool hasDSP()
const {
670 return getSTI().hasFeature(Mips::FeatureDSP);
673 bool hasDSPR2()
const {
674 return getSTI().hasFeature(Mips::FeatureDSPR2);
677 bool hasDSPR3()
const {
678 return getSTI().hasFeature(Mips::FeatureDSPR3);
681 bool hasMSA()
const {
682 return getSTI().hasFeature(Mips::FeatureMSA);
685 bool hasCnMips()
const {
686 return (getSTI().
hasFeature(Mips::FeatureCnMips));
689 bool hasCnMipsP()
const {
690 return (getSTI().
hasFeature(Mips::FeatureCnMipsP));
693 bool isR5900()
const {
return (getSTI().
hasFeature(Mips::FeatureR5900)); }
699 bool inMips16Mode()
const {
700 return getSTI().hasFeature(Mips::FeatureMips16);
703 bool useTraps()
const {
704 return getSTI().hasFeature(Mips::FeatureUseTCCInDIV);
707 bool useSoftFloat()
const {
708 return getSTI().hasFeature(Mips::FeatureSoftFloat);
711 bool isSingleFloat()
const {
712 return getSTI().hasFeature(Mips::FeatureSingleFloat);
716 return getSTI().hasFeature(Mips::FeatureMT);
719 bool hasCRC()
const {
720 return getSTI().hasFeature(Mips::FeatureCRC);
723 bool hasVirt()
const {
724 return getSTI().hasFeature(Mips::FeatureVirt);
727 bool hasGINV()
const {
728 return getSTI().hasFeature(Mips::FeatureGINV);
731 bool hasForbiddenSlot(
const MCInstrDesc &MCID)
const {
735 bool SafeInForbiddenSlot(
const MCInstrDesc &MCID)
const {
739 void onEndOfFile()
override;
742 void warnIfRegIndexIsAT(MCRegister RegIndex, SMLoc Loc);
744 void warnIfNoMacro(SMLoc Loc);
746 bool isLittle()
const {
return IsLittleEndian; }
748 bool areEqualRegs(
const MCParsedAsmOperand &Op1,
749 const MCParsedAsmOperand &Op2)
const override;
764 RegKind_MSACtrl = 16,
769 RegKind_HWRegs = 256,
773 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
774 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
775 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
788 MipsOperand(KindTy K, MipsAsmParser &Parser) : Kind(
K), AsmParser(Parser) {}
790 ~MipsOperand()
override {
799 case k_RegisterIndex:
807 MipsAsmParser &AsmParser;
818 const MCRegisterInfo *RegInfo;
836 struct RegIdxOp RegIdx;
839 struct RegListOp RegList;
842 SMLoc StartLoc, EndLoc;
845 static std::unique_ptr<MipsOperand> CreateReg(
unsigned Index, StringRef Str,
847 const MCRegisterInfo *RegInfo,
849 MipsAsmParser &Parser) {
850 auto Op = std::make_unique<MipsOperand>(k_RegisterIndex, Parser);
852 Op->RegIdx.RegInfo = RegInfo;
853 Op->RegIdx.Kind = RegKind;
854 Op->RegIdx.Tok.Data = Str.data();
855 Op->RegIdx.Tok.Length = Str.size();
864 MCRegister getGPR32Reg()
const {
865 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
866 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
867 unsigned ClassID = Mips::GPR32RegClassID;
868 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
873 MCRegister getGPRMM16Reg()
const {
874 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
875 unsigned ClassID = Mips::GPR32RegClassID;
876 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
881 MCRegister getGPR64Reg()
const {
882 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
883 unsigned ClassID = Mips::GPR64RegClassID;
884 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
890 MCRegister getAFGR64Reg()
const {
891 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
892 if (RegIdx.Index % 2 != 0)
893 AsmParser.Warning(StartLoc,
"Float register should be even.");
894 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
895 .getRegister(RegIdx.Index / 2);
900 MCRegister getFGR64Reg()
const {
901 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
902 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
903 .getRegister(RegIdx.Index);
908 MCRegister getFGR32Reg()
const {
909 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
910 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
911 .getRegister(RegIdx.Index);
916 MCRegister getFCCReg()
const {
917 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) &&
"Invalid access!");
918 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
919 .getRegister(RegIdx.Index);
924 MCRegister getMSA128Reg()
const {
925 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) &&
"Invalid access!");
928 unsigned ClassID = Mips::MSA128BRegClassID;
929 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
934 MCRegister getMSACtrlReg()
const {
935 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) &&
"Invalid access!");
936 unsigned ClassID = Mips::MSACtrlRegClassID;
937 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
942 MCRegister getCOP0Reg()
const {
943 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) &&
"Invalid access!");
944 unsigned ClassID = Mips::COP0RegClassID;
945 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
950 MCRegister getCOP2Reg()
const {
951 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) &&
"Invalid access!");
952 unsigned ClassID = Mips::COP2RegClassID;
953 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
958 MCRegister getCOP3Reg()
const {
959 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) &&
"Invalid access!");
960 unsigned ClassID = Mips::COP3RegClassID;
961 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
966 MCRegister getACC64DSPReg()
const {
967 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
968 unsigned ClassID = Mips::ACC64DSPRegClassID;
969 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
974 MCRegister getHI32DSPReg()
const {
975 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
976 unsigned ClassID = Mips::HI32DSPRegClassID;
977 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
982 MCRegister getLO32DSPReg()
const {
983 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
984 unsigned ClassID = Mips::LO32DSPRegClassID;
985 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
990 MCRegister getCCRReg()
const {
991 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) &&
"Invalid access!");
992 unsigned ClassID = Mips::CCRRegClassID;
993 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
998 MCRegister getHWRegsReg()
const {
999 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) &&
"Invalid access!");
1000 unsigned ClassID = Mips::HWRegsRegClassID;
1001 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1005 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const {
1015 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1022 void addGPR32ZeroAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1023 assert(
N == 1 &&
"Invalid number of operands!");
1027 void addGPR32NonZeroAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1028 assert(
N == 1 &&
"Invalid number of operands!");
1032 void addGPR32AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1033 assert(
N == 1 &&
"Invalid number of operands!");
1037 void addGPRMM16AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1038 assert(
N == 1 &&
"Invalid number of operands!");
1042 void addGPRMM16AsmRegZeroOperands(MCInst &Inst,
unsigned N)
const {
1043 assert(
N == 1 &&
"Invalid number of operands!");
1047 void addGPRMM16AsmRegMovePOperands(MCInst &Inst,
unsigned N)
const {
1048 assert(
N == 1 &&
"Invalid number of operands!");
1052 void addGPRMM16AsmRegMovePPairFirstOperands(MCInst &Inst,
unsigned N)
const {
1053 assert(
N == 1 &&
"Invalid number of operands!");
1057 void addGPRMM16AsmRegMovePPairSecondOperands(MCInst &Inst,
1059 assert(
N == 1 &&
"Invalid number of operands!");
1066 void addGPR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1067 assert(
N == 1 &&
"Invalid number of operands!");
1071 void addAFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1072 assert(
N == 1 &&
"Invalid number of operands!");
1076 void addStrictlyAFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1077 assert(
N == 1 &&
"Invalid number of operands!");
1081 void addStrictlyFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1082 assert(
N == 1 &&
"Invalid number of operands!");
1086 void addFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1087 assert(
N == 1 &&
"Invalid number of operands!");
1091 void addFGR32AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1092 assert(
N == 1 &&
"Invalid number of operands!");
1096 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1097 AsmParser.getParser().printError(
1098 StartLoc,
"-mno-odd-spreg prohibits the use of odd FPU "
1102 void addStrictlyFGR32AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1103 assert(
N == 1 &&
"Invalid number of operands!");
1106 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1107 AsmParser.Error(StartLoc,
"-mno-odd-spreg prohibits the use of odd FPU "
1111 void addFCCAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1112 assert(
N == 1 &&
"Invalid number of operands!");
1116 void addMSA128AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1117 assert(
N == 1 &&
"Invalid number of operands!");
1121 void addMSACtrlAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1122 assert(
N == 1 &&
"Invalid number of operands!");
1126 void addCOP0AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1127 assert(
N == 1 &&
"Invalid number of operands!");
1131 void addCOP2AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1132 assert(
N == 1 &&
"Invalid number of operands!");
1136 void addCOP3AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1137 assert(
N == 1 &&
"Invalid number of operands!");
1141 void addACC64DSPAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1142 assert(
N == 1 &&
"Invalid number of operands!");
1146 void addHI32DSPAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1147 assert(
N == 1 &&
"Invalid number of operands!");
1151 void addLO32DSPAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1152 assert(
N == 1 &&
"Invalid number of operands!");
1156 void addCCRAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1157 assert(
N == 1 &&
"Invalid number of operands!");
1161 void addHWRegsAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1162 assert(
N == 1 &&
"Invalid number of operands!");
1166 template <
unsigned Bits,
int Offset = 0,
int AdjustOffset = 0>
1167 void addConstantUImmOperands(MCInst &Inst,
unsigned N)
const {
1168 assert(
N == 1 &&
"Invalid number of operands!");
1172 Imm += AdjustOffset;
1176 template <
unsigned Bits>
1177 void addSImmOperands(MCInst &Inst,
unsigned N)
const {
1178 if (isImm() && !isConstantImm()) {
1182 addConstantSImmOperands<Bits, 0, 0>(Inst,
N);
1185 template <
unsigned Bits>
1186 void addUImmOperands(MCInst &Inst,
unsigned N)
const {
1187 if (isImm() && !isConstantImm()) {
1191 addConstantUImmOperands<Bits, 0, 0>(Inst,
N);
1194 template <
unsigned Bits,
int Offset = 0,
int AdjustOffset = 0>
1195 void addConstantSImmOperands(MCInst &Inst,
unsigned N)
const {
1196 assert(
N == 1 &&
"Invalid number of operands!");
1197 int64_t
Imm = getConstantImm() -
Offset;
1200 Imm += AdjustOffset;
1204 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1205 assert(
N == 1 &&
"Invalid number of operands!");
1206 const MCExpr *Expr =
getImm();
1207 addExpr(Inst, Expr);
1210 void addMemOperands(MCInst &Inst,
unsigned N)
const {
1211 assert(
N == 2 &&
"Invalid number of operands!");
1214 ? getMemBase()->getGPR64Reg()
1215 : getMemBase()->getGPR32Reg()));
1217 const MCExpr *Expr = getMemOff();
1218 addExpr(Inst, Expr);
1221 void addMicroMipsMemOperands(MCInst &Inst,
unsigned N)
const {
1222 assert(
N == 2 &&
"Invalid number of operands!");
1226 const MCExpr *Expr = getMemOff();
1227 addExpr(Inst, Expr);
1230 void addRegListOperands(MCInst &Inst,
unsigned N)
const {
1231 assert(
N == 1 &&
"Invalid number of operands!");
1233 for (
auto RegNo : getRegList())
1237 bool isReg()
const override {
1240 return isGPRAsmReg() && RegIdx.Index == 0;
1243 bool isRegIdx()
const {
return Kind == k_RegisterIndex; }
1244 bool isImm()
const override {
return Kind == k_Immediate; }
1246 bool isConstantImm()
const {
1248 return isImm() &&
getImm()->evaluateAsAbsolute(Res);
1251 bool isConstantImmz()
const {
1252 return isConstantImm() && getConstantImm() == 0;
1255 template <
unsigned Bits,
int Offset = 0>
bool isConstantUImm()
const {
1259 template <
unsigned Bits>
bool isSImm()
const {
1263 if (
getImm()->evaluateAsAbsolute(Res))
1269 template <
unsigned Bits>
bool isUImm()
const {
1273 if (
getImm()->evaluateAsAbsolute(Res))
1279 template <
unsigned Bits>
bool isAnyImm()
const {
1280 return isConstantImm() ? (
isInt<Bits>(getConstantImm()) ||
1285 template <
unsigned Bits,
int Offset = 0>
bool isConstantSImm()
const {
1289 template <
unsigned Bottom,
unsigned Top>
bool isConstantUImmRange()
const {
1290 return isConstantImm() && getConstantImm() >= Bottom &&
1291 getConstantImm() <= Top;
1294 bool isToken()
const override {
1297 return Kind == k_Token;
1300 bool isMem()
const override {
return Kind == k_Memory; }
1302 bool isConstantMemOff()
const {
1307 template <
unsigned Bits,
unsigned ShiftAmount = 0>
1308 bool isMemWithSimmOffset()
const {
1311 if (!getMemBase()->isGPRAsmReg())
1314 (isConstantMemOff() &&
1318 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res,
nullptr);
1322 bool isMemWithPtrSizeOffset()
const {
1325 if (!getMemBase()->isGPRAsmReg())
1327 const unsigned PtrBits = AsmParser.getABI().ArePtrs64bit() ? 64 : 32;
1329 (isConstantMemOff() &&
isIntN(PtrBits, getConstantMemOff())))
1332 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res,
nullptr);
1336 bool isMemWithGRPMM16Base()
const {
1337 return isMem() && getMemBase()->isMM16AsmReg();
1340 template <
unsigned Bits>
bool isMemWithUimmOffsetSP()
const {
1342 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1345 template <
unsigned Bits>
bool isMemWithUimmWordAlignedOffsetSP()
const {
1347 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1348 && (getMemBase()->getGPR32Reg() == Mips::SP);
1351 template <
unsigned Bits>
bool isMemWithSimmWordAlignedOffsetGP()
const {
1353 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1354 && (getMemBase()->getGPR32Reg() == Mips::GP);
1357 template <
unsigned Bits,
unsigned ShiftLeftAmount>
1358 bool isScaledUImm()
const {
1359 return isConstantImm() &&
1363 template <
unsigned Bits,
unsigned ShiftLeftAmount>
1364 bool isScaledSImm()
const {
1365 if (isConstantImm() &&
1370 if (Kind != k_Immediate)
1373 bool Success =
getImm()->evaluateAsRelocatable(Res,
nullptr);
1377 bool isRegList16()
const {
1381 int Size = RegList.List->size();
1385 MCRegister R0 = RegList.List->front();
1386 MCRegister R1 = RegList.List->back();
1387 if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1388 (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1391 MCRegister PrevReg = RegList.List->front();
1392 for (
int i = 1; i <
Size - 1; i++) {
1393 MCRegister
Reg = (*(RegList.List))[i];
1394 if (
Reg != PrevReg + 1)
1402 bool isInvNum()
const {
return Kind == k_Immediate; }
1404 bool isLSAImm()
const {
1405 if (!isConstantImm())
1407 int64_t Val = getConstantImm();
1408 return 1 <= Val && Val <= 4;
1411 bool isRegList()
const {
return Kind == k_RegList; }
1414 assert(Kind == k_Token &&
"Invalid access!");
1415 return StringRef(Tok.Data, Tok.Length);
1418 MCRegister
getReg()
const override {
1421 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1422 RegIdx.Kind & RegKind_GPR)
1423 return getGPR32Reg();
1429 const MCExpr *
getImm()
const {
1430 assert((Kind == k_Immediate) &&
"Invalid access!");
1434 int64_t getConstantImm()
const {
1435 const MCExpr *Val =
getImm();
1437 (void)Val->evaluateAsAbsolute(
Value);
1441 MipsOperand *getMemBase()
const {
1442 assert((Kind == k_Memory) &&
"Invalid access!");
1446 const MCExpr *getMemOff()
const {
1447 assert((Kind == k_Memory) &&
"Invalid access!");
1451 int64_t getConstantMemOff()
const {
1452 return static_cast<const MCConstantExpr *
>(getMemOff())->
getValue();
1455 const SmallVectorImpl<MCRegister> &getRegList()
const {
1456 assert((Kind == k_RegList) &&
"Invalid access!");
1457 return *(RegList.List);
1460 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1461 MipsAsmParser &Parser) {
1462 auto Op = std::make_unique<MipsOperand>(k_Token, Parser);
1463 Op->Tok.Data = Str.data();
1464 Op->Tok.Length = Str.size();
1472 static std::unique_ptr<MipsOperand>
1473 createNumericReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1474 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1475 LLVM_DEBUG(
dbgs() <<
"createNumericReg(" << Index <<
", ...)\n");
1476 return CreateReg(Index, Str, RegKind_Numeric, RegInfo, S,
E, Parser);
1481 static std::unique_ptr<MipsOperand>
1482 createGPRReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1483 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1484 return CreateReg(Index, Str, RegKind_GPR, RegInfo, S,
E, Parser);
1489 static std::unique_ptr<MipsOperand>
1490 createFGRReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1491 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1492 return CreateReg(Index, Str, RegKind_FGR, RegInfo, S,
E, Parser);
1497 static std::unique_ptr<MipsOperand>
1498 createHWRegsReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1499 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1500 return CreateReg(Index, Str, RegKind_HWRegs, RegInfo, S,
E, Parser);
1505 static std::unique_ptr<MipsOperand>
1506 createFCCReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1507 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1508 return CreateReg(Index, Str, RegKind_FCC, RegInfo, S,
E, Parser);
1513 static std::unique_ptr<MipsOperand>
1514 createACCReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1515 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1516 return CreateReg(Index, Str, RegKind_ACC, RegInfo, S,
E, Parser);
1521 static std::unique_ptr<MipsOperand>
1522 createMSA128Reg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1523 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1524 return CreateReg(Index, Str, RegKind_MSA128, RegInfo, S,
E, Parser);
1529 static std::unique_ptr<MipsOperand>
1530 createMSACtrlReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1531 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1532 return CreateReg(Index, Str, RegKind_MSACtrl, RegInfo, S,
E, Parser);
1535 static std::unique_ptr<MipsOperand>
1536 CreateImm(
const MCExpr *Val, SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1537 auto Op = std::make_unique<MipsOperand>(k_Immediate, Parser);
1544 static std::unique_ptr<MipsOperand>
1545 CreateMem(std::unique_ptr<MipsOperand>
Base,
const MCExpr *Off, SMLoc S,
1546 SMLoc
E, MipsAsmParser &Parser) {
1547 auto Op = std::make_unique<MipsOperand>(k_Memory, Parser);
1548 Op->Mem.Base =
Base.release();
1555 static std::unique_ptr<MipsOperand>
1556 CreateRegList(SmallVectorImpl<MCRegister> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1557 MipsAsmParser &Parser) {
1558 assert(!Regs.
empty() &&
"Empty list not allowed");
1560 auto Op = std::make_unique<MipsOperand>(k_RegList, Parser);
1563 Op->StartLoc = StartLoc;
1564 Op->EndLoc = EndLoc;
1568 bool isGPRZeroAsmReg()
const {
1569 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
1572 bool isGPRNonZeroAsmReg()
const {
1573 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index > 0 &&
1577 bool isGPRAsmReg()
const {
1578 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1581 bool isMM16AsmReg()
const {
1582 if (!(isRegIdx() && RegIdx.Kind))
1584 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1585 || RegIdx.Index == 16 || RegIdx.Index == 17);
1588 bool isMM16AsmRegZero()
const {
1589 if (!(isRegIdx() && RegIdx.Kind))
1591 return (RegIdx.Index == 0 ||
1592 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1593 RegIdx.Index == 17);
1596 bool isMM16AsmRegMoveP()
const {
1597 if (!(isRegIdx() && RegIdx.Kind))
1599 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1600 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1603 bool isMM16AsmRegMovePPairFirst()
const {
1604 if (!(isRegIdx() && RegIdx.Kind))
1606 return RegIdx.Index >= 4 && RegIdx.Index <= 6;
1609 bool isMM16AsmRegMovePPairSecond()
const {
1610 if (!(isRegIdx() && RegIdx.Kind))
1612 return (RegIdx.Index == 21 || RegIdx.Index == 22 ||
1613 (RegIdx.Index >= 5 && RegIdx.Index <= 7));
1616 bool isFGRAsmReg()
const {
1618 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1621 bool isStrictlyFGRAsmReg()
const {
1623 return isRegIdx() && RegIdx.Kind == RegKind_FGR && RegIdx.Index <= 31;
1626 bool isHWRegsAsmReg()
const {
1627 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1630 bool isCCRAsmReg()
const {
1631 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1634 bool isFCCAsmReg()
const {
1635 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1637 return RegIdx.Index <= 7;
1640 bool isACCAsmReg()
const {
1641 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1644 bool isCOP0AsmReg()
const {
1645 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1648 bool isCOP2AsmReg()
const {
1649 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1652 bool isCOP3AsmReg()
const {
1653 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1656 bool isMSA128AsmReg()
const {
1657 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1660 bool isMSACtrlAsmReg()
const {
1661 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1665 SMLoc getStartLoc()
const override {
return StartLoc; }
1667 SMLoc getEndLoc()
const override {
return EndLoc; }
1669 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1678 Mem.Base->print(OS, MAI);
1683 case k_RegisterIndex:
1684 OS <<
"RegIdx<" << RegIdx.Index <<
":" << RegIdx.Kind <<
", "
1685 << StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) <<
">";
1692 for (
auto Reg : (*RegList.List))
1693 OS <<
Reg.
id() <<
" ";
1699 bool isValidForTie(
const MipsOperand &
Other)
const {
1700 if (Kind !=
Other.Kind)
1707 case k_RegisterIndex: {
1708 StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length);
1709 StringRef OtherToken(
Other.RegIdx.Tok.Data,
Other.RegIdx.Tok.Length);
1710 return Token == OtherToken;
1726 case Mips::JRC16_MM:
1728 case Mips::JALRS_MM:
1729 case Mips::JALRS16_MM:
1730 case Mips::BGEZALS_MM:
1731 case Mips::BLTZALS_MM:
1742 return &SRExpr->getSymbol();
1801 unsigned NumOp =
MCID.getNumOperands();
1802 if (NumOp != 3 && NumOp != 4)
1832bool MipsAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
1835 MipsTargetStreamer &TOut = getTargetStreamer();
1836 const unsigned Opcode = Inst.
getOpcode();
1837 const MCInstrDesc &MCID = MII.get(Opcode);
1838 bool ExpandedJalSym =
false;
1852 assert(hasCnMips() &&
"instruction only valid for octeon cpus");
1863 if (!
isIntN(inMicroMipsMode() ? 17 : 18,
Offset.getImm()))
1864 return Error(IDLoc,
"branch target out of range");
1867 return Error(IDLoc,
"branch to misaligned address");
1881 case Mips::BGEZAL_MM:
1882 case Mips::BLTZAL_MM:
1885 case Mips::BC1EQZC_MMR6:
1886 case Mips::BC1NEZC_MMR6:
1887 case Mips::BC2EQZC_MMR6:
1888 case Mips::BC2NEZC_MMR6:
1893 if (!
isIntN(inMicroMipsMode() ? 17 : 18,
Offset.getImm()))
1894 return Error(IDLoc,
"branch target out of range");
1897 return Error(IDLoc,
"branch to misaligned address");
1899 case Mips::BGEC:
case Mips::BGEC_MMR6:
1900 case Mips::BLTC:
case Mips::BLTC_MMR6:
1901 case Mips::BGEUC:
case Mips::BGEUC_MMR6:
1902 case Mips::BLTUC:
case Mips::BLTUC_MMR6:
1903 case Mips::BEQC:
case Mips::BEQC_MMR6:
1904 case Mips::BNEC:
case Mips::BNEC_MMR6:
1910 return Error(IDLoc,
"branch target out of range");
1912 return Error(IDLoc,
"branch to misaligned address");
1914 case Mips::BLEZC:
case Mips::BLEZC_MMR6:
1915 case Mips::BGEZC:
case Mips::BGEZC_MMR6:
1916 case Mips::BGTZC:
case Mips::BGTZC_MMR6:
1917 case Mips::BLTZC:
case Mips::BLTZC_MMR6:
1923 return Error(IDLoc,
"branch target out of range");
1925 return Error(IDLoc,
"branch to misaligned address");
1927 case Mips::BEQZC:
case Mips::BEQZC_MMR6:
1928 case Mips::BNEZC:
case Mips::BNEZC_MMR6:
1934 return Error(IDLoc,
"branch target out of range");
1936 return Error(IDLoc,
"branch to misaligned address");
1938 case Mips::BEQZ16_MM:
1939 case Mips::BEQZC16_MMR6:
1940 case Mips::BNEZ16_MM:
1941 case Mips::BNEZC16_MMR6:
1947 return Error(IDLoc,
"branch target out of range");
1949 return Error(IDLoc,
"branch to misaligned address");
1956 if (hasMips32r6() && Opcode == Mips::SSNOP) {
1957 std::string
ISA = hasMips64r6() ?
"MIPS64r6" :
"MIPS32r6";
1958 Warning(IDLoc,
"ssnop is deprecated for " + ISA +
" and is equivalent to a "
1978 return Error(IDLoc,
"expected immediate operand kind");
1981 Opcode == Mips::BBIT1 ? 63 : 31))
1982 return Error(IDLoc,
"immediate operand value out of range");
1984 Inst.
setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1995 return Error(IDLoc,
"expected immediate operand kind");
1998 return Error(IDLoc,
"immediate operand value out of range");
2010 unsigned FirstOp = 1;
2011 unsigned SecondOp = 2;
2015 case Mips::SDivIMacro:
2016 case Mips::UDivIMacro:
2017 case Mips::DSDivIMacro:
2018 case Mips::DUDivIMacro:
2020 return Error(IDLoc,
"expected immediate operand kind");
2024 Warning(IDLoc,
"dividing zero by zero");
2026 Warning(IDLoc,
"division by zero");
2038 case Mips::SDivMacro:
2039 case Mips::DSDivMacro:
2040 case Mips::UDivMacro:
2041 case Mips::DUDivMacro:
2046 case Mips::DIVU_MMR6:
2047 case Mips::DIV_MMR6:
2052 Warning(IDLoc,
"dividing zero by zero");
2054 Warning(IDLoc,
"division by zero");
2060 if ((Opcode == Mips::J || Opcode == Mips::J_MM) && inPicMode()) {
2062 BInst.
setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
2071 if ((Opcode == Mips::JAL || Opcode == Mips::JAL_MM) && inPicMode()) {
2072 warnIfNoMacro(IDLoc);
2075 return Error(IDLoc,
"unsupported constant in relocation");
2083 return Error(IDLoc,
"jal doesn't support multiple symbols in PIC mode");
2089 if (expandLoadAddress(Mips::T9, MCRegister(), Inst.
getOperand(0),
2090 !isGP64bit(), IDLoc, Out, STI))
2094 if (inMicroMipsMode())
2095 JalrInst.
setOpcode(IsCpRestoreSet ? Mips::JALRS_MM : Mips::JALR_MM);
2101 if (isJalrRelocAvailable(JalExpr)) {
2107 const MCExpr *RelocJalrExpr =
2111 *TmpExpr, inMicroMipsMode() ?
"R_MICROMIPS_JALR" :
"R_MIPS_JALR",
2117 ExpandedJalSym =
true;
2126 expandMem9Inst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2129 expandMem16Inst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2132 return getParser().hasPendingError();
2136 if (inMicroMipsMode()) {
2137 if (MCID.
mayLoad() && Opcode != Mips::LWP_MM) {
2140 const MCOperandInfo &OpInfo = MCID.
operands()[i];
2145 int MemOffset =
Op.getImm();
2148 if (
isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
2151 (
BaseReg.getReg() == Mips::GP ||
2152 BaseReg.getReg() == Mips::GP_64)) {
2154 TOut.
emitRRI(Mips::LWGP_MM, DstReg.
getReg(), Mips::GP, MemOffset,
2171 case Mips::ADDIUSP_MM:
2174 return Error(IDLoc,
"expected immediate operand kind");
2178 return Error(IDLoc,
"immediate operand value out of range");
2180 case Mips::SLL16_MM:
2181 case Mips::SRL16_MM:
2184 return Error(IDLoc,
"expected immediate operand kind");
2187 return Error(IDLoc,
"immediate operand value out of range");
2192 return Error(IDLoc,
"expected immediate operand kind");
2195 return Error(IDLoc,
"immediate operand value out of range");
2197 case Mips::ADDIUR2_MM:
2200 return Error(IDLoc,
"expected immediate operand kind");
2202 if (!(
Imm == 1 ||
Imm == -1 ||
2204 return Error(IDLoc,
"immediate operand value out of range");
2206 case Mips::ANDI16_MM:
2209 return Error(IDLoc,
"expected immediate operand kind");
2213 Imm == 64 ||
Imm == 255 ||
Imm == 32768 ||
Imm == 65535))
2214 return Error(IDLoc,
"immediate operand value out of range");
2216 case Mips::LBU16_MM:
2219 return Error(IDLoc,
"expected immediate operand kind");
2222 return Error(IDLoc,
"immediate operand value out of range");
2225 case Mips::SB16_MMR6:
2228 return Error(IDLoc,
"expected immediate operand kind");
2231 return Error(IDLoc,
"immediate operand value out of range");
2233 case Mips::LHU16_MM:
2235 case Mips::SH16_MMR6:
2238 return Error(IDLoc,
"expected immediate operand kind");
2241 return Error(IDLoc,
"immediate operand value out of range");
2245 case Mips::SW16_MMR6:
2248 return Error(IDLoc,
"expected immediate operand kind");
2251 return Error(IDLoc,
"immediate operand value out of range");
2253 case Mips::ADDIUPC_MM:
2256 return Error(IDLoc,
"expected immediate operand kind");
2259 return Error(IDLoc,
"immediate operand value out of range");
2264 return Error(IDLoc,
"invalid operand for instruction");
2266 case Mips::MOVEP_MM:
2267 case Mips::MOVEP_MMR6: {
2270 bool RegPair = ((R0 == Mips::A1 && R1 == Mips::A2) ||
2271 (R0 == Mips::A1 && R1 == Mips::A3) ||
2272 (R0 == Mips::A2 && R1 == Mips::A3) ||
2273 (R0 == Mips::A0 && R1 == Mips::S5) ||
2274 (R0 == Mips::A0 && R1 == Mips::S6) ||
2275 (R0 == Mips::A0 && R1 == Mips::A1) ||
2276 (R0 == Mips::A0 && R1 == Mips::A2) ||
2277 (R0 == Mips::A0 && R1 == Mips::A3));
2279 return Error(IDLoc,
"invalid operand for instruction");
2285 bool FillDelaySlot =
2290 bool PrevForbiddenSlotAttr = CurForbiddenSlotAttr;
2293 bool SetReorderAfterNop =
false;
2298 if (PrevForbiddenSlotAttr && !SafeInForbiddenSlot(MCID)) {
2308 if (AssemblerOptions.
back()->isReorder() && !FillDelaySlot) {
2309 SetReorderAfterNop =
true;
2318 CurForbiddenSlotAttr =
2319 hasForbiddenSlot(MCID) && AssemblerOptions.
back()->isReorder();
2321 if (FillDelaySlot || CurForbiddenSlotAttr)
2324 MacroExpanderResultTy ExpandResult =
2325 tryExpandInstruction(Inst, IDLoc, Out, STI);
2326 switch (ExpandResult) {
2328 Out.emitInstruction(Inst, *STI);
2342 if (PrevForbiddenSlotAttr && !SetReorderAfterNop && !FillDelaySlot &&
2343 AssemblerOptions.
back()->isReorder()) {
2349 if (inMicroMipsMode()) {
2364 if (FillDelaySlot) {
2369 if ((Opcode == Mips::JalOneReg || Opcode == Mips::JalTwoReg ||
2371 isPicAndNotNxxAbi()) {
2372 if (IsCpRestoreSet) {
2376 if (!AssemblerOptions.
back()->isReorder())
2383 Warning(IDLoc,
"no .cprestore used in PIC mode");
2389void MipsAsmParser::onEndOfFile() {
2390 MipsTargetStreamer &TOut = getTargetStreamer();
2391 SMLoc IDLoc = SMLoc();
2393 if (CurForbiddenSlotAttr) {
2395 if (AssemblerOptions.
back()->isReorder())
2400MipsAsmParser::MacroExpanderResultTy
2401MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2402 const MCSubtargetInfo *STI) {
2405 return MER_NotAMacro;
2406 case Mips::LoadImm32:
2407 return expandLoadImm(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2408 case Mips::LoadImm64:
2409 return expandLoadImm(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2410 case Mips::LoadAddrImm32:
2411 case Mips::LoadAddrImm64:
2414 "expected immediate operand kind");
2416 return expandLoadAddress(
2418 Inst.
getOpcode() == Mips::LoadAddrImm32, IDLoc, Out, STI)
2421 case Mips::LoadAddrReg32:
2422 case Mips::LoadAddrReg64:
2426 "expected immediate operand kind");
2430 Inst.
getOpcode() == Mips::LoadAddrReg32, IDLoc,
2434 case Mips::B_MM_Pseudo:
2435 case Mips::B_MMR6_Pseudo:
2436 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2440 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2442 case Mips::JalOneReg:
2443 case Mips::JalTwoReg:
2444 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2447 case Mips::BEQLImmMacro:
2448 case Mips::BNELImmMacro:
2449 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2466 case Mips::BLTImmMacro:
2467 case Mips::BLEImmMacro:
2468 case Mips::BGEImmMacro:
2469 case Mips::BGTImmMacro:
2470 case Mips::BLTUImmMacro:
2471 case Mips::BLEUImmMacro:
2472 case Mips::BGEUImmMacro:
2473 case Mips::BGTUImmMacro:
2474 case Mips::BLTLImmMacro:
2475 case Mips::BLELImmMacro:
2476 case Mips::BGELImmMacro:
2477 case Mips::BGTLImmMacro:
2478 case Mips::BLTULImmMacro:
2479 case Mips::BLEULImmMacro:
2480 case Mips::BGEULImmMacro:
2481 case Mips::BGTULImmMacro:
2482 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2483 case Mips::SDivMacro:
2484 case Mips::SDivIMacro:
2485 case Mips::SRemMacro:
2486 case Mips::SRemIMacro:
2487 return expandDivRem(Inst, IDLoc, Out, STI,
false,
true) ? MER_Fail
2489 case Mips::DSDivMacro:
2490 case Mips::DSDivIMacro:
2491 case Mips::DSRemMacro:
2492 case Mips::DSRemIMacro:
2493 return expandDivRem(Inst, IDLoc, Out, STI,
true,
true) ? MER_Fail
2495 case Mips::UDivMacro:
2496 case Mips::UDivIMacro:
2497 case Mips::URemMacro:
2498 case Mips::URemIMacro:
2499 return expandDivRem(Inst, IDLoc, Out, STI,
false,
false) ? MER_Fail
2501 case Mips::DUDivMacro:
2502 case Mips::DUDivIMacro:
2503 case Mips::DURemMacro:
2504 case Mips::DURemIMacro:
2505 return expandDivRem(Inst, IDLoc, Out, STI,
true,
false) ? MER_Fail
2507 case Mips::PseudoTRUNC_W_S:
2508 return expandTrunc(Inst,
false,
false, IDLoc, Out, STI) ? MER_Fail
2510 case Mips::PseudoTRUNC_W_D32:
2511 return expandTrunc(Inst,
true,
false, IDLoc, Out, STI) ? MER_Fail
2513 case Mips::PseudoTRUNC_W_D:
2514 return expandTrunc(Inst,
true,
true, IDLoc, Out, STI) ? MER_Fail
2517 case Mips::LoadImmSingleGPR:
2518 return expandLoadSingleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2520 case Mips::LoadImmSingleFGR:
2521 return expandLoadSingleImmToFPR(Inst, IDLoc, Out, STI) ? MER_Fail
2523 case Mips::LoadImmDoubleGPR:
2524 return expandLoadDoubleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2526 case Mips::LoadImmDoubleFGR:
2527 return expandLoadDoubleImmToFPR(Inst,
true, IDLoc, Out, STI) ? MER_Fail
2529 case Mips::LoadImmDoubleFGR_32:
2530 return expandLoadDoubleImmToFPR(Inst,
false, IDLoc, Out, STI) ? MER_Fail
2534 return expandUlh(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2536 return expandUlh(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2538 return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2541 return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2543 case Mips::NORImm64:
2544 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2547 return expandSge(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2550 case Mips::SGEImm64:
2551 case Mips::SGEUImm64:
2552 return expandSgeImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2555 case Mips::SGTImm64:
2556 case Mips::SGTUImm64:
2557 return expandSgtImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2560 return expandSle(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2563 case Mips::SLEImm64:
2564 case Mips::SLEUImm64:
2565 return expandSleImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2566 case Mips::SLTImm64:
2569 return MER_NotAMacro;
2571 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2572 case Mips::SLTUImm64:
2575 return MER_NotAMacro;
2577 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2578 case Mips::ADDi:
case Mips::ADDi_MM:
2579 case Mips::ADDiu:
case Mips::ADDiu_MM:
2580 case Mips::SLTi:
case Mips::SLTi_MM:
2581 case Mips::SLTiu:
case Mips::SLTiu_MM:
2586 return MER_NotAMacro;
2587 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2590 return MER_NotAMacro;
2591 case Mips::ANDi:
case Mips::ANDi_MM:
case Mips::ANDi64:
2592 case Mips::ORi:
case Mips::ORi_MM:
case Mips::ORi64:
2593 case Mips::XORi:
case Mips::XORi_MM:
case Mips::XORi64:
2598 return MER_NotAMacro;
2599 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2602 return MER_NotAMacro;
2605 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2608 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2611 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2614 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2615 case Mips::ABSMacro:
2616 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2617 case Mips::MULImmMacro:
2618 case Mips::DMULImmMacro:
2619 return expandMulImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2620 case Mips::MULOMacro:
2621 case Mips::DMULOMacro:
2622 return expandMulO(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2623 case Mips::MULOUMacro:
2624 case Mips::DMULOUMacro:
2625 return expandMulOU(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2626 case Mips::DMULMacro:
2627 return expandDMULMacro(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2630 return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2635 return expandStoreDM1Macro(Inst, IDLoc, Out, STI)
2638 case Mips::SEQMacro:
2639 return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2640 case Mips::SEQIMacro:
2641 return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2642 case Mips::SNEMacro:
2643 return expandSne(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2644 case Mips::SNEIMacro:
2645 return expandSneI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2646 case Mips::MFTC0:
case Mips::MTTC0:
2647 case Mips::MFTGPR:
case Mips::MTTGPR:
2648 case Mips::MFTLO:
case Mips::MTTLO:
2649 case Mips::MFTHI:
case Mips::MTTHI:
2650 case Mips::MFTACX:
case Mips::MTTACX:
2651 case Mips::MFTDSP:
case Mips::MTTDSP:
2652 case Mips::MFTC1:
case Mips::MTTC1:
2653 case Mips::MFTHC1:
case Mips::MTTHC1:
2654 case Mips::CFTC1:
case Mips::CTTC1:
2655 return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2657 case Mips::SaadAddr:
2658 return expandSaaAddr(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2662bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2664 const MCSubtargetInfo *STI) {
2665 MipsTargetStreamer &TOut = getTargetStreamer();
2670 const MCOperand FirstRegOp = Inst.
getOperand(0);
2671 const unsigned Opcode = Inst.
getOpcode();
2673 if (Opcode == Mips::JalOneReg) {
2675 if (IsCpRestoreSet && inMicroMipsMode()) {
2678 }
else if (inMicroMipsMode()) {
2679 JalrInst.
setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2686 }
else if (Opcode == Mips::JalTwoReg) {
2688 if (IsCpRestoreSet && inMicroMipsMode())
2691 JalrInst.
setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2693 const MCOperand SecondRegOp = Inst.
getOperand(1);
2696 Out.emitInstruction(JalrInst, *STI);
2700 const MCInstrDesc &MCID = MII.get(JalrInst.
getOpcode());
2723bool MipsAsmParser::loadImmediate(int64_t ImmValue, MCRegister DstReg,
2724 MCRegister SrcReg,
bool Is32BitImm,
2725 bool IsAddress, SMLoc IDLoc, MCStreamer &Out,
2726 const MCSubtargetInfo *STI) {
2727 MipsTargetStreamer &TOut = getTargetStreamer();
2729 if (!Is32BitImm && !isGP64bit()) {
2730 Error(IDLoc,
"instruction requires a 64-bit architecture");
2741 Error(IDLoc,
"instruction requires a 32-bit immediate");
2746 MCRegister ZeroReg = IsAddress ?
ABI.GetNullPtr() :
ABI.GetZeroReg();
2747 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2749 bool UseSrcReg =
false;
2753 MCRegister TmpReg = DstReg;
2755 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2758 MCRegister ATReg = getATReg(IDLoc);
2771 if (IsAddress && !Is32BitImm) {
2772 TOut.
emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2776 TOut.
emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2781 MCRegister TmpReg = DstReg;
2782 if (SrcReg == DstReg) {
2783 TmpReg = getATReg(IDLoc);
2788 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2790 TOut.
emitRRR(
ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2795 warnIfNoMacro(IDLoc);
2797 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2798 uint16_t Bits15To0 = ImmValue & 0xffff;
2799 if (!Is32BitImm && !
isInt<32>(ImmValue)) {
2802 if (ImmValue == 0xffffffff) {
2803 TOut.
emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2804 TOut.
emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2806 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2812 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2813 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2815 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2817 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2821 TOut.
emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2823 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2825 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2831 Error(IDLoc,
"instruction requires a 32-bit immediate");
2838 assert(
BitWidth >= 17 &&
"ImmValue must be at least 17-bit wide");
2842 unsigned ShiftAmount =
BitWidth - 16;
2843 uint16_t
Bits = (ImmValue >> ShiftAmount) & 0xffff;
2844 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2845 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2848 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2853 warnIfNoMacro(IDLoc);
2860 if (loadImmediate(ImmValue >> 32, TmpReg, MCRegister(),
true,
false, IDLoc,
2866 unsigned ShiftCarriedForwards = 16;
2867 for (
int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2868 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2870 if (ImmChunk != 0) {
2871 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2872 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2873 ShiftCarriedForwards = 0;
2876 ShiftCarriedForwards += 16;
2878 ShiftCarriedForwards -= 16;
2881 if (ShiftCarriedForwards)
2882 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2885 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2890bool MipsAsmParser::expandLoadImm(MCInst &Inst,
bool Is32BitImm, SMLoc IDLoc,
2891 MCStreamer &Out,
const MCSubtargetInfo *STI) {
2893 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
2894 const MCOperand &DstRegOp = Inst.
getOperand(0);
2895 assert(DstRegOp.
isReg() &&
"expected register operand kind");
2897 if (loadImmediate(ImmOp.
getImm(), DstRegOp.
getReg(), MCRegister(), Is32BitImm,
2898 false, IDLoc, Out, STI))
2904bool MipsAsmParser::expandLoadAddress(MCRegister DstReg, MCRegister BaseReg,
2906 bool Is32BitAddress, SMLoc IDLoc,
2908 const MCSubtargetInfo *STI) {
2910 if (Is32BitAddress &&
ABI.ArePtrs64bit()) {
2911 Warning(IDLoc,
"la used to load 64-bit address");
2913 Is32BitAddress =
false;
2917 if (!Is32BitAddress && !hasMips3()) {
2918 Error(IDLoc,
"instruction requires a 64-bit architecture");
2923 return loadAndAddSymbolAddress(
Offset.getExpr(), DstReg, BaseReg,
2924 Is32BitAddress, IDLoc, Out, STI);
2926 if (!
ABI.ArePtrs64bit()) {
2928 Is32BitAddress =
true;
2931 return loadImmediate(
Offset.getImm(), DstReg, BaseReg, Is32BitAddress,
true,
2935bool MipsAsmParser::loadAndAddSymbolAddress(
const MCExpr *SymExpr,
2937 MCRegister SrcReg,
bool Is32BitSym,
2938 SMLoc IDLoc, MCStreamer &Out,
2939 const MCSubtargetInfo *STI) {
2940 MipsTargetStreamer &TOut = getTargetStreamer();
2942 SrcReg.
isValid() && SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64;
2943 warnIfNoMacro(IDLoc);
2948 Error(IDLoc,
"expected relocatable expression");
2952 Error(IDLoc,
"expected relocatable expression with only one symbol");
2956 bool IsPtr64 =
ABI.ArePtrs64bit();
2959 ?
static_cast<const MCSymbolELF *
>(Res.
getAddSym())
2967 bool UseXGOT = STI->
hasFeature(Mips::FeatureXGOT) && !IsLocalSym;
2973 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2976 const MCExpr *CallHiExpr =
2978 const MCExpr *CallLoExpr =
2982 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, DstReg, GPReg,
2984 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, DstReg,
2987 const MCExpr *CallExpr =
2989 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, GPReg,
2995 MCRegister TmpReg = DstReg;
2997 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
3001 MCRegister ATReg = getATReg(IDLoc);
3020 const MCExpr *CallHiExpr =
3027 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg, GPReg,
3029 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, TmpReg,
3033 TOut.
emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3039 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3044 const MCSpecifierExpr *GotExpr =
nullptr;
3045 const MCExpr *LoExpr =
nullptr;
3046 if (
ABI.IsN32() ||
ABI.IsN64()) {
3065 Error(IDLoc,
"macro instruction uses large offset, which is not "
3066 "currently supported");
3095 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, GPReg,
3099 TOut.
emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3103 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3109 const auto *HiExpr =
3111 const auto *LoExpr =
3115 if (
ABI.ArePtrs64bit() && isGP64bit()) {
3123 const auto *HighestExpr =
3125 const auto *HigherExpr =
3130 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
3132 if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
3133 MCRegister ATReg = getATReg(IDLoc);
3145 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3147 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3150 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3153 TOut.
emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
3156 }
else if (canUseATReg() && !RdRegIsRsReg && DstReg != getATReg(IDLoc)) {
3157 MCRegister ATReg = getATReg(IDLoc);
3173 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3177 TOut.
emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3178 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3180 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3183 }
else if ((!canUseATReg() && !RdRegIsRsReg) ||
3184 (canUseATReg() && DstReg == getATReg(IDLoc))) {
3195 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3197 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3198 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3200 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3201 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3204 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3210 assert(SrcReg == DstReg && !canUseATReg() &&
3211 "Could have expanded dla but didn't?");
3212 reportParseError(IDLoc,
3213 "pseudo-instruction requires $at, which is not available");
3227 MCRegister TmpReg = DstReg;
3229 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
3232 MCRegister ATReg = getATReg(IDLoc);
3243 TOut.
emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3246 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
3255 if (getMipsMCRegisterClass(Mips::FGR32RegClassID).
contains(
Reg))
3256 return Reg == (
unsigned)Mips::F31 ? (
unsigned)Mips::F0 :
Reg + 1;
3258 default:
llvm_unreachable(
"Unknown register in assembly macro expansion!");
3259 case Mips::ZERO:
return Mips::AT;
3260 case Mips::AT:
return Mips::V0;
3261 case Mips::V0:
return Mips::V1;
3262 case Mips::V1:
return Mips::A0;
3263 case Mips::A0:
return Mips::A1;
3264 case Mips::A1:
return Mips::A2;
3265 case Mips::A2:
return Mips::A3;
3266 case Mips::A3:
return Mips::T0;
3267 case Mips::T0:
return Mips::T1;
3268 case Mips::T1:
return Mips::T2;
3269 case Mips::T2:
return Mips::T3;
3270 case Mips::T3:
return Mips::T4;
3271 case Mips::T4:
return Mips::T5;
3272 case Mips::T5:
return Mips::T6;
3273 case Mips::T6:
return Mips::T7;
3274 case Mips::T7:
return Mips::S0;
3275 case Mips::S0:
return Mips::S1;
3276 case Mips::S1:
return Mips::S2;
3277 case Mips::S2:
return Mips::S3;
3278 case Mips::S3:
return Mips::S4;
3279 case Mips::S4:
return Mips::S5;
3280 case Mips::S5:
return Mips::S6;
3281 case Mips::S6:
return Mips::S7;
3282 case Mips::S7:
return Mips::T8;
3283 case Mips::T8:
return Mips::T9;
3284 case Mips::T9:
return Mips::K0;
3285 case Mips::K0:
return Mips::K1;
3286 case Mips::K1:
return Mips::GP;
3287 case Mips::GP:
return Mips::SP;
3288 case Mips::SP:
return Mips::FP;
3289 case Mips::FP:
return Mips::RA;
3290 case Mips::RA:
return Mips::ZERO;
3291 case Mips::D0:
return Mips::F1;
3292 case Mips::D1:
return Mips::F3;
3293 case Mips::D2:
return Mips::F5;
3294 case Mips::D3:
return Mips::F7;
3295 case Mips::D4:
return Mips::F9;
3296 case Mips::D5:
return Mips::F11;
3297 case Mips::D6:
return Mips::F13;
3298 case Mips::D7:
return Mips::F15;
3299 case Mips::D8:
return Mips::F17;
3300 case Mips::D9:
return Mips::F19;
3301 case Mips::D10:
return Mips::F21;
3302 case Mips::D11:
return Mips::F23;
3303 case Mips::D12:
return Mips::F25;
3304 case Mips::D13:
return Mips::F27;
3305 case Mips::D14:
return Mips::F29;
3306 case Mips::D15:
return Mips::F31;
3316bool MipsAsmParser::emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc,
3318 MCRegister ATReg = getATReg(IDLoc);
3324 const auto *GotExpr =
3327 if(isABI_O32() || isABI_N32()) {
3336 const auto *HiExpr =
3345 if(isABI_O32() || isABI_N32()) {
3349 const auto *HighestExpr =
3352 const auto *HigherExpr =
3357 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3359 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3362 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3371 if ((
Hi_32(ImmOp64) & 0x7ff00000) == 0) {
3382 float TmpFloat =
static_cast<float>(DoubleImm);
3386bool MipsAsmParser::expandLoadSingleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3388 const MCSubtargetInfo *STI) {
3391 "Invalid instruction operand.");
3398 return loadImmediate(ImmOp32, FirstReg, MCRegister(),
true,
false, IDLoc, Out,
3402bool MipsAsmParser::expandLoadSingleImmToFPR(MCInst &Inst, SMLoc IDLoc,
3404 const MCSubtargetInfo *STI) {
3405 MipsTargetStreamer &TOut = getTargetStreamer();
3408 "Invalid instruction operand.");
3417 MCRegister TmpReg = Mips::ZERO;
3419 TmpReg = getATReg(IDLoc);
3424 if (
Lo_32(ImmOp64) == 0) {
3425 if (TmpReg != Mips::ZERO && loadImmediate(ImmOp32, TmpReg, MCRegister(),
3426 true,
false, IDLoc, Out, STI))
3428 TOut.
emitRR(Mips::MTC1, FirstReg, TmpReg, IDLoc, STI);
3432 MCSection *CS = getStreamer().getCurrentSectionOnly();
3435 MCSection *ReadOnlySection =
3442 getStreamer().switchSection(ReadOnlySection);
3443 getStreamer().emitLabel(Sym, IDLoc);
3444 getStreamer().emitInt32(ImmOp32);
3445 getStreamer().switchSection(CS);
3447 if (emitPartialAddress(TOut, IDLoc, Sym))
3454bool MipsAsmParser::expandLoadDoubleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3456 const MCSubtargetInfo *STI) {
3457 MipsTargetStreamer &TOut = getTargetStreamer();
3460 "Invalid instruction operand.");
3467 if (
Lo_32(ImmOp64) == 0) {
3469 if (loadImmediate(ImmOp64, FirstReg, MCRegister(),
false,
false, IDLoc,
3473 if (loadImmediate(
Hi_32(ImmOp64), FirstReg, MCRegister(),
true,
false,
3477 if (loadImmediate(0,
nextReg(FirstReg), MCRegister(),
true,
false, IDLoc,
3484 MCSection *CS = getStreamer().getCurrentSectionOnly();
3485 MCSection *ReadOnlySection =
3492 getStreamer().switchSection(ReadOnlySection);
3493 getStreamer().emitLabel(Sym, IDLoc);
3494 getStreamer().emitValueToAlignment(
Align(8));
3495 getStreamer().emitIntValue(ImmOp64, 8);
3496 getStreamer().switchSection(CS);
3498 MCRegister TmpReg = getATReg(IDLoc);
3502 if (emitPartialAddress(TOut, IDLoc, Sym))
3505 TOut.
emitRRX(isABI_N64() ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3509 TOut.
emitRRI(Mips::LD, FirstReg, TmpReg, 0, IDLoc, STI);
3511 TOut.
emitRRI(Mips::LW, FirstReg, TmpReg, 0, IDLoc, STI);
3512 TOut.
emitRRI(Mips::LW,
nextReg(FirstReg), TmpReg, 4, IDLoc, STI);
3517bool MipsAsmParser::expandLoadDoubleImmToFPR(MCInst &Inst,
bool Is64FPU,
3518 SMLoc IDLoc, MCStreamer &Out,
3519 const MCSubtargetInfo *STI) {
3520 MipsTargetStreamer &TOut = getTargetStreamer();
3523 "Invalid instruction operand.");
3530 MCRegister TmpReg = Mips::ZERO;
3532 TmpReg = getATReg(IDLoc);
3537 if ((
Lo_32(ImmOp64) == 0) &&
3538 !((
Hi_32(ImmOp64) & 0xffff0000) && (
Hi_32(ImmOp64) & 0x0000ffff))) {
3540 if (TmpReg != Mips::ZERO && loadImmediate(ImmOp64, TmpReg, MCRegister(),
3541 false,
false, IDLoc, Out, STI))
3543 TOut.
emitRR(Mips::DMTC1, FirstReg, TmpReg, IDLoc, STI);
3547 if (TmpReg != Mips::ZERO &&
3548 loadImmediate(
Hi_32(ImmOp64), TmpReg, MCRegister(),
true,
false, IDLoc,
3552 if (hasMips32r2()) {
3553 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3554 TOut.
emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, TmpReg, IDLoc, STI);
3556 TOut.
emitRR(Mips::MTC1,
nextReg(FirstReg), TmpReg, IDLoc, STI);
3557 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3562 MCSection *CS = getStreamer().getCurrentSectionOnly();
3565 MCSection *ReadOnlySection =
3572 getStreamer().switchSection(ReadOnlySection);
3573 getStreamer().emitLabel(Sym, IDLoc);
3574 getStreamer().emitValueToAlignment(
Align(8));
3575 getStreamer().emitIntValue(ImmOp64, 8);
3576 getStreamer().switchSection(CS);
3578 if (emitPartialAddress(TOut, IDLoc, Sym))
3581 TOut.
emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, TmpReg,
3587bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
3589 const MCSubtargetInfo *STI) {
3590 MipsTargetStreamer &TOut = getTargetStreamer();
3593 "unexpected number of operands");
3603 assert(
Offset.isImm() &&
"expected immediate operand kind");
3607 if (inMicroMipsMode())
3608 Inst.
setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3611 return Error(IDLoc,
"branch target out of range");
3613 return Error(IDLoc,
"branch to misaligned address");
3621 Out.emitInstruction(Inst, *STI);
3625 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
3632bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3633 const MCSubtargetInfo *STI) {
3634 MipsTargetStreamer &TOut = getTargetStreamer();
3635 const MCOperand &DstRegOp = Inst.
getOperand(0);
3636 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3639 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
3641 const MCOperand &MemOffsetOp = Inst.
getOperand(2);
3643 "expected immediate or expression operand");
3645 bool IsLikely =
false;
3655 case Mips::BEQLImmMacro:
3659 case Mips::BNELImmMacro:
3668 int64_t ImmValue = ImmOp.
getImm();
3669 if (ImmValue == 0) {
3673 TOut.
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3675 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3678 warnIfNoMacro(IDLoc);
3680 MCRegister ATReg = getATReg(IDLoc);
3684 if (loadImmediate(ImmValue, ATReg, MCRegister(), !isGP64bit(),
true, IDLoc,
3688 if (IsLikely && MemOffsetOp.
isExpr()) {
3691 TOut.
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3693 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3698void MipsAsmParser::expandMem16Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3699 const MCSubtargetInfo *STI,
bool IsLoad) {
3701 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3702 unsigned StartOp = NumOp == 3 ? 0 : 1;
3704 const MCOperand &DstRegOp = Inst.
getOperand(StartOp);
3705 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3706 const MCOperand &BaseRegOp = Inst.
getOperand(StartOp + 1);
3707 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3710 MipsTargetStreamer &TOut = getTargetStreamer();
3712 MCRegister DstReg = DstRegOp.
getReg();
3714 MCRegister TmpReg = DstReg;
3716 const MCInstrDesc &
Desc = MII.get(OpCode);
3717 int16_t DstRegClass =
3718 MII.getOpRegClassID(
Desc.operands()[StartOp],
3720 unsigned DstRegClassID =
3721 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3722 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3723 (DstRegClassID == Mips::GPR64RegClassID);
3725 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3728 TmpReg = getATReg(IDLoc);
3733 auto emitInstWithOffset = [&](
const MCOperand &
Off) {
3735 TOut.
emitRRX(OpCode, DstReg, TmpReg, Off, IDLoc, STI);
3737 TOut.
emitRRRX(OpCode, DstReg, DstReg, TmpReg, Off, IDLoc, STI);
3741 int64_t LoOffset =
OffsetOp.getImm() & 0xffff;
3742 int64_t HiOffset =
OffsetOp.getImm() & ~0xffff;
3746 if (LoOffset & 0x8000)
3747 HiOffset += 0x10000;
3749 bool IsLargeOffset = HiOffset != 0;
3751 if (IsLargeOffset) {
3753 if (loadImmediate(HiOffset, TmpReg, MCRegister(), Is32BitImm,
true, IDLoc,
3758 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3759 TOut.
emitRRR(
ABI.ArePtrs64bit() ? Mips::DADDu : Mips::ADDu, TmpReg,
3760 TmpReg, BaseReg, IDLoc, STI);
3774 if (!
OffsetOp.getExpr()->evaluateAsRelocatable(Res,
nullptr)) {
3775 Error(IDLoc,
"expected relocatable expression");
3779 Error(IDLoc,
"expected relocatable expression with only one symbol");
3783 loadAndAddSymbolAddress(
3785 BaseReg, !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3793 const MCExpr *OffExpr =
OffsetOp.getExpr();
3805 TOut.
emitRX(Mips::LUi, TmpReg, HighestOperand, IDLoc, STI);
3806 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HigherOperand, IDLoc, STI);
3807 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3808 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HiOperand, IDLoc, STI);
3809 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3810 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3811 TOut.
emitRRR(Mips::DADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3812 emitInstWithOffset(LoOperand);
3815 TOut.
emitRX(Mips::LUi, TmpReg, HiOperand, IDLoc, STI);
3816 if (BaseReg != Mips::ZERO)
3817 TOut.
emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3819 emitInstWithOffset(LoOperand);
3828void MipsAsmParser::expandMem9Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3829 const MCSubtargetInfo *STI,
bool IsLoad) {
3831 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3832 unsigned StartOp = NumOp == 3 ? 0 : 1;
3834 const MCOperand &DstRegOp = Inst.
getOperand(StartOp);
3835 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3836 const MCOperand &BaseRegOp = Inst.
getOperand(StartOp + 1);
3837 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3840 MipsTargetStreamer &TOut = getTargetStreamer();
3842 MCRegister DstReg = DstRegOp.
getReg();
3844 MCRegister TmpReg = DstReg;
3846 const MCInstrDesc &
Desc = MII.get(OpCode);
3847 int16_t DstRegClass =
3848 MII.getOpRegClassID(
Desc.operands()[StartOp],
3851 unsigned DstRegClassID =
3852 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3853 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3854 (DstRegClassID == Mips::GPR64RegClassID);
3856 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3859 TmpReg = getATReg(IDLoc);
3864 auto emitInst = [&]() {
3873 loadImmediate(
OffsetOp.getImm(), TmpReg, BaseReg, !
ABI.ArePtrs64bit(),
true,
3880 loadAndAddSymbolAddress(
OffsetOp.getExpr(), TmpReg, BaseReg,
3881 !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3889bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
3891 const MCSubtargetInfo *STI) {
3894 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3898 Inst.
getOperand(OpNum - 3).
isReg() &&
"Invalid instruction operand.");
3907 if (inMicroMipsMode() && hasMips32r6())
3908 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3910 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3914 Out.emitInstruction(Inst, *STI);
3918bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
3920 const MCSubtargetInfo *STI) {
3921 MipsTargetStreamer &TOut = getTargetStreamer();
3922 bool EmittedNoMacroWarning =
false;
3923 unsigned PseudoOpcode = Inst.
getOpcode();
3928 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3929 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3934 else if (TrgOp.
isImm()) {
3935 warnIfNoMacro(IDLoc);
3936 EmittedNoMacroWarning =
true;
3938 TrgReg = getATReg(IDLoc);
3942 switch(PseudoOpcode) {
3945 case Mips::BLTImmMacro:
3946 PseudoOpcode = Mips::BLT;
3948 case Mips::BLEImmMacro:
3949 PseudoOpcode = Mips::BLE;
3951 case Mips::BGEImmMacro:
3952 PseudoOpcode = Mips::BGE;
3954 case Mips::BGTImmMacro:
3955 PseudoOpcode = Mips::BGT;
3957 case Mips::BLTUImmMacro:
3958 PseudoOpcode = Mips::BLTU;
3960 case Mips::BLEUImmMacro:
3961 PseudoOpcode = Mips::BLEU;
3963 case Mips::BGEUImmMacro:
3964 PseudoOpcode = Mips::BGEU;
3966 case Mips::BGTUImmMacro:
3967 PseudoOpcode = Mips::BGTU;
3969 case Mips::BLTLImmMacro:
3970 PseudoOpcode = Mips::BLTL;
3972 case Mips::BLELImmMacro:
3973 PseudoOpcode = Mips::BLEL;
3975 case Mips::BGELImmMacro:
3976 PseudoOpcode = Mips::BGEL;
3978 case Mips::BGTLImmMacro:
3979 PseudoOpcode = Mips::BGTL;
3981 case Mips::BLTULImmMacro:
3982 PseudoOpcode = Mips::BLTUL;
3984 case Mips::BLEULImmMacro:
3985 PseudoOpcode = Mips::BLEUL;
3987 case Mips::BGEULImmMacro:
3988 PseudoOpcode = Mips::BGEUL;
3990 case Mips::BGTULImmMacro:
3991 PseudoOpcode = Mips::BGTUL;
3995 if (loadImmediate(TrgOp.
getImm(), TrgReg, MCRegister(), !isGP64bit(),
false,
4000 switch (PseudoOpcode) {
4005 AcceptsEquality =
false;
4006 ReverseOrderSLT =
false;
4008 ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
4009 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
4010 ZeroSrcOpcode = Mips::BGTZ;
4011 ZeroTrgOpcode = Mips::BLTZ;
4017 AcceptsEquality =
true;
4018 ReverseOrderSLT =
true;
4020 ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
4021 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
4022 ZeroSrcOpcode = Mips::BGEZ;
4023 ZeroTrgOpcode = Mips::BLEZ;
4029 AcceptsEquality =
true;
4030 ReverseOrderSLT =
false;
4032 ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
4033 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
4034 ZeroSrcOpcode = Mips::BLEZ;
4035 ZeroTrgOpcode = Mips::BGEZ;
4041 AcceptsEquality =
false;
4042 ReverseOrderSLT =
true;
4044 ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
4045 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
4046 ZeroSrcOpcode = Mips::BLTZ;
4047 ZeroTrgOpcode = Mips::BGTZ;
4053 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
4054 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
4055 if (IsSrcRegZero && IsTrgRegZero) {
4059 if (PseudoOpcode == Mips::BLT) {
4064 if (PseudoOpcode == Mips::BLE) {
4067 Warning(IDLoc,
"branch is always taken");
4070 if (PseudoOpcode == Mips::BGE) {
4073 Warning(IDLoc,
"branch is always taken");
4076 if (PseudoOpcode == Mips::BGT) {
4081 if (PseudoOpcode == Mips::BGTU) {
4082 TOut.
emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
4086 if (AcceptsEquality) {
4089 TOut.
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4091 Warning(IDLoc,
"branch is always taken");
4098 if (IsSrcRegZero || IsTrgRegZero) {
4099 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
4100 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
4107 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
4108 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
4114 TOut.
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4116 Warning(IDLoc,
"branch is always taken");
4132 TOut.
emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
4133 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
4140 TOut.
emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
4141 IsSrcRegZero ? TrgReg : SrcReg,
4148 MCRegister ATRegNum = getATReg(IDLoc);
4152 if (!EmittedNoMacroWarning)
4153 warnIfNoMacro(IDLoc);
4170 TOut.
emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
4171 ReverseOrderSLT ? TrgReg : SrcReg,
4172 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
4174 TOut.
emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
4175 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
4189bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4190 const MCSubtargetInfo *STI,
4191 const bool IsMips64,
const bool Signed) {
4192 MipsTargetStreamer &TOut = getTargetStreamer();
4194 warnIfNoMacro(IDLoc);
4196 const MCOperand &RdRegOp = Inst.
getOperand(0);
4197 assert(RdRegOp.
isReg() &&
"expected register operand kind");
4198 MCRegister RdReg = RdRegOp.
getReg();
4200 const MCOperand &RsRegOp = Inst.
getOperand(1);
4201 assert(RsRegOp.
isReg() &&
"expected register operand kind");
4202 MCRegister RsReg = RsRegOp.
getReg();
4209 "expected register or immediate operand kind");
4213 ImmValue = RtOp.
getImm();
4220 DivOp =
Signed ? Mips::DSDIV : Mips::DUDIV;
4221 ZeroReg = Mips::ZERO_64;
4224 DivOp =
Signed ? Mips::SDIV : Mips::UDIV;
4225 ZeroReg = Mips::ZERO;
4229 bool UseTraps = useTraps();
4232 bool isDiv = Opcode == Mips::SDivMacro || Opcode == Mips::SDivIMacro ||
4233 Opcode == Mips::UDivMacro || Opcode == Mips::UDivIMacro ||
4234 Opcode == Mips::DSDivMacro || Opcode == Mips::DSDivIMacro ||
4235 Opcode == Mips::DUDivMacro || Opcode == Mips::DUDivIMacro;
4237 bool isRem = Opcode == Mips::SRemMacro || Opcode == Mips::SRemIMacro ||
4238 Opcode == Mips::URemMacro || Opcode == Mips::URemIMacro ||
4239 Opcode == Mips::DSRemMacro || Opcode == Mips::DSRemIMacro ||
4240 Opcode == Mips::DURemMacro || Opcode == Mips::DURemIMacro;
4243 MCRegister ATReg = getATReg(IDLoc);
4249 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4251 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4255 if (isRem && (ImmValue == 1 || (
Signed && (ImmValue == -1)))) {
4256 TOut.
emitRRR(Mips::OR, RdReg, ZeroReg, ZeroReg, IDLoc, STI);
4258 }
else if (isDiv && ImmValue == 1) {
4259 TOut.
emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI);
4261 }
else if (isDiv &&
Signed && ImmValue == -1) {
4262 TOut.
emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
4265 if (loadImmediate(ImmValue, ATReg, MCRegister(),
isInt<32>(ImmValue),
4266 false, Inst.
getLoc(), Out, STI))
4268 TOut.
emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
4269 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4279 if (!
NoZeroDivCheck && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
4281 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4284 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4290 if (isRem && (RdReg == Mips::ZERO || RdReg == Mips::ZERO_64)) {
4291 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4300 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4303 TOut.
emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4306 BrTarget =
Context.createTempSymbol();
4309 TOut.
emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4314 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4320 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4324bool MipsAsmParser::expandTrunc(MCInst &Inst,
bool IsDouble,
bool Is64FPU,
4325 SMLoc IDLoc, MCStreamer &Out,
4326 const MCSubtargetInfo *STI) {
4327 MipsTargetStreamer &TOut = getTargetStreamer();
4337 if (hasMips1() && !hasMips2()) {
4338 MCRegister ATReg = getATReg(IDLoc);
4341 TOut.
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4342 TOut.
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4344 TOut.
emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4345 TOut.
emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4346 TOut.
emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4348 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4350 FirstReg, SecondReg, IDLoc, STI);
4351 TOut.
emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4356 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4358 FirstReg, SecondReg, IDLoc, STI);
4363bool MipsAsmParser::expandUlh(MCInst &Inst,
bool Signed, SMLoc IDLoc,
4364 MCStreamer &Out,
const MCSubtargetInfo *STI) {
4365 if (hasMips32r6() || hasMips64r6()) {
4366 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4369 const MCOperand &DstRegOp = Inst.
getOperand(0);
4370 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4371 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4372 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4373 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4374 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4376 MipsTargetStreamer &TOut = getTargetStreamer();
4377 MCRegister DstReg = DstRegOp.
getReg();
4378 MCRegister SrcReg = SrcRegOp.
getReg();
4379 int64_t OffsetValue = OffsetImmOp.
getImm();
4383 warnIfNoMacro(IDLoc);
4384 MCRegister ATReg = getATReg(IDLoc);
4389 if (IsLargeOffset) {
4390 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4395 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4396 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4400 MCRegister FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4401 MCRegister SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4403 MCRegister LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4404 MCRegister SllReg = IsLargeOffset ? DstReg : ATReg;
4406 TOut.
emitRRI(
Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4407 FirstOffset, IDLoc, STI);
4408 TOut.
emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4409 TOut.
emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4410 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4415bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4416 const MCSubtargetInfo *STI) {
4417 if (hasMips32r6() || hasMips64r6()) {
4418 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4421 const MCOperand &DstRegOp = Inst.
getOperand(0);
4422 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4423 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4424 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4425 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4426 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4428 MipsTargetStreamer &TOut = getTargetStreamer();
4429 MCRegister DstReg = DstRegOp.
getReg();
4430 MCRegister SrcReg = SrcRegOp.
getReg();
4431 int64_t OffsetValue = OffsetImmOp.
getImm();
4433 warnIfNoMacro(IDLoc);
4434 MCRegister ATReg = getATReg(IDLoc);
4439 if (IsLargeOffset) {
4440 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4445 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4446 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4450 if (IsLargeOffset) {
4451 TOut.
emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4452 TOut.
emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4453 TOut.
emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4454 TOut.
emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4455 TOut.
emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4456 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4458 TOut.
emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4459 TOut.
emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4460 TOut.
emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4466bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4467 const MCSubtargetInfo *STI) {
4468 if (hasMips32r6() || hasMips64r6()) {
4469 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4472 const MCOperand &DstRegOp = Inst.
getOperand(0);
4473 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4474 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4475 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4476 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4477 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4479 MipsTargetStreamer &TOut = getTargetStreamer();
4480 MCRegister DstReg = DstRegOp.
getReg();
4481 MCRegister SrcReg = SrcRegOp.
getReg();
4482 int64_t OffsetValue = OffsetImmOp.
getImm();
4486 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4487 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4491 bool IsLoadInst = (Inst.
getOpcode() == Mips::Ulw);
4492 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4493 MCRegister TmpReg = SrcReg;
4494 if (IsLargeOffset || DoMove) {
4495 warnIfNoMacro(IDLoc);
4496 TmpReg = getATReg(IDLoc);
4501 if (IsLargeOffset) {
4502 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4510 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4511 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4512 TOut.
emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4513 TOut.
emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4516 TOut.
emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4521bool MipsAsmParser::expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4522 const MCSubtargetInfo *STI) {
4523 MipsTargetStreamer &TOut = getTargetStreamer();
4535 warnIfNoMacro(IDLoc);
4549 TOut.
emitRRR(OpCode, DstReg, SrcReg, OpReg, IDLoc, STI);
4550 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4555bool MipsAsmParser::expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4556 const MCSubtargetInfo *STI) {
4557 MipsTargetStreamer &TOut = getTargetStreamer();
4567 unsigned OpRegCode, OpImmCode;
4569 warnIfNoMacro(IDLoc);
4573 case Mips::SGEImm64:
4574 OpRegCode = Mips::SLT;
4575 OpImmCode = Mips::SLTi;
4578 case Mips::SGEUImm64:
4579 OpRegCode = Mips::SLTu;
4580 OpImmCode = Mips::SLTiu;
4589 TOut.
emitRRI(OpImmCode, DstReg, SrcReg, ImmValue, IDLoc, STI);
4590 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4592 MCRegister ImmReg = DstReg;
4593 if (DstReg == SrcReg) {
4594 MCRegister ATReg = getATReg(Inst.
getLoc());
4600 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
4601 false, IDLoc, Out, STI))
4604 TOut.
emitRRR(OpRegCode, DstReg, SrcReg, ImmReg, IDLoc, STI);
4605 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4611bool MipsAsmParser::expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4612 const MCSubtargetInfo *STI) {
4613 MipsTargetStreamer &TOut = getTargetStreamer();
4622 MCRegister ImmReg = DstReg;
4626 warnIfNoMacro(IDLoc);
4630 case Mips::SGTImm64:
4634 case Mips::SGTUImm64:
4641 if (DstReg == SrcReg) {
4642 MCRegister ATReg = getATReg(Inst.
getLoc());
4648 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
false,
4653 TOut.
emitRRR(OpCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4658bool MipsAsmParser::expandSle(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4659 const MCSubtargetInfo *STI) {
4660 MipsTargetStreamer &TOut = getTargetStreamer();
4672 warnIfNoMacro(IDLoc);
4686 TOut.
emitRRR(OpCode, DstReg, OpReg, SrcReg, IDLoc, STI);
4687 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4692bool MipsAsmParser::expandSleImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4693 const MCSubtargetInfo *STI) {
4694 MipsTargetStreamer &TOut = getTargetStreamer();
4706 warnIfNoMacro(IDLoc);
4710 case Mips::SLEImm64:
4711 OpRegCode = Mips::SLT;
4714 case Mips::SLEUImm64:
4715 OpRegCode = Mips::SLTu;
4722 MCRegister ImmReg = DstReg;
4723 if (DstReg == SrcReg) {
4724 MCRegister ATReg = getATReg(Inst.
getLoc());
4730 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
false,
4734 TOut.
emitRRR(OpRegCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4735 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4740bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
4742 const MCSubtargetInfo *STI) {
4743 MipsTargetStreamer &TOut = getTargetStreamer();
4751 MCRegister FinalDstReg;
4758 unsigned FinalOpcode = Inst.
getOpcode();
4760 if (DstReg == SrcReg) {
4761 ATReg = getATReg(Inst.
getLoc());
4764 FinalDstReg = DstReg;
4768 if (!loadImmediate(ImmValue, DstReg, MCRegister(), Is32Bit,
false,
4769 Inst.
getLoc(), Out, STI)) {
4770 switch (FinalOpcode) {
4774 FinalOpcode = Mips::ADD;
4777 FinalOpcode = Mips::ADDu;
4780 FinalOpcode = Mips::AND;
4783 FinalOpcode = Mips::NOR;
4786 FinalOpcode = Mips::OR;
4789 FinalOpcode = Mips::SLT;
4792 FinalOpcode = Mips::SLTu;
4795 FinalOpcode = Mips::XOR;
4798 FinalOpcode = Mips::ADD_MM;
4800 case Mips::ADDiu_MM:
4801 FinalOpcode = Mips::ADDu_MM;
4804 FinalOpcode = Mips::AND_MM;
4807 FinalOpcode = Mips::OR_MM;
4810 FinalOpcode = Mips::SLT_MM;
4812 case Mips::SLTiu_MM:
4813 FinalOpcode = Mips::SLTu_MM;
4816 FinalOpcode = Mips::XOR_MM;
4819 FinalOpcode = Mips::AND64;
4821 case Mips::NORImm64:
4822 FinalOpcode = Mips::NOR64;
4825 FinalOpcode = Mips::OR64;
4827 case Mips::SLTImm64:
4828 FinalOpcode = Mips::SLT64;
4830 case Mips::SLTUImm64:
4831 FinalOpcode = Mips::SLTu64;
4834 FinalOpcode = Mips::XOR64;
4839 TOut.
emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4841 TOut.
emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4847bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4848 const MCSubtargetInfo *STI) {
4849 MipsTargetStreamer &TOut = getTargetStreamer();
4854 MCRegister TmpReg =
DReg;
4856 unsigned FirstShift = Mips::NOP;
4857 unsigned SecondShift = Mips::NOP;
4859 if (hasMips32r2()) {
4861 TmpReg = getATReg(Inst.
getLoc());
4867 TOut.
emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4868 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
4873 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
4885 FirstShift = Mips::SRLV;
4886 SecondShift = Mips::SLLV;
4889 FirstShift = Mips::SLLV;
4890 SecondShift = Mips::SRLV;
4894 ATReg = getATReg(Inst.
getLoc());
4898 TOut.
emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4899 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
4900 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
4901 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
4909bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
4911 const MCSubtargetInfo *STI) {
4912 MipsTargetStreamer &TOut = getTargetStreamer();
4918 unsigned FirstShift = Mips::NOP;
4919 unsigned SecondShift = Mips::NOP;
4921 if (hasMips32r2()) {
4926 ShiftValue = MaxShift - ImmValue;
4927 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
4932 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.
getLoc(), STI);
4940 if (ImmValue == 0) {
4949 FirstShift = Mips::SLL;
4950 SecondShift = Mips::SRL;
4953 FirstShift = Mips::SRL;
4954 SecondShift = Mips::SLL;
4958 ATReg = getATReg(Inst.
getLoc());
4962 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.
getLoc(), STI);
4963 TOut.
emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.
getLoc(), STI);
4964 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
4972bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4973 const MCSubtargetInfo *STI) {
4974 MipsTargetStreamer &TOut = getTargetStreamer();
4979 MCRegister TmpReg =
DReg;
4981 unsigned FirstShift = Mips::NOP;
4982 unsigned SecondShift = Mips::NOP;
4984 if (hasMips64r2()) {
4985 if (TmpReg == SReg) {
4986 TmpReg = getATReg(Inst.
getLoc());
4992 TOut.
emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4993 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
4998 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
5010 FirstShift = Mips::DSRLV;
5011 SecondShift = Mips::DSLLV;
5014 FirstShift = Mips::DSLLV;
5015 SecondShift = Mips::DSRLV;
5019 ATReg = getATReg(Inst.
getLoc());
5023 TOut.
emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
5024 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
5025 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
5026 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5034bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
5036 const MCSubtargetInfo *STI) {
5037 MipsTargetStreamer &TOut = getTargetStreamer();
5043 unsigned FirstShift = Mips::NOP;
5044 unsigned SecondShift = Mips::NOP;
5048 if (hasMips64r2()) {
5049 unsigned FinalOpcode = Mips::NOP;
5051 FinalOpcode = Mips::DROTR;
5052 else if (ImmValue % 32 == 0)
5053 FinalOpcode = Mips::DROTR32;
5054 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
5056 FinalOpcode = Mips::DROTR32;
5058 FinalOpcode = Mips::DROTR;
5059 }
else if (ImmValue >= 33) {
5061 FinalOpcode = Mips::DROTR;
5063 FinalOpcode = Mips::DROTR32;
5066 uint64_t ShiftValue = ImmValue % 32;
5068 ShiftValue = (32 - ImmValue % 32) % 32;
5070 TOut.
emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
5076 if (ImmValue == 0) {
5077 TOut.
emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.
getLoc(), STI);
5085 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5086 FirstShift = Mips::DSLL;
5087 SecondShift = Mips::DSRL32;
5089 if (ImmValue == 32) {
5090 FirstShift = Mips::DSLL32;
5091 SecondShift = Mips::DSRL32;
5093 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5094 FirstShift = Mips::DSLL32;
5095 SecondShift = Mips::DSRL;
5099 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5100 FirstShift = Mips::DSRL;
5101 SecondShift = Mips::DSLL32;
5103 if (ImmValue == 32) {
5104 FirstShift = Mips::DSRL32;
5105 SecondShift = Mips::DSLL32;
5107 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5108 FirstShift = Mips::DSRL32;
5109 SecondShift = Mips::DSLL;
5114 ATReg = getATReg(Inst.
getLoc());
5118 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.
getLoc(), STI);
5119 TOut.
emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
5121 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5129bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5130 const MCSubtargetInfo *STI) {
5131 MipsTargetStreamer &TOut = getTargetStreamer();
5135 TOut.
emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
5136 if (FirstRegOp != SecondRegOp)
5137 TOut.
emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
5140 TOut.
emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
5145bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5146 const MCSubtargetInfo *STI) {
5147 MipsTargetStreamer &TOut = getTargetStreamer();
5153 ATReg = getATReg(IDLoc);
5157 loadImmediate(ImmValue, ATReg, MCRegister(),
true,
false, IDLoc, Out, STI);
5159 TOut.
emitRR(Inst.
getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
5160 SrcReg, ATReg, IDLoc, STI);
5162 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5167bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5168 const MCSubtargetInfo *STI) {
5169 MipsTargetStreamer &TOut = getTargetStreamer();
5175 ATReg = getATReg(Inst.
getLoc());
5179 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
5180 SrcReg, TmpReg, IDLoc, STI);
5182 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5184 TOut.
emitRRI(Inst.
getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
5185 DstReg, DstReg, 0x1F, IDLoc, STI);
5187 TOut.
emitR(Mips::MFHI, ATReg, IDLoc, STI);
5190 TOut.
emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
5197 TOut.
emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
5198 if (AssemblerOptions.
back()->isReorder())
5200 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5204 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5209bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5210 const MCSubtargetInfo *STI) {
5211 MipsTargetStreamer &TOut = getTargetStreamer();
5217 ATReg = getATReg(IDLoc);
5221 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
5222 SrcReg, TmpReg, IDLoc, STI);
5224 TOut.
emitR(Mips::MFHI, ATReg, IDLoc, STI);
5225 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5227 TOut.
emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);
5234 TOut.
emitRRX(Mips::BEQ, ATReg, Mips::ZERO, LabelOp, IDLoc, STI);
5235 if (AssemblerOptions.
back()->isReorder())
5237 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5245bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5246 const MCSubtargetInfo *STI) {
5247 MipsTargetStreamer &TOut = getTargetStreamer();
5252 TOut.
emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
5253 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5263bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
5265 const MCSubtargetInfo *STI,
5270 warnIfNoMacro(IDLoc);
5272 MipsTargetStreamer &TOut = getTargetStreamer();
5273 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
5275 MCRegister SecondReg =
nextReg(FirstReg);
5280 warnIfRegIndexIsAT(FirstReg, IDLoc);
5283 "Offset for load macro is not immediate!");
5286 signed NextOffset = FirstOffset.
getImm() + 4;
5294 if (FirstReg != BaseReg || !IsLoad) {
5295 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5296 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5298 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5299 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5311bool MipsAsmParser::expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc,
5313 const MCSubtargetInfo *STI) {
5317 warnIfNoMacro(IDLoc);
5319 MipsTargetStreamer &TOut = getTargetStreamer();
5320 unsigned Opcode = Mips::SWC1;
5322 MCRegister SecondReg =
nextReg(FirstReg);
5327 warnIfRegIndexIsAT(FirstReg, IDLoc);
5330 "Offset for macro is not immediate!");
5333 signed NextOffset = FirstOffset.
getImm() + 4;
5339 if (!IsLittleEndian)
5342 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5343 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5348bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5349 const MCSubtargetInfo *STI) {
5350 MipsTargetStreamer &TOut = getTargetStreamer();
5361 warnIfNoMacro(IDLoc);
5363 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5364 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5365 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5369 MCRegister
Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5370 TOut.
emitRRI(Mips::SLTiu, DstReg,
Reg, 1, IDLoc, STI);
5374bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5375 const MCSubtargetInfo *STI) {
5376 MipsTargetStreamer &TOut = getTargetStreamer();
5387 warnIfNoMacro(IDLoc);
5390 TOut.
emitRRI(Mips::SLTiu, DstReg, SrcReg, 1, IDLoc, STI);
5394 if (SrcReg == Mips::ZERO) {
5395 Warning(IDLoc,
"comparison is always false");
5396 TOut.
emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
5397 DstReg, SrcReg, SrcReg, IDLoc, STI);
5402 if (
Imm > -0x8000 &&
Imm < 0) {
5404 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5410 MCRegister ATReg = getATReg(IDLoc);
5414 if (loadImmediate(
Imm, ATReg, MCRegister(),
true, isGP64bit(), IDLoc, Out,
5418 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5419 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5424 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5428bool MipsAsmParser::expandSne(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5429 const MCSubtargetInfo *STI) {
5431 MipsTargetStreamer &TOut = getTargetStreamer();
5442 warnIfNoMacro(IDLoc);
5444 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5445 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5446 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5450 MCRegister
Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5451 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO,
Reg, IDLoc, STI);
5455bool MipsAsmParser::expandSneI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5456 const MCSubtargetInfo *STI) {
5457 MipsTargetStreamer &TOut = getTargetStreamer();
5468 warnIfNoMacro(IDLoc);
5470 if (ImmValue == 0) {
5471 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, SrcReg, IDLoc, STI);
5475 if (SrcReg == Mips::ZERO) {
5476 Warning(IDLoc,
"comparison is always true");
5477 if (loadImmediate(1, DstReg, MCRegister(),
true,
false, IDLoc, Out, STI))
5483 if (ImmValue > -0x8000 && ImmValue < 0) {
5484 ImmValue = -ImmValue;
5485 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5491 TOut.
emitRRI(
Opc, DstReg, SrcReg, ImmValue, IDLoc, STI);
5492 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5496 MCRegister ATReg = getATReg(IDLoc);
5500 if (loadImmediate(ImmValue, ATReg, MCRegister(),
isInt<32>(ImmValue),
false,
5504 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5505 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5568 case Mips::F0:
return Mips::ZERO;
5569 case Mips::F1:
return Mips::AT;
5570 case Mips::F2:
return Mips::V0;
5571 case Mips::F3:
return Mips::V1;
5572 case Mips::F4:
return Mips::A0;
5573 case Mips::F5:
return Mips::A1;
5574 case Mips::F6:
return Mips::A2;
5575 case Mips::F7:
return Mips::A3;
5576 case Mips::F8:
return Mips::T0;
5577 case Mips::F9:
return Mips::T1;
5578 case Mips::F10:
return Mips::T2;
5579 case Mips::F11:
return Mips::T3;
5580 case Mips::F12:
return Mips::T4;
5581 case Mips::F13:
return Mips::T5;
5582 case Mips::F14:
return Mips::T6;
5583 case Mips::F15:
return Mips::T7;
5584 case Mips::F16:
return Mips::S0;
5585 case Mips::F17:
return Mips::S1;
5586 case Mips::F18:
return Mips::S2;
5587 case Mips::F19:
return Mips::S3;
5588 case Mips::F20:
return Mips::S4;
5589 case Mips::F21:
return Mips::S5;
5590 case Mips::F22:
return Mips::S6;
5591 case Mips::F23:
return Mips::S7;
5592 case Mips::F24:
return Mips::T8;
5593 case Mips::F25:
return Mips::T9;
5594 case Mips::F26:
return Mips::K0;
5595 case Mips::F27:
return Mips::K1;
5596 case Mips::F28:
return Mips::GP;
5597 case Mips::F29:
return Mips::SP;
5598 case Mips::F30:
return Mips::FP;
5599 case Mips::F31:
return Mips::RA;
5607 case Mips::COP00:
return Mips::ZERO;
5608 case Mips::COP01:
return Mips::AT;
5609 case Mips::COP02:
return Mips::V0;
5610 case Mips::COP03:
return Mips::V1;
5611 case Mips::COP04:
return Mips::A0;
5612 case Mips::COP05:
return Mips::A1;
5613 case Mips::COP06:
return Mips::A2;
5614 case Mips::COP07:
return Mips::A3;
5615 case Mips::COP08:
return Mips::T0;
5616 case Mips::COP09:
return Mips::T1;
5617 case Mips::COP010:
return Mips::T2;
5618 case Mips::COP011:
return Mips::T3;
5619 case Mips::COP012:
return Mips::T4;
5620 case Mips::COP013:
return Mips::T5;
5621 case Mips::COP014:
return Mips::T6;
5622 case Mips::COP015:
return Mips::T7;
5623 case Mips::COP016:
return Mips::S0;
5624 case Mips::COP017:
return Mips::S1;
5625 case Mips::COP018:
return Mips::S2;
5626 case Mips::COP019:
return Mips::S3;
5627 case Mips::COP020:
return Mips::S4;
5628 case Mips::COP021:
return Mips::S5;
5629 case Mips::COP022:
return Mips::S6;
5630 case Mips::COP023:
return Mips::S7;
5631 case Mips::COP024:
return Mips::T8;
5632 case Mips::COP025:
return Mips::T9;
5633 case Mips::COP026:
return Mips::K0;
5634 case Mips::COP027:
return Mips::K1;
5635 case Mips::COP028:
return Mips::GP;
5636 case Mips::COP029:
return Mips::SP;
5637 case Mips::COP030:
return Mips::FP;
5638 case Mips::COP031:
return Mips::RA;
5645bool MipsAsmParser::expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5646 const MCSubtargetInfo *STI) {
5647 MipsTargetStreamer &TOut = getTargetStreamer();
5652 bool IsMFTR =
false;
5706 IsMFTR ? MCRegister(rd)
5708 : Inst.getOperand(0).
getReg());
5710 TOut.
emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, u, sel, h, IDLoc,
5715bool MipsAsmParser::expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5716 const MCSubtargetInfo *STI) {
5721 warnIfNoMacro(IDLoc);
5723 MipsTargetStreamer &TOut = getTargetStreamer();
5724 unsigned Opcode = Inst.
getOpcode() == Mips::SaaAddr ? Mips::SAA : Mips::SAAD;
5727 const MCOperand &BaseOp = Inst.
getOperand(2);
5729 if (BaseOp.
isImm()) {
5730 int64_t ImmValue = BaseOp.
getImm();
5731 if (ImmValue == 0) {
5732 TOut.
emitRR(Opcode, RtReg, BaseReg, IDLoc, STI);
5737 MCRegister ATReg = getATReg(IDLoc);
5741 if (expandLoadAddress(ATReg, BaseReg, BaseOp, !isGP64bit(), IDLoc, Out, STI))
5744 TOut.
emitRR(Opcode, RtReg, ATReg, IDLoc, STI);
5749MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
5753 return Match_Success;
5756 if (
static_cast<MipsOperand &
>(*
Operands[1])
5757 .isValidForTie(
static_cast<MipsOperand &
>(*
Operands[2])))
5758 return Match_Success;
5759 return Match_RequiresSameSrcAndDst;
5763unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
5770 return Match_RequiresNoZeroRegister;
5771 return Match_Success;
5777 case Mips::JALR_HB64:
5778 case Mips::JALRC_HB_MMR6:
5779 case Mips::JALRC_MMR6:
5781 return Match_RequiresDifferentSrcAndDst;
5782 return Match_Success;
5785 return Match_RequiresDifferentSrcAndDst;
5786 return Match_Success;
5789 return Match_NonZeroOperandForSync;
5790 return Match_Success;
5796 return Match_NonZeroOperandForMTCX;
5797 return Match_Success;
5810 case Mips::BLEZC:
case Mips::BLEZC_MMR6:
5811 case Mips::BGEZC:
case Mips::BGEZC_MMR6:
5812 case Mips::BGTZC:
case Mips::BGTZC_MMR6:
5813 case Mips::BLTZC:
case Mips::BLTZC_MMR6:
5814 case Mips::BEQZC:
case Mips::BEQZC_MMR6:
5815 case Mips::BNEZC:
case Mips::BNEZC_MMR6:
5824 return Match_RequiresNoZeroRegister;
5825 return Match_Success;
5826 case Mips::BGEC:
case Mips::BGEC_MMR6:
5827 case Mips::BLTC:
case Mips::BLTC_MMR6:
5828 case Mips::BGEUC:
case Mips::BGEUC_MMR6:
5829 case Mips::BLTUC:
case Mips::BLTUC_MMR6:
5830 case Mips::BEQC:
case Mips::BEQC_MMR6:
5831 case Mips::BNEC:
case Mips::BNEC_MMR6:
5840 return Match_RequiresNoZeroRegister;
5843 return Match_RequiresNoZeroRegister;
5845 return Match_RequiresDifferentOperands;
5846 return Match_Success;
5849 "Operands must be immediates for dins!");
5852 if ((0 > (Pos +
Size)) || ((Pos +
Size) > 32))
5853 return Match_RequiresPosSizeRange0_32;
5854 return Match_Success;
5859 "Operands must be immediates for dinsm/dinsu!");
5862 if ((32 >= (Pos +
Size)) || ((Pos +
Size) > 64))
5863 return Match_RequiresPosSizeRange33_64;
5864 return Match_Success;
5868 "Operands must be immediates for DEXTM!");
5871 if ((1 > (Pos +
Size)) || ((Pos +
Size) > 63))
5872 return Match_RequiresPosSizeUImm6;
5873 return Match_Success;
5878 "Operands must be immediates for dextm/dextu!");
5881 if ((32 > (Pos +
Size)) || ((Pos +
Size) > 64))
5882 return Match_RequiresPosSizeRange33_64;
5883 return Match_Success;
5885 case Mips::CRC32B:
case Mips::CRC32CB:
5886 case Mips::CRC32H:
case Mips::CRC32CH:
5887 case Mips::CRC32W:
case Mips::CRC32CW:
5888 case Mips::CRC32D:
case Mips::CRC32CD:
5890 return Match_RequiresSameSrcAndDst;
5891 return Match_Success;
5897 return Match_NoFCCRegisterForCurrentISA;
5899 return Match_Success;
5907 if (ErrorLoc ==
SMLoc())
5914bool MipsAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
5918 bool MatchingInlineAsm) {
5920 unsigned MatchResult =
5921 MatchInstructionImpl(
Operands, Inst, ErrorInfo, MatchingInlineAsm);
5923 switch (MatchResult) {
5925 if (processInstruction(Inst, IDLoc, Out, STI))
5928 case Match_MissingFeature:
5929 Error(IDLoc,
"instruction requires a CPU feature not currently enabled");
5931 case Match_InvalidTiedOperand:
5932 Error(IDLoc,
"operand must match destination register");
5934 case Match_InvalidOperand: {
5935 SMLoc ErrorLoc = IDLoc;
5936 if (ErrorInfo != ~0ULL) {
5938 return Error(IDLoc,
"too few operands for instruction");
5940 ErrorLoc =
Operands[ErrorInfo]->getStartLoc();
5941 if (ErrorLoc == SMLoc())
5945 return Error(ErrorLoc,
"invalid operand for instruction");
5947 case Match_NonZeroOperandForSync:
5949 "s-type must be zero or unspecified for pre-MIPS32 ISAs");
5950 case Match_NonZeroOperandForMTCX:
5951 return Error(IDLoc,
"selector must be zero for pre-MIPS32 ISAs");
5952 case Match_MnemonicFail:
5953 return Error(IDLoc,
"invalid instruction");
5954 case Match_RequiresDifferentSrcAndDst:
5955 return Error(IDLoc,
"source and destination must be different");
5956 case Match_RequiresDifferentOperands:
5957 return Error(IDLoc,
"registers must be different");
5958 case Match_RequiresNoZeroRegister:
5959 return Error(IDLoc,
"invalid operand ($zero) for instruction");
5960 case Match_RequiresSameSrcAndDst:
5961 return Error(IDLoc,
"source and destination must match");
5962 case Match_NoFCCRegisterForCurrentISA:
5964 "non-zero fcc register doesn't exist in current ISA level");
5969 "expected 1-bit unsigned immediate");
5972 "expected 2-bit unsigned immediate");
5975 "expected immediate in range 1 .. 4");
5978 "expected 3-bit unsigned immediate");
5981 "expected 4-bit unsigned immediate");
5984 "expected 4-bit signed immediate");
5987 "expected 5-bit unsigned immediate");
5990 "expected 5-bit signed immediate");
5993 "expected immediate in range 1 .. 32");
5994 case Match_UImm5_32:
5996 "expected immediate in range 32 .. 63");
5997 case Match_UImm5_33:
5999 "expected immediate in range 33 .. 64");
6000 case Match_UImm5_0_Report_UImm6:
6004 "expected 6-bit unsigned immediate");
6005 case Match_UImm5_Lsl2:
6007 "expected both 7-bit unsigned immediate and multiple of 4");
6008 case Match_UImmRange2_64:
6010 "expected immediate in range 2 .. 64");
6013 "expected 6-bit unsigned immediate");
6014 case Match_UImm6_Lsl2:
6016 "expected both 8-bit unsigned immediate and multiple of 4");
6019 "expected 6-bit signed immediate");
6022 "expected 7-bit unsigned immediate");
6023 case Match_UImm7_N1:
6025 "expected immediate in range -1 .. 126");
6026 case Match_SImm7_Lsl2:
6028 "expected both 9-bit signed immediate and multiple of 4");
6031 "expected 8-bit unsigned immediate");
6032 case Match_UImm10_0:
6034 "expected 10-bit unsigned immediate");
6035 case Match_SImm10_0:
6037 "expected 10-bit signed immediate");
6038 case Match_SImm11_0:
6040 "expected 11-bit signed immediate");
6042 case Match_UImm16_Relaxed:
6043 case Match_UImm16_AltRelaxed:
6045 "expected 16-bit unsigned immediate");
6047 case Match_SImm16_Relaxed:
6049 "expected 16-bit signed immediate");
6050 case Match_SImm18_Lsl3:
6052 "expected both 18-bit signed immediate and multiple of 8");
6053 case Match_SImm19_Lsl2:
6055 "expected both 19-bit signed immediate and multiple of 4");
6056 case Match_UImm20_0:
6058 "expected 20-bit unsigned immediate");
6059 case Match_UImm26_0:
6061 "expected 26-bit unsigned immediate");
6063 case Match_SImm32_Relaxed:
6065 "expected 32-bit signed immediate");
6066 case Match_UImm32_Coerced:
6068 "expected 32-bit immediate");
6069 case Match_MemSImm9:
6071 "expected memory with 9-bit signed offset");
6072 case Match_MemSImm10:
6074 "expected memory with 10-bit signed offset");
6075 case Match_MemSImm10Lsl1:
6077 "expected memory with 11-bit signed offset and multiple of 2");
6078 case Match_MemSImm10Lsl2:
6080 "expected memory with 12-bit signed offset and multiple of 4");
6081 case Match_MemSImm10Lsl3:
6083 "expected memory with 13-bit signed offset and multiple of 8");
6084 case Match_MemSImm11:
6086 "expected memory with 11-bit signed offset");
6087 case Match_MemSImm12:
6089 "expected memory with 12-bit signed offset");
6090 case Match_MemSImm16:
6092 "expected memory with 16-bit signed offset");
6093 case Match_MemSImmPtr:
6095 "expected memory with 32-bit signed offset");
6096 case Match_RequiresPosSizeRange0_32: {
6097 SMLoc ErrorStart =
Operands[3]->getStartLoc();
6098 SMLoc ErrorEnd =
Operands[4]->getEndLoc();
6099 return Error(ErrorStart,
"size plus position are not in the range 0 .. 32",
6100 SMRange(ErrorStart, ErrorEnd));
6102 case Match_RequiresPosSizeUImm6: {
6103 SMLoc ErrorStart =
Operands[3]->getStartLoc();
6104 SMLoc ErrorEnd =
Operands[4]->getEndLoc();
6105 return Error(ErrorStart,
"size plus position are not in the range 1 .. 63",
6106 SMRange(ErrorStart, ErrorEnd));
6108 case Match_RequiresPosSizeRange33_64: {
6109 SMLoc ErrorStart =
Operands[3]->getStartLoc();
6110 SMLoc ErrorEnd =
Operands[4]->getEndLoc();
6111 return Error(ErrorStart,
"size plus position are not in the range 33 .. 64",
6112 SMRange(ErrorStart, ErrorEnd));
6119void MipsAsmParser::warnIfRegIndexIsAT(MCRegister RegIndex, SMLoc Loc) {
6120 if (RegIndex && AssemblerOptions.
back()->getATRegIndex() == RegIndex)
6121 Warning(Loc,
"used $at (currently $" + Twine(RegIndex.
id()) +
6122 ") without \".set noat\"");
6125void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
6126 if (!AssemblerOptions.
back()->isMacro())
6127 Warning(Loc,
"macro instruction expanded into multiple instructions");
6130void MipsAsmParser::ConvertXWPOperands(MCInst &Inst,
6134 "Unexpected instruction!");
6135 ((MipsOperand &)*
Operands[1]).addGPR32ZeroAsmRegOperands(Inst, 1);
6136 MCRegister NextReg =
nextReg(((MipsOperand &)*
Operands[1]).getGPR32Reg());
6138 ((MipsOperand &)*
Operands[2]).addMemOperands(Inst, 2);
6142MipsAsmParser::printWarningWithFixIt(
const Twine &
Msg,
const Twine &FixMsg,
6143 SMRange
Range,
bool ShowColors) {
6149int MipsAsmParser::matchCPURegisterName(StringRef Name) {
6150 const MCRegisterInfo &MRI = *
getContext().getRegisterInfo();
6156 AsmToken RegTok = getLexer().peekTok();
6157 StringRef FixedName =
6159 printWarningWithFixIt(
"register names $t4-$t7 are only available in O32.",
6160 "Did you mean $" + FixedName +
"?",
6166int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
6167 const MCRegisterInfo &MRI = *
getContext().getRegisterInfo();
6169 Mips::RegAliasName);
6173int MipsAsmParser::matchFPURegisterName(StringRef Name) {
6174 if (Name[0] ==
'f') {
6175 StringRef NumString =
Name.substr(1);
6186int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
6187 if (
Name.starts_with(
"fcc")) {
6188 StringRef NumString =
Name.substr(3);
6199int MipsAsmParser::matchACRegisterName(StringRef Name) {
6200 if (
Name.starts_with(
"ac")) {
6201 StringRef NumString =
Name.substr(2);
6212int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
6215 if (
Name.front() !=
'w' ||
Name.drop_front(1).getAsInteger(10, IntVal))
6224int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
6225 const MCRegisterInfo &MRI = *
getContext().getRegisterInfo();
6227 Name, MRI, Mips::MSACtrlRegClassID, Mips::RegAliasName);
6231bool MipsAsmParser::canUseATReg() {
6232 return AssemblerOptions.
back()->getATRegIndex() != 0;
6235MCRegister MipsAsmParser::getATReg(SMLoc Loc) {
6236 unsigned ATIndex = AssemblerOptions.
back()->getATRegIndex();
6238 reportParseError(Loc,
6239 "pseudo-instruction requires $at, which is not available");
6243 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
6247MCRegister MipsAsmParser::getReg(
int RC,
int RegNo) {
6248 return getContext().getRegisterInfo()->getRegClass(RC).getRegister(RegNo);
6254const MCExpr *MipsAsmParser::parseRelocExpr() {
6255 auto getOp = [](StringRef
Op) {
6256 return StringSwitch<Mips::Specifier>(
Op)
6284 MCAsmParser &Parser = getParser();
6286 const MCExpr *Res =
nullptr;
6292 auto Op = getOp(Name);
6301 while (
Ops.size()) {
6310 MCAsmParser &Parser = getParser();
6320 ParseStatus Res = MatchOperandParserImpl(
Operands, Mnemonic,
true);
6331 switch (getLexer().getKind()) {
6341 if (!parseAnyRegister(
Operands).isNoMatch())
6354 Operands.push_back(MipsOperand::CreateImm(SymRef, S,
E, *
this));
6359 const MCExpr *Expr = parseRelocExpr();
6363 Operands.push_back(MipsOperand::CreateImm(Expr, S,
E, *
this));
6370bool MipsAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
6372 return !tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess();
6375ParseStatus MipsAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
6378 ParseStatus Res = parseAnyRegister(
Operands);
6381 MipsOperand &Operand =
static_cast<MipsOperand &
>(*
Operands.front());
6382 StartLoc = Operand.getStartLoc();
6383 EndLoc = Operand.getEndLoc();
6389 if (Operand.isGPRAsmReg()) {
6391 Reg = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
6402 MCAsmParser &Parser = getParser();
6404 const MCExpr *IdVal =
nullptr;
6406 bool isParenExpr =
false;
6417 IdVal = parseRelocExpr();
6423 const AsmToken &Tok = Parser.
getTok();
6425 MipsOperand &Mnemonic =
static_cast<MipsOperand &
>(*
Operands[0]);
6426 if (Mnemonic.getToken() ==
"la" || Mnemonic.getToken() ==
"dla") {
6429 Operands.push_back(MipsOperand::CreateImm(IdVal, S,
E, *
this));
6438 auto Base = MipsOperand::createGPRReg(
6439 0,
"0",
getContext().getRegisterInfo(), S,
E, *
this);
6441 MipsOperand::CreateMem(std::move(
Base), IdVal, S,
E, *
this));
6493 const MCExpr * NextExpr;
6494 if (getParser().parseExpression(NextExpr))
6517 std::unique_ptr<MipsOperand>
op(
6518 static_cast<MipsOperand *
>(
Operands.back().release()));
6525 if (IdVal->evaluateAsAbsolute(
Imm))
6532 Operands.push_back(MipsOperand::CreateMem(std::move(
op), IdVal, S,
E, *
this));
6537 MCAsmParser &Parser = getParser();
6546 const MCSymbolRefExpr *
Ref =
static_cast<const MCSymbolRefExpr *
>(Expr);
6547 StringRef DefSymbol =
Ref->getSymbol().getName();
6550 matchAnyRegisterNameWithoutDollar(
Operands, DefSymbol.
substr(1), S);
6564 if (Entry != RegisterSets.
end()) {
6566 matchAnyRegisterWithoutDollar(
Operands,
Entry->getValue(), S);
6577ParseStatus MipsAsmParser::matchAnyRegisterNameWithoutDollar(
6579 int Index = matchCPURegisterName(Identifier);
6581 Operands.push_back(MipsOperand::createGPRReg(
6582 Index, Identifier,
getContext().getRegisterInfo(), S,
6583 getLexer().getLoc(), *
this));
6587 Index = matchHWRegsRegisterName(Identifier);
6589 Operands.push_back(MipsOperand::createHWRegsReg(
6590 Index, Identifier,
getContext().getRegisterInfo(), S,
6591 getLexer().getLoc(), *
this));
6595 Index = matchFPURegisterName(Identifier);
6597 Operands.push_back(MipsOperand::createFGRReg(
6598 Index, Identifier,
getContext().getRegisterInfo(), S,
6599 getLexer().getLoc(), *
this));
6603 Index = matchFCCRegisterName(Identifier);
6605 Operands.push_back(MipsOperand::createFCCReg(
6606 Index, Identifier,
getContext().getRegisterInfo(), S,
6607 getLexer().getLoc(), *
this));
6611 Index = matchACRegisterName(Identifier);
6613 Operands.push_back(MipsOperand::createACCReg(
6614 Index, Identifier,
getContext().getRegisterInfo(), S,
6615 getLexer().getLoc(), *
this));
6619 Index = matchMSA128RegisterName(Identifier);
6621 Operands.push_back(MipsOperand::createMSA128Reg(
6622 Index, Identifier,
getContext().getRegisterInfo(), S,
6623 getLexer().getLoc(), *
this));
6627 Index = matchMSA128CtrlRegisterName(Identifier);
6629 Operands.push_back(MipsOperand::createMSACtrlReg(
6630 Index, Identifier,
getContext().getRegisterInfo(), S,
6631 getLexer().getLoc(), *
this));
6640 const AsmToken &Token, SMLoc S) {
6644 return matchAnyRegisterNameWithoutDollar(
Operands, Identifier, S);
6649 if (RegNum < 0 || RegNum > 31) {
6653 Error(getLexer().getLoc(),
"invalid register number");
6655 Operands.push_back(MipsOperand::createNumericReg(
6668 auto Token = getLexer().peekTok(
false);
6669 return matchAnyRegisterWithoutDollar(
Operands, Token, S);
6673 MCAsmParser &Parser = getParser();
6676 auto Token = Parser.
getTok();
6678 SMLoc S = Token.
getLoc();
6691 ParseStatus Res = matchAnyRegisterWithoutDollar(
Operands, S);
6700 MCAsmParser &Parser = getParser();
6703 SMLoc S = getLexer().getLoc();
6706 ParseStatus Res = parseAnyRegister(
Operands);
6711 const MCExpr *Expr =
nullptr;
6717 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *
this));
6722 MCAsmParser &Parser = getParser();
6723 const MCExpr *IdVal;
6734 if (getParser().parseExpression(IdVal))
6741 Operands.push_back(MipsOperand::CreateImm(
6747 MCAsmParser &Parser = getParser();
6751 bool RegRange =
false;
6758 while (parseAnyRegister(TmpOperands).isSuccess()) {
6759 SMLoc
E = getLexer().getLoc();
6760 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*TmpOperands.
back());
6761 Reg = isGP64bit() ? RegOpnd.getGPR64Reg() : RegOpnd.getGPR32Reg();
6765 if ((isGP64bit() &&
Reg == Mips::RA_64) ||
6766 (!isGP64bit() &&
Reg == Mips::RA)) {
6769 MCRegister TmpReg = PrevReg + 1;
6770 while (TmpReg <=
Reg) {
6771 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
6772 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
6774 return Error(
E,
"invalid register operand");
6778 TmpReg = TmpReg.
id() + 1;
6785 ((isGP64bit() && (
Reg != Mips::S0_64) && (
Reg != Mips::RA_64)) ||
6786 (!isGP64bit() && (
Reg != Mips::S0) && (
Reg != Mips::RA))))
6787 return Error(
E,
"$16 or $31 expected");
6788 if (!(((
Reg == Mips::FP ||
Reg == Mips::RA ||
6789 (
Reg >= Mips::S0 &&
Reg <= Mips::S7)) &&
6791 ((
Reg == Mips::FP_64 ||
Reg == Mips::RA_64 ||
6792 (
Reg >= Mips::S0_64 &&
Reg <= Mips::S7_64)) &&
6794 return Error(
E,
"invalid register operand");
6795 if (PrevReg.
isValid() && (
Reg != PrevReg + 1) &&
6796 ((
Reg != Mips::FP &&
Reg != Mips::RA && !isGP64bit()) ||
6797 (
Reg != Mips::FP_64 &&
Reg != Mips::RA_64 && isGP64bit())))
6798 return Error(
E,
"consecutive register numbers expected");
6808 return Error(
E,
"',' or '-' expected");
6818 Operands.push_back(MipsOperand::CreateRegList(Regs, S,
E, *
this));
6829 MCAsmParser &Parser = getParser();
6832 MipsOperand::CreateToken(
"(", getLexer().getLoc(), *
this));
6834 if (parseOperand(
Operands, Name)) {
6835 SMLoc Loc = getLexer().getLoc();
6836 return Error(Loc,
"unexpected token in argument list");
6839 SMLoc Loc = getLexer().getLoc();
6840 return Error(Loc,
"unexpected token, expected ')'");
6843 MipsOperand::CreateToken(
")", getLexer().getLoc(), *
this));
6855bool MipsAsmParser::parseBracketSuffix(StringRef Name,
6857 MCAsmParser &Parser = getParser();
6860 MipsOperand::CreateToken(
"[", getLexer().getLoc(), *
this));
6862 if (parseOperand(
Operands, Name)) {
6863 SMLoc Loc = getLexer().getLoc();
6864 return Error(Loc,
"unexpected token in argument list");
6867 SMLoc Loc = getLexer().getLoc();
6868 return Error(Loc,
"unexpected token, expected ']'");
6871 MipsOperand::CreateToken(
"]", getLexer().getLoc(), *
this));
6878 unsigned VariantID = 0);
6893bool MipsAsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
6895 MCAsmParser &Parser = getParser();
6899 getTargetStreamer().forbidModuleDirective();
6902 if (!mnemonicIsValid(Name, 0)) {
6903 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
6905 return Error(NameLoc,
"unknown instruction" + Suggestion);
6908 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *
this));
6913 if (parseOperand(
Operands, Name)) {
6914 SMLoc Loc = getLexer().getLoc();
6915 return Error(Loc,
"unexpected token in argument list");
6924 if (parseOperand(
Operands, Name)) {
6925 SMLoc Loc = getLexer().getLoc();
6926 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 setFeatureBits(Mips::FeatureMips16,
"mips16");
7166 getTargetStreamer().emitDirectiveSetMips16();
7171bool MipsAsmParser::parseSetNoMips16Directive() {
7172 MCAsmParser &Parser = getParser();
7177 reportParseError(
"unexpected token, expected end of statement");
7181 clearFeatureBits(Mips::FeatureMips16,
"mips16");
7182 getTargetStreamer().emitDirectiveSetNoMips16();
7187bool MipsAsmParser::parseSetFpDirective() {
7188 MCAsmParser &Parser = getParser();
7194 AsmToken Tok = Parser.
getTok();
7196 reportParseError(
"unexpected token, expected equals sign '='");
7202 if (!parseFpABIValue(FpAbiVal,
".set"))
7206 reportParseError(
"unexpected token, expected end of statement");
7209 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
7214bool MipsAsmParser::parseSetOddSPRegDirective() {
7215 MCAsmParser &Parser = getParser();
7219 reportParseError(
"unexpected token, expected end of statement");
7223 clearFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
7224 getTargetStreamer().emitDirectiveSetOddSPReg();
7228bool MipsAsmParser::parseSetNoOddSPRegDirective() {
7229 MCAsmParser &Parser = getParser();
7233 reportParseError(
"unexpected token, expected end of statement");
7237 setFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
7238 getTargetStreamer().emitDirectiveSetNoOddSPReg();
7242bool MipsAsmParser::parseSetMtDirective() {
7243 MCAsmParser &Parser = getParser();
7248 reportParseError(
"unexpected token, expected end of statement");
7252 setFeatureBits(Mips::FeatureMT,
"mt");
7253 getTargetStreamer().emitDirectiveSetMt();
7258bool MipsAsmParser::parseSetNoMtDirective() {
7259 MCAsmParser &Parser = getParser();
7264 reportParseError(
"unexpected token, expected end of statement");
7268 clearFeatureBits(Mips::FeatureMT,
"mt");
7270 getTargetStreamer().emitDirectiveSetNoMt();
7275bool MipsAsmParser::parseSetNoCRCDirective() {
7276 MCAsmParser &Parser = getParser();
7281 reportParseError(
"unexpected token, expected end of statement");
7285 clearFeatureBits(Mips::FeatureCRC,
"crc");
7287 getTargetStreamer().emitDirectiveSetNoCRC();
7292bool MipsAsmParser::parseSetNoVirtDirective() {
7293 MCAsmParser &Parser = getParser();
7298 reportParseError(
"unexpected token, expected end of statement");
7302 clearFeatureBits(Mips::FeatureVirt,
"virt");
7304 getTargetStreamer().emitDirectiveSetNoVirt();
7309bool MipsAsmParser::parseSetNoGINVDirective() {
7310 MCAsmParser &Parser = getParser();
7315 reportParseError(
"unexpected token, expected end of statement");
7319 clearFeatureBits(Mips::FeatureGINV,
"ginv");
7321 getTargetStreamer().emitDirectiveSetNoGINV();
7326bool MipsAsmParser::parseSetPopDirective() {
7327 MCAsmParser &Parser = getParser();
7328 SMLoc Loc = getLexer().getLoc();
7332 return reportParseError(
"unexpected token, expected end of statement");
7336 if (AssemblerOptions.
size() == 2)
7337 return reportParseError(Loc,
".set pop with no .set push");
7339 MCSubtargetInfo &STI = copySTI();
7341 setAvailableFeatures(
7342 ComputeAvailableFeatures(AssemblerOptions.
back()->getFeatures()));
7345 getTargetStreamer().emitDirectiveSetPop();
7349bool MipsAsmParser::parseSetPushDirective() {
7350 MCAsmParser &Parser = getParser();
7353 return reportParseError(
"unexpected token, expected end of statement");
7357 std::make_unique<MipsAssemblerOptions>(AssemblerOptions.
back().get()));
7359 getTargetStreamer().emitDirectiveSetPush();
7363bool MipsAsmParser::parseSetSoftFloatDirective() {
7364 MCAsmParser &Parser = getParser();
7367 return reportParseError(
"unexpected token, expected end of statement");
7369 setFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
7370 getTargetStreamer().emitDirectiveSetSoftFloat();
7374bool MipsAsmParser::parseSetHardFloatDirective() {
7375 MCAsmParser &Parser = getParser();
7378 return reportParseError(
"unexpected token, expected end of statement");
7380 clearFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
7381 getTargetStreamer().emitDirectiveSetHardFloat();
7385bool MipsAsmParser::parseSetAssignment() {
7387 MCAsmParser &Parser = getParser();
7390 return reportParseError(
"expected identifier after .set");
7393 return reportParseError(
"unexpected token, expected comma");
7408 const MCExpr *
Value;
7410 Parser, Sym,
Value))
7412 getStreamer().emitAssignment(Sym,
Value);
7417bool MipsAsmParser::parseSetMips0Directive() {
7418 MCAsmParser &Parser = getParser();
7421 return reportParseError(
"unexpected token, expected end of statement");
7424 MCSubtargetInfo &STI = copySTI();
7425 setAvailableFeatures(
7426 ComputeAvailableFeatures(AssemblerOptions.
front()->getFeatures()));
7428 AssemblerOptions.
back()->setFeatures(AssemblerOptions.
front()->getFeatures());
7430 getTargetStreamer().emitDirectiveSetMips0();
7434bool MipsAsmParser::parseSetArchDirective() {
7435 MCAsmParser &Parser = getParser();
7438 return reportParseError(
"unexpected token, expected equals sign");
7441 StringRef Arch = getParser().parseStringToEndOfStatement().trim();
7443 return reportParseError(
"expected arch identifier");
7445 StringRef ArchFeatureName =
7446 StringSwitch<StringRef>(Arch)
7447 .Case(
"mips1",
"mips1")
7448 .Case(
"mips2",
"mips2")
7449 .Case(
"mips3",
"mips3")
7450 .Case(
"mips4",
"mips4")
7451 .Case(
"mips5",
"mips5")
7452 .Case(
"mips32",
"mips32")
7453 .Case(
"mips32r2",
"mips32r2")
7454 .Case(
"mips32r3",
"mips32r3")
7455 .Case(
"mips32r5",
"mips32r5")
7456 .Case(
"mips32r6",
"mips32r6")
7457 .Case(
"mips64",
"mips64")
7458 .Case(
"mips64r2",
"mips64r2")
7459 .Case(
"mips64r3",
"mips64r3")
7460 .Case(
"mips64r5",
"mips64r5")
7461 .Case(
"mips64r6",
"mips64r6")
7462 .Case(
"octeon",
"cnmips")
7463 .Case(
"octeon+",
"cnmipsp")
7464 .Case(
"r4000",
"mips3")
7467 if (ArchFeatureName.
empty())
7468 return reportParseError(
"unsupported architecture");
7470 if (ArchFeatureName ==
"mips64r6" && inMicroMipsMode())
7471 return reportParseError(
"mips64r6 does not support microMIPS");
7473 selectArch(ArchFeatureName);
7474 getTargetStreamer().emitDirectiveSetArch(Arch);
7478bool MipsAsmParser::parseSetFeature(
uint64_t Feature) {
7479 MCAsmParser &Parser = getParser();
7482 return reportParseError(
"unexpected token, expected end of statement");
7487 case Mips::FeatureMips3D:
7488 setFeatureBits(Mips::FeatureMips3D,
"mips3d");
7489 getTargetStreamer().emitDirectiveSetMips3D();
7491 case Mips::FeatureDSP:
7492 setFeatureBits(Mips::FeatureDSP,
"dsp");
7493 getTargetStreamer().emitDirectiveSetDsp();
7495 case Mips::FeatureDSPR2:
7496 setFeatureBits(Mips::FeatureDSPR2,
"dspr2");
7497 getTargetStreamer().emitDirectiveSetDspr2();
7499 case Mips::FeatureMicroMips:
7500 setFeatureBits(Mips::FeatureMicroMips,
"micromips");
7501 getTargetStreamer().emitDirectiveSetMicroMips();
7503 case Mips::FeatureMips1:
7504 selectArch(
"mips1");
7505 getTargetStreamer().emitDirectiveSetMips1();
7507 case Mips::FeatureMips2:
7508 selectArch(
"mips2");
7509 getTargetStreamer().emitDirectiveSetMips2();
7511 case Mips::FeatureMips3:
7512 selectArch(
"mips3");
7513 getTargetStreamer().emitDirectiveSetMips3();
7515 case Mips::FeatureMips4:
7516 selectArch(
"mips4");
7517 getTargetStreamer().emitDirectiveSetMips4();
7519 case Mips::FeatureMips5:
7520 selectArch(
"mips5");
7521 getTargetStreamer().emitDirectiveSetMips5();
7523 case Mips::FeatureMips32:
7524 selectArch(
"mips32");
7525 getTargetStreamer().emitDirectiveSetMips32();
7527 case Mips::FeatureMips32r2:
7528 selectArch(
"mips32r2");
7529 getTargetStreamer().emitDirectiveSetMips32R2();
7531 case Mips::FeatureMips32r3:
7532 selectArch(
"mips32r3");
7533 getTargetStreamer().emitDirectiveSetMips32R3();
7535 case Mips::FeatureMips32r5:
7536 selectArch(
"mips32r5");
7537 getTargetStreamer().emitDirectiveSetMips32R5();
7539 case Mips::FeatureMips32r6:
7540 selectArch(
"mips32r6");
7541 getTargetStreamer().emitDirectiveSetMips32R6();
7543 case Mips::FeatureMips64:
7544 selectArch(
"mips64");
7545 getTargetStreamer().emitDirectiveSetMips64();
7547 case Mips::FeatureMips64r2:
7548 selectArch(
"mips64r2");
7549 getTargetStreamer().emitDirectiveSetMips64R2();
7551 case Mips::FeatureMips64r3:
7552 selectArch(
"mips64r3");
7553 getTargetStreamer().emitDirectiveSetMips64R3();
7555 case Mips::FeatureMips64r5:
7556 selectArch(
"mips64r5");
7557 getTargetStreamer().emitDirectiveSetMips64R5();
7559 case Mips::FeatureMips64r6:
7560 selectArch(
"mips64r6");
7561 getTargetStreamer().emitDirectiveSetMips64R6();
7563 case Mips::FeatureCRC:
7564 setFeatureBits(Mips::FeatureCRC,
"crc");
7565 getTargetStreamer().emitDirectiveSetCRC();
7567 case Mips::FeatureVirt:
7568 setFeatureBits(Mips::FeatureVirt,
"virt");
7569 getTargetStreamer().emitDirectiveSetVirt();
7571 case Mips::FeatureGINV:
7572 setFeatureBits(Mips::FeatureGINV,
"ginv");
7573 getTargetStreamer().emitDirectiveSetGINV();
7579bool MipsAsmParser::eatComma(StringRef ErrorStr) {
7580 MCAsmParser &Parser = getParser();
7582 SMLoc Loc = getLexer().getLoc();
7583 return Error(Loc, ErrorStr);
7594bool MipsAsmParser::isPicAndNotNxxAbi() {
7595 return inPicMode() && !(isABI_N32() || isABI_N64());
7598bool MipsAsmParser::parseDirectiveCpAdd(SMLoc Loc) {
7600 ParseStatus Res = parseAnyRegister(
Reg);
7602 reportParseError(
"expected register");
7606 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7607 if (!RegOpnd.isGPRAsmReg()) {
7608 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7614 reportParseError(
"unexpected token, expected end of statement");
7619 getTargetStreamer().emitDirectiveCpAdd(RegOpnd.getGPR32Reg());
7623bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
7624 if (AssemblerOptions.
back()->isReorder())
7625 Warning(Loc,
".cpload should be inside a noreorder section");
7627 if (inMips16Mode()) {
7628 reportParseError(
".cpload is not supported in Mips16 mode");
7633 ParseStatus Res = parseAnyRegister(
Reg);
7635 reportParseError(
"expected register containing function address");
7639 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7640 if (!RegOpnd.isGPRAsmReg()) {
7641 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7647 reportParseError(
"unexpected token, expected end of statement");
7651 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
7655bool MipsAsmParser::parseDirectiveCpLocal(SMLoc Loc) {
7656 if (!isABI_N32() && !isABI_N64()) {
7657 reportParseError(
".cplocal is allowed only in N32 or N64 mode");
7662 ParseStatus Res = parseAnyRegister(
Reg);
7664 reportParseError(
"expected register containing global pointer");
7668 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7669 if (!RegOpnd.isGPRAsmReg()) {
7670 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7676 reportParseError(
"unexpected token, expected end of statement");
7681 MCRegister NewReg = RegOpnd.getGPR32Reg();
7685 getTargetStreamer().emitDirectiveCpLocal(NewReg);
7689bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
7690 MCAsmParser &Parser = getParser();
7695 if (inMips16Mode()) {
7696 reportParseError(
".cprestore is not supported in Mips16 mode");
7701 const MCExpr *StackOffset;
7702 int64_t StackOffsetVal;
7704 reportParseError(
"expected stack offset value");
7708 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
7709 reportParseError(
"stack offset is not an absolute expression");
7713 if (StackOffsetVal < 0) {
7714 Warning(Loc,
".cprestore with negative stack offset has no effect");
7715 IsCpRestoreSet =
false;
7717 IsCpRestoreSet =
true;
7718 CpRestoreOffset = StackOffsetVal;
7723 reportParseError(
"unexpected token, expected end of statement");
7727 if (!getTargetStreamer().emitDirectiveCpRestore(
7728 CpRestoreOffset, [&]() {
return getATReg(Loc); }, Loc, STI))
7734bool MipsAsmParser::parseDirectiveCPSetup() {
7735 MCAsmParser &Parser = getParser();
7737 bool SaveIsReg =
true;
7740 ParseStatus Res = parseAnyRegister(TmpReg);
7742 reportParseError(
"expected register containing function address");
7746 MipsOperand &FuncRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7747 if (!FuncRegOpnd.isGPRAsmReg()) {
7748 reportParseError(FuncRegOpnd.getStartLoc(),
"invalid register");
7752 MCRegister FuncReg = FuncRegOpnd.getGPR32Reg();
7755 if (!eatComma(
"unexpected token, expected comma"))
7758 Res = parseAnyRegister(TmpReg);
7760 const MCExpr *OffsetExpr;
7762 SMLoc ExprLoc = getLexer().
getLoc();
7765 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
7766 reportParseError(ExprLoc,
"expected save register or stack offset");
7773 MipsOperand &SaveOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7774 if (!SaveOpnd.isGPRAsmReg()) {
7775 reportParseError(SaveOpnd.getStartLoc(),
"invalid register");
7778 Save = SaveOpnd.getGPR32Reg().id();
7781 if (!eatComma(
"unexpected token, expected comma"))
7786 reportParseError(
"expected expression");
7791 reportParseError(
"expected symbol");
7794 const MCSymbolRefExpr *
Ref =
static_cast<const MCSymbolRefExpr *
>(Expr);
7796 CpSaveLocation = Save;
7797 CpSaveLocationIsRegister = SaveIsReg;
7799 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save,
Ref->getSymbol(),
7804bool MipsAsmParser::parseDirectiveCPReturn() {
7805 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
7806 CpSaveLocationIsRegister);
7810bool MipsAsmParser::parseDirectiveNaN() {
7811 MCAsmParser &Parser = getParser();
7813 const AsmToken &Tok = Parser.
getTok();
7817 getTargetStreamer().emitDirectiveNaN2008();
7819 }
else if (Tok.
getString() ==
"legacy") {
7821 getTargetStreamer().emitDirectiveNaNLegacy();
7827 reportParseError(
"invalid option in .nan directive");
7831bool MipsAsmParser::parseDirectiveSet() {
7832 const AsmToken &Tok = getParser().getTok();
7834 SMLoc Loc = Tok.
getLoc();
7836 if (IdVal ==
"noat")
7837 return parseSetNoAtDirective();
7839 return parseSetAtDirective();
7840 if (IdVal ==
"arch")
7841 return parseSetArchDirective();
7842 if (IdVal ==
"bopt") {
7843 Warning(Loc,
"'bopt' feature is unsupported");
7847 if (IdVal ==
"nobopt") {
7853 return parseSetFpDirective();
7854 if (IdVal ==
"oddspreg")
7855 return parseSetOddSPRegDirective();
7856 if (IdVal ==
"nooddspreg")
7857 return parseSetNoOddSPRegDirective();
7859 return parseSetPopDirective();
7860 if (IdVal ==
"push")
7861 return parseSetPushDirective();
7862 if (IdVal ==
"reorder")
7863 return parseSetReorderDirective();
7864 if (IdVal ==
"noreorder")
7865 return parseSetNoReorderDirective();
7866 if (IdVal ==
"macro")
7867 return parseSetMacroDirective();
7868 if (IdVal ==
"nomacro")
7869 return parseSetNoMacroDirective();
7870 if (IdVal ==
"mips16")
7871 return parseSetMips16Directive();
7872 if (IdVal ==
"nomips16")
7873 return parseSetNoMips16Directive();
7874 if (IdVal ==
"nomicromips") {
7875 clearFeatureBits(Mips::FeatureMicroMips,
"micromips");
7876 getTargetStreamer().emitDirectiveSetNoMicroMips();
7877 getParser().eatToEndOfStatement();
7880 if (IdVal ==
"micromips") {
7881 if (hasMips64r6()) {
7882 Error(Loc,
".set micromips directive is not supported with MIPS64R6");
7885 return parseSetFeature(Mips::FeatureMicroMips);
7887 if (IdVal ==
"mips0")
7888 return parseSetMips0Directive();
7889 if (IdVal ==
"mips1")
7890 return parseSetFeature(Mips::FeatureMips1);
7891 if (IdVal ==
"mips2")
7892 return parseSetFeature(Mips::FeatureMips2);
7893 if (IdVal ==
"mips3")
7894 return parseSetFeature(Mips::FeatureMips3);
7895 if (IdVal ==
"mips4")
7896 return parseSetFeature(Mips::FeatureMips4);
7897 if (IdVal ==
"mips5")
7898 return parseSetFeature(Mips::FeatureMips5);
7899 if (IdVal ==
"mips32")
7900 return parseSetFeature(Mips::FeatureMips32);
7901 if (IdVal ==
"mips32r2")
7902 return parseSetFeature(Mips::FeatureMips32r2);
7903 if (IdVal ==
"mips32r3")
7904 return parseSetFeature(Mips::FeatureMips32r3);
7905 if (IdVal ==
"mips32r5")
7906 return parseSetFeature(Mips::FeatureMips32r5);
7907 if (IdVal ==
"mips32r6")
7908 return parseSetFeature(Mips::FeatureMips32r6);
7909 if (IdVal ==
"mips64")
7910 return parseSetFeature(Mips::FeatureMips64);
7911 if (IdVal ==
"mips64r2")
7912 return parseSetFeature(Mips::FeatureMips64r2);
7913 if (IdVal ==
"mips64r3")
7914 return parseSetFeature(Mips::FeatureMips64r3);
7915 if (IdVal ==
"mips64r5")
7916 return parseSetFeature(Mips::FeatureMips64r5);
7917 if (IdVal ==
"mips64r6") {
7918 if (inMicroMipsMode()) {
7919 Error(Loc,
"MIPS64R6 is not supported with microMIPS");
7922 return parseSetFeature(Mips::FeatureMips64r6);
7925 return parseSetFeature(Mips::FeatureDSP);
7926 if (IdVal ==
"dspr2")
7927 return parseSetFeature(Mips::FeatureDSPR2);
7928 if (IdVal ==
"nodsp")
7929 return parseSetNoDspDirective();
7930 if (IdVal ==
"mips3d")
7931 return parseSetFeature(Mips::FeatureMips3D);
7932 if (IdVal ==
"nomips3d")
7933 return parseSetNoMips3DDirective();
7935 return parseSetMsaDirective();
7936 if (IdVal ==
"nomsa")
7937 return parseSetNoMsaDirective();
7939 return parseSetMtDirective();
7940 if (IdVal ==
"nomt")
7941 return parseSetNoMtDirective();
7942 if (IdVal ==
"softfloat")
7943 return parseSetSoftFloatDirective();
7944 if (IdVal ==
"hardfloat")
7945 return parseSetHardFloatDirective();
7947 return parseSetFeature(Mips::FeatureCRC);
7948 if (IdVal ==
"nocrc")
7949 return parseSetNoCRCDirective();
7950 if (IdVal ==
"virt")
7951 return parseSetFeature(Mips::FeatureVirt);
7952 if (IdVal ==
"novirt")
7953 return parseSetNoVirtDirective();
7954 if (IdVal ==
"ginv")
7955 return parseSetFeature(Mips::FeatureGINV);
7956 if (IdVal ==
"noginv")
7957 return parseSetNoGINVDirective();
7960 return parseSetAssignment();
7965bool MipsAsmParser::parseDirectiveGpWord() {
7966 const MCExpr *
Value;
7967 if (getParser().parseExpression(
Value))
7969 getTargetStreamer().emitGPRel32Value(
Value);
7975bool MipsAsmParser::parseDirectiveGpDWord() {
7976 const MCExpr *
Value;
7977 if (getParser().parseExpression(
Value))
7979 getTargetStreamer().emitGPRel64Value(
Value);
7985bool MipsAsmParser::parseDirectiveDtpRelWord() {
7986 const MCExpr *
Value;
7987 if (getParser().parseExpression(
Value))
7989 getTargetStreamer().emitDTPRel32Value(
Value);
7995bool MipsAsmParser::parseDirectiveDtpRelDWord() {
7996 const MCExpr *
Value;
7997 if (getParser().parseExpression(
Value))
7999 getTargetStreamer().emitDTPRel64Value(
Value);
8005bool MipsAsmParser::parseDirectiveTpRelWord() {
8006 const MCExpr *
Value;
8007 if (getParser().parseExpression(
Value))
8009 getTargetStreamer().emitTPRel32Value(
Value);
8015bool MipsAsmParser::parseDirectiveTpRelDWord() {
8016 const MCExpr *
Value;
8017 if (getParser().parseExpression(
Value))
8019 getTargetStreamer().emitTPRel64Value(
Value);
8023bool MipsAsmParser::parseDirectiveOption() {
8024 MCAsmParser &Parser = getParser();
8026 AsmToken Tok = Parser.
getTok();
8030 "unexpected token, expected identifier");
8035 if (Option ==
"pic0") {
8037 IsPicEnabled =
false;
8039 getTargetStreamer().emitDirectiveOptionPic0();
8043 "unexpected token, expected end of statement");
8048 if (Option ==
"pic2") {
8050 IsPicEnabled =
true;
8052 getTargetStreamer().emitDirectiveOptionPic2();
8056 "unexpected token, expected end of statement");
8063 "unknown option, expected 'pic0' or 'pic2'");
8070bool MipsAsmParser::parseInsnDirective() {
8073 reportParseError(
"unexpected token, expected end of statement");
8079 getTargetStreamer().emitDirectiveInsn();
8087bool MipsAsmParser::parseRSectionDirective(StringRef Section) {
8090 reportParseError(
"unexpected token, expected end of statement");
8094 MCSection *ELFSection =
getContext().getELFSection(
8096 getParser().getStreamer().switchSection(ELFSection);
8105bool MipsAsmParser::parseSSectionDirective(StringRef Section,
unsigned Type) {
8108 reportParseError(
"unexpected token, expected end of statement");
8112 MCSection *ELFSection =
getContext().getELFSection(
8114 getParser().getStreamer().switchSection(ELFSection);
8133bool MipsAsmParser::parseDirectiveModule() {
8134 MCAsmParser &Parser = getParser();
8135 AsmLexer &Lexer = getLexer();
8138 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
8140 reportParseError(
".module directive must appear before any code");
8146 reportParseError(
"expected .module option identifier");
8150 if (Option ==
"oddspreg") {
8151 clearModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
8155 getTargetStreamer().updateABIInfo(*
this);
8160 getTargetStreamer().emitDirectiveModuleOddSPReg();
8164 reportParseError(
"unexpected token, expected end of statement");
8169 }
else if (Option ==
"nooddspreg") {
8171 return Error(L,
"'.module nooddspreg' requires the O32 ABI");
8174 setModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
8178 getTargetStreamer().updateABIInfo(*
this);
8183 getTargetStreamer().emitDirectiveModuleOddSPReg();
8187 reportParseError(
"unexpected token, expected end of statement");
8192 }
else if (Option ==
"fp") {
8193 return parseDirectiveModuleFP();
8194 }
else if (Option ==
"softfloat") {
8195 setModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
8199 getTargetStreamer().updateABIInfo(*
this);
8204 getTargetStreamer().emitDirectiveModuleSoftFloat();
8208 reportParseError(
"unexpected token, expected end of statement");
8213 }
else if (Option ==
"hardfloat") {
8214 clearModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
8218 getTargetStreamer().updateABIInfo(*
this);
8223 getTargetStreamer().emitDirectiveModuleHardFloat();
8227 reportParseError(
"unexpected token, expected end of statement");
8232 }
else if (Option ==
"mt") {
8233 setModuleFeatureBits(Mips::FeatureMT,
"mt");
8237 getTargetStreamer().updateABIInfo(*
this);
8242 getTargetStreamer().emitDirectiveModuleMT();
8246 reportParseError(
"unexpected token, expected end of statement");
8251 }
else if (Option ==
"crc") {
8252 setModuleFeatureBits(Mips::FeatureCRC,
"crc");
8256 getTargetStreamer().updateABIInfo(*
this);
8261 getTargetStreamer().emitDirectiveModuleCRC();
8265 reportParseError(
"unexpected token, expected end of statement");
8270 }
else if (Option ==
"nocrc") {
8271 clearModuleFeatureBits(Mips::FeatureCRC,
"crc");
8275 getTargetStreamer().updateABIInfo(*
this);
8280 getTargetStreamer().emitDirectiveModuleNoCRC();
8284 reportParseError(
"unexpected token, expected end of statement");
8289 }
else if (Option ==
"virt") {
8290 setModuleFeatureBits(Mips::FeatureVirt,
"virt");
8294 getTargetStreamer().updateABIInfo(*
this);
8299 getTargetStreamer().emitDirectiveModuleVirt();
8303 reportParseError(
"unexpected token, expected end of statement");
8308 }
else if (Option ==
"novirt") {
8309 clearModuleFeatureBits(Mips::FeatureVirt,
"virt");
8313 getTargetStreamer().updateABIInfo(*
this);
8318 getTargetStreamer().emitDirectiveModuleNoVirt();
8322 reportParseError(
"unexpected token, expected end of statement");
8327 }
else if (Option ==
"ginv") {
8328 setModuleFeatureBits(Mips::FeatureGINV,
"ginv");
8332 getTargetStreamer().updateABIInfo(*
this);
8337 getTargetStreamer().emitDirectiveModuleGINV();
8341 reportParseError(
"unexpected token, expected end of statement");
8346 }
else if (Option ==
"noginv") {
8347 clearModuleFeatureBits(Mips::FeatureGINV,
"ginv");
8351 getTargetStreamer().updateABIInfo(*
this);
8356 getTargetStreamer().emitDirectiveModuleNoGINV();
8360 reportParseError(
"unexpected token, expected end of statement");
8366 return Error(L,
"'" + Twine(Option) +
"' is not a valid .module option.");
8374bool MipsAsmParser::parseDirectiveModuleFP() {
8375 MCAsmParser &Parser = getParser();
8376 AsmLexer &Lexer = getLexer();
8379 reportParseError(
"unexpected token, expected equals sign '='");
8385 if (!parseFpABIValue(FpABI,
".module"))
8389 reportParseError(
"unexpected token, expected end of statement");
8395 getTargetStreamer().updateABIInfo(*
this);
8400 getTargetStreamer().emitDirectiveModuleFP();
8407 StringRef Directive) {
8408 MCAsmParser &Parser = getParser();
8409 AsmLexer &Lexer = getLexer();
8410 bool ModuleLevelOptions = Directive ==
".module";
8416 if (
Value !=
"xx") {
8417 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
8422 reportParseError(
"'" + Directive +
" fp=xx' requires the O32 ABI");
8426 FpABI = MipsABIFlagsSection::FpABIKind::XX;
8427 if (ModuleLevelOptions) {
8428 setModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8429 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8431 setFeatureBits(Mips::FeatureFPXX,
"fpxx");
8432 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8442 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
8448 reportParseError(
"'" + Directive +
" fp=32' requires the O32 ABI");
8452 FpABI = MipsABIFlagsSection::FpABIKind::S32;
8453 if (ModuleLevelOptions) {
8454 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8455 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8457 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
8458 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8461 FpABI = MipsABIFlagsSection::FpABIKind::S64;
8462 if (ModuleLevelOptions) {
8463 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8464 setModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8466 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
8467 setFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8477bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
8483 MCAsmParser &Parser = getParser();
8484 StringRef IDVal = DirectiveID.
getString();
8486 if (IDVal ==
".cpadd") {
8487 parseDirectiveCpAdd(DirectiveID.
getLoc());
8490 if (IDVal ==
".cpload") {
8491 parseDirectiveCpLoad(DirectiveID.
getLoc());
8494 if (IDVal ==
".cprestore") {
8495 parseDirectiveCpRestore(DirectiveID.
getLoc());
8498 if (IDVal ==
".cplocal") {
8499 parseDirectiveCpLocal(DirectiveID.
getLoc());
8502 if (IDVal ==
".ent") {
8506 reportParseError(
"expected identifier after .ent");
8520 reportParseError(
"unexpected token, expected end of statement");
8524 const MCExpr *DummyNumber;
8525 int64_t DummyNumberVal;
8529 reportParseError(
"expected number after comma");
8532 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
8533 reportParseError(
"expected an absolute expression after comma");
8540 reportParseError(
"unexpected token, expected end of statement");
8546 getTargetStreamer().emitDirectiveEnt(*Sym);
8548 IsCpRestoreSet =
false;
8552 if (IDVal ==
".end") {
8556 reportParseError(
"expected identifier after .end");
8561 reportParseError(
"unexpected token, expected end of statement");
8565 if (CurrentFn ==
nullptr) {
8566 reportParseError(
".end used without .ent");
8570 if ((SymbolName != CurrentFn->
getName())) {
8571 reportParseError(
".end symbol does not match .ent symbol");
8575 getTargetStreamer().emitDirectiveEnd(SymbolName);
8576 CurrentFn =
nullptr;
8577 IsCpRestoreSet =
false;
8581 if (IDVal ==
".frame") {
8584 ParseStatus Res = parseAnyRegister(TmpReg);
8586 reportParseError(
"expected stack register");
8590 MipsOperand &StackRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
8591 if (!StackRegOpnd.isGPRAsmReg()) {
8592 reportParseError(StackRegOpnd.getStartLoc(),
8593 "expected general purpose register");
8596 MCRegister StackReg = StackRegOpnd.getGPR32Reg();
8601 reportParseError(
"unexpected token, expected comma");
8606 const MCExpr *FrameSize;
8607 int64_t FrameSizeVal;
8610 reportParseError(
"expected frame size value");
8614 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
8615 reportParseError(
"frame size not an absolute expression");
8622 reportParseError(
"unexpected token, expected comma");
8628 Res = parseAnyRegister(TmpReg);
8630 reportParseError(
"expected return register");
8634 MipsOperand &ReturnRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
8635 if (!ReturnRegOpnd.isGPRAsmReg()) {
8636 reportParseError(ReturnRegOpnd.getStartLoc(),
8637 "expected general purpose register");
8643 reportParseError(
"unexpected token, expected end of statement");
8647 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
8648 ReturnRegOpnd.getGPR32Reg());
8649 IsCpRestoreSet =
false;
8653 if (IDVal ==
".set") {
8654 parseDirectiveSet();
8658 if (IDVal ==
".mask" || IDVal ==
".fmask") {
8669 const MCExpr *BitMask;
8673 reportParseError(
"expected bitmask value");
8677 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
8678 reportParseError(
"bitmask not an absolute expression");
8685 reportParseError(
"unexpected token, expected comma");
8690 const MCExpr *FrameOffset;
8691 int64_t FrameOffsetVal;
8694 reportParseError(
"expected frame offset value");
8698 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
8699 reportParseError(
"frame offset not an absolute expression");
8705 reportParseError(
"unexpected token, expected end of statement");
8709 if (IDVal ==
".mask")
8710 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
8712 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
8716 if (IDVal ==
".nan")
8717 return parseDirectiveNaN();
8719 if (IDVal ==
".gpword") {
8720 parseDirectiveGpWord();
8724 if (IDVal ==
".gpdword") {
8725 parseDirectiveGpDWord();
8729 if (IDVal ==
".dtprelword") {
8730 parseDirectiveDtpRelWord();
8734 if (IDVal ==
".dtpreldword") {
8735 parseDirectiveDtpRelDWord();
8739 if (IDVal ==
".tprelword") {
8740 parseDirectiveTpRelWord();
8744 if (IDVal ==
".tpreldword") {
8745 parseDirectiveTpRelDWord();
8749 if (IDVal ==
".option") {
8750 parseDirectiveOption();
8754 if (IDVal ==
".abicalls") {
8755 getTargetStreamer().emitDirectiveAbiCalls();
8758 "unexpected token, expected end of statement");
8763 if (IDVal ==
".cpsetup") {
8764 parseDirectiveCPSetup();
8767 if (IDVal ==
".cpreturn") {
8768 parseDirectiveCPReturn();
8771 if (IDVal ==
".module") {
8772 parseDirectiveModule();
8775 if (IDVal ==
".llvm_internal_mips_reallow_module_directive") {
8776 parseInternalDirectiveReallowModule();
8779 if (IDVal ==
".insn") {
8780 parseInsnDirective();
8783 if (IDVal ==
".rdata") {
8784 parseRSectionDirective(
".rodata");
8787 if (IDVal ==
".sbss") {
8791 if (IDVal ==
".sdata") {
8799bool MipsAsmParser::parseInternalDirectiveReallowModule() {
8802 reportParseError(
"unexpected token, expected end of statement");
8806 getTargetStreamer().reallowModuleDirective();
8820#define GET_REGISTER_MATCHER
8821#define GET_MATCHER_IMPLEMENTATION
8822#define GET_MNEMONIC_SPELL_CHECKER
8823#include "MipsGenAsmMatcher.inc"
8825bool MipsAsmParser::mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID) {
8827 const MatchEntry *Start, *End;
8828 switch (VariantID) {
8830 case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0);
break;
8833 auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
8834 return MnemonicRange.first != MnemonicRange.second;
static const TargetRegisterClass * getRegClass(const MachineInstr &MI, Register Reg)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
This file declares a class to represent arbitrary precision floating point values and provide a varie...
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
static Value * expandAbs(CallInst *Orig)
std::pair< Instruction::BinaryOps, Value * > OffsetOp
Find all possible pairs (BinOp, RHS) that BinOp V, RHS can be simplified.
static constexpr Value * getValue(Ty &ValueOrUse)
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static FeatureBitset getFeatures(MCSubtargetInfo &STI, StringRef CPU, StringRef TuneCPU, StringRef FS, StringTable ProcNames, ArrayRef< SubtargetSubTypeKV > ProcDesc, ArrayRef< SubtargetFeatureKV > ProcFeatures)
static bool hasFeature(StringRef Feature, const FeatureBitset &FeatureBits, ArrayRef< SubtargetFeatureKV > ProcFeatures)
static unsigned countMCSymbolRefExpr(const MCExpr *Expr)
static std::string MipsMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, unsigned VariantID=0)
static uint64_t convertIntToDoubleImm(uint64_t ImmOp64)
static uint32_t covertDoubleImmToSingleImm(uint64_t ImmOp64)
static unsigned getRegisterForMxtrDSP(MCInst &Inst, bool IsMFDSP)
static bool hasShortDelaySlot(MCInst &Inst)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsAsmParser()
static bool needsExpandMemInst(MCInst &Inst, const MCInstrDesc &MCID)
cl::opt< bool > EmitJalrReloc
static bool isShiftedUIntAtAnyPosition(uint64_t x)
Can the value be represented by a unsigned N-bit value and a shift left?
static bool isEvaluated(const MCExpr *Expr)
static unsigned getRegisterForMxtrC0(MCInst &Inst, bool IsMFTC0)
static const MCSymbol * getSingleMCSymbol(const MCExpr *Expr)
static MCRegister nextReg(MCRegister Reg)
static unsigned getRegisterForMxtrFP(MCInst &Inst, bool IsMFTC1)
cl::opt< bool > NoZeroDivCheck
static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands, uint64_t ErrorInfo)
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static const fltSemantics & IEEEdouble()
APInt bitcastToAPInt() const
uint64_t getZExtValue() const
Get zero extended value.
SMLoc getLoc() const
Get the current source location.
const AsmToken peekTok(bool ShouldSkipSpace=true)
Look ahead at the next token to be lexed.
bool is(AsmToken::TokenKind K) const
Check if the current token has kind K.
bool isNot(AsmToken::TokenKind K) const
Check if the current token has kind K.
Target independent representation for an assembler token.
LLVM_ABI SMLoc getLoc() const
int64_t getIntVal() const
bool isNot(TokenKind K) const
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
bool is(TokenKind K) const
TokenKind getKind() const
LLVM_ABI SMRange getLocRange() const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
Base class for user error types.
Container class for subtarget features.
void printExpr(raw_ostream &, const MCExpr &) const
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
bool parseToken(AsmToken::TokenKind T, const Twine &Msg="unexpected token")
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
Binary assembler expressions.
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
static LLVM_ABI const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
@ LShr
Logical shift right.
@ Xor
Bitwise exclusive or.
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Base class for the full range of assembler expressions which are needed for parsing.
LLVM_ABI bool evaluateAsRelocatable(MCValue &Res, const MCAssembler *Asm) const
Try to evaluate the expression to a relocatable value, i.e.
@ Unary
Unary expressions.
@ Constant
Constant expressions.
@ SymbolRef
References to labels and assigned expressions.
@ Target
Target specific expression.
@ Specifier
Expression with a relocation specifier.
@ Binary
Binary expressions.
Instances of this class represent a single low-level machine instruction.
unsigned getNumOperands() const
unsigned getOpcode() const
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
const MCOperand & getOperand(unsigned i) const
Describe properties that are true of each instruction in the target description file.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
ArrayRef< MCOperandInfo > operands() const
bool mayStore() const
Return true if this instruction could possibly modify memory.
bool mayLoad() const
Return true if this instruction could possibly read memory.
bool isBranch() const
Returns true if this is a conditional, unconditional, or indirect branch.
bool isCall() const
Return true if the instruction is a call.
bool hasDelaySlot() const
Returns true if the specified instruction has a delay slot which must be filled by the code generator...
Interface to description of machine instruction set.
This holds information about one operand of a machine instruction, indicating the register class for ...
uint8_t OperandType
Information about the type of the operand.
Instances of this class represent operands of the MCInst class.
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
MCRegister getReg() const
Returns the register number.
const MCExpr * getExpr() const
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual bool isReg() const =0
isReg - Is this a register operand?
virtual MCRegister getReg() const =0
MCRegister getRegister(unsigned i) const
getRegister - Return the specified register in the class.
uint16_t getEncodingValue(MCRegister Reg) const
Returns the encoding for Reg.
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
Wrapper class representing physical registers. Should be passed by value.
constexpr bool isValid() const
constexpr unsigned id() const
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
Streaming machine code generation interface.
virtual void emitRelocDirective(const MCExpr &Offset, StringRef Name, const MCExpr *Expr, SMLoc Loc={})
Record a relocation described by the .reloc directive.
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
void setFeatureBits(const FeatureBitset &FeatureBits_)
const Triple & getTargetTriple() const
const FeatureBitset & getFeatureBits() const
const FeatureBitset & ToggleFeature(uint64_t FB)
Toggle a feature and return the re-computed feature bits.
virtual unsigned getHwMode(enum HwModeType type=HwMode_Default) const
HwMode ID corresponding to the 'type' parameter is retrieved from the HwMode bit set of the current s...
Represent a reference to a symbol from inside an expression.
uint16_t getSpecifier() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
bool isInSection() const
isInSection - Check if this symbol is defined in some section (i.e., it is defined but not absolute).
bool isUndefined() const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).
StringRef getName() const
getName - Get the symbol name.
bool isVariable() const
isVariable - Check if this is a variable symbol.
const MCExpr * getVariableValue() const
Get the expression of the variable symbol.
bool isTemporary() const
isTemporary - Check if this is an assembler temporary symbol.
MCTargetAsmParser - Generic interface to target specific assembly parsers.
MCStreamer & getStreamer()
Unary assembler expressions.
const MCSymbol * getAddSym() const
int64_t getConstant() const
const MCSymbol * getSubSym() const
static const char * getRegisterName(MCRegister Reg, unsigned AltIdx=Mips::NoRegAltName)
void emitRRX(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, MCOperand Op2, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveSetReorder()
void emitRRRX(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, MCRegister Reg2, MCOperand Op3, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRX(unsigned Opcode, MCRegister Reg0, MCOperand Op1, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitR(unsigned Opcode, MCRegister Reg0, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void setUsesMicroMips()
void emitRRI(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, int16_t Imm, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitEmptyDelaySlot(bool hasShortDelaySlot, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRI(unsigned Opcode, MCRegister Reg0, int32_t Imm, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRR(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, SMLoc IDLoc, const MCSubtargetInfo *STI)
void updateABIInfo(const PredicateLibrary &P)
void emitRRIII(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, int16_t Imm0, int16_t Imm1, int16_t Imm2, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitDSLL(MCRegister DstReg, MCRegister SrcReg, int16_t ShiftAmount, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitGPRestore(int Offset, SMLoc IDLoc, const MCSubtargetInfo *STI)
Emit the $gp restore operation for .cprestore.
void emitNop(SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRRR(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, MCRegister Reg2, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveSetNoReorder()
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
static constexpr StatusTy Failure
constexpr bool isSuccess() const
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
constexpr bool isNoMatch() const
constexpr unsigned id() const
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
void push_back(const T &Elt)
iterator find(StringRef Key)
Represent a constant reference to a string, i.e.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
Check if the string is empty.
LLVM_ABI bool isLittleEndian() const
Tests whether the target triple is little endian.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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.
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()
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,...