63#define DEBUG_TYPE "mips-asm-parser"
76class MipsAssemblerOptions {
78 MipsAssemblerOptions(
const FeatureBitset &Features_) : Features(Features_) {}
80 MipsAssemblerOptions(
const MipsAssemblerOptions *Opts) {
81 ATReg = Opts->getATRegIndex();
82 Reorder = Opts->isReorder();
83 Macro = Opts->isMacro();
84 Features = Opts->getFeatures();
87 unsigned getATRegIndex()
const {
return ATReg; }
88 bool setATRegIndex(
unsigned Reg) {
96 bool isReorder()
const {
return Reorder; }
97 void setReorder() { Reorder =
true; }
98 void setNoReorder() { Reorder =
false; }
100 bool isMacro()
const {
return Macro; }
101 void setMacro() {
Macro =
true; }
102 void setNoMacro() {
Macro =
false; }
104 const FeatureBitset &
getFeatures()
const {
return Features; }
105 void setFeatures(
const FeatureBitset &Features_) { Features = Features_; }
112 static const FeatureBitset AllArchRelatedMask;
118 FeatureBitset Features;
123const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
124 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
125 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
126 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
127 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
128 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
129 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
130 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
131 Mips::FeatureCnMipsP, Mips::FeatureFP64Bit, Mips::FeatureGP64Bit,
138 MipsTargetStreamer &getTargetStreamer() {
139 assert(getParser().getStreamer().getTargetStreamer() &&
140 "do not have a target streamer");
141 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
142 return static_cast<MipsTargetStreamer &
>(TS);
154 bool CurForbiddenSlotAttr;
157 unsigned CpSaveLocation;
159 bool CpSaveLocationIsRegister;
162 StringMap<AsmToken> RegisterSets;
165 void printWarningWithFixIt(
const Twine &
Msg,
const Twine &FixMsg,
166 SMRange
Range,
bool ShowColors =
true);
170#define GET_ASSEMBLER_HEADER
171#include "MipsGenAsmMatcher.inc"
174 checkEarlyTargetMatchPredicate(
MCInst &Inst,
176 unsigned checkTargetMatchPredicate(
MCInst &Inst)
override;
178 bool matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
181 bool MatchingInlineAsm)
override;
186 SMLoc &EndLoc)
override;
192 bool mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID);
197 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);
447 bool validateMSAIndex(
int Val,
int RegKind);
471 void selectArch(StringRef ArchFeature) {
472 MCSubtargetInfo &STI = copySTI();
474 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
476 setAvailableFeatures(
481 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
483 MCSubtargetInfo &STI = copySTI();
484 setAvailableFeatures(
490 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
492 MCSubtargetInfo &STI = copySTI();
493 setAvailableFeatures(
499 void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
500 setFeatureBits(Feature, FeatureString);
501 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
504 void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
505 clearFeatureBits(Feature, FeatureString);
506 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
510 enum MipsMatchResultTy {
511 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
512 Match_RequiresDifferentOperands,
513 Match_RequiresNoZeroRegister,
514 Match_RequiresSameSrcAndDst,
515 Match_NoFCCRegisterForCurrentISA,
516 Match_NonZeroOperandForSync,
517 Match_NonZeroOperandForMTCX,
518 Match_RequiresPosSizeRange0_32,
519 Match_RequiresPosSizeRange33_64,
520 Match_RequiresPosSizeUImm6,
521#define GET_OPERAND_DIAGNOSTIC_TYPES
522#include "MipsGenAsmMatcher.inc"
523#undef GET_OPERAND_DIAGNOSTIC_TYPES
526 MipsAsmParser(
const MCSubtargetInfo &sti, MCAsmParser &parser,
527 const MCInstrInfo &MII)
528 : MCTargetAsmParser(sti, MII),
530 sti.getTargetTriple(),
540 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
543 AssemblerOptions.push_back(
544 std::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
547 AssemblerOptions.push_back(
548 std::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
550 getTargetStreamer().updateABIInfo(*
this);
552 if (!isABI_O32() && !useOddSPReg() != 0)
557 CurForbiddenSlotAttr =
false;
558 IsPicEnabled =
getContext().getObjectFileInfo()->isPositionIndependent();
560 IsCpRestoreSet =
false;
561 CpRestoreOffset = -1;
562 GPReg = ABI.GetGlobalPtr();
567 if (getSTI().
getCPU() ==
"mips64r6" && inMicroMipsMode())
570 if (!isABI_O32() && inMicroMipsMode())
575 bool hasEightFccRegisters()
const {
return hasMips4() || hasMips32(); }
577 bool isGP64bit()
const {
578 return getSTI().hasFeature(Mips::FeatureGP64Bit);
581 bool isFP64bit()
const {
582 return getSTI().hasFeature(Mips::FeatureFP64Bit);
585 bool isJalrRelocAvailable(
const MCExpr *JalExpr) {
594 return ABI.IsN32() || ABI.IsN64();
598 const MipsABIInfo &getABI()
const {
return ABI; }
599 bool isABI_N32()
const {
return ABI.IsN32(); }
600 bool isABI_N64()
const {
return ABI.IsN64(); }
601 bool isABI_O32()
const {
return ABI.IsO32(); }
602 bool isABI_FPXX()
const {
603 return getSTI().hasFeature(Mips::FeatureFPXX);
606 bool useOddSPReg()
const {
607 return !(getSTI().hasFeature(Mips::FeatureNoOddSPReg));
610 bool inMicroMipsMode()
const {
611 return getSTI().hasFeature(Mips::FeatureMicroMips);
614 bool hasMips1()
const {
615 return getSTI().hasFeature(Mips::FeatureMips1);
618 bool hasMips2()
const {
619 return getSTI().hasFeature(Mips::FeatureMips2);
622 bool hasMips3()
const {
623 return getSTI().hasFeature(Mips::FeatureMips3);
626 bool hasMips4()
const {
627 return getSTI().hasFeature(Mips::FeatureMips4);
630 bool hasMips5()
const {
631 return getSTI().hasFeature(Mips::FeatureMips5);
634 bool hasMips32()
const {
635 return getSTI().hasFeature(Mips::FeatureMips32);
638 bool hasMips64()
const {
639 return getSTI().hasFeature(Mips::FeatureMips64);
642 bool hasMips32r2()
const {
643 return getSTI().hasFeature(Mips::FeatureMips32r2);
646 bool hasMips64r2()
const {
647 return getSTI().hasFeature(Mips::FeatureMips64r2);
650 bool hasMips32r3()
const {
651 return (getSTI().
hasFeature(Mips::FeatureMips32r3));
654 bool hasMips64r3()
const {
655 return (getSTI().
hasFeature(Mips::FeatureMips64r3));
658 bool hasMips32r5()
const {
659 return (getSTI().
hasFeature(Mips::FeatureMips32r5));
662 bool hasMips64r5()
const {
663 return (getSTI().
hasFeature(Mips::FeatureMips64r5));
666 bool hasMips32r6()
const {
667 return getSTI().hasFeature(Mips::FeatureMips32r6);
670 bool hasMips64r6()
const {
671 return getSTI().hasFeature(Mips::FeatureMips64r6);
674 bool hasDSP()
const {
675 return getSTI().hasFeature(Mips::FeatureDSP);
678 bool hasDSPR2()
const {
679 return getSTI().hasFeature(Mips::FeatureDSPR2);
682 bool hasDSPR3()
const {
683 return getSTI().hasFeature(Mips::FeatureDSPR3);
686 bool hasMSA()
const {
687 return getSTI().hasFeature(Mips::FeatureMSA);
690 bool hasCnMips()
const {
691 return (getSTI().
hasFeature(Mips::FeatureCnMips));
694 bool hasCnMipsP()
const {
695 return (getSTI().
hasFeature(Mips::FeatureCnMipsP));
698 bool isR5900()
const {
return (getSTI().
hasFeature(Mips::FeatureR5900)); }
704 bool inMips16Mode()
const {
705 return getSTI().hasFeature(Mips::FeatureMips16);
708 bool useTraps()
const {
709 return getSTI().hasFeature(Mips::FeatureUseTCCInDIV);
712 bool useSoftFloat()
const {
713 return getSTI().hasFeature(Mips::FeatureSoftFloat);
716 bool isSingleFloat()
const {
717 return getSTI().hasFeature(Mips::FeatureSingleFloat);
721 return getSTI().hasFeature(Mips::FeatureMT);
724 bool hasCRC()
const {
725 return getSTI().hasFeature(Mips::FeatureCRC);
728 bool hasVirt()
const {
729 return getSTI().hasFeature(Mips::FeatureVirt);
732 bool hasGINV()
const {
733 return getSTI().hasFeature(Mips::FeatureGINV);
736 bool hasForbiddenSlot(
const MCInstrDesc &MCID)
const {
740 bool SafeInForbiddenSlot(
const MCInstrDesc &MCID)
const {
744 void onEndOfFile()
override;
747 void warnIfRegIndexIsAT(MCRegister RegIndex, SMLoc Loc);
749 void warnIfNoMacro(SMLoc Loc);
751 bool isLittle()
const {
return IsLittleEndian; }
753 bool areEqualRegs(
const MCParsedAsmOperand &Op1,
754 const MCParsedAsmOperand &Op2)
const override;
769 RegKind_MSACtrl = 16,
774 RegKind_HWRegs = 256,
778 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
779 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
780 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
793 MipsOperand(KindTy K, MipsAsmParser &Parser) : Kind(
K), AsmParser(Parser) {}
795 ~MipsOperand()
override {
804 case k_RegisterIndex:
812 MipsAsmParser &AsmParser;
823 const MCRegisterInfo *RegInfo;
841 struct RegIdxOp RegIdx;
844 struct RegListOp RegList;
847 SMLoc StartLoc, EndLoc;
850 static std::unique_ptr<MipsOperand> CreateReg(
unsigned Index, StringRef Str,
852 const MCRegisterInfo *RegInfo,
854 MipsAsmParser &Parser) {
855 auto Op = std::make_unique<MipsOperand>(k_RegisterIndex, Parser);
857 Op->RegIdx.RegInfo = RegInfo;
858 Op->RegIdx.Kind = RegKind;
859 Op->RegIdx.Tok.Data = Str.data();
860 Op->RegIdx.Tok.Length = Str.size();
869 MCRegister getGPR32Reg()
const {
870 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
871 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
872 unsigned ClassID = Mips::GPR32RegClassID;
873 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
878 MCRegister getGPRMM16Reg()
const {
879 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
880 unsigned ClassID = Mips::GPR32RegClassID;
881 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
886 MCRegister getGPR64Reg()
const {
887 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
888 unsigned ClassID = Mips::GPR64RegClassID;
889 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
895 MCRegister getAFGR64Reg()
const {
896 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
897 if (RegIdx.Index % 2 != 0)
898 AsmParser.Warning(StartLoc,
"Float register should be even.");
899 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
900 .getRegister(RegIdx.Index / 2);
905 MCRegister getFGR64Reg()
const {
906 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
907 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
908 .getRegister(RegIdx.Index);
913 MCRegister getFGR32Reg()
const {
914 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
915 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
916 .getRegister(RegIdx.Index);
921 MCRegister getFCCReg()
const {
922 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) &&
"Invalid access!");
923 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
924 .getRegister(RegIdx.Index);
929 MCRegister getMSA128Reg()
const {
930 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) &&
"Invalid access!");
933 unsigned ClassID = Mips::MSA128BRegClassID;
934 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
939 MCRegister getMSACtrlReg()
const {
940 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) &&
"Invalid access!");
941 unsigned ClassID = Mips::MSACtrlRegClassID;
942 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
947 MCRegister getCOP0Reg()
const {
948 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) &&
"Invalid access!");
949 unsigned ClassID = Mips::COP0RegClassID;
950 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
955 MCRegister getCOP2Reg()
const {
956 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) &&
"Invalid access!");
957 unsigned ClassID = Mips::COP2RegClassID;
958 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
963 MCRegister getCOP3Reg()
const {
964 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) &&
"Invalid access!");
965 unsigned ClassID = Mips::COP3RegClassID;
966 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
971 MCRegister getACC64DSPReg()
const {
972 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
973 unsigned ClassID = Mips::ACC64DSPRegClassID;
974 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
979 MCRegister getHI32DSPReg()
const {
980 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
981 unsigned ClassID = Mips::HI32DSPRegClassID;
982 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
987 MCRegister getLO32DSPReg()
const {
988 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
989 unsigned ClassID = Mips::LO32DSPRegClassID;
990 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
995 MCRegister getCCRReg()
const {
996 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) &&
"Invalid access!");
997 unsigned ClassID = Mips::CCRRegClassID;
998 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1003 MCRegister getHWRegsReg()
const {
1004 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) &&
"Invalid access!");
1005 unsigned ClassID = Mips::HWRegsRegClassID;
1006 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1010 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const {
1020 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1027 void addGPR32ZeroAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1028 assert(
N == 1 &&
"Invalid number of operands!");
1032 void addGPR32NonZeroAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1033 assert(
N == 1 &&
"Invalid number of operands!");
1037 void addGPR32AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1038 assert(
N == 1 &&
"Invalid number of operands!");
1042 void addGPRMM16AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1043 assert(
N == 1 &&
"Invalid number of operands!");
1047 void addGPRMM16AsmRegZeroOperands(MCInst &Inst,
unsigned N)
const {
1048 assert(
N == 1 &&
"Invalid number of operands!");
1052 void addGPRMM16AsmRegMovePOperands(MCInst &Inst,
unsigned N)
const {
1053 assert(
N == 1 &&
"Invalid number of operands!");
1057 void addGPRMM16AsmRegMovePPairFirstOperands(MCInst &Inst,
unsigned N)
const {
1058 assert(
N == 1 &&
"Invalid number of operands!");
1062 void addGPRMM16AsmRegMovePPairSecondOperands(MCInst &Inst,
1064 assert(
N == 1 &&
"Invalid number of operands!");
1071 void addGPR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1072 assert(
N == 1 &&
"Invalid number of operands!");
1076 void addAFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1077 assert(
N == 1 &&
"Invalid number of operands!");
1081 void addStrictlyAFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1082 assert(
N == 1 &&
"Invalid number of operands!");
1086 void addStrictlyFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1087 assert(
N == 1 &&
"Invalid number of operands!");
1091 void addFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1092 assert(
N == 1 &&
"Invalid number of operands!");
1096 void addFGR32AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1097 assert(
N == 1 &&
"Invalid number of operands!");
1101 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1102 AsmParser.getParser().printError(
1103 StartLoc,
"-mno-odd-spreg prohibits the use of odd FPU "
1107 void addStrictlyFGR32AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1108 assert(
N == 1 &&
"Invalid number of operands!");
1111 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1112 AsmParser.Error(StartLoc,
"-mno-odd-spreg prohibits the use of odd FPU "
1116 void addFCCAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1117 assert(
N == 1 &&
"Invalid number of operands!");
1121 void addMSA128AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1122 assert(
N == 1 &&
"Invalid number of operands!");
1126 void addMSACtrlAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1127 assert(
N == 1 &&
"Invalid number of operands!");
1131 void addCOP0AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1132 assert(
N == 1 &&
"Invalid number of operands!");
1136 void addCOP2AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1137 assert(
N == 1 &&
"Invalid number of operands!");
1141 void addCOP3AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1142 assert(
N == 1 &&
"Invalid number of operands!");
1146 void addACC64DSPAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1147 assert(
N == 1 &&
"Invalid number of operands!");
1151 void addHI32DSPAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1152 assert(
N == 1 &&
"Invalid number of operands!");
1156 void addLO32DSPAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1157 assert(
N == 1 &&
"Invalid number of operands!");
1161 void addCCRAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1162 assert(
N == 1 &&
"Invalid number of operands!");
1166 void addHWRegsAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1167 assert(
N == 1 &&
"Invalid number of operands!");
1171 template <
unsigned Bits,
int Offset = 0,
int AdjustOffset = 0>
1172 void addConstantUImmOperands(MCInst &Inst,
unsigned N)
const {
1173 assert(
N == 1 &&
"Invalid number of operands!");
1174 uint64_t
Imm = getConstantImm() -
Offset;
1177 Imm += AdjustOffset;
1181 template <
unsigned Bits>
1182 void addSImmOperands(MCInst &Inst,
unsigned N)
const {
1183 if (isImm() && !isConstantImm()) {
1187 addConstantSImmOperands<Bits, 0, 0>(Inst,
N);
1190 template <
unsigned Bits>
1191 void addUImmOperands(MCInst &Inst,
unsigned N)
const {
1192 if (isImm() && !isConstantImm()) {
1196 addConstantUImmOperands<Bits, 0, 0>(Inst,
N);
1199 template <
unsigned Bits,
int Offset = 0,
int AdjustOffset = 0>
1200 void addConstantSImmOperands(MCInst &Inst,
unsigned N)
const {
1201 assert(
N == 1 &&
"Invalid number of operands!");
1202 int64_t
Imm = getConstantImm() -
Offset;
1205 Imm += AdjustOffset;
1209 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1210 assert(
N == 1 &&
"Invalid number of operands!");
1211 const MCExpr *Expr =
getImm();
1212 addExpr(Inst, Expr);
1215 void addMemOperands(MCInst &Inst,
unsigned N)
const {
1216 assert(
N == 2 &&
"Invalid number of operands!");
1219 ? getMemBase()->getGPR64Reg()
1220 : getMemBase()->getGPR32Reg()));
1222 const MCExpr *Expr = getMemOff();
1223 addExpr(Inst, Expr);
1226 void addMicroMipsMemOperands(MCInst &Inst,
unsigned N)
const {
1227 assert(
N == 2 &&
"Invalid number of operands!");
1231 const MCExpr *Expr = getMemOff();
1232 addExpr(Inst, Expr);
1235 void addRegListOperands(MCInst &Inst,
unsigned N)
const {
1236 assert(
N == 1 &&
"Invalid number of operands!");
1238 for (
auto RegNo : getRegList())
1242 bool isReg()
const override {
1245 return isGPRAsmReg() && RegIdx.Index == 0;
1248 bool isRegIdx()
const {
return Kind == k_RegisterIndex; }
1249 bool isImm()
const override {
return Kind == k_Immediate; }
1251 bool isConstantImm()
const {
1253 return isImm() &&
getImm()->evaluateAsAbsolute(Res);
1256 bool isConstantImmz()
const {
1257 return isConstantImm() && getConstantImm() == 0;
1260 template <
unsigned Bits,
int Offset = 0>
bool isConstantUImm()
const {
1264 template <
unsigned Bits>
bool isSImm()
const {
1268 if (
getImm()->evaluateAsAbsolute(Res))
1274 template <
unsigned Bits>
bool isUImm()
const {
1278 if (
getImm()->evaluateAsAbsolute(Res))
1284 template <
unsigned Bits>
bool isAnyImm()
const {
1285 return isConstantImm() ? (
isInt<Bits>(getConstantImm()) ||
1290 template <
unsigned Bits,
int Offset = 0>
bool isConstantSImm()
const {
1294 template <
unsigned Bottom,
unsigned Top>
bool isConstantUImmRange()
const {
1295 return isConstantImm() && getConstantImm() >= Bottom &&
1296 getConstantImm() <= Top;
1299 bool isToken()
const override {
1302 return Kind == k_Token;
1305 bool isMem()
const override {
return Kind == k_Memory; }
1307 bool isConstantMemOff()
const {
1312 template <
unsigned Bits,
unsigned ShiftAmount = 0>
1313 bool isMemWithSimmOffset()
const {
1316 if (!getMemBase()->isGPRAsmReg())
1319 (isConstantMemOff() &&
1323 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res,
nullptr);
1327 bool isMemWithPtrSizeOffset()
const {
1330 if (!getMemBase()->isGPRAsmReg())
1332 const unsigned PtrBits = AsmParser.getABI().ArePtrs64bit() ? 64 : 32;
1334 (isConstantMemOff() &&
isIntN(PtrBits, getConstantMemOff())))
1337 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res,
nullptr);
1341 bool isMemWithGRPMM16Base()
const {
1342 return isMem() && getMemBase()->isMM16AsmReg();
1345 template <
unsigned Bits>
bool isMemWithUimmOffsetSP()
const {
1347 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1350 template <
unsigned Bits>
bool isMemWithUimmWordAlignedOffsetSP()
const {
1352 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1353 && (getMemBase()->getGPR32Reg() == Mips::SP);
1356 template <
unsigned Bits>
bool isMemWithSimmWordAlignedOffsetGP()
const {
1358 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1359 && (getMemBase()->getGPR32Reg() == Mips::GP);
1362 template <
unsigned Bits,
unsigned ShiftLeftAmount>
1363 bool isScaledUImm()
const {
1364 return isConstantImm() &&
1368 template <
unsigned Bits,
unsigned ShiftLeftAmount>
1369 bool isScaledSImm()
const {
1370 if (isConstantImm() &&
1375 if (Kind != k_Immediate)
1378 bool Success =
getImm()->evaluateAsRelocatable(Res,
nullptr);
1382 bool isRegList16()
const {
1386 int Size = RegList.List->size();
1390 MCRegister R0 = RegList.List->front();
1391 MCRegister R1 = RegList.List->back();
1392 if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1393 (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1396 MCRegister PrevReg = RegList.List->front();
1397 for (
int i = 1; i <
Size - 1; i++) {
1398 MCRegister
Reg = (*(RegList.List))[i];
1399 if (
Reg != PrevReg + 1)
1407 bool isInvNum()
const {
return Kind == k_Immediate; }
1409 bool isLSAImm()
const {
1410 if (!isConstantImm())
1412 int64_t Val = getConstantImm();
1413 return 1 <= Val && Val <= 4;
1416 bool isRegList()
const {
return Kind == k_RegList; }
1419 assert(Kind == k_Token &&
"Invalid access!");
1420 return StringRef(Tok.Data, Tok.Length);
1423 MCRegister
getReg()
const override {
1426 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1427 RegIdx.Kind & RegKind_GPR)
1428 return getGPR32Reg();
1434 const MCExpr *
getImm()
const {
1435 assert((Kind == k_Immediate) &&
"Invalid access!");
1439 int64_t getConstantImm()
const {
1440 const MCExpr *Val =
getImm();
1442 (void)Val->evaluateAsAbsolute(
Value);
1446 MipsOperand *getMemBase()
const {
1447 assert((Kind == k_Memory) &&
"Invalid access!");
1451 const MCExpr *getMemOff()
const {
1452 assert((Kind == k_Memory) &&
"Invalid access!");
1456 int64_t getConstantMemOff()
const {
1457 return static_cast<const MCConstantExpr *
>(getMemOff())->
getValue();
1460 const SmallVectorImpl<MCRegister> &getRegList()
const {
1461 assert((Kind == k_RegList) &&
"Invalid access!");
1462 return *(RegList.List);
1465 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1466 MipsAsmParser &Parser) {
1467 auto Op = std::make_unique<MipsOperand>(k_Token, Parser);
1468 Op->Tok.Data = Str.data();
1469 Op->Tok.Length = Str.size();
1477 static std::unique_ptr<MipsOperand>
1478 createNumericReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1479 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1480 LLVM_DEBUG(
dbgs() <<
"createNumericReg(" << Index <<
", ...)\n");
1481 return CreateReg(Index, Str, RegKind_Numeric, RegInfo, S,
E, Parser);
1486 static std::unique_ptr<MipsOperand>
1487 createGPRReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1488 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1489 return CreateReg(Index, Str, RegKind_GPR, RegInfo, S,
E, Parser);
1494 static std::unique_ptr<MipsOperand>
1495 createFGRReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1496 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1497 return CreateReg(Index, Str, RegKind_FGR, RegInfo, S,
E, Parser);
1502 static std::unique_ptr<MipsOperand>
1503 createHWRegsReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1504 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1505 return CreateReg(Index, Str, RegKind_HWRegs, RegInfo, S,
E, Parser);
1510 static std::unique_ptr<MipsOperand>
1511 createFCCReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1512 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1513 return CreateReg(Index, Str, RegKind_FCC, RegInfo, S,
E, Parser);
1518 static std::unique_ptr<MipsOperand>
1519 createACCReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1520 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1521 return CreateReg(Index, Str, RegKind_ACC, RegInfo, S,
E, Parser);
1526 static std::unique_ptr<MipsOperand>
1527 createMSA128Reg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1528 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1529 return CreateReg(Index, Str, RegKind_MSA128, RegInfo, S,
E, Parser);
1534 static std::unique_ptr<MipsOperand>
1535 createMSACtrlReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1536 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1537 return CreateReg(Index, Str, RegKind_MSACtrl, RegInfo, S,
E, Parser);
1540 static std::unique_ptr<MipsOperand>
1541 CreateImm(
const MCExpr *Val, SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1542 auto Op = std::make_unique<MipsOperand>(k_Immediate, Parser);
1549 static std::unique_ptr<MipsOperand>
1550 CreateMem(std::unique_ptr<MipsOperand>
Base,
const MCExpr *Off, SMLoc S,
1551 SMLoc
E, MipsAsmParser &Parser) {
1552 auto Op = std::make_unique<MipsOperand>(k_Memory, Parser);
1553 Op->Mem.Base =
Base.release();
1560 static std::unique_ptr<MipsOperand>
1561 CreateRegList(SmallVectorImpl<MCRegister> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1562 MipsAsmParser &Parser) {
1563 assert(!Regs.
empty() &&
"Empty list not allowed");
1565 auto Op = std::make_unique<MipsOperand>(k_RegList, Parser);
1568 Op->StartLoc = StartLoc;
1569 Op->EndLoc = EndLoc;
1573 bool isGPRZeroAsmReg()
const {
1574 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
1577 bool isGPRNonZeroAsmReg()
const {
1578 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index > 0 &&
1582 bool isGPRAsmReg()
const {
1583 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1586 bool isMM16AsmReg()
const {
1587 if (!(isRegIdx() && RegIdx.Kind))
1589 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1590 || RegIdx.Index == 16 || RegIdx.Index == 17);
1593 bool isMM16AsmRegZero()
const {
1594 if (!(isRegIdx() && RegIdx.Kind))
1596 return (RegIdx.Index == 0 ||
1597 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1598 RegIdx.Index == 17);
1601 bool isMM16AsmRegMoveP()
const {
1602 if (!(isRegIdx() && RegIdx.Kind))
1604 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1605 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1608 bool isMM16AsmRegMovePPairFirst()
const {
1609 if (!(isRegIdx() && RegIdx.Kind))
1611 return RegIdx.Index >= 4 && RegIdx.Index <= 6;
1614 bool isMM16AsmRegMovePPairSecond()
const {
1615 if (!(isRegIdx() && RegIdx.Kind))
1617 return (RegIdx.Index == 21 || RegIdx.Index == 22 ||
1618 (RegIdx.Index >= 5 && RegIdx.Index <= 7));
1621 bool isFGRAsmReg()
const {
1623 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1626 bool isStrictlyFGRAsmReg()
const {
1628 return isRegIdx() && RegIdx.Kind == RegKind_FGR && RegIdx.Index <= 31;
1631 bool isHWRegsAsmReg()
const {
1632 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1635 bool isCCRAsmReg()
const {
1636 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1639 bool isFCCAsmReg()
const {
1640 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1642 return RegIdx.Index <= 7;
1645 bool isACCAsmReg()
const {
1646 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1649 bool isCOP0AsmReg()
const {
1650 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1653 bool isCOP2AsmReg()
const {
1654 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1657 bool isCOP3AsmReg()
const {
1658 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1661 bool isMSA128AsmReg()
const {
1662 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1665 bool isMSACtrlAsmReg()
const {
1666 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1670 SMLoc getStartLoc()
const override {
return StartLoc; }
1672 SMLoc getEndLoc()
const override {
return EndLoc; }
1674 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1683 Mem.Base->print(OS, MAI);
1688 case k_RegisterIndex:
1689 OS <<
"RegIdx<" << RegIdx.Index <<
":" << RegIdx.Kind <<
", "
1690 << StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) <<
">";
1697 for (
auto Reg : (*RegList.List))
1698 OS <<
Reg.
id() <<
" ";
1704 bool isValidForTie(
const MipsOperand &
Other)
const {
1705 if (Kind !=
Other.Kind)
1712 case k_RegisterIndex: {
1713 StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length);
1714 StringRef OtherToken(
Other.RegIdx.Tok.Data,
Other.RegIdx.Tok.Length);
1715 return Token == OtherToken;
1731 case Mips::JRC16_MM:
1733 case Mips::JALRS_MM:
1734 case Mips::JALRS16_MM:
1735 case Mips::BGEZALS_MM:
1736 case Mips::BLTZALS_MM:
1747 return &SRExpr->getSymbol();
1806 unsigned NumOp =
MCID.getNumOperands();
1807 if (NumOp != 3 && NumOp != 4)
1837bool MipsAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
1840 MipsTargetStreamer &TOut = getTargetStreamer();
1841 const unsigned Opcode = Inst.
getOpcode();
1842 const MCInstrDesc &MCID = MII.get(Opcode);
1843 bool ExpandedJalSym =
false;
1857 assert(hasCnMips() &&
"instruction only valid for octeon cpus");
1868 if (!
isIntN(inMicroMipsMode() ? 17 : 18,
Offset.getImm()))
1869 return Error(IDLoc,
"branch target out of range");
1872 return Error(IDLoc,
"branch to misaligned address");
1886 case Mips::BGEZAL_MM:
1887 case Mips::BLTZAL_MM:
1890 case Mips::BC1EQZC_MMR6:
1891 case Mips::BC1NEZC_MMR6:
1892 case Mips::BC2EQZC_MMR6:
1893 case Mips::BC2NEZC_MMR6:
1898 if (!
isIntN(inMicroMipsMode() ? 17 : 18,
Offset.getImm()))
1899 return Error(IDLoc,
"branch target out of range");
1902 return Error(IDLoc,
"branch to misaligned address");
1904 case Mips::BGEC:
case Mips::BGEC_MMR6:
1905 case Mips::BLTC:
case Mips::BLTC_MMR6:
1906 case Mips::BGEUC:
case Mips::BGEUC_MMR6:
1907 case Mips::BLTUC:
case Mips::BLTUC_MMR6:
1908 case Mips::BEQC:
case Mips::BEQC_MMR6:
1909 case Mips::BNEC:
case Mips::BNEC_MMR6:
1915 return Error(IDLoc,
"branch target out of range");
1917 return Error(IDLoc,
"branch to misaligned address");
1919 case Mips::BLEZC:
case Mips::BLEZC_MMR6:
1920 case Mips::BGEZC:
case Mips::BGEZC_MMR6:
1921 case Mips::BGTZC:
case Mips::BGTZC_MMR6:
1922 case Mips::BLTZC:
case Mips::BLTZC_MMR6:
1928 return Error(IDLoc,
"branch target out of range");
1930 return Error(IDLoc,
"branch to misaligned address");
1932 case Mips::BEQZC:
case Mips::BEQZC_MMR6:
1933 case Mips::BNEZC:
case Mips::BNEZC_MMR6:
1939 return Error(IDLoc,
"branch target out of range");
1941 return Error(IDLoc,
"branch to misaligned address");
1943 case Mips::BEQZ16_MM:
1944 case Mips::BEQZC16_MMR6:
1945 case Mips::BNEZ16_MM:
1946 case Mips::BNEZC16_MMR6:
1952 return Error(IDLoc,
"branch target out of range");
1954 return Error(IDLoc,
"branch to misaligned address");
1961 if (hasMips32r6() && Opcode == Mips::SSNOP) {
1962 std::string
ISA = hasMips64r6() ?
"MIPS64r6" :
"MIPS32r6";
1963 Warning(IDLoc,
"ssnop is deprecated for " + ISA +
" and is equivalent to a "
1983 return Error(IDLoc,
"expected immediate operand kind");
1985 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1986 Opcode == Mips::BBIT1 ? 63 : 31))
1987 return Error(IDLoc,
"immediate operand value out of range");
1989 Inst.
setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
2000 return Error(IDLoc,
"expected immediate operand kind");
2003 return Error(IDLoc,
"immediate operand value out of range");
2015 unsigned FirstOp = 1;
2016 unsigned SecondOp = 2;
2020 case Mips::SDivIMacro:
2021 case Mips::UDivIMacro:
2022 case Mips::DSDivIMacro:
2023 case Mips::DUDivIMacro:
2025 return Error(IDLoc,
"expected immediate operand kind");
2029 Warning(IDLoc,
"dividing zero by zero");
2031 Warning(IDLoc,
"division by zero");
2043 case Mips::SDivMacro:
2044 case Mips::DSDivMacro:
2045 case Mips::UDivMacro:
2046 case Mips::DUDivMacro:
2051 case Mips::DIVU_MMR6:
2052 case Mips::DIV_MMR6:
2057 Warning(IDLoc,
"dividing zero by zero");
2059 Warning(IDLoc,
"division by zero");
2065 if ((Opcode == Mips::J || Opcode == Mips::J_MM) && inPicMode()) {
2067 BInst.
setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
2076 if ((Opcode == Mips::JAL || Opcode == Mips::JAL_MM) && inPicMode()) {
2077 warnIfNoMacro(IDLoc);
2080 return Error(IDLoc,
"unsupported constant in relocation");
2088 return Error(IDLoc,
"jal doesn't support multiple symbols in PIC mode");
2094 if (expandLoadAddress(Mips::T9, MCRegister(), Inst.
getOperand(0),
2095 !isGP64bit(), IDLoc, Out, STI))
2099 if (inMicroMipsMode())
2100 JalrInst.
setOpcode(IsCpRestoreSet ? Mips::JALRS_MM : Mips::JALR_MM);
2106 if (isJalrRelocAvailable(JalExpr)) {
2112 const MCExpr *RelocJalrExpr =
2116 *TmpExpr, inMicroMipsMode() ?
"R_MICROMIPS_JALR" :
"R_MIPS_JALR",
2122 ExpandedJalSym =
true;
2131 expandMem9Inst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2134 expandMem16Inst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2137 return getParser().hasPendingError();
2141 if (inMicroMipsMode()) {
2142 if (MCID.
mayLoad() && Opcode != Mips::LWP_MM) {
2145 const MCOperandInfo &OpInfo = MCID.
operands()[i];
2150 int MemOffset =
Op.getImm();
2153 if (
isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
2156 (
BaseReg.getReg() == Mips::GP ||
2157 BaseReg.getReg() == Mips::GP_64)) {
2159 TOut.
emitRRI(Mips::LWGP_MM, DstReg.
getReg(), Mips::GP, MemOffset,
2176 case Mips::ADDIUSP_MM:
2179 return Error(IDLoc,
"expected immediate operand kind");
2181 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
2183 return Error(IDLoc,
"immediate operand value out of range");
2185 case Mips::SLL16_MM:
2186 case Mips::SRL16_MM:
2189 return Error(IDLoc,
"expected immediate operand kind");
2191 if (Imm < 1 || Imm > 8)
2192 return Error(IDLoc,
"immediate operand value out of range");
2197 return Error(IDLoc,
"expected immediate operand kind");
2199 if (Imm < -1 || Imm > 126)
2200 return Error(IDLoc,
"immediate operand value out of range");
2202 case Mips::ADDIUR2_MM:
2205 return Error(IDLoc,
"expected immediate operand kind");
2207 if (!(Imm == 1 || Imm == -1 ||
2208 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
2209 return Error(IDLoc,
"immediate operand value out of range");
2211 case Mips::ANDI16_MM:
2214 return Error(IDLoc,
"expected immediate operand kind");
2216 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
2217 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
2218 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
2219 return Error(IDLoc,
"immediate operand value out of range");
2221 case Mips::LBU16_MM:
2224 return Error(IDLoc,
"expected immediate operand kind");
2226 if (Imm < -1 || Imm > 14)
2227 return Error(IDLoc,
"immediate operand value out of range");
2230 case Mips::SB16_MMR6:
2233 return Error(IDLoc,
"expected immediate operand kind");
2235 if (Imm < 0 || Imm > 15)
2236 return Error(IDLoc,
"immediate operand value out of range");
2238 case Mips::LHU16_MM:
2240 case Mips::SH16_MMR6:
2243 return Error(IDLoc,
"expected immediate operand kind");
2245 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
2246 return Error(IDLoc,
"immediate operand value out of range");
2250 case Mips::SW16_MMR6:
2253 return Error(IDLoc,
"expected immediate operand kind");
2255 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
2256 return Error(IDLoc,
"immediate operand value out of range");
2258 case Mips::ADDIUPC_MM:
2261 return Error(IDLoc,
"expected immediate operand kind");
2264 return Error(IDLoc,
"immediate operand value out of range");
2269 return Error(IDLoc,
"invalid operand for instruction");
2271 case Mips::MOVEP_MM:
2272 case Mips::MOVEP_MMR6: {
2275 bool RegPair = ((R0 == Mips::A1 && R1 == Mips::A2) ||
2276 (R0 == Mips::A1 && R1 == Mips::A3) ||
2277 (R0 == Mips::A2 && R1 == Mips::A3) ||
2278 (R0 == Mips::A0 && R1 == Mips::S5) ||
2279 (R0 == Mips::A0 && R1 == Mips::S6) ||
2280 (R0 == Mips::A0 && R1 == Mips::A1) ||
2281 (R0 == Mips::A0 && R1 == Mips::A2) ||
2282 (R0 == Mips::A0 && R1 == Mips::A3));
2284 return Error(IDLoc,
"invalid operand for instruction");
2290 bool FillDelaySlot =
2295 bool PrevForbiddenSlotAttr = CurForbiddenSlotAttr;
2298 bool SetReorderAfterNop =
false;
2303 if (PrevForbiddenSlotAttr && !SafeInForbiddenSlot(MCID)) {
2313 if (AssemblerOptions.
back()->isReorder() && !FillDelaySlot) {
2314 SetReorderAfterNop =
true;
2323 CurForbiddenSlotAttr =
2324 hasForbiddenSlot(MCID) && AssemblerOptions.
back()->isReorder();
2326 if (FillDelaySlot || CurForbiddenSlotAttr)
2329 MacroExpanderResultTy ExpandResult =
2330 tryExpandInstruction(Inst, IDLoc, Out, STI);
2331 switch (ExpandResult) {
2347 if (PrevForbiddenSlotAttr && !SetReorderAfterNop && !FillDelaySlot &&
2348 AssemblerOptions.
back()->isReorder()) {
2354 if (inMicroMipsMode()) {
2369 if (FillDelaySlot) {
2374 if ((Opcode == Mips::JalOneReg || Opcode == Mips::JalTwoReg ||
2376 isPicAndNotNxxAbi()) {
2377 if (IsCpRestoreSet) {
2381 if (!AssemblerOptions.
back()->isReorder())
2388 Warning(IDLoc,
"no .cprestore used in PIC mode");
2394void MipsAsmParser::onEndOfFile() {
2395 MipsTargetStreamer &TOut = getTargetStreamer();
2396 SMLoc IDLoc = SMLoc();
2398 if (CurForbiddenSlotAttr) {
2400 if (AssemblerOptions.
back()->isReorder())
2405MipsAsmParser::MacroExpanderResultTy
2406MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2407 const MCSubtargetInfo *STI) {
2410 return MER_NotAMacro;
2411 case Mips::LoadImm32:
2412 return expandLoadImm(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2413 case Mips::LoadImm64:
2414 return expandLoadImm(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2415 case Mips::LoadAddrImm32:
2416 case Mips::LoadAddrImm64:
2419 "expected immediate operand kind");
2421 return expandLoadAddress(
2423 Inst.
getOpcode() == Mips::LoadAddrImm32, IDLoc, Out, STI)
2426 case Mips::LoadAddrReg32:
2427 case Mips::LoadAddrReg64:
2431 "expected immediate operand kind");
2435 Inst.
getOpcode() == Mips::LoadAddrReg32, IDLoc,
2439 case Mips::B_MM_Pseudo:
2440 case Mips::B_MMR6_Pseudo:
2441 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2445 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2447 case Mips::JalOneReg:
2448 case Mips::JalTwoReg:
2449 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2452 case Mips::BEQLImmMacro:
2453 case Mips::BNELImmMacro:
2454 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2471 case Mips::BLTImmMacro:
2472 case Mips::BLEImmMacro:
2473 case Mips::BGEImmMacro:
2474 case Mips::BGTImmMacro:
2475 case Mips::BLTUImmMacro:
2476 case Mips::BLEUImmMacro:
2477 case Mips::BGEUImmMacro:
2478 case Mips::BGTUImmMacro:
2479 case Mips::BLTLImmMacro:
2480 case Mips::BLELImmMacro:
2481 case Mips::BGELImmMacro:
2482 case Mips::BGTLImmMacro:
2483 case Mips::BLTULImmMacro:
2484 case Mips::BLEULImmMacro:
2485 case Mips::BGEULImmMacro:
2486 case Mips::BGTULImmMacro:
2487 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2488 case Mips::SDivMacro:
2489 case Mips::SDivIMacro:
2490 case Mips::SRemMacro:
2491 case Mips::SRemIMacro:
2492 return expandDivRem(Inst, IDLoc, Out, STI,
false,
true) ? MER_Fail
2494 case Mips::DSDivMacro:
2495 case Mips::DSDivIMacro:
2496 case Mips::DSRemMacro:
2497 case Mips::DSRemIMacro:
2498 return expandDivRem(Inst, IDLoc, Out, STI,
true,
true) ? MER_Fail
2500 case Mips::UDivMacro:
2501 case Mips::UDivIMacro:
2502 case Mips::URemMacro:
2503 case Mips::URemIMacro:
2504 return expandDivRem(Inst, IDLoc, Out, STI,
false,
false) ? MER_Fail
2506 case Mips::DUDivMacro:
2507 case Mips::DUDivIMacro:
2508 case Mips::DURemMacro:
2509 case Mips::DURemIMacro:
2510 return expandDivRem(Inst, IDLoc, Out, STI,
true,
false) ? MER_Fail
2512 case Mips::PseudoTRUNC_W_S:
2513 return expandTrunc(Inst,
false,
false, IDLoc, Out, STI) ? MER_Fail
2515 case Mips::PseudoTRUNC_W_D32:
2516 return expandTrunc(Inst,
true,
false, IDLoc, Out, STI) ? MER_Fail
2518 case Mips::PseudoTRUNC_W_D:
2519 return expandTrunc(Inst,
true,
true, IDLoc, Out, STI) ? MER_Fail
2522 case Mips::LoadImmSingleGPR:
2523 return expandLoadSingleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2525 case Mips::LoadImmSingleFGR:
2526 return expandLoadSingleImmToFPR(Inst, IDLoc, Out, STI) ? MER_Fail
2528 case Mips::LoadImmDoubleGPR:
2529 return expandLoadDoubleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2531 case Mips::LoadImmDoubleFGR:
2532 return expandLoadDoubleImmToFPR(Inst,
true, IDLoc, Out, STI) ? MER_Fail
2534 case Mips::LoadImmDoubleFGR_32:
2535 return expandLoadDoubleImmToFPR(Inst,
false, IDLoc, Out, STI) ? MER_Fail
2539 return expandUlh(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2541 return expandUlh(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2543 return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2546 return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2548 case Mips::NORImm64:
2549 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2552 return expandSge(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2555 case Mips::SGEImm64:
2556 case Mips::SGEUImm64:
2557 return expandSgeImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2560 case Mips::SGTImm64:
2561 case Mips::SGTUImm64:
2562 return expandSgtImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2565 return expandSle(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2568 case Mips::SLEImm64:
2569 case Mips::SLEUImm64:
2570 return expandSleImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2571 case Mips::SLTImm64:
2574 return MER_NotAMacro;
2576 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2577 case Mips::SLTUImm64:
2580 return MER_NotAMacro;
2582 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2583 case Mips::ADDi:
case Mips::ADDi_MM:
2584 case Mips::ADDiu:
case Mips::ADDiu_MM:
2585 case Mips::SLTi:
case Mips::SLTi_MM:
2586 case Mips::SLTiu:
case Mips::SLTiu_MM:
2591 return MER_NotAMacro;
2592 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2595 return MER_NotAMacro;
2596 case Mips::ANDi:
case Mips::ANDi_MM:
case Mips::ANDi64:
2597 case Mips::ORi:
case Mips::ORi_MM:
case Mips::ORi64:
2598 case Mips::XORi:
case Mips::XORi_MM:
case Mips::XORi64:
2603 return MER_NotAMacro;
2604 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2607 return MER_NotAMacro;
2610 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2613 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2616 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2619 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2620 case Mips::ABSMacro:
2621 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2622 case Mips::MULImmMacro:
2623 case Mips::DMULImmMacro:
2624 return expandMulImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2625 case Mips::MULOMacro:
2626 case Mips::DMULOMacro:
2627 return expandMulO(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2628 case Mips::MULOUMacro:
2629 case Mips::DMULOUMacro:
2630 return expandMulOU(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2631 case Mips::DMULMacro:
2632 return expandDMULMacro(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2635 return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2640 return expandStoreDM1Macro(Inst, IDLoc, Out, STI)
2643 case Mips::SEQMacro:
2644 return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2645 case Mips::SEQIMacro:
2646 return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2647 case Mips::SNEMacro:
2648 return expandSne(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2649 case Mips::SNEIMacro:
2650 return expandSneI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2651 case Mips::MFTC0:
case Mips::MTTC0:
2652 case Mips::MFTGPR:
case Mips::MTTGPR:
2653 case Mips::MFTLO:
case Mips::MTTLO:
2654 case Mips::MFTHI:
case Mips::MTTHI:
2655 case Mips::MFTACX:
case Mips::MTTACX:
2656 case Mips::MFTDSP:
case Mips::MTTDSP:
2657 case Mips::MFTC1:
case Mips::MTTC1:
2658 case Mips::MFTHC1:
case Mips::MTTHC1:
2659 case Mips::CFTC1:
case Mips::CTTC1:
2660 return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2662 case Mips::SaadAddr:
2663 return expandSaaAddr(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2667bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2669 const MCSubtargetInfo *STI) {
2670 MipsTargetStreamer &TOut = getTargetStreamer();
2675 const MCOperand FirstRegOp = Inst.
getOperand(0);
2676 const unsigned Opcode = Inst.
getOpcode();
2678 if (Opcode == Mips::JalOneReg) {
2680 if (IsCpRestoreSet && inMicroMipsMode()) {
2683 }
else if (inMicroMipsMode()) {
2684 JalrInst.
setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2691 }
else if (Opcode == Mips::JalTwoReg) {
2693 if (IsCpRestoreSet && inMicroMipsMode())
2696 JalrInst.
setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2698 const MCOperand SecondRegOp = Inst.
getOperand(1);
2705 const MCInstrDesc &MCID = MII.get(JalrInst.
getOpcode());
2728bool MipsAsmParser::loadImmediate(int64_t ImmValue, MCRegister DstReg,
2729 MCRegister SrcReg,
bool Is32BitImm,
2730 bool IsAddress, SMLoc IDLoc, MCStreamer &Out,
2731 const MCSubtargetInfo *STI) {
2732 MipsTargetStreamer &TOut = getTargetStreamer();
2734 if (!Is32BitImm && !isGP64bit()) {
2735 Error(IDLoc,
"instruction requires a 64-bit architecture");
2746 Error(IDLoc,
"instruction requires a 32-bit immediate");
2751 MCRegister ZeroReg = IsAddress ?
ABI.GetNullPtr() :
ABI.GetZeroReg();
2752 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2754 bool UseSrcReg =
false;
2758 MCRegister TmpReg = DstReg;
2760 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2763 MCRegister ATReg = getATReg(IDLoc);
2776 if (IsAddress && !Is32BitImm) {
2777 TOut.
emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2781 TOut.
emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2786 MCRegister TmpReg = DstReg;
2787 if (SrcReg == DstReg) {
2788 TmpReg = getATReg(IDLoc);
2793 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2795 TOut.
emitRRR(
ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2800 warnIfNoMacro(IDLoc);
2802 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2803 uint16_t Bits15To0 = ImmValue & 0xffff;
2804 if (!Is32BitImm && !
isInt<32>(ImmValue)) {
2807 if (ImmValue == 0xffffffff) {
2808 TOut.
emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2809 TOut.
emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2811 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2817 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2818 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2820 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2822 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2826 TOut.
emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2828 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2830 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2836 Error(IDLoc,
"instruction requires a 32-bit immediate");
2843 assert(
BitWidth >= 17 &&
"ImmValue must be at least 17-bit wide");
2847 unsigned ShiftAmount =
BitWidth - 16;
2848 uint16_t
Bits = (ImmValue >> ShiftAmount) & 0xffff;
2849 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2850 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2853 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2858 warnIfNoMacro(IDLoc);
2865 if (loadImmediate(ImmValue >> 32, TmpReg, MCRegister(),
true,
false, IDLoc,
2871 unsigned ShiftCarriedForwards = 16;
2872 for (
int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2873 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2875 if (ImmChunk != 0) {
2876 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2877 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2878 ShiftCarriedForwards = 0;
2881 ShiftCarriedForwards += 16;
2883 ShiftCarriedForwards -= 16;
2886 if (ShiftCarriedForwards)
2887 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2890 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2895bool MipsAsmParser::expandLoadImm(MCInst &Inst,
bool Is32BitImm, SMLoc IDLoc,
2896 MCStreamer &Out,
const MCSubtargetInfo *STI) {
2898 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
2899 const MCOperand &DstRegOp = Inst.
getOperand(0);
2900 assert(DstRegOp.
isReg() &&
"expected register operand kind");
2902 if (loadImmediate(ImmOp.
getImm(), DstRegOp.
getReg(), MCRegister(), Is32BitImm,
2903 false, IDLoc, Out, STI))
2909bool MipsAsmParser::expandLoadAddress(MCRegister DstReg, MCRegister BaseReg,
2911 bool Is32BitAddress, SMLoc IDLoc,
2913 const MCSubtargetInfo *STI) {
2915 if (Is32BitAddress &&
ABI.ArePtrs64bit()) {
2916 Warning(IDLoc,
"la used to load 64-bit address");
2918 Is32BitAddress =
false;
2922 if (!Is32BitAddress && !hasMips3()) {
2923 Error(IDLoc,
"instruction requires a 64-bit architecture");
2928 return loadAndAddSymbolAddress(
Offset.getExpr(), DstReg, BaseReg,
2929 Is32BitAddress, IDLoc, Out, STI);
2931 if (!
ABI.ArePtrs64bit()) {
2933 Is32BitAddress =
true;
2936 return loadImmediate(
Offset.getImm(), DstReg, BaseReg, Is32BitAddress,
true,
2940bool MipsAsmParser::loadAndAddSymbolAddress(
const MCExpr *SymExpr,
2942 MCRegister SrcReg,
bool Is32BitSym,
2943 SMLoc IDLoc, MCStreamer &Out,
2944 const MCSubtargetInfo *STI) {
2945 MipsTargetStreamer &TOut = getTargetStreamer();
2947 SrcReg.
isValid() && SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64;
2948 warnIfNoMacro(IDLoc);
2953 Error(IDLoc,
"expected relocatable expression");
2957 Error(IDLoc,
"expected relocatable expression with only one symbol");
2961 bool IsPtr64 =
ABI.ArePtrs64bit();
2965 static_cast<const MCSymbolELF *
>(Res.
getAddSym())->getBinding() ==
2972 bool UseXGOT = STI->
hasFeature(Mips::FeatureXGOT) && !IsLocalSym;
2978 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2981 const MCExpr *CallHiExpr =
2983 const MCExpr *CallLoExpr =
2987 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, DstReg, GPReg,
2989 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, DstReg,
2992 const MCExpr *CallExpr =
2994 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, GPReg,
3000 MCRegister TmpReg = DstReg;
3002 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
3006 MCRegister ATReg = getATReg(IDLoc);
3025 const MCExpr *CallHiExpr =
3032 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg, GPReg,
3034 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, TmpReg,
3038 TOut.
emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3044 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3049 const MCSpecifierExpr *GotExpr =
nullptr;
3050 const MCExpr *LoExpr =
nullptr;
3051 if (
ABI.IsN32() ||
ABI.IsN64()) {
3070 Error(IDLoc,
"macro instruction uses large offset, which is not "
3071 "currently supported");
3100 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, GPReg,
3104 TOut.
emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3108 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3114 const auto *HiExpr =
3116 const auto *LoExpr =
3120 if (
ABI.ArePtrs64bit() && isGP64bit()) {
3128 const auto *HighestExpr =
3130 const auto *HigherExpr =
3135 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
3137 if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
3138 MCRegister ATReg = getATReg(IDLoc);
3150 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3152 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3155 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3158 TOut.
emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
3161 }
else if (canUseATReg() && !RdRegIsRsReg && DstReg != getATReg(IDLoc)) {
3162 MCRegister ATReg = getATReg(IDLoc);
3178 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3182 TOut.
emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3183 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3185 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3188 }
else if ((!canUseATReg() && !RdRegIsRsReg) ||
3189 (canUseATReg() && DstReg == getATReg(IDLoc))) {
3200 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3202 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3203 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3205 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3206 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3209 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3215 assert(SrcReg == DstReg && !canUseATReg() &&
3216 "Could have expanded dla but didn't?");
3217 reportParseError(IDLoc,
3218 "pseudo-instruction requires $at, which is not available");
3232 MCRegister TmpReg = DstReg;
3234 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
3237 MCRegister ATReg = getATReg(IDLoc);
3248 TOut.
emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3251 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
3260 if (getMipsMCRegisterClass(Mips::FGR32RegClassID).
contains(
Reg))
3261 return Reg == (
unsigned)Mips::F31 ? (
unsigned)Mips::F0 :
Reg + 1;
3263 default:
llvm_unreachable(
"Unknown register in assembly macro expansion!");
3264 case Mips::ZERO:
return Mips::AT;
3265 case Mips::AT:
return Mips::V0;
3266 case Mips::V0:
return Mips::V1;
3267 case Mips::V1:
return Mips::A0;
3268 case Mips::A0:
return Mips::A1;
3269 case Mips::A1:
return Mips::A2;
3270 case Mips::A2:
return Mips::A3;
3271 case Mips::A3:
return Mips::T0;
3272 case Mips::T0:
return Mips::T1;
3273 case Mips::T1:
return Mips::T2;
3274 case Mips::T2:
return Mips::T3;
3275 case Mips::T3:
return Mips::T4;
3276 case Mips::T4:
return Mips::T5;
3277 case Mips::T5:
return Mips::T6;
3278 case Mips::T6:
return Mips::T7;
3279 case Mips::T7:
return Mips::S0;
3280 case Mips::S0:
return Mips::S1;
3281 case Mips::S1:
return Mips::S2;
3282 case Mips::S2:
return Mips::S3;
3283 case Mips::S3:
return Mips::S4;
3284 case Mips::S4:
return Mips::S5;
3285 case Mips::S5:
return Mips::S6;
3286 case Mips::S6:
return Mips::S7;
3287 case Mips::S7:
return Mips::T8;
3288 case Mips::T8:
return Mips::T9;
3289 case Mips::T9:
return Mips::K0;
3290 case Mips::K0:
return Mips::K1;
3291 case Mips::K1:
return Mips::GP;
3292 case Mips::GP:
return Mips::SP;
3293 case Mips::SP:
return Mips::FP;
3294 case Mips::FP:
return Mips::RA;
3295 case Mips::RA:
return Mips::ZERO;
3296 case Mips::D0:
return Mips::F1;
3297 case Mips::D1:
return Mips::F3;
3298 case Mips::D2:
return Mips::F5;
3299 case Mips::D3:
return Mips::F7;
3300 case Mips::D4:
return Mips::F9;
3301 case Mips::D5:
return Mips::F11;
3302 case Mips::D6:
return Mips::F13;
3303 case Mips::D7:
return Mips::F15;
3304 case Mips::D8:
return Mips::F17;
3305 case Mips::D9:
return Mips::F19;
3306 case Mips::D10:
return Mips::F21;
3307 case Mips::D11:
return Mips::F23;
3308 case Mips::D12:
return Mips::F25;
3309 case Mips::D13:
return Mips::F27;
3310 case Mips::D14:
return Mips::F29;
3311 case Mips::D15:
return Mips::F31;
3321bool MipsAsmParser::emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc,
3323 MCRegister ATReg = getATReg(IDLoc);
3329 const auto *GotExpr =
3332 if(isABI_O32() || isABI_N32()) {
3341 const auto *HiExpr =
3350 if(isABI_O32() || isABI_N32()) {
3354 const auto *HighestExpr =
3357 const auto *HigherExpr =
3362 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3364 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3367 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3376 if ((
Hi_32(ImmOp64) & 0x7ff00000) == 0) {
3387 float TmpFloat =
static_cast<float>(DoubleImm);
3391bool MipsAsmParser::expandLoadSingleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3393 const MCSubtargetInfo *STI) {
3396 "Invalid instruction operand.");
3403 return loadImmediate(ImmOp32, FirstReg, MCRegister(),
true,
false, IDLoc, Out,
3407bool MipsAsmParser::expandLoadSingleImmToFPR(MCInst &Inst, SMLoc IDLoc,
3409 const MCSubtargetInfo *STI) {
3410 MipsTargetStreamer &TOut = getTargetStreamer();
3413 "Invalid instruction operand.");
3422 MCRegister TmpReg = Mips::ZERO;
3424 TmpReg = getATReg(IDLoc);
3429 if (
Lo_32(ImmOp64) == 0) {
3430 if (TmpReg != Mips::ZERO && loadImmediate(ImmOp32, TmpReg, MCRegister(),
3431 true,
false, IDLoc, Out, STI))
3433 TOut.
emitRR(Mips::MTC1, FirstReg, TmpReg, IDLoc, STI);
3437 MCSection *CS = getStreamer().getCurrentSectionOnly();
3440 MCSection *ReadOnlySection =
3447 getStreamer().switchSection(ReadOnlySection);
3448 getStreamer().emitLabel(Sym, IDLoc);
3449 getStreamer().emitInt32(ImmOp32);
3450 getStreamer().switchSection(CS);
3452 if (emitPartialAddress(TOut, IDLoc, Sym))
3459bool MipsAsmParser::expandLoadDoubleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3461 const MCSubtargetInfo *STI) {
3462 MipsTargetStreamer &TOut = getTargetStreamer();
3465 "Invalid instruction operand.");
3472 if (
Lo_32(ImmOp64) == 0) {
3474 if (loadImmediate(ImmOp64, FirstReg, MCRegister(),
false,
false, IDLoc,
3478 if (loadImmediate(
Hi_32(ImmOp64), FirstReg, MCRegister(),
true,
false,
3482 if (loadImmediate(0,
nextReg(FirstReg), MCRegister(),
true,
false, IDLoc,
3489 MCSection *CS = getStreamer().getCurrentSectionOnly();
3490 MCSection *ReadOnlySection =
3497 getStreamer().switchSection(ReadOnlySection);
3498 getStreamer().emitLabel(Sym, IDLoc);
3499 getStreamer().emitValueToAlignment(
Align(8));
3500 getStreamer().emitIntValue(ImmOp64, 8);
3501 getStreamer().switchSection(CS);
3503 MCRegister TmpReg = getATReg(IDLoc);
3507 if (emitPartialAddress(TOut, IDLoc, Sym))
3510 TOut.
emitRRX(isABI_N64() ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3514 TOut.
emitRRI(Mips::LD, FirstReg, TmpReg, 0, IDLoc, STI);
3516 TOut.
emitRRI(Mips::LW, FirstReg, TmpReg, 0, IDLoc, STI);
3517 TOut.
emitRRI(Mips::LW,
nextReg(FirstReg), TmpReg, 4, IDLoc, STI);
3522bool MipsAsmParser::expandLoadDoubleImmToFPR(MCInst &Inst,
bool Is64FPU,
3523 SMLoc IDLoc, MCStreamer &Out,
3524 const MCSubtargetInfo *STI) {
3525 MipsTargetStreamer &TOut = getTargetStreamer();
3528 "Invalid instruction operand.");
3535 MCRegister TmpReg = Mips::ZERO;
3537 TmpReg = getATReg(IDLoc);
3542 if ((
Lo_32(ImmOp64) == 0) &&
3543 !((
Hi_32(ImmOp64) & 0xffff0000) && (
Hi_32(ImmOp64) & 0x0000ffff))) {
3545 if (TmpReg != Mips::ZERO && loadImmediate(ImmOp64, TmpReg, MCRegister(),
3546 false,
false, IDLoc, Out, STI))
3548 TOut.
emitRR(Mips::DMTC1, FirstReg, TmpReg, IDLoc, STI);
3552 if (TmpReg != Mips::ZERO &&
3553 loadImmediate(
Hi_32(ImmOp64), TmpReg, MCRegister(),
true,
false, IDLoc,
3557 if (hasMips32r2()) {
3558 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3559 TOut.
emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, TmpReg, IDLoc, STI);
3561 TOut.
emitRR(Mips::MTC1,
nextReg(FirstReg), TmpReg, IDLoc, STI);
3562 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3567 MCSection *CS = getStreamer().getCurrentSectionOnly();
3570 MCSection *ReadOnlySection =
3577 getStreamer().switchSection(ReadOnlySection);
3578 getStreamer().emitLabel(Sym, IDLoc);
3579 getStreamer().emitValueToAlignment(
Align(8));
3580 getStreamer().emitIntValue(ImmOp64, 8);
3581 getStreamer().switchSection(CS);
3583 if (emitPartialAddress(TOut, IDLoc, Sym))
3586 TOut.
emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, TmpReg,
3592bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
3594 const MCSubtargetInfo *STI) {
3595 MipsTargetStreamer &TOut = getTargetStreamer();
3598 "unexpected number of operands");
3608 assert(
Offset.isImm() &&
"expected immediate operand kind");
3612 if (inMicroMipsMode())
3613 Inst.
setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3616 return Error(IDLoc,
"branch target out of range");
3618 return Error(IDLoc,
"branch to misaligned address");
3630 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
3637bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3638 const MCSubtargetInfo *STI) {
3639 MipsTargetStreamer &TOut = getTargetStreamer();
3640 const MCOperand &DstRegOp = Inst.
getOperand(0);
3641 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3644 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
3646 const MCOperand &MemOffsetOp = Inst.
getOperand(2);
3648 "expected immediate or expression operand");
3650 bool IsLikely =
false;
3660 case Mips::BEQLImmMacro:
3664 case Mips::BNELImmMacro:
3673 int64_t ImmValue = ImmOp.
getImm();
3674 if (ImmValue == 0) {
3678 TOut.
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3680 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3683 warnIfNoMacro(IDLoc);
3685 MCRegister ATReg = getATReg(IDLoc);
3689 if (loadImmediate(ImmValue, ATReg, MCRegister(), !isGP64bit(),
true, IDLoc,
3693 if (IsLikely && MemOffsetOp.
isExpr()) {
3696 TOut.
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3698 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3703void MipsAsmParser::expandMem16Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3704 const MCSubtargetInfo *STI,
bool IsLoad) {
3706 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3707 unsigned StartOp = NumOp == 3 ? 0 : 1;
3709 const MCOperand &DstRegOp = Inst.
getOperand(StartOp);
3710 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3711 const MCOperand &BaseRegOp = Inst.
getOperand(StartOp + 1);
3712 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3715 MipsTargetStreamer &TOut = getTargetStreamer();
3717 MCRegister DstReg = DstRegOp.
getReg();
3719 MCRegister TmpReg = DstReg;
3721 const MCInstrDesc &
Desc = MII.get(OpCode);
3722 int16_t DstRegClass =
3723 MII.getOpRegClassID(
Desc.operands()[StartOp],
3725 unsigned DstRegClassID =
3726 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3727 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3728 (DstRegClassID == Mips::GPR64RegClassID);
3730 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3733 TmpReg = getATReg(IDLoc);
3738 auto emitInstWithOffset = [&](
const MCOperand &
Off) {
3740 TOut.
emitRRX(OpCode, DstReg, TmpReg, Off, IDLoc, STI);
3742 TOut.
emitRRRX(OpCode, DstReg, DstReg, TmpReg, Off, IDLoc, STI);
3746 int64_t LoOffset =
OffsetOp.getImm() & 0xffff;
3747 int64_t HiOffset =
OffsetOp.getImm() & ~0xffff;
3751 if (LoOffset & 0x8000)
3752 HiOffset += 0x10000;
3754 bool IsLargeOffset = HiOffset != 0;
3756 if (IsLargeOffset) {
3758 if (loadImmediate(HiOffset, TmpReg, MCRegister(), Is32BitImm,
true, IDLoc,
3763 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3764 TOut.
emitRRR(
ABI.ArePtrs64bit() ? Mips::DADDu : Mips::ADDu, TmpReg,
3765 TmpReg, BaseReg, IDLoc, STI);
3779 if (!
OffsetOp.getExpr()->evaluateAsRelocatable(Res,
nullptr)) {
3780 Error(IDLoc,
"expected relocatable expression");
3784 Error(IDLoc,
"expected relocatable expression with only one symbol");
3788 loadAndAddSymbolAddress(
3790 BaseReg, !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3798 const MCExpr *OffExpr =
OffsetOp.getExpr();
3810 TOut.
emitRX(Mips::LUi, TmpReg, HighestOperand, IDLoc, STI);
3811 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HigherOperand, IDLoc, STI);
3812 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3813 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HiOperand, IDLoc, STI);
3814 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3815 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3816 TOut.
emitRRR(Mips::DADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3817 emitInstWithOffset(LoOperand);
3820 TOut.
emitRX(Mips::LUi, TmpReg, HiOperand, IDLoc, STI);
3821 if (BaseReg != Mips::ZERO)
3822 TOut.
emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3824 emitInstWithOffset(LoOperand);
3833void MipsAsmParser::expandMem9Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3834 const MCSubtargetInfo *STI,
bool IsLoad) {
3836 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3837 unsigned StartOp = NumOp == 3 ? 0 : 1;
3839 const MCOperand &DstRegOp = Inst.
getOperand(StartOp);
3840 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3841 const MCOperand &BaseRegOp = Inst.
getOperand(StartOp + 1);
3842 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3845 MipsTargetStreamer &TOut = getTargetStreamer();
3847 MCRegister DstReg = DstRegOp.
getReg();
3849 MCRegister TmpReg = DstReg;
3851 const MCInstrDesc &
Desc = MII.get(OpCode);
3852 int16_t DstRegClass =
3853 MII.getOpRegClassID(
Desc.operands()[StartOp],
3856 unsigned DstRegClassID =
3857 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3858 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3859 (DstRegClassID == Mips::GPR64RegClassID);
3861 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3864 TmpReg = getATReg(IDLoc);
3869 auto emitInst = [&]() {
3878 loadImmediate(
OffsetOp.getImm(), TmpReg, BaseReg, !
ABI.ArePtrs64bit(),
true,
3885 loadAndAddSymbolAddress(
OffsetOp.getExpr(), TmpReg, BaseReg,
3886 !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3894bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
3896 const MCSubtargetInfo *STI) {
3899 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3903 Inst.
getOperand(OpNum - 3).
isReg() &&
"Invalid instruction operand.");
3912 if (inMicroMipsMode() && hasMips32r6())
3913 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3915 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3923bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
3925 const MCSubtargetInfo *STI) {
3926 MipsTargetStreamer &TOut = getTargetStreamer();
3927 bool EmittedNoMacroWarning =
false;
3928 unsigned PseudoOpcode = Inst.
getOpcode();
3933 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3934 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3939 else if (TrgOp.
isImm()) {
3940 warnIfNoMacro(IDLoc);
3941 EmittedNoMacroWarning =
true;
3943 TrgReg = getATReg(IDLoc);
3947 switch(PseudoOpcode) {
3950 case Mips::BLTImmMacro:
3951 PseudoOpcode = Mips::BLT;
3953 case Mips::BLEImmMacro:
3954 PseudoOpcode = Mips::BLE;
3956 case Mips::BGEImmMacro:
3957 PseudoOpcode = Mips::BGE;
3959 case Mips::BGTImmMacro:
3960 PseudoOpcode = Mips::BGT;
3962 case Mips::BLTUImmMacro:
3963 PseudoOpcode = Mips::BLTU;
3965 case Mips::BLEUImmMacro:
3966 PseudoOpcode = Mips::BLEU;
3968 case Mips::BGEUImmMacro:
3969 PseudoOpcode = Mips::BGEU;
3971 case Mips::BGTUImmMacro:
3972 PseudoOpcode = Mips::BGTU;
3974 case Mips::BLTLImmMacro:
3975 PseudoOpcode = Mips::BLTL;
3977 case Mips::BLELImmMacro:
3978 PseudoOpcode = Mips::BLEL;
3980 case Mips::BGELImmMacro:
3981 PseudoOpcode = Mips::BGEL;
3983 case Mips::BGTLImmMacro:
3984 PseudoOpcode = Mips::BGTL;
3986 case Mips::BLTULImmMacro:
3987 PseudoOpcode = Mips::BLTUL;
3989 case Mips::BLEULImmMacro:
3990 PseudoOpcode = Mips::BLEUL;
3992 case Mips::BGEULImmMacro:
3993 PseudoOpcode = Mips::BGEUL;
3995 case Mips::BGTULImmMacro:
3996 PseudoOpcode = Mips::BGTUL;
4000 if (loadImmediate(TrgOp.
getImm(), TrgReg, MCRegister(), !isGP64bit(),
false,
4005 switch (PseudoOpcode) {
4010 AcceptsEquality =
false;
4011 ReverseOrderSLT =
false;
4013 ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
4014 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
4015 ZeroSrcOpcode = Mips::BGTZ;
4016 ZeroTrgOpcode = Mips::BLTZ;
4022 AcceptsEquality =
true;
4023 ReverseOrderSLT =
true;
4025 ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
4026 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
4027 ZeroSrcOpcode = Mips::BGEZ;
4028 ZeroTrgOpcode = Mips::BLEZ;
4034 AcceptsEquality =
true;
4035 ReverseOrderSLT =
false;
4037 ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
4038 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
4039 ZeroSrcOpcode = Mips::BLEZ;
4040 ZeroTrgOpcode = Mips::BGEZ;
4046 AcceptsEquality =
false;
4047 ReverseOrderSLT =
true;
4049 ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
4050 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
4051 ZeroSrcOpcode = Mips::BLTZ;
4052 ZeroTrgOpcode = Mips::BGTZ;
4058 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
4059 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
4060 if (IsSrcRegZero && IsTrgRegZero) {
4064 if (PseudoOpcode == Mips::BLT) {
4069 if (PseudoOpcode == Mips::BLE) {
4072 Warning(IDLoc,
"branch is always taken");
4075 if (PseudoOpcode == Mips::BGE) {
4078 Warning(IDLoc,
"branch is always taken");
4081 if (PseudoOpcode == Mips::BGT) {
4086 if (PseudoOpcode == Mips::BGTU) {
4087 TOut.
emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
4091 if (AcceptsEquality) {
4094 TOut.
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4096 Warning(IDLoc,
"branch is always taken");
4103 if (IsSrcRegZero || IsTrgRegZero) {
4104 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
4105 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
4112 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
4113 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
4119 TOut.
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4121 Warning(IDLoc,
"branch is always taken");
4137 TOut.
emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
4138 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
4145 TOut.
emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
4146 IsSrcRegZero ? TrgReg : SrcReg,
4153 MCRegister ATRegNum = getATReg(IDLoc);
4157 if (!EmittedNoMacroWarning)
4158 warnIfNoMacro(IDLoc);
4175 TOut.
emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
4176 ReverseOrderSLT ? TrgReg : SrcReg,
4177 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
4179 TOut.
emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
4180 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
4194bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4195 const MCSubtargetInfo *STI,
4196 const bool IsMips64,
const bool Signed) {
4197 MipsTargetStreamer &TOut = getTargetStreamer();
4199 warnIfNoMacro(IDLoc);
4201 const MCOperand &RdRegOp = Inst.
getOperand(0);
4202 assert(RdRegOp.
isReg() &&
"expected register operand kind");
4203 MCRegister RdReg = RdRegOp.
getReg();
4205 const MCOperand &RsRegOp = Inst.
getOperand(1);
4206 assert(RsRegOp.
isReg() &&
"expected register operand kind");
4207 MCRegister RsReg = RsRegOp.
getReg();
4214 "expected register or immediate operand kind");
4218 ImmValue = RtOp.
getImm();
4225 DivOp =
Signed ? Mips::DSDIV : Mips::DUDIV;
4226 ZeroReg = Mips::ZERO_64;
4229 DivOp =
Signed ? Mips::SDIV : Mips::UDIV;
4230 ZeroReg = Mips::ZERO;
4234 bool UseTraps = useTraps();
4237 bool isDiv = Opcode == Mips::SDivMacro || Opcode == Mips::SDivIMacro ||
4238 Opcode == Mips::UDivMacro || Opcode == Mips::UDivIMacro ||
4239 Opcode == Mips::DSDivMacro || Opcode == Mips::DSDivIMacro ||
4240 Opcode == Mips::DUDivMacro || Opcode == Mips::DUDivIMacro;
4242 bool isRem = Opcode == Mips::SRemMacro || Opcode == Mips::SRemIMacro ||
4243 Opcode == Mips::URemMacro || Opcode == Mips::URemIMacro ||
4244 Opcode == Mips::DSRemMacro || Opcode == Mips::DSRemIMacro ||
4245 Opcode == Mips::DURemMacro || Opcode == Mips::DURemIMacro;
4248 MCRegister ATReg = getATReg(IDLoc);
4254 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4256 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4260 if (isRem && (ImmValue == 1 || (
Signed && (ImmValue == -1)))) {
4261 TOut.
emitRRR(Mips::OR, RdReg, ZeroReg, ZeroReg, IDLoc, STI);
4263 }
else if (isDiv && ImmValue == 1) {
4264 TOut.
emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI);
4266 }
else if (isDiv &&
Signed && ImmValue == -1) {
4267 TOut.
emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
4270 if (loadImmediate(ImmValue, ATReg, MCRegister(),
isInt<32>(ImmValue),
4271 false, Inst.
getLoc(), Out, STI))
4273 TOut.
emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
4274 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4284 if (!
NoZeroDivCheck && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
4286 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4289 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4295 if (isRem && (RdReg == Mips::ZERO || RdReg == Mips::ZERO_64)) {
4296 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4305 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4308 TOut.
emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4311 BrTarget =
Context.createTempSymbol();
4314 TOut.
emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4319 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4325 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4329bool MipsAsmParser::expandTrunc(MCInst &Inst,
bool IsDouble,
bool Is64FPU,
4330 SMLoc IDLoc, MCStreamer &Out,
4331 const MCSubtargetInfo *STI) {
4332 MipsTargetStreamer &TOut = getTargetStreamer();
4342 if (hasMips1() && !hasMips2()) {
4343 MCRegister ATReg = getATReg(IDLoc);
4346 TOut.
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4347 TOut.
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4349 TOut.
emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4350 TOut.
emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4351 TOut.
emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4353 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4355 FirstReg, SecondReg, IDLoc, STI);
4356 TOut.
emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4361 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4363 FirstReg, SecondReg, IDLoc, STI);
4368bool MipsAsmParser::expandUlh(MCInst &Inst,
bool Signed, SMLoc IDLoc,
4369 MCStreamer &Out,
const MCSubtargetInfo *STI) {
4370 if (hasMips32r6() || hasMips64r6()) {
4371 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4374 const MCOperand &DstRegOp = Inst.
getOperand(0);
4375 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4376 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4377 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4378 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4379 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4381 MipsTargetStreamer &TOut = getTargetStreamer();
4382 MCRegister DstReg = DstRegOp.
getReg();
4383 MCRegister SrcReg = SrcRegOp.
getReg();
4384 int64_t OffsetValue = OffsetImmOp.
getImm();
4388 warnIfNoMacro(IDLoc);
4389 MCRegister ATReg = getATReg(IDLoc);
4394 if (IsLargeOffset) {
4395 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4400 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4401 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4405 MCRegister FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4406 MCRegister SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4408 MCRegister LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4409 MCRegister SllReg = IsLargeOffset ? DstReg : ATReg;
4411 TOut.
emitRRI(
Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4412 FirstOffset, IDLoc, STI);
4413 TOut.
emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4414 TOut.
emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4415 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4420bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4421 const MCSubtargetInfo *STI) {
4422 if (hasMips32r6() || hasMips64r6()) {
4423 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4426 const MCOperand &DstRegOp = Inst.
getOperand(0);
4427 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4428 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4429 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4430 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4431 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4433 MipsTargetStreamer &TOut = getTargetStreamer();
4434 MCRegister DstReg = DstRegOp.
getReg();
4435 MCRegister SrcReg = SrcRegOp.
getReg();
4436 int64_t OffsetValue = OffsetImmOp.
getImm();
4438 warnIfNoMacro(IDLoc);
4439 MCRegister ATReg = getATReg(IDLoc);
4444 if (IsLargeOffset) {
4445 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4450 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4451 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4455 if (IsLargeOffset) {
4456 TOut.
emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4457 TOut.
emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4458 TOut.
emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4459 TOut.
emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4460 TOut.
emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4461 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4463 TOut.
emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4464 TOut.
emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4465 TOut.
emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4471bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4472 const MCSubtargetInfo *STI) {
4473 if (hasMips32r6() || hasMips64r6()) {
4474 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4477 const MCOperand &DstRegOp = Inst.
getOperand(0);
4478 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4479 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4480 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4481 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4482 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4484 MipsTargetStreamer &TOut = getTargetStreamer();
4485 MCRegister DstReg = DstRegOp.
getReg();
4486 MCRegister SrcReg = SrcRegOp.
getReg();
4487 int64_t OffsetValue = OffsetImmOp.
getImm();
4491 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4492 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4496 bool IsLoadInst = (Inst.
getOpcode() == Mips::Ulw);
4497 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4498 MCRegister TmpReg = SrcReg;
4499 if (IsLargeOffset || DoMove) {
4500 warnIfNoMacro(IDLoc);
4501 TmpReg = getATReg(IDLoc);
4506 if (IsLargeOffset) {
4507 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4515 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4516 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4517 TOut.
emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4518 TOut.
emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4521 TOut.
emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4526bool MipsAsmParser::expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4527 const MCSubtargetInfo *STI) {
4528 MipsTargetStreamer &TOut = getTargetStreamer();
4540 warnIfNoMacro(IDLoc);
4554 TOut.
emitRRR(OpCode, DstReg, SrcReg, OpReg, IDLoc, STI);
4555 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4560bool MipsAsmParser::expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4561 const MCSubtargetInfo *STI) {
4562 MipsTargetStreamer &TOut = getTargetStreamer();
4572 unsigned OpRegCode, OpImmCode;
4574 warnIfNoMacro(IDLoc);
4578 case Mips::SGEImm64:
4579 OpRegCode = Mips::SLT;
4580 OpImmCode = Mips::SLTi;
4583 case Mips::SGEUImm64:
4584 OpRegCode = Mips::SLTu;
4585 OpImmCode = Mips::SLTiu;
4594 TOut.
emitRRI(OpImmCode, DstReg, SrcReg, ImmValue, IDLoc, STI);
4595 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4597 MCRegister ImmReg = DstReg;
4598 if (DstReg == SrcReg) {
4599 MCRegister ATReg = getATReg(Inst.
getLoc());
4605 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
4606 false, IDLoc, Out, STI))
4609 TOut.
emitRRR(OpRegCode, DstReg, SrcReg, ImmReg, IDLoc, STI);
4610 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4616bool MipsAsmParser::expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4617 const MCSubtargetInfo *STI) {
4618 MipsTargetStreamer &TOut = getTargetStreamer();
4627 MCRegister ImmReg = DstReg;
4631 warnIfNoMacro(IDLoc);
4635 case Mips::SGTImm64:
4639 case Mips::SGTUImm64:
4646 if (DstReg == SrcReg) {
4647 MCRegister ATReg = getATReg(Inst.
getLoc());
4653 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
false,
4658 TOut.
emitRRR(OpCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4663bool MipsAsmParser::expandSle(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4664 const MCSubtargetInfo *STI) {
4665 MipsTargetStreamer &TOut = getTargetStreamer();
4677 warnIfNoMacro(IDLoc);
4691 TOut.
emitRRR(OpCode, DstReg, OpReg, SrcReg, IDLoc, STI);
4692 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4697bool MipsAsmParser::expandSleImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4698 const MCSubtargetInfo *STI) {
4699 MipsTargetStreamer &TOut = getTargetStreamer();
4711 warnIfNoMacro(IDLoc);
4715 case Mips::SLEImm64:
4716 OpRegCode = Mips::SLT;
4719 case Mips::SLEUImm64:
4720 OpRegCode = Mips::SLTu;
4727 MCRegister ImmReg = DstReg;
4728 if (DstReg == SrcReg) {
4729 MCRegister ATReg = getATReg(Inst.
getLoc());
4735 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
false,
4739 TOut.
emitRRR(OpRegCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4740 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4745bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
4747 const MCSubtargetInfo *STI) {
4748 MipsTargetStreamer &TOut = getTargetStreamer();
4756 MCRegister FinalDstReg;
4763 unsigned FinalOpcode = Inst.
getOpcode();
4765 if (DstReg == SrcReg) {
4766 ATReg = getATReg(Inst.
getLoc());
4769 FinalDstReg = DstReg;
4773 if (!loadImmediate(ImmValue, DstReg, MCRegister(), Is32Bit,
false,
4774 Inst.
getLoc(), Out, STI)) {
4775 switch (FinalOpcode) {
4779 FinalOpcode = Mips::ADD;
4782 FinalOpcode = Mips::ADDu;
4785 FinalOpcode = Mips::AND;
4788 FinalOpcode = Mips::NOR;
4791 FinalOpcode = Mips::OR;
4794 FinalOpcode = Mips::SLT;
4797 FinalOpcode = Mips::SLTu;
4800 FinalOpcode = Mips::XOR;
4803 FinalOpcode = Mips::ADD_MM;
4805 case Mips::ADDiu_MM:
4806 FinalOpcode = Mips::ADDu_MM;
4809 FinalOpcode = Mips::AND_MM;
4812 FinalOpcode = Mips::OR_MM;
4815 FinalOpcode = Mips::SLT_MM;
4817 case Mips::SLTiu_MM:
4818 FinalOpcode = Mips::SLTu_MM;
4821 FinalOpcode = Mips::XOR_MM;
4824 FinalOpcode = Mips::AND64;
4826 case Mips::NORImm64:
4827 FinalOpcode = Mips::NOR64;
4830 FinalOpcode = Mips::OR64;
4832 case Mips::SLTImm64:
4833 FinalOpcode = Mips::SLT64;
4835 case Mips::SLTUImm64:
4836 FinalOpcode = Mips::SLTu64;
4839 FinalOpcode = Mips::XOR64;
4844 TOut.
emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4846 TOut.
emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4852bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4853 const MCSubtargetInfo *STI) {
4854 MipsTargetStreamer &TOut = getTargetStreamer();
4859 MCRegister TmpReg =
DReg;
4861 unsigned FirstShift = Mips::NOP;
4862 unsigned SecondShift = Mips::NOP;
4864 if (hasMips32r2()) {
4866 TmpReg = getATReg(Inst.
getLoc());
4872 TOut.
emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4873 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
4878 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
4890 FirstShift = Mips::SRLV;
4891 SecondShift = Mips::SLLV;
4894 FirstShift = Mips::SLLV;
4895 SecondShift = Mips::SRLV;
4899 ATReg = getATReg(Inst.
getLoc());
4903 TOut.
emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4904 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
4905 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
4906 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
4914bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
4916 const MCSubtargetInfo *STI) {
4917 MipsTargetStreamer &TOut = getTargetStreamer();
4923 unsigned FirstShift = Mips::NOP;
4924 unsigned SecondShift = Mips::NOP;
4926 if (hasMips32r2()) {
4928 uint64_t MaxShift = 32;
4929 uint64_t ShiftValue = ImmValue;
4931 ShiftValue = MaxShift - ImmValue;
4932 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
4937 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.
getLoc(), STI);
4945 if (ImmValue == 0) {
4954 FirstShift = Mips::SLL;
4955 SecondShift = Mips::SRL;
4958 FirstShift = Mips::SRL;
4959 SecondShift = Mips::SLL;
4963 ATReg = getATReg(Inst.
getLoc());
4967 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.
getLoc(), STI);
4968 TOut.
emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.
getLoc(), STI);
4969 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
4977bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4978 const MCSubtargetInfo *STI) {
4979 MipsTargetStreamer &TOut = getTargetStreamer();
4984 MCRegister TmpReg =
DReg;
4986 unsigned FirstShift = Mips::NOP;
4987 unsigned SecondShift = Mips::NOP;
4989 if (hasMips64r2()) {
4990 if (TmpReg == SReg) {
4991 TmpReg = getATReg(Inst.
getLoc());
4997 TOut.
emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4998 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
5003 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
5015 FirstShift = Mips::DSRLV;
5016 SecondShift = Mips::DSLLV;
5019 FirstShift = Mips::DSLLV;
5020 SecondShift = Mips::DSRLV;
5024 ATReg = getATReg(Inst.
getLoc());
5028 TOut.
emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
5029 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
5030 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
5031 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5039bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
5041 const MCSubtargetInfo *STI) {
5042 MipsTargetStreamer &TOut = getTargetStreamer();
5048 unsigned FirstShift = Mips::NOP;
5049 unsigned SecondShift = Mips::NOP;
5053 if (hasMips64r2()) {
5054 unsigned FinalOpcode = Mips::NOP;
5056 FinalOpcode = Mips::DROTR;
5057 else if (ImmValue % 32 == 0)
5058 FinalOpcode = Mips::DROTR32;
5059 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
5061 FinalOpcode = Mips::DROTR32;
5063 FinalOpcode = Mips::DROTR;
5064 }
else if (ImmValue >= 33) {
5066 FinalOpcode = Mips::DROTR;
5068 FinalOpcode = Mips::DROTR32;
5071 uint64_t ShiftValue = ImmValue % 32;
5073 ShiftValue = (32 - ImmValue % 32) % 32;
5075 TOut.
emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
5081 if (ImmValue == 0) {
5082 TOut.
emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.
getLoc(), STI);
5090 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5091 FirstShift = Mips::DSLL;
5092 SecondShift = Mips::DSRL32;
5094 if (ImmValue == 32) {
5095 FirstShift = Mips::DSLL32;
5096 SecondShift = Mips::DSRL32;
5098 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5099 FirstShift = Mips::DSLL32;
5100 SecondShift = Mips::DSRL;
5104 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5105 FirstShift = Mips::DSRL;
5106 SecondShift = Mips::DSLL32;
5108 if (ImmValue == 32) {
5109 FirstShift = Mips::DSRL32;
5110 SecondShift = Mips::DSLL32;
5112 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5113 FirstShift = Mips::DSRL32;
5114 SecondShift = Mips::DSLL;
5119 ATReg = getATReg(Inst.
getLoc());
5123 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.
getLoc(), STI);
5124 TOut.
emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
5126 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5134bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5135 const MCSubtargetInfo *STI) {
5136 MipsTargetStreamer &TOut = getTargetStreamer();
5140 TOut.
emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
5141 if (FirstRegOp != SecondRegOp)
5142 TOut.
emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
5145 TOut.
emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
5150bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5151 const MCSubtargetInfo *STI) {
5152 MipsTargetStreamer &TOut = getTargetStreamer();
5158 ATReg = getATReg(IDLoc);
5162 loadImmediate(ImmValue, ATReg, MCRegister(),
true,
false, IDLoc, Out, STI);
5164 TOut.
emitRR(Inst.
getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
5165 SrcReg, ATReg, IDLoc, STI);
5167 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5172bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5173 const MCSubtargetInfo *STI) {
5174 MipsTargetStreamer &TOut = getTargetStreamer();
5180 ATReg = getATReg(Inst.
getLoc());
5184 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
5185 SrcReg, TmpReg, IDLoc, STI);
5187 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5189 TOut.
emitRRI(Inst.
getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
5190 DstReg, DstReg, 0x1F, IDLoc, STI);
5192 TOut.
emitR(Mips::MFHI, ATReg, IDLoc, STI);
5195 TOut.
emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
5202 TOut.
emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
5203 if (AssemblerOptions.
back()->isReorder())
5205 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5209 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5214bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5215 const MCSubtargetInfo *STI) {
5216 MipsTargetStreamer &TOut = getTargetStreamer();
5222 ATReg = getATReg(IDLoc);
5226 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
5227 SrcReg, TmpReg, IDLoc, STI);
5229 TOut.
emitR(Mips::MFHI, ATReg, IDLoc, STI);
5230 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5232 TOut.
emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);
5239 TOut.
emitRRX(Mips::BEQ, ATReg, Mips::ZERO, LabelOp, IDLoc, STI);
5240 if (AssemblerOptions.
back()->isReorder())
5242 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5250bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5251 const MCSubtargetInfo *STI) {
5252 MipsTargetStreamer &TOut = getTargetStreamer();
5257 TOut.
emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
5258 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5268bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
5270 const MCSubtargetInfo *STI,
5275 warnIfNoMacro(IDLoc);
5277 MipsTargetStreamer &TOut = getTargetStreamer();
5278 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
5280 MCRegister SecondReg =
nextReg(FirstReg);
5285 warnIfRegIndexIsAT(FirstReg, IDLoc);
5288 "Offset for load macro is not immediate!");
5291 signed NextOffset = FirstOffset.
getImm() + 4;
5299 if (FirstReg != BaseReg || !IsLoad) {
5300 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5301 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5303 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5304 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5316bool MipsAsmParser::expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc,
5318 const MCSubtargetInfo *STI) {
5322 warnIfNoMacro(IDLoc);
5324 MipsTargetStreamer &TOut = getTargetStreamer();
5325 unsigned Opcode = Mips::SWC1;
5327 MCRegister SecondReg =
nextReg(FirstReg);
5332 warnIfRegIndexIsAT(FirstReg, IDLoc);
5335 "Offset for macro is not immediate!");
5338 signed NextOffset = FirstOffset.
getImm() + 4;
5344 if (!IsLittleEndian)
5347 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5348 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5353bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5354 const MCSubtargetInfo *STI) {
5355 MipsTargetStreamer &TOut = getTargetStreamer();
5366 warnIfNoMacro(IDLoc);
5368 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5369 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5370 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5374 MCRegister
Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5375 TOut.
emitRRI(Mips::SLTiu, DstReg,
Reg, 1, IDLoc, STI);
5379bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5380 const MCSubtargetInfo *STI) {
5381 MipsTargetStreamer &TOut = getTargetStreamer();
5392 warnIfNoMacro(IDLoc);
5395 TOut.
emitRRI(Mips::SLTiu, DstReg, SrcReg, 1, IDLoc, STI);
5399 if (SrcReg == Mips::ZERO) {
5400 Warning(IDLoc,
"comparison is always false");
5401 TOut.
emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
5402 DstReg, SrcReg, SrcReg, IDLoc, STI);
5407 if (Imm > -0x8000 && Imm < 0) {
5409 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5415 MCRegister ATReg = getATReg(IDLoc);
5419 if (loadImmediate(Imm, ATReg, MCRegister(),
true, isGP64bit(), IDLoc, Out,
5423 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5424 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5428 TOut.
emitRRI(
Opc, DstReg, SrcReg, Imm, IDLoc, STI);
5429 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5433bool MipsAsmParser::expandSne(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5434 const MCSubtargetInfo *STI) {
5436 MipsTargetStreamer &TOut = getTargetStreamer();
5447 warnIfNoMacro(IDLoc);
5449 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5450 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5451 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5455 MCRegister
Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5456 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO,
Reg, IDLoc, STI);
5460bool MipsAsmParser::expandSneI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5461 const MCSubtargetInfo *STI) {
5462 MipsTargetStreamer &TOut = getTargetStreamer();
5473 warnIfNoMacro(IDLoc);
5475 if (ImmValue == 0) {
5476 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, SrcReg, IDLoc, STI);
5480 if (SrcReg == Mips::ZERO) {
5481 Warning(IDLoc,
"comparison is always true");
5482 if (loadImmediate(1, DstReg, MCRegister(),
true,
false, IDLoc, Out, STI))
5488 if (ImmValue > -0x8000 && ImmValue < 0) {
5489 ImmValue = -ImmValue;
5490 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5496 TOut.
emitRRI(
Opc, DstReg, SrcReg, ImmValue, IDLoc, STI);
5497 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5501 MCRegister ATReg = getATReg(IDLoc);
5505 if (loadImmediate(ImmValue, ATReg, MCRegister(),
isInt<32>(ImmValue),
false,
5509 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5510 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5573 case Mips::F0:
return Mips::ZERO;
5574 case Mips::F1:
return Mips::AT;
5575 case Mips::F2:
return Mips::V0;
5576 case Mips::F3:
return Mips::V1;
5577 case Mips::F4:
return Mips::A0;
5578 case Mips::F5:
return Mips::A1;
5579 case Mips::F6:
return Mips::A2;
5580 case Mips::F7:
return Mips::A3;
5581 case Mips::F8:
return Mips::T0;
5582 case Mips::F9:
return Mips::T1;
5583 case Mips::F10:
return Mips::T2;
5584 case Mips::F11:
return Mips::T3;
5585 case Mips::F12:
return Mips::T4;
5586 case Mips::F13:
return Mips::T5;
5587 case Mips::F14:
return Mips::T6;
5588 case Mips::F15:
return Mips::T7;
5589 case Mips::F16:
return Mips::S0;
5590 case Mips::F17:
return Mips::S1;
5591 case Mips::F18:
return Mips::S2;
5592 case Mips::F19:
return Mips::S3;
5593 case Mips::F20:
return Mips::S4;
5594 case Mips::F21:
return Mips::S5;
5595 case Mips::F22:
return Mips::S6;
5596 case Mips::F23:
return Mips::S7;
5597 case Mips::F24:
return Mips::T8;
5598 case Mips::F25:
return Mips::T9;
5599 case Mips::F26:
return Mips::K0;
5600 case Mips::F27:
return Mips::K1;
5601 case Mips::F28:
return Mips::GP;
5602 case Mips::F29:
return Mips::SP;
5603 case Mips::F30:
return Mips::FP;
5604 case Mips::F31:
return Mips::RA;
5612 case Mips::COP00:
return Mips::ZERO;
5613 case Mips::COP01:
return Mips::AT;
5614 case Mips::COP02:
return Mips::V0;
5615 case Mips::COP03:
return Mips::V1;
5616 case Mips::COP04:
return Mips::A0;
5617 case Mips::COP05:
return Mips::A1;
5618 case Mips::COP06:
return Mips::A2;
5619 case Mips::COP07:
return Mips::A3;
5620 case Mips::COP08:
return Mips::T0;
5621 case Mips::COP09:
return Mips::T1;
5622 case Mips::COP010:
return Mips::T2;
5623 case Mips::COP011:
return Mips::T3;
5624 case Mips::COP012:
return Mips::T4;
5625 case Mips::COP013:
return Mips::T5;
5626 case Mips::COP014:
return Mips::T6;
5627 case Mips::COP015:
return Mips::T7;
5628 case Mips::COP016:
return Mips::S0;
5629 case Mips::COP017:
return Mips::S1;
5630 case Mips::COP018:
return Mips::S2;
5631 case Mips::COP019:
return Mips::S3;
5632 case Mips::COP020:
return Mips::S4;
5633 case Mips::COP021:
return Mips::S5;
5634 case Mips::COP022:
return Mips::S6;
5635 case Mips::COP023:
return Mips::S7;
5636 case Mips::COP024:
return Mips::T8;
5637 case Mips::COP025:
return Mips::T9;
5638 case Mips::COP026:
return Mips::K0;
5639 case Mips::COP027:
return Mips::K1;
5640 case Mips::COP028:
return Mips::GP;
5641 case Mips::COP029:
return Mips::SP;
5642 case Mips::COP030:
return Mips::FP;
5643 case Mips::COP031:
return Mips::RA;
5650bool MipsAsmParser::expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5651 const MCSubtargetInfo *STI) {
5652 MipsTargetStreamer &TOut = getTargetStreamer();
5657 bool IsMFTR =
false;
5711 IsMFTR ? MCRegister(rd)
5713 : Inst.getOperand(0).
getReg());
5715 TOut.
emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, u, sel, h, IDLoc,
5720bool MipsAsmParser::expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5721 const MCSubtargetInfo *STI) {
5726 warnIfNoMacro(IDLoc);
5728 MipsTargetStreamer &TOut = getTargetStreamer();
5729 unsigned Opcode = Inst.
getOpcode() == Mips::SaaAddr ? Mips::SAA : Mips::SAAD;
5732 const MCOperand &BaseOp = Inst.
getOperand(2);
5734 if (BaseOp.
isImm()) {
5735 int64_t ImmValue = BaseOp.
getImm();
5736 if (ImmValue == 0) {
5737 TOut.
emitRR(Opcode, RtReg, BaseReg, IDLoc, STI);
5742 MCRegister ATReg = getATReg(IDLoc);
5746 if (expandLoadAddress(ATReg, BaseReg, BaseOp, !isGP64bit(), IDLoc, Out, STI))
5749 TOut.
emitRR(Opcode, RtReg, ATReg, IDLoc, STI);
5754MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
5758 return Match_Success;
5761 if (
static_cast<MipsOperand &
>(*
Operands[1])
5762 .isValidForTie(
static_cast<MipsOperand &
>(*
Operands[2])))
5763 return Match_Success;
5764 return Match_RequiresSameSrcAndDst;
5768unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
5775 return Match_RequiresNoZeroRegister;
5776 return Match_Success;
5782 case Mips::JALR_HB64:
5783 case Mips::JALRC_HB_MMR6:
5784 case Mips::JALRC_MMR6:
5786 return Match_RequiresDifferentSrcAndDst;
5787 return Match_Success;
5790 return Match_RequiresDifferentSrcAndDst;
5791 return Match_Success;
5794 return Match_NonZeroOperandForSync;
5795 return Match_Success;
5801 return Match_NonZeroOperandForMTCX;
5802 return Match_Success;
5815 case Mips::BLEZC:
case Mips::BLEZC_MMR6:
5816 case Mips::BGEZC:
case Mips::BGEZC_MMR6:
5817 case Mips::BGTZC:
case Mips::BGTZC_MMR6:
5818 case Mips::BLTZC:
case Mips::BLTZC_MMR6:
5819 case Mips::BEQZC:
case Mips::BEQZC_MMR6:
5820 case Mips::BNEZC:
case Mips::BNEZC_MMR6:
5829 return Match_RequiresNoZeroRegister;
5830 return Match_Success;
5831 case Mips::BGEC:
case Mips::BGEC_MMR6:
5832 case Mips::BLTC:
case Mips::BLTC_MMR6:
5833 case Mips::BGEUC:
case Mips::BGEUC_MMR6:
5834 case Mips::BLTUC:
case Mips::BLTUC_MMR6:
5835 case Mips::BEQC:
case Mips::BEQC_MMR6:
5836 case Mips::BNEC:
case Mips::BNEC_MMR6:
5845 return Match_RequiresNoZeroRegister;
5848 return Match_RequiresNoZeroRegister;
5850 return Match_RequiresDifferentOperands;
5851 return Match_Success;
5854 "Operands must be immediates for dins!");
5857 if ((0 > (Pos +
Size)) || ((Pos +
Size) > 32))
5858 return Match_RequiresPosSizeRange0_32;
5859 return Match_Success;
5864 "Operands must be immediates for dinsm/dinsu!");
5867 if ((32 >= (Pos +
Size)) || ((Pos +
Size) > 64))
5868 return Match_RequiresPosSizeRange33_64;
5869 return Match_Success;
5873 "Operands must be immediates for DEXTM!");
5876 if ((1 > (Pos +
Size)) || ((Pos +
Size) > 63))
5877 return Match_RequiresPosSizeUImm6;
5878 return Match_Success;
5883 "Operands must be immediates for dextm/dextu!");
5886 if ((32 > (Pos +
Size)) || ((Pos +
Size) > 64))
5887 return Match_RequiresPosSizeRange33_64;
5888 return Match_Success;
5890 case Mips::CRC32B:
case Mips::CRC32CB:
5891 case Mips::CRC32H:
case Mips::CRC32CH:
5892 case Mips::CRC32W:
case Mips::CRC32CW:
5893 case Mips::CRC32D:
case Mips::CRC32CD:
5895 return Match_RequiresSameSrcAndDst;
5896 return Match_Success;
5899 uint64_t TSFlags = MII.get(Inst.
getOpcode()).TSFlags;
5902 return Match_NoFCCRegisterForCurrentISA;
5904 return Match_Success;
5912 if (ErrorLoc ==
SMLoc())
5919bool MipsAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
5922 uint64_t &ErrorInfo,
5923 bool MatchingInlineAsm) {
5925 unsigned MatchResult =
5926 MatchInstructionImpl(
Operands, Inst, ErrorInfo, MatchingInlineAsm);
5928 switch (MatchResult) {
5930 if (processInstruction(Inst, IDLoc, Out, STI))
5933 case Match_MissingFeature:
5934 Error(IDLoc,
"instruction requires a CPU feature not currently enabled");
5936 case Match_InvalidTiedOperand:
5937 Error(IDLoc,
"operand must match destination register");
5939 case Match_InvalidOperand: {
5940 SMLoc ErrorLoc = IDLoc;
5941 if (ErrorInfo != ~0ULL) {
5943 return Error(IDLoc,
"too few operands for instruction");
5945 ErrorLoc =
Operands[ErrorInfo]->getStartLoc();
5946 if (ErrorLoc == SMLoc())
5950 return Error(ErrorLoc,
"invalid operand for instruction");
5952 case Match_NonZeroOperandForSync:
5954 "s-type must be zero or unspecified for pre-MIPS32 ISAs");
5955 case Match_NonZeroOperandForMTCX:
5956 return Error(IDLoc,
"selector must be zero for pre-MIPS32 ISAs");
5957 case Match_MnemonicFail:
5958 return Error(IDLoc,
"invalid instruction");
5959 case Match_RequiresDifferentSrcAndDst:
5960 return Error(IDLoc,
"source and destination must be different");
5961 case Match_RequiresDifferentOperands:
5962 return Error(IDLoc,
"registers must be different");
5963 case Match_RequiresNoZeroRegister:
5964 return Error(IDLoc,
"invalid operand ($zero) for instruction");
5965 case Match_RequiresSameSrcAndDst:
5966 return Error(IDLoc,
"source and destination must match");
5967 case Match_NoFCCRegisterForCurrentISA:
5969 "non-zero fcc register doesn't exist in current ISA level");
5974 "expected 1-bit unsigned immediate");
5977 "expected 2-bit unsigned immediate");
5980 "expected immediate in range 1 .. 4");
5983 "expected 3-bit unsigned immediate");
5986 "expected 4-bit unsigned immediate");
5989 "expected 4-bit signed immediate");
5992 "expected 5-bit unsigned immediate");
5995 "expected 5-bit signed immediate");
5998 "expected immediate in range 1 .. 32");
5999 case Match_UImm5_32:
6001 "expected immediate in range 32 .. 63");
6002 case Match_UImm5_33:
6004 "expected immediate in range 33 .. 64");
6005 case Match_UImm5_0_Report_UImm6:
6009 "expected 6-bit unsigned immediate");
6010 case Match_UImm5_Lsl2:
6012 "expected both 7-bit unsigned immediate and multiple of 4");
6013 case Match_UImmRange2_64:
6015 "expected immediate in range 2 .. 64");
6018 "expected 6-bit unsigned immediate");
6019 case Match_UImm6_Lsl2:
6021 "expected both 8-bit unsigned immediate and multiple of 4");
6024 "expected 6-bit signed immediate");
6027 "expected 7-bit unsigned immediate");
6028 case Match_UImm7_N1:
6030 "expected immediate in range -1 .. 126");
6031 case Match_SImm7_Lsl2:
6033 "expected both 9-bit signed immediate and multiple of 4");
6036 "expected 8-bit unsigned immediate");
6037 case Match_UImm10_0:
6039 "expected 10-bit unsigned immediate");
6040 case Match_SImm10_0:
6042 "expected 10-bit signed immediate");
6043 case Match_SImm11_0:
6045 "expected 11-bit signed immediate");
6047 case Match_UImm16_Relaxed:
6048 case Match_UImm16_AltRelaxed:
6050 "expected 16-bit unsigned immediate");
6052 case Match_SImm16_Relaxed:
6054 "expected 16-bit signed immediate");
6055 case Match_SImm18_Lsl3:
6057 "expected both 18-bit signed immediate and multiple of 8");
6058 case Match_SImm19_Lsl2:
6060 "expected both 19-bit signed immediate and multiple of 4");
6061 case Match_UImm20_0:
6063 "expected 20-bit unsigned immediate");
6064 case Match_UImm26_0:
6066 "expected 26-bit unsigned immediate");
6068 case Match_SImm32_Relaxed:
6070 "expected 32-bit signed immediate");
6071 case Match_UImm32_Coerced:
6073 "expected 32-bit immediate");
6074 case Match_MemSImm9:
6076 "expected memory with 9-bit signed offset");
6077 case Match_MemSImm10:
6079 "expected memory with 10-bit signed offset");
6080 case Match_MemSImm10Lsl1:
6082 "expected memory with 11-bit signed offset and multiple of 2");
6083 case Match_MemSImm10Lsl2:
6085 "expected memory with 12-bit signed offset and multiple of 4");
6086 case Match_MemSImm10Lsl3:
6088 "expected memory with 13-bit signed offset and multiple of 8");
6089 case Match_MemSImm11:
6091 "expected memory with 11-bit signed offset");
6092 case Match_MemSImm12:
6094 "expected memory with 12-bit signed offset");
6095 case Match_MemSImm16:
6097 "expected memory with 16-bit signed offset");
6098 case Match_MemSImmPtr:
6100 "expected memory with 32-bit signed offset");
6101 case Match_RequiresPosSizeRange0_32: {
6102 SMLoc ErrorStart =
Operands[3]->getStartLoc();
6103 SMLoc ErrorEnd =
Operands[4]->getEndLoc();
6104 return Error(ErrorStart,
"size plus position are not in the range 0 .. 32",
6105 SMRange(ErrorStart, ErrorEnd));
6107 case Match_RequiresPosSizeUImm6: {
6108 SMLoc ErrorStart =
Operands[3]->getStartLoc();
6109 SMLoc ErrorEnd =
Operands[4]->getEndLoc();
6110 return Error(ErrorStart,
"size plus position are not in the range 1 .. 63",
6111 SMRange(ErrorStart, ErrorEnd));
6113 case Match_RequiresPosSizeRange33_64: {
6114 SMLoc ErrorStart =
Operands[3]->getStartLoc();
6115 SMLoc ErrorEnd =
Operands[4]->getEndLoc();
6116 return Error(ErrorStart,
"size plus position are not in the range 33 .. 64",
6117 SMRange(ErrorStart, ErrorEnd));
6124void MipsAsmParser::warnIfRegIndexIsAT(MCRegister RegIndex, SMLoc Loc) {
6125 if (RegIndex && AssemblerOptions.
back()->getATRegIndex() == RegIndex)
6126 Warning(Loc,
"used $at (currently $" + Twine(RegIndex.
id()) +
6127 ") without \".set noat\"");
6130void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
6131 if (!AssemblerOptions.
back()->isMacro())
6132 Warning(Loc,
"macro instruction expanded into multiple instructions");
6135void MipsAsmParser::ConvertXWPOperands(MCInst &Inst,
6139 "Unexpected instruction!");
6140 ((MipsOperand &)*
Operands[1]).addGPR32ZeroAsmRegOperands(Inst, 1);
6141 MCRegister NextReg =
nextReg(((MipsOperand &)*
Operands[1]).getGPR32Reg());
6143 ((MipsOperand &)*
Operands[2]).addMemOperands(Inst, 2);
6147MipsAsmParser::printWarningWithFixIt(
const Twine &
Msg,
const Twine &FixMsg,
6148 SMRange
Range,
bool ShowColors) {
6154int MipsAsmParser::matchCPURegisterName(StringRef Name) {
6157 CC = StringSwitch<unsigned>(Name)
6159 .Cases({
"at",
"AT"}, 1)
6193 if (!(isABI_N32() || isABI_N64()))
6196 if (12 <= CC && CC <= 15) {
6198 AsmToken RegTok = getLexer().peekTok();
6201 StringRef FixedName = StringSwitch<StringRef>(Name)
6207 assert(FixedName !=
"" &&
"Register name is not one of t4-t7.");
6209 printWarningWithFixIt(
"register names $t4-$t7 are only available in O32.",
6210 "Did you mean $" + FixedName +
"?", RegRange);
6216 if (8 <= CC && CC <= 11)
6220 CC = StringSwitch<unsigned>(Name)
6232int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
6235 CC = StringSwitch<unsigned>(Name)
6236 .Case(
"hwr_cpunum", 0)
6237 .Case(
"hwr_synci_step", 1)
6239 .Case(
"hwr_ccres", 3)
6240 .Case(
"hwr_ulr", 29)
6246int MipsAsmParser::matchFPURegisterName(StringRef Name) {
6247 if (Name[0] ==
'f') {
6248 StringRef NumString =
Name.substr(1);
6259int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
6260 if (
Name.starts_with(
"fcc")) {
6261 StringRef NumString =
Name.substr(3);
6272int MipsAsmParser::matchACRegisterName(StringRef Name) {
6273 if (
Name.starts_with(
"ac")) {
6274 StringRef NumString =
Name.substr(2);
6285int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
6288 if (
Name.front() !=
'w' ||
Name.drop_front(1).getAsInteger(10, IntVal))
6297int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
6300 CC = StringSwitch<unsigned>(Name)
6303 .Case(
"msaaccess", 2)
6305 .Case(
"msamodify", 4)
6306 .Case(
"msarequest", 5)
6308 .Case(
"msaunmap", 7)
6314bool MipsAsmParser::canUseATReg() {
6315 return AssemblerOptions.
back()->getATRegIndex() != 0;
6318MCRegister MipsAsmParser::getATReg(SMLoc Loc) {
6319 unsigned ATIndex = AssemblerOptions.
back()->getATRegIndex();
6321 reportParseError(Loc,
6322 "pseudo-instruction requires $at, which is not available");
6326 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
6330MCRegister MipsAsmParser::getReg(
int RC,
int RegNo) {
6331 return getContext().getRegisterInfo()->getRegClass(RC).getRegister(RegNo);
6337const MCExpr *MipsAsmParser::parseRelocExpr() {
6338 auto getOp = [](StringRef
Op) {
6339 return StringSwitch<Mips::Specifier>(
Op)
6367 MCAsmParser &Parser = getParser();
6369 const MCExpr *Res =
nullptr;
6375 auto Op = getOp(Name);
6384 while (
Ops.size()) {
6393 MCAsmParser &Parser = getParser();
6403 ParseStatus Res = MatchOperandParserImpl(
Operands, Mnemonic,
true);
6414 switch (getLexer().getKind()) {
6424 if (!parseAnyRegister(
Operands).isNoMatch())
6437 Operands.push_back(MipsOperand::CreateImm(SymRef, S,
E, *
this));
6442 const MCExpr *Expr = parseRelocExpr();
6446 Operands.push_back(MipsOperand::CreateImm(Expr, S,
E, *
this));
6453bool MipsAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
6455 return !tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess();
6458ParseStatus MipsAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
6461 ParseStatus Res = parseAnyRegister(
Operands);
6464 MipsOperand &Operand =
static_cast<MipsOperand &
>(*
Operands.front());
6465 StartLoc = Operand.getStartLoc();
6466 EndLoc = Operand.getEndLoc();
6472 if (Operand.isGPRAsmReg()) {
6474 Reg = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
6485 MCAsmParser &Parser = getParser();
6487 const MCExpr *IdVal =
nullptr;
6489 bool isParenExpr =
false;
6500 IdVal = parseRelocExpr();
6506 const AsmToken &Tok = Parser.
getTok();
6508 MipsOperand &Mnemonic =
static_cast<MipsOperand &
>(*
Operands[0]);
6509 if (Mnemonic.getToken() ==
"la" || Mnemonic.getToken() ==
"dla") {
6512 Operands.push_back(MipsOperand::CreateImm(IdVal, S,
E, *
this));
6521 auto Base = MipsOperand::createGPRReg(
6522 0,
"0",
getContext().getRegisterInfo(), S,
E, *
this);
6524 MipsOperand::CreateMem(std::move(
Base), IdVal, S,
E, *
this));
6576 const MCExpr * NextExpr;
6577 if (getParser().parseExpression(NextExpr))
6600 std::unique_ptr<MipsOperand>
op(
6601 static_cast<MipsOperand *
>(
Operands.back().release()));
6608 if (IdVal->evaluateAsAbsolute(Imm))
6615 Operands.push_back(MipsOperand::CreateMem(std::move(
op), IdVal, S,
E, *
this));
6620 MCAsmParser &Parser = getParser();
6629 const MCSymbolRefExpr *
Ref =
static_cast<const MCSymbolRefExpr *
>(Expr);
6630 StringRef DefSymbol =
Ref->getSymbol().getName();
6633 matchAnyRegisterNameWithoutDollar(
Operands, DefSymbol.
substr(1), S);
6647 if (Entry != RegisterSets.
end()) {
6649 matchAnyRegisterWithoutDollar(
Operands,
Entry->getValue(), S);
6660ParseStatus MipsAsmParser::matchAnyRegisterNameWithoutDollar(
6662 int Index = matchCPURegisterName(Identifier);
6664 Operands.push_back(MipsOperand::createGPRReg(
6665 Index, Identifier,
getContext().getRegisterInfo(), S,
6666 getLexer().getLoc(), *
this));
6670 Index = matchHWRegsRegisterName(Identifier);
6672 Operands.push_back(MipsOperand::createHWRegsReg(
6673 Index, Identifier,
getContext().getRegisterInfo(), S,
6674 getLexer().getLoc(), *
this));
6678 Index = matchFPURegisterName(Identifier);
6680 Operands.push_back(MipsOperand::createFGRReg(
6681 Index, Identifier,
getContext().getRegisterInfo(), S,
6682 getLexer().getLoc(), *
this));
6686 Index = matchFCCRegisterName(Identifier);
6688 Operands.push_back(MipsOperand::createFCCReg(
6689 Index, Identifier,
getContext().getRegisterInfo(), S,
6690 getLexer().getLoc(), *
this));
6694 Index = matchACRegisterName(Identifier);
6696 Operands.push_back(MipsOperand::createACCReg(
6697 Index, Identifier,
getContext().getRegisterInfo(), S,
6698 getLexer().getLoc(), *
this));
6702 Index = matchMSA128RegisterName(Identifier);
6704 Operands.push_back(MipsOperand::createMSA128Reg(
6705 Index, Identifier,
getContext().getRegisterInfo(), S,
6706 getLexer().getLoc(), *
this));
6710 Index = matchMSA128CtrlRegisterName(Identifier);
6712 Operands.push_back(MipsOperand::createMSACtrlReg(
6713 Index, Identifier,
getContext().getRegisterInfo(), S,
6714 getLexer().getLoc(), *
this));
6723 const AsmToken &Token, SMLoc S) {
6727 return matchAnyRegisterNameWithoutDollar(
Operands, Identifier, S);
6732 if (RegNum < 0 || RegNum > 31) {
6736 Error(getLexer().getLoc(),
"invalid register number");
6738 Operands.push_back(MipsOperand::createNumericReg(
6751 auto Token = getLexer().peekTok(
false);
6752 return matchAnyRegisterWithoutDollar(
Operands, Token, S);
6756 MCAsmParser &Parser = getParser();
6759 auto Token = Parser.
getTok();
6761 SMLoc S = Token.
getLoc();
6774 ParseStatus Res = matchAnyRegisterWithoutDollar(
Operands, S);
6783 MCAsmParser &Parser = getParser();
6786 SMLoc S = getLexer().getLoc();
6789 ParseStatus Res = parseAnyRegister(
Operands);
6794 const MCExpr *Expr =
nullptr;
6800 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *
this));
6805 MCAsmParser &Parser = getParser();
6806 const MCExpr *IdVal;
6817 if (getParser().parseExpression(IdVal))
6824 Operands.push_back(MipsOperand::CreateImm(
6830 MCAsmParser &Parser = getParser();
6834 bool RegRange =
false;
6841 while (parseAnyRegister(TmpOperands).isSuccess()) {
6842 SMLoc
E = getLexer().getLoc();
6843 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*TmpOperands.
back());
6844 Reg = isGP64bit() ? RegOpnd.getGPR64Reg() : RegOpnd.getGPR32Reg();
6848 if ((isGP64bit() &&
Reg == Mips::RA_64) ||
6849 (!isGP64bit() &&
Reg == Mips::RA)) {
6852 MCRegister TmpReg = PrevReg + 1;
6853 while (TmpReg <=
Reg) {
6854 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
6855 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
6857 return Error(
E,
"invalid register operand");
6861 TmpReg = TmpReg.
id() + 1;
6868 ((isGP64bit() && (
Reg != Mips::S0_64) && (
Reg != Mips::RA_64)) ||
6869 (!isGP64bit() && (
Reg != Mips::S0) && (
Reg != Mips::RA))))
6870 return Error(
E,
"$16 or $31 expected");
6871 if (!(((
Reg == Mips::FP ||
Reg == Mips::RA ||
6872 (
Reg >= Mips::S0 &&
Reg <= Mips::S7)) &&
6874 ((
Reg == Mips::FP_64 ||
Reg == Mips::RA_64 ||
6875 (
Reg >= Mips::S0_64 &&
Reg <= Mips::S7_64)) &&
6877 return Error(
E,
"invalid register operand");
6878 if (PrevReg.
isValid() && (
Reg != PrevReg + 1) &&
6879 ((
Reg != Mips::FP &&
Reg != Mips::RA && !isGP64bit()) ||
6880 (
Reg != Mips::FP_64 &&
Reg != Mips::RA_64 && isGP64bit())))
6881 return Error(
E,
"consecutive register numbers expected");
6891 return Error(
E,
"',' or '-' expected");
6901 Operands.push_back(MipsOperand::CreateRegList(Regs, S,
E, *
this));
6912 MCAsmParser &Parser = getParser();
6915 MipsOperand::CreateToken(
"(", getLexer().getLoc(), *
this));
6917 if (parseOperand(
Operands, Name)) {
6918 SMLoc Loc = getLexer().getLoc();
6919 return Error(Loc,
"unexpected token in argument list");
6922 SMLoc Loc = getLexer().getLoc();
6923 return Error(Loc,
"unexpected token, expected ')'");
6926 MipsOperand::CreateToken(
")", getLexer().getLoc(), *
this));
6938bool MipsAsmParser::parseBracketSuffix(StringRef Name,
6940 MCAsmParser &Parser = getParser();
6943 MipsOperand::CreateToken(
"[", getLexer().getLoc(), *
this));
6945 if (parseOperand(
Operands, Name)) {
6946 SMLoc Loc = getLexer().getLoc();
6947 return Error(Loc,
"unexpected token in argument list");
6950 SMLoc Loc = getLexer().getLoc();
6951 return Error(Loc,
"unexpected token, expected ']'");
6954 MipsOperand::CreateToken(
"]", getLexer().getLoc(), *
this));
6961 unsigned VariantID = 0);
6976bool MipsAsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
6978 MCAsmParser &Parser = getParser();
6982 getTargetStreamer().forbidModuleDirective();
6985 if (!mnemonicIsValid(Name, 0)) {
6986 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
6988 return Error(NameLoc,
"unknown instruction" + Suggestion);
6991 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *
this));
6996 if (parseOperand(
Operands, Name)) {
6997 SMLoc Loc = getLexer().getLoc();
6998 return Error(Loc,
"unexpected token in argument list");
7007 if (parseOperand(
Operands, Name)) {
7008 SMLoc Loc = getLexer().getLoc();
7009 return Error(Loc,
"unexpected token in argument list");
7013 if (parseBracketSuffix(Name,
Operands))
7021 SMLoc Loc = getLexer().getLoc();
7022 return Error(Loc,
"unexpected token in argument list");
7030bool MipsAsmParser::reportParseError(
const Twine &ErrorMsg) {
7031 SMLoc Loc = getLexer().getLoc();
7032 return Error(Loc, ErrorMsg);
7035bool MipsAsmParser::reportParseError(SMLoc Loc,
const Twine &ErrorMsg) {
7036 return Error(Loc, ErrorMsg);
7039bool MipsAsmParser::parseSetNoAtDirective() {
7040 MCAsmParser &Parser = getParser();
7044 AssemblerOptions.
back()->setATRegIndex(0);
7050 reportParseError(
"unexpected token, expected end of statement");
7054 getTargetStreamer().emitDirectiveSetNoAt();
7059bool MipsAsmParser::parseSetAtDirective() {
7062 MCAsmParser &Parser = getParser();
7067 AssemblerOptions.
back()->setATRegIndex(1);
7069 getTargetStreamer().emitDirectiveSetAt();
7075 reportParseError(
"unexpected token, expected equals sign");
7082 reportParseError(
"no register specified");
7085 reportParseError(
"unexpected token, expected dollar sign '$'");
7095 AtRegNo = matchCPURegisterName(
Reg.getIdentifier());
7097 AtRegNo =
Reg.getIntVal();
7099 reportParseError(
"unexpected token, expected identifier or integer");
7104 if (!AssemblerOptions.
back()->setATRegIndex(AtRegNo)) {
7105 reportParseError(
"invalid register");
7112 reportParseError(
"unexpected token, expected end of statement");
7116 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
7122bool MipsAsmParser::parseSetReorderDirective() {
7123 MCAsmParser &Parser = getParser();
7127 reportParseError(
"unexpected token, expected end of statement");
7130 AssemblerOptions.
back()->setReorder();
7131 getTargetStreamer().emitDirectiveSetReorder();
7136bool MipsAsmParser::parseSetNoReorderDirective() {
7137 MCAsmParser &Parser = getParser();
7141 reportParseError(
"unexpected token, expected end of statement");
7144 AssemblerOptions.
back()->setNoReorder();
7145 getTargetStreamer().emitDirectiveSetNoReorder();
7150bool MipsAsmParser::parseSetMacroDirective() {
7151 MCAsmParser &Parser = getParser();
7155 reportParseError(
"unexpected token, expected end of statement");
7158 AssemblerOptions.
back()->setMacro();
7159 getTargetStreamer().emitDirectiveSetMacro();
7164bool MipsAsmParser::parseSetNoMacroDirective() {
7165 MCAsmParser &Parser = getParser();
7169 reportParseError(
"unexpected token, expected end of statement");
7172 if (AssemblerOptions.
back()->isReorder()) {
7173 reportParseError(
"`noreorder' must be set before `nomacro'");
7176 AssemblerOptions.
back()->setNoMacro();
7177 getTargetStreamer().emitDirectiveSetNoMacro();
7182bool MipsAsmParser::parseSetMsaDirective() {
7183 MCAsmParser &Parser = getParser();
7188 return reportParseError(
"unexpected token, expected end of statement");
7190 setFeatureBits(Mips::FeatureMSA,
"msa");
7191 getTargetStreamer().emitDirectiveSetMsa();
7195bool MipsAsmParser::parseSetNoMsaDirective() {
7196 MCAsmParser &Parser = getParser();
7201 return reportParseError(
"unexpected token, expected end of statement");
7203 clearFeatureBits(Mips::FeatureMSA,
"msa");
7204 getTargetStreamer().emitDirectiveSetNoMsa();
7208bool MipsAsmParser::parseSetNoDspDirective() {
7209 MCAsmParser &Parser = getParser();
7214 reportParseError(
"unexpected token, expected end of statement");
7218 clearFeatureBits(Mips::FeatureDSP,
"dsp");
7219 getTargetStreamer().emitDirectiveSetNoDsp();
7223bool MipsAsmParser::parseSetNoMips3DDirective() {
7224 MCAsmParser &Parser = getParser();
7229 reportParseError(
"unexpected token, expected end of statement");
7233 clearFeatureBits(Mips::FeatureMips3D,
"mips3d");
7234 getTargetStreamer().emitDirectiveSetNoMips3D();
7238bool MipsAsmParser::parseSetMips16Directive() {
7239 MCAsmParser &Parser = getParser();
7244 reportParseError(
"unexpected token, expected end of statement");
7248 setFeatureBits(Mips::FeatureMips16,
"mips16");
7249 getTargetStreamer().emitDirectiveSetMips16();
7254bool MipsAsmParser::parseSetNoMips16Directive() {
7255 MCAsmParser &Parser = getParser();
7260 reportParseError(
"unexpected token, expected end of statement");
7264 clearFeatureBits(Mips::FeatureMips16,
"mips16");
7265 getTargetStreamer().emitDirectiveSetNoMips16();
7270bool MipsAsmParser::parseSetFpDirective() {
7271 MCAsmParser &Parser = getParser();
7277 AsmToken Tok = Parser.
getTok();
7279 reportParseError(
"unexpected token, expected equals sign '='");
7285 if (!parseFpABIValue(FpAbiVal,
".set"))
7289 reportParseError(
"unexpected token, expected end of statement");
7292 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
7297bool MipsAsmParser::parseSetOddSPRegDirective() {
7298 MCAsmParser &Parser = getParser();
7302 reportParseError(
"unexpected token, expected end of statement");
7306 clearFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
7307 getTargetStreamer().emitDirectiveSetOddSPReg();
7311bool MipsAsmParser::parseSetNoOddSPRegDirective() {
7312 MCAsmParser &Parser = getParser();
7316 reportParseError(
"unexpected token, expected end of statement");
7320 setFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
7321 getTargetStreamer().emitDirectiveSetNoOddSPReg();
7325bool MipsAsmParser::parseSetMtDirective() {
7326 MCAsmParser &Parser = getParser();
7331 reportParseError(
"unexpected token, expected end of statement");
7335 setFeatureBits(Mips::FeatureMT,
"mt");
7336 getTargetStreamer().emitDirectiveSetMt();
7341bool MipsAsmParser::parseSetNoMtDirective() {
7342 MCAsmParser &Parser = getParser();
7347 reportParseError(
"unexpected token, expected end of statement");
7351 clearFeatureBits(Mips::FeatureMT,
"mt");
7353 getTargetStreamer().emitDirectiveSetNoMt();
7358bool MipsAsmParser::parseSetNoCRCDirective() {
7359 MCAsmParser &Parser = getParser();
7364 reportParseError(
"unexpected token, expected end of statement");
7368 clearFeatureBits(Mips::FeatureCRC,
"crc");
7370 getTargetStreamer().emitDirectiveSetNoCRC();
7375bool MipsAsmParser::parseSetNoVirtDirective() {
7376 MCAsmParser &Parser = getParser();
7381 reportParseError(
"unexpected token, expected end of statement");
7385 clearFeatureBits(Mips::FeatureVirt,
"virt");
7387 getTargetStreamer().emitDirectiveSetNoVirt();
7392bool MipsAsmParser::parseSetNoGINVDirective() {
7393 MCAsmParser &Parser = getParser();
7398 reportParseError(
"unexpected token, expected end of statement");
7402 clearFeatureBits(Mips::FeatureGINV,
"ginv");
7404 getTargetStreamer().emitDirectiveSetNoGINV();
7409bool MipsAsmParser::parseSetPopDirective() {
7410 MCAsmParser &Parser = getParser();
7411 SMLoc Loc = getLexer().getLoc();
7415 return reportParseError(
"unexpected token, expected end of statement");
7419 if (AssemblerOptions.
size() == 2)
7420 return reportParseError(Loc,
".set pop with no .set push");
7422 MCSubtargetInfo &STI = copySTI();
7424 setAvailableFeatures(
7425 ComputeAvailableFeatures(AssemblerOptions.
back()->getFeatures()));
7428 getTargetStreamer().emitDirectiveSetPop();
7432bool MipsAsmParser::parseSetPushDirective() {
7433 MCAsmParser &Parser = getParser();
7436 return reportParseError(
"unexpected token, expected end of statement");
7440 std::make_unique<MipsAssemblerOptions>(AssemblerOptions.
back().get()));
7442 getTargetStreamer().emitDirectiveSetPush();
7446bool MipsAsmParser::parseSetSoftFloatDirective() {
7447 MCAsmParser &Parser = getParser();
7450 return reportParseError(
"unexpected token, expected end of statement");
7452 setFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
7453 getTargetStreamer().emitDirectiveSetSoftFloat();
7457bool MipsAsmParser::parseSetHardFloatDirective() {
7458 MCAsmParser &Parser = getParser();
7461 return reportParseError(
"unexpected token, expected end of statement");
7463 clearFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
7464 getTargetStreamer().emitDirectiveSetHardFloat();
7468bool MipsAsmParser::parseSetAssignment() {
7470 MCAsmParser &Parser = getParser();
7473 return reportParseError(
"expected identifier after .set");
7476 return reportParseError(
"unexpected token, expected comma");
7491 const MCExpr *
Value;
7493 Parser, Sym,
Value))
7495 getStreamer().emitAssignment(Sym,
Value);
7500bool MipsAsmParser::parseSetMips0Directive() {
7501 MCAsmParser &Parser = getParser();
7504 return reportParseError(
"unexpected token, expected end of statement");
7507 MCSubtargetInfo &STI = copySTI();
7508 setAvailableFeatures(
7509 ComputeAvailableFeatures(AssemblerOptions.
front()->getFeatures()));
7511 AssemblerOptions.
back()->setFeatures(AssemblerOptions.
front()->getFeatures());
7513 getTargetStreamer().emitDirectiveSetMips0();
7517bool MipsAsmParser::parseSetArchDirective() {
7518 MCAsmParser &Parser = getParser();
7521 return reportParseError(
"unexpected token, expected equals sign");
7524 StringRef Arch = getParser().parseStringToEndOfStatement().trim();
7526 return reportParseError(
"expected arch identifier");
7528 StringRef ArchFeatureName =
7529 StringSwitch<StringRef>(Arch)
7530 .Case(
"mips1",
"mips1")
7531 .Case(
"mips2",
"mips2")
7532 .Case(
"mips3",
"mips3")
7533 .Case(
"mips4",
"mips4")
7534 .Case(
"mips5",
"mips5")
7535 .Case(
"mips32",
"mips32")
7536 .Case(
"mips32r2",
"mips32r2")
7537 .Case(
"mips32r3",
"mips32r3")
7538 .Case(
"mips32r5",
"mips32r5")
7539 .Case(
"mips32r6",
"mips32r6")
7540 .Case(
"mips64",
"mips64")
7541 .Case(
"mips64r2",
"mips64r2")
7542 .Case(
"mips64r3",
"mips64r3")
7543 .Case(
"mips64r5",
"mips64r5")
7544 .Case(
"mips64r6",
"mips64r6")
7545 .Case(
"octeon",
"cnmips")
7546 .Case(
"octeon+",
"cnmipsp")
7547 .Case(
"r4000",
"mips3")
7550 if (ArchFeatureName.
empty())
7551 return reportParseError(
"unsupported architecture");
7553 if (ArchFeatureName ==
"mips64r6" && inMicroMipsMode())
7554 return reportParseError(
"mips64r6 does not support microMIPS");
7556 selectArch(ArchFeatureName);
7557 getTargetStreamer().emitDirectiveSetArch(Arch);
7561bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
7562 MCAsmParser &Parser = getParser();
7565 return reportParseError(
"unexpected token, expected end of statement");
7570 case Mips::FeatureMips3D:
7571 setFeatureBits(Mips::FeatureMips3D,
"mips3d");
7572 getTargetStreamer().emitDirectiveSetMips3D();
7574 case Mips::FeatureDSP:
7575 setFeatureBits(Mips::FeatureDSP,
"dsp");
7576 getTargetStreamer().emitDirectiveSetDsp();
7578 case Mips::FeatureDSPR2:
7579 setFeatureBits(Mips::FeatureDSPR2,
"dspr2");
7580 getTargetStreamer().emitDirectiveSetDspr2();
7582 case Mips::FeatureMicroMips:
7583 setFeatureBits(Mips::FeatureMicroMips,
"micromips");
7584 getTargetStreamer().emitDirectiveSetMicroMips();
7586 case Mips::FeatureMips1:
7587 selectArch(
"mips1");
7588 getTargetStreamer().emitDirectiveSetMips1();
7590 case Mips::FeatureMips2:
7591 selectArch(
"mips2");
7592 getTargetStreamer().emitDirectiveSetMips2();
7594 case Mips::FeatureMips3:
7595 selectArch(
"mips3");
7596 getTargetStreamer().emitDirectiveSetMips3();
7598 case Mips::FeatureMips4:
7599 selectArch(
"mips4");
7600 getTargetStreamer().emitDirectiveSetMips4();
7602 case Mips::FeatureMips5:
7603 selectArch(
"mips5");
7604 getTargetStreamer().emitDirectiveSetMips5();
7606 case Mips::FeatureMips32:
7607 selectArch(
"mips32");
7608 getTargetStreamer().emitDirectiveSetMips32();
7610 case Mips::FeatureMips32r2:
7611 selectArch(
"mips32r2");
7612 getTargetStreamer().emitDirectiveSetMips32R2();
7614 case Mips::FeatureMips32r3:
7615 selectArch(
"mips32r3");
7616 getTargetStreamer().emitDirectiveSetMips32R3();
7618 case Mips::FeatureMips32r5:
7619 selectArch(
"mips32r5");
7620 getTargetStreamer().emitDirectiveSetMips32R5();
7622 case Mips::FeatureMips32r6:
7623 selectArch(
"mips32r6");
7624 getTargetStreamer().emitDirectiveSetMips32R6();
7626 case Mips::FeatureMips64:
7627 selectArch(
"mips64");
7628 getTargetStreamer().emitDirectiveSetMips64();
7630 case Mips::FeatureMips64r2:
7631 selectArch(
"mips64r2");
7632 getTargetStreamer().emitDirectiveSetMips64R2();
7634 case Mips::FeatureMips64r3:
7635 selectArch(
"mips64r3");
7636 getTargetStreamer().emitDirectiveSetMips64R3();
7638 case Mips::FeatureMips64r5:
7639 selectArch(
"mips64r5");
7640 getTargetStreamer().emitDirectiveSetMips64R5();
7642 case Mips::FeatureMips64r6:
7643 selectArch(
"mips64r6");
7644 getTargetStreamer().emitDirectiveSetMips64R6();
7646 case Mips::FeatureCRC:
7647 setFeatureBits(Mips::FeatureCRC,
"crc");
7648 getTargetStreamer().emitDirectiveSetCRC();
7650 case Mips::FeatureVirt:
7651 setFeatureBits(Mips::FeatureVirt,
"virt");
7652 getTargetStreamer().emitDirectiveSetVirt();
7654 case Mips::FeatureGINV:
7655 setFeatureBits(Mips::FeatureGINV,
"ginv");
7656 getTargetStreamer().emitDirectiveSetGINV();
7662bool MipsAsmParser::eatComma(StringRef ErrorStr) {
7663 MCAsmParser &Parser = getParser();
7665 SMLoc Loc = getLexer().getLoc();
7666 return Error(Loc, ErrorStr);
7677bool MipsAsmParser::isPicAndNotNxxAbi() {
7678 return inPicMode() && !(isABI_N32() || isABI_N64());
7681bool MipsAsmParser::parseDirectiveCpAdd(SMLoc Loc) {
7683 ParseStatus Res = parseAnyRegister(
Reg);
7685 reportParseError(
"expected register");
7689 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7690 if (!RegOpnd.isGPRAsmReg()) {
7691 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7697 reportParseError(
"unexpected token, expected end of statement");
7702 getTargetStreamer().emitDirectiveCpAdd(RegOpnd.getGPR32Reg());
7706bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
7707 if (AssemblerOptions.
back()->isReorder())
7708 Warning(Loc,
".cpload should be inside a noreorder section");
7710 if (inMips16Mode()) {
7711 reportParseError(
".cpload is not supported in Mips16 mode");
7716 ParseStatus Res = parseAnyRegister(
Reg);
7718 reportParseError(
"expected register containing function address");
7722 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7723 if (!RegOpnd.isGPRAsmReg()) {
7724 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7730 reportParseError(
"unexpected token, expected end of statement");
7734 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
7738bool MipsAsmParser::parseDirectiveCpLocal(SMLoc Loc) {
7739 if (!isABI_N32() && !isABI_N64()) {
7740 reportParseError(
".cplocal is allowed only in N32 or N64 mode");
7745 ParseStatus Res = parseAnyRegister(
Reg);
7747 reportParseError(
"expected register containing global pointer");
7751 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7752 if (!RegOpnd.isGPRAsmReg()) {
7753 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7759 reportParseError(
"unexpected token, expected end of statement");
7764 MCRegister NewReg = RegOpnd.getGPR32Reg();
7768 getTargetStreamer().emitDirectiveCpLocal(NewReg);
7772bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
7773 MCAsmParser &Parser = getParser();
7778 if (inMips16Mode()) {
7779 reportParseError(
".cprestore is not supported in Mips16 mode");
7784 const MCExpr *StackOffset;
7785 int64_t StackOffsetVal;
7787 reportParseError(
"expected stack offset value");
7791 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
7792 reportParseError(
"stack offset is not an absolute expression");
7796 if (StackOffsetVal < 0) {
7797 Warning(Loc,
".cprestore with negative stack offset has no effect");
7798 IsCpRestoreSet =
false;
7800 IsCpRestoreSet =
true;
7801 CpRestoreOffset = StackOffsetVal;
7806 reportParseError(
"unexpected token, expected end of statement");
7810 if (!getTargetStreamer().emitDirectiveCpRestore(
7811 CpRestoreOffset, [&]() {
return getATReg(Loc); }, Loc, STI))
7817bool MipsAsmParser::parseDirectiveCPSetup() {
7818 MCAsmParser &Parser = getParser();
7820 bool SaveIsReg =
true;
7823 ParseStatus Res = parseAnyRegister(TmpReg);
7825 reportParseError(
"expected register containing function address");
7829 MipsOperand &FuncRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7830 if (!FuncRegOpnd.isGPRAsmReg()) {
7831 reportParseError(FuncRegOpnd.getStartLoc(),
"invalid register");
7835 MCRegister FuncReg = FuncRegOpnd.getGPR32Reg();
7838 if (!eatComma(
"unexpected token, expected comma"))
7841 Res = parseAnyRegister(TmpReg);
7843 const MCExpr *OffsetExpr;
7845 SMLoc ExprLoc = getLexer().
getLoc();
7848 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
7849 reportParseError(ExprLoc,
"expected save register or stack offset");
7856 MipsOperand &SaveOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7857 if (!SaveOpnd.isGPRAsmReg()) {
7858 reportParseError(SaveOpnd.getStartLoc(),
"invalid register");
7861 Save = SaveOpnd.getGPR32Reg().id();
7864 if (!eatComma(
"unexpected token, expected comma"))
7869 reportParseError(
"expected expression");
7874 reportParseError(
"expected symbol");
7877 const MCSymbolRefExpr *
Ref =
static_cast<const MCSymbolRefExpr *
>(Expr);
7879 CpSaveLocation = Save;
7880 CpSaveLocationIsRegister = SaveIsReg;
7882 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save,
Ref->getSymbol(),
7887bool MipsAsmParser::parseDirectiveCPReturn() {
7888 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
7889 CpSaveLocationIsRegister);
7893bool MipsAsmParser::parseDirectiveNaN() {
7894 MCAsmParser &Parser = getParser();
7896 const AsmToken &Tok = Parser.
getTok();
7900 getTargetStreamer().emitDirectiveNaN2008();
7902 }
else if (Tok.
getString() ==
"legacy") {
7904 getTargetStreamer().emitDirectiveNaNLegacy();
7910 reportParseError(
"invalid option in .nan directive");
7914bool MipsAsmParser::parseDirectiveSet() {
7915 const AsmToken &Tok = getParser().getTok();
7917 SMLoc Loc = Tok.
getLoc();
7919 if (IdVal ==
"noat")
7920 return parseSetNoAtDirective();
7922 return parseSetAtDirective();
7923 if (IdVal ==
"arch")
7924 return parseSetArchDirective();
7925 if (IdVal ==
"bopt") {
7926 Warning(Loc,
"'bopt' feature is unsupported");
7930 if (IdVal ==
"nobopt") {
7936 return parseSetFpDirective();
7937 if (IdVal ==
"oddspreg")
7938 return parseSetOddSPRegDirective();
7939 if (IdVal ==
"nooddspreg")
7940 return parseSetNoOddSPRegDirective();
7942 return parseSetPopDirective();
7943 if (IdVal ==
"push")
7944 return parseSetPushDirective();
7945 if (IdVal ==
"reorder")
7946 return parseSetReorderDirective();
7947 if (IdVal ==
"noreorder")
7948 return parseSetNoReorderDirective();
7949 if (IdVal ==
"macro")
7950 return parseSetMacroDirective();
7951 if (IdVal ==
"nomacro")
7952 return parseSetNoMacroDirective();
7953 if (IdVal ==
"mips16")
7954 return parseSetMips16Directive();
7955 if (IdVal ==
"nomips16")
7956 return parseSetNoMips16Directive();
7957 if (IdVal ==
"nomicromips") {
7958 clearFeatureBits(Mips::FeatureMicroMips,
"micromips");
7959 getTargetStreamer().emitDirectiveSetNoMicroMips();
7960 getParser().eatToEndOfStatement();
7963 if (IdVal ==
"micromips") {
7964 if (hasMips64r6()) {
7965 Error(Loc,
".set micromips directive is not supported with MIPS64R6");
7968 return parseSetFeature(Mips::FeatureMicroMips);
7970 if (IdVal ==
"mips0")
7971 return parseSetMips0Directive();
7972 if (IdVal ==
"mips1")
7973 return parseSetFeature(Mips::FeatureMips1);
7974 if (IdVal ==
"mips2")
7975 return parseSetFeature(Mips::FeatureMips2);
7976 if (IdVal ==
"mips3")
7977 return parseSetFeature(Mips::FeatureMips3);
7978 if (IdVal ==
"mips4")
7979 return parseSetFeature(Mips::FeatureMips4);
7980 if (IdVal ==
"mips5")
7981 return parseSetFeature(Mips::FeatureMips5);
7982 if (IdVal ==
"mips32")
7983 return parseSetFeature(Mips::FeatureMips32);
7984 if (IdVal ==
"mips32r2")
7985 return parseSetFeature(Mips::FeatureMips32r2);
7986 if (IdVal ==
"mips32r3")
7987 return parseSetFeature(Mips::FeatureMips32r3);
7988 if (IdVal ==
"mips32r5")
7989 return parseSetFeature(Mips::FeatureMips32r5);
7990 if (IdVal ==
"mips32r6")
7991 return parseSetFeature(Mips::FeatureMips32r6);
7992 if (IdVal ==
"mips64")
7993 return parseSetFeature(Mips::FeatureMips64);
7994 if (IdVal ==
"mips64r2")
7995 return parseSetFeature(Mips::FeatureMips64r2);
7996 if (IdVal ==
"mips64r3")
7997 return parseSetFeature(Mips::FeatureMips64r3);
7998 if (IdVal ==
"mips64r5")
7999 return parseSetFeature(Mips::FeatureMips64r5);
8000 if (IdVal ==
"mips64r6") {
8001 if (inMicroMipsMode()) {
8002 Error(Loc,
"MIPS64R6 is not supported with microMIPS");
8005 return parseSetFeature(Mips::FeatureMips64r6);
8008 return parseSetFeature(Mips::FeatureDSP);
8009 if (IdVal ==
"dspr2")
8010 return parseSetFeature(Mips::FeatureDSPR2);
8011 if (IdVal ==
"nodsp")
8012 return parseSetNoDspDirective();
8013 if (IdVal ==
"mips3d")
8014 return parseSetFeature(Mips::FeatureMips3D);
8015 if (IdVal ==
"nomips3d")
8016 return parseSetNoMips3DDirective();
8018 return parseSetMsaDirective();
8019 if (IdVal ==
"nomsa")
8020 return parseSetNoMsaDirective();
8022 return parseSetMtDirective();
8023 if (IdVal ==
"nomt")
8024 return parseSetNoMtDirective();
8025 if (IdVal ==
"softfloat")
8026 return parseSetSoftFloatDirective();
8027 if (IdVal ==
"hardfloat")
8028 return parseSetHardFloatDirective();
8030 return parseSetFeature(Mips::FeatureCRC);
8031 if (IdVal ==
"nocrc")
8032 return parseSetNoCRCDirective();
8033 if (IdVal ==
"virt")
8034 return parseSetFeature(Mips::FeatureVirt);
8035 if (IdVal ==
"novirt")
8036 return parseSetNoVirtDirective();
8037 if (IdVal ==
"ginv")
8038 return parseSetFeature(Mips::FeatureGINV);
8039 if (IdVal ==
"noginv")
8040 return parseSetNoGINVDirective();
8043 return parseSetAssignment();
8048bool MipsAsmParser::parseDirectiveGpWord() {
8049 const MCExpr *
Value;
8050 if (getParser().parseExpression(
Value))
8052 getTargetStreamer().emitGPRel32Value(
Value);
8058bool MipsAsmParser::parseDirectiveGpDWord() {
8059 const MCExpr *
Value;
8060 if (getParser().parseExpression(
Value))
8062 getTargetStreamer().emitGPRel64Value(
Value);
8068bool MipsAsmParser::parseDirectiveDtpRelWord() {
8069 const MCExpr *
Value;
8070 if (getParser().parseExpression(
Value))
8072 getTargetStreamer().emitDTPRel32Value(
Value);
8078bool MipsAsmParser::parseDirectiveDtpRelDWord() {
8079 const MCExpr *
Value;
8080 if (getParser().parseExpression(
Value))
8082 getTargetStreamer().emitDTPRel64Value(
Value);
8088bool MipsAsmParser::parseDirectiveTpRelWord() {
8089 const MCExpr *
Value;
8090 if (getParser().parseExpression(
Value))
8092 getTargetStreamer().emitTPRel32Value(
Value);
8098bool MipsAsmParser::parseDirectiveTpRelDWord() {
8099 const MCExpr *
Value;
8100 if (getParser().parseExpression(
Value))
8102 getTargetStreamer().emitTPRel64Value(
Value);
8106bool MipsAsmParser::parseDirectiveOption() {
8107 MCAsmParser &Parser = getParser();
8109 AsmToken Tok = Parser.
getTok();
8113 "unexpected token, expected identifier");
8118 if (Option ==
"pic0") {
8120 IsPicEnabled =
false;
8122 getTargetStreamer().emitDirectiveOptionPic0();
8126 "unexpected token, expected end of statement");
8131 if (Option ==
"pic2") {
8133 IsPicEnabled =
true;
8135 getTargetStreamer().emitDirectiveOptionPic2();
8139 "unexpected token, expected end of statement");
8146 "unknown option, expected 'pic0' or 'pic2'");
8153bool MipsAsmParser::parseInsnDirective() {
8156 reportParseError(
"unexpected token, expected end of statement");
8162 getTargetStreamer().emitDirectiveInsn();
8170bool MipsAsmParser::parseRSectionDirective(StringRef Section) {
8173 reportParseError(
"unexpected token, expected end of statement");
8177 MCSection *ELFSection =
getContext().getELFSection(
8179 getParser().getStreamer().switchSection(ELFSection);
8188bool MipsAsmParser::parseSSectionDirective(StringRef Section,
unsigned Type) {
8191 reportParseError(
"unexpected token, expected end of statement");
8195 MCSection *ELFSection =
getContext().getELFSection(
8197 getParser().getStreamer().switchSection(ELFSection);
8216bool MipsAsmParser::parseDirectiveModule() {
8217 MCAsmParser &Parser = getParser();
8218 AsmLexer &Lexer = getLexer();
8221 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
8223 reportParseError(
".module directive must appear before any code");
8229 reportParseError(
"expected .module option identifier");
8233 if (Option ==
"oddspreg") {
8234 clearModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
8238 getTargetStreamer().updateABIInfo(*
this);
8243 getTargetStreamer().emitDirectiveModuleOddSPReg();
8247 reportParseError(
"unexpected token, expected end of statement");
8252 }
else if (Option ==
"nooddspreg") {
8254 return Error(L,
"'.module nooddspreg' requires the O32 ABI");
8257 setModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
8261 getTargetStreamer().updateABIInfo(*
this);
8266 getTargetStreamer().emitDirectiveModuleOddSPReg();
8270 reportParseError(
"unexpected token, expected end of statement");
8275 }
else if (Option ==
"fp") {
8276 return parseDirectiveModuleFP();
8277 }
else if (Option ==
"softfloat") {
8278 setModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
8282 getTargetStreamer().updateABIInfo(*
this);
8287 getTargetStreamer().emitDirectiveModuleSoftFloat();
8291 reportParseError(
"unexpected token, expected end of statement");
8296 }
else if (Option ==
"hardfloat") {
8297 clearModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
8301 getTargetStreamer().updateABIInfo(*
this);
8306 getTargetStreamer().emitDirectiveModuleHardFloat();
8310 reportParseError(
"unexpected token, expected end of statement");
8315 }
else if (Option ==
"mt") {
8316 setModuleFeatureBits(Mips::FeatureMT,
"mt");
8320 getTargetStreamer().updateABIInfo(*
this);
8325 getTargetStreamer().emitDirectiveModuleMT();
8329 reportParseError(
"unexpected token, expected end of statement");
8334 }
else if (Option ==
"crc") {
8335 setModuleFeatureBits(Mips::FeatureCRC,
"crc");
8339 getTargetStreamer().updateABIInfo(*
this);
8344 getTargetStreamer().emitDirectiveModuleCRC();
8348 reportParseError(
"unexpected token, expected end of statement");
8353 }
else if (Option ==
"nocrc") {
8354 clearModuleFeatureBits(Mips::FeatureCRC,
"crc");
8358 getTargetStreamer().updateABIInfo(*
this);
8363 getTargetStreamer().emitDirectiveModuleNoCRC();
8367 reportParseError(
"unexpected token, expected end of statement");
8372 }
else if (Option ==
"virt") {
8373 setModuleFeatureBits(Mips::FeatureVirt,
"virt");
8377 getTargetStreamer().updateABIInfo(*
this);
8382 getTargetStreamer().emitDirectiveModuleVirt();
8386 reportParseError(
"unexpected token, expected end of statement");
8391 }
else if (Option ==
"novirt") {
8392 clearModuleFeatureBits(Mips::FeatureVirt,
"virt");
8396 getTargetStreamer().updateABIInfo(*
this);
8401 getTargetStreamer().emitDirectiveModuleNoVirt();
8405 reportParseError(
"unexpected token, expected end of statement");
8410 }
else if (Option ==
"ginv") {
8411 setModuleFeatureBits(Mips::FeatureGINV,
"ginv");
8415 getTargetStreamer().updateABIInfo(*
this);
8420 getTargetStreamer().emitDirectiveModuleGINV();
8424 reportParseError(
"unexpected token, expected end of statement");
8429 }
else if (Option ==
"noginv") {
8430 clearModuleFeatureBits(Mips::FeatureGINV,
"ginv");
8434 getTargetStreamer().updateABIInfo(*
this);
8439 getTargetStreamer().emitDirectiveModuleNoGINV();
8443 reportParseError(
"unexpected token, expected end of statement");
8449 return Error(L,
"'" + Twine(Option) +
"' is not a valid .module option.");
8457bool MipsAsmParser::parseDirectiveModuleFP() {
8458 MCAsmParser &Parser = getParser();
8459 AsmLexer &Lexer = getLexer();
8462 reportParseError(
"unexpected token, expected equals sign '='");
8468 if (!parseFpABIValue(FpABI,
".module"))
8472 reportParseError(
"unexpected token, expected end of statement");
8478 getTargetStreamer().updateABIInfo(*
this);
8483 getTargetStreamer().emitDirectiveModuleFP();
8490 StringRef Directive) {
8491 MCAsmParser &Parser = getParser();
8492 AsmLexer &Lexer = getLexer();
8493 bool ModuleLevelOptions = Directive ==
".module";
8499 if (
Value !=
"xx") {
8500 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
8505 reportParseError(
"'" + Directive +
" fp=xx' requires the O32 ABI");
8509 FpABI = MipsABIFlagsSection::FpABIKind::XX;
8510 if (ModuleLevelOptions) {
8511 setModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8512 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8514 setFeatureBits(Mips::FeatureFPXX,
"fpxx");
8515 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8525 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
8531 reportParseError(
"'" + Directive +
" fp=32' requires the O32 ABI");
8535 FpABI = MipsABIFlagsSection::FpABIKind::S32;
8536 if (ModuleLevelOptions) {
8537 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8538 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8540 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
8541 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8544 FpABI = MipsABIFlagsSection::FpABIKind::S64;
8545 if (ModuleLevelOptions) {
8546 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8547 setModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8549 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
8550 setFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8560bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
8566 MCAsmParser &Parser = getParser();
8567 StringRef IDVal = DirectiveID.
getString();
8569 if (IDVal ==
".cpadd") {
8570 parseDirectiveCpAdd(DirectiveID.
getLoc());
8573 if (IDVal ==
".cpload") {
8574 parseDirectiveCpLoad(DirectiveID.
getLoc());
8577 if (IDVal ==
".cprestore") {
8578 parseDirectiveCpRestore(DirectiveID.
getLoc());
8581 if (IDVal ==
".cplocal") {
8582 parseDirectiveCpLocal(DirectiveID.
getLoc());
8585 if (IDVal ==
".ent") {
8589 reportParseError(
"expected identifier after .ent");
8603 reportParseError(
"unexpected token, expected end of statement");
8607 const MCExpr *DummyNumber;
8608 int64_t DummyNumberVal;
8612 reportParseError(
"expected number after comma");
8615 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
8616 reportParseError(
"expected an absolute expression after comma");
8623 reportParseError(
"unexpected token, expected end of statement");
8629 getTargetStreamer().emitDirectiveEnt(*Sym);
8631 IsCpRestoreSet =
false;
8635 if (IDVal ==
".end") {
8639 reportParseError(
"expected identifier after .end");
8644 reportParseError(
"unexpected token, expected end of statement");
8648 if (CurrentFn ==
nullptr) {
8649 reportParseError(
".end used without .ent");
8653 if ((SymbolName != CurrentFn->
getName())) {
8654 reportParseError(
".end symbol does not match .ent symbol");
8658 getTargetStreamer().emitDirectiveEnd(SymbolName);
8659 CurrentFn =
nullptr;
8660 IsCpRestoreSet =
false;
8664 if (IDVal ==
".frame") {
8667 ParseStatus Res = parseAnyRegister(TmpReg);
8669 reportParseError(
"expected stack register");
8673 MipsOperand &StackRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
8674 if (!StackRegOpnd.isGPRAsmReg()) {
8675 reportParseError(StackRegOpnd.getStartLoc(),
8676 "expected general purpose register");
8679 MCRegister StackReg = StackRegOpnd.getGPR32Reg();
8684 reportParseError(
"unexpected token, expected comma");
8689 const MCExpr *FrameSize;
8690 int64_t FrameSizeVal;
8693 reportParseError(
"expected frame size value");
8697 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
8698 reportParseError(
"frame size not an absolute expression");
8705 reportParseError(
"unexpected token, expected comma");
8711 Res = parseAnyRegister(TmpReg);
8713 reportParseError(
"expected return register");
8717 MipsOperand &ReturnRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
8718 if (!ReturnRegOpnd.isGPRAsmReg()) {
8719 reportParseError(ReturnRegOpnd.getStartLoc(),
8720 "expected general purpose register");
8726 reportParseError(
"unexpected token, expected end of statement");
8730 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
8731 ReturnRegOpnd.getGPR32Reg());
8732 IsCpRestoreSet =
false;
8736 if (IDVal ==
".set") {
8737 parseDirectiveSet();
8741 if (IDVal ==
".mask" || IDVal ==
".fmask") {
8752 const MCExpr *BitMask;
8756 reportParseError(
"expected bitmask value");
8760 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
8761 reportParseError(
"bitmask not an absolute expression");
8768 reportParseError(
"unexpected token, expected comma");
8773 const MCExpr *FrameOffset;
8774 int64_t FrameOffsetVal;
8777 reportParseError(
"expected frame offset value");
8781 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
8782 reportParseError(
"frame offset not an absolute expression");
8788 reportParseError(
"unexpected token, expected end of statement");
8792 if (IDVal ==
".mask")
8793 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
8795 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
8799 if (IDVal ==
".nan")
8800 return parseDirectiveNaN();
8802 if (IDVal ==
".gpword") {
8803 parseDirectiveGpWord();
8807 if (IDVal ==
".gpdword") {
8808 parseDirectiveGpDWord();
8812 if (IDVal ==
".dtprelword") {
8813 parseDirectiveDtpRelWord();
8817 if (IDVal ==
".dtpreldword") {
8818 parseDirectiveDtpRelDWord();
8822 if (IDVal ==
".tprelword") {
8823 parseDirectiveTpRelWord();
8827 if (IDVal ==
".tpreldword") {
8828 parseDirectiveTpRelDWord();
8832 if (IDVal ==
".option") {
8833 parseDirectiveOption();
8837 if (IDVal ==
".abicalls") {
8838 getTargetStreamer().emitDirectiveAbiCalls();
8841 "unexpected token, expected end of statement");
8846 if (IDVal ==
".cpsetup") {
8847 parseDirectiveCPSetup();
8850 if (IDVal ==
".cpreturn") {
8851 parseDirectiveCPReturn();
8854 if (IDVal ==
".module") {
8855 parseDirectiveModule();
8858 if (IDVal ==
".llvm_internal_mips_reallow_module_directive") {
8859 parseInternalDirectiveReallowModule();
8862 if (IDVal ==
".insn") {
8863 parseInsnDirective();
8866 if (IDVal ==
".rdata") {
8867 parseRSectionDirective(
".rodata");
8870 if (IDVal ==
".sbss") {
8874 if (IDVal ==
".sdata") {
8882bool MipsAsmParser::parseInternalDirectiveReallowModule() {
8885 reportParseError(
"unexpected token, expected end of statement");
8889 getTargetStreamer().reallowModuleDirective();
8903#define GET_REGISTER_MATCHER
8904#define GET_MATCHER_IMPLEMENTATION
8905#define GET_MNEMONIC_SPELL_CHECKER
8906#include "MipsGenAsmMatcher.inc"
8908bool MipsAsmParser::mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID) {
8910 const MatchEntry *Start, *End;
8911 switch (VariantID) {
8913 case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0);
break;
8916 auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
8917 return MnemonicRange.first != MnemonicRange.second;
static const TargetRegisterClass * getRegClass(const MachineInstr &MI, Register Reg)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
This file declares a class to represent arbitrary precision floating point values and provide a varie...
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
static Value * expandAbs(CallInst *Orig)
std::pair< Instruction::BinaryOps, Value * > OffsetOp
Find all possible pairs (BinOp, RHS) that BinOp V, RHS can be simplified.
static constexpr Value * getValue(Ty &ValueOrUse)
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static FeatureBitset getFeatures(MCSubtargetInfo &STI, StringRef CPU, StringRef TuneCPU, StringRef FS, StringTable ProcNames, ArrayRef< SubtargetSubTypeKV > ProcDesc, ArrayRef< SubtargetFeatureKV > ProcFeatures)
static bool hasFeature(StringRef Feature, const FeatureBitset &FeatureBits, ArrayRef< SubtargetFeatureKV > ProcFeatures)
static unsigned countMCSymbolRefExpr(const MCExpr *Expr)
static std::string MipsMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, unsigned VariantID=0)
static uint64_t convertIntToDoubleImm(uint64_t ImmOp64)
static uint32_t covertDoubleImmToSingleImm(uint64_t ImmOp64)
static unsigned getRegisterForMxtrDSP(MCInst &Inst, bool IsMFDSP)
static bool hasShortDelaySlot(MCInst &Inst)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsAsmParser()
static bool needsExpandMemInst(MCInst &Inst, const MCInstrDesc &MCID)
cl::opt< bool > EmitJalrReloc
static bool isShiftedUIntAtAnyPosition(uint64_t x)
Can the value be represented by a unsigned N-bit value and a shift left?
static bool isEvaluated(const MCExpr *Expr)
static unsigned getRegisterForMxtrC0(MCInst &Inst, bool IsMFTC0)
static const MCSymbol * getSingleMCSymbol(const MCExpr *Expr)
static MCRegister nextReg(MCRegister Reg)
static unsigned getRegisterForMxtrFP(MCInst &Inst, bool IsMFTC1)
cl::opt< bool > NoZeroDivCheck
static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands, uint64_t ErrorInfo)
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
static PPCTargetMachine::PPCABI computeTargetABI(const Triple &TT, const TargetOptions &Options)
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static const fltSemantics & IEEEdouble()
APInt bitcastToAPInt() const
uint64_t getZExtValue() const
Get zero extended value.
SMLoc getLoc() const
Get the current source location.
const AsmToken peekTok(bool ShouldSkipSpace=true)
Look ahead at the next token to be lexed.
bool is(AsmToken::TokenKind K) const
Check if the current token has kind K.
bool isNot(AsmToken::TokenKind K) const
Check if the current token has kind K.
Target independent representation for an assembler token.
LLVM_ABI SMLoc getLoc() const
int64_t getIntVal() const
bool isNot(TokenKind K) const
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
bool is(TokenKind K) const
TokenKind getKind() const
LLVM_ABI SMRange getLocRange() const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
Base class for user error types.
Container class for subtarget features.
void printExpr(raw_ostream &, const MCExpr &) const
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
bool parseToken(AsmToken::TokenKind T, const Twine &Msg="unexpected token")
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
Binary assembler expressions.
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
static LLVM_ABI const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
@ LShr
Logical shift right.
@ Xor
Bitwise exclusive or.
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Base class for the full range of assembler expressions which are needed for parsing.
LLVM_ABI bool evaluateAsRelocatable(MCValue &Res, const MCAssembler *Asm) const
Try to evaluate the expression to a relocatable value, i.e.
@ Unary
Unary expressions.
@ Constant
Constant expressions.
@ SymbolRef
References to labels and assigned expressions.
@ Target
Target specific expression.
@ Specifier
Expression with a relocation specifier.
@ Binary
Binary expressions.
Instances of this class represent a single low-level machine instruction.
unsigned getNumOperands() const
unsigned getOpcode() const
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
const MCOperand & getOperand(unsigned i) const
Describe properties that are true of each instruction in the target description file.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
ArrayRef< MCOperandInfo > operands() const
bool mayStore() const
Return true if this instruction could possibly modify memory.
bool mayLoad() const
Return true if this instruction could possibly read memory.
bool isBranch() const
Returns true if this is a conditional, unconditional, or indirect branch.
bool isCall() const
Return true if the instruction is a call.
bool hasDelaySlot() const
Returns true if the specified instruction has a delay slot which must be filled by the code generator...
Interface to description of machine instruction set.
This holds information about one operand of a machine instruction, indicating the register class for ...
uint8_t OperandType
Information about the type of the operand.
Instances of this class represent operands of the MCInst class.
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
MCRegister getReg() const
Returns the register number.
const MCExpr * getExpr() const
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual bool isReg() const =0
isReg - Is this a register operand?
virtual MCRegister getReg() const =0
Wrapper class representing physical registers. Should be passed by value.
constexpr bool isValid() const
constexpr unsigned id() const
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
Streaming machine code generation interface.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
virtual void emitRelocDirective(const MCExpr &Offset, StringRef Name, const MCExpr *Expr, SMLoc Loc={})
Record a relocation described by the .reloc directive.
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
void setFeatureBits(const FeatureBitset &FeatureBits_)
const Triple & getTargetTriple() const
const FeatureBitset & getFeatureBits() const
const FeatureBitset & ToggleFeature(uint64_t FB)
Toggle a feature and return the re-computed feature bits.
virtual unsigned getHwMode(enum HwModeType type=HwMode_Default) const
HwMode ID corresponding to the 'type' parameter is retrieved from the HwMode bit set of the current s...
Represent a reference to a symbol from inside an expression.
uint16_t getSpecifier() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
bool isInSection() const
isInSection - Check if this symbol is defined in some section (i.e., it is defined but not absolute).
bool isUndefined() const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).
StringRef getName() const
getName - Get the symbol name.
bool isVariable() const
isVariable - Check if this is a variable symbol.
const MCExpr * getVariableValue() const
Get the expression of the variable symbol.
bool isTemporary() const
isTemporary - Check if this is an assembler temporary symbol.
MCTargetAsmParser - Generic interface to target specific assembly parsers.
MCStreamer & getStreamer()
Unary assembler expressions.
const MCSymbol * getAddSym() const
int64_t getConstant() const
const MCSymbol * getSubSym() const
void emitRRX(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, MCOperand Op2, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveSetReorder()
void emitRRRX(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, MCRegister Reg2, MCOperand Op3, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRX(unsigned Opcode, MCRegister Reg0, MCOperand Op1, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitR(unsigned Opcode, MCRegister Reg0, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void setUsesMicroMips()
void emitRRI(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, int16_t Imm, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitEmptyDelaySlot(bool hasShortDelaySlot, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRI(unsigned Opcode, MCRegister Reg0, int32_t Imm, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRR(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, SMLoc IDLoc, const MCSubtargetInfo *STI)
void updateABIInfo(const PredicateLibrary &P)
void emitRRIII(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, int16_t Imm0, int16_t Imm1, int16_t Imm2, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitDSLL(MCRegister DstReg, MCRegister SrcReg, int16_t ShiftAmount, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitGPRestore(int Offset, SMLoc IDLoc, const MCSubtargetInfo *STI)
Emit the $gp restore operation for .cprestore.
void emitNop(SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRRR(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, MCRegister Reg2, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveSetNoReorder()
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
static constexpr StatusTy Failure
constexpr bool isSuccess() const
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
constexpr bool isNoMatch() const
constexpr unsigned id() const
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
void push_back(const T &Elt)
iterator find(StringRef Key)
Represent a constant reference to a string, i.e.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
Check if the string is empty.
LLVM_ABI bool isLittleEndian() const
Tests whether the target triple is little endian.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
LLVM_ABI bool parseAssignmentExpression(StringRef Name, bool allow_redef, MCAsmParser &Parser, MCSymbol *&Symbol, const MCExpr *&Value)
Parse a value expression and return whether it can be assigned to a symbol with the given name.
@ CE
Windows NT (Windows on ARM)
LLVM_ABI StringRef getABIName()
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
unsigned getOpcode(const VPValue *V)
Return the instruction opcode for the recipe defining V or 0 for unsupported recipes and VPValues not...
This is an optimization pass for GlobalISel generic memory operations.
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Target & getTheMips64Target()
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
static StringRef getCPU(StringRef CPU)
Processes a CPU name.
int bit_width(T Value)
Returns the number of bits needed to represent Value if Value is nonzero.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
@ Success
The lock was released successfully.
Target & getTheMips64elTarget()
uint64_t offsetToAlignment(uint64_t Value, Align Alignment)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
@ Ref
The access may reference the value stored in memory.
To bit_cast(const From &from) noexcept
Target & getTheMipselTarget()
DWARFExpression::Operation Op
constexpr bool isShiftedInt(int64_t x)
Checks if a signed integer is an N bit number shifted left by S.
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
static uint16_t getSpecifier(const MCSymbolRefExpr *SRE)
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
Target & getTheMipsTarget()
constexpr bool isShiftedUInt(uint64_t x)
Checks if a unsigned integer is an N bit number shifted left by S.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...