64#define DEBUG_TYPE "mips-asm-parser"
77class MipsAssemblerOptions {
79 MipsAssemblerOptions(
const FeatureBitset &Features_) : Features(Features_) {}
81 MipsAssemblerOptions(
const MipsAssemblerOptions *Opts) {
82 ATReg = Opts->getATRegIndex();
83 Reorder = Opts->isReorder();
84 Macro = Opts->isMacro();
85 Features = Opts->getFeatures();
88 unsigned getATRegIndex()
const {
return ATReg; }
89 bool setATRegIndex(
unsigned Reg) {
97 bool isReorder()
const {
return Reorder; }
98 void setReorder() { Reorder =
true; }
99 void setNoReorder() { Reorder =
false; }
101 bool isMacro()
const {
return Macro; }
102 void setMacro() {
Macro =
true; }
103 void setNoMacro() {
Macro =
false; }
105 const FeatureBitset &
getFeatures()
const {
return Features; }
106 void setFeatures(
const FeatureBitset &Features_) { Features = Features_; }
113 static const FeatureBitset AllArchRelatedMask;
119 FeatureBitset Features;
124const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
125 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
126 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
127 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
128 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
129 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
130 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
131 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
132 Mips::FeatureCnMipsP, Mips::FeatureFP64Bit, Mips::FeatureGP64Bit,
139 MipsTargetStreamer &getTargetStreamer() {
140 assert(getParser().getStreamer().getTargetStreamer() &&
141 "do not have a target streamer");
142 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
143 return static_cast<MipsTargetStreamer &
>(TS);
155 bool CurForbiddenSlotAttr;
158 unsigned CpSaveLocation;
160 bool CpSaveLocationIsRegister;
163 StringMap<AsmToken> RegisterSets;
166 void printWarningWithFixIt(
const Twine &
Msg,
const Twine &FixMsg,
167 SMRange
Range,
bool ShowColors =
true);
171#define GET_ASSEMBLER_HEADER
172#include "MipsGenAsmMatcher.inc"
175 checkEarlyTargetMatchPredicate(
MCInst &Inst,
177 unsigned checkTargetMatchPredicate(
MCInst &Inst)
override;
179 bool matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
182 bool MatchingInlineAsm)
override;
187 SMLoc &EndLoc)
override;
193 bool mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID);
198 bool ParseDirective(
AsmToken DirectiveID)
override;
210 const MCExpr *parseRelocExpr();
216 enum MacroExpanderResultTy {
223 MacroExpanderResultTy tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
225 const MCSubtargetInfo *STI);
227 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
228 const MCSubtargetInfo *STI);
230 bool loadImmediate(int64_t ImmValue, MCRegister DstReg, MCRegister SrcReg,
231 bool Is32BitImm,
bool IsAddress, SMLoc IDLoc,
232 MCStreamer &Out,
const MCSubtargetInfo *STI);
234 bool loadAndAddSymbolAddress(
const MCExpr *SymExpr, MCRegister DstReg,
235 MCRegister SrcReg,
bool Is32BitSym, SMLoc IDLoc,
236 MCStreamer &Out,
const MCSubtargetInfo *STI);
238 bool emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc, MCSymbol *Sym);
240 bool expandLoadImm(MCInst &Inst,
bool Is32BitImm, SMLoc IDLoc,
241 MCStreamer &Out,
const MCSubtargetInfo *STI);
243 bool expandLoadSingleImmToGPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
244 const MCSubtargetInfo *STI);
245 bool expandLoadSingleImmToFPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
246 const MCSubtargetInfo *STI);
247 bool expandLoadDoubleImmToGPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
248 const MCSubtargetInfo *STI);
249 bool expandLoadDoubleImmToFPR(MCInst &Inst,
bool Is64FPU, SMLoc IDLoc,
250 MCStreamer &Out,
const MCSubtargetInfo *STI);
252 bool expandLoadAddress(MCRegister DstReg, MCRegister BaseReg,
253 const MCOperand &
Offset,
bool Is32BitAddress,
254 SMLoc IDLoc, MCStreamer &Out,
255 const MCSubtargetInfo *STI);
257 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
258 const MCSubtargetInfo *STI);
260 void expandMem16Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
261 const MCSubtargetInfo *STI,
bool IsLoad);
262 void expandMem9Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
263 const MCSubtargetInfo *STI,
bool IsLoad);
265 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
266 const MCSubtargetInfo *STI);
268 bool expandAliasImmediate(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
269 const MCSubtargetInfo *STI);
271 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
272 const MCSubtargetInfo *STI);
274 bool expandCondBranches(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
275 const MCSubtargetInfo *STI);
277 bool expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
278 const MCSubtargetInfo *STI,
const bool IsMips64,
281 bool expandTrunc(MCInst &Inst,
bool IsDouble,
bool Is64FPU, SMLoc IDLoc,
282 MCStreamer &Out,
const MCSubtargetInfo *STI);
284 bool expandUlh(MCInst &Inst,
bool Signed, SMLoc IDLoc, MCStreamer &Out,
285 const MCSubtargetInfo *STI);
287 bool expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
288 const MCSubtargetInfo *STI);
290 bool expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
291 const MCSubtargetInfo *STI);
293 bool expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
294 const MCSubtargetInfo *STI);
296 bool expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
297 const MCSubtargetInfo *STI);
299 bool expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
300 const MCSubtargetInfo *STI);
302 bool expandSle(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
303 const MCSubtargetInfo *STI);
305 bool expandSleImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
306 const MCSubtargetInfo *STI);
308 bool expandRotation(MCInst &Inst, SMLoc IDLoc,
309 MCStreamer &Out,
const MCSubtargetInfo *STI);
310 bool expandRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
311 const MCSubtargetInfo *STI);
312 bool expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
313 const MCSubtargetInfo *STI);
314 bool expandDRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
315 const MCSubtargetInfo *STI);
317 bool expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
318 const MCSubtargetInfo *STI);
320 bool expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
321 const MCSubtargetInfo *STI);
323 bool expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
324 const MCSubtargetInfo *STI);
326 bool expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
327 const MCSubtargetInfo *STI);
329 bool expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
330 const MCSubtargetInfo *STI);
332 bool expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
333 const MCSubtargetInfo *STI,
bool IsLoad);
335 bool expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
336 const MCSubtargetInfo *STI);
338 bool expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
339 const MCSubtargetInfo *STI);
341 bool expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
342 const MCSubtargetInfo *STI);
344 bool expandSne(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
345 const MCSubtargetInfo *STI);
347 bool expandSneI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
348 const MCSubtargetInfo *STI);
350 bool expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
351 const MCSubtargetInfo *STI);
353 bool expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
354 const MCSubtargetInfo *STI);
356 bool reportParseError(
const Twine &ErrorMsg);
357 bool reportParseError(SMLoc Loc,
const Twine &ErrorMsg);
359 bool parseSetMips0Directive();
360 bool parseSetArchDirective();
361 bool parseSetFeature(
uint64_t Feature);
362 bool isPicAndNotNxxAbi();
363 bool parseDirectiveCpAdd(SMLoc Loc);
364 bool parseDirectiveCpLoad(SMLoc Loc);
365 bool parseDirectiveCpLocal(SMLoc Loc);
366 bool parseDirectiveCpRestore(SMLoc Loc);
367 bool parseDirectiveCPSetup();
368 bool parseDirectiveCPReturn();
369 bool parseDirectiveNaN();
370 bool parseDirectiveSet();
371 bool parseDirectiveOption();
372 bool parseInsnDirective();
373 bool parseRSectionDirective(StringRef Section);
374 bool parseSSectionDirective(StringRef Section,
unsigned Type);
376 bool parseSetAtDirective();
377 bool parseSetNoAtDirective();
378 bool parseSetMacroDirective();
379 bool parseSetNoMacroDirective();
380 bool parseSetMsaDirective();
381 bool parseSetNoMsaDirective();
382 bool parseSetNoDspDirective();
383 bool parseSetNoMips3DDirective();
384 bool parseSetReorderDirective();
385 bool parseSetNoReorderDirective();
386 bool parseSetMips16Directive();
387 bool parseSetNoMips16Directive();
388 bool parseSetFpDirective();
389 bool parseSetOddSPRegDirective();
390 bool parseSetNoOddSPRegDirective();
391 bool parseSetPopDirective();
392 bool parseSetPushDirective();
393 bool parseSetSoftFloatDirective();
394 bool parseSetHardFloatDirective();
395 bool parseSetMtDirective();
396 bool parseSetNoMtDirective();
397 bool parseSetNoCRCDirective();
398 bool parseSetNoVirtDirective();
399 bool parseSetNoGINVDirective();
400 bool parseSetNoEVADirective();
402 bool parseSetAssignment();
404 bool parseDirectiveGpWord();
405 bool parseDirectiveGpDWord();
406 bool parseDirectiveDtpRelWord();
407 bool parseDirectiveDtpRelDWord();
408 bool parseDirectiveTpRelWord();
409 bool parseDirectiveTpRelDWord();
410 bool parseDirectiveModule();
411 bool parseDirectiveModuleFP();
413 StringRef Directive);
415 bool parseInternalDirectiveReallowModule();
417 bool eatComma(StringRef ErrorStr);
419 int matchCPURegisterName(StringRef Symbol);
421 int matchHWRegsRegisterName(StringRef Symbol);
423 int matchFPURegisterName(StringRef Name);
425 int matchFCCRegisterName(StringRef Name);
427 int matchACRegisterName(StringRef Name);
429 int matchMSA128RegisterName(StringRef Name);
431 int matchMSA128CtrlRegisterName(StringRef Name);
433 MCRegister
getReg(
int RC,
int RegNo);
438 MCRegister getATReg(SMLoc Loc);
442 bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
443 const MCSubtargetInfo *STI);
467 void selectArch(StringRef ArchFeature) {
468 MCSubtargetInfo &STI = copySTI();
470 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
472 setAvailableFeatures(
477 void setFeatureBits(
uint64_t Feature, StringRef FeatureString) {
479 MCSubtargetInfo &STI = copySTI();
480 setAvailableFeatures(
486 void clearFeatureBits(
uint64_t Feature, StringRef FeatureString) {
488 MCSubtargetInfo &STI = copySTI();
489 setAvailableFeatures(
495 void setModuleFeatureBits(
uint64_t Feature, StringRef FeatureString) {
496 setFeatureBits(Feature, FeatureString);
497 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
500 void clearModuleFeatureBits(
uint64_t Feature, StringRef FeatureString) {
501 clearFeatureBits(Feature, FeatureString);
502 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
506 enum MipsMatchResultTy {
507 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
508 Match_RequiresDifferentOperands,
509 Match_RequiresNoZeroRegister,
510 Match_RequiresSameSrcAndDst,
511 Match_NoFCCRegisterForCurrentISA,
512 Match_NonZeroOperandForSync,
513 Match_NonZeroOperandForMTCX,
514 Match_RequiresPosSizeRange0_32,
515 Match_RequiresPosSizeRange33_64,
516 Match_RequiresPosSizeUImm6,
517#define GET_OPERAND_DIAGNOSTIC_TYPES
518#include "MipsGenAsmMatcher.inc"
519#undef GET_OPERAND_DIAGNOSTIC_TYPES
522 MipsAsmParser(
const MCSubtargetInfo &sti, MCAsmParser &parser,
523 const MCInstrInfo &MII)
524 : MCTargetAsmParser(sti, MII),
526 sti.getTargetTriple(),
536 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
539 AssemblerOptions.push_back(
540 std::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
543 AssemblerOptions.push_back(
544 std::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
546 getTargetStreamer().updateABIInfo(*
this);
548 if (!isABI_O32() && !useOddSPReg() != 0)
553 CurForbiddenSlotAttr =
false;
554 IsPicEnabled =
getContext().getObjectFileInfo()->isPositionIndependent();
556 IsCpRestoreSet =
false;
557 CpRestoreOffset = -1;
558 GPReg = ABI.GetGlobalPtr();
563 if (getSTI().
getCPU() ==
"mips64r6" && inMicroMipsMode())
566 if (!isABI_O32() && inMicroMipsMode())
571 bool hasEightFccRegisters()
const {
return hasMips4() || hasMips32(); }
573 bool isGP64bit()
const {
574 return getSTI().hasFeature(Mips::FeatureGP64Bit);
577 bool isFP64bit()
const {
578 return getSTI().hasFeature(Mips::FeatureFP64Bit);
581 bool isJalrRelocAvailable(
const MCExpr *JalExpr) {
590 return ABI.IsN32() || ABI.IsN64();
594 const MipsABIInfo &
getABI()
const {
return ABI; }
595 bool isABI_N32()
const {
return ABI.IsN32(); }
596 bool isABI_N64()
const {
return ABI.IsN64(); }
597 bool isABI_O32()
const {
return ABI.IsO32(); }
598 bool isABI_FPXX()
const {
599 return getSTI().hasFeature(Mips::FeatureFPXX);
602 bool useOddSPReg()
const {
603 return !(getSTI().hasFeature(Mips::FeatureNoOddSPReg));
606 bool inMicroMipsMode()
const {
607 return getSTI().hasFeature(Mips::FeatureMicroMips);
610 bool hasMips1()
const {
611 return getSTI().hasFeature(Mips::FeatureMips1);
614 bool hasMips2()
const {
615 return getSTI().hasFeature(Mips::FeatureMips2);
618 bool hasMips3()
const {
619 return getSTI().hasFeature(Mips::FeatureMips3);
622 bool hasMips4()
const {
623 return getSTI().hasFeature(Mips::FeatureMips4);
626 bool hasMips5()
const {
627 return getSTI().hasFeature(Mips::FeatureMips5);
630 bool hasMips32()
const {
631 return getSTI().hasFeature(Mips::FeatureMips32);
634 bool hasMips64()
const {
635 return getSTI().hasFeature(Mips::FeatureMips64);
638 bool hasMips32r2()
const {
639 return getSTI().hasFeature(Mips::FeatureMips32r2);
642 bool hasMips64r2()
const {
643 return getSTI().hasFeature(Mips::FeatureMips64r2);
646 bool hasMips32r3()
const {
647 return (getSTI().
hasFeature(Mips::FeatureMips32r3));
650 bool hasMips64r3()
const {
651 return (getSTI().
hasFeature(Mips::FeatureMips64r3));
654 bool hasMips32r5()
const {
655 return (getSTI().
hasFeature(Mips::FeatureMips32r5));
658 bool hasMips64r5()
const {
659 return (getSTI().
hasFeature(Mips::FeatureMips64r5));
662 bool hasMips32r6()
const {
663 return getSTI().hasFeature(Mips::FeatureMips32r6);
666 bool hasMips64r6()
const {
667 return getSTI().hasFeature(Mips::FeatureMips64r6);
670 bool hasDSP()
const {
671 return getSTI().hasFeature(Mips::FeatureDSP);
674 bool hasDSPR2()
const {
675 return getSTI().hasFeature(Mips::FeatureDSPR2);
678 bool hasDSPR3()
const {
679 return getSTI().hasFeature(Mips::FeatureDSPR3);
682 bool hasMSA()
const {
683 return getSTI().hasFeature(Mips::FeatureMSA);
686 bool hasCnMips()
const {
687 return (getSTI().
hasFeature(Mips::FeatureCnMips));
690 bool hasCnMipsP()
const {
691 return (getSTI().
hasFeature(Mips::FeatureCnMipsP));
694 bool isR5900()
const {
return (getSTI().
hasFeature(Mips::FeatureR5900)); }
700 bool inMips16Mode()
const {
701 return getSTI().hasFeature(Mips::FeatureMips16);
704 bool useTraps()
const {
705 return getSTI().hasFeature(Mips::FeatureUseTCCInDIV);
708 bool useSoftFloat()
const {
709 return getSTI().hasFeature(Mips::FeatureSoftFloat);
712 bool isSingleFloat()
const {
713 return getSTI().hasFeature(Mips::FeatureSingleFloat);
717 return getSTI().hasFeature(Mips::FeatureMT);
720 bool hasCRC()
const {
721 return getSTI().hasFeature(Mips::FeatureCRC);
724 bool hasVirt()
const {
725 return getSTI().hasFeature(Mips::FeatureVirt);
728 bool hasGINV()
const {
729 return getSTI().hasFeature(Mips::FeatureGINV);
732 bool hasForbiddenSlot(
const MCInstrDesc &MCID)
const {
736 bool SafeInForbiddenSlot(
const MCInstrDesc &MCID)
const {
740 void onEndOfFile()
override;
743 void warnIfRegIndexIsAT(MCRegister RegIndex, SMLoc Loc);
745 void warnIfNoMacro(SMLoc Loc);
747 bool isLittle()
const {
return IsLittleEndian; }
749 bool areEqualRegs(
const MCParsedAsmOperand &Op1,
750 const MCParsedAsmOperand &Op2)
const override;
765 RegKind_MSACtrl = 16,
770 RegKind_HWRegs = 256,
774 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
775 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
776 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
789 MipsOperand(KindTy K, MipsAsmParser &Parser) : Kind(
K), AsmParser(Parser) {}
791 ~MipsOperand()
override {
800 case k_RegisterIndex:
808 MipsAsmParser &AsmParser;
819 const MCRegisterInfo *RegInfo;
837 struct RegIdxOp RegIdx;
840 struct RegListOp RegList;
843 SMLoc StartLoc, EndLoc;
846 static std::unique_ptr<MipsOperand> CreateReg(
unsigned Index, StringRef Str,
848 const MCRegisterInfo *RegInfo,
850 MipsAsmParser &Parser) {
851 auto Op = std::make_unique<MipsOperand>(k_RegisterIndex, Parser);
853 Op->RegIdx.RegInfo = RegInfo;
854 Op->RegIdx.Kind = RegKind;
855 Op->RegIdx.Tok.Data = Str.data();
856 Op->RegIdx.Tok.Length = Str.size();
865 MCRegister getGPR32Reg()
const {
866 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
867 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
868 unsigned ClassID = Mips::GPR32RegClassID;
869 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
874 MCRegister getGPRMM16Reg()
const {
875 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
876 unsigned ClassID = Mips::GPR32RegClassID;
877 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
882 MCRegister getGPR64Reg()
const {
883 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
884 unsigned ClassID = Mips::GPR64RegClassID;
885 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
891 MCRegister getAFGR64Reg()
const {
892 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
893 if (RegIdx.Index % 2 != 0)
894 AsmParser.Warning(StartLoc,
"Float register should be even.");
895 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
896 .getRegister(RegIdx.Index / 2);
901 MCRegister getFGR64Reg()
const {
902 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
903 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
904 .getRegister(RegIdx.Index);
909 MCRegister getFGR32Reg()
const {
910 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
911 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
912 .getRegister(RegIdx.Index);
917 MCRegister getFCCReg()
const {
918 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) &&
"Invalid access!");
919 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
920 .getRegister(RegIdx.Index);
925 MCRegister getMSA128Reg()
const {
926 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) &&
"Invalid access!");
929 unsigned ClassID = Mips::MSA128BRegClassID;
930 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
935 MCRegister getMSACtrlReg()
const {
936 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) &&
"Invalid access!");
937 unsigned ClassID = Mips::MSACtrlRegClassID;
938 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
943 MCRegister getCOP0Reg()
const {
944 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) &&
"Invalid access!");
945 unsigned ClassID = Mips::COP0RegClassID;
946 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
951 MCRegister getCOP2Reg()
const {
952 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) &&
"Invalid access!");
953 unsigned ClassID = Mips::COP2RegClassID;
954 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
959 MCRegister getCOP3Reg()
const {
960 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) &&
"Invalid access!");
961 unsigned ClassID = Mips::COP3RegClassID;
962 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
967 MCRegister getACC64DSPReg()
const {
968 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
969 unsigned ClassID = Mips::ACC64DSPRegClassID;
970 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
975 MCRegister getHI32DSPReg()
const {
976 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
977 unsigned ClassID = Mips::HI32DSPRegClassID;
978 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
983 MCRegister getLO32DSPReg()
const {
984 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
985 unsigned ClassID = Mips::LO32DSPRegClassID;
986 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
991 MCRegister getCCRReg()
const {
992 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) &&
"Invalid access!");
993 unsigned ClassID = Mips::CCRRegClassID;
994 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
999 MCRegister getHWRegsReg()
const {
1000 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) &&
"Invalid access!");
1001 unsigned ClassID = Mips::HWRegsRegClassID;
1002 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1006 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const {
1016 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1023 void addGPR32ZeroAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1024 assert(
N == 1 &&
"Invalid number of operands!");
1028 void addGPR32NonZeroAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1029 assert(
N == 1 &&
"Invalid number of operands!");
1033 void addGPR32AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1034 assert(
N == 1 &&
"Invalid number of operands!");
1038 void addGPRMM16AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1039 assert(
N == 1 &&
"Invalid number of operands!");
1043 void addGPRMM16AsmRegZeroOperands(MCInst &Inst,
unsigned N)
const {
1044 assert(
N == 1 &&
"Invalid number of operands!");
1048 void addGPRMM16AsmRegMovePOperands(MCInst &Inst,
unsigned N)
const {
1049 assert(
N == 1 &&
"Invalid number of operands!");
1053 void addGPRMM16AsmRegMovePPairFirstOperands(MCInst &Inst,
unsigned N)
const {
1054 assert(
N == 1 &&
"Invalid number of operands!");
1058 void addGPRMM16AsmRegMovePPairSecondOperands(MCInst &Inst,
1060 assert(
N == 1 &&
"Invalid number of operands!");
1067 void addGPR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1068 assert(
N == 1 &&
"Invalid number of operands!");
1072 void addAFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1073 assert(
N == 1 &&
"Invalid number of operands!");
1077 void addStrictlyAFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1078 assert(
N == 1 &&
"Invalid number of operands!");
1082 void addStrictlyFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1083 assert(
N == 1 &&
"Invalid number of operands!");
1087 void addFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1088 assert(
N == 1 &&
"Invalid number of operands!");
1092 void addFGR32AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1093 assert(
N == 1 &&
"Invalid number of operands!");
1097 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1098 AsmParser.getParser().printError(
1099 StartLoc,
"-mno-odd-spreg prohibits the use of odd FPU "
1103 void addStrictlyFGR32AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1104 assert(
N == 1 &&
"Invalid number of operands!");
1107 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1108 AsmParser.Error(StartLoc,
"-mno-odd-spreg prohibits the use of odd FPU "
1112 void addFCCAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1113 assert(
N == 1 &&
"Invalid number of operands!");
1117 void addMSA128AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1118 assert(
N == 1 &&
"Invalid number of operands!");
1122 void addMSACtrlAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1123 assert(
N == 1 &&
"Invalid number of operands!");
1127 void addCOP0AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1128 assert(
N == 1 &&
"Invalid number of operands!");
1132 void addCOP2AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1133 assert(
N == 1 &&
"Invalid number of operands!");
1137 void addCOP3AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1138 assert(
N == 1 &&
"Invalid number of operands!");
1142 void addACC64DSPAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1143 assert(
N == 1 &&
"Invalid number of operands!");
1147 void addHI32DSPAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1148 assert(
N == 1 &&
"Invalid number of operands!");
1152 void addLO32DSPAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1153 assert(
N == 1 &&
"Invalid number of operands!");
1157 void addCCRAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1158 assert(
N == 1 &&
"Invalid number of operands!");
1162 void addHWRegsAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1163 assert(
N == 1 &&
"Invalid number of operands!");
1167 template <
unsigned Bits,
int Offset = 0,
int AdjustOffset = 0>
1168 void addConstantUImmOperands(MCInst &Inst,
unsigned N)
const {
1169 assert(
N == 1 &&
"Invalid number of operands!");
1173 Imm += AdjustOffset;
1177 template <
unsigned Bits>
1178 void addSImmOperands(MCInst &Inst,
unsigned N)
const {
1179 if (isImm() && !isConstantImm()) {
1183 addConstantSImmOperands<Bits, 0, 0>(Inst,
N);
1186 template <
unsigned Bits>
1187 void addUImmOperands(MCInst &Inst,
unsigned N)
const {
1188 if (isImm() && !isConstantImm()) {
1192 addConstantUImmOperands<Bits, 0, 0>(Inst,
N);
1195 template <
unsigned Bits,
int Offset = 0,
int AdjustOffset = 0>
1196 void addConstantSImmOperands(MCInst &Inst,
unsigned N)
const {
1197 assert(
N == 1 &&
"Invalid number of operands!");
1198 int64_t
Imm = getConstantImm() -
Offset;
1201 Imm += AdjustOffset;
1205 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1206 assert(
N == 1 &&
"Invalid number of operands!");
1207 const MCExpr *Expr =
getImm();
1208 addExpr(Inst, Expr);
1211 void addMemOperands(MCInst &Inst,
unsigned N)
const {
1212 assert(
N == 2 &&
"Invalid number of operands!");
1215 ? getMemBase()->getGPR64Reg()
1216 : getMemBase()->getGPR32Reg()));
1218 const MCExpr *Expr = getMemOff();
1219 addExpr(Inst, Expr);
1222 void addMicroMipsMemOperands(MCInst &Inst,
unsigned N)
const {
1223 assert(
N == 2 &&
"Invalid number of operands!");
1227 const MCExpr *Expr = getMemOff();
1228 addExpr(Inst, Expr);
1231 void addRegListOperands(MCInst &Inst,
unsigned N)
const {
1232 assert(
N == 1 &&
"Invalid number of operands!");
1234 for (
auto RegNo : getRegList())
1238 bool isReg()
const override {
1241 return isGPRAsmReg() && RegIdx.Index == 0;
1244 bool isRegIdx()
const {
return Kind == k_RegisterIndex; }
1245 bool isImm()
const override {
return Kind == k_Immediate; }
1247 bool isConstantImm()
const {
1249 return isImm() &&
getImm()->evaluateAsAbsolute(Res);
1252 bool isConstantImmz()
const {
1253 return isConstantImm() && getConstantImm() == 0;
1256 template <
unsigned Bits,
int Offset = 0>
bool isConstantUImm()
const {
1260 template <
unsigned Bits>
bool isSImm()
const {
1264 if (
getImm()->evaluateAsAbsolute(Res))
1270 template <
unsigned Bits>
bool isUImm()
const {
1274 if (
getImm()->evaluateAsAbsolute(Res))
1280 template <
unsigned Bits>
bool isAnyImm()
const {
1281 return isConstantImm() ? (
isInt<Bits>(getConstantImm()) ||
1286 template <
unsigned Bits,
int Offset = 0>
bool isConstantSImm()
const {
1290 template <
unsigned Bottom,
unsigned Top>
bool isConstantUImmRange()
const {
1291 return isConstantImm() && getConstantImm() >= Bottom &&
1292 getConstantImm() <= Top;
1295 bool isToken()
const override {
1298 return Kind == k_Token;
1301 bool isMem()
const override {
return Kind == k_Memory; }
1303 bool isConstantMemOff()
const {
1308 template <
unsigned Bits,
unsigned ShiftAmount = 0>
1309 bool isMemWithSimmOffset()
const {
1312 if (!getMemBase()->isGPRAsmReg())
1315 (isConstantMemOff() &&
1319 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res,
nullptr);
1323 bool isMemWithPtrSizeOffset()
const {
1326 if (!getMemBase()->isGPRAsmReg())
1328 const unsigned PtrBits = AsmParser.getABI().ArePtrs64bit() ? 64 : 32;
1330 (isConstantMemOff() &&
isIntN(PtrBits, getConstantMemOff())))
1333 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res,
nullptr);
1337 bool isMemWithGRPMM16Base()
const {
1338 return isMem() && getMemBase()->isMM16AsmReg();
1341 template <
unsigned Bits>
bool isMemWithUimmOffsetSP()
const {
1343 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1346 template <
unsigned Bits>
bool isMemWithUimmWordAlignedOffsetSP()
const {
1348 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1349 && (getMemBase()->getGPR32Reg() == Mips::SP);
1352 template <
unsigned Bits>
bool isMemWithSimmWordAlignedOffsetGP()
const {
1354 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1355 && (getMemBase()->getGPR32Reg() == Mips::GP);
1358 template <
unsigned Bits,
unsigned ShiftLeftAmount>
1359 bool isScaledUImm()
const {
1360 return isConstantImm() &&
1364 template <
unsigned Bits,
unsigned ShiftLeftAmount>
1365 bool isScaledSImm()
const {
1366 if (isConstantImm() &&
1371 if (Kind != k_Immediate)
1374 bool Success =
getImm()->evaluateAsRelocatable(Res,
nullptr);
1378 bool isRegList16()
const {
1382 int Size = RegList.List->size();
1386 MCRegister R0 = RegList.List->front();
1387 MCRegister R1 = RegList.List->back();
1388 if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1389 (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1392 MCRegister PrevReg = RegList.List->front();
1393 for (
int i = 1; i <
Size - 1; i++) {
1394 MCRegister
Reg = (*(RegList.List))[i];
1395 if (
Reg != PrevReg + 1)
1403 bool isInvNum()
const {
return Kind == k_Immediate; }
1405 bool isLSAImm()
const {
1406 if (!isConstantImm())
1408 int64_t Val = getConstantImm();
1409 return 1 <= Val && Val <= 4;
1412 bool isRegList()
const {
return Kind == k_RegList; }
1415 assert(Kind == k_Token &&
"Invalid access!");
1416 return StringRef(Tok.Data, Tok.Length);
1419 MCRegister
getReg()
const override {
1422 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1423 RegIdx.Kind & RegKind_GPR)
1424 return getGPR32Reg();
1430 const MCExpr *
getImm()
const {
1431 assert((Kind == k_Immediate) &&
"Invalid access!");
1435 int64_t getConstantImm()
const {
1436 const MCExpr *Val =
getImm();
1438 (void)Val->evaluateAsAbsolute(
Value);
1442 MipsOperand *getMemBase()
const {
1443 assert((Kind == k_Memory) &&
"Invalid access!");
1447 const MCExpr *getMemOff()
const {
1448 assert((Kind == k_Memory) &&
"Invalid access!");
1452 int64_t getConstantMemOff()
const {
1453 return static_cast<const MCConstantExpr *
>(getMemOff())->
getValue();
1456 const SmallVectorImpl<MCRegister> &getRegList()
const {
1457 assert((Kind == k_RegList) &&
"Invalid access!");
1458 return *(RegList.List);
1461 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1462 MipsAsmParser &Parser) {
1463 auto Op = std::make_unique<MipsOperand>(k_Token, Parser);
1464 Op->Tok.Data = Str.data();
1465 Op->Tok.Length = Str.size();
1473 static std::unique_ptr<MipsOperand>
1474 createNumericReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1475 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1476 LLVM_DEBUG(
dbgs() <<
"createNumericReg(" << Index <<
", ...)\n");
1477 return CreateReg(Index, Str, RegKind_Numeric, RegInfo, S,
E, Parser);
1482 static std::unique_ptr<MipsOperand>
1483 createGPRReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1484 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1485 return CreateReg(Index, Str, RegKind_GPR, RegInfo, S,
E, Parser);
1490 static std::unique_ptr<MipsOperand>
1491 createFGRReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1492 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1493 return CreateReg(Index, Str, RegKind_FGR, RegInfo, S,
E, Parser);
1498 static std::unique_ptr<MipsOperand>
1499 createHWRegsReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1500 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1501 return CreateReg(Index, Str, RegKind_HWRegs, RegInfo, S,
E, Parser);
1506 static std::unique_ptr<MipsOperand>
1507 createFCCReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1508 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1509 return CreateReg(Index, Str, RegKind_FCC, RegInfo, S,
E, Parser);
1514 static std::unique_ptr<MipsOperand>
1515 createACCReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1516 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1517 return CreateReg(Index, Str, RegKind_ACC, RegInfo, S,
E, Parser);
1522 static std::unique_ptr<MipsOperand>
1523 createMSA128Reg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1524 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1525 return CreateReg(Index, Str, RegKind_MSA128, RegInfo, S,
E, Parser);
1530 static std::unique_ptr<MipsOperand>
1531 createMSACtrlReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1532 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1533 return CreateReg(Index, Str, RegKind_MSACtrl, RegInfo, S,
E, Parser);
1536 static std::unique_ptr<MipsOperand>
1537 CreateImm(
const MCExpr *Val, SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1538 auto Op = std::make_unique<MipsOperand>(k_Immediate, Parser);
1545 static std::unique_ptr<MipsOperand>
1546 CreateMem(std::unique_ptr<MipsOperand>
Base,
const MCExpr *
Off, SMLoc S,
1547 SMLoc
E, MipsAsmParser &Parser) {
1548 auto Op = std::make_unique<MipsOperand>(k_Memory, Parser);
1549 Op->Mem.Base =
Base.release();
1556 static std::unique_ptr<MipsOperand>
1557 CreateRegList(SmallVectorImpl<MCRegister> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1558 MipsAsmParser &Parser) {
1559 assert(!Regs.
empty() &&
"Empty list not allowed");
1561 auto Op = std::make_unique<MipsOperand>(k_RegList, Parser);
1564 Op->StartLoc = StartLoc;
1565 Op->EndLoc = EndLoc;
1569 bool isGPRZeroAsmReg()
const {
1570 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
1573 bool isGPRNonZeroAsmReg()
const {
1574 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index > 0 &&
1578 bool isGPRAsmReg()
const {
1579 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1582 bool isMM16AsmReg()
const {
1583 if (!(isRegIdx() && RegIdx.Kind))
1585 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1586 || RegIdx.Index == 16 || RegIdx.Index == 17);
1589 bool isMM16AsmRegZero()
const {
1590 if (!(isRegIdx() && RegIdx.Kind))
1592 return (RegIdx.Index == 0 ||
1593 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1594 RegIdx.Index == 17);
1597 bool isMM16AsmRegMoveP()
const {
1598 if (!(isRegIdx() && RegIdx.Kind))
1600 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1601 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1604 bool isMM16AsmRegMovePPairFirst()
const {
1605 if (!(isRegIdx() && RegIdx.Kind))
1607 return RegIdx.Index >= 4 && RegIdx.Index <= 6;
1610 bool isMM16AsmRegMovePPairSecond()
const {
1611 if (!(isRegIdx() && RegIdx.Kind))
1613 return (RegIdx.Index == 21 || RegIdx.Index == 22 ||
1614 (RegIdx.Index >= 5 && RegIdx.Index <= 7));
1617 bool isFGRAsmReg()
const {
1619 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1622 bool isStrictlyFGRAsmReg()
const {
1624 return isRegIdx() && RegIdx.Kind == RegKind_FGR && RegIdx.Index <= 31;
1627 bool isHWRegsAsmReg()
const {
1628 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1631 bool isCCRAsmReg()
const {
1632 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1635 bool isFCCAsmReg()
const {
1636 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1638 return RegIdx.Index <= 7;
1641 bool isACCAsmReg()
const {
1642 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1645 bool isCOP0AsmReg()
const {
1646 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1649 bool isCOP2AsmReg()
const {
1650 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1653 bool isCOP3AsmReg()
const {
1654 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1657 bool isMSA128AsmReg()
const {
1658 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1661 bool isMSACtrlAsmReg()
const {
1662 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1666 SMLoc getStartLoc()
const override {
return StartLoc; }
1668 SMLoc getEndLoc()
const override {
return EndLoc; }
1670 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1679 Mem.Base->print(OS, MAI);
1684 case k_RegisterIndex:
1685 OS <<
"RegIdx<" << RegIdx.Index <<
":" << RegIdx.Kind <<
", "
1686 << StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) <<
">";
1693 for (
auto Reg : (*RegList.List))
1694 OS <<
Reg.
id() <<
" ";
1700 bool isValidForTie(
const MipsOperand &
Other)
const {
1701 if (Kind !=
Other.Kind)
1708 case k_RegisterIndex: {
1709 StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length);
1710 StringRef OtherToken(
Other.RegIdx.Tok.Data,
Other.RegIdx.Tok.Length);
1711 return Token == OtherToken;
1727 case Mips::JRC16_MM:
1729 case Mips::JALRS_MM:
1730 case Mips::JALRS16_MM:
1731 case Mips::BGEZALS_MM:
1732 case Mips::BLTZALS_MM:
1743 return &SRExpr->getSymbol();
1802 unsigned NumOp =
MCID.getNumOperands();
1803 if (NumOp != 3 && NumOp != 4)
1833bool MipsAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
1836 MipsTargetStreamer &TOut = getTargetStreamer();
1837 const unsigned Opcode = Inst.
getOpcode();
1838 const MCInstrDesc &MCID = MII.get(Opcode);
1839 bool ExpandedJalSym =
false;
1853 assert(hasCnMips() &&
"instruction only valid for octeon cpus");
1864 if (!
isIntN(inMicroMipsMode() ? 17 : 18,
Offset.getImm()))
1865 return Error(IDLoc,
"branch target out of range");
1868 return Error(IDLoc,
"branch to misaligned address");
1882 case Mips::BGEZAL_MM:
1883 case Mips::BLTZAL_MM:
1886 case Mips::BC1EQZC_MMR6:
1887 case Mips::BC1NEZC_MMR6:
1888 case Mips::BC2EQZC_MMR6:
1889 case Mips::BC2NEZC_MMR6:
1894 if (!
isIntN(inMicroMipsMode() ? 17 : 18,
Offset.getImm()))
1895 return Error(IDLoc,
"branch target out of range");
1898 return Error(IDLoc,
"branch to misaligned address");
1900 case Mips::BGEC:
case Mips::BGEC_MMR6:
1901 case Mips::BLTC:
case Mips::BLTC_MMR6:
1902 case Mips::BGEUC:
case Mips::BGEUC_MMR6:
1903 case Mips::BLTUC:
case Mips::BLTUC_MMR6:
1904 case Mips::BEQC:
case Mips::BEQC_MMR6:
1905 case Mips::BNEC:
case Mips::BNEC_MMR6:
1911 return Error(IDLoc,
"branch target out of range");
1913 return Error(IDLoc,
"branch to misaligned address");
1915 case Mips::BLEZC:
case Mips::BLEZC_MMR6:
1916 case Mips::BGEZC:
case Mips::BGEZC_MMR6:
1917 case Mips::BGTZC:
case Mips::BGTZC_MMR6:
1918 case Mips::BLTZC:
case Mips::BLTZC_MMR6:
1924 return Error(IDLoc,
"branch target out of range");
1926 return Error(IDLoc,
"branch to misaligned address");
1928 case Mips::BEQZC:
case Mips::BEQZC_MMR6:
1929 case Mips::BNEZC:
case Mips::BNEZC_MMR6:
1935 return Error(IDLoc,
"branch target out of range");
1937 return Error(IDLoc,
"branch to misaligned address");
1939 case Mips::BEQZ16_MM:
1940 case Mips::BEQZC16_MMR6:
1941 case Mips::BNEZ16_MM:
1942 case Mips::BNEZC16_MMR6:
1948 return Error(IDLoc,
"branch target out of range");
1950 return Error(IDLoc,
"branch to misaligned address");
1957 if (hasMips32r6() && Opcode == Mips::SSNOP) {
1958 std::string
ISA = hasMips64r6() ?
"MIPS64r6" :
"MIPS32r6";
1959 Warning(IDLoc,
"ssnop is deprecated for " + ISA +
" and is equivalent to a "
1979 return Error(IDLoc,
"expected immediate operand kind");
1982 Opcode == Mips::BBIT1 ? 63 : 31))
1983 return Error(IDLoc,
"immediate operand value out of range");
1985 Inst.
setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1996 return Error(IDLoc,
"expected immediate operand kind");
1999 return Error(IDLoc,
"immediate operand value out of range");
2011 unsigned FirstOp = 1;
2012 unsigned SecondOp = 2;
2016 case Mips::SDivIMacro:
2017 case Mips::UDivIMacro:
2018 case Mips::DSDivIMacro:
2019 case Mips::DUDivIMacro:
2021 return Error(IDLoc,
"expected immediate operand kind");
2025 Warning(IDLoc,
"dividing zero by zero");
2027 Warning(IDLoc,
"division by zero");
2039 case Mips::SDivMacro:
2040 case Mips::DSDivMacro:
2041 case Mips::UDivMacro:
2042 case Mips::DUDivMacro:
2047 case Mips::DIVU_MMR6:
2048 case Mips::DIV_MMR6:
2053 Warning(IDLoc,
"dividing zero by zero");
2055 Warning(IDLoc,
"division by zero");
2061 if ((Opcode == Mips::J || Opcode == Mips::J_MM) && inPicMode()) {
2063 BInst.
setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
2072 if ((Opcode == Mips::JAL || Opcode == Mips::JAL_MM) && inPicMode()) {
2073 warnIfNoMacro(IDLoc);
2076 return Error(IDLoc,
"unsupported constant in relocation");
2084 return Error(IDLoc,
"jal doesn't support multiple symbols in PIC mode");
2090 if (expandLoadAddress(Mips::T9, MCRegister(), Inst.
getOperand(0),
2091 !isGP64bit(), IDLoc, Out, STI))
2095 if (inMicroMipsMode())
2096 JalrInst.
setOpcode(IsCpRestoreSet ? Mips::JALRS_MM : Mips::JALR_MM);
2102 if (isJalrRelocAvailable(JalExpr)) {
2108 const MCExpr *RelocJalrExpr =
2112 *TmpExpr, inMicroMipsMode() ?
"R_MICROMIPS_JALR" :
"R_MIPS_JALR",
2118 ExpandedJalSym =
true;
2127 expandMem9Inst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2130 expandMem16Inst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2133 return getParser().hasPendingError();
2137 if (inMicroMipsMode()) {
2138 if (MCID.
mayLoad() && Opcode != Mips::LWP_MM) {
2141 const MCOperandInfo &OpInfo = MCID.
operands()[i];
2146 int MemOffset =
Op.getImm();
2149 if (
isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
2152 (
BaseReg.getReg() == Mips::GP ||
2153 BaseReg.getReg() == Mips::GP_64)) {
2155 TOut.
emitRRI(Mips::LWGP_MM, DstReg.
getReg(), Mips::GP, MemOffset,
2172 case Mips::ADDIUSP_MM:
2175 return Error(IDLoc,
"expected immediate operand kind");
2179 return Error(IDLoc,
"immediate operand value out of range");
2181 case Mips::SLL16_MM:
2182 case Mips::SRL16_MM:
2185 return Error(IDLoc,
"expected immediate operand kind");
2188 return Error(IDLoc,
"immediate operand value out of range");
2193 return Error(IDLoc,
"expected immediate operand kind");
2196 return Error(IDLoc,
"immediate operand value out of range");
2198 case Mips::ADDIUR2_MM:
2201 return Error(IDLoc,
"expected immediate operand kind");
2203 if (!(
Imm == 1 ||
Imm == -1 ||
2205 return Error(IDLoc,
"immediate operand value out of range");
2207 case Mips::ANDI16_MM:
2210 return Error(IDLoc,
"expected immediate operand kind");
2214 Imm == 64 ||
Imm == 255 ||
Imm == 32768 ||
Imm == 65535))
2215 return Error(IDLoc,
"immediate operand value out of range");
2217 case Mips::LBU16_MM:
2220 return Error(IDLoc,
"expected immediate operand kind");
2223 return Error(IDLoc,
"immediate operand value out of range");
2226 case Mips::SB16_MMR6:
2229 return Error(IDLoc,
"expected immediate operand kind");
2232 return Error(IDLoc,
"immediate operand value out of range");
2234 case Mips::LHU16_MM:
2236 case Mips::SH16_MMR6:
2239 return Error(IDLoc,
"expected immediate operand kind");
2242 return Error(IDLoc,
"immediate operand value out of range");
2246 case Mips::SW16_MMR6:
2249 return Error(IDLoc,
"expected immediate operand kind");
2252 return Error(IDLoc,
"immediate operand value out of range");
2254 case Mips::ADDIUPC_MM:
2257 return Error(IDLoc,
"expected immediate operand kind");
2260 return Error(IDLoc,
"immediate operand value out of range");
2265 return Error(IDLoc,
"invalid operand for instruction");
2267 case Mips::MOVEP_MM:
2268 case Mips::MOVEP_MMR6: {
2271 bool RegPair = ((R0 == Mips::A1 && R1 == Mips::A2) ||
2272 (R0 == Mips::A1 && R1 == Mips::A3) ||
2273 (R0 == Mips::A2 && R1 == Mips::A3) ||
2274 (R0 == Mips::A0 && R1 == Mips::S5) ||
2275 (R0 == Mips::A0 && R1 == Mips::S6) ||
2276 (R0 == Mips::A0 && R1 == Mips::A1) ||
2277 (R0 == Mips::A0 && R1 == Mips::A2) ||
2278 (R0 == Mips::A0 && R1 == Mips::A3));
2280 return Error(IDLoc,
"invalid operand for instruction");
2286 bool FillDelaySlot =
2291 bool PrevForbiddenSlotAttr = CurForbiddenSlotAttr;
2294 bool SetReorderAfterNop =
false;
2299 if (PrevForbiddenSlotAttr && !SafeInForbiddenSlot(MCID)) {
2309 if (AssemblerOptions.
back()->isReorder() && !FillDelaySlot) {
2310 SetReorderAfterNop =
true;
2319 CurForbiddenSlotAttr =
2320 hasForbiddenSlot(MCID) && AssemblerOptions.
back()->isReorder();
2322 if (FillDelaySlot || CurForbiddenSlotAttr)
2325 MacroExpanderResultTy ExpandResult =
2326 tryExpandInstruction(Inst, IDLoc, Out, STI);
2327 switch (ExpandResult) {
2329 Out.emitInstruction(Inst, *STI);
2343 if (PrevForbiddenSlotAttr && !SetReorderAfterNop && !FillDelaySlot &&
2344 AssemblerOptions.
back()->isReorder()) {
2350 if (inMicroMipsMode()) {
2365 if (FillDelaySlot) {
2370 if ((Opcode == Mips::JalOneReg || Opcode == Mips::JalTwoReg ||
2372 isPicAndNotNxxAbi()) {
2373 if (IsCpRestoreSet) {
2377 if (!AssemblerOptions.
back()->isReorder())
2384 Warning(IDLoc,
"no .cprestore used in PIC mode");
2390void MipsAsmParser::onEndOfFile() {
2391 MipsTargetStreamer &TOut = getTargetStreamer();
2392 SMLoc IDLoc = SMLoc();
2394 if (CurForbiddenSlotAttr) {
2396 if (AssemblerOptions.
back()->isReorder())
2401MipsAsmParser::MacroExpanderResultTy
2402MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2403 const MCSubtargetInfo *STI) {
2406 return MER_NotAMacro;
2407 case Mips::LoadImm32:
2408 return expandLoadImm(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2409 case Mips::LoadImm64:
2410 return expandLoadImm(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2411 case Mips::LoadAddrImm32:
2412 case Mips::LoadAddrImm64:
2415 "expected immediate operand kind");
2417 return expandLoadAddress(
2419 Inst.
getOpcode() == Mips::LoadAddrImm32, IDLoc, Out, STI)
2422 case Mips::LoadAddrReg32:
2423 case Mips::LoadAddrReg64:
2427 "expected immediate operand kind");
2431 Inst.
getOpcode() == Mips::LoadAddrReg32, IDLoc,
2435 case Mips::B_MM_Pseudo:
2436 case Mips::B_MMR6_Pseudo:
2437 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2441 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2443 case Mips::JalOneReg:
2444 case Mips::JalTwoReg:
2445 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2448 case Mips::BEQLImmMacro:
2449 case Mips::BNELImmMacro:
2450 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2467 case Mips::BLTImmMacro:
2468 case Mips::BLEImmMacro:
2469 case Mips::BGEImmMacro:
2470 case Mips::BGTImmMacro:
2471 case Mips::BLTUImmMacro:
2472 case Mips::BLEUImmMacro:
2473 case Mips::BGEUImmMacro:
2474 case Mips::BGTUImmMacro:
2475 case Mips::BLTLImmMacro:
2476 case Mips::BLELImmMacro:
2477 case Mips::BGELImmMacro:
2478 case Mips::BGTLImmMacro:
2479 case Mips::BLTULImmMacro:
2480 case Mips::BLEULImmMacro:
2481 case Mips::BGEULImmMacro:
2482 case Mips::BGTULImmMacro:
2483 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2484 case Mips::SDivMacro:
2485 case Mips::SDivIMacro:
2486 case Mips::SRemMacro:
2487 case Mips::SRemIMacro:
2488 return expandDivRem(Inst, IDLoc, Out, STI,
false,
true) ? MER_Fail
2490 case Mips::DSDivMacro:
2491 case Mips::DSDivIMacro:
2492 case Mips::DSRemMacro:
2493 case Mips::DSRemIMacro:
2494 return expandDivRem(Inst, IDLoc, Out, STI,
true,
true) ? MER_Fail
2496 case Mips::UDivMacro:
2497 case Mips::UDivIMacro:
2498 case Mips::URemMacro:
2499 case Mips::URemIMacro:
2500 return expandDivRem(Inst, IDLoc, Out, STI,
false,
false) ? MER_Fail
2502 case Mips::DUDivMacro:
2503 case Mips::DUDivIMacro:
2504 case Mips::DURemMacro:
2505 case Mips::DURemIMacro:
2506 return expandDivRem(Inst, IDLoc, Out, STI,
true,
false) ? MER_Fail
2508 case Mips::PseudoTRUNC_W_S:
2509 return expandTrunc(Inst,
false,
false, IDLoc, Out, STI) ? MER_Fail
2511 case Mips::PseudoTRUNC_W_D32:
2512 return expandTrunc(Inst,
true,
false, IDLoc, Out, STI) ? MER_Fail
2514 case Mips::PseudoTRUNC_W_D:
2515 return expandTrunc(Inst,
true,
true, IDLoc, Out, STI) ? MER_Fail
2518 case Mips::LoadImmSingleGPR:
2519 return expandLoadSingleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2521 case Mips::LoadImmSingleFGR:
2522 return expandLoadSingleImmToFPR(Inst, IDLoc, Out, STI) ? MER_Fail
2524 case Mips::LoadImmDoubleGPR:
2525 return expandLoadDoubleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2527 case Mips::LoadImmDoubleFGR:
2528 return expandLoadDoubleImmToFPR(Inst,
true, IDLoc, Out, STI) ? MER_Fail
2530 case Mips::LoadImmDoubleFGR_32:
2531 return expandLoadDoubleImmToFPR(Inst,
false, IDLoc, Out, STI) ? MER_Fail
2535 return expandUlh(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2537 return expandUlh(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2539 return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2542 return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2544 case Mips::NORImm64:
2545 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2548 return expandSge(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2551 case Mips::SGEImm64:
2552 case Mips::SGEUImm64:
2553 return expandSgeImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2556 case Mips::SGTImm64:
2557 case Mips::SGTUImm64:
2558 return expandSgtImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2561 return expandSle(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2564 case Mips::SLEImm64:
2565 case Mips::SLEUImm64:
2566 return expandSleImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2567 case Mips::SLTImm64:
2570 return MER_NotAMacro;
2572 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2573 case Mips::SLTUImm64:
2576 return MER_NotAMacro;
2578 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2579 case Mips::ADDi:
case Mips::ADDi_MM:
2580 case Mips::ADDiu:
case Mips::ADDiu_MM:
2581 case Mips::SLTi:
case Mips::SLTi_MM:
2582 case Mips::SLTiu:
case Mips::SLTiu_MM:
2587 return MER_NotAMacro;
2588 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2591 return MER_NotAMacro;
2592 case Mips::ANDi:
case Mips::ANDi_MM:
case Mips::ANDi64:
2593 case Mips::ORi:
case Mips::ORi_MM:
case Mips::ORi64:
2594 case Mips::XORi:
case Mips::XORi_MM:
case Mips::XORi64:
2599 return MER_NotAMacro;
2600 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2603 return MER_NotAMacro;
2606 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2609 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2612 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2615 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2616 case Mips::ABSMacro:
2617 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2618 case Mips::MULImmMacro:
2619 case Mips::DMULImmMacro:
2620 return expandMulImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2621 case Mips::MULOMacro:
2622 case Mips::DMULOMacro:
2623 return expandMulO(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2624 case Mips::MULOUMacro:
2625 case Mips::DMULOUMacro:
2626 return expandMulOU(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2627 case Mips::DMULMacro:
2628 return expandDMULMacro(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2631 return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2636 return expandStoreDM1Macro(Inst, IDLoc, Out, STI)
2639 case Mips::SEQMacro:
2640 return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2641 case Mips::SEQIMacro:
2642 return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2643 case Mips::SNEMacro:
2644 return expandSne(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2645 case Mips::SNEIMacro:
2646 return expandSneI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2647 case Mips::MFTC0:
case Mips::MTTC0:
2648 case Mips::MFTGPR:
case Mips::MTTGPR:
2649 case Mips::MFTLO:
case Mips::MTTLO:
2650 case Mips::MFTHI:
case Mips::MTTHI:
2651 case Mips::MFTACX:
case Mips::MTTACX:
2652 case Mips::MFTDSP:
case Mips::MTTDSP:
2653 case Mips::MFTC1:
case Mips::MTTC1:
2654 case Mips::MFTHC1:
case Mips::MTTHC1:
2655 case Mips::CFTC1:
case Mips::CTTC1:
2656 return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2658 case Mips::SaadAddr:
2659 return expandSaaAddr(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2663bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2665 const MCSubtargetInfo *STI) {
2666 MipsTargetStreamer &TOut = getTargetStreamer();
2671 const MCOperand FirstRegOp = Inst.
getOperand(0);
2672 const unsigned Opcode = Inst.
getOpcode();
2674 if (Opcode == Mips::JalOneReg) {
2676 if (IsCpRestoreSet && inMicroMipsMode()) {
2679 }
else if (inMicroMipsMode()) {
2680 JalrInst.
setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2687 }
else if (Opcode == Mips::JalTwoReg) {
2689 if (IsCpRestoreSet && inMicroMipsMode())
2692 JalrInst.
setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2694 const MCOperand SecondRegOp = Inst.
getOperand(1);
2697 Out.emitInstruction(JalrInst, *STI);
2701 const MCInstrDesc &MCID = MII.get(JalrInst.
getOpcode());
2724bool MipsAsmParser::loadImmediate(int64_t ImmValue, MCRegister DstReg,
2725 MCRegister SrcReg,
bool Is32BitImm,
2726 bool IsAddress, SMLoc IDLoc, MCStreamer &Out,
2727 const MCSubtargetInfo *STI) {
2728 MipsTargetStreamer &TOut = getTargetStreamer();
2730 if (!Is32BitImm && !isGP64bit()) {
2731 Error(IDLoc,
"instruction requires a 64-bit architecture");
2742 Error(IDLoc,
"instruction requires a 32-bit immediate");
2747 MCRegister ZeroReg = IsAddress ?
ABI.GetNullPtr() :
ABI.GetZeroReg();
2748 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2750 bool UseSrcReg =
false;
2754 MCRegister TmpReg = DstReg;
2756 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2759 MCRegister ATReg = getATReg(IDLoc);
2772 if (IsAddress && !Is32BitImm) {
2773 TOut.
emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2777 TOut.
emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2782 MCRegister TmpReg = DstReg;
2783 if (SrcReg == DstReg) {
2784 TmpReg = getATReg(IDLoc);
2789 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2791 TOut.
emitRRR(
ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2796 warnIfNoMacro(IDLoc);
2798 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2799 uint16_t Bits15To0 = ImmValue & 0xffff;
2800 if (!Is32BitImm && !
isInt<32>(ImmValue)) {
2803 if (ImmValue == 0xffffffff) {
2804 TOut.
emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2805 TOut.
emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2807 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2813 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2814 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2816 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2818 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2822 TOut.
emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2824 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2826 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2832 Error(IDLoc,
"instruction requires a 32-bit immediate");
2839 assert(
BitWidth >= 17 &&
"ImmValue must be at least 17-bit wide");
2843 unsigned ShiftAmount =
BitWidth - 16;
2844 uint16_t
Bits = (ImmValue >> ShiftAmount) & 0xffff;
2845 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2846 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2849 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2854 warnIfNoMacro(IDLoc);
2861 if (loadImmediate(ImmValue >> 32, TmpReg, MCRegister(),
true,
false, IDLoc,
2867 unsigned ShiftCarriedForwards = 16;
2868 for (
int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2869 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2871 if (ImmChunk != 0) {
2872 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2873 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2874 ShiftCarriedForwards = 0;
2877 ShiftCarriedForwards += 16;
2879 ShiftCarriedForwards -= 16;
2882 if (ShiftCarriedForwards)
2883 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2886 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2891bool MipsAsmParser::expandLoadImm(MCInst &Inst,
bool Is32BitImm, SMLoc IDLoc,
2892 MCStreamer &Out,
const MCSubtargetInfo *STI) {
2894 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
2895 const MCOperand &DstRegOp = Inst.
getOperand(0);
2896 assert(DstRegOp.
isReg() &&
"expected register operand kind");
2898 if (loadImmediate(ImmOp.
getImm(), DstRegOp.
getReg(), MCRegister(), Is32BitImm,
2899 false, IDLoc, Out, STI))
2905bool MipsAsmParser::expandLoadAddress(MCRegister DstReg, MCRegister BaseReg,
2907 bool Is32BitAddress, SMLoc IDLoc,
2909 const MCSubtargetInfo *STI) {
2911 if (Is32BitAddress &&
ABI.ArePtrs64bit()) {
2912 Warning(IDLoc,
"la used to load 64-bit address");
2914 Is32BitAddress =
false;
2918 if (!Is32BitAddress && !hasMips3()) {
2919 Error(IDLoc,
"instruction requires a 64-bit architecture");
2924 return loadAndAddSymbolAddress(
Offset.getExpr(), DstReg, BaseReg,
2925 Is32BitAddress, IDLoc, Out, STI);
2927 if (!
ABI.ArePtrs64bit()) {
2929 Is32BitAddress =
true;
2932 return loadImmediate(
Offset.getImm(), DstReg, BaseReg, Is32BitAddress,
true,
2936bool MipsAsmParser::loadAndAddSymbolAddress(
const MCExpr *SymExpr,
2938 MCRegister SrcReg,
bool Is32BitSym,
2939 SMLoc IDLoc, MCStreamer &Out,
2940 const MCSubtargetInfo *STI) {
2941 MipsTargetStreamer &TOut = getTargetStreamer();
2943 SrcReg.
isValid() && SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64;
2944 warnIfNoMacro(IDLoc);
2949 Error(IDLoc,
"expected relocatable expression");
2953 Error(IDLoc,
"expected relocatable expression with only one symbol");
2957 bool IsPtr64 =
ABI.ArePtrs64bit();
2960 ?
static_cast<const MCSymbolELF *
>(Res.
getAddSym())
2968 bool UseXGOT = STI->
hasFeature(Mips::FeatureXGOT) && !IsLocalSym;
2974 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2977 const MCExpr *CallHiExpr =
2979 const MCExpr *CallLoExpr =
2983 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, DstReg, GPReg,
2985 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, DstReg,
2988 const MCExpr *CallExpr =
2990 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, GPReg,
2996 MCRegister TmpReg = DstReg;
2998 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
3002 MCRegister ATReg = getATReg(IDLoc);
3021 const MCExpr *CallHiExpr =
3028 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg, GPReg,
3030 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, TmpReg,
3034 TOut.
emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3040 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3045 const MCSpecifierExpr *GotExpr =
nullptr;
3046 const MCExpr *LoExpr =
nullptr;
3047 if (
ABI.IsN32() ||
ABI.IsN64()) {
3066 Error(IDLoc,
"macro instruction uses large offset, which is not "
3067 "currently supported");
3096 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, GPReg,
3100 TOut.
emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3104 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3110 const auto *HiExpr =
3112 const auto *LoExpr =
3116 if (
ABI.ArePtrs64bit() && isGP64bit()) {
3124 const auto *HighestExpr =
3126 const auto *HigherExpr =
3131 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
3133 if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
3134 MCRegister ATReg = getATReg(IDLoc);
3146 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3148 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3151 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3154 TOut.
emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
3157 }
else if (canUseATReg() && !RdRegIsRsReg && DstReg != getATReg(IDLoc)) {
3158 MCRegister ATReg = getATReg(IDLoc);
3174 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3178 TOut.
emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3179 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3181 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3184 }
else if ((!canUseATReg() && !RdRegIsRsReg) ||
3185 (canUseATReg() && DstReg == getATReg(IDLoc))) {
3196 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3198 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3199 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3201 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3202 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3205 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3211 assert(SrcReg == DstReg && !canUseATReg() &&
3212 "Could have expanded dla but didn't?");
3213 reportParseError(IDLoc,
3214 "pseudo-instruction requires $at, which is not available");
3228 MCRegister TmpReg = DstReg;
3230 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
3233 MCRegister ATReg = getATReg(IDLoc);
3244 TOut.
emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3247 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
3256 if (getMipsMCRegisterClass(Mips::FGR32RegClassID).
contains(
Reg))
3257 return Reg == (
unsigned)Mips::F31 ? (
unsigned)Mips::F0 :
Reg + 1;
3259 default:
llvm_unreachable(
"Unknown register in assembly macro expansion!");
3260 case Mips::ZERO:
return Mips::AT;
3261 case Mips::AT:
return Mips::V0;
3262 case Mips::V0:
return Mips::V1;
3263 case Mips::V1:
return Mips::A0;
3264 case Mips::A0:
return Mips::A1;
3265 case Mips::A1:
return Mips::A2;
3266 case Mips::A2:
return Mips::A3;
3267 case Mips::A3:
return Mips::T0;
3268 case Mips::T0:
return Mips::T1;
3269 case Mips::T1:
return Mips::T2;
3270 case Mips::T2:
return Mips::T3;
3271 case Mips::T3:
return Mips::T4;
3272 case Mips::T4:
return Mips::T5;
3273 case Mips::T5:
return Mips::T6;
3274 case Mips::T6:
return Mips::T7;
3275 case Mips::T7:
return Mips::S0;
3276 case Mips::S0:
return Mips::S1;
3277 case Mips::S1:
return Mips::S2;
3278 case Mips::S2:
return Mips::S3;
3279 case Mips::S3:
return Mips::S4;
3280 case Mips::S4:
return Mips::S5;
3281 case Mips::S5:
return Mips::S6;
3282 case Mips::S6:
return Mips::S7;
3283 case Mips::S7:
return Mips::T8;
3284 case Mips::T8:
return Mips::T9;
3285 case Mips::T9:
return Mips::K0;
3286 case Mips::K0:
return Mips::K1;
3287 case Mips::K1:
return Mips::GP;
3288 case Mips::GP:
return Mips::SP;
3289 case Mips::SP:
return Mips::FP;
3290 case Mips::FP:
return Mips::RA;
3291 case Mips::RA:
return Mips::ZERO;
3292 case Mips::D0:
return Mips::F1;
3293 case Mips::D1:
return Mips::F3;
3294 case Mips::D2:
return Mips::F5;
3295 case Mips::D3:
return Mips::F7;
3296 case Mips::D4:
return Mips::F9;
3297 case Mips::D5:
return Mips::F11;
3298 case Mips::D6:
return Mips::F13;
3299 case Mips::D7:
return Mips::F15;
3300 case Mips::D8:
return Mips::F17;
3301 case Mips::D9:
return Mips::F19;
3302 case Mips::D10:
return Mips::F21;
3303 case Mips::D11:
return Mips::F23;
3304 case Mips::D12:
return Mips::F25;
3305 case Mips::D13:
return Mips::F27;
3306 case Mips::D14:
return Mips::F29;
3307 case Mips::D15:
return Mips::F31;
3317bool MipsAsmParser::emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc,
3319 MCRegister ATReg = getATReg(IDLoc);
3325 const auto *GotExpr =
3328 if(isABI_O32() || isABI_N32()) {
3337 const auto *HiExpr =
3346 if(isABI_O32() || isABI_N32()) {
3350 const auto *HighestExpr =
3353 const auto *HigherExpr =
3358 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3360 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3363 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3372 if ((
Hi_32(ImmOp64) & 0x7ff00000) == 0) {
3383 float TmpFloat =
static_cast<float>(DoubleImm);
3387bool MipsAsmParser::expandLoadSingleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3389 const MCSubtargetInfo *STI) {
3392 "Invalid instruction operand.");
3399 return loadImmediate(ImmOp32, FirstReg, MCRegister(),
true,
false, IDLoc, Out,
3403bool MipsAsmParser::expandLoadSingleImmToFPR(MCInst &Inst, SMLoc IDLoc,
3405 const MCSubtargetInfo *STI) {
3406 MipsTargetStreamer &TOut = getTargetStreamer();
3409 "Invalid instruction operand.");
3418 MCRegister TmpReg = Mips::ZERO;
3420 TmpReg = getATReg(IDLoc);
3425 if (
Lo_32(ImmOp64) == 0) {
3426 if (TmpReg != Mips::ZERO && loadImmediate(ImmOp32, TmpReg, MCRegister(),
3427 true,
false, IDLoc, Out, STI))
3429 TOut.
emitRR(Mips::MTC1, FirstReg, TmpReg, IDLoc, STI);
3433 MCSection *CS = getStreamer().getCurrentSectionOnly();
3436 MCSection *ReadOnlySection =
3443 getStreamer().switchSection(ReadOnlySection);
3444 getStreamer().emitLabel(Sym, IDLoc);
3445 getStreamer().emitInt32(ImmOp32);
3446 getStreamer().switchSection(CS);
3448 if (emitPartialAddress(TOut, IDLoc, Sym))
3455bool MipsAsmParser::expandLoadDoubleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3457 const MCSubtargetInfo *STI) {
3458 MipsTargetStreamer &TOut = getTargetStreamer();
3461 "Invalid instruction operand.");
3468 if (
Lo_32(ImmOp64) == 0) {
3470 if (loadImmediate(ImmOp64, FirstReg, MCRegister(),
false,
false, IDLoc,
3474 if (loadImmediate(
Hi_32(ImmOp64), FirstReg, MCRegister(),
true,
false,
3478 if (loadImmediate(0,
nextReg(FirstReg), MCRegister(),
true,
false, IDLoc,
3485 MCSection *CS = getStreamer().getCurrentSectionOnly();
3486 MCSection *ReadOnlySection =
3493 getStreamer().switchSection(ReadOnlySection);
3494 getStreamer().emitLabel(Sym, IDLoc);
3495 getStreamer().emitValueToAlignment(
Align(8));
3496 getStreamer().emitIntValue(ImmOp64, 8);
3497 getStreamer().switchSection(CS);
3499 MCRegister TmpReg = getATReg(IDLoc);
3503 if (emitPartialAddress(TOut, IDLoc, Sym))
3506 TOut.
emitRRX(isABI_N64() ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3510 TOut.
emitRRI(Mips::LD, FirstReg, TmpReg, 0, IDLoc, STI);
3512 TOut.
emitRRI(Mips::LW, FirstReg, TmpReg, 0, IDLoc, STI);
3513 TOut.
emitRRI(Mips::LW,
nextReg(FirstReg), TmpReg, 4, IDLoc, STI);
3518bool MipsAsmParser::expandLoadDoubleImmToFPR(MCInst &Inst,
bool Is64FPU,
3519 SMLoc IDLoc, MCStreamer &Out,
3520 const MCSubtargetInfo *STI) {
3521 MipsTargetStreamer &TOut = getTargetStreamer();
3524 "Invalid instruction operand.");
3531 MCRegister TmpReg = Mips::ZERO;
3533 TmpReg = getATReg(IDLoc);
3538 if ((
Lo_32(ImmOp64) == 0) &&
3539 !((
Hi_32(ImmOp64) & 0xffff0000) && (
Hi_32(ImmOp64) & 0x0000ffff))) {
3541 if (TmpReg != Mips::ZERO && loadImmediate(ImmOp64, TmpReg, MCRegister(),
3542 false,
false, IDLoc, Out, STI))
3544 TOut.
emitRR(Mips::DMTC1, FirstReg, TmpReg, IDLoc, STI);
3548 if (TmpReg != Mips::ZERO &&
3549 loadImmediate(
Hi_32(ImmOp64), TmpReg, MCRegister(),
true,
false, IDLoc,
3553 if (hasMips32r2()) {
3554 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3555 TOut.
emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, TmpReg, IDLoc, STI);
3557 TOut.
emitRR(Mips::MTC1,
nextReg(FirstReg), TmpReg, IDLoc, STI);
3558 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3563 MCSection *CS = getStreamer().getCurrentSectionOnly();
3566 MCSection *ReadOnlySection =
3573 getStreamer().switchSection(ReadOnlySection);
3574 getStreamer().emitLabel(Sym, IDLoc);
3575 getStreamer().emitValueToAlignment(
Align(8));
3576 getStreamer().emitIntValue(ImmOp64, 8);
3577 getStreamer().switchSection(CS);
3579 if (emitPartialAddress(TOut, IDLoc, Sym))
3582 TOut.
emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, TmpReg,
3588bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
3590 const MCSubtargetInfo *STI) {
3591 MipsTargetStreamer &TOut = getTargetStreamer();
3594 "unexpected number of operands");
3604 assert(
Offset.isImm() &&
"expected immediate operand kind");
3608 if (inMicroMipsMode())
3609 Inst.
setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3612 return Error(IDLoc,
"branch target out of range");
3614 return Error(IDLoc,
"branch to misaligned address");
3622 Out.emitInstruction(Inst, *STI);
3626 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
3633bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3634 const MCSubtargetInfo *STI) {
3635 MipsTargetStreamer &TOut = getTargetStreamer();
3636 const MCOperand &DstRegOp = Inst.
getOperand(0);
3637 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3640 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
3642 const MCOperand &MemOffsetOp = Inst.
getOperand(2);
3644 "expected immediate or expression operand");
3646 bool IsLikely =
false;
3656 case Mips::BEQLImmMacro:
3660 case Mips::BNELImmMacro:
3669 int64_t ImmValue = ImmOp.
getImm();
3670 if (ImmValue == 0) {
3674 TOut.
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3676 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3679 warnIfNoMacro(IDLoc);
3681 MCRegister ATReg = getATReg(IDLoc);
3685 if (loadImmediate(ImmValue, ATReg, MCRegister(), !isGP64bit(),
true, IDLoc,
3689 if (IsLikely && MemOffsetOp.
isExpr()) {
3692 TOut.
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3694 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3699void MipsAsmParser::expandMem16Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3700 const MCSubtargetInfo *STI,
bool IsLoad) {
3702 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3703 unsigned StartOp = NumOp == 3 ? 0 : 1;
3705 const MCOperand &DstRegOp = Inst.
getOperand(StartOp);
3706 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3707 const MCOperand &BaseRegOp = Inst.
getOperand(StartOp + 1);
3708 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3711 MipsTargetStreamer &TOut = getTargetStreamer();
3713 MCRegister DstReg = DstRegOp.
getReg();
3715 MCRegister TmpReg = DstReg;
3717 const MCInstrDesc &
Desc = MII.get(OpCode);
3718 int16_t DstRegClass =
3719 MII.getOpRegClassID(
Desc.operands()[StartOp],
3721 unsigned DstRegClassID =
3722 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3723 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3724 (DstRegClassID == Mips::GPR64RegClassID);
3726 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3729 TmpReg = getATReg(IDLoc);
3734 auto emitInstWithOffset = [&](
const MCOperand &
Off) {
3736 TOut.
emitRRX(OpCode, DstReg, TmpReg,
Off, IDLoc, STI);
3738 TOut.
emitRRRX(OpCode, DstReg, DstReg, TmpReg,
Off, IDLoc, STI);
3742 int64_t LoOffset =
OffsetOp.getImm() & 0xffff;
3743 int64_t HiOffset =
OffsetOp.getImm() & ~0xffff;
3747 if (LoOffset & 0x8000)
3748 HiOffset += 0x10000;
3750 bool IsLargeOffset = HiOffset != 0;
3752 if (IsLargeOffset) {
3754 if (loadImmediate(HiOffset, TmpReg, MCRegister(), Is32BitImm,
true, IDLoc,
3759 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3760 TOut.
emitRRR(
ABI.ArePtrs64bit() ? Mips::DADDu : Mips::ADDu, TmpReg,
3761 TmpReg, BaseReg, IDLoc, STI);
3775 if (!
OffsetOp.getExpr()->evaluateAsRelocatable(Res,
nullptr)) {
3776 Error(IDLoc,
"expected relocatable expression");
3780 Error(IDLoc,
"expected relocatable expression with only one symbol");
3784 loadAndAddSymbolAddress(
3786 BaseReg, !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3794 const MCExpr *OffExpr =
OffsetOp.getExpr();
3806 TOut.
emitRX(Mips::LUi, TmpReg, HighestOperand, IDLoc, STI);
3807 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HigherOperand, IDLoc, STI);
3808 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3809 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HiOperand, IDLoc, STI);
3810 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3811 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3812 TOut.
emitRRR(Mips::DADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3813 emitInstWithOffset(LoOperand);
3816 TOut.
emitRX(Mips::LUi, TmpReg, HiOperand, IDLoc, STI);
3817 if (BaseReg != Mips::ZERO)
3818 TOut.
emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3820 emitInstWithOffset(LoOperand);
3829void MipsAsmParser::expandMem9Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3830 const MCSubtargetInfo *STI,
bool IsLoad) {
3832 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3833 unsigned StartOp = NumOp == 3 ? 0 : 1;
3835 const MCOperand &DstRegOp = Inst.
getOperand(StartOp);
3836 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3837 const MCOperand &BaseRegOp = Inst.
getOperand(StartOp + 1);
3838 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3841 MipsTargetStreamer &TOut = getTargetStreamer();
3843 MCRegister DstReg = DstRegOp.
getReg();
3845 MCRegister TmpReg = DstReg;
3847 const MCInstrDesc &
Desc = MII.get(OpCode);
3848 int16_t DstRegClass =
3849 MII.getOpRegClassID(
Desc.operands()[StartOp],
3852 unsigned DstRegClassID =
3853 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3854 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3855 (DstRegClassID == Mips::GPR64RegClassID);
3857 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3860 TmpReg = getATReg(IDLoc);
3865 auto emitInst = [&]() {
3874 loadImmediate(
OffsetOp.getImm(), TmpReg, BaseReg, !
ABI.ArePtrs64bit(),
true,
3881 loadAndAddSymbolAddress(
OffsetOp.getExpr(), TmpReg, BaseReg,
3882 !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3890bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
3892 const MCSubtargetInfo *STI) {
3895 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3899 Inst.
getOperand(OpNum - 3).
isReg() &&
"Invalid instruction operand.");
3908 if (inMicroMipsMode() && hasMips32r6())
3909 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3911 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3915 Out.emitInstruction(Inst, *STI);
3919bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
3921 const MCSubtargetInfo *STI) {
3922 MipsTargetStreamer &TOut = getTargetStreamer();
3923 bool EmittedNoMacroWarning =
false;
3924 unsigned PseudoOpcode = Inst.
getOpcode();
3929 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3930 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3935 else if (TrgOp.
isImm()) {
3936 warnIfNoMacro(IDLoc);
3937 EmittedNoMacroWarning =
true;
3939 TrgReg = getATReg(IDLoc);
3943 switch(PseudoOpcode) {
3946 case Mips::BLTImmMacro:
3947 PseudoOpcode = Mips::BLT;
3949 case Mips::BLEImmMacro:
3950 PseudoOpcode = Mips::BLE;
3952 case Mips::BGEImmMacro:
3953 PseudoOpcode = Mips::BGE;
3955 case Mips::BGTImmMacro:
3956 PseudoOpcode = Mips::BGT;
3958 case Mips::BLTUImmMacro:
3959 PseudoOpcode = Mips::BLTU;
3961 case Mips::BLEUImmMacro:
3962 PseudoOpcode = Mips::BLEU;
3964 case Mips::BGEUImmMacro:
3965 PseudoOpcode = Mips::BGEU;
3967 case Mips::BGTUImmMacro:
3968 PseudoOpcode = Mips::BGTU;
3970 case Mips::BLTLImmMacro:
3971 PseudoOpcode = Mips::BLTL;
3973 case Mips::BLELImmMacro:
3974 PseudoOpcode = Mips::BLEL;
3976 case Mips::BGELImmMacro:
3977 PseudoOpcode = Mips::BGEL;
3979 case Mips::BGTLImmMacro:
3980 PseudoOpcode = Mips::BGTL;
3982 case Mips::BLTULImmMacro:
3983 PseudoOpcode = Mips::BLTUL;
3985 case Mips::BLEULImmMacro:
3986 PseudoOpcode = Mips::BLEUL;
3988 case Mips::BGEULImmMacro:
3989 PseudoOpcode = Mips::BGEUL;
3991 case Mips::BGTULImmMacro:
3992 PseudoOpcode = Mips::BGTUL;
3996 if (loadImmediate(TrgOp.
getImm(), TrgReg, MCRegister(), !isGP64bit(),
false,
4001 switch (PseudoOpcode) {
4006 AcceptsEquality =
false;
4007 ReverseOrderSLT =
false;
4009 ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
4010 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
4011 ZeroSrcOpcode = Mips::BGTZ;
4012 ZeroTrgOpcode = Mips::BLTZ;
4018 AcceptsEquality =
true;
4019 ReverseOrderSLT =
true;
4021 ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
4022 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
4023 ZeroSrcOpcode = Mips::BGEZ;
4024 ZeroTrgOpcode = Mips::BLEZ;
4030 AcceptsEquality =
true;
4031 ReverseOrderSLT =
false;
4033 ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
4034 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
4035 ZeroSrcOpcode = Mips::BLEZ;
4036 ZeroTrgOpcode = Mips::BGEZ;
4042 AcceptsEquality =
false;
4043 ReverseOrderSLT =
true;
4045 ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
4046 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
4047 ZeroSrcOpcode = Mips::BLTZ;
4048 ZeroTrgOpcode = Mips::BGTZ;
4054 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
4055 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
4056 if (IsSrcRegZero && IsTrgRegZero) {
4060 if (PseudoOpcode == Mips::BLT) {
4065 if (PseudoOpcode == Mips::BLE) {
4068 Warning(IDLoc,
"branch is always taken");
4071 if (PseudoOpcode == Mips::BGE) {
4074 Warning(IDLoc,
"branch is always taken");
4077 if (PseudoOpcode == Mips::BGT) {
4082 if (PseudoOpcode == Mips::BGTU) {
4083 TOut.
emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
4087 if (AcceptsEquality) {
4090 TOut.
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4092 Warning(IDLoc,
"branch is always taken");
4099 if (IsSrcRegZero || IsTrgRegZero) {
4100 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
4101 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
4108 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
4109 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
4115 TOut.
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4117 Warning(IDLoc,
"branch is always taken");
4133 TOut.
emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
4134 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
4141 TOut.
emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
4142 IsSrcRegZero ? TrgReg : SrcReg,
4149 MCRegister ATRegNum = getATReg(IDLoc);
4153 if (!EmittedNoMacroWarning)
4154 warnIfNoMacro(IDLoc);
4171 TOut.
emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
4172 ReverseOrderSLT ? TrgReg : SrcReg,
4173 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
4175 TOut.
emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
4176 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
4190bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4191 const MCSubtargetInfo *STI,
4192 const bool IsMips64,
const bool Signed) {
4193 MipsTargetStreamer &TOut = getTargetStreamer();
4195 warnIfNoMacro(IDLoc);
4197 const MCOperand &RdRegOp = Inst.
getOperand(0);
4198 assert(RdRegOp.
isReg() &&
"expected register operand kind");
4199 MCRegister RdReg = RdRegOp.
getReg();
4201 const MCOperand &RsRegOp = Inst.
getOperand(1);
4202 assert(RsRegOp.
isReg() &&
"expected register operand kind");
4203 MCRegister RsReg = RsRegOp.
getReg();
4210 "expected register or immediate operand kind");
4214 ImmValue = RtOp.
getImm();
4221 DivOp =
Signed ? Mips::DSDIV : Mips::DUDIV;
4222 ZeroReg = Mips::ZERO_64;
4225 DivOp =
Signed ? Mips::SDIV : Mips::UDIV;
4226 ZeroReg = Mips::ZERO;
4230 bool UseTraps = useTraps();
4233 bool isDiv = Opcode == Mips::SDivMacro || Opcode == Mips::SDivIMacro ||
4234 Opcode == Mips::UDivMacro || Opcode == Mips::UDivIMacro ||
4235 Opcode == Mips::DSDivMacro || Opcode == Mips::DSDivIMacro ||
4236 Opcode == Mips::DUDivMacro || Opcode == Mips::DUDivIMacro;
4238 bool isRem = Opcode == Mips::SRemMacro || Opcode == Mips::SRemIMacro ||
4239 Opcode == Mips::URemMacro || Opcode == Mips::URemIMacro ||
4240 Opcode == Mips::DSRemMacro || Opcode == Mips::DSRemIMacro ||
4241 Opcode == Mips::DURemMacro || Opcode == Mips::DURemIMacro;
4244 MCRegister ATReg = getATReg(IDLoc);
4250 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4252 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4256 if (isRem && (ImmValue == 1 || (
Signed && (ImmValue == -1)))) {
4257 TOut.
emitRRR(Mips::OR, RdReg, ZeroReg, ZeroReg, IDLoc, STI);
4259 }
else if (isDiv && ImmValue == 1) {
4260 TOut.
emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI);
4262 }
else if (isDiv &&
Signed && ImmValue == -1) {
4263 TOut.
emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
4266 if (loadImmediate(ImmValue, ATReg, MCRegister(),
isInt<32>(ImmValue),
4267 false, Inst.
getLoc(), Out, STI))
4269 TOut.
emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
4270 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4280 if (!
NoZeroDivCheck && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
4282 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4285 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4291 if (isRem && (RdReg == Mips::ZERO || RdReg == Mips::ZERO_64)) {
4292 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4301 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4304 TOut.
emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4307 BrTarget =
Context.createTempSymbol();
4310 TOut.
emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4315 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4321 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4325bool MipsAsmParser::expandTrunc(MCInst &Inst,
bool IsDouble,
bool Is64FPU,
4326 SMLoc IDLoc, MCStreamer &Out,
4327 const MCSubtargetInfo *STI) {
4328 MipsTargetStreamer &TOut = getTargetStreamer();
4338 if (hasMips1() && !hasMips2()) {
4339 MCRegister ATReg = getATReg(IDLoc);
4342 TOut.
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4343 TOut.
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4345 TOut.
emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4346 TOut.
emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4347 TOut.
emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4349 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4351 FirstReg, SecondReg, IDLoc, STI);
4352 TOut.
emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4357 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4359 FirstReg, SecondReg, IDLoc, STI);
4364bool MipsAsmParser::expandUlh(MCInst &Inst,
bool Signed, SMLoc IDLoc,
4365 MCStreamer &Out,
const MCSubtargetInfo *STI) {
4366 if (hasMips32r6() || hasMips64r6()) {
4367 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4370 const MCOperand &DstRegOp = Inst.
getOperand(0);
4371 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4372 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4373 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4374 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4375 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4377 MipsTargetStreamer &TOut = getTargetStreamer();
4378 MCRegister DstReg = DstRegOp.
getReg();
4379 MCRegister SrcReg = SrcRegOp.
getReg();
4380 int64_t OffsetValue = OffsetImmOp.
getImm();
4384 warnIfNoMacro(IDLoc);
4385 MCRegister ATReg = getATReg(IDLoc);
4390 if (IsLargeOffset) {
4391 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4396 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4397 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4401 MCRegister FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4402 MCRegister SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4404 MCRegister LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4405 MCRegister SllReg = IsLargeOffset ? DstReg : ATReg;
4407 TOut.
emitRRI(
Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4408 FirstOffset, IDLoc, STI);
4409 TOut.
emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4410 TOut.
emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4411 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4416bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4417 const MCSubtargetInfo *STI) {
4418 if (hasMips32r6() || hasMips64r6()) {
4419 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4422 const MCOperand &DstRegOp = Inst.
getOperand(0);
4423 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4424 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4425 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4426 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4427 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4429 MipsTargetStreamer &TOut = getTargetStreamer();
4430 MCRegister DstReg = DstRegOp.
getReg();
4431 MCRegister SrcReg = SrcRegOp.
getReg();
4432 int64_t OffsetValue = OffsetImmOp.
getImm();
4434 warnIfNoMacro(IDLoc);
4435 MCRegister ATReg = getATReg(IDLoc);
4440 if (IsLargeOffset) {
4441 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4446 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4447 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4451 if (IsLargeOffset) {
4452 TOut.
emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4453 TOut.
emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4454 TOut.
emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4455 TOut.
emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4456 TOut.
emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4457 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4459 TOut.
emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4460 TOut.
emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4461 TOut.
emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4467bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4468 const MCSubtargetInfo *STI) {
4469 if (hasMips32r6() || hasMips64r6()) {
4470 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4473 const MCOperand &DstRegOp = Inst.
getOperand(0);
4474 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4475 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4476 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4477 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4478 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4480 MipsTargetStreamer &TOut = getTargetStreamer();
4481 MCRegister DstReg = DstRegOp.
getReg();
4482 MCRegister SrcReg = SrcRegOp.
getReg();
4483 int64_t OffsetValue = OffsetImmOp.
getImm();
4487 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4488 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4492 bool IsLoadInst = (Inst.
getOpcode() == Mips::Ulw);
4493 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4494 MCRegister TmpReg = SrcReg;
4495 if (IsLargeOffset || DoMove) {
4496 warnIfNoMacro(IDLoc);
4497 TmpReg = getATReg(IDLoc);
4502 if (IsLargeOffset) {
4503 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4511 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4512 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4513 TOut.
emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4514 TOut.
emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4517 TOut.
emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4522bool MipsAsmParser::expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4523 const MCSubtargetInfo *STI) {
4524 MipsTargetStreamer &TOut = getTargetStreamer();
4536 warnIfNoMacro(IDLoc);
4550 TOut.
emitRRR(OpCode, DstReg, SrcReg, OpReg, IDLoc, STI);
4551 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4556bool MipsAsmParser::expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4557 const MCSubtargetInfo *STI) {
4558 MipsTargetStreamer &TOut = getTargetStreamer();
4568 unsigned OpRegCode, OpImmCode;
4570 warnIfNoMacro(IDLoc);
4574 case Mips::SGEImm64:
4575 OpRegCode = Mips::SLT;
4576 OpImmCode = Mips::SLTi;
4579 case Mips::SGEUImm64:
4580 OpRegCode = Mips::SLTu;
4581 OpImmCode = Mips::SLTiu;
4590 TOut.
emitRRI(OpImmCode, DstReg, SrcReg, ImmValue, IDLoc, STI);
4591 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4593 MCRegister ImmReg = DstReg;
4594 if (DstReg == SrcReg) {
4595 MCRegister ATReg = getATReg(Inst.
getLoc());
4601 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
4602 false, IDLoc, Out, STI))
4605 TOut.
emitRRR(OpRegCode, DstReg, SrcReg, ImmReg, IDLoc, STI);
4606 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4612bool MipsAsmParser::expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4613 const MCSubtargetInfo *STI) {
4614 MipsTargetStreamer &TOut = getTargetStreamer();
4623 MCRegister ImmReg = DstReg;
4627 warnIfNoMacro(IDLoc);
4631 case Mips::SGTImm64:
4635 case Mips::SGTUImm64:
4642 if (DstReg == SrcReg) {
4643 MCRegister ATReg = getATReg(Inst.
getLoc());
4649 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
false,
4654 TOut.
emitRRR(OpCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4659bool MipsAsmParser::expandSle(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4660 const MCSubtargetInfo *STI) {
4661 MipsTargetStreamer &TOut = getTargetStreamer();
4673 warnIfNoMacro(IDLoc);
4687 TOut.
emitRRR(OpCode, DstReg, OpReg, SrcReg, IDLoc, STI);
4688 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4693bool MipsAsmParser::expandSleImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4694 const MCSubtargetInfo *STI) {
4695 MipsTargetStreamer &TOut = getTargetStreamer();
4707 warnIfNoMacro(IDLoc);
4711 case Mips::SLEImm64:
4712 OpRegCode = Mips::SLT;
4715 case Mips::SLEUImm64:
4716 OpRegCode = Mips::SLTu;
4723 MCRegister ImmReg = DstReg;
4724 if (DstReg == SrcReg) {
4725 MCRegister ATReg = getATReg(Inst.
getLoc());
4731 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
false,
4735 TOut.
emitRRR(OpRegCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4736 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4741bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
4743 const MCSubtargetInfo *STI) {
4744 MipsTargetStreamer &TOut = getTargetStreamer();
4752 MCRegister FinalDstReg;
4759 unsigned FinalOpcode = Inst.
getOpcode();
4761 if (DstReg == SrcReg) {
4762 ATReg = getATReg(Inst.
getLoc());
4765 FinalDstReg = DstReg;
4769 if (!loadImmediate(ImmValue, DstReg, MCRegister(), Is32Bit,
false,
4770 Inst.
getLoc(), Out, STI)) {
4771 switch (FinalOpcode) {
4775 FinalOpcode = Mips::ADD;
4778 FinalOpcode = Mips::ADDu;
4781 FinalOpcode = Mips::AND;
4784 FinalOpcode = Mips::NOR;
4787 FinalOpcode = Mips::OR;
4790 FinalOpcode = Mips::SLT;
4793 FinalOpcode = Mips::SLTu;
4796 FinalOpcode = Mips::XOR;
4799 FinalOpcode = Mips::ADD_MM;
4801 case Mips::ADDiu_MM:
4802 FinalOpcode = Mips::ADDu_MM;
4805 FinalOpcode = Mips::AND_MM;
4808 FinalOpcode = Mips::OR_MM;
4811 FinalOpcode = Mips::SLT_MM;
4813 case Mips::SLTiu_MM:
4814 FinalOpcode = Mips::SLTu_MM;
4817 FinalOpcode = Mips::XOR_MM;
4820 FinalOpcode = Mips::AND64;
4822 case Mips::NORImm64:
4823 FinalOpcode = Mips::NOR64;
4826 FinalOpcode = Mips::OR64;
4828 case Mips::SLTImm64:
4829 FinalOpcode = Mips::SLT64;
4831 case Mips::SLTUImm64:
4832 FinalOpcode = Mips::SLTu64;
4835 FinalOpcode = Mips::XOR64;
4840 TOut.
emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4842 TOut.
emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4848bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4849 const MCSubtargetInfo *STI) {
4850 MipsTargetStreamer &TOut = getTargetStreamer();
4855 MCRegister TmpReg =
DReg;
4857 unsigned FirstShift = Mips::NOP;
4858 unsigned SecondShift = Mips::NOP;
4860 if (hasMips32r2()) {
4862 TmpReg = getATReg(Inst.
getLoc());
4868 TOut.
emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4869 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
4874 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
4886 FirstShift = Mips::SRLV;
4887 SecondShift = Mips::SLLV;
4890 FirstShift = Mips::SLLV;
4891 SecondShift = Mips::SRLV;
4895 ATReg = getATReg(Inst.
getLoc());
4899 TOut.
emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4900 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
4901 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
4902 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
4910bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
4912 const MCSubtargetInfo *STI) {
4913 MipsTargetStreamer &TOut = getTargetStreamer();
4919 unsigned FirstShift = Mips::NOP;
4920 unsigned SecondShift = Mips::NOP;
4922 if (hasMips32r2()) {
4927 ShiftValue = MaxShift - ImmValue;
4928 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
4933 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.
getLoc(), STI);
4941 if (ImmValue == 0) {
4950 FirstShift = Mips::SLL;
4951 SecondShift = Mips::SRL;
4954 FirstShift = Mips::SRL;
4955 SecondShift = Mips::SLL;
4959 ATReg = getATReg(Inst.
getLoc());
4963 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.
getLoc(), STI);
4964 TOut.
emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.
getLoc(), STI);
4965 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
4973bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4974 const MCSubtargetInfo *STI) {
4975 MipsTargetStreamer &TOut = getTargetStreamer();
4980 MCRegister TmpReg =
DReg;
4982 unsigned FirstShift = Mips::NOP;
4983 unsigned SecondShift = Mips::NOP;
4985 if (hasMips64r2()) {
4986 if (TmpReg == SReg) {
4987 TmpReg = getATReg(Inst.
getLoc());
4993 TOut.
emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4994 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
4999 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
5011 FirstShift = Mips::DSRLV;
5012 SecondShift = Mips::DSLLV;
5015 FirstShift = Mips::DSLLV;
5016 SecondShift = Mips::DSRLV;
5020 ATReg = getATReg(Inst.
getLoc());
5024 TOut.
emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
5025 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
5026 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
5027 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5035bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
5037 const MCSubtargetInfo *STI) {
5038 MipsTargetStreamer &TOut = getTargetStreamer();
5044 unsigned FirstShift = Mips::NOP;
5045 unsigned SecondShift = Mips::NOP;
5049 if (hasMips64r2()) {
5050 unsigned FinalOpcode = Mips::NOP;
5052 FinalOpcode = Mips::DROTR;
5053 else if (ImmValue % 32 == 0)
5054 FinalOpcode = Mips::DROTR32;
5055 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
5057 FinalOpcode = Mips::DROTR32;
5059 FinalOpcode = Mips::DROTR;
5060 }
else if (ImmValue >= 33) {
5062 FinalOpcode = Mips::DROTR;
5064 FinalOpcode = Mips::DROTR32;
5067 uint64_t ShiftValue = ImmValue % 32;
5069 ShiftValue = (32 - ImmValue % 32) % 32;
5071 TOut.
emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
5077 if (ImmValue == 0) {
5078 TOut.
emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.
getLoc(), STI);
5086 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5087 FirstShift = Mips::DSLL;
5088 SecondShift = Mips::DSRL32;
5090 if (ImmValue == 32) {
5091 FirstShift = Mips::DSLL32;
5092 SecondShift = Mips::DSRL32;
5094 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5095 FirstShift = Mips::DSLL32;
5096 SecondShift = Mips::DSRL;
5100 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5101 FirstShift = Mips::DSRL;
5102 SecondShift = Mips::DSLL32;
5104 if (ImmValue == 32) {
5105 FirstShift = Mips::DSRL32;
5106 SecondShift = Mips::DSLL32;
5108 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5109 FirstShift = Mips::DSRL32;
5110 SecondShift = Mips::DSLL;
5115 ATReg = getATReg(Inst.
getLoc());
5119 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.
getLoc(), STI);
5120 TOut.
emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
5122 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5130bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5131 const MCSubtargetInfo *STI) {
5132 MipsTargetStreamer &TOut = getTargetStreamer();
5136 TOut.
emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
5137 if (FirstRegOp != SecondRegOp)
5138 TOut.
emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
5141 TOut.
emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
5146bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5147 const MCSubtargetInfo *STI) {
5148 MipsTargetStreamer &TOut = getTargetStreamer();
5154 ATReg = getATReg(IDLoc);
5158 loadImmediate(ImmValue, ATReg, MCRegister(),
true,
false, IDLoc, Out, STI);
5160 TOut.
emitRR(Inst.
getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
5161 SrcReg, ATReg, IDLoc, STI);
5163 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5168bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5169 const MCSubtargetInfo *STI) {
5170 MipsTargetStreamer &TOut = getTargetStreamer();
5176 ATReg = getATReg(Inst.
getLoc());
5180 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
5181 SrcReg, TmpReg, IDLoc, STI);
5183 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5185 TOut.
emitRRI(Inst.
getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
5186 DstReg, DstReg, 0x1F, IDLoc, STI);
5188 TOut.
emitR(Mips::MFHI, ATReg, IDLoc, STI);
5191 TOut.
emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
5198 TOut.
emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
5199 if (AssemblerOptions.
back()->isReorder())
5201 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5205 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5210bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5211 const MCSubtargetInfo *STI) {
5212 MipsTargetStreamer &TOut = getTargetStreamer();
5218 ATReg = getATReg(IDLoc);
5222 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
5223 SrcReg, TmpReg, IDLoc, STI);
5225 TOut.
emitR(Mips::MFHI, ATReg, IDLoc, STI);
5226 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5228 TOut.
emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);
5235 TOut.
emitRRX(Mips::BEQ, ATReg, Mips::ZERO, LabelOp, IDLoc, STI);
5236 if (AssemblerOptions.
back()->isReorder())
5238 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5246bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5247 const MCSubtargetInfo *STI) {
5248 MipsTargetStreamer &TOut = getTargetStreamer();
5253 TOut.
emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
5254 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5264bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
5266 const MCSubtargetInfo *STI,
5271 warnIfNoMacro(IDLoc);
5273 MipsTargetStreamer &TOut = getTargetStreamer();
5274 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
5276 MCRegister SecondReg =
nextReg(FirstReg);
5281 warnIfRegIndexIsAT(FirstReg, IDLoc);
5284 "Offset for load macro is not immediate!");
5287 signed NextOffset = FirstOffset.
getImm() + 4;
5295 if (FirstReg != BaseReg || !IsLoad) {
5296 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5297 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5299 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5300 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5312bool MipsAsmParser::expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc,
5314 const MCSubtargetInfo *STI) {
5318 warnIfNoMacro(IDLoc);
5320 MipsTargetStreamer &TOut = getTargetStreamer();
5321 unsigned Opcode = Mips::SWC1;
5323 MCRegister SecondReg =
nextReg(FirstReg);
5328 warnIfRegIndexIsAT(FirstReg, IDLoc);
5331 "Offset for macro is not immediate!");
5334 signed NextOffset = FirstOffset.
getImm() + 4;
5340 if (!IsLittleEndian)
5343 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5344 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5349bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5350 const MCSubtargetInfo *STI) {
5351 MipsTargetStreamer &TOut = getTargetStreamer();
5362 warnIfNoMacro(IDLoc);
5364 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5365 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5366 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5370 MCRegister
Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5371 TOut.
emitRRI(Mips::SLTiu, DstReg,
Reg, 1, IDLoc, STI);
5375bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5376 const MCSubtargetInfo *STI) {
5377 MipsTargetStreamer &TOut = getTargetStreamer();
5388 warnIfNoMacro(IDLoc);
5391 TOut.
emitRRI(Mips::SLTiu, DstReg, SrcReg, 1, IDLoc, STI);
5395 if (SrcReg == Mips::ZERO) {
5396 Warning(IDLoc,
"comparison is always false");
5397 TOut.
emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
5398 DstReg, SrcReg, SrcReg, IDLoc, STI);
5403 if (
Imm > -0x8000 &&
Imm < 0) {
5405 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5411 MCRegister ATReg = getATReg(IDLoc);
5415 if (loadImmediate(
Imm, ATReg, MCRegister(),
true, isGP64bit(), IDLoc, Out,
5419 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5420 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5425 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5429bool MipsAsmParser::expandSne(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5430 const MCSubtargetInfo *STI) {
5432 MipsTargetStreamer &TOut = getTargetStreamer();
5443 warnIfNoMacro(IDLoc);
5445 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5446 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5447 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5451 MCRegister
Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5452 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO,
Reg, IDLoc, STI);
5456bool MipsAsmParser::expandSneI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5457 const MCSubtargetInfo *STI) {
5458 MipsTargetStreamer &TOut = getTargetStreamer();
5469 warnIfNoMacro(IDLoc);
5471 if (ImmValue == 0) {
5472 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, SrcReg, IDLoc, STI);
5476 if (SrcReg == Mips::ZERO) {
5477 Warning(IDLoc,
"comparison is always true");
5478 if (loadImmediate(1, DstReg, MCRegister(),
true,
false, IDLoc, Out, STI))
5484 if (ImmValue > -0x8000 && ImmValue < 0) {
5485 ImmValue = -ImmValue;
5486 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5492 TOut.
emitRRI(
Opc, DstReg, SrcReg, ImmValue, IDLoc, STI);
5493 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5497 MCRegister ATReg = getATReg(IDLoc);
5501 if (loadImmediate(ImmValue, ATReg, MCRegister(),
isInt<32>(ImmValue),
false,
5505 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5506 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5569 case Mips::F0:
return Mips::ZERO;
5570 case Mips::F1:
return Mips::AT;
5571 case Mips::F2:
return Mips::V0;
5572 case Mips::F3:
return Mips::V1;
5573 case Mips::F4:
return Mips::A0;
5574 case Mips::F5:
return Mips::A1;
5575 case Mips::F6:
return Mips::A2;
5576 case Mips::F7:
return Mips::A3;
5577 case Mips::F8:
return Mips::T0;
5578 case Mips::F9:
return Mips::T1;
5579 case Mips::F10:
return Mips::T2;
5580 case Mips::F11:
return Mips::T3;
5581 case Mips::F12:
return Mips::T4;
5582 case Mips::F13:
return Mips::T5;
5583 case Mips::F14:
return Mips::T6;
5584 case Mips::F15:
return Mips::T7;
5585 case Mips::F16:
return Mips::S0;
5586 case Mips::F17:
return Mips::S1;
5587 case Mips::F18:
return Mips::S2;
5588 case Mips::F19:
return Mips::S3;
5589 case Mips::F20:
return Mips::S4;
5590 case Mips::F21:
return Mips::S5;
5591 case Mips::F22:
return Mips::S6;
5592 case Mips::F23:
return Mips::S7;
5593 case Mips::F24:
return Mips::T8;
5594 case Mips::F25:
return Mips::T9;
5595 case Mips::F26:
return Mips::K0;
5596 case Mips::F27:
return Mips::K1;
5597 case Mips::F28:
return Mips::GP;
5598 case Mips::F29:
return Mips::SP;
5599 case Mips::F30:
return Mips::FP;
5600 case Mips::F31:
return Mips::RA;
5608 case Mips::COP00:
return Mips::ZERO;
5609 case Mips::COP01:
return Mips::AT;
5610 case Mips::COP02:
return Mips::V0;
5611 case Mips::COP03:
return Mips::V1;
5612 case Mips::COP04:
return Mips::A0;
5613 case Mips::COP05:
return Mips::A1;
5614 case Mips::COP06:
return Mips::A2;
5615 case Mips::COP07:
return Mips::A3;
5616 case Mips::COP08:
return Mips::T0;
5617 case Mips::COP09:
return Mips::T1;
5618 case Mips::COP010:
return Mips::T2;
5619 case Mips::COP011:
return Mips::T3;
5620 case Mips::COP012:
return Mips::T4;
5621 case Mips::COP013:
return Mips::T5;
5622 case Mips::COP014:
return Mips::T6;
5623 case Mips::COP015:
return Mips::T7;
5624 case Mips::COP016:
return Mips::S0;
5625 case Mips::COP017:
return Mips::S1;
5626 case Mips::COP018:
return Mips::S2;
5627 case Mips::COP019:
return Mips::S3;
5628 case Mips::COP020:
return Mips::S4;
5629 case Mips::COP021:
return Mips::S5;
5630 case Mips::COP022:
return Mips::S6;
5631 case Mips::COP023:
return Mips::S7;
5632 case Mips::COP024:
return Mips::T8;
5633 case Mips::COP025:
return Mips::T9;
5634 case Mips::COP026:
return Mips::K0;
5635 case Mips::COP027:
return Mips::K1;
5636 case Mips::COP028:
return Mips::GP;
5637 case Mips::COP029:
return Mips::SP;
5638 case Mips::COP030:
return Mips::FP;
5639 case Mips::COP031:
return Mips::RA;
5646bool MipsAsmParser::expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5647 const MCSubtargetInfo *STI) {
5648 MipsTargetStreamer &TOut = getTargetStreamer();
5653 bool IsMFTR =
false;
5707 IsMFTR ? MCRegister(rd)
5709 : Inst.getOperand(0).
getReg());
5711 TOut.
emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, u, sel, h, IDLoc,
5716bool MipsAsmParser::expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5717 const MCSubtargetInfo *STI) {
5722 warnIfNoMacro(IDLoc);
5724 MipsTargetStreamer &TOut = getTargetStreamer();
5725 unsigned Opcode = Inst.
getOpcode() == Mips::SaaAddr ? Mips::SAA : Mips::SAAD;
5728 const MCOperand &BaseOp = Inst.
getOperand(2);
5730 if (BaseOp.
isImm()) {
5731 int64_t ImmValue = BaseOp.
getImm();
5732 if (ImmValue == 0) {
5733 TOut.
emitRR(Opcode, RtReg, BaseReg, IDLoc, STI);
5738 MCRegister ATReg = getATReg(IDLoc);
5742 if (expandLoadAddress(ATReg, BaseReg, BaseOp, !isGP64bit(), IDLoc, Out, STI))
5745 TOut.
emitRR(Opcode, RtReg, ATReg, IDLoc, STI);
5750MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
5754 return Match_Success;
5757 if (
static_cast<MipsOperand &
>(*
Operands[1])
5758 .isValidForTie(
static_cast<MipsOperand &
>(*
Operands[2])))
5759 return Match_Success;
5760 return Match_RequiresSameSrcAndDst;
5764unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
5771 return Match_RequiresNoZeroRegister;
5772 return Match_Success;
5778 case Mips::JALR_HB64:
5779 case Mips::JALRC_HB_MMR6:
5780 case Mips::JALRC_MMR6:
5782 return Match_RequiresDifferentSrcAndDst;
5783 return Match_Success;
5786 return Match_RequiresDifferentSrcAndDst;
5787 return Match_Success;
5790 return Match_NonZeroOperandForSync;
5791 return Match_Success;
5797 return Match_NonZeroOperandForMTCX;
5798 return Match_Success;
5811 case Mips::BLEZC:
case Mips::BLEZC_MMR6:
5812 case Mips::BGEZC:
case Mips::BGEZC_MMR6:
5813 case Mips::BGTZC:
case Mips::BGTZC_MMR6:
5814 case Mips::BLTZC:
case Mips::BLTZC_MMR6:
5815 case Mips::BEQZC:
case Mips::BEQZC_MMR6:
5816 case Mips::BNEZC:
case Mips::BNEZC_MMR6:
5825 return Match_RequiresNoZeroRegister;
5826 return Match_Success;
5827 case Mips::BGEC:
case Mips::BGEC_MMR6:
5828 case Mips::BLTC:
case Mips::BLTC_MMR6:
5829 case Mips::BGEUC:
case Mips::BGEUC_MMR6:
5830 case Mips::BLTUC:
case Mips::BLTUC_MMR6:
5831 case Mips::BEQC:
case Mips::BEQC_MMR6:
5832 case Mips::BNEC:
case Mips::BNEC_MMR6:
5841 return Match_RequiresNoZeroRegister;
5844 return Match_RequiresNoZeroRegister;
5846 return Match_RequiresDifferentOperands;
5847 return Match_Success;
5850 "Operands must be immediates for dins!");
5853 if ((0 > (Pos +
Size)) || ((Pos +
Size) > 32))
5854 return Match_RequiresPosSizeRange0_32;
5855 return Match_Success;
5860 "Operands must be immediates for dinsm/dinsu!");
5863 if ((32 >= (Pos +
Size)) || ((Pos +
Size) > 64))
5864 return Match_RequiresPosSizeRange33_64;
5865 return Match_Success;
5869 "Operands must be immediates for DEXTM!");
5872 if ((1 > (Pos +
Size)) || ((Pos +
Size) > 63))
5873 return Match_RequiresPosSizeUImm6;
5874 return Match_Success;
5879 "Operands must be immediates for dextm/dextu!");
5882 if ((32 > (Pos +
Size)) || ((Pos +
Size) > 64))
5883 return Match_RequiresPosSizeRange33_64;
5884 return Match_Success;
5886 case Mips::CRC32B:
case Mips::CRC32CB:
5887 case Mips::CRC32H:
case Mips::CRC32CH:
5888 case Mips::CRC32W:
case Mips::CRC32CW:
5889 case Mips::CRC32D:
case Mips::CRC32CD:
5891 return Match_RequiresSameSrcAndDst;
5892 return Match_Success;
5898 return Match_NoFCCRegisterForCurrentISA;
5900 return Match_Success;
5908 if (ErrorLoc ==
SMLoc())
5915bool MipsAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
5919 bool MatchingInlineAsm) {
5921 unsigned MatchResult =
5922 MatchInstructionImpl(
Operands, Inst, ErrorInfo, MatchingInlineAsm);
5924 switch (MatchResult) {
5926 if (processInstruction(Inst, IDLoc, Out, STI))
5929 case Match_MissingFeature:
5930 Error(IDLoc,
"instruction requires a CPU feature not currently enabled");
5932 case Match_InvalidTiedOperand:
5933 Error(IDLoc,
"operand must match destination register");
5935 case Match_InvalidOperand: {
5936 SMLoc ErrorLoc = IDLoc;
5937 if (ErrorInfo != ~0ULL) {
5939 return Error(IDLoc,
"too few operands for instruction");
5941 ErrorLoc =
Operands[ErrorInfo]->getStartLoc();
5942 if (ErrorLoc == SMLoc())
5946 return Error(ErrorLoc,
"invalid operand for instruction");
5948 case Match_NonZeroOperandForSync:
5950 "s-type must be zero or unspecified for pre-MIPS32 ISAs");
5951 case Match_NonZeroOperandForMTCX:
5952 return Error(IDLoc,
"selector must be zero for pre-MIPS32 ISAs");
5953 case Match_MnemonicFail:
5954 return Error(IDLoc,
"invalid instruction");
5955 case Match_RequiresDifferentSrcAndDst:
5956 return Error(IDLoc,
"source and destination must be different");
5957 case Match_RequiresDifferentOperands:
5958 return Error(IDLoc,
"registers must be different");
5959 case Match_RequiresNoZeroRegister:
5960 return Error(IDLoc,
"invalid operand ($zero) for instruction");
5961 case Match_RequiresSameSrcAndDst:
5962 return Error(IDLoc,
"source and destination must match");
5963 case Match_NoFCCRegisterForCurrentISA:
5965 "non-zero fcc register doesn't exist in current ISA level");
5970 "expected 1-bit unsigned immediate");
5973 "expected 2-bit unsigned immediate");
5976 "expected immediate in range 1 .. 4");
5979 "expected 3-bit unsigned immediate");
5982 "expected 4-bit unsigned immediate");
5985 "expected 4-bit signed immediate");
5988 "expected 5-bit unsigned immediate");
5991 "expected 5-bit signed immediate");
5994 "expected immediate in range 1 .. 32");
5995 case Match_UImm5_32:
5997 "expected immediate in range 32 .. 63");
5998 case Match_UImm5_33:
6000 "expected immediate in range 33 .. 64");
6001 case Match_UImm5_0_Report_UImm6:
6005 "expected 6-bit unsigned immediate");
6006 case Match_UImm5_Lsl2:
6008 "expected both 7-bit unsigned immediate and multiple of 4");
6009 case Match_UImmRange2_64:
6011 "expected immediate in range 2 .. 64");
6014 "expected 6-bit unsigned immediate");
6015 case Match_UImm6_Lsl2:
6017 "expected both 8-bit unsigned immediate and multiple of 4");
6020 "expected 6-bit signed immediate");
6023 "expected 7-bit unsigned immediate");
6024 case Match_UImm7_N1:
6026 "expected immediate in range -1 .. 126");
6027 case Match_SImm7_Lsl2:
6029 "expected both 9-bit signed immediate and multiple of 4");
6032 "expected 8-bit unsigned immediate");
6033 case Match_UImm10_0:
6035 "expected 10-bit unsigned immediate");
6036 case Match_SImm10_0:
6038 "expected 10-bit signed immediate");
6039 case Match_SImm11_0:
6041 "expected 11-bit signed immediate");
6043 case Match_UImm16_Relaxed:
6044 case Match_UImm16_AltRelaxed:
6046 "expected 16-bit unsigned immediate");
6048 case Match_SImm16_Relaxed:
6050 "expected 16-bit signed immediate");
6051 case Match_SImm18_Lsl3:
6053 "expected both 18-bit signed immediate and multiple of 8");
6054 case Match_SImm19_Lsl2:
6056 "expected both 19-bit signed immediate and multiple of 4");
6057 case Match_UImm20_0:
6059 "expected 20-bit unsigned immediate");
6060 case Match_UImm26_0:
6062 "expected 26-bit unsigned immediate");
6064 case Match_SImm32_Relaxed:
6066 "expected 32-bit signed immediate");
6067 case Match_UImm32_Coerced:
6069 "expected 32-bit immediate");
6070 case Match_MemSImm9:
6072 "expected memory with 9-bit signed offset");
6073 case Match_MemSImm10:
6075 "expected memory with 10-bit signed offset");
6076 case Match_MemSImm10Lsl1:
6078 "expected memory with 11-bit signed offset and multiple of 2");
6079 case Match_MemSImm10Lsl2:
6081 "expected memory with 12-bit signed offset and multiple of 4");
6082 case Match_MemSImm10Lsl3:
6084 "expected memory with 13-bit signed offset and multiple of 8");
6085 case Match_MemSImm11:
6087 "expected memory with 11-bit signed offset");
6088 case Match_MemSImm12:
6090 "expected memory with 12-bit signed offset");
6091 case Match_MemSImm16:
6093 "expected memory with 16-bit signed offset");
6094 case Match_MemSImmPtr:
6096 "expected memory with 32-bit signed offset");
6097 case Match_RequiresPosSizeRange0_32: {
6098 SMLoc ErrorStart =
Operands[3]->getStartLoc();
6099 SMLoc ErrorEnd =
Operands[4]->getEndLoc();
6100 return Error(ErrorStart,
"size plus position are not in the range 0 .. 32",
6101 SMRange(ErrorStart, ErrorEnd));
6103 case Match_RequiresPosSizeUImm6: {
6104 SMLoc ErrorStart =
Operands[3]->getStartLoc();
6105 SMLoc ErrorEnd =
Operands[4]->getEndLoc();
6106 return Error(ErrorStart,
"size plus position are not in the range 1 .. 63",
6107 SMRange(ErrorStart, ErrorEnd));
6109 case Match_RequiresPosSizeRange33_64: {
6110 SMLoc ErrorStart =
Operands[3]->getStartLoc();
6111 SMLoc ErrorEnd =
Operands[4]->getEndLoc();
6112 return Error(ErrorStart,
"size plus position are not in the range 33 .. 64",
6113 SMRange(ErrorStart, ErrorEnd));
6120void MipsAsmParser::warnIfRegIndexIsAT(MCRegister RegIndex, SMLoc Loc) {
6121 if (RegIndex && AssemblerOptions.
back()->getATRegIndex() == RegIndex)
6122 Warning(Loc,
"used $at (currently $" + Twine(RegIndex.
id()) +
6123 ") without \".set noat\"");
6126void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
6127 if (!AssemblerOptions.
back()->isMacro())
6128 Warning(Loc,
"macro instruction expanded into multiple instructions");
6131void MipsAsmParser::ConvertXWPOperands(MCInst &Inst,
6135 "Unexpected instruction!");
6136 ((MipsOperand &)*
Operands[1]).addGPR32ZeroAsmRegOperands(Inst, 1);
6137 MCRegister NextReg =
nextReg(((MipsOperand &)*
Operands[1]).getGPR32Reg());
6139 ((MipsOperand &)*
Operands[2]).addMemOperands(Inst, 2);
6143MipsAsmParser::printWarningWithFixIt(
const Twine &
Msg,
const Twine &FixMsg,
6144 SMRange
Range,
bool ShowColors) {
6150int MipsAsmParser::matchCPURegisterName(StringRef Name) {
6151 const MCRegisterInfo &MRI = *
getContext().getRegisterInfo();
6157 AsmToken RegTok = getLexer().peekTok();
6158 StringRef FixedName =
6160 printWarningWithFixIt(
"register names $t4-$t7 are only available in O32.",
6161 "Did you mean $" + FixedName +
"?",
6167int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
6168 const MCRegisterInfo &MRI = *
getContext().getRegisterInfo();
6170 Mips::RegAliasName);
6174int MipsAsmParser::matchFPURegisterName(StringRef Name) {
6175 if (Name[0] ==
'f') {
6176 StringRef NumString =
Name.substr(1);
6187int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
6188 if (
Name.starts_with(
"fcc")) {
6189 StringRef NumString =
Name.substr(3);
6200int MipsAsmParser::matchACRegisterName(StringRef Name) {
6201 if (
Name.starts_with(
"ac")) {
6202 StringRef NumString =
Name.substr(2);
6213int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
6216 if (
Name.front() !=
'w' ||
Name.drop_front(1).getAsInteger(10, IntVal))
6225int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
6226 const MCRegisterInfo &MRI = *
getContext().getRegisterInfo();
6228 Name, MRI, Mips::MSACtrlRegClassID, Mips::RegAliasName);
6232bool MipsAsmParser::canUseATReg() {
6233 return AssemblerOptions.
back()->getATRegIndex() != 0;
6236MCRegister MipsAsmParser::getATReg(SMLoc Loc) {
6237 unsigned ATIndex = AssemblerOptions.
back()->getATRegIndex();
6239 reportParseError(Loc,
6240 "pseudo-instruction requires $at, which is not available");
6244 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
6248MCRegister MipsAsmParser::getReg(
int RC,
int RegNo) {
6249 return getContext().getRegisterInfo()->getRegClass(RC).getRegister(RegNo);
6255const MCExpr *MipsAsmParser::parseRelocExpr() {
6256 auto getOp = [](StringRef
Op) {
6257 return StringSwitch<Mips::Specifier>(
Op)
6285 MCAsmParser &Parser = getParser();
6287 const MCExpr *Res =
nullptr;
6293 auto Op = getOp(Name);
6302 while (
Ops.size()) {
6311 MCAsmParser &Parser = getParser();
6321 ParseStatus Res = MatchOperandParserImpl(
Operands, Mnemonic,
true);
6332 switch (getLexer().getKind()) {
6342 if (!parseAnyRegister(
Operands).isNoMatch())
6355 Operands.push_back(MipsOperand::CreateImm(SymRef, S,
E, *
this));
6360 const MCExpr *Expr = parseRelocExpr();
6364 Operands.push_back(MipsOperand::CreateImm(Expr, S,
E, *
this));
6371bool MipsAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
6373 return !tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess();
6376ParseStatus MipsAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
6379 ParseStatus Res = parseAnyRegister(
Operands);
6382 MipsOperand &Operand =
static_cast<MipsOperand &
>(*
Operands.front());
6383 StartLoc = Operand.getStartLoc();
6384 EndLoc = Operand.getEndLoc();
6390 if (Operand.isGPRAsmReg()) {
6392 Reg = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
6403 MCAsmParser &Parser = getParser();
6405 const MCExpr *IdVal =
nullptr;
6407 bool isParenExpr =
false;
6418 IdVal = parseRelocExpr();
6424 const AsmToken &Tok = Parser.
getTok();
6426 MipsOperand &Mnemonic =
static_cast<MipsOperand &
>(*
Operands[0]);
6427 if (Mnemonic.getToken() ==
"la" || Mnemonic.getToken() ==
"dla") {
6430 Operands.push_back(MipsOperand::CreateImm(IdVal, S,
E, *
this));
6439 auto Base = MipsOperand::createGPRReg(
6440 0,
"0",
getContext().getRegisterInfo(), S,
E, *
this);
6442 MipsOperand::CreateMem(std::move(
Base), IdVal, S,
E, *
this));
6494 const MCExpr * NextExpr;
6495 if (getParser().parseExpression(NextExpr))
6518 std::unique_ptr<MipsOperand>
op(
6519 static_cast<MipsOperand *
>(
Operands.back().release()));
6526 if (IdVal->evaluateAsAbsolute(
Imm))
6533 Operands.push_back(MipsOperand::CreateMem(std::move(
op), IdVal, S,
E, *
this));
6538 MCAsmParser &Parser = getParser();
6547 const MCSymbolRefExpr *
Ref =
static_cast<const MCSymbolRefExpr *
>(Expr);
6548 StringRef DefSymbol =
Ref->getSymbol().getName();
6551 matchAnyRegisterNameWithoutDollar(
Operands, DefSymbol.
substr(1), S);
6565 if (Entry != RegisterSets.
end()) {
6567 matchAnyRegisterWithoutDollar(
Operands,
Entry->getValue(), S);
6578ParseStatus MipsAsmParser::matchAnyRegisterNameWithoutDollar(
6580 int Index = matchCPURegisterName(Identifier);
6582 Operands.push_back(MipsOperand::createGPRReg(
6583 Index, Identifier,
getContext().getRegisterInfo(), S,
6584 getLexer().getLoc(), *
this));
6588 Index = matchHWRegsRegisterName(Identifier);
6590 Operands.push_back(MipsOperand::createHWRegsReg(
6591 Index, Identifier,
getContext().getRegisterInfo(), S,
6592 getLexer().getLoc(), *
this));
6596 Index = matchFPURegisterName(Identifier);
6598 Operands.push_back(MipsOperand::createFGRReg(
6599 Index, Identifier,
getContext().getRegisterInfo(), S,
6600 getLexer().getLoc(), *
this));
6604 Index = matchFCCRegisterName(Identifier);
6606 Operands.push_back(MipsOperand::createFCCReg(
6607 Index, Identifier,
getContext().getRegisterInfo(), S,
6608 getLexer().getLoc(), *
this));
6612 Index = matchACRegisterName(Identifier);
6614 Operands.push_back(MipsOperand::createACCReg(
6615 Index, Identifier,
getContext().getRegisterInfo(), S,
6616 getLexer().getLoc(), *
this));
6620 Index = matchMSA128RegisterName(Identifier);
6622 Operands.push_back(MipsOperand::createMSA128Reg(
6623 Index, Identifier,
getContext().getRegisterInfo(), S,
6624 getLexer().getLoc(), *
this));
6628 Index = matchMSA128CtrlRegisterName(Identifier);
6630 Operands.push_back(MipsOperand::createMSACtrlReg(
6631 Index, Identifier,
getContext().getRegisterInfo(), S,
6632 getLexer().getLoc(), *
this));
6641 const AsmToken &Token, SMLoc S) {
6645 return matchAnyRegisterNameWithoutDollar(
Operands, Identifier, S);
6650 if (RegNum < 0 || RegNum > 31) {
6654 Error(getLexer().getLoc(),
"invalid register number");
6656 Operands.push_back(MipsOperand::createNumericReg(
6669 auto Token = getLexer().peekTok(
false);
6670 return matchAnyRegisterWithoutDollar(
Operands, Token, S);
6674 MCAsmParser &Parser = getParser();
6677 auto Token = Parser.
getTok();
6679 SMLoc S = Token.
getLoc();
6692 ParseStatus Res = matchAnyRegisterWithoutDollar(
Operands, S);
6701 MCAsmParser &Parser = getParser();
6704 SMLoc S = getLexer().getLoc();
6707 ParseStatus Res = parseAnyRegister(
Operands);
6712 const MCExpr *Expr =
nullptr;
6718 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *
this));
6723 MCAsmParser &Parser = getParser();
6724 const MCExpr *IdVal;
6735 if (getParser().parseExpression(IdVal))
6742 Operands.push_back(MipsOperand::CreateImm(
6748 MCAsmParser &Parser = getParser();
6752 bool RegRange =
false;
6759 while (parseAnyRegister(TmpOperands).isSuccess()) {
6760 SMLoc
E = getLexer().getLoc();
6761 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*TmpOperands.
back());
6762 Reg = isGP64bit() ? RegOpnd.getGPR64Reg() : RegOpnd.getGPR32Reg();
6766 if ((isGP64bit() &&
Reg == Mips::RA_64) ||
6767 (!isGP64bit() &&
Reg == Mips::RA)) {
6770 MCRegister TmpReg = PrevReg + 1;
6771 while (TmpReg <=
Reg) {
6772 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
6773 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
6775 return Error(
E,
"invalid register operand");
6779 TmpReg = TmpReg.
id() + 1;
6786 ((isGP64bit() && (
Reg != Mips::S0_64) && (
Reg != Mips::RA_64)) ||
6787 (!isGP64bit() && (
Reg != Mips::S0) && (
Reg != Mips::RA))))
6788 return Error(
E,
"$16 or $31 expected");
6789 if (!(((
Reg == Mips::FP ||
Reg == Mips::RA ||
6790 (
Reg >= Mips::S0 &&
Reg <= Mips::S7)) &&
6792 ((
Reg == Mips::FP_64 ||
Reg == Mips::RA_64 ||
6793 (
Reg >= Mips::S0_64 &&
Reg <= Mips::S7_64)) &&
6795 return Error(
E,
"invalid register operand");
6796 if (PrevReg.
isValid() && (
Reg != PrevReg + 1) &&
6797 ((
Reg != Mips::FP &&
Reg != Mips::RA && !isGP64bit()) ||
6798 (
Reg != Mips::FP_64 &&
Reg != Mips::RA_64 && isGP64bit())))
6799 return Error(
E,
"consecutive register numbers expected");
6809 return Error(
E,
"',' or '-' expected");
6819 Operands.push_back(MipsOperand::CreateRegList(Regs, S,
E, *
this));
6830 MCAsmParser &Parser = getParser();
6833 MipsOperand::CreateToken(
"(", getLexer().getLoc(), *
this));
6835 if (parseOperand(
Operands, Name)) {
6836 SMLoc Loc = getLexer().getLoc();
6837 return Error(Loc,
"unexpected token in argument list");
6840 SMLoc Loc = getLexer().getLoc();
6841 return Error(Loc,
"unexpected token, expected ')'");
6844 MipsOperand::CreateToken(
")", getLexer().getLoc(), *
this));
6856bool MipsAsmParser::parseBracketSuffix(StringRef Name,
6858 MCAsmParser &Parser = getParser();
6861 MipsOperand::CreateToken(
"[", getLexer().getLoc(), *
this));
6863 if (parseOperand(
Operands, Name)) {
6864 SMLoc Loc = getLexer().getLoc();
6865 return Error(Loc,
"unexpected token in argument list");
6868 SMLoc Loc = getLexer().getLoc();
6869 return Error(Loc,
"unexpected token, expected ']'");
6872 MipsOperand::CreateToken(
"]", getLexer().getLoc(), *
this));
6879 unsigned VariantID = 0);
6894bool MipsAsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
6896 MCAsmParser &Parser = getParser();
6900 getTargetStreamer().forbidModuleDirective();
6903 if (!mnemonicIsValid(Name, 0)) {
6904 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
6906 return Error(NameLoc,
"unknown instruction" + Suggestion);
6909 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *
this));
6914 if (parseOperand(
Operands, Name)) {
6915 SMLoc Loc = getLexer().getLoc();
6916 return Error(Loc,
"unexpected token in argument list");
6925 if (parseOperand(
Operands, Name)) {
6926 SMLoc Loc = getLexer().getLoc();
6927 return Error(Loc,
"unexpected token in argument list");
6931 if (parseBracketSuffix(Name,
Operands))
6939 SMLoc Loc = getLexer().getLoc();
6940 return Error(Loc,
"unexpected token in argument list");
6948bool MipsAsmParser::reportParseError(
const Twine &ErrorMsg) {
6949 SMLoc Loc = getLexer().getLoc();
6950 return Error(Loc, ErrorMsg);
6953bool MipsAsmParser::reportParseError(SMLoc Loc,
const Twine &ErrorMsg) {
6954 return Error(Loc, ErrorMsg);
6957bool MipsAsmParser::parseSetNoAtDirective() {
6958 MCAsmParser &Parser = getParser();
6962 AssemblerOptions.
back()->setATRegIndex(0);
6968 reportParseError(
"unexpected token, expected end of statement");
6972 getTargetStreamer().emitDirectiveSetNoAt();
6977bool MipsAsmParser::parseSetAtDirective() {
6980 MCAsmParser &Parser = getParser();
6985 AssemblerOptions.
back()->setATRegIndex(1);
6987 getTargetStreamer().emitDirectiveSetAt();
6993 reportParseError(
"unexpected token, expected equals sign");
7000 reportParseError(
"no register specified");
7003 reportParseError(
"unexpected token, expected dollar sign '$'");
7013 AtRegNo = matchCPURegisterName(
Reg.getIdentifier());
7015 AtRegNo =
Reg.getIntVal();
7017 reportParseError(
"unexpected token, expected identifier or integer");
7022 if (!AssemblerOptions.
back()->setATRegIndex(AtRegNo)) {
7023 reportParseError(
"invalid register");
7030 reportParseError(
"unexpected token, expected end of statement");
7034 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
7040bool MipsAsmParser::parseSetReorderDirective() {
7041 MCAsmParser &Parser = getParser();
7045 reportParseError(
"unexpected token, expected end of statement");
7048 AssemblerOptions.
back()->setReorder();
7049 getTargetStreamer().emitDirectiveSetReorder();
7054bool MipsAsmParser::parseSetNoReorderDirective() {
7055 MCAsmParser &Parser = getParser();
7059 reportParseError(
"unexpected token, expected end of statement");
7062 AssemblerOptions.
back()->setNoReorder();
7063 getTargetStreamer().emitDirectiveSetNoReorder();
7068bool MipsAsmParser::parseSetMacroDirective() {
7069 MCAsmParser &Parser = getParser();
7073 reportParseError(
"unexpected token, expected end of statement");
7076 AssemblerOptions.
back()->setMacro();
7077 getTargetStreamer().emitDirectiveSetMacro();
7082bool MipsAsmParser::parseSetNoMacroDirective() {
7083 MCAsmParser &Parser = getParser();
7087 reportParseError(
"unexpected token, expected end of statement");
7090 if (AssemblerOptions.
back()->isReorder()) {
7091 reportParseError(
"`noreorder' must be set before `nomacro'");
7094 AssemblerOptions.
back()->setNoMacro();
7095 getTargetStreamer().emitDirectiveSetNoMacro();
7100bool MipsAsmParser::parseSetMsaDirective() {
7101 MCAsmParser &Parser = getParser();
7106 return reportParseError(
"unexpected token, expected end of statement");
7108 setFeatureBits(Mips::FeatureMSA,
"msa");
7109 getTargetStreamer().emitDirectiveSetMsa();
7113bool MipsAsmParser::parseSetNoMsaDirective() {
7114 MCAsmParser &Parser = getParser();
7119 return reportParseError(
"unexpected token, expected end of statement");
7121 clearFeatureBits(Mips::FeatureMSA,
"msa");
7122 getTargetStreamer().emitDirectiveSetNoMsa();
7126bool MipsAsmParser::parseSetNoDspDirective() {
7127 MCAsmParser &Parser = getParser();
7132 reportParseError(
"unexpected token, expected end of statement");
7136 clearFeatureBits(Mips::FeatureDSP,
"dsp");
7137 getTargetStreamer().emitDirectiveSetNoDsp();
7141bool MipsAsmParser::parseSetNoMips3DDirective() {
7142 MCAsmParser &Parser = getParser();
7147 reportParseError(
"unexpected token, expected end of statement");
7151 clearFeatureBits(Mips::FeatureMips3D,
"mips3d");
7152 getTargetStreamer().emitDirectiveSetNoMips3D();
7156bool MipsAsmParser::parseSetMips16Directive() {
7157 MCAsmParser &Parser = getParser();
7162 reportParseError(
"unexpected token, expected end of statement");
7166 setFeatureBits(Mips::FeatureMips16,
"mips16");
7167 getTargetStreamer().emitDirectiveSetMips16();
7172bool MipsAsmParser::parseSetNoMips16Directive() {
7173 MCAsmParser &Parser = getParser();
7178 reportParseError(
"unexpected token, expected end of statement");
7182 clearFeatureBits(Mips::FeatureMips16,
"mips16");
7183 getTargetStreamer().emitDirectiveSetNoMips16();
7188bool MipsAsmParser::parseSetFpDirective() {
7189 MCAsmParser &Parser = getParser();
7195 AsmToken Tok = Parser.
getTok();
7197 reportParseError(
"unexpected token, expected equals sign '='");
7203 if (!parseFpABIValue(FpAbiVal,
".set"))
7207 reportParseError(
"unexpected token, expected end of statement");
7210 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
7215bool MipsAsmParser::parseSetOddSPRegDirective() {
7216 MCAsmParser &Parser = getParser();
7220 reportParseError(
"unexpected token, expected end of statement");
7224 clearFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
7225 getTargetStreamer().emitDirectiveSetOddSPReg();
7229bool MipsAsmParser::parseSetNoOddSPRegDirective() {
7230 MCAsmParser &Parser = getParser();
7234 reportParseError(
"unexpected token, expected end of statement");
7238 setFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
7239 getTargetStreamer().emitDirectiveSetNoOddSPReg();
7243bool MipsAsmParser::parseSetMtDirective() {
7244 MCAsmParser &Parser = getParser();
7249 reportParseError(
"unexpected token, expected end of statement");
7253 setFeatureBits(Mips::FeatureMT,
"mt");
7254 getTargetStreamer().emitDirectiveSetMt();
7259bool MipsAsmParser::parseSetNoMtDirective() {
7260 MCAsmParser &Parser = getParser();
7265 reportParseError(
"unexpected token, expected end of statement");
7269 clearFeatureBits(Mips::FeatureMT,
"mt");
7271 getTargetStreamer().emitDirectiveSetNoMt();
7276bool MipsAsmParser::parseSetNoCRCDirective() {
7277 MCAsmParser &Parser = getParser();
7282 reportParseError(
"unexpected token, expected end of statement");
7286 clearFeatureBits(Mips::FeatureCRC,
"crc");
7288 getTargetStreamer().emitDirectiveSetNoCRC();
7293bool MipsAsmParser::parseSetNoVirtDirective() {
7294 MCAsmParser &Parser = getParser();
7299 reportParseError(
"unexpected token, expected end of statement");
7303 clearFeatureBits(Mips::FeatureVirt,
"virt");
7305 getTargetStreamer().emitDirectiveSetNoVirt();
7310bool MipsAsmParser::parseSetNoGINVDirective() {
7311 MCAsmParser &Parser = getParser();
7316 reportParseError(
"unexpected token, expected end of statement");
7320 clearFeatureBits(Mips::FeatureGINV,
"ginv");
7322 getTargetStreamer().emitDirectiveSetNoGINV();
7327bool MipsAsmParser::parseSetNoEVADirective() {
7328 MCAsmParser &Parser = getParser();
7333 reportParseError(
"unexpected token, expected end of statement");
7337 clearFeatureBits(Mips::FeatureEVA,
"eva");
7339 getTargetStreamer().emitDirectiveSetNoEVA();
7344bool MipsAsmParser::parseSetPopDirective() {
7345 MCAsmParser &Parser = getParser();
7346 SMLoc Loc = getLexer().getLoc();
7350 return reportParseError(
"unexpected token, expected end of statement");
7354 if (AssemblerOptions.
size() == 2)
7355 return reportParseError(Loc,
".set pop with no .set push");
7357 MCSubtargetInfo &STI = copySTI();
7359 setAvailableFeatures(
7360 ComputeAvailableFeatures(AssemblerOptions.
back()->getFeatures()));
7363 getTargetStreamer().emitDirectiveSetPop();
7367bool MipsAsmParser::parseSetPushDirective() {
7368 MCAsmParser &Parser = getParser();
7371 return reportParseError(
"unexpected token, expected end of statement");
7375 std::make_unique<MipsAssemblerOptions>(AssemblerOptions.
back().get()));
7377 getTargetStreamer().emitDirectiveSetPush();
7381bool MipsAsmParser::parseSetSoftFloatDirective() {
7382 MCAsmParser &Parser = getParser();
7385 return reportParseError(
"unexpected token, expected end of statement");
7387 setFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
7388 getTargetStreamer().emitDirectiveSetSoftFloat();
7392bool MipsAsmParser::parseSetHardFloatDirective() {
7393 MCAsmParser &Parser = getParser();
7396 return reportParseError(
"unexpected token, expected end of statement");
7398 clearFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
7399 getTargetStreamer().emitDirectiveSetHardFloat();
7403bool MipsAsmParser::parseSetAssignment() {
7405 MCAsmParser &Parser = getParser();
7408 return reportParseError(
"expected identifier after .set");
7411 return reportParseError(
"unexpected token, expected comma");
7426 const MCExpr *
Value;
7428 Parser, Sym,
Value))
7430 getStreamer().emitAssignment(Sym,
Value);
7435bool MipsAsmParser::parseSetMips0Directive() {
7436 MCAsmParser &Parser = getParser();
7439 return reportParseError(
"unexpected token, expected end of statement");
7442 MCSubtargetInfo &STI = copySTI();
7443 setAvailableFeatures(
7444 ComputeAvailableFeatures(AssemblerOptions.
front()->getFeatures()));
7446 AssemblerOptions.
back()->setFeatures(AssemblerOptions.
front()->getFeatures());
7448 getTargetStreamer().emitDirectiveSetMips0();
7452bool MipsAsmParser::parseSetArchDirective() {
7453 MCAsmParser &Parser = getParser();
7456 return reportParseError(
"unexpected token, expected equals sign");
7459 StringRef Arch = getParser().parseStringToEndOfStatement().trim();
7461 return reportParseError(
"expected arch identifier");
7463 StringRef ArchFeatureName =
7464 StringSwitch<StringRef>(Arch)
7465 .Case(
"mips1",
"mips1")
7466 .Case(
"mips2",
"mips2")
7467 .Case(
"mips3",
"mips3")
7468 .Case(
"mips4",
"mips4")
7469 .Case(
"mips5",
"mips5")
7470 .Case(
"mips32",
"mips32")
7471 .Case(
"mips32r2",
"mips32r2")
7472 .Case(
"mips32r3",
"mips32r3")
7473 .Case(
"mips32r5",
"mips32r5")
7474 .Case(
"mips32r6",
"mips32r6")
7475 .Case(
"mips64",
"mips64")
7476 .Case(
"mips64r2",
"mips64r2")
7477 .Case(
"mips64r3",
"mips64r3")
7478 .Case(
"mips64r5",
"mips64r5")
7479 .Case(
"mips64r6",
"mips64r6")
7480 .Case(
"octeon",
"cnmips")
7481 .Case(
"octeon+",
"cnmipsp")
7482 .Case(
"r4000",
"mips3")
7485 if (ArchFeatureName.
empty())
7486 return reportParseError(
"unsupported architecture");
7488 if (ArchFeatureName ==
"mips64r6" && inMicroMipsMode())
7489 return reportParseError(
"mips64r6 does not support microMIPS");
7491 selectArch(ArchFeatureName);
7492 getTargetStreamer().emitDirectiveSetArch(Arch);
7496bool MipsAsmParser::parseSetFeature(
uint64_t Feature) {
7497 MCAsmParser &Parser = getParser();
7500 return reportParseError(
"unexpected token, expected end of statement");
7505 case Mips::FeatureMips3D:
7506 setFeatureBits(Mips::FeatureMips3D,
"mips3d");
7507 getTargetStreamer().emitDirectiveSetMips3D();
7509 case Mips::FeatureDSP:
7510 setFeatureBits(Mips::FeatureDSP,
"dsp");
7511 getTargetStreamer().emitDirectiveSetDsp();
7513 case Mips::FeatureDSPR2:
7514 setFeatureBits(Mips::FeatureDSPR2,
"dspr2");
7515 getTargetStreamer().emitDirectiveSetDspr2();
7517 case Mips::FeatureMicroMips:
7518 setFeatureBits(Mips::FeatureMicroMips,
"micromips");
7519 getTargetStreamer().emitDirectiveSetMicroMips();
7521 case Mips::FeatureMips1:
7522 selectArch(
"mips1");
7523 getTargetStreamer().emitDirectiveSetMips1();
7525 case Mips::FeatureMips2:
7526 selectArch(
"mips2");
7527 getTargetStreamer().emitDirectiveSetMips2();
7529 case Mips::FeatureMips3:
7530 selectArch(
"mips3");
7531 getTargetStreamer().emitDirectiveSetMips3();
7533 case Mips::FeatureMips4:
7534 selectArch(
"mips4");
7535 getTargetStreamer().emitDirectiveSetMips4();
7537 case Mips::FeatureMips5:
7538 selectArch(
"mips5");
7539 getTargetStreamer().emitDirectiveSetMips5();
7541 case Mips::FeatureMips32:
7542 selectArch(
"mips32");
7543 getTargetStreamer().emitDirectiveSetMips32();
7545 case Mips::FeatureMips32r2:
7546 selectArch(
"mips32r2");
7547 getTargetStreamer().emitDirectiveSetMips32R2();
7549 case Mips::FeatureMips32r3:
7550 selectArch(
"mips32r3");
7551 getTargetStreamer().emitDirectiveSetMips32R3();
7553 case Mips::FeatureMips32r5:
7554 selectArch(
"mips32r5");
7555 getTargetStreamer().emitDirectiveSetMips32R5();
7557 case Mips::FeatureMips32r6:
7558 selectArch(
"mips32r6");
7559 getTargetStreamer().emitDirectiveSetMips32R6();
7561 case Mips::FeatureMips64:
7562 selectArch(
"mips64");
7563 getTargetStreamer().emitDirectiveSetMips64();
7565 case Mips::FeatureMips64r2:
7566 selectArch(
"mips64r2");
7567 getTargetStreamer().emitDirectiveSetMips64R2();
7569 case Mips::FeatureMips64r3:
7570 selectArch(
"mips64r3");
7571 getTargetStreamer().emitDirectiveSetMips64R3();
7573 case Mips::FeatureMips64r5:
7574 selectArch(
"mips64r5");
7575 getTargetStreamer().emitDirectiveSetMips64R5();
7577 case Mips::FeatureMips64r6:
7578 selectArch(
"mips64r6");
7579 getTargetStreamer().emitDirectiveSetMips64R6();
7581 case Mips::FeatureCRC:
7582 setFeatureBits(Mips::FeatureCRC,
"crc");
7583 getTargetStreamer().emitDirectiveSetCRC();
7585 case Mips::FeatureVirt:
7586 setFeatureBits(Mips::FeatureVirt,
"virt");
7587 getTargetStreamer().emitDirectiveSetVirt();
7589 case Mips::FeatureGINV:
7590 setFeatureBits(Mips::FeatureGINV,
"ginv");
7591 getTargetStreamer().emitDirectiveSetGINV();
7593 case Mips::FeatureEVA:
7594 setFeatureBits(Mips::FeatureEVA,
"eva");
7595 getTargetStreamer().emitDirectiveSetEVA();
7601bool MipsAsmParser::eatComma(StringRef ErrorStr) {
7602 MCAsmParser &Parser = getParser();
7604 SMLoc Loc = getLexer().getLoc();
7605 return Error(Loc, ErrorStr);
7616bool MipsAsmParser::isPicAndNotNxxAbi() {
7617 return inPicMode() && !(isABI_N32() || isABI_N64());
7620bool MipsAsmParser::parseDirectiveCpAdd(SMLoc Loc) {
7622 ParseStatus Res = parseAnyRegister(
Reg);
7624 reportParseError(
"expected register");
7628 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7629 if (!RegOpnd.isGPRAsmReg()) {
7630 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7636 reportParseError(
"unexpected token, expected end of statement");
7641 getTargetStreamer().emitDirectiveCpAdd(RegOpnd.getGPR32Reg());
7645bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
7646 if (AssemblerOptions.
back()->isReorder())
7647 Warning(Loc,
".cpload should be inside a noreorder section");
7649 if (inMips16Mode()) {
7650 reportParseError(
".cpload is not supported in Mips16 mode");
7655 ParseStatus Res = parseAnyRegister(
Reg);
7657 reportParseError(
"expected register containing function address");
7661 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7662 if (!RegOpnd.isGPRAsmReg()) {
7663 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7669 reportParseError(
"unexpected token, expected end of statement");
7673 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
7677bool MipsAsmParser::parseDirectiveCpLocal(SMLoc Loc) {
7678 if (!isABI_N32() && !isABI_N64()) {
7679 reportParseError(
".cplocal is allowed only in N32 or N64 mode");
7684 ParseStatus Res = parseAnyRegister(
Reg);
7686 reportParseError(
"expected register containing global pointer");
7690 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7691 if (!RegOpnd.isGPRAsmReg()) {
7692 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7698 reportParseError(
"unexpected token, expected end of statement");
7703 MCRegister NewReg = RegOpnd.getGPR32Reg();
7707 getTargetStreamer().emitDirectiveCpLocal(NewReg);
7711bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
7712 MCAsmParser &Parser = getParser();
7717 if (inMips16Mode()) {
7718 reportParseError(
".cprestore is not supported in Mips16 mode");
7723 const MCExpr *StackOffset;
7724 int64_t StackOffsetVal;
7726 reportParseError(
"expected stack offset value");
7730 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
7731 reportParseError(
"stack offset is not an absolute expression");
7735 if (StackOffsetVal < 0) {
7736 Warning(Loc,
".cprestore with negative stack offset has no effect");
7737 IsCpRestoreSet =
false;
7739 IsCpRestoreSet =
true;
7740 CpRestoreOffset = StackOffsetVal;
7745 reportParseError(
"unexpected token, expected end of statement");
7749 if (!getTargetStreamer().emitDirectiveCpRestore(
7750 CpRestoreOffset, [&]() {
return getATReg(Loc); }, Loc, STI))
7756bool MipsAsmParser::parseDirectiveCPSetup() {
7757 MCAsmParser &Parser = getParser();
7759 bool SaveIsReg =
true;
7762 ParseStatus Res = parseAnyRegister(TmpReg);
7764 reportParseError(
"expected register containing function address");
7768 MipsOperand &FuncRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7769 if (!FuncRegOpnd.isGPRAsmReg()) {
7770 reportParseError(FuncRegOpnd.getStartLoc(),
"invalid register");
7774 MCRegister FuncReg = FuncRegOpnd.getGPR32Reg();
7777 if (!eatComma(
"unexpected token, expected comma"))
7780 Res = parseAnyRegister(TmpReg);
7782 const MCExpr *OffsetExpr;
7784 SMLoc ExprLoc = getLexer().
getLoc();
7787 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
7788 reportParseError(ExprLoc,
"expected save register or stack offset");
7795 MipsOperand &SaveOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7796 if (!SaveOpnd.isGPRAsmReg()) {
7797 reportParseError(SaveOpnd.getStartLoc(),
"invalid register");
7800 Save = SaveOpnd.getGPR32Reg().id();
7803 if (!eatComma(
"unexpected token, expected comma"))
7808 reportParseError(
"expected expression");
7813 reportParseError(
"expected symbol");
7816 const MCSymbolRefExpr *
Ref =
static_cast<const MCSymbolRefExpr *
>(Expr);
7818 CpSaveLocation = Save;
7819 CpSaveLocationIsRegister = SaveIsReg;
7821 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save,
Ref->getSymbol(),
7826bool MipsAsmParser::parseDirectiveCPReturn() {
7827 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
7828 CpSaveLocationIsRegister);
7832bool MipsAsmParser::parseDirectiveNaN() {
7833 MCAsmParser &Parser = getParser();
7835 const AsmToken &Tok = Parser.
getTok();
7839 getTargetStreamer().emitDirectiveNaN2008();
7841 }
else if (Tok.
getString() ==
"legacy") {
7843 getTargetStreamer().emitDirectiveNaNLegacy();
7849 reportParseError(
"invalid option in .nan directive");
7853bool MipsAsmParser::parseDirectiveSet() {
7854 const AsmToken &Tok = getParser().getTok();
7856 SMLoc Loc = Tok.
getLoc();
7858 if (IdVal ==
"noat")
7859 return parseSetNoAtDirective();
7861 return parseSetAtDirective();
7862 if (IdVal ==
"arch")
7863 return parseSetArchDirective();
7864 if (IdVal ==
"bopt") {
7865 Warning(Loc,
"'bopt' feature is unsupported");
7869 if (IdVal ==
"nobopt") {
7875 return parseSetFpDirective();
7876 if (IdVal ==
"oddspreg")
7877 return parseSetOddSPRegDirective();
7878 if (IdVal ==
"nooddspreg")
7879 return parseSetNoOddSPRegDirective();
7881 return parseSetPopDirective();
7882 if (IdVal ==
"push")
7883 return parseSetPushDirective();
7884 if (IdVal ==
"reorder")
7885 return parseSetReorderDirective();
7886 if (IdVal ==
"noreorder")
7887 return parseSetNoReorderDirective();
7888 if (IdVal ==
"macro")
7889 return parseSetMacroDirective();
7890 if (IdVal ==
"nomacro")
7891 return parseSetNoMacroDirective();
7892 if (IdVal ==
"mips16")
7893 return parseSetMips16Directive();
7894 if (IdVal ==
"nomips16")
7895 return parseSetNoMips16Directive();
7896 if (IdVal ==
"nomicromips") {
7897 clearFeatureBits(Mips::FeatureMicroMips,
"micromips");
7898 getTargetStreamer().emitDirectiveSetNoMicroMips();
7899 getParser().eatToEndOfStatement();
7902 if (IdVal ==
"micromips") {
7903 if (hasMips64r6()) {
7904 Error(Loc,
".set micromips directive is not supported with MIPS64R6");
7907 return parseSetFeature(Mips::FeatureMicroMips);
7909 if (IdVal ==
"mips0")
7910 return parseSetMips0Directive();
7911 if (IdVal ==
"mips1")
7912 return parseSetFeature(Mips::FeatureMips1);
7913 if (IdVal ==
"mips2")
7914 return parseSetFeature(Mips::FeatureMips2);
7915 if (IdVal ==
"mips3")
7916 return parseSetFeature(Mips::FeatureMips3);
7917 if (IdVal ==
"mips4")
7918 return parseSetFeature(Mips::FeatureMips4);
7919 if (IdVal ==
"mips5")
7920 return parseSetFeature(Mips::FeatureMips5);
7921 if (IdVal ==
"mips32")
7922 return parseSetFeature(Mips::FeatureMips32);
7923 if (IdVal ==
"mips32r2")
7924 return parseSetFeature(Mips::FeatureMips32r2);
7925 if (IdVal ==
"mips32r3")
7926 return parseSetFeature(Mips::FeatureMips32r3);
7927 if (IdVal ==
"mips32r5")
7928 return parseSetFeature(Mips::FeatureMips32r5);
7929 if (IdVal ==
"mips32r6")
7930 return parseSetFeature(Mips::FeatureMips32r6);
7931 if (IdVal ==
"mips64")
7932 return parseSetFeature(Mips::FeatureMips64);
7933 if (IdVal ==
"mips64r2")
7934 return parseSetFeature(Mips::FeatureMips64r2);
7935 if (IdVal ==
"mips64r3")
7936 return parseSetFeature(Mips::FeatureMips64r3);
7937 if (IdVal ==
"mips64r5")
7938 return parseSetFeature(Mips::FeatureMips64r5);
7939 if (IdVal ==
"mips64r6") {
7940 if (inMicroMipsMode()) {
7941 Error(Loc,
"MIPS64R6 is not supported with microMIPS");
7944 return parseSetFeature(Mips::FeatureMips64r6);
7947 return parseSetFeature(Mips::FeatureDSP);
7948 if (IdVal ==
"dspr2")
7949 return parseSetFeature(Mips::FeatureDSPR2);
7950 if (IdVal ==
"nodsp")
7951 return parseSetNoDspDirective();
7952 if (IdVal ==
"mips3d")
7953 return parseSetFeature(Mips::FeatureMips3D);
7954 if (IdVal ==
"nomips3d")
7955 return parseSetNoMips3DDirective();
7957 return parseSetMsaDirective();
7958 if (IdVal ==
"nomsa")
7959 return parseSetNoMsaDirective();
7961 return parseSetMtDirective();
7962 if (IdVal ==
"nomt")
7963 return parseSetNoMtDirective();
7964 if (IdVal ==
"softfloat")
7965 return parseSetSoftFloatDirective();
7966 if (IdVal ==
"hardfloat")
7967 return parseSetHardFloatDirective();
7969 return parseSetFeature(Mips::FeatureCRC);
7970 if (IdVal ==
"nocrc")
7971 return parseSetNoCRCDirective();
7972 if (IdVal ==
"virt")
7973 return parseSetFeature(Mips::FeatureVirt);
7974 if (IdVal ==
"novirt")
7975 return parseSetNoVirtDirective();
7976 if (IdVal ==
"ginv")
7977 return parseSetFeature(Mips::FeatureGINV);
7978 if (IdVal ==
"noginv")
7979 return parseSetNoGINVDirective();
7981 return parseSetFeature(Mips::FeatureEVA);
7982 if (IdVal ==
"noeva")
7983 return parseSetNoEVADirective();
7986 return parseSetAssignment();
7991bool MipsAsmParser::parseDirectiveGpWord() {
7992 const MCExpr *
Value;
7993 if (getParser().parseExpression(
Value))
7995 getTargetStreamer().emitGPRel32Value(
Value);
8001bool MipsAsmParser::parseDirectiveGpDWord() {
8002 const MCExpr *
Value;
8003 if (getParser().parseExpression(
Value))
8005 getTargetStreamer().emitGPRel64Value(
Value);
8011bool MipsAsmParser::parseDirectiveDtpRelWord() {
8012 const MCExpr *
Value;
8013 if (getParser().parseExpression(
Value))
8015 getTargetStreamer().emitDTPRel32Value(
Value);
8021bool MipsAsmParser::parseDirectiveDtpRelDWord() {
8022 const MCExpr *
Value;
8023 if (getParser().parseExpression(
Value))
8025 getTargetStreamer().emitDTPRel64Value(
Value);
8031bool MipsAsmParser::parseDirectiveTpRelWord() {
8032 const MCExpr *
Value;
8033 if (getParser().parseExpression(
Value))
8035 getTargetStreamer().emitTPRel32Value(
Value);
8041bool MipsAsmParser::parseDirectiveTpRelDWord() {
8042 const MCExpr *
Value;
8043 if (getParser().parseExpression(
Value))
8045 getTargetStreamer().emitTPRel64Value(
Value);
8049bool MipsAsmParser::parseDirectiveOption() {
8050 MCAsmParser &Parser = getParser();
8052 AsmToken Tok = Parser.
getTok();
8056 "unexpected token, expected identifier");
8061 if (Option ==
"pic0") {
8063 IsPicEnabled =
false;
8065 getTargetStreamer().emitDirectiveOptionPic0();
8069 "unexpected token, expected end of statement");
8074 if (Option ==
"pic2") {
8076 IsPicEnabled =
true;
8078 getTargetStreamer().emitDirectiveOptionPic2();
8082 "unexpected token, expected end of statement");
8089 "unknown option, expected 'pic0' or 'pic2'");
8096bool MipsAsmParser::parseInsnDirective() {
8099 reportParseError(
"unexpected token, expected end of statement");
8105 getTargetStreamer().emitDirectiveInsn();
8113bool MipsAsmParser::parseRSectionDirective(StringRef Section) {
8116 reportParseError(
"unexpected token, expected end of statement");
8120 MCSection *ELFSection =
getContext().getELFSection(
8122 getParser().getStreamer().switchSection(ELFSection);
8131bool MipsAsmParser::parseSSectionDirective(StringRef Section,
unsigned Type) {
8134 reportParseError(
"unexpected token, expected end of statement");
8138 MCSection *ELFSection =
getContext().getELFSection(
8140 getParser().getStreamer().switchSection(ELFSection);
8159bool MipsAsmParser::parseDirectiveModule() {
8160 MCAsmParser &Parser = getParser();
8161 AsmLexer &Lexer = getLexer();
8164 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
8166 reportParseError(
".module directive must appear before any code");
8172 reportParseError(
"expected .module option identifier");
8176 if (Option ==
"oddspreg") {
8177 clearModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
8181 getTargetStreamer().updateABIInfo(*
this);
8186 getTargetStreamer().emitDirectiveModuleOddSPReg();
8190 reportParseError(
"unexpected token, expected end of statement");
8195 }
else if (Option ==
"nooddspreg") {
8197 return Error(L,
"'.module nooddspreg' requires the O32 ABI");
8200 setModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
8204 getTargetStreamer().updateABIInfo(*
this);
8209 getTargetStreamer().emitDirectiveModuleOddSPReg();
8213 reportParseError(
"unexpected token, expected end of statement");
8218 }
else if (Option ==
"fp") {
8219 return parseDirectiveModuleFP();
8220 }
else if (Option ==
"softfloat") {
8221 setModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
8225 getTargetStreamer().updateABIInfo(*
this);
8230 getTargetStreamer().emitDirectiveModuleSoftFloat();
8234 reportParseError(
"unexpected token, expected end of statement");
8239 }
else if (Option ==
"hardfloat") {
8240 clearModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
8244 getTargetStreamer().updateABIInfo(*
this);
8249 getTargetStreamer().emitDirectiveModuleHardFloat();
8253 reportParseError(
"unexpected token, expected end of statement");
8258 }
else if (Option ==
"mt") {
8259 setModuleFeatureBits(Mips::FeatureMT,
"mt");
8263 getTargetStreamer().updateABIInfo(*
this);
8268 getTargetStreamer().emitDirectiveModuleMT();
8272 reportParseError(
"unexpected token, expected end of statement");
8277 }
else if (Option ==
"crc") {
8278 setModuleFeatureBits(Mips::FeatureCRC,
"crc");
8282 getTargetStreamer().updateABIInfo(*
this);
8287 getTargetStreamer().emitDirectiveModuleCRC();
8291 reportParseError(
"unexpected token, expected end of statement");
8296 }
else if (Option ==
"nocrc") {
8297 clearModuleFeatureBits(Mips::FeatureCRC,
"crc");
8301 getTargetStreamer().updateABIInfo(*
this);
8306 getTargetStreamer().emitDirectiveModuleNoCRC();
8310 reportParseError(
"unexpected token, expected end of statement");
8315 }
else if (Option ==
"virt") {
8316 setModuleFeatureBits(Mips::FeatureVirt,
"virt");
8320 getTargetStreamer().updateABIInfo(*
this);
8325 getTargetStreamer().emitDirectiveModuleVirt();
8329 reportParseError(
"unexpected token, expected end of statement");
8334 }
else if (Option ==
"novirt") {
8335 clearModuleFeatureBits(Mips::FeatureVirt,
"virt");
8339 getTargetStreamer().updateABIInfo(*
this);
8344 getTargetStreamer().emitDirectiveModuleNoVirt();
8348 reportParseError(
"unexpected token, expected end of statement");
8353 }
else if (Option ==
"ginv") {
8354 setModuleFeatureBits(Mips::FeatureGINV,
"ginv");
8358 getTargetStreamer().updateABIInfo(*
this);
8363 getTargetStreamer().emitDirectiveModuleGINV();
8367 reportParseError(
"unexpected token, expected end of statement");
8372 }
else if (Option ==
"noginv") {
8373 clearModuleFeatureBits(Mips::FeatureGINV,
"ginv");
8377 getTargetStreamer().updateABIInfo(*
this);
8382 getTargetStreamer().emitDirectiveModuleNoGINV();
8386 reportParseError(
"unexpected token, expected end of statement");
8392 return Error(L,
"'" + Twine(Option) +
"' is not a valid .module option.");
8400bool MipsAsmParser::parseDirectiveModuleFP() {
8401 MCAsmParser &Parser = getParser();
8402 AsmLexer &Lexer = getLexer();
8405 reportParseError(
"unexpected token, expected equals sign '='");
8411 if (!parseFpABIValue(FpABI,
".module"))
8415 reportParseError(
"unexpected token, expected end of statement");
8421 getTargetStreamer().updateABIInfo(*
this);
8426 getTargetStreamer().emitDirectiveModuleFP();
8433 StringRef Directive) {
8434 MCAsmParser &Parser = getParser();
8435 AsmLexer &Lexer = getLexer();
8436 bool ModuleLevelOptions = Directive ==
".module";
8442 if (
Value !=
"xx") {
8443 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
8448 reportParseError(
"'" + Directive +
" fp=xx' requires the O32 ABI");
8452 FpABI = MipsABIFlagsSection::FpABIKind::XX;
8453 if (ModuleLevelOptions) {
8454 setModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8455 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8457 setFeatureBits(Mips::FeatureFPXX,
"fpxx");
8458 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8468 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
8474 reportParseError(
"'" + Directive +
" fp=32' requires the O32 ABI");
8478 FpABI = MipsABIFlagsSection::FpABIKind::S32;
8479 if (ModuleLevelOptions) {
8480 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8481 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8483 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
8484 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8487 FpABI = MipsABIFlagsSection::FpABIKind::S64;
8488 if (ModuleLevelOptions) {
8489 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8490 setModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8492 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
8493 setFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8503bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
8509 MCAsmParser &Parser = getParser();
8510 StringRef IDVal = DirectiveID.
getString();
8512 if (IDVal ==
".cpadd") {
8513 parseDirectiveCpAdd(DirectiveID.
getLoc());
8516 if (IDVal ==
".cpload") {
8517 parseDirectiveCpLoad(DirectiveID.
getLoc());
8520 if (IDVal ==
".cprestore") {
8521 parseDirectiveCpRestore(DirectiveID.
getLoc());
8524 if (IDVal ==
".cplocal") {
8525 parseDirectiveCpLocal(DirectiveID.
getLoc());
8528 if (IDVal ==
".ent") {
8532 reportParseError(
"expected identifier after .ent");
8546 reportParseError(
"unexpected token, expected end of statement");
8550 const MCExpr *DummyNumber;
8551 int64_t DummyNumberVal;
8555 reportParseError(
"expected number after comma");
8558 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
8559 reportParseError(
"expected an absolute expression after comma");
8566 reportParseError(
"unexpected token, expected end of statement");
8572 getTargetStreamer().emitDirectiveEnt(*Sym);
8574 IsCpRestoreSet =
false;
8578 if (IDVal ==
".end") {
8582 reportParseError(
"expected identifier after .end");
8587 reportParseError(
"unexpected token, expected end of statement");
8591 if (CurrentFn ==
nullptr) {
8592 reportParseError(
".end used without .ent");
8596 if ((SymbolName != CurrentFn->
getName())) {
8597 reportParseError(
".end symbol does not match .ent symbol");
8601 getTargetStreamer().emitDirectiveEnd(SymbolName);
8602 CurrentFn =
nullptr;
8603 IsCpRestoreSet =
false;
8607 if (IDVal ==
".frame") {
8610 ParseStatus Res = parseAnyRegister(TmpReg);
8612 reportParseError(
"expected stack register");
8616 MipsOperand &StackRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
8617 if (!StackRegOpnd.isGPRAsmReg()) {
8618 reportParseError(StackRegOpnd.getStartLoc(),
8619 "expected general purpose register");
8622 MCRegister StackReg = StackRegOpnd.getGPR32Reg();
8627 reportParseError(
"unexpected token, expected comma");
8632 const MCExpr *FrameSize;
8633 int64_t FrameSizeVal;
8636 reportParseError(
"expected frame size value");
8640 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
8641 reportParseError(
"frame size not an absolute expression");
8648 reportParseError(
"unexpected token, expected comma");
8654 Res = parseAnyRegister(TmpReg);
8656 reportParseError(
"expected return register");
8660 MipsOperand &ReturnRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
8661 if (!ReturnRegOpnd.isGPRAsmReg()) {
8662 reportParseError(ReturnRegOpnd.getStartLoc(),
8663 "expected general purpose register");
8669 reportParseError(
"unexpected token, expected end of statement");
8673 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
8674 ReturnRegOpnd.getGPR32Reg());
8675 IsCpRestoreSet =
false;
8679 if (IDVal ==
".set") {
8680 parseDirectiveSet();
8684 if (IDVal ==
".mask" || IDVal ==
".fmask") {
8695 const MCExpr *BitMask;
8699 reportParseError(
"expected bitmask value");
8703 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
8704 reportParseError(
"bitmask not an absolute expression");
8711 reportParseError(
"unexpected token, expected comma");
8716 const MCExpr *FrameOffset;
8717 int64_t FrameOffsetVal;
8720 reportParseError(
"expected frame offset value");
8724 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
8725 reportParseError(
"frame offset not an absolute expression");
8731 reportParseError(
"unexpected token, expected end of statement");
8735 if (IDVal ==
".mask")
8736 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
8738 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
8742 if (IDVal ==
".nan")
8743 return parseDirectiveNaN();
8745 if (IDVal ==
".gpword") {
8746 parseDirectiveGpWord();
8750 if (IDVal ==
".gpdword") {
8751 parseDirectiveGpDWord();
8755 if (IDVal ==
".dtprelword") {
8756 parseDirectiveDtpRelWord();
8760 if (IDVal ==
".dtpreldword") {
8761 parseDirectiveDtpRelDWord();
8765 if (IDVal ==
".tprelword") {
8766 parseDirectiveTpRelWord();
8770 if (IDVal ==
".tpreldword") {
8771 parseDirectiveTpRelDWord();
8775 if (IDVal ==
".option") {
8776 parseDirectiveOption();
8780 if (IDVal ==
".abicalls") {
8781 getTargetStreamer().emitDirectiveAbiCalls();
8784 "unexpected token, expected end of statement");
8789 if (IDVal ==
".cpsetup") {
8790 parseDirectiveCPSetup();
8793 if (IDVal ==
".cpreturn") {
8794 parseDirectiveCPReturn();
8797 if (IDVal ==
".module") {
8798 parseDirectiveModule();
8801 if (IDVal ==
".llvm_internal_mips_reallow_module_directive") {
8802 parseInternalDirectiveReallowModule();
8805 if (IDVal ==
".insn") {
8806 parseInsnDirective();
8809 if (IDVal ==
".rdata") {
8810 parseRSectionDirective(
".rodata");
8813 if (IDVal ==
".sbss") {
8817 if (IDVal ==
".sdata") {
8825bool MipsAsmParser::parseInternalDirectiveReallowModule() {
8828 reportParseError(
"unexpected token, expected end of statement");
8832 getTargetStreamer().reallowModuleDirective();
8846#define GET_REGISTER_MATCHER
8847#define GET_MATCHER_IMPLEMENTATION
8848#define GET_MNEMONIC_SPELL_CHECKER
8849#include "MipsGenAsmMatcher.inc"
8851bool MipsAsmParser::mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID) {
8853 const MatchEntry *Start, *End;
8854 switch (VariantID) {
8856 case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0);
break;
8859 auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
8860 return MnemonicRange.first != MnemonicRange.second;
static const TargetRegisterClass * getRegClass(const MachineInstr &MI, Register Reg)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
This file declares a class to represent arbitrary precision floating point values and provide a varie...
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
static Value * expandAbs(CallInst *Orig)
std::pair< Instruction::BinaryOps, Value * > OffsetOp
Find all possible pairs (BinOp, RHS) that BinOp V, RHS can be simplified.
static constexpr Value * getValue(Ty &ValueOrUse)
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static FeatureBitset getFeatures(MCSubtargetInfo &STI, StringRef CPU, StringRef TuneCPU, StringRef FS, StringTable ProcNames, ArrayRef< SubtargetSubTypeKV > ProcDesc, ArrayRef< SubtargetFeatureKV > ProcFeatures)
static bool hasFeature(StringRef Feature, const FeatureBitset &FeatureBits, ArrayRef< SubtargetFeatureKV > ProcFeatures)
static unsigned countMCSymbolRefExpr(const MCExpr *Expr)
static std::string MipsMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, unsigned VariantID=0)
static uint64_t convertIntToDoubleImm(uint64_t ImmOp64)
static uint32_t covertDoubleImmToSingleImm(uint64_t ImmOp64)
static unsigned getRegisterForMxtrDSP(MCInst &Inst, bool IsMFDSP)
static bool hasShortDelaySlot(MCInst &Inst)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsAsmParser()
static bool needsExpandMemInst(MCInst &Inst, const MCInstrDesc &MCID)
cl::opt< bool > EmitJalrReloc
static bool isShiftedUIntAtAnyPosition(uint64_t x)
Can the value be represented by a unsigned N-bit value and a shift left?
static bool isEvaluated(const MCExpr *Expr)
static unsigned getRegisterForMxtrC0(MCInst &Inst, bool IsMFTC0)
static const MCSymbol * getSingleMCSymbol(const MCExpr *Expr)
static MCRegister nextReg(MCRegister Reg)
static unsigned getRegisterForMxtrFP(MCInst &Inst, bool IsMFTC1)
cl::opt< bool > NoZeroDivCheck
static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands, uint64_t ErrorInfo)
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static const fltSemantics & IEEEdouble()
APInt bitcastToAPInt() const
uint64_t getZExtValue() const
Get zero extended value.
SMLoc getLoc() const
Get the current source location.
const AsmToken peekTok(bool ShouldSkipSpace=true)
Look ahead at the next token to be lexed.
bool is(AsmToken::TokenKind K) const
Check if the current token has kind K.
bool isNot(AsmToken::TokenKind K) const
Check if the current token has kind K.
Target independent representation for an assembler token.
LLVM_ABI SMLoc getLoc() const
int64_t getIntVal() const
bool isNot(TokenKind K) const
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
bool is(TokenKind K) const
TokenKind getKind() const
LLVM_ABI SMRange getLocRange() const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
Base class for user error types.
Container class for subtarget features.
void printExpr(raw_ostream &, const MCExpr &) const
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
bool parseToken(AsmToken::TokenKind T, const Twine &Msg="unexpected token")
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
Binary assembler expressions.
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
static LLVM_ABI const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
@ LShr
Logical shift right.
@ Xor
Bitwise exclusive or.
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Base class for the full range of assembler expressions which are needed for parsing.
LLVM_ABI bool evaluateAsRelocatable(MCValue &Res, const MCAssembler *Asm) const
Try to evaluate the expression to a relocatable value, i.e.
@ Unary
Unary expressions.
@ Constant
Constant expressions.
@ SymbolRef
References to labels and assigned expressions.
@ Target
Target specific expression.
@ Specifier
Expression with a relocation specifier.
@ Binary
Binary expressions.
Instances of this class represent a single low-level machine instruction.
unsigned getNumOperands() const
unsigned getOpcode() const
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
const MCOperand & getOperand(unsigned i) const
Describe properties that are true of each instruction in the target description file.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
ArrayRef< MCOperandInfo > operands() const
bool mayStore() const
Return true if this instruction could possibly modify memory.
bool mayLoad() const
Return true if this instruction could possibly read memory.
bool isBranch() const
Returns true if this is a conditional, unconditional, or indirect branch.
bool isCall() const
Return true if the instruction is a call.
bool hasDelaySlot() const
Returns true if the specified instruction has a delay slot which must be filled by the code generator...
Interface to description of machine instruction set.
This holds information about one operand of a machine instruction, indicating the register class for ...
uint8_t OperandType
Information about the type of the operand.
Instances of this class represent operands of the MCInst class.
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
MCRegister getReg() const
Returns the register number.
const MCExpr * getExpr() const
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual bool isReg() const =0
isReg - Is this a register operand?
virtual MCRegister getReg() const =0
MCRegister getRegister(unsigned i) const
getRegister - Return the specified register in the class.
uint16_t getEncodingValue(MCRegister Reg) const
Returns the encoding for Reg.
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
Wrapper class representing physical registers. Should be passed by value.
constexpr bool isValid() const
constexpr unsigned id() const
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
Streaming machine code generation interface.
virtual void emitRelocDirective(const MCExpr &Offset, StringRef Name, const MCExpr *Expr, SMLoc Loc={})
Record a relocation described by the .reloc directive.
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
void setFeatureBits(const FeatureBitset &FeatureBits_)
const Triple & getTargetTriple() const
const FeatureBitset & getFeatureBits() const
const FeatureBitset & ToggleFeature(uint64_t FB)
Toggle a feature and return the re-computed feature bits.
virtual unsigned getHwMode(enum HwModeType type=HwMode_Default) const
HwMode ID corresponding to the 'type' parameter is retrieved from the HwMode bit set of the current s...
Represent a reference to a symbol from inside an expression.
uint16_t getSpecifier() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
bool isInSection() const
isInSection - Check if this symbol is defined in some section (i.e., it is defined but not absolute).
bool isUndefined() const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).
StringRef getName() const
getName - Get the symbol name.
bool isVariable() const
isVariable - Check if this is a variable symbol.
const MCExpr * getVariableValue() const
Get the expression of the variable symbol.
bool isTemporary() const
isTemporary - Check if this is an assembler temporary symbol.
MCTargetAsmParser - Generic interface to target specific assembly parsers.
MCStreamer & getStreamer()
Unary assembler expressions.
const MCSymbol * getAddSym() const
int64_t getConstant() const
const MCSymbol * getSubSym() const
static const char * getRegisterName(MCRegister Reg, unsigned AltIdx=Mips::NoRegAltName)
void emitRRX(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, MCOperand Op2, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveSetReorder()
void emitRRRX(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, MCRegister Reg2, MCOperand Op3, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRX(unsigned Opcode, MCRegister Reg0, MCOperand Op1, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitR(unsigned Opcode, MCRegister Reg0, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void setUsesMicroMips()
void emitRRI(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, int16_t Imm, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitEmptyDelaySlot(bool hasShortDelaySlot, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRI(unsigned Opcode, MCRegister Reg0, int32_t Imm, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRR(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, SMLoc IDLoc, const MCSubtargetInfo *STI)
void updateABIInfo(const PredicateLibrary &P)
void emitRRIII(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, int16_t Imm0, int16_t Imm1, int16_t Imm2, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitDSLL(MCRegister DstReg, MCRegister SrcReg, int16_t ShiftAmount, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitGPRestore(int Offset, SMLoc IDLoc, const MCSubtargetInfo *STI)
Emit the $gp restore operation for .cprestore.
void emitNop(SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRRR(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, MCRegister Reg2, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveSetNoReorder()
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
static constexpr StatusTy Failure
constexpr bool isSuccess() const
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
constexpr bool isNoMatch() const
constexpr unsigned id() const
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
void push_back(const T &Elt)
iterator find(StringRef Key)
Represent a constant reference to a string, i.e.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
Check if the string is empty.
LLVM_ABI bool isLittleEndian() const
Tests whether the target triple is little endian.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
LLVM_ABI LLVM_READONLY ARMABI computeTargetABI(const Triple &TT, StringRef ABIName="")
LLVM_ABI bool parseAssignmentExpression(StringRef Name, bool allow_redef, MCAsmParser &Parser, MCSymbol *&Symbol, const MCExpr *&Value)
Parse a value expression and return whether it can be assigned to a symbol with the given name.
MCRegister matchRegisterName(StringRef Name, const MCRegisterInfo &MRI, unsigned RegClassID, unsigned AltIdx)
Match a symbolic name in RegClassID, or return an invalid register.
int getCPURegisterIndex(StringRef Name, const MCRegisterInfo &MRI, unsigned AltIdx, bool *IsDeprecated=nullptr)
Return a GPR name's hardware index, or -1 if unknown.
WebAssemblyABI getABI(StringRef Name)
Parse an ABI name into the corresponding enum.
@ CE
Windows NT (Windows on ARM)
LLVM_ABI StringRef getABIName()
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
unsigned getOpcode(const VPValue *V)
Return the instruction opcode for the recipe defining V or 0 for unsupported recipes and VPValues not...
This is an optimization pass for GlobalISel generic memory operations.
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Target & getTheMips64Target()
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
static StringRef getCPU(StringRef CPU)
Processes a CPU name.
int bit_width(T Value)
Returns the number of bits needed to represent Value if Value is nonzero.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
@ Success
The lock was released successfully.
Target & getTheMips64elTarget()
uint64_t offsetToAlignment(uint64_t Value, Align Alignment)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
@ Ref
The access may reference the value stored in memory.
To bit_cast(const From &from) noexcept
Target & getTheMipselTarget()
DWARFExpression::Operation Op
constexpr bool isShiftedInt(int64_t x)
Checks if a signed integer is an N bit number shifted left by S.
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
static uint16_t getSpecifier(const MCSymbolRefExpr *SRE)
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
Target & getTheMipsTarget()
constexpr bool isShiftedUInt(uint64_t x)
Checks if a unsigned integer is an N bit number shifted left by S.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...