64#define DEBUG_TYPE "mips-asm-parser"
74class MipsAssemblerOptions {
76 MipsAssemblerOptions(
const FeatureBitset &Features_) : Features(Features_) {}
78 MipsAssemblerOptions(
const MipsAssemblerOptions *Opts) {
79 ATReg = Opts->getATRegIndex();
80 Reorder = Opts->isReorder();
81 Macro = Opts->isMacro();
82 Features = Opts->getFeatures();
85 unsigned getATRegIndex()
const {
return ATReg; }
86 bool setATRegIndex(
unsigned Reg) {
94 bool isReorder()
const {
return Reorder; }
95 void setReorder() { Reorder =
true; }
96 void setNoReorder() { Reorder =
false; }
98 bool isMacro()
const {
return Macro; }
99 void setMacro() {
Macro =
true; }
100 void setNoMacro() {
Macro =
false; }
102 const FeatureBitset &
getFeatures()
const {
return Features; }
103 void setFeatures(
const FeatureBitset &Features_) { Features = Features_; }
110 static const FeatureBitset AllArchRelatedMask;
116 FeatureBitset Features;
121const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
122 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
123 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
124 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
125 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
126 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
127 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
128 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
129 Mips::FeatureCnMipsP, Mips::FeatureFP64Bit, Mips::FeatureGP64Bit,
136 MipsTargetStreamer &getTargetStreamer() {
137 assert(getParser().getStreamer().getTargetStreamer() &&
138 "do not have a target streamer");
139 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
140 return static_cast<MipsTargetStreamer &
>(TS);
143 const MipsMCOptions &CLOpts;
153 bool CurForbiddenSlotAttr;
156 unsigned CpSaveLocation;
158 bool CpSaveLocationIsRegister;
161 StringMap<AsmToken> RegisterSets;
164 void printWarningWithFixIt(
const Twine &
Msg,
const Twine &FixMsg,
165 SMRange
Range,
bool ShowColors =
true);
168 template <
unsigned Opcode,
bool IsMFTR>
169 void ConvertMTTransferCOP0Operands(MCInst &Inst,
172 ConvertMTTransferCOP0Operands<Mips::MFTR, true>(Inst,
Operands);
175 ConvertMTTransferCOP0Operands<Mips::MTTR, false>(Inst,
Operands);
178#define GET_ASSEMBLER_HEADER
179#include "MipsGenAsmMatcher.inc"
182 checkEarlyTargetMatchPredicate(
MCInst &Inst,
184 unsigned checkTargetMatchPredicate(
MCInst &Inst)
override;
186 bool matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
189 bool MatchingInlineAsm)
override;
194 SMLoc &EndLoc)
override;
200 bool mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID);
205 bool ParseDirective(
AsmToken DirectiveID)
override;
209 const MCExpr *parseMemOffset();
220 const MCExpr *parseRelocExpr();
221 bool parsePrimaryExpr(
const MCExpr *&Res,
SMLoc &EndLoc)
override;
227 enum MacroExpanderResultTy {
234 MacroExpanderResultTy tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
236 const MCSubtargetInfo *STI);
238 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
239 const MCSubtargetInfo *STI);
241 bool loadImmediate(int64_t ImmValue, MCRegister DstReg, MCRegister SrcReg,
242 bool Is32BitImm,
bool IsAddress, SMLoc IDLoc,
243 MCStreamer &Out,
const MCSubtargetInfo *STI);
245 bool loadAndAddSymbolAddress(
const MCExpr *SymExpr, MCRegister DstReg,
246 MCRegister SrcReg,
bool Is32BitSym, SMLoc IDLoc,
247 MCStreamer &Out,
const MCSubtargetInfo *STI);
249 bool emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc, MCSymbol *Sym);
251 bool expandLoadImm(MCInst &Inst,
bool Is32BitImm, SMLoc IDLoc,
252 MCStreamer &Out,
const MCSubtargetInfo *STI);
254 bool expandLoadSingleImmToGPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
255 const MCSubtargetInfo *STI);
256 bool expandLoadSingleImmToFPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
257 const MCSubtargetInfo *STI);
258 bool expandLoadDoubleImmToGPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
259 const MCSubtargetInfo *STI);
260 bool expandLoadDoubleImmToFPR(MCInst &Inst,
bool Is64FPU, SMLoc IDLoc,
261 MCStreamer &Out,
const MCSubtargetInfo *STI);
263 bool expandLoadAddress(MCRegister DstReg, MCRegister BaseReg,
264 const MCOperand &
Offset,
bool Is32BitAddress,
265 SMLoc IDLoc, MCStreamer &Out,
266 const MCSubtargetInfo *STI);
268 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
269 const MCSubtargetInfo *STI);
271 void expandMem16Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
272 const MCSubtargetInfo *STI,
bool IsLoad);
273 void expandMem9Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
274 const MCSubtargetInfo *STI,
bool IsLoad);
276 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
277 const MCSubtargetInfo *STI);
279 bool expandAliasImmediate(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
280 const MCSubtargetInfo *STI);
282 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
283 const MCSubtargetInfo *STI);
285 bool expandCondBranches(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
286 const MCSubtargetInfo *STI);
288 bool expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
289 const MCSubtargetInfo *STI,
const bool IsMips64,
292 bool expandTrunc(MCInst &Inst,
bool IsDouble,
bool Is64FPU, SMLoc IDLoc,
293 MCStreamer &Out,
const MCSubtargetInfo *STI);
295 bool expandUlh(MCInst &Inst,
bool Signed, SMLoc IDLoc, MCStreamer &Out,
296 const MCSubtargetInfo *STI);
298 bool expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
299 const MCSubtargetInfo *STI);
301 bool expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
302 const MCSubtargetInfo *STI);
304 bool expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
305 const MCSubtargetInfo *STI);
307 bool expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
308 const MCSubtargetInfo *STI);
310 bool expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
311 const MCSubtargetInfo *STI);
313 bool expandSle(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
314 const MCSubtargetInfo *STI);
316 bool expandSleImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
317 const MCSubtargetInfo *STI);
319 bool expandRotation(MCInst &Inst, SMLoc IDLoc,
320 MCStreamer &Out,
const MCSubtargetInfo *STI);
321 bool expandRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
322 const MCSubtargetInfo *STI);
323 bool expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
324 const MCSubtargetInfo *STI);
325 bool expandDRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
326 const MCSubtargetInfo *STI);
328 bool expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
329 const MCSubtargetInfo *STI);
331 bool expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
332 const MCSubtargetInfo *STI);
334 bool expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
335 const MCSubtargetInfo *STI);
337 bool expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
338 const MCSubtargetInfo *STI);
340 bool expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
341 const MCSubtargetInfo *STI);
343 bool expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
344 const MCSubtargetInfo *STI,
bool IsLoad);
346 bool expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
347 const MCSubtargetInfo *STI);
349 bool expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
350 const MCSubtargetInfo *STI);
352 bool expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
353 const MCSubtargetInfo *STI);
355 bool expandSne(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
356 const MCSubtargetInfo *STI);
358 bool expandSneI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
359 const MCSubtargetInfo *STI);
361 bool expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
362 const MCSubtargetInfo *STI);
364 bool expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
365 const MCSubtargetInfo *STI);
367 bool reportParseError(
const Twine &ErrorMsg);
368 bool reportParseError(SMLoc Loc,
const Twine &ErrorMsg);
370 bool parseSetMips0Directive();
371 bool parseSetArchDirective();
372 bool parseSetFeature(
uint64_t Feature);
373 bool isPicAndNotNxxAbi();
374 bool parseDirectiveCpAdd(SMLoc Loc);
375 bool parseDirectiveCpLoad(SMLoc Loc);
376 bool parseDirectiveCpLocal(SMLoc Loc);
377 bool parseDirectiveCpRestore(SMLoc Loc);
378 bool parseDirectiveCPSetup();
379 bool parseDirectiveCPReturn();
380 bool parseDirectiveNaN();
381 bool parseDirectiveSet();
382 bool parseDirectiveOption();
383 bool parseInsnDirective();
384 bool parseRSectionDirective(StringRef Section);
385 bool parseSSectionDirective(StringRef Section,
unsigned Type);
387 bool parseSetAtDirective();
388 bool parseSetNoAtDirective();
389 bool parseSetMacroDirective();
390 bool parseSetNoMacroDirective();
391 bool parseSetMsaDirective();
392 bool parseSetNoMsaDirective();
393 bool parseSetNoDspDirective();
394 bool parseSetNoMips3DDirective();
395 bool parseSetReorderDirective();
396 bool parseSetNoReorderDirective();
397 bool parseSetMips16Directive();
398 bool parseSetNoMips16Directive();
399 bool parseSetFpDirective();
400 bool parseSetOddSPRegDirective();
401 bool parseSetNoOddSPRegDirective();
402 bool parseSetPopDirective();
403 bool parseSetPushDirective();
404 bool parseSetSoftFloatDirective();
405 bool parseSetHardFloatDirective();
406 bool parseSetMtDirective();
407 bool parseSetNoMtDirective();
408 bool parseSetNoCRCDirective();
409 bool parseSetNoVirtDirective();
410 bool parseSetNoGINVDirective();
411 bool parseSetNoEVADirective();
413 bool parseSetAssignment();
415 bool parseDirectiveGpWord();
416 bool parseDirectiveGpDWord();
417 bool parseDirectiveDtpRelWord();
418 bool parseDirectiveDtpRelDWord();
419 bool parseDirectiveTpRelWord();
420 bool parseDirectiveTpRelDWord();
421 bool parseDirectiveModule();
422 bool parseDirectiveModuleFP();
424 StringRef Directive);
426 bool parseInternalDirectiveReallowModule();
428 bool eatComma(StringRef ErrorStr);
430 int matchCPURegisterName(StringRef Symbol);
432 int matchHWRegsRegisterName(StringRef Symbol);
434 int matchFPURegisterName(StringRef Name);
436 int matchFCCRegisterName(StringRef Name);
438 int matchACRegisterName(StringRef Name);
440 int matchMSA128RegisterName(StringRef Name);
442 int matchMSA128CtrlRegisterName(StringRef Name);
444 MCRegister
getReg(
int RC,
int RegNo);
449 MCRegister getATReg(SMLoc Loc);
453 bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
454 const MCSubtargetInfo *STI);
478 void selectArch(StringRef ArchFeature) {
479 MCSubtargetInfo &STI = copySTI();
481 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
483 setAvailableFeatures(
488 void setFeatureBits(
uint64_t Feature, StringRef FeatureString) {
490 MCSubtargetInfo &STI = copySTI();
491 setAvailableFeatures(
497 void clearFeatureBits(
uint64_t Feature, StringRef FeatureString) {
499 MCSubtargetInfo &STI = copySTI();
500 setAvailableFeatures(
506 void setModuleFeatureBits(
uint64_t Feature, StringRef FeatureString) {
507 setFeatureBits(Feature, FeatureString);
508 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
511 void clearModuleFeatureBits(
uint64_t Feature, StringRef FeatureString) {
512 clearFeatureBits(Feature, FeatureString);
513 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
517 enum MipsMatchResultTy {
518 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
519 Match_RequiresDifferentOperands,
520 Match_RequiresNoZeroRegister,
521 Match_RequiresSameSrcAndDst,
522 Match_NoFCCRegisterForCurrentISA,
523 Match_NonZeroOperandForSync,
524 Match_NonZeroOperandForMTCX,
525 Match_RequiresPosSizeRange0_32,
526 Match_RequiresPosSizeRange33_64,
527 Match_RequiresPosSizeUImm6,
528#define GET_OPERAND_DIAGNOSTIC_TYPES
529#include "MipsGenAsmMatcher.inc"
530#undef GET_OPERAND_DIAGNOSTIC_TYPES
533 MipsAsmParser(
const MCSubtargetInfo &sti, MCAsmParser &parser,
534 const MCInstrInfo &MII)
535 : MCTargetAsmParser(sti, MII),
538 sti.getTargetTriple(),
548 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
551 AssemblerOptions.push_back(
552 std::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
555 AssemblerOptions.push_back(
556 std::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
558 getTargetStreamer().updateABIInfo(*
this);
560 if (!isABI_O32() && !useOddSPReg() != 0)
565 CurForbiddenSlotAttr =
false;
566 IsPicEnabled =
getContext().getObjectFileInfo()->isPositionIndependent();
568 IsCpRestoreSet =
false;
569 CpRestoreOffset = -1;
570 GPReg = ABI.GetGlobalPtr();
575 if (getSTI().
getCPU() ==
"mips64r6" && inMicroMipsMode())
578 if (!isABI_O32() && inMicroMipsMode())
583 bool hasEightFccRegisters()
const {
return hasMips4() || hasMips32(); }
585 bool isGP64bit()
const {
586 return getSTI().hasFeature(Mips::FeatureGP64Bit);
589 bool isFP64bit()
const {
590 return getSTI().hasFeature(Mips::FeatureFP64Bit);
593 bool isJalrRelocAvailable(
const MCExpr *JalExpr) {
594 if (!CLOpts.jalr_reloc)
602 return ABI.IsN32() || ABI.IsN64();
606 const MipsABIInfo &
getABI()
const {
return ABI; }
607 bool isABI_N32()
const {
return ABI.IsN32(); }
608 bool isABI_N64()
const {
return ABI.IsN64(); }
609 bool isABI_O32()
const {
return ABI.IsO32(); }
610 bool isABI_FPXX()
const {
611 return getSTI().hasFeature(Mips::FeatureFPXX);
614 bool useOddSPReg()
const {
615 return !(getSTI().hasFeature(Mips::FeatureNoOddSPReg));
618 bool inMicroMipsMode()
const {
619 return getSTI().hasFeature(Mips::FeatureMicroMips);
622 bool hasMips1()
const {
623 return getSTI().hasFeature(Mips::FeatureMips1);
626 bool hasMips2()
const {
627 return getSTI().hasFeature(Mips::FeatureMips2);
630 bool hasMips3()
const {
631 return getSTI().hasFeature(Mips::FeatureMips3);
634 bool hasMips4()
const {
635 return getSTI().hasFeature(Mips::FeatureMips4);
638 bool hasMips5()
const {
639 return getSTI().hasFeature(Mips::FeatureMips5);
642 bool hasMips32()
const {
643 return getSTI().hasFeature(Mips::FeatureMips32);
646 bool hasMips64()
const {
647 return getSTI().hasFeature(Mips::FeatureMips64);
650 bool hasMips32r2()
const {
651 return getSTI().hasFeature(Mips::FeatureMips32r2);
654 bool hasMips64r2()
const {
655 return getSTI().hasFeature(Mips::FeatureMips64r2);
658 bool hasMips32r3()
const {
659 return (getSTI().
hasFeature(Mips::FeatureMips32r3));
662 bool hasMips64r3()
const {
663 return (getSTI().
hasFeature(Mips::FeatureMips64r3));
666 bool hasMips32r5()
const {
667 return (getSTI().
hasFeature(Mips::FeatureMips32r5));
670 bool hasMips64r5()
const {
671 return (getSTI().
hasFeature(Mips::FeatureMips64r5));
674 bool hasMips32r6()
const {
675 return getSTI().hasFeature(Mips::FeatureMips32r6);
678 bool hasMips64r6()
const {
679 return getSTI().hasFeature(Mips::FeatureMips64r6);
682 bool hasDSP()
const {
683 return getSTI().hasFeature(Mips::FeatureDSP);
686 bool hasDSPR2()
const {
687 return getSTI().hasFeature(Mips::FeatureDSPR2);
690 bool hasDSPR3()
const {
691 return getSTI().hasFeature(Mips::FeatureDSPR3);
694 bool hasMSA()
const {
695 return getSTI().hasFeature(Mips::FeatureMSA);
698 bool hasCnMips()
const {
699 return (getSTI().
hasFeature(Mips::FeatureCnMips));
702 bool hasCnMipsP()
const {
703 return (getSTI().
hasFeature(Mips::FeatureCnMipsP));
706 bool isR5900()
const {
return (getSTI().
hasFeature(Mips::FeatureR5900)); }
712 bool inMips16Mode()
const {
713 return getSTI().hasFeature(Mips::FeatureMips16);
716 bool useTraps()
const {
717 return getSTI().hasFeature(Mips::FeatureUseTCCInDIV);
720 bool useSoftFloat()
const {
721 return getSTI().hasFeature(Mips::FeatureSoftFloat);
724 bool isSingleFloat()
const {
725 return getSTI().hasFeature(Mips::FeatureSingleFloat);
729 return getSTI().hasFeature(Mips::FeatureMT);
732 bool hasCRC()
const {
733 return getSTI().hasFeature(Mips::FeatureCRC);
736 bool hasVirt()
const {
737 return getSTI().hasFeature(Mips::FeatureVirt);
740 bool hasGINV()
const {
741 return getSTI().hasFeature(Mips::FeatureGINV);
744 bool hasForbiddenSlot(
const MCInstrDesc &MCID)
const {
748 bool SafeInForbiddenSlot(
const MCInstrDesc &MCID)
const {
752 void onEndOfFile()
override;
755 void warnIfRegIndexIsAT(MCRegister RegIndex, SMLoc Loc);
757 void warnIfNoMacro(SMLoc Loc);
759 bool isLittle()
const {
return IsLittleEndian; }
761 bool areEqualRegs(
const MCParsedAsmOperand &Op1,
762 const MCParsedAsmOperand &Op2)
const override;
777 RegKind_MSACtrl = 16,
782 RegKind_HWRegs = 256,
786 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
787 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
788 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
801 MipsOperand(KindTy K, MipsAsmParser &Parser) : Kind(
K), AsmParser(Parser) {}
803 ~MipsOperand()
override {
812 case k_RegisterIndex:
820 MipsAsmParser &AsmParser;
831 const MCRegisterInfo *RegInfo;
849 struct RegIdxOp RegIdx;
852 struct RegListOp RegList;
855 SMLoc StartLoc, EndLoc;
858 static std::unique_ptr<MipsOperand> CreateReg(
unsigned Index, StringRef Str,
860 const MCRegisterInfo *RegInfo,
862 MipsAsmParser &Parser) {
863 auto Op = std::make_unique<MipsOperand>(k_RegisterIndex, Parser);
865 Op->RegIdx.RegInfo = RegInfo;
866 Op->RegIdx.Kind = RegKind;
867 Op->RegIdx.Tok.Data = Str.data();
868 Op->RegIdx.Tok.Length = Str.size();
877 MCRegister getGPR32Reg()
const {
878 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
879 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
880 unsigned ClassID = Mips::GPR32RegClassID;
881 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
886 MCRegister getGPRMM16Reg()
const {
887 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
888 unsigned ClassID = Mips::GPR32RegClassID;
889 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
894 MCRegister getGPR64Reg()
const {
895 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
896 unsigned ClassID = Mips::GPR64RegClassID;
897 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
903 MCRegister getAFGR64Reg()
const {
904 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
905 if (RegIdx.Index % 2 != 0)
906 AsmParser.Warning(StartLoc,
"Float register should be even.");
907 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
908 .getRegister(RegIdx.Index / 2);
913 MCRegister getFGR64Reg()
const {
914 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
915 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
916 .getRegister(RegIdx.Index);
921 MCRegister getFGR32Reg()
const {
922 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
923 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
924 .getRegister(RegIdx.Index);
929 MCRegister getFCCReg()
const {
930 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) &&
"Invalid access!");
931 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
932 .getRegister(RegIdx.Index);
937 MCRegister getMSA128Reg()
const {
938 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) &&
"Invalid access!");
941 unsigned ClassID = Mips::MSA128BRegClassID;
942 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
947 MCRegister getMSACtrlReg()
const {
948 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) &&
"Invalid access!");
949 unsigned ClassID = Mips::MSACtrlRegClassID;
950 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
955 MCRegister getCOP0Reg()
const {
961 MCRegister getCOP2Reg()
const {
962 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) &&
"Invalid access!");
963 unsigned ClassID = Mips::COP2RegClassID;
964 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
969 MCRegister getCOP3Reg()
const {
970 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) &&
"Invalid access!");
971 unsigned ClassID = Mips::COP3RegClassID;
972 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
977 MCRegister getACC64DSPReg()
const {
978 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
979 unsigned ClassID = Mips::ACC64DSPRegClassID;
980 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
985 MCRegister getHI32DSPReg()
const {
986 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
987 unsigned ClassID = Mips::HI32DSPRegClassID;
988 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
993 MCRegister getLO32DSPReg()
const {
994 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
995 unsigned ClassID = Mips::LO32DSPRegClassID;
996 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1001 MCRegister getCCRReg()
const {
1002 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) &&
"Invalid access!");
1003 unsigned ClassID = Mips::CCRRegClassID;
1004 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1009 MCRegister getHWRegsReg()
const {
1010 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) &&
"Invalid access!");
1011 unsigned ClassID = Mips::HWRegsRegClassID;
1012 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1016 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const {
1026 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1033 void addGPR32ZeroAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1034 assert(
N == 1 &&
"Invalid number of operands!");
1038 void addGPR32NonZeroAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1039 assert(
N == 1 &&
"Invalid number of operands!");
1043 void addGPR32AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1044 assert(
N == 1 &&
"Invalid number of operands!");
1048 void addGPRMM16AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1049 assert(
N == 1 &&
"Invalid number of operands!");
1053 void addGPRMM16AsmRegZeroOperands(MCInst &Inst,
unsigned N)
const {
1054 assert(
N == 1 &&
"Invalid number of operands!");
1058 void addGPRMM16AsmRegMovePOperands(MCInst &Inst,
unsigned N)
const {
1059 assert(
N == 1 &&
"Invalid number of operands!");
1063 void addGPRMM16AsmRegMovePPairFirstOperands(MCInst &Inst,
unsigned N)
const {
1064 assert(
N == 1 &&
"Invalid number of operands!");
1068 void addGPRMM16AsmRegMovePPairSecondOperands(MCInst &Inst,
1070 assert(
N == 1 &&
"Invalid number of operands!");
1077 void addGPR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1078 assert(
N == 1 &&
"Invalid number of operands!");
1082 void addAFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1083 assert(
N == 1 &&
"Invalid number of operands!");
1087 void addStrictlyAFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1088 assert(
N == 1 &&
"Invalid number of operands!");
1092 void addStrictlyFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1093 assert(
N == 1 &&
"Invalid number of operands!");
1097 void addFGR64AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1098 assert(
N == 1 &&
"Invalid number of operands!");
1102 void addFGR32AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1103 assert(
N == 1 &&
"Invalid number of operands!");
1107 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1108 AsmParser.getParser().printError(
1109 StartLoc,
"-mno-odd-spreg prohibits the use of odd FPU "
1113 void addStrictlyFGR32AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1114 assert(
N == 1 &&
"Invalid number of operands!");
1117 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1118 AsmParser.Error(StartLoc,
"-mno-odd-spreg prohibits the use of odd FPU "
1122 void addFCCAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1123 assert(
N == 1 &&
"Invalid number of operands!");
1127 void addMSA128AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1128 assert(
N == 1 &&
"Invalid number of operands!");
1132 void addMSACtrlAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1133 assert(
N == 1 &&
"Invalid number of operands!");
1137 void addCOP0AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1138 assert(
N == 1 &&
"Invalid number of operands!");
1142 void addCOP2AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1143 assert(
N == 1 &&
"Invalid number of operands!");
1147 void addCOP3AsmRegOperands(MCInst &Inst,
unsigned N)
const {
1148 assert(
N == 1 &&
"Invalid number of operands!");
1152 void addACC64DSPAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1153 assert(
N == 1 &&
"Invalid number of operands!");
1157 void addHI32DSPAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1158 assert(
N == 1 &&
"Invalid number of operands!");
1162 void addLO32DSPAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1163 assert(
N == 1 &&
"Invalid number of operands!");
1167 void addCCRAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1168 assert(
N == 1 &&
"Invalid number of operands!");
1172 void addHWRegsAsmRegOperands(MCInst &Inst,
unsigned N)
const {
1173 assert(
N == 1 &&
"Invalid number of operands!");
1177 template <
unsigned Bits,
int Offset = 0,
int AdjustOffset = 0>
1178 void addConstantUImmOperands(MCInst &Inst,
unsigned N)
const {
1179 assert(
N == 1 &&
"Invalid number of operands!");
1183 Imm += AdjustOffset;
1187 template <
unsigned Bits>
1188 void addSImmOperands(MCInst &Inst,
unsigned N)
const {
1189 if (isImm() && !isConstantImm()) {
1193 addConstantSImmOperands<Bits, 0, 0>(Inst,
N);
1196 template <
unsigned Bits>
1197 void addUImmOperands(MCInst &Inst,
unsigned N)
const {
1198 if (isImm() && !isConstantImm()) {
1202 addConstantUImmOperands<Bits, 0, 0>(Inst,
N);
1205 template <
unsigned Bits,
int Offset = 0,
int AdjustOffset = 0>
1206 void addConstantSImmOperands(MCInst &Inst,
unsigned N)
const {
1207 assert(
N == 1 &&
"Invalid number of operands!");
1208 int64_t
Imm = getConstantImm() -
Offset;
1211 Imm += AdjustOffset;
1215 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1216 assert(
N == 1 &&
"Invalid number of operands!");
1217 const MCExpr *Expr =
getImm();
1218 addExpr(Inst, Expr);
1221 void addPtrRegOperands(MCInst &Inst,
unsigned N)
const {
1222 assert(
N == 1 &&
"Invalid number of operands!");
1224 AsmParser.getABI().ArePtrs64bit() ? getGPR64Reg() : getGPR32Reg()));
1227 void addMemOperands(MCInst &Inst,
unsigned N)
const {
1228 assert(
N == 2 &&
"Invalid number of operands!");
1229 getMemBase()->addPtrRegOperands(Inst, 1);
1230 addExpr(Inst, getMemOff());
1233 bool isSPAsmReg()
const {
return isGPRAsmReg() && RegIdx.Index == 29; }
1234 bool isGPAsmReg()
const {
return isGPRAsmReg() && RegIdx.Index == 28; }
1236 bool isSImmPtr()
const {
1237 return AsmParser.getABI().ArePtrs64bit() ? isScaledSImm<64, 0>()
1238 : isScaledSImm<32, 0>();
1241 void addRegListOperands(MCInst &Inst,
unsigned N)
const {
1242 assert(
N == 1 &&
"Invalid number of operands!");
1244 for (
auto RegNo : getRegList())
1248 bool isReg()
const override {
1251 return isGPRAsmReg() && RegIdx.Index == 0;
1254 bool isRegIdx()
const {
return Kind == k_RegisterIndex; }
1256 bool isNumericReg()
const {
1257 return isRegIdx() && RegIdx.Kind == RegKind_Numeric && RegIdx.Index < 32;
1260 unsigned getNumericRegIndex()
const {
1261 assert(isNumericReg() &&
"Invalid numeric register");
1262 return RegIdx.Index;
1265 bool isImm()
const override {
return Kind == k_Immediate; }
1267 bool isConstantImm()
const {
1269 return isImm() &&
getImm()->evaluateAsAbsolute(Res);
1272 bool isConstantImmz()
const {
1273 return isConstantImm() && getConstantImm() == 0;
1276 template <
unsigned Bits,
int Offset = 0>
bool isConstantUImm()
const {
1280 template <
unsigned Bits>
bool isSImm()
const {
1284 if (
getImm()->evaluateAsAbsolute(Res))
1290 template <
unsigned Bits>
bool isUImm()
const {
1294 if (
getImm()->evaluateAsAbsolute(Res))
1300 template <
unsigned Bits>
bool isAnyImm()
const {
1301 return isConstantImm() ? (
isInt<Bits>(getConstantImm()) ||
1306 template <
unsigned Bits,
int Offset = 0>
bool isConstantSImm()
const {
1310 template <
unsigned Bottom,
unsigned Top>
bool isConstantUImmRange()
const {
1311 return isConstantImm() && getConstantImm() >= Bottom &&
1312 getConstantImm() <= Top;
1315 bool isToken()
const override {
1318 return Kind == k_Token;
1321 bool isMem()
const override {
return Kind == k_Memory; }
1326 template <
unsigned Bits,
unsigned ShiftLeftAmount,
int Bias = 0>
1327 bool isScaledUImm()
const {
1329 uint64_t(getConstantImm()) - Bias);
1332 template <
unsigned Bits,
unsigned ShiftLeftAmount>
1333 bool isScaledSImm()
const {
1334 if (isConstantImm() &&
1339 if (Kind != k_Immediate)
1344 bool Success =
getImm()->evaluateAsRelocatable(Res,
nullptr);
1348 bool isRegList16()
const {
1352 int Size = RegList.List->size();
1356 MCRegister R0 = RegList.List->front();
1357 MCRegister R1 = RegList.List->back();
1358 if (!((R0 == Mips::R16 && R1 ==
Mips::RA) ||
1362 MCRegister PrevReg = RegList.List->front();
1363 for (
int i = 1; i <
Size - 1; i++) {
1364 MCRegister
Reg = (*(RegList.List))[i];
1365 if (
Reg != PrevReg + 1)
1373 bool isInvNum()
const {
return Kind == k_Immediate; }
1375 bool isLSAImm()
const {
1376 if (!isConstantImm())
1378 int64_t Val = getConstantImm();
1379 return 1 <= Val && Val <= 4;
1382 bool isRegList()
const {
return Kind == k_RegList; }
1385 assert(Kind == k_Token &&
"Invalid access!");
1386 return StringRef(Tok.Data, Tok.Length);
1389 MCRegister
getReg()
const override {
1392 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1393 RegIdx.Kind & RegKind_GPR)
1394 return getGPR32Reg();
1400 const MCExpr *
getImm()
const {
1401 assert((Kind == k_Immediate) &&
"Invalid access!");
1405 int64_t getConstantImm()
const {
1406 const MCExpr *Val =
getImm();
1408 (void)Val->evaluateAsAbsolute(
Value);
1412 MipsOperand *getMemBase()
const {
1413 assert((Kind == k_Memory) &&
"Invalid access!");
1417 const MCExpr *getMemOff()
const {
1418 assert((Kind == k_Memory) &&
"Invalid access!");
1422 const SmallVectorImpl<MCRegister> &getRegList()
const {
1423 assert((Kind == k_RegList) &&
"Invalid access!");
1424 return *(RegList.List);
1427 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1428 MipsAsmParser &Parser) {
1429 auto Op = std::make_unique<MipsOperand>(k_Token, Parser);
1430 Op->Tok.Data = Str.data();
1431 Op->Tok.Length = Str.size();
1439 static std::unique_ptr<MipsOperand>
1440 createNumericReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1441 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1442 LLVM_DEBUG(
dbgs() <<
"createNumericReg(" << Index <<
", ...)\n");
1443 return CreateReg(Index, Str, RegKind_Numeric, RegInfo, S,
E, Parser);
1448 static std::unique_ptr<MipsOperand>
1449 createGPRReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1450 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1451 return CreateReg(Index, Str, RegKind_GPR, RegInfo, S,
E, Parser);
1456 static std::unique_ptr<MipsOperand>
1457 createFGRReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1458 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1459 return CreateReg(Index, Str, RegKind_FGR, RegInfo, S,
E, Parser);
1462 static std::unique_ptr<MipsOperand>
1463 createCOP0Reg(
unsigned Encoding, StringRef Str,
const MCRegisterInfo *RegInfo,
1464 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1467 "Invalid COP0 register encoding");
1468 return CreateReg(Encoding, Str, RegKind_COP0, RegInfo, S,
E, Parser);
1473 static std::unique_ptr<MipsOperand>
1474 createHWRegsReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1475 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1476 return CreateReg(Index, Str, RegKind_HWRegs, RegInfo, S,
E, Parser);
1481 static std::unique_ptr<MipsOperand>
1482 createFCCReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1483 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1484 return CreateReg(Index, Str, RegKind_FCC, RegInfo, S,
E, Parser);
1489 static std::unique_ptr<MipsOperand>
1490 createACCReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1491 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1492 return CreateReg(Index, Str, RegKind_ACC, RegInfo, S,
E, Parser);
1497 static std::unique_ptr<MipsOperand>
1498 createMSA128Reg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1499 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1500 return CreateReg(Index, Str, RegKind_MSA128, RegInfo, S,
E, Parser);
1505 static std::unique_ptr<MipsOperand>
1506 createMSACtrlReg(
unsigned Index, StringRef Str,
const MCRegisterInfo *RegInfo,
1507 SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1508 return CreateReg(Index, Str, RegKind_MSACtrl, RegInfo, S,
E, Parser);
1511 static std::unique_ptr<MipsOperand>
1512 CreateImm(
const MCExpr *Val, SMLoc S, SMLoc
E, MipsAsmParser &Parser) {
1513 auto Op = std::make_unique<MipsOperand>(k_Immediate, Parser);
1520 static std::unique_ptr<MipsOperand>
1521 CreateMem(std::unique_ptr<MipsOperand>
Base,
const MCExpr *
Off, SMLoc S,
1522 SMLoc
E, MipsAsmParser &Parser) {
1523 auto Op = std::make_unique<MipsOperand>(k_Memory, Parser);
1524 Op->Mem.Base =
Base.release();
1531 static std::unique_ptr<MipsOperand>
1532 CreateRegList(SmallVectorImpl<MCRegister> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1533 MipsAsmParser &Parser) {
1534 assert(!Regs.
empty() &&
"Empty list not allowed");
1536 auto Op = std::make_unique<MipsOperand>(k_RegList, Parser);
1539 Op->StartLoc = StartLoc;
1540 Op->EndLoc = EndLoc;
1544 bool isGPRZeroAsmReg()
const {
1545 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
1548 bool isGPRNonZeroAsmReg()
const {
1549 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index > 0 &&
1553 bool isGPRAsmReg()
const {
1554 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1557 bool isMM16AsmReg()
const {
1560 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1561 || RegIdx.Index == 16 || RegIdx.Index == 17);
1564 bool isMM16AsmRegZero()
const {
1567 return (RegIdx.Index == 0 ||
1568 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1569 RegIdx.Index == 17);
1572 bool isMM16AsmRegMoveP()
const {
1573 if (!(isRegIdx() && RegIdx.Kind))
1575 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1576 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1579 bool isMM16AsmRegMovePPairFirst()
const {
1580 if (!(isRegIdx() && RegIdx.Kind))
1582 return RegIdx.Index >= 4 && RegIdx.Index <= 6;
1585 bool isMM16AsmRegMovePPairSecond()
const {
1586 if (!(isRegIdx() && RegIdx.Kind))
1588 return (RegIdx.Index == 21 || RegIdx.Index == 22 ||
1589 (RegIdx.Index >= 5 && RegIdx.Index <= 7));
1592 bool isFGRAsmReg()
const {
1594 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1597 bool isStrictlyFGRAsmReg()
const {
1599 return isRegIdx() && RegIdx.Kind == RegKind_FGR && RegIdx.Index <= 31;
1602 bool isHWRegsAsmReg()
const {
1603 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1606 bool isCCRAsmReg()
const {
1607 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1610 bool isFCCAsmReg()
const {
1611 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1613 return RegIdx.Index <= 7;
1616 bool isACCAsmReg()
const {
1617 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1620 bool isCOP0AsmReg()
const {
1621 return isRegIdx() && RegIdx.Kind == RegKind_COP0;
1624 unsigned getCOP0Encoding()
const {
1625 assert(isCOP0AsmReg() &&
"Invalid COP0 register");
1626 return RegIdx.Index;
1629 bool isCOP2AsmReg()
const {
1630 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1633 bool isCOP3AsmReg()
const {
1634 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1637 bool isMSA128AsmReg()
const {
1638 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1641 bool isMSACtrlAsmReg()
const {
1642 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1646 SMLoc getStartLoc()
const override {
return StartLoc; }
1648 SMLoc getEndLoc()
const override {
return EndLoc; }
1650 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1659 Mem.Base->print(OS, MAI);
1664 case k_RegisterIndex:
1665 OS <<
"RegIdx<" << RegIdx.Index <<
":" << RegIdx.Kind <<
", "
1666 << StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) <<
">";
1673 for (
auto Reg : (*RegList.List))
1674 OS <<
Reg.
id() <<
" ";
1680 bool isValidForTie(
const MipsOperand &
Other)
const {
1681 if (Kind !=
Other.Kind)
1688 case k_RegisterIndex: {
1689 StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length);
1690 StringRef OtherToken(
Other.RegIdx.Tok.Data,
Other.RegIdx.Tok.Length);
1691 return Token == OtherToken;
1707 case Mips::JRC16_MM:
1709 case Mips::JALRS_MM:
1710 case Mips::JALRS16_MM:
1711 case Mips::BGEZALS_MM:
1712 case Mips::BLTZALS_MM:
1723 return &SRExpr->getSymbol();
1782 unsigned NumOp =
MCID.getNumOperands();
1783 if (NumOp != 3 && NumOp != 4)
1813bool MipsAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
1816 MipsTargetStreamer &TOut = getTargetStreamer();
1817 const unsigned Opcode = Inst.
getOpcode();
1818 const MCInstrDesc &MCID = MII.get(Opcode);
1819 bool ExpandedJalSym =
false;
1833 assert(hasCnMips() &&
"instruction only valid for octeon cpus");
1844 if (!
isIntN(inMicroMipsMode() ? 17 : 18,
Offset.getImm()))
1845 return Error(IDLoc,
"branch target out of range");
1848 return Error(IDLoc,
"branch to misaligned address");
1862 case Mips::BGEZAL_MM:
1863 case Mips::BLTZAL_MM:
1866 case Mips::BC1EQZC_MMR6:
1867 case Mips::BC1NEZC_MMR6:
1868 case Mips::BC2EQZC_MMR6:
1869 case Mips::BC2NEZC_MMR6:
1874 if (!
isIntN(inMicroMipsMode() ? 17 : 18,
Offset.getImm()))
1875 return Error(IDLoc,
"branch target out of range");
1878 return Error(IDLoc,
"branch to misaligned address");
1880 case Mips::BGEC:
case Mips::BGEC_MMR6:
1881 case Mips::BLTC:
case Mips::BLTC_MMR6:
1882 case Mips::BGEUC:
case Mips::BGEUC_MMR6:
1883 case Mips::BLTUC:
case Mips::BLTUC_MMR6:
1884 case Mips::BEQC:
case Mips::BEQC_MMR6:
1885 case Mips::BNEC:
case Mips::BNEC_MMR6:
1891 return Error(IDLoc,
"branch target out of range");
1893 return Error(IDLoc,
"branch to misaligned address");
1895 case Mips::BLEZC:
case Mips::BLEZC_MMR6:
1896 case Mips::BGEZC:
case Mips::BGEZC_MMR6:
1897 case Mips::BGTZC:
case Mips::BGTZC_MMR6:
1898 case Mips::BLTZC:
case Mips::BLTZC_MMR6:
1904 return Error(IDLoc,
"branch target out of range");
1906 return Error(IDLoc,
"branch to misaligned address");
1908 case Mips::BEQZC:
case Mips::BEQZC_MMR6:
1909 case Mips::BNEZC:
case Mips::BNEZC_MMR6:
1915 return Error(IDLoc,
"branch target out of range");
1917 return Error(IDLoc,
"branch to misaligned address");
1919 case Mips::BEQZ16_MM:
1920 case Mips::BEQZC16_MMR6:
1921 case Mips::BNEZ16_MM:
1922 case Mips::BNEZC16_MMR6:
1928 return Error(IDLoc,
"branch target out of range");
1930 return Error(IDLoc,
"branch to misaligned address");
1937 if (hasMips32r6() && Opcode == Mips::SSNOP) {
1938 std::string
ISA = hasMips64r6() ?
"MIPS64r6" :
"MIPS32r6";
1939 Warning(IDLoc,
"ssnop is deprecated for " + ISA +
" and is equivalent to a "
1959 return Error(IDLoc,
"expected immediate operand kind");
1962 Opcode == Mips::BBIT1 ? 63 : 31))
1963 return Error(IDLoc,
"immediate operand value out of range");
1965 Inst.
setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1976 return Error(IDLoc,
"expected immediate operand kind");
1979 return Error(IDLoc,
"immediate operand value out of range");
1991 unsigned FirstOp = 1;
1992 unsigned SecondOp = 2;
1996 case Mips::SDivIMacro:
1997 case Mips::UDivIMacro:
1998 case Mips::DSDivIMacro:
1999 case Mips::DUDivIMacro:
2001 return Error(IDLoc,
"expected immediate operand kind");
2005 Warning(IDLoc,
"dividing zero by zero");
2007 Warning(IDLoc,
"division by zero");
2019 case Mips::SDivMacro:
2020 case Mips::DSDivMacro:
2021 case Mips::UDivMacro:
2022 case Mips::DUDivMacro:
2027 case Mips::DIVU_MMR6:
2028 case Mips::DIV_MMR6:
2033 Warning(IDLoc,
"dividing zero by zero");
2035 Warning(IDLoc,
"division by zero");
2041 if ((Opcode == Mips::J || Opcode == Mips::J_MM) && inPicMode()) {
2043 BInst.
setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
2052 if ((Opcode == Mips::JAL || Opcode == Mips::JAL_MM) && inPicMode()) {
2053 warnIfNoMacro(IDLoc);
2056 return Error(IDLoc,
"unsupported constant in relocation");
2064 return Error(IDLoc,
"jal doesn't support multiple symbols in PIC mode");
2070 if (expandLoadAddress(
getABI().getTempReg(9), MCRegister(),
2071 Inst.
getOperand(0), !isGP64bit(), IDLoc, Out, STI))
2075 if (inMicroMipsMode())
2076 JalrInst.
setOpcode(IsCpRestoreSet ? Mips::JALRS_MM : Mips::JALR_MM);
2082 if (isJalrRelocAvailable(JalExpr)) {
2088 const MCExpr *RelocJalrExpr =
2092 *TmpExpr, inMicroMipsMode() ?
"R_MICROMIPS_JALR" :
"R_MIPS_JALR",
2098 ExpandedJalSym =
true;
2107 expandMem9Inst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2110 expandMem16Inst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2113 return getParser().hasPendingError();
2117 if (inMicroMipsMode()) {
2118 if (Opcode == Mips::LW_MM || Opcode == Mips::LW_MMR6) {
2121 const MCOperandInfo &OpInfo = MCID.
operands()[i];
2126 int MemOffset =
Op.getImm();
2129 if (
isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
2152 case Mips::ADDIUSP_MM:
2155 return Error(IDLoc,
"expected immediate operand kind");
2159 return Error(IDLoc,
"immediate operand value out of range");
2161 case Mips::SLL16_MM:
2162 case Mips::SRL16_MM:
2165 return Error(IDLoc,
"expected immediate operand kind");
2168 return Error(IDLoc,
"immediate operand value out of range");
2173 return Error(IDLoc,
"expected immediate operand kind");
2176 return Error(IDLoc,
"immediate operand value out of range");
2178 case Mips::ADDIUR2_MM:
2181 return Error(IDLoc,
"expected immediate operand kind");
2183 if (!(
Imm == 1 ||
Imm == -1 ||
2185 return Error(IDLoc,
"immediate operand value out of range");
2187 case Mips::ANDI16_MM:
2190 return Error(IDLoc,
"expected immediate operand kind");
2194 Imm == 64 ||
Imm == 255 ||
Imm == 32768 ||
Imm == 65535))
2195 return Error(IDLoc,
"immediate operand value out of range");
2197 case Mips::LBU16_MM:
2200 return Error(IDLoc,
"expected immediate operand kind");
2203 return Error(IDLoc,
"immediate operand value out of range");
2206 case Mips::SB16_MMR6:
2209 return Error(IDLoc,
"expected immediate operand kind");
2212 return Error(IDLoc,
"immediate operand value out of range");
2214 case Mips::LHU16_MM:
2216 case Mips::SH16_MMR6:
2219 return Error(IDLoc,
"expected immediate operand kind");
2222 return Error(IDLoc,
"immediate operand value out of range");
2226 case Mips::SW16_MMR6:
2229 return Error(IDLoc,
"expected immediate operand kind");
2232 return Error(IDLoc,
"immediate operand value out of range");
2234 case Mips::ADDIUPC_MM:
2237 return Error(IDLoc,
"expected immediate operand kind");
2240 return Error(IDLoc,
"immediate operand value out of range");
2245 return Error(IDLoc,
"invalid operand for instruction");
2247 case Mips::MOVEP_MM:
2248 case Mips::MOVEP_MMR6: {
2251 bool RegPair = ((R0 == Mips::R5 && R1 == Mips::R6) ||
2252 (R0 == Mips::R5 && R1 == Mips::R7) ||
2253 (R0 == Mips::R6 && R1 == Mips::R7) ||
2254 (R0 == Mips::R4 && R1 == Mips::R21) ||
2255 (R0 == Mips::R4 && R1 == Mips::R22) ||
2256 (R0 == Mips::R4 && R1 == Mips::R5) ||
2257 (R0 == Mips::R4 && R1 == Mips::R6) ||
2258 (R0 == Mips::R4 && R1 == Mips::R7));
2260 return Error(IDLoc,
"invalid operand for instruction");
2266 bool FillDelaySlot =
2271 bool PrevForbiddenSlotAttr = CurForbiddenSlotAttr;
2274 bool SetReorderAfterNop =
false;
2279 if (PrevForbiddenSlotAttr && !SafeInForbiddenSlot(MCID)) {
2289 if (AssemblerOptions.
back()->isReorder() && !FillDelaySlot) {
2290 SetReorderAfterNop =
true;
2299 CurForbiddenSlotAttr =
2300 hasForbiddenSlot(MCID) && AssemblerOptions.
back()->isReorder();
2302 if (FillDelaySlot || CurForbiddenSlotAttr)
2305 MacroExpanderResultTy ExpandResult =
2306 tryExpandInstruction(Inst, IDLoc, Out, STI);
2307 switch (ExpandResult) {
2309 Out.emitInstruction(Inst, *STI);
2323 if (PrevForbiddenSlotAttr && !SetReorderAfterNop && !FillDelaySlot &&
2324 AssemblerOptions.
back()->isReorder()) {
2330 if (inMicroMipsMode()) {
2345 if (FillDelaySlot) {
2350 if ((Opcode == Mips::JalOneReg || Opcode == Mips::JalTwoReg ||
2352 isPicAndNotNxxAbi()) {
2353 if (IsCpRestoreSet) {
2357 if (!AssemblerOptions.
back()->isReorder())
2364 Warning(IDLoc,
"no .cprestore used in PIC mode");
2370void MipsAsmParser::onEndOfFile() {
2371 MipsTargetStreamer &TOut = getTargetStreamer();
2372 SMLoc IDLoc = SMLoc();
2374 if (CurForbiddenSlotAttr) {
2376 if (AssemblerOptions.
back()->isReorder())
2381MipsAsmParser::MacroExpanderResultTy
2382MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2383 const MCSubtargetInfo *STI) {
2386 return MER_NotAMacro;
2387 case Mips::LoadImm32:
2388 return expandLoadImm(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2389 case Mips::LoadImm64:
2390 return expandLoadImm(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2391 case Mips::LoadAddrImm32:
2392 case Mips::LoadAddrImm64:
2395 "expected immediate operand kind");
2397 return expandLoadAddress(
2399 Inst.
getOpcode() == Mips::LoadAddrImm32, IDLoc, Out, STI)
2402 case Mips::LoadAddrReg32:
2403 case Mips::LoadAddrReg64:
2407 "expected immediate operand kind");
2411 Inst.
getOpcode() == Mips::LoadAddrReg32, IDLoc,
2415 case Mips::B_MM_Pseudo:
2416 case Mips::B_MMR6_Pseudo:
2417 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2421 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2423 case Mips::JalOneReg:
2424 case Mips::JalTwoReg:
2425 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2428 case Mips::BEQLImmMacro:
2429 case Mips::BNELImmMacro:
2430 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2447 case Mips::BLTImmMacro:
2448 case Mips::BLEImmMacro:
2449 case Mips::BGEImmMacro:
2450 case Mips::BGTImmMacro:
2451 case Mips::BLTUImmMacro:
2452 case Mips::BLEUImmMacro:
2453 case Mips::BGEUImmMacro:
2454 case Mips::BGTUImmMacro:
2455 case Mips::BLTLImmMacro:
2456 case Mips::BLELImmMacro:
2457 case Mips::BGELImmMacro:
2458 case Mips::BGTLImmMacro:
2459 case Mips::BLTULImmMacro:
2460 case Mips::BLEULImmMacro:
2461 case Mips::BGEULImmMacro:
2462 case Mips::BGTULImmMacro:
2463 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2464 case Mips::SDivMacro:
2465 case Mips::SDivIMacro:
2466 case Mips::SRemMacro:
2467 case Mips::SRemIMacro:
2468 return expandDivRem(Inst, IDLoc, Out, STI,
false,
true) ? MER_Fail
2470 case Mips::DSDivMacro:
2471 case Mips::DSDivIMacro:
2472 case Mips::DSRemMacro:
2473 case Mips::DSRemIMacro:
2474 return expandDivRem(Inst, IDLoc, Out, STI,
true,
true) ? MER_Fail
2476 case Mips::UDivMacro:
2477 case Mips::UDivIMacro:
2478 case Mips::URemMacro:
2479 case Mips::URemIMacro:
2480 return expandDivRem(Inst, IDLoc, Out, STI,
false,
false) ? MER_Fail
2482 case Mips::DUDivMacro:
2483 case Mips::DUDivIMacro:
2484 case Mips::DURemMacro:
2485 case Mips::DURemIMacro:
2486 return expandDivRem(Inst, IDLoc, Out, STI,
true,
false) ? MER_Fail
2488 case Mips::PseudoTRUNC_W_S:
2489 return expandTrunc(Inst,
false,
false, IDLoc, Out, STI) ? MER_Fail
2491 case Mips::PseudoTRUNC_W_D32:
2492 return expandTrunc(Inst,
true,
false, IDLoc, Out, STI) ? MER_Fail
2494 case Mips::PseudoTRUNC_W_D:
2495 return expandTrunc(Inst,
true,
true, IDLoc, Out, STI) ? MER_Fail
2498 case Mips::LoadImmSingleGPR:
2499 return expandLoadSingleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2501 case Mips::LoadImmSingleFGR:
2502 return expandLoadSingleImmToFPR(Inst, IDLoc, Out, STI) ? MER_Fail
2504 case Mips::LoadImmDoubleGPR:
2505 return expandLoadDoubleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2507 case Mips::LoadImmDoubleFGR:
2508 return expandLoadDoubleImmToFPR(Inst,
true, IDLoc, Out, STI) ? MER_Fail
2510 case Mips::LoadImmDoubleFGR_32:
2511 return expandLoadDoubleImmToFPR(Inst,
false, IDLoc, Out, STI) ? MER_Fail
2515 return expandUlh(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2517 return expandUlh(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2519 return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2522 return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2524 case Mips::NORImm64:
2525 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2528 return expandSge(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2531 case Mips::SGEImm64:
2532 case Mips::SGEUImm64:
2533 return expandSgeImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2536 case Mips::SGTImm64:
2537 case Mips::SGTUImm64:
2538 return expandSgtImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2541 return expandSle(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2544 case Mips::SLEImm64:
2545 case Mips::SLEUImm64:
2546 return expandSleImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2547 case Mips::SLTImm64:
2550 return MER_NotAMacro;
2552 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2553 case Mips::SLTUImm64:
2556 return MER_NotAMacro;
2558 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2559 case Mips::ADDi:
case Mips::ADDi_MM:
2560 case Mips::ADDiu:
case Mips::ADDiu_MM:
2561 case Mips::SLTi:
case Mips::SLTi_MM:
2562 case Mips::SLTiu:
case Mips::SLTiu_MM:
2567 return MER_NotAMacro;
2568 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2571 return MER_NotAMacro;
2572 case Mips::ANDi:
case Mips::ANDi_MM:
case Mips::ANDi64:
2573 case Mips::ORi:
case Mips::ORi_MM:
case Mips::ORi64:
2574 case Mips::XORi:
case Mips::XORi_MM:
case Mips::XORi64:
2579 return MER_NotAMacro;
2580 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2583 return MER_NotAMacro;
2586 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2589 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2592 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2595 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2596 case Mips::ABSMacro:
2597 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2598 case Mips::MULImmMacro:
2599 case Mips::DMULImmMacro:
2600 return expandMulImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2601 case Mips::MULOMacro:
2602 case Mips::DMULOMacro:
2603 return expandMulO(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2604 case Mips::MULOUMacro:
2605 case Mips::DMULOUMacro:
2606 return expandMulOU(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2607 case Mips::DMULMacro:
2608 return expandDMULMacro(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2611 return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2616 return expandStoreDM1Macro(Inst, IDLoc, Out, STI)
2619 case Mips::SEQMacro:
2620 return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2621 case Mips::SEQIMacro:
2622 return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2623 case Mips::SNEMacro:
2624 return expandSne(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2625 case Mips::SNEIMacro:
2626 return expandSneI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2627 case Mips::MFTGPR:
case Mips::MTTGPR:
2628 case Mips::MFTLO:
case Mips::MTTLO:
2629 case Mips::MFTHI:
case Mips::MTTHI:
2630 case Mips::MFTACX:
case Mips::MTTACX:
2631 case Mips::MFTDSP:
case Mips::MTTDSP:
2632 case Mips::MFTC1:
case Mips::MTTC1:
2633 case Mips::MFTHC1:
case Mips::MTTHC1:
2634 case Mips::CFTC1:
case Mips::CTTC1:
2635 return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2637 case Mips::SaadAddr:
2638 return expandSaaAddr(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2642bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2644 const MCSubtargetInfo *STI) {
2645 MipsTargetStreamer &TOut = getTargetStreamer();
2650 const MCOperand FirstRegOp = Inst.
getOperand(0);
2651 const unsigned Opcode = Inst.
getOpcode();
2653 if (Opcode == Mips::JalOneReg) {
2655 if (IsCpRestoreSet && inMicroMipsMode()) {
2658 }
else if (inMicroMipsMode()) {
2659 JalrInst.
setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2666 }
else if (Opcode == Mips::JalTwoReg) {
2668 if (IsCpRestoreSet && inMicroMipsMode())
2671 JalrInst.
setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2673 const MCOperand SecondRegOp = Inst.
getOperand(1);
2676 Out.emitInstruction(JalrInst, *STI);
2680 const MCInstrDesc &MCID = MII.get(JalrInst.
getOpcode());
2703bool MipsAsmParser::loadImmediate(int64_t ImmValue, MCRegister DstReg,
2704 MCRegister SrcReg,
bool Is32BitImm,
2705 bool IsAddress, SMLoc IDLoc, MCStreamer &Out,
2706 const MCSubtargetInfo *STI) {
2707 MipsTargetStreamer &TOut = getTargetStreamer();
2709 if (!Is32BitImm && !isGP64bit()) {
2710 Error(IDLoc,
"instruction requires a 64-bit architecture");
2721 Error(IDLoc,
"instruction requires a 32-bit immediate");
2726 MCRegister ZeroReg = IsAddress ?
ABI.GetNullPtr() :
ABI.GetZeroReg();
2727 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2729 bool UseSrcReg =
false;
2733 MCRegister TmpReg = DstReg;
2735 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2738 MCRegister ATReg = getATReg(IDLoc);
2751 if (IsAddress && !Is32BitImm) {
2752 TOut.
emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2756 TOut.
emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2761 MCRegister TmpReg = DstReg;
2762 if (SrcReg == DstReg) {
2763 TmpReg = getATReg(IDLoc);
2768 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2770 TOut.
emitRRR(
ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2775 warnIfNoMacro(IDLoc);
2777 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2778 uint16_t Bits15To0 = ImmValue & 0xffff;
2779 if (!Is32BitImm && !
isInt<32>(ImmValue)) {
2782 if (ImmValue == 0xffffffff) {
2783 TOut.
emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2784 TOut.
emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2786 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2792 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2793 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2795 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2797 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2801 TOut.
emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2803 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2805 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2811 Error(IDLoc,
"instruction requires a 32-bit immediate");
2818 assert(
BitWidth >= 17 &&
"ImmValue must be at least 17-bit wide");
2822 unsigned ShiftAmount =
BitWidth - 16;
2823 uint16_t
Bits = (ImmValue >> ShiftAmount) & 0xffff;
2824 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2825 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2828 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2833 warnIfNoMacro(IDLoc);
2840 if (loadImmediate(ImmValue >> 32, TmpReg, MCRegister(),
true,
false, IDLoc,
2846 unsigned ShiftCarriedForwards = 16;
2847 for (
int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2848 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2850 if (ImmChunk != 0) {
2851 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2852 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2853 ShiftCarriedForwards = 0;
2856 ShiftCarriedForwards += 16;
2858 ShiftCarriedForwards -= 16;
2861 if (ShiftCarriedForwards)
2862 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2865 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2870bool MipsAsmParser::expandLoadImm(MCInst &Inst,
bool Is32BitImm, SMLoc IDLoc,
2871 MCStreamer &Out,
const MCSubtargetInfo *STI) {
2873 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
2874 const MCOperand &DstRegOp = Inst.
getOperand(0);
2875 assert(DstRegOp.
isReg() &&
"expected register operand kind");
2877 if (loadImmediate(ImmOp.
getImm(), DstRegOp.
getReg(), MCRegister(), Is32BitImm,
2878 false, IDLoc, Out, STI))
2884bool MipsAsmParser::expandLoadAddress(MCRegister DstReg, MCRegister BaseReg,
2886 bool Is32BitAddress, SMLoc IDLoc,
2888 const MCSubtargetInfo *STI) {
2890 if (Is32BitAddress &&
ABI.ArePtrs64bit()) {
2891 Warning(IDLoc,
"la used to load 64-bit address");
2893 Is32BitAddress =
false;
2897 if (!Is32BitAddress && !hasMips3()) {
2898 Error(IDLoc,
"instruction requires a 64-bit architecture");
2903 return loadAndAddSymbolAddress(
Offset.getExpr(), DstReg, BaseReg,
2904 Is32BitAddress, IDLoc, Out, STI);
2906 if (!
ABI.ArePtrs64bit()) {
2908 Is32BitAddress =
true;
2911 return loadImmediate(
Offset.getImm(), DstReg, BaseReg, Is32BitAddress,
true,
2915bool MipsAsmParser::loadAndAddSymbolAddress(
const MCExpr *SymExpr,
2917 MCRegister SrcReg,
bool Is32BitSym,
2918 SMLoc IDLoc, MCStreamer &Out,
2919 const MCSubtargetInfo *STI) {
2920 MipsTargetStreamer &TOut = getTargetStreamer();
2922 SrcReg.
isValid() && SrcReg != Mips::R0 && SrcReg != Mips::R0_64;
2923 warnIfNoMacro(IDLoc);
2928 Error(IDLoc,
"expected relocatable expression");
2932 Error(IDLoc,
"expected relocatable expression with only one symbol");
2936 bool IsPtr64 =
ABI.ArePtrs64bit();
2939 ?
static_cast<const MCSymbolELF *
>(Res.
getAddSym())
2947 bool UseXGOT = STI->
hasFeature(Mips::FeatureXGOT) && !IsLocalSym;
2953 if ((DstReg ==
getABI().getTempReg(9,
false) ||
2954 DstReg ==
getABI().getTempReg(9,
true)) &&
2955 !UseSrcReg && Res.
getConstant() == 0 && !IsLocalSym) {
2957 const MCExpr *CallHiExpr =
2959 const MCExpr *CallLoExpr =
2963 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, DstReg, GPReg,
2965 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, DstReg,
2968 const MCExpr *CallExpr =
2970 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, GPReg,
2976 MCRegister TmpReg = DstReg;
2978 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2982 MCRegister ATReg = getATReg(IDLoc);
3001 const MCExpr *CallHiExpr =
3008 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg, GPReg,
3010 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, TmpReg,
3014 TOut.
emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3020 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3025 const MCSpecifierExpr *GotExpr =
nullptr;
3026 const MCExpr *LoExpr =
nullptr;
3027 if (
ABI.IsN32() ||
ABI.IsN64()) {
3046 Error(IDLoc,
"macro instruction uses large offset, which is not "
3047 "currently supported");
3076 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, GPReg,
3080 TOut.
emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3084 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3090 const auto *HiExpr =
3092 const auto *LoExpr =
3096 if (
ABI.ArePtrs64bit() && isGP64bit()) {
3104 const auto *HighestExpr =
3106 const auto *HigherExpr =
3111 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
3113 if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
3114 MCRegister ATReg = getATReg(IDLoc);
3126 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3128 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3131 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3134 TOut.
emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
3137 }
else if (canUseATReg() && !RdRegIsRsReg && DstReg != getATReg(IDLoc)) {
3138 MCRegister ATReg = getATReg(IDLoc);
3154 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3158 TOut.
emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3159 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3161 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3164 }
else if ((!canUseATReg() && !RdRegIsRsReg) ||
3165 (canUseATReg() && DstReg == getATReg(IDLoc))) {
3176 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3178 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3179 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3181 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3182 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3185 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3191 assert(SrcReg == DstReg && !canUseATReg() &&
3192 "Could have expanded dla but didn't?");
3193 reportParseError(IDLoc,
3194 "pseudo-instruction requires $at, which is not available");
3208 MCRegister TmpReg = DstReg;
3210 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
3213 MCRegister ATReg = getATReg(IDLoc);
3224 TOut.
emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3227 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
3236 if (getMipsMCRegisterClass(Mips::FGR32RegClassID).
contains(
Reg))
3237 return Reg == (
unsigned)Mips::F31 ? (
unsigned)Mips::F0 :
Reg + 1;
3239 default:
llvm_unreachable(
"Unknown register in assembly macro expansion!");
3304 case Mips::D0:
return Mips::F1;
3305 case Mips::D1:
return Mips::F3;
3306 case Mips::D2:
return Mips::F5;
3307 case Mips::D3:
return Mips::F7;
3308 case Mips::D4:
return Mips::F9;
3309 case Mips::D5:
return Mips::F11;
3310 case Mips::D6:
return Mips::F13;
3311 case Mips::D7:
return Mips::F15;
3312 case Mips::D8:
return Mips::F17;
3313 case Mips::D9:
return Mips::F19;
3335bool MipsAsmParser::emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc,
3337 MCRegister ATReg = getATReg(IDLoc);
3343 const auto *GotExpr =
3346 if(isABI_O32() || isABI_N32()) {
3355 const auto *HiExpr =
3364 if(isABI_O32() || isABI_N32()) {
3368 const auto *HighestExpr =
3371 const auto *HigherExpr =
3376 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3378 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3381 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3390 if ((
Hi_32(ImmOp64) & 0x7ff00000) == 0) {
3401 float TmpFloat =
static_cast<float>(DoubleImm);
3405bool MipsAsmParser::expandLoadSingleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3407 const MCSubtargetInfo *STI) {
3410 "Invalid instruction operand.");
3417 return loadImmediate(ImmOp32, FirstReg, MCRegister(),
true,
false, IDLoc, Out,
3421bool MipsAsmParser::expandLoadSingleImmToFPR(MCInst &Inst, SMLoc IDLoc,
3423 const MCSubtargetInfo *STI) {
3424 MipsTargetStreamer &TOut = getTargetStreamer();
3427 "Invalid instruction operand.");
3436 MCRegister TmpReg = Mips::R0;
3438 TmpReg = getATReg(IDLoc);
3443 if (
Lo_32(ImmOp64) == 0) {
3444 if (TmpReg != Mips::R0 && loadImmediate(ImmOp32, TmpReg, MCRegister(),
true,
3445 false, IDLoc, Out, STI))
3447 TOut.
emitRR(Mips::MTC1, FirstReg, TmpReg, IDLoc, STI);
3451 MCSection *CS = getStreamer().getCurrentSectionOnly();
3454 MCSection *ReadOnlySection =
3461 getStreamer().switchSection(ReadOnlySection);
3462 getStreamer().emitLabel(Sym, IDLoc);
3463 getStreamer().emitInt32(ImmOp32);
3464 getStreamer().switchSection(CS);
3466 if (emitPartialAddress(TOut, IDLoc, Sym))
3473bool MipsAsmParser::expandLoadDoubleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3475 const MCSubtargetInfo *STI) {
3476 MipsTargetStreamer &TOut = getTargetStreamer();
3479 "Invalid instruction operand.");
3486 if (
Lo_32(ImmOp64) == 0) {
3488 if (loadImmediate(ImmOp64, FirstReg, MCRegister(),
false,
false, IDLoc,
3492 if (loadImmediate(
Hi_32(ImmOp64), FirstReg, MCRegister(),
true,
false,
3496 if (loadImmediate(0,
nextReg(FirstReg), MCRegister(),
true,
false, IDLoc,
3503 MCSection *CS = getStreamer().getCurrentSectionOnly();
3504 MCSection *ReadOnlySection =
3511 getStreamer().switchSection(ReadOnlySection);
3512 getStreamer().emitLabel(Sym, IDLoc);
3513 getStreamer().emitValueToAlignment(
Align(8));
3514 getStreamer().emitIntValue(ImmOp64, 8);
3515 getStreamer().switchSection(CS);
3517 MCRegister TmpReg = getATReg(IDLoc);
3521 if (emitPartialAddress(TOut, IDLoc, Sym))
3524 TOut.
emitRRX(isABI_N64() ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3528 TOut.
emitRRI(Mips::LD, FirstReg, TmpReg, 0, IDLoc, STI);
3530 TOut.
emitRRI(Mips::LW, FirstReg, TmpReg, 0, IDLoc, STI);
3531 TOut.
emitRRI(Mips::LW,
nextReg(FirstReg), TmpReg, 4, IDLoc, STI);
3536bool MipsAsmParser::expandLoadDoubleImmToFPR(MCInst &Inst,
bool Is64FPU,
3537 SMLoc IDLoc, MCStreamer &Out,
3538 const MCSubtargetInfo *STI) {
3539 MipsTargetStreamer &TOut = getTargetStreamer();
3542 "Invalid instruction operand.");
3549 MCRegister TmpReg = Mips::R0;
3551 TmpReg = getATReg(IDLoc);
3556 if ((
Lo_32(ImmOp64) == 0) &&
3557 !((
Hi_32(ImmOp64) & 0xffff0000) && (
Hi_32(ImmOp64) & 0x0000ffff))) {
3559 if (TmpReg != Mips::R0 && loadImmediate(ImmOp64, TmpReg, MCRegister(),
3560 false,
false, IDLoc, Out, STI))
3562 TOut.
emitRR(Mips::DMTC1, FirstReg, TmpReg, IDLoc, STI);
3566 if (TmpReg != Mips::R0 &&
3567 loadImmediate(
Hi_32(ImmOp64), TmpReg, MCRegister(),
true,
false, IDLoc,
3571 if (hasMips32r2()) {
3572 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::R0, IDLoc, STI);
3573 TOut.
emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, TmpReg, IDLoc, STI);
3575 TOut.
emitRR(Mips::MTC1,
nextReg(FirstReg), TmpReg, IDLoc, STI);
3576 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::R0, IDLoc, STI);
3581 MCSection *CS = getStreamer().getCurrentSectionOnly();
3584 MCSection *ReadOnlySection =
3591 getStreamer().switchSection(ReadOnlySection);
3592 getStreamer().emitLabel(Sym, IDLoc);
3593 getStreamer().emitValueToAlignment(
Align(8));
3594 getStreamer().emitIntValue(ImmOp64, 8);
3595 getStreamer().switchSection(CS);
3597 if (emitPartialAddress(TOut, IDLoc, Sym))
3600 TOut.
emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, TmpReg,
3606bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
3608 const MCSubtargetInfo *STI) {
3609 MipsTargetStreamer &TOut = getTargetStreamer();
3612 "unexpected number of operands");
3622 assert(
Offset.isImm() &&
"expected immediate operand kind");
3626 if (inMicroMipsMode())
3627 Inst.
setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3630 return Error(IDLoc,
"branch target out of range");
3632 return Error(IDLoc,
"branch to misaligned address");
3640 Out.emitInstruction(Inst, *STI);
3644 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
3651bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3652 const MCSubtargetInfo *STI) {
3653 MipsTargetStreamer &TOut = getTargetStreamer();
3654 const MCOperand &DstRegOp = Inst.
getOperand(0);
3655 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3658 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
3660 const MCOperand &MemOffsetOp = Inst.
getOperand(2);
3662 "expected immediate or expression operand");
3664 bool IsLikely =
false;
3674 case Mips::BEQLImmMacro:
3678 case Mips::BNELImmMacro:
3687 int64_t ImmValue = ImmOp.
getImm();
3688 if (ImmValue == 0) {
3692 TOut.
emitRRI(Mips::SLL, Mips::R0, Mips::R0, 0, IDLoc, STI);
3694 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), Mips::R0, MemOffsetOp, IDLoc,
3697 warnIfNoMacro(IDLoc);
3699 MCRegister ATReg = getATReg(IDLoc);
3703 if (loadImmediate(ImmValue, ATReg, MCRegister(), !isGP64bit(),
true, IDLoc,
3707 if (IsLikely && MemOffsetOp.
isExpr()) {
3710 TOut.
emitRRI(Mips::SLL, Mips::R0, Mips::R0, 0, IDLoc, STI);
3712 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3717void MipsAsmParser::expandMem16Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3718 const MCSubtargetInfo *STI,
bool IsLoad) {
3720 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3721 unsigned StartOp = NumOp == 3 ? 0 : 1;
3723 const MCOperand &DstRegOp = Inst.
getOperand(StartOp);
3724 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3725 const MCOperand &BaseRegOp = Inst.
getOperand(StartOp + 1);
3726 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3729 MipsTargetStreamer &TOut = getTargetStreamer();
3731 MCRegister DstReg = DstRegOp.
getReg();
3733 MCRegister TmpReg = DstReg;
3735 const MCInstrDesc &
Desc = MII.get(OpCode);
3736 int16_t DstRegClass =
3737 MII.getOpRegClassID(
Desc.operands()[StartOp],
3739 unsigned DstRegClassID =
3740 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3741 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3742 (DstRegClassID == Mips::GPR64RegClassID);
3744 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3747 TmpReg = getATReg(IDLoc);
3752 auto emitInstWithOffset = [&](
const MCOperand &
Off) {
3754 TOut.
emitRRX(OpCode, DstReg, TmpReg,
Off, IDLoc, STI);
3756 TOut.
emitRRRX(OpCode, DstReg, DstReg, TmpReg,
Off, IDLoc, STI);
3760 int64_t LoOffset =
OffsetOp.getImm() & 0xffff;
3761 int64_t HiOffset =
OffsetOp.getImm() & ~0xffff;
3765 if (LoOffset & 0x8000)
3766 HiOffset += 0x10000;
3768 bool IsLargeOffset = HiOffset != 0;
3770 if (IsLargeOffset) {
3772 if (loadImmediate(HiOffset, TmpReg, MCRegister(), Is32BitImm,
true, IDLoc,
3777 if (BaseReg != Mips::R0 && BaseReg != Mips::R0_64)
3778 TOut.
emitRRR(
ABI.ArePtrs64bit() ? Mips::DADDu : Mips::ADDu, TmpReg,
3779 TmpReg, BaseReg, IDLoc, STI);
3793 if (!
OffsetOp.getExpr()->evaluateAsRelocatable(Res,
nullptr)) {
3794 Error(IDLoc,
"expected relocatable expression");
3798 Error(IDLoc,
"expected relocatable expression with only one symbol");
3802 loadAndAddSymbolAddress(
3804 BaseReg, !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3812 const MCExpr *OffExpr =
OffsetOp.getExpr();
3824 TOut.
emitRX(Mips::LUi, TmpReg, HighestOperand, IDLoc, STI);
3825 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HigherOperand, IDLoc, STI);
3826 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3827 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HiOperand, IDLoc, STI);
3828 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3829 if (BaseReg != Mips::R0 && BaseReg != Mips::R0_64)
3830 TOut.
emitRRR(Mips::DADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3831 emitInstWithOffset(LoOperand);
3834 TOut.
emitRX(Mips::LUi, TmpReg, HiOperand, IDLoc, STI);
3835 if (BaseReg != Mips::R0)
3836 TOut.
emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3838 emitInstWithOffset(LoOperand);
3847void MipsAsmParser::expandMem9Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3848 const MCSubtargetInfo *STI,
bool IsLoad) {
3850 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3851 unsigned StartOp = NumOp == 3 ? 0 : 1;
3853 const MCOperand &DstRegOp = Inst.
getOperand(StartOp);
3854 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3855 const MCOperand &BaseRegOp = Inst.
getOperand(StartOp + 1);
3856 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3859 MipsTargetStreamer &TOut = getTargetStreamer();
3861 MCRegister DstReg = DstRegOp.
getReg();
3863 MCRegister TmpReg = DstReg;
3865 const MCInstrDesc &
Desc = MII.get(OpCode);
3866 int16_t DstRegClass =
3867 MII.getOpRegClassID(
Desc.operands()[StartOp],
3870 unsigned DstRegClassID =
3871 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3872 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3873 (DstRegClassID == Mips::GPR64RegClassID);
3875 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3878 TmpReg = getATReg(IDLoc);
3883 auto emitInst = [&]() {
3892 loadImmediate(
OffsetOp.getImm(), TmpReg, BaseReg, !
ABI.ArePtrs64bit(),
true,
3899 loadAndAddSymbolAddress(
OffsetOp.getExpr(), TmpReg, BaseReg,
3900 !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3908bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
3910 const MCSubtargetInfo *STI) {
3913 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3917 Inst.
getOperand(OpNum - 3).
isReg() &&
"Invalid instruction operand.");
3926 if (inMicroMipsMode() && hasMips32r6())
3927 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3929 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3933 Out.emitInstruction(Inst, *STI);
3937bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
3939 const MCSubtargetInfo *STI) {
3940 MipsTargetStreamer &TOut = getTargetStreamer();
3941 bool EmittedNoMacroWarning =
false;
3942 unsigned PseudoOpcode = Inst.
getOpcode();
3947 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3948 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3953 else if (TrgOp.
isImm()) {
3954 warnIfNoMacro(IDLoc);
3955 EmittedNoMacroWarning =
true;
3957 TrgReg = getATReg(IDLoc);
3961 switch(PseudoOpcode) {
3964 case Mips::BLTImmMacro:
3965 PseudoOpcode = Mips::BLT;
3967 case Mips::BLEImmMacro:
3968 PseudoOpcode = Mips::BLE;
3970 case Mips::BGEImmMacro:
3971 PseudoOpcode = Mips::BGE;
3973 case Mips::BGTImmMacro:
3974 PseudoOpcode = Mips::BGT;
3976 case Mips::BLTUImmMacro:
3977 PseudoOpcode = Mips::BLTU;
3979 case Mips::BLEUImmMacro:
3980 PseudoOpcode = Mips::BLEU;
3982 case Mips::BGEUImmMacro:
3983 PseudoOpcode = Mips::BGEU;
3985 case Mips::BGTUImmMacro:
3986 PseudoOpcode = Mips::BGTU;
3988 case Mips::BLTLImmMacro:
3989 PseudoOpcode = Mips::BLTL;
3991 case Mips::BLELImmMacro:
3992 PseudoOpcode = Mips::BLEL;
3994 case Mips::BGELImmMacro:
3995 PseudoOpcode = Mips::BGEL;
3997 case Mips::BGTLImmMacro:
3998 PseudoOpcode = Mips::BGTL;
4000 case Mips::BLTULImmMacro:
4001 PseudoOpcode = Mips::BLTUL;
4003 case Mips::BLEULImmMacro:
4004 PseudoOpcode = Mips::BLEUL;
4006 case Mips::BGEULImmMacro:
4007 PseudoOpcode = Mips::BGEUL;
4009 case Mips::BGTULImmMacro:
4010 PseudoOpcode = Mips::BGTUL;
4014 if (loadImmediate(TrgOp.
getImm(), TrgReg, MCRegister(), !isGP64bit(),
false,
4019 switch (PseudoOpcode) {
4024 AcceptsEquality =
false;
4025 ReverseOrderSLT =
false;
4027 ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
4028 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
4029 ZeroSrcOpcode = Mips::BGTZ;
4030 ZeroTrgOpcode = Mips::BLTZ;
4036 AcceptsEquality =
true;
4037 ReverseOrderSLT =
true;
4039 ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
4040 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
4041 ZeroSrcOpcode = Mips::BGEZ;
4042 ZeroTrgOpcode = Mips::BLEZ;
4048 AcceptsEquality =
true;
4049 ReverseOrderSLT =
false;
4051 ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
4052 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
4053 ZeroSrcOpcode = Mips::BLEZ;
4054 ZeroTrgOpcode = Mips::BGEZ;
4060 AcceptsEquality =
false;
4061 ReverseOrderSLT =
true;
4063 ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
4064 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
4065 ZeroSrcOpcode = Mips::BLTZ;
4066 ZeroTrgOpcode = Mips::BGTZ;
4072 bool IsTrgRegZero = (TrgReg == Mips::R0);
4073 bool IsSrcRegZero = (SrcReg == Mips::R0);
4074 if (IsSrcRegZero && IsTrgRegZero) {
4078 if (PseudoOpcode == Mips::BLT) {
4083 if (PseudoOpcode == Mips::BLE) {
4086 Warning(IDLoc,
"branch is always taken");
4089 if (PseudoOpcode == Mips::BGE) {
4092 Warning(IDLoc,
"branch is always taken");
4095 if (PseudoOpcode == Mips::BGT) {
4100 if (PseudoOpcode == Mips::BGTU) {
4101 TOut.
emitRRX(Mips::BNE, Mips::R0, Mips::R0,
4105 if (AcceptsEquality) {
4108 TOut.
emitRRX(Mips::BEQ, Mips::R0, Mips::R0,
4110 Warning(IDLoc,
"branch is always taken");
4117 if (IsSrcRegZero || IsTrgRegZero) {
4118 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
4119 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
4126 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
4127 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
4133 TOut.
emitRRX(Mips::BEQ, Mips::R0, Mips::R0,
4135 Warning(IDLoc,
"branch is always taken");
4151 TOut.
emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
4152 IsSrcRegZero ? TrgReg : SrcReg, Mips::R0,
4159 TOut.
emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
4160 IsSrcRegZero ? TrgReg : SrcReg,
4167 MCRegister ATRegNum = getATReg(IDLoc);
4171 if (!EmittedNoMacroWarning)
4172 warnIfNoMacro(IDLoc);
4189 TOut.
emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
4190 ReverseOrderSLT ? TrgReg : SrcReg,
4191 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
4193 TOut.
emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
4194 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
4208bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4209 const MCSubtargetInfo *STI,
4210 const bool IsMips64,
const bool Signed) {
4211 MipsTargetStreamer &TOut = getTargetStreamer();
4213 warnIfNoMacro(IDLoc);
4215 const MCOperand &RdRegOp = Inst.
getOperand(0);
4216 assert(RdRegOp.
isReg() &&
"expected register operand kind");
4217 MCRegister RdReg = RdRegOp.
getReg();
4219 const MCOperand &RsRegOp = Inst.
getOperand(1);
4220 assert(RsRegOp.
isReg() &&
"expected register operand kind");
4221 MCRegister RsReg = RsRegOp.
getReg();
4228 "expected register or immediate operand kind");
4232 ImmValue = RtOp.
getImm();
4239 DivOp =
Signed ? Mips::DSDIV : Mips::DUDIV;
4240 ZeroReg = Mips::R0_64;
4243 DivOp =
Signed ? Mips::SDIV : Mips::UDIV;
4248 bool UseTraps = useTraps();
4251 bool isDiv = Opcode == Mips::SDivMacro || Opcode == Mips::SDivIMacro ||
4252 Opcode == Mips::UDivMacro || Opcode == Mips::UDivIMacro ||
4253 Opcode == Mips::DSDivMacro || Opcode == Mips::DSDivIMacro ||
4254 Opcode == Mips::DUDivMacro || Opcode == Mips::DUDivIMacro;
4256 bool isRem = Opcode == Mips::SRemMacro || Opcode == Mips::SRemIMacro ||
4257 Opcode == Mips::URemMacro || Opcode == Mips::URemIMacro ||
4258 Opcode == Mips::DSRemMacro || Opcode == Mips::DSRemIMacro ||
4259 Opcode == Mips::DURemMacro || Opcode == Mips::DURemIMacro;
4262 MCRegister ATReg = getATReg(IDLoc);
4266 if (!CLOpts.mno_check_zero_division && ImmValue == 0) {
4268 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4270 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4274 if (isRem && (ImmValue == 1 || (
Signed && (ImmValue == -1)))) {
4275 TOut.
emitRRR(Mips::OR, RdReg, ZeroReg, ZeroReg, IDLoc, STI);
4277 }
else if (isDiv && ImmValue == 1) {
4278 TOut.
emitRRR(Mips::OR, RdReg, RsReg, Mips::R0, IDLoc, STI);
4280 }
else if (isDiv &&
Signed && ImmValue == -1) {
4281 TOut.
emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
4284 if (loadImmediate(ImmValue, ATReg, MCRegister(),
isInt<32>(ImmValue),
4285 false, Inst.
getLoc(), Out, STI))
4287 TOut.
emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
4288 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4298 if (!CLOpts.mno_check_zero_division &&
4299 (RtReg == Mips::R0 || RtReg == Mips::R0_64)) {
4301 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4304 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4310 if (isRem && (RdReg == Mips::R0 || RdReg == Mips::R0_64)) {
4311 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4320 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4321 if (!CLOpts.mno_check_zero_division) {
4323 TOut.
emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4326 BrTarget =
Context.createTempSymbol();
4329 TOut.
emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4334 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4340 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4344bool MipsAsmParser::expandTrunc(MCInst &Inst,
bool IsDouble,
bool Is64FPU,
4345 SMLoc IDLoc, MCStreamer &Out,
4346 const MCSubtargetInfo *STI) {
4347 MipsTargetStreamer &TOut = getTargetStreamer();
4357 if (hasMips1() && !hasMips2()) {
4358 MCRegister ATReg = getATReg(IDLoc);
4364 TOut.
emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4365 TOut.
emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4368 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4370 FirstReg, SecondReg, IDLoc, STI);
4376 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4378 FirstReg, SecondReg, IDLoc, STI);
4383bool MipsAsmParser::expandUlh(MCInst &Inst,
bool Signed, SMLoc IDLoc,
4384 MCStreamer &Out,
const MCSubtargetInfo *STI) {
4385 if (hasMips32r6() || hasMips64r6()) {
4386 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4389 const MCOperand &DstRegOp = Inst.
getOperand(0);
4390 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4391 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4392 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4393 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4394 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4396 MipsTargetStreamer &TOut = getTargetStreamer();
4397 MCRegister DstReg = DstRegOp.
getReg();
4398 MCRegister SrcReg = SrcRegOp.
getReg();
4399 int64_t OffsetValue = OffsetImmOp.
getImm();
4403 warnIfNoMacro(IDLoc);
4404 MCRegister ATReg = getATReg(IDLoc);
4409 if (IsLargeOffset) {
4410 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4415 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4416 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4420 MCRegister FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4421 MCRegister SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4423 MCRegister LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4424 MCRegister SllReg = IsLargeOffset ? DstReg : ATReg;
4426 TOut.
emitRRI(
Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4427 FirstOffset, IDLoc, STI);
4428 TOut.
emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4429 TOut.
emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4430 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4435bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4436 const MCSubtargetInfo *STI) {
4437 if (hasMips32r6() || hasMips64r6()) {
4438 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4441 const MCOperand &DstRegOp = Inst.
getOperand(0);
4442 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4443 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4444 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4445 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4446 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4448 MipsTargetStreamer &TOut = getTargetStreamer();
4449 MCRegister DstReg = DstRegOp.
getReg();
4450 MCRegister SrcReg = SrcRegOp.
getReg();
4451 int64_t OffsetValue = OffsetImmOp.
getImm();
4453 warnIfNoMacro(IDLoc);
4454 MCRegister ATReg = getATReg(IDLoc);
4459 if (IsLargeOffset) {
4460 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4465 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4466 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4470 if (IsLargeOffset) {
4471 TOut.
emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4472 TOut.
emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4473 TOut.
emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4474 TOut.
emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4475 TOut.
emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4476 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4478 TOut.
emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4479 TOut.
emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4480 TOut.
emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4486bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4487 const MCSubtargetInfo *STI) {
4488 if (hasMips32r6() || hasMips64r6()) {
4489 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4492 const MCOperand &DstRegOp = Inst.
getOperand(0);
4493 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4494 const MCOperand &SrcRegOp = Inst.
getOperand(1);
4495 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4496 const MCOperand &OffsetImmOp = Inst.
getOperand(2);
4497 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4499 MipsTargetStreamer &TOut = getTargetStreamer();
4500 MCRegister DstReg = DstRegOp.
getReg();
4501 MCRegister SrcReg = SrcRegOp.
getReg();
4502 int64_t OffsetValue = OffsetImmOp.
getImm();
4506 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4507 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4511 bool IsLoadInst = (Inst.
getOpcode() == Mips::Ulw);
4512 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4513 MCRegister TmpReg = SrcReg;
4514 if (IsLargeOffset || DoMove) {
4515 warnIfNoMacro(IDLoc);
4516 TmpReg = getATReg(IDLoc);
4521 if (IsLargeOffset) {
4522 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4530 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4531 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4532 TOut.
emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4533 TOut.
emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4536 TOut.
emitRRR(Mips::OR, TmpReg, DstReg, Mips::R0, IDLoc, STI);
4541bool MipsAsmParser::expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4542 const MCSubtargetInfo *STI) {
4543 MipsTargetStreamer &TOut = getTargetStreamer();
4555 warnIfNoMacro(IDLoc);
4569 TOut.
emitRRR(OpCode, DstReg, SrcReg, OpReg, IDLoc, STI);
4570 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4575bool MipsAsmParser::expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4576 const MCSubtargetInfo *STI) {
4577 MipsTargetStreamer &TOut = getTargetStreamer();
4587 unsigned OpRegCode, OpImmCode;
4589 warnIfNoMacro(IDLoc);
4593 case Mips::SGEImm64:
4594 OpRegCode = Mips::SLT;
4595 OpImmCode = Mips::SLTi;
4598 case Mips::SGEUImm64:
4599 OpRegCode = Mips::SLTu;
4600 OpImmCode = Mips::SLTiu;
4609 TOut.
emitRRI(OpImmCode, DstReg, SrcReg, ImmValue, IDLoc, STI);
4610 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4612 MCRegister ImmReg = DstReg;
4613 if (DstReg == SrcReg) {
4614 MCRegister ATReg = getATReg(Inst.
getLoc());
4620 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
4621 false, IDLoc, Out, STI))
4624 TOut.
emitRRR(OpRegCode, DstReg, SrcReg, ImmReg, IDLoc, STI);
4625 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4631bool MipsAsmParser::expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4632 const MCSubtargetInfo *STI) {
4633 MipsTargetStreamer &TOut = getTargetStreamer();
4642 MCRegister ImmReg = DstReg;
4646 warnIfNoMacro(IDLoc);
4650 case Mips::SGTImm64:
4654 case Mips::SGTUImm64:
4661 if (DstReg == SrcReg) {
4662 MCRegister ATReg = getATReg(Inst.
getLoc());
4668 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
false,
4673 TOut.
emitRRR(OpCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4678bool MipsAsmParser::expandSle(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4679 const MCSubtargetInfo *STI) {
4680 MipsTargetStreamer &TOut = getTargetStreamer();
4692 warnIfNoMacro(IDLoc);
4706 TOut.
emitRRR(OpCode, DstReg, OpReg, SrcReg, IDLoc, STI);
4707 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4712bool MipsAsmParser::expandSleImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4713 const MCSubtargetInfo *STI) {
4714 MipsTargetStreamer &TOut = getTargetStreamer();
4726 warnIfNoMacro(IDLoc);
4730 case Mips::SLEImm64:
4731 OpRegCode = Mips::SLT;
4734 case Mips::SLEUImm64:
4735 OpRegCode = Mips::SLTu;
4742 MCRegister ImmReg = DstReg;
4743 if (DstReg == SrcReg) {
4744 MCRegister ATReg = getATReg(Inst.
getLoc());
4750 if (loadImmediate(ImmValue, ImmReg, MCRegister(),
isInt<32>(ImmValue),
false,
4754 TOut.
emitRRR(OpRegCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4755 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4760bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
4762 const MCSubtargetInfo *STI) {
4763 MipsTargetStreamer &TOut = getTargetStreamer();
4771 MCRegister FinalDstReg;
4778 unsigned FinalOpcode = Inst.
getOpcode();
4780 if (DstReg == SrcReg) {
4781 ATReg = getATReg(Inst.
getLoc());
4784 FinalDstReg = DstReg;
4788 if (!loadImmediate(ImmValue, DstReg, MCRegister(), Is32Bit,
false,
4789 Inst.
getLoc(), Out, STI)) {
4790 switch (FinalOpcode) {
4794 FinalOpcode = Mips::ADD;
4797 FinalOpcode = Mips::ADDu;
4800 FinalOpcode = Mips::AND;
4803 FinalOpcode = Mips::NOR;
4806 FinalOpcode = Mips::OR;
4809 FinalOpcode = Mips::SLT;
4812 FinalOpcode = Mips::SLTu;
4815 FinalOpcode = Mips::XOR;
4818 FinalOpcode = Mips::ADD_MM;
4820 case Mips::ADDiu_MM:
4821 FinalOpcode = Mips::ADDu_MM;
4824 FinalOpcode = Mips::AND_MM;
4827 FinalOpcode = Mips::OR_MM;
4830 FinalOpcode = Mips::SLT_MM;
4832 case Mips::SLTiu_MM:
4833 FinalOpcode = Mips::SLTu_MM;
4836 FinalOpcode = Mips::XOR_MM;
4839 FinalOpcode = Mips::AND64;
4841 case Mips::NORImm64:
4842 FinalOpcode = Mips::NOR64;
4845 FinalOpcode = Mips::OR64;
4847 case Mips::SLTImm64:
4848 FinalOpcode = Mips::SLT64;
4850 case Mips::SLTUImm64:
4851 FinalOpcode = Mips::SLTu64;
4854 FinalOpcode = Mips::XOR64;
4859 TOut.
emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4861 TOut.
emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4867bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4868 const MCSubtargetInfo *STI) {
4869 MipsTargetStreamer &TOut = getTargetStreamer();
4874 MCRegister TmpReg =
DReg;
4876 unsigned FirstShift = Mips::NOP;
4877 unsigned SecondShift = Mips::NOP;
4879 if (hasMips32r2()) {
4881 TmpReg = getATReg(Inst.
getLoc());
4887 TOut.
emitRRR(Mips::SUBu, TmpReg, Mips::R0, TReg, Inst.
getLoc(), STI);
4888 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
4893 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
4905 FirstShift = Mips::SRLV;
4906 SecondShift = Mips::SLLV;
4909 FirstShift = Mips::SLLV;
4910 SecondShift = Mips::SRLV;
4914 ATReg = getATReg(Inst.
getLoc());
4918 TOut.
emitRRR(Mips::SUBu, ATReg, Mips::R0, TReg, Inst.
getLoc(), STI);
4919 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
4920 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
4921 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
4929bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
4931 const MCSubtargetInfo *STI) {
4932 MipsTargetStreamer &TOut = getTargetStreamer();
4938 unsigned FirstShift = Mips::NOP;
4939 unsigned SecondShift = Mips::NOP;
4941 if (hasMips32r2()) {
4946 ShiftValue = MaxShift - ImmValue;
4947 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
4952 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.
getLoc(), STI);
4960 if (ImmValue == 0) {
4969 FirstShift = Mips::SLL;
4970 SecondShift = Mips::SRL;
4973 FirstShift = Mips::SRL;
4974 SecondShift = Mips::SLL;
4978 ATReg = getATReg(Inst.
getLoc());
4982 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.
getLoc(), STI);
4983 TOut.
emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.
getLoc(), STI);
4984 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
4992bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4993 const MCSubtargetInfo *STI) {
4994 MipsTargetStreamer &TOut = getTargetStreamer();
4999 MCRegister TmpReg =
DReg;
5001 unsigned FirstShift = Mips::NOP;
5002 unsigned SecondShift = Mips::NOP;
5004 if (hasMips64r2()) {
5005 if (TmpReg == SReg) {
5006 TmpReg = getATReg(Inst.
getLoc());
5012 TOut.
emitRRR(Mips::DSUBu, TmpReg, Mips::R0, TReg, Inst.
getLoc(), STI);
5013 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
5018 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
5030 FirstShift = Mips::DSRLV;
5031 SecondShift = Mips::DSLLV;
5034 FirstShift = Mips::DSLLV;
5035 SecondShift = Mips::DSRLV;
5039 ATReg = getATReg(Inst.
getLoc());
5043 TOut.
emitRRR(Mips::DSUBu, ATReg, Mips::R0, TReg, Inst.
getLoc(), STI);
5044 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
5045 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
5046 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5054bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
5056 const MCSubtargetInfo *STI) {
5057 MipsTargetStreamer &TOut = getTargetStreamer();
5063 unsigned FirstShift = Mips::NOP;
5064 unsigned SecondShift = Mips::NOP;
5066 if (hasMips64r2()) {
5067 unsigned FinalOpcode = Mips::NOP;
5069 FinalOpcode = Mips::DROTR;
5070 else if (ImmValue % 32 == 0)
5071 FinalOpcode = Mips::DROTR32;
5072 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
5074 FinalOpcode = Mips::DROTR32;
5076 FinalOpcode = Mips::DROTR;
5077 }
else if (ImmValue >= 33) {
5079 FinalOpcode = Mips::DROTR;
5081 FinalOpcode = Mips::DROTR32;
5084 uint64_t ShiftValue = ImmValue % 32;
5086 ShiftValue = (32 - ImmValue % 32) % 32;
5088 TOut.
emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
5094 if (ImmValue == 0) {
5095 TOut.
emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.
getLoc(), STI);
5103 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5104 FirstShift = Mips::DSLL;
5105 SecondShift = Mips::DSRL32;
5107 if (ImmValue == 32) {
5108 FirstShift = Mips::DSLL32;
5109 SecondShift = Mips::DSRL32;
5111 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5112 FirstShift = Mips::DSLL32;
5113 SecondShift = Mips::DSRL;
5117 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5118 FirstShift = Mips::DSRL;
5119 SecondShift = Mips::DSLL32;
5121 if (ImmValue == 32) {
5122 FirstShift = Mips::DSRL32;
5123 SecondShift = Mips::DSLL32;
5125 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5126 FirstShift = Mips::DSRL32;
5127 SecondShift = Mips::DSLL;
5132 ATReg = getATReg(Inst.
getLoc());
5136 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.
getLoc(), STI);
5137 TOut.
emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
5139 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5147bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5148 const MCSubtargetInfo *STI) {
5149 MipsTargetStreamer &TOut = getTargetStreamer();
5153 TOut.
emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
5154 if (FirstRegOp != SecondRegOp)
5155 TOut.
emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::R0, IDLoc, STI);
5158 TOut.
emitRRR(Mips::SUB, FirstRegOp, Mips::R0, SecondRegOp, IDLoc, STI);
5163bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5164 const MCSubtargetInfo *STI) {
5165 MipsTargetStreamer &TOut = getTargetStreamer();
5171 ATReg = getATReg(IDLoc);
5175 loadImmediate(ImmValue, ATReg, MCRegister(),
true,
false, IDLoc, Out, STI);
5177 TOut.
emitRR(Inst.
getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
5178 SrcReg, ATReg, IDLoc, STI);
5180 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5185bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5186 const MCSubtargetInfo *STI) {
5187 MipsTargetStreamer &TOut = getTargetStreamer();
5193 ATReg = getATReg(Inst.
getLoc());
5197 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
5198 SrcReg, TmpReg, IDLoc, STI);
5200 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5202 TOut.
emitRRI(Inst.
getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
5203 DstReg, DstReg, 0x1F, IDLoc, STI);
5205 TOut.
emitR(Mips::MFHI, ATReg, IDLoc, STI);
5208 TOut.
emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
5215 TOut.
emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
5216 if (AssemblerOptions.
back()->isReorder())
5218 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5222 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5227bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5228 const MCSubtargetInfo *STI) {
5229 MipsTargetStreamer &TOut = getTargetStreamer();
5235 ATReg = getATReg(IDLoc);
5239 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
5240 SrcReg, TmpReg, IDLoc, STI);
5242 TOut.
emitR(Mips::MFHI, ATReg, IDLoc, STI);
5243 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5245 TOut.
emitRRI(Mips::TNE, ATReg, Mips::R0, 6, IDLoc, STI);
5252 TOut.
emitRRX(Mips::BEQ, ATReg, Mips::R0, LabelOp, IDLoc, STI);
5253 if (AssemblerOptions.
back()->isReorder())
5255 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5263bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5264 const MCSubtargetInfo *STI) {
5265 MipsTargetStreamer &TOut = getTargetStreamer();
5270 TOut.
emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
5271 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5281bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
5283 const MCSubtargetInfo *STI,
5288 warnIfNoMacro(IDLoc);
5290 MipsTargetStreamer &TOut = getTargetStreamer();
5291 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
5293 MCRegister SecondReg =
nextReg(FirstReg);
5298 warnIfRegIndexIsAT(FirstReg, IDLoc);
5301 "Offset for load macro is not immediate!");
5304 signed NextOffset = FirstOffset.
getImm() + 4;
5312 if (FirstReg != BaseReg || !IsLoad) {
5313 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5314 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5316 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5317 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5329bool MipsAsmParser::expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc,
5331 const MCSubtargetInfo *STI) {
5335 warnIfNoMacro(IDLoc);
5337 MipsTargetStreamer &TOut = getTargetStreamer();
5338 unsigned Opcode = Mips::SWC1;
5340 MCRegister SecondReg =
nextReg(FirstReg);
5345 warnIfRegIndexIsAT(FirstReg, IDLoc);
5348 "Offset for macro is not immediate!");
5351 signed NextOffset = FirstOffset.
getImm() + 4;
5357 if (!IsLittleEndian)
5360 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5361 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5366bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5367 const MCSubtargetInfo *STI) {
5368 MipsTargetStreamer &TOut = getTargetStreamer();
5379 warnIfNoMacro(IDLoc);
5381 if (SrcReg != Mips::R0 && OpReg != Mips::R0) {
5382 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5383 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5387 MCRegister
Reg = SrcReg == Mips::R0 ? OpReg : SrcReg;
5388 TOut.
emitRRI(Mips::SLTiu, DstReg,
Reg, 1, IDLoc, STI);
5392bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5393 const MCSubtargetInfo *STI) {
5394 MipsTargetStreamer &TOut = getTargetStreamer();
5405 warnIfNoMacro(IDLoc);
5408 TOut.
emitRRI(Mips::SLTiu, DstReg, SrcReg, 1, IDLoc, STI);
5412 if (SrcReg == Mips::R0) {
5413 Warning(IDLoc,
"comparison is always false");
5414 TOut.
emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
5415 DstReg, SrcReg, SrcReg, IDLoc, STI);
5420 if (
Imm > -0x8000 &&
Imm < 0) {
5422 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5428 MCRegister ATReg = getATReg(IDLoc);
5432 if (loadImmediate(
Imm, ATReg, MCRegister(),
true, isGP64bit(), IDLoc, Out,
5436 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5437 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5442 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5446bool MipsAsmParser::expandSne(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5447 const MCSubtargetInfo *STI) {
5449 MipsTargetStreamer &TOut = getTargetStreamer();
5460 warnIfNoMacro(IDLoc);
5462 if (SrcReg != Mips::R0 && OpReg != Mips::R0) {
5463 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5464 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::R0, DstReg, IDLoc, STI);
5468 MCRegister
Reg = SrcReg == Mips::R0 ? OpReg : SrcReg;
5469 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::R0,
Reg, IDLoc, STI);
5473bool MipsAsmParser::expandSneI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5474 const MCSubtargetInfo *STI) {
5475 MipsTargetStreamer &TOut = getTargetStreamer();
5486 warnIfNoMacro(IDLoc);
5488 if (ImmValue == 0) {
5489 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::R0, SrcReg, IDLoc, STI);
5493 if (SrcReg == Mips::R0) {
5494 Warning(IDLoc,
"comparison is always true");
5495 if (loadImmediate(1, DstReg, MCRegister(),
true,
false, IDLoc, Out, STI))
5501 if (ImmValue > -0x8000 && ImmValue < 0) {
5502 ImmValue = -ImmValue;
5503 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5509 TOut.
emitRRI(
Opc, DstReg, SrcReg, ImmValue, IDLoc, STI);
5510 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::R0, DstReg, IDLoc, STI);
5514 MCRegister ATReg = getATReg(IDLoc);
5518 if (loadImmediate(ImmValue, ATReg, MCRegister(),
isInt<32>(ImmValue),
false,
5522 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5523 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::R0, DstReg, IDLoc, STI);
5657bool MipsAsmParser::expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5658 const MCSubtargetInfo *STI) {
5659 MipsTargetStreamer &TOut = getTargetStreamer();
5663 bool IsMFTR =
false;
5709 IsMFTR ? MCRegister(rd)
5711 : Inst.getOperand(0).
getReg());
5713 TOut.
emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, 1, sel, h, IDLoc,
5718bool MipsAsmParser::expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5719 const MCSubtargetInfo *STI) {
5724 warnIfNoMacro(IDLoc);
5726 MipsTargetStreamer &TOut = getTargetStreamer();
5727 unsigned Opcode = Inst.
getOpcode() == Mips::SaaAddr ? Mips::SAA : Mips::SAAD;
5730 const MCOperand &BaseOp = Inst.
getOperand(2);
5732 if (BaseOp.
isImm()) {
5733 int64_t ImmValue = BaseOp.
getImm();
5734 if (ImmValue == 0) {
5735 TOut.
emitRR(Opcode, RtReg, BaseReg, IDLoc, STI);
5740 MCRegister ATReg = getATReg(IDLoc);
5744 if (expandLoadAddress(ATReg, BaseReg, BaseOp, !isGP64bit(), IDLoc, Out, STI))
5747 TOut.
emitRR(Opcode, RtReg, ATReg, IDLoc, STI);
5752MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
5756 return Match_Success;
5759 if (
static_cast<MipsOperand &
>(*
Operands[1])
5760 .isValidForTie(
static_cast<MipsOperand &
>(*
Operands[2])))
5761 return Match_Success;
5762 return Match_RequiresSameSrcAndDst;
5766unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
5773 return Match_RequiresNoZeroRegister;
5774 return Match_Success;
5780 case Mips::JALR_HB64:
5781 case Mips::JALRC_HB_MMR6:
5782 case Mips::JALRC_MMR6:
5784 return Match_RequiresDifferentSrcAndDst;
5785 return Match_Success;
5788 return Match_RequiresDifferentSrcAndDst;
5789 return Match_Success;
5792 return Match_NonZeroOperandForSync;
5793 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();
5943 ErrorLoc =
static_cast<MipsOperand &
>(*
Operands[ErrorInfo])
5946 if (ErrorLoc == SMLoc())
5950 return Error(ErrorLoc,
"invalid operand for instruction");
5952 case Match_NonZeroOperandForSync:
5954 "s-type must be zero or unspecified for pre-MIPS32 ISAs");
5955 case Match_NonZeroOperandForMTCX:
5956 return Error(IDLoc,
"selector must be zero for pre-MIPS32 ISAs");
5957 case Match_MnemonicFail:
5958 return Error(IDLoc,
"invalid instruction");
5959 case Match_RequiresDifferentSrcAndDst:
5960 return Error(IDLoc,
"source and destination must be different");
5961 case Match_RequiresDifferentOperands:
5962 return Error(IDLoc,
"registers must be different");
5963 case Match_RequiresNoZeroRegister:
5964 return Error(IDLoc,
"invalid operand ($zero) for instruction");
5965 case Match_RequiresSameSrcAndDst:
5966 return Error(IDLoc,
"source and destination must match");
5967 case Match_NoFCCRegisterForCurrentISA:
5969 "non-zero fcc register doesn't exist in current ISA level");
5974 "expected 1-bit unsigned immediate");
5977 "expected 2-bit unsigned immediate");
5980 "expected immediate in range 1 .. 4");
5983 "expected 3-bit unsigned immediate");
5986 "expected 4-bit unsigned immediate");
5989 "expected 4-bit signed immediate");
5992 "expected 5-bit unsigned immediate");
5995 "expected 5-bit signed immediate");
5998 "expected immediate in range 1 .. 32");
5999 case Match_UImm5_32:
6001 "expected immediate in range 32 .. 63");
6002 case Match_UImm5_33:
6004 "expected immediate in range 33 .. 64");
6005 case Match_UImm5_0_Report_UImm6:
6009 "expected 6-bit unsigned immediate");
6010 case Match_ConstantMemOffset:
6012 !
static_cast<MipsOperand &
>(*
Operands[ErrorInfo]).isConstantImm())
6014 "expected immediate operand kind");
6016 "immediate operand value out of range");
6017 case Match_UImm5_Lsl2:
6019 "expected both 7-bit unsigned immediate and multiple of 4");
6020 case Match_UImmRange2_64:
6022 "expected immediate in range 2 .. 64");
6025 "expected 6-bit unsigned immediate");
6026 case Match_UImm6_Lsl2:
6028 "expected both 8-bit unsigned immediate and multiple of 4");
6031 "expected 6-bit signed immediate");
6034 "expected 7-bit unsigned immediate");
6035 case Match_UImm7_N1:
6037 "expected immediate in range -1 .. 126");
6038 case Match_SImm7_Lsl2:
6040 "expected both 9-bit signed immediate and multiple of 4");
6043 "expected 8-bit unsigned immediate");
6044 case Match_UImm10_0:
6046 "expected 10-bit unsigned immediate");
6047 case Match_SImm10_0:
6049 "expected 10-bit signed immediate");
6050 case Match_SImm11_0:
6052 "expected 11-bit signed immediate");
6054 case Match_UImm16_Relaxed:
6055 case Match_UImm16_AltRelaxed:
6057 "expected 16-bit unsigned immediate");
6059 case Match_SImm16_Relaxed:
6061 "expected 16-bit signed immediate");
6062 case Match_SImm18_Lsl3:
6064 "expected both 18-bit signed immediate and multiple of 8");
6065 case Match_SImm19_Lsl2:
6067 "expected both 19-bit signed immediate and multiple of 4");
6068 case Match_UImm20_0:
6070 "expected 20-bit unsigned immediate");
6071 case Match_UImm26_0:
6073 "expected 26-bit unsigned immediate");
6075 case Match_SImm32_Relaxed:
6077 "expected 32-bit signed immediate");
6078 case Match_UImm32_Coerced:
6080 "expected 32-bit immediate");
6081 case Match_MemSImm9:
6083 "expected memory with 9-bit signed offset");
6084 case Match_MemSImm10:
6086 "expected memory with 10-bit signed offset");
6087 case Match_MemSImm10Lsl1:
6089 "expected memory with 11-bit signed offset and multiple of 2");
6090 case Match_MemSImm10Lsl2:
6092 "expected memory with 12-bit signed offset and multiple of 4");
6093 case Match_MemSImm10Lsl3:
6095 "expected memory with 13-bit signed offset and multiple of 8");
6096 case Match_MemSImm11:
6098 "expected memory with 11-bit signed offset");
6099 case Match_MemSImm12:
6101 "expected memory with 12-bit signed offset");
6102 case Match_MemSImm16:
6104 "expected memory with 16-bit signed offset");
6105 case Match_MemSImmPtr:
6107 "expected memory with 32-bit signed offset");
6108 case Match_RequiresPosSizeRange0_32: {
6109 SMLoc ErrorStart =
Operands[3]->getStartLoc();
6110 SMLoc ErrorEnd =
Operands[4]->getEndLoc();
6111 return Error(ErrorStart,
"size plus position are not in the range 0 .. 32",
6112 SMRange(ErrorStart, ErrorEnd));
6114 case Match_RequiresPosSizeUImm6: {
6115 SMLoc ErrorStart =
Operands[3]->getStartLoc();
6116 SMLoc ErrorEnd =
Operands[4]->getEndLoc();
6117 return Error(ErrorStart,
"size plus position are not in the range 1 .. 63",
6118 SMRange(ErrorStart, ErrorEnd));
6120 case Match_RequiresPosSizeRange33_64: {
6121 SMLoc ErrorStart =
Operands[3]->getStartLoc();
6122 SMLoc ErrorEnd =
Operands[4]->getEndLoc();
6123 return Error(ErrorStart,
"size plus position are not in the range 33 .. 64",
6124 SMRange(ErrorStart, ErrorEnd));
6131void MipsAsmParser::warnIfRegIndexIsAT(MCRegister RegIndex, SMLoc Loc) {
6132 if (RegIndex && AssemblerOptions.
back()->getATRegIndex() == RegIndex)
6133 Warning(Loc,
"used $at (currently $" + Twine(RegIndex.
id()) +
6134 ") without \".set noat\"");
6137void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
6138 if (!AssemblerOptions.
back()->isMacro())
6139 Warning(Loc,
"macro instruction expanded into multiple instructions");
6142void MipsAsmParser::ConvertXWPOperands(MCInst &Inst,
6146 "Unexpected instruction!");
6147 ((MipsOperand &)*
Operands[1]).addGPR32ZeroAsmRegOperands(Inst, 1);
6148 MCRegister NextReg =
nextReg(((MipsOperand &)*
Operands[1]).getGPR32Reg());
6150 static_cast<MipsOperand &
>(*
Operands[4]).addPtrRegOperands(Inst, 1);
6151 static_cast<MipsOperand &
>(*
Operands[2]).addImmOperands(Inst, 1);
6154template <
unsigned Opcode,
bool IsMFTR>
6155void MipsAsmParser::ConvertMTTransferCOP0Operands(
6157 MCRegister GPR =
static_cast<const MipsOperand &
>(*
Operands[1]).getGPR32Reg();
6159 static_cast<const MipsOperand &
>(*
Operands[2]).getCOP0Encoding();
6163 ->getRegClass(Mips::GPR32RegClassID)
6174MipsAsmParser::printWarningWithFixIt(
const Twine &
Msg,
const Twine &FixMsg,
6175 SMRange
Range,
bool ShowColors) {
6181int MipsAsmParser::matchCPURegisterName(StringRef Name) {
6182 const MCRegisterInfo &
MRI = *
getContext().getRegisterInfo();
6188 AsmToken RegTok = getLexer().peekTok();
6189 StringRef FixedName =
6191 printWarningWithFixIt(
"register names $t4-$t7 are only available in O32.",
6192 "Did you mean $" + FixedName +
"?",
6198int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
6199 const MCRegisterInfo &
MRI = *
getContext().getRegisterInfo();
6201 Mips::RegAliasName);
6202 return Reg ?
MRI.getEncodingValue(
Reg) : -1;
6205int MipsAsmParser::matchFPURegisterName(StringRef Name) {
6206 if (Name[0] ==
'f') {
6207 StringRef NumString =
Name.substr(1);
6218int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
6219 if (
Name.starts_with(
"fcc")) {
6220 StringRef NumString =
Name.substr(3);
6231int MipsAsmParser::matchACRegisterName(StringRef Name) {
6232 if (
Name.starts_with(
"ac")) {
6233 StringRef NumString =
Name.substr(2);
6244int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
6247 if (
Name.front() !=
'w' ||
Name.drop_front(1).getAsInteger(10, IntVal))
6256int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
6257 const MCRegisterInfo &
MRI = *
getContext().getRegisterInfo();
6259 Name,
MRI, Mips::MSACtrlRegClassID, Mips::RegAliasName);
6260 return Reg ?
MRI.getEncodingValue(
Reg) : -1;
6263bool MipsAsmParser::canUseATReg() {
6264 return AssemblerOptions.
back()->getATRegIndex() != 0;
6267MCRegister MipsAsmParser::getATReg(SMLoc Loc) {
6268 unsigned ATIndex = AssemblerOptions.
back()->getATRegIndex();
6270 reportParseError(Loc,
6271 "pseudo-instruction requires $at, which is not available");
6275 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
6279MCRegister MipsAsmParser::getReg(
int RC,
int RegNo) {
6280 return getContext().getRegisterInfo()->getRegClass(RC).getRegister(RegNo);
6285bool MipsAsmParser::parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
6287 return getParser().parsePrimaryExpr(Res, EndLoc);
6288 Res = parseRelocExpr();
6289 EndLoc = getLexer().getLoc();
6295const MCExpr *MipsAsmParser::parseRelocExpr() {
6296 auto getOp = [](StringRef
Op) {
6297 return StringSwitch<Mips::Specifier>(
Op)
6325 MCAsmParser &Parser = getParser();
6327 const MCExpr *Res =
nullptr;
6333 auto Op = getOp(Name);
6342 while (
Ops.size()) {
6351 MCAsmParser &Parser = getParser();
6361 ParseStatus Res = MatchOperandParserImpl(
Operands, Mnemonic,
true);
6372 switch (getLexer().getKind()) {
6382 if (!parseAnyRegister(
Operands).isNoMatch())
6395 Operands.push_back(MipsOperand::CreateImm(SymRef, S,
E, *
this));
6400 const MCExpr *Expr = parseRelocExpr();
6404 Operands.push_back(MipsOperand::CreateImm(Expr, S,
E, *
this));
6411bool MipsAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
6413 return !tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess();
6416ParseStatus MipsAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
6419 ParseStatus Res = parseAnyRegister(
Operands);
6422 MipsOperand &Operand =
static_cast<MipsOperand &
>(*
Operands.front());
6423 StartLoc = Operand.getStartLoc();
6424 EndLoc = Operand.getEndLoc();
6430 if (Operand.isGPRAsmReg()) {
6432 Reg = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
6442const MCExpr *MipsAsmParser::parseMemOffset() {
6449 if (getParser().parseExpression(
Offset))
6458 SMLoc S = getLexer().getLoc();
6459 const MCExpr *
Offset = parseMemOffset();
6463 SMLoc
E = getLexer().getLoc();
6475 Operands.push_back(MipsOperand::CreateToken(
"(",
E, *
this));
6476 Operands.push_back(MipsOperand::createGPRReg(
6478 Operands.push_back(MipsOperand::CreateToken(
")",
E, *
this));
6483 MCAsmParser &Parser = getParser();
6485 const MCExpr *
Address = parseMemOffset();
6502 std::unique_ptr<MipsOperand>
Base(
6503 static_cast<MipsOperand *
>(
Operands.back().release()));
6505 E =
Base->getEndLoc();
6507 MipsOperand::CreateMem(std::move(
Base),
Address, S,
E, *
this));
6512 MCAsmParser &Parser = getParser();
6521 const MCSymbolRefExpr *
Ref =
static_cast<const MCSymbolRefExpr *
>(Expr);
6522 StringRef DefSymbol =
Ref->getSymbol().getName();
6525 matchAnyRegisterNameWithoutDollar(
Operands, DefSymbol.
substr(1), S);
6539 if (Entry != RegisterSets.
end()) {
6541 matchAnyRegisterWithoutDollar(
Operands,
Entry->getValue(), S);
6552ParseStatus MipsAsmParser::matchAnyRegisterNameWithoutDollar(
6554 int Index = matchCPURegisterName(Identifier);
6556 Operands.push_back(MipsOperand::createGPRReg(
6557 Index, Identifier,
getContext().getRegisterInfo(), S,
6558 getLexer().getLoc(), *
this));
6562 Index = matchHWRegsRegisterName(Identifier);
6564 Operands.push_back(MipsOperand::createHWRegsReg(
6565 Index, Identifier,
getContext().getRegisterInfo(), S,
6566 getLexer().getLoc(), *
this));
6570 const MCRegisterInfo &
MRI = *
getContext().getRegisterInfo();
6572 Identifier,
MRI, Mips::COP0RegClassID, Mips::RegAliasName)) {
6573 Operands.push_back(MipsOperand::createCOP0Reg(
MRI.getEncodingValue(
Reg),
6574 Identifier, &
MRI, S,
6575 getLexer().getLoc(), *
this));
6579 Index = matchFPURegisterName(Identifier);
6581 Operands.push_back(MipsOperand::createFGRReg(
6582 Index, Identifier,
getContext().getRegisterInfo(), S,
6583 getLexer().getLoc(), *
this));
6587 Index = matchFCCRegisterName(Identifier);
6589 Operands.push_back(MipsOperand::createFCCReg(
6590 Index, Identifier,
getContext().getRegisterInfo(), S,
6591 getLexer().getLoc(), *
this));
6595 Index = matchACRegisterName(Identifier);
6597 Operands.push_back(MipsOperand::createACCReg(
6598 Index, Identifier,
getContext().getRegisterInfo(), S,
6599 getLexer().getLoc(), *
this));
6603 Index = matchMSA128RegisterName(Identifier);
6605 Operands.push_back(MipsOperand::createMSA128Reg(
6606 Index, Identifier,
getContext().getRegisterInfo(), S,
6607 getLexer().getLoc(), *
this));
6611 Index = matchMSA128CtrlRegisterName(Identifier);
6613 Operands.push_back(MipsOperand::createMSACtrlReg(
6614 Index, Identifier,
getContext().getRegisterInfo(), S,
6615 getLexer().getLoc(), *
this));
6624 const AsmToken &Token, SMLoc S) {
6628 return matchAnyRegisterNameWithoutDollar(
Operands, Identifier, S);
6633 if (RegNum < 0 || RegNum > 31) {
6637 Error(getLexer().getLoc(),
"invalid register number");
6639 Operands.push_back(MipsOperand::createNumericReg(
6652 auto Token = getLexer().peekTok(
false);
6653 return matchAnyRegisterWithoutDollar(
Operands, Token, S);
6657 SMLoc S = getLexer().getLoc();
6659 ParseStatus Res = parseAnyRegister(RegOperands);
6662 const auto &
Op =
static_cast<const MipsOperand &
>(*RegOperands.
back());
6664 if (
Op.isCOP0AsmReg()) {
6665 Encoding =
Op.getCOP0Encoding();
6667 return Error(getLexer().getLoc(),
6668 "explicit selector is not allowed for named COP0 register");
6669 }
else if (
Op.isNumericReg()) {
6673 SMLoc SelLoc = getLexer().getLoc();
6675 if (getParser().parseExpression(Expr))
6677 if (!Expr->evaluateAsAbsolute(Sel) || !
isUInt<3>(Sel))
6678 return Error(SelLoc,
"expected 3-bit unsigned immediate");
6682 return Error(S,
"invalid operand for instruction");
6685 return Error(S,
"selector must be zero for pre-MIPS32 ISAs");
6687 const MCRegisterInfo &
MRI = *
getContext().getRegisterInfo();
6688 Operands.push_back(MipsOperand::createCOP0Reg(Encoding,
"", &
MRI, S,
6689 getLexer().getLoc(), *
this));
6694 MCAsmParser &Parser = getParser();
6697 auto Token = Parser.
getTok();
6699 SMLoc S = Token.
getLoc();
6712 ParseStatus Res = matchAnyRegisterWithoutDollar(
Operands, S);
6721 MCAsmParser &Parser = getParser();
6724 SMLoc S = getLexer().getLoc();
6727 ParseStatus Res = parseAnyRegister(
Operands);
6732 const MCExpr *Expr =
nullptr;
6738 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *
this));
6743 MCAsmParser &Parser = getParser();
6744 const MCExpr *IdVal;
6755 if (getParser().parseExpression(IdVal))
6762 Operands.push_back(MipsOperand::CreateImm(
6768 MCAsmParser &Parser = getParser();
6772 bool RegRange =
false;
6779 while (parseAnyRegister(TmpOperands).isSuccess()) {
6780 SMLoc
E = getLexer().getLoc();
6781 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*TmpOperands.
back());
6782 Reg = isGP64bit() ? RegOpnd.getGPR64Reg() : RegOpnd.getGPR32Reg();
6790 MCRegister TmpReg = PrevReg + 1;
6791 while (TmpReg <=
Reg) {
6792 if ((((TmpReg < Mips::R16) || (TmpReg > Mips::R23)) &&
6794 (((TmpReg < Mips::R16_64) || (TmpReg > Mips::R23_64)) &&
6796 return Error(
E,
"invalid register operand");
6800 TmpReg = TmpReg.
id() + 1;
6809 return Error(
E,
"$16 or $31 expected");
6811 (
Reg >= Mips::R16 &&
Reg <= Mips::R23)) &&
6814 (
Reg >= Mips::R16_64 &&
Reg <= Mips::R23_64)) &&
6816 return Error(
E,
"invalid register operand");
6817 if (PrevReg.
isValid() && (
Reg != PrevReg + 1) &&
6820 return Error(
E,
"consecutive register numbers expected");
6830 return Error(
E,
"',' or '-' expected");
6840 Operands.push_back(MipsOperand::CreateRegList(Regs, S,
E, *
this));
6841 return parseMemOffsetOperand(
Operands);
6850 MCAsmParser &Parser = getParser();
6853 MipsOperand::CreateToken(
"(", getLexer().getLoc(), *
this));
6855 if (parseOperand(
Operands, Name)) {
6856 SMLoc Loc = getLexer().getLoc();
6857 return Error(Loc,
"unexpected token in argument list");
6860 SMLoc Loc = getLexer().getLoc();
6861 return Error(Loc,
"unexpected token, expected ')'");
6864 MipsOperand::CreateToken(
")", getLexer().getLoc(), *
this));
6876bool MipsAsmParser::parseBracketSuffix(StringRef Name,
6878 MCAsmParser &Parser = getParser();
6881 MipsOperand::CreateToken(
"[", getLexer().getLoc(), *
this));
6883 if (parseOperand(
Operands, Name)) {
6884 SMLoc Loc = getLexer().getLoc();
6885 return Error(Loc,
"unexpected token in argument list");
6888 SMLoc Loc = getLexer().getLoc();
6889 return Error(Loc,
"unexpected token, expected ']'");
6892 MipsOperand::CreateToken(
"]", getLexer().getLoc(), *
this));
6899 unsigned VariantID = 0);
6914bool MipsAsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
6916 MCAsmParser &Parser = getParser();
6920 getTargetStreamer().forbidModuleDirective();
6923 if (!mnemonicIsValid(Name, 0)) {
6924 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
6926 return Error(NameLoc,
"unknown instruction" + Suggestion);
6929 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *
this));
6934 bool IsFirstOperand =
Operands.size() == 1;
6936 if (parseOperand(
Operands, Name)) {
6937 SMLoc Loc = getLexer().getLoc();
6938 return Error(Loc,
"unexpected token in argument list");
6943 if (parseBracketSuffix(Name,
Operands))
6951 SMLoc Loc = getLexer().getLoc();
6952 return Error(Loc,
"unexpected token in argument list");
6960bool MipsAsmParser::reportParseError(
const Twine &ErrorMsg) {
6961 SMLoc Loc = getLexer().getLoc();
6962 return Error(Loc, ErrorMsg);
6965bool MipsAsmParser::reportParseError(SMLoc Loc,
const Twine &ErrorMsg) {
6966 return Error(Loc, ErrorMsg);
6969bool MipsAsmParser::parseSetNoAtDirective() {
6970 MCAsmParser &Parser = getParser();
6974 AssemblerOptions.
back()->setATRegIndex(0);
6980 reportParseError(
"unexpected token, expected end of statement");
6984 getTargetStreamer().emitDirectiveSetNoAt();
6989bool MipsAsmParser::parseSetAtDirective() {
6992 MCAsmParser &Parser = getParser();
6997 AssemblerOptions.
back()->setATRegIndex(1);
6999 getTargetStreamer().emitDirectiveSetAt();
7005 reportParseError(
"unexpected token, expected equals sign");
7012 reportParseError(
"no register specified");
7015 reportParseError(
"unexpected token, expected dollar sign '$'");
7025 AtRegNo = matchCPURegisterName(
Reg.getIdentifier());
7027 AtRegNo =
Reg.getIntVal();
7029 reportParseError(
"unexpected token, expected identifier or integer");
7034 if (!AssemblerOptions.
back()->setATRegIndex(AtRegNo)) {
7035 reportParseError(
"invalid register");
7042 reportParseError(
"unexpected token, expected end of statement");
7046 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
7052bool MipsAsmParser::parseSetReorderDirective() {
7053 MCAsmParser &Parser = getParser();
7057 reportParseError(
"unexpected token, expected end of statement");
7060 AssemblerOptions.
back()->setReorder();
7061 getTargetStreamer().emitDirectiveSetReorder();
7066bool MipsAsmParser::parseSetNoReorderDirective() {
7067 MCAsmParser &Parser = getParser();
7071 reportParseError(
"unexpected token, expected end of statement");
7074 AssemblerOptions.
back()->setNoReorder();
7075 getTargetStreamer().emitDirectiveSetNoReorder();
7080bool MipsAsmParser::parseSetMacroDirective() {
7081 MCAsmParser &Parser = getParser();
7085 reportParseError(
"unexpected token, expected end of statement");
7088 AssemblerOptions.
back()->setMacro();
7089 getTargetStreamer().emitDirectiveSetMacro();
7094bool MipsAsmParser::parseSetNoMacroDirective() {
7095 MCAsmParser &Parser = getParser();
7099 reportParseError(
"unexpected token, expected end of statement");
7102 if (AssemblerOptions.
back()->isReorder()) {
7103 reportParseError(
"`noreorder' must be set before `nomacro'");
7106 AssemblerOptions.
back()->setNoMacro();
7107 getTargetStreamer().emitDirectiveSetNoMacro();
7112bool MipsAsmParser::parseSetMsaDirective() {
7113 MCAsmParser &Parser = getParser();
7118 return reportParseError(
"unexpected token, expected end of statement");
7120 setFeatureBits(Mips::FeatureMSA,
"msa");
7121 getTargetStreamer().emitDirectiveSetMsa();
7125bool MipsAsmParser::parseSetNoMsaDirective() {
7126 MCAsmParser &Parser = getParser();
7131 return reportParseError(
"unexpected token, expected end of statement");
7133 clearFeatureBits(Mips::FeatureMSA,
"msa");
7134 getTargetStreamer().emitDirectiveSetNoMsa();
7138bool MipsAsmParser::parseSetNoDspDirective() {
7139 MCAsmParser &Parser = getParser();
7144 reportParseError(
"unexpected token, expected end of statement");
7148 clearFeatureBits(Mips::FeatureDSP,
"dsp");
7149 getTargetStreamer().emitDirectiveSetNoDsp();
7153bool MipsAsmParser::parseSetNoMips3DDirective() {
7154 MCAsmParser &Parser = getParser();
7159 reportParseError(
"unexpected token, expected end of statement");
7163 clearFeatureBits(Mips::FeatureMips3D,
"mips3d");
7164 getTargetStreamer().emitDirectiveSetNoMips3D();
7168bool MipsAsmParser::parseSetMips16Directive() {
7169 MCAsmParser &Parser = getParser();
7174 reportParseError(
"unexpected token, expected end of statement");
7178 clearFeatureBits(Mips::FeatureMicroMips,
"micromips");
7179 setFeatureBits(Mips::FeatureMips16,
"mips16");
7180 getTargetStreamer().emitDirectiveSetMips16();
7185bool MipsAsmParser::parseSetNoMips16Directive() {
7186 MCAsmParser &Parser = getParser();
7191 reportParseError(
"unexpected token, expected end of statement");
7195 clearFeatureBits(Mips::FeatureMips16,
"mips16");
7196 getTargetStreamer().emitDirectiveSetNoMips16();
7201bool MipsAsmParser::parseSetFpDirective() {
7202 MCAsmParser &Parser = getParser();
7208 AsmToken Tok = Parser.
getTok();
7210 reportParseError(
"unexpected token, expected equals sign '='");
7216 if (!parseFpABIValue(FpAbiVal,
".set"))
7220 reportParseError(
"unexpected token, expected end of statement");
7223 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
7228bool MipsAsmParser::parseSetOddSPRegDirective() {
7229 MCAsmParser &Parser = getParser();
7233 reportParseError(
"unexpected token, expected end of statement");
7237 clearFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
7238 getTargetStreamer().emitDirectiveSetOddSPReg();
7242bool MipsAsmParser::parseSetNoOddSPRegDirective() {
7243 MCAsmParser &Parser = getParser();
7247 reportParseError(
"unexpected token, expected end of statement");
7251 setFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
7252 getTargetStreamer().emitDirectiveSetNoOddSPReg();
7256bool MipsAsmParser::parseSetMtDirective() {
7257 MCAsmParser &Parser = getParser();
7262 reportParseError(
"unexpected token, expected end of statement");
7266 setFeatureBits(Mips::FeatureMT,
"mt");
7267 getTargetStreamer().emitDirectiveSetMt();
7272bool MipsAsmParser::parseSetNoMtDirective() {
7273 MCAsmParser &Parser = getParser();
7278 reportParseError(
"unexpected token, expected end of statement");
7282 clearFeatureBits(Mips::FeatureMT,
"mt");
7284 getTargetStreamer().emitDirectiveSetNoMt();
7289bool MipsAsmParser::parseSetNoCRCDirective() {
7290 MCAsmParser &Parser = getParser();
7295 reportParseError(
"unexpected token, expected end of statement");
7299 clearFeatureBits(Mips::FeatureCRC,
"crc");
7301 getTargetStreamer().emitDirectiveSetNoCRC();
7306bool MipsAsmParser::parseSetNoVirtDirective() {
7307 MCAsmParser &Parser = getParser();
7312 reportParseError(
"unexpected token, expected end of statement");
7316 clearFeatureBits(Mips::FeatureVirt,
"virt");
7318 getTargetStreamer().emitDirectiveSetNoVirt();
7323bool MipsAsmParser::parseSetNoGINVDirective() {
7324 MCAsmParser &Parser = getParser();
7329 reportParseError(
"unexpected token, expected end of statement");
7333 clearFeatureBits(Mips::FeatureGINV,
"ginv");
7335 getTargetStreamer().emitDirectiveSetNoGINV();
7340bool MipsAsmParser::parseSetNoEVADirective() {
7341 MCAsmParser &Parser = getParser();
7346 reportParseError(
"unexpected token, expected end of statement");
7350 clearFeatureBits(Mips::FeatureEVA,
"eva");
7352 getTargetStreamer().emitDirectiveSetNoEVA();
7357bool MipsAsmParser::parseSetPopDirective() {
7358 MCAsmParser &Parser = getParser();
7359 SMLoc Loc = getLexer().getLoc();
7363 return reportParseError(
"unexpected token, expected end of statement");
7367 if (AssemblerOptions.
size() == 2)
7368 return reportParseError(Loc,
".set pop with no .set push");
7370 MCSubtargetInfo &STI = copySTI();
7372 setAvailableFeatures(
7373 ComputeAvailableFeatures(AssemblerOptions.
back()->getFeatures()));
7376 getTargetStreamer().emitDirectiveSetPop();
7380bool MipsAsmParser::parseSetPushDirective() {
7381 MCAsmParser &Parser = getParser();
7384 return reportParseError(
"unexpected token, expected end of statement");
7388 std::make_unique<MipsAssemblerOptions>(AssemblerOptions.
back().get()));
7390 getTargetStreamer().emitDirectiveSetPush();
7394bool MipsAsmParser::parseSetSoftFloatDirective() {
7395 MCAsmParser &Parser = getParser();
7398 return reportParseError(
"unexpected token, expected end of statement");
7400 setFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
7401 getTargetStreamer().emitDirectiveSetSoftFloat();
7405bool MipsAsmParser::parseSetHardFloatDirective() {
7406 MCAsmParser &Parser = getParser();
7409 return reportParseError(
"unexpected token, expected end of statement");
7411 clearFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
7412 getTargetStreamer().emitDirectiveSetHardFloat();
7416bool MipsAsmParser::parseSetAssignment() {
7418 MCAsmParser &Parser = getParser();
7421 return reportParseError(
"expected identifier after .set");
7424 return reportParseError(
"unexpected token, expected comma");
7439 const MCExpr *
Value;
7441 Parser, Sym,
Value))
7443 getStreamer().emitAssignment(Sym,
Value);
7448bool MipsAsmParser::parseSetMips0Directive() {
7449 MCAsmParser &Parser = getParser();
7452 return reportParseError(
"unexpected token, expected end of statement");
7455 MCSubtargetInfo &STI = copySTI();
7456 setAvailableFeatures(
7457 ComputeAvailableFeatures(AssemblerOptions.
front()->getFeatures()));
7459 AssemblerOptions.
back()->setFeatures(AssemblerOptions.
front()->getFeatures());
7461 getTargetStreamer().emitDirectiveSetMips0();
7465bool MipsAsmParser::parseSetArchDirective() {
7466 MCAsmParser &Parser = getParser();
7469 return reportParseError(
"unexpected token, expected equals sign");
7472 StringRef Arch = getParser().parseStringToEndOfStatement().trim();
7474 return reportParseError(
"expected arch identifier");
7476 StringRef ArchFeatureName =
7477 StringSwitch<StringRef>(Arch)
7478 .Case(
"mips1",
"mips1")
7479 .Case(
"mips2",
"mips2")
7480 .Case(
"mips3",
"mips3")
7481 .Case(
"mips4",
"mips4")
7482 .Case(
"mips5",
"mips5")
7483 .Case(
"mips32",
"mips32")
7484 .Case(
"mips32r2",
"mips32r2")
7485 .Case(
"mips32r3",
"mips32r3")
7486 .Case(
"mips32r5",
"mips32r5")
7487 .Case(
"mips32r6",
"mips32r6")
7488 .Case(
"mips64",
"mips64")
7489 .Case(
"mips64r2",
"mips64r2")
7490 .Case(
"mips64r3",
"mips64r3")
7491 .Case(
"mips64r5",
"mips64r5")
7492 .Case(
"mips64r6",
"mips64r6")
7493 .Case(
"octeon",
"cnmips")
7494 .Case(
"octeon+",
"cnmipsp")
7495 .Case(
"r4000",
"mips3")
7498 if (ArchFeatureName.
empty())
7499 return reportParseError(
"unsupported architecture");
7501 if (ArchFeatureName ==
"mips64r6" && inMicroMipsMode())
7502 return reportParseError(
"mips64r6 does not support microMIPS");
7504 selectArch(ArchFeatureName);
7505 getTargetStreamer().emitDirectiveSetArch(Arch);
7509bool MipsAsmParser::parseSetFeature(
uint64_t Feature) {
7510 MCAsmParser &Parser = getParser();
7513 return reportParseError(
"unexpected token, expected end of statement");
7518 case Mips::FeatureMips3D:
7519 setFeatureBits(Mips::FeatureMips3D,
"mips3d");
7520 getTargetStreamer().emitDirectiveSetMips3D();
7522 case Mips::FeatureDSP:
7523 setFeatureBits(Mips::FeatureDSP,
"dsp");
7524 getTargetStreamer().emitDirectiveSetDsp();
7526 case Mips::FeatureDSPR2:
7527 setFeatureBits(Mips::FeatureDSPR2,
"dspr2");
7528 getTargetStreamer().emitDirectiveSetDspr2();
7530 case Mips::FeatureMicroMips:
7531 clearFeatureBits(Mips::FeatureMips16,
"mips16");
7532 setFeatureBits(Mips::FeatureMicroMips,
"micromips");
7533 getTargetStreamer().emitDirectiveSetMicroMips();
7535 case Mips::FeatureMips1:
7536 selectArch(
"mips1");
7537 getTargetStreamer().emitDirectiveSetMips1();
7539 case Mips::FeatureMips2:
7540 selectArch(
"mips2");
7541 getTargetStreamer().emitDirectiveSetMips2();
7543 case Mips::FeatureMips3:
7544 selectArch(
"mips3");
7545 getTargetStreamer().emitDirectiveSetMips3();
7547 case Mips::FeatureMips4:
7548 selectArch(
"mips4");
7549 getTargetStreamer().emitDirectiveSetMips4();
7551 case Mips::FeatureMips5:
7552 selectArch(
"mips5");
7553 getTargetStreamer().emitDirectiveSetMips5();
7555 case Mips::FeatureMips32:
7556 selectArch(
"mips32");
7557 getTargetStreamer().emitDirectiveSetMips32();
7559 case Mips::FeatureMips32r2:
7560 selectArch(
"mips32r2");
7561 getTargetStreamer().emitDirectiveSetMips32R2();
7563 case Mips::FeatureMips32r3:
7564 selectArch(
"mips32r3");
7565 getTargetStreamer().emitDirectiveSetMips32R3();
7567 case Mips::FeatureMips32r5:
7568 selectArch(
"mips32r5");
7569 getTargetStreamer().emitDirectiveSetMips32R5();
7571 case Mips::FeatureMips32r6:
7572 selectArch(
"mips32r6");
7573 getTargetStreamer().emitDirectiveSetMips32R6();
7575 case Mips::FeatureMips64:
7576 selectArch(
"mips64");
7577 getTargetStreamer().emitDirectiveSetMips64();
7579 case Mips::FeatureMips64r2:
7580 selectArch(
"mips64r2");
7581 getTargetStreamer().emitDirectiveSetMips64R2();
7583 case Mips::FeatureMips64r3:
7584 selectArch(
"mips64r3");
7585 getTargetStreamer().emitDirectiveSetMips64R3();
7587 case Mips::FeatureMips64r5:
7588 selectArch(
"mips64r5");
7589 getTargetStreamer().emitDirectiveSetMips64R5();
7591 case Mips::FeatureMips64r6:
7592 selectArch(
"mips64r6");
7593 getTargetStreamer().emitDirectiveSetMips64R6();
7595 case Mips::FeatureCRC:
7596 setFeatureBits(Mips::FeatureCRC,
"crc");
7597 getTargetStreamer().emitDirectiveSetCRC();
7599 case Mips::FeatureVirt:
7600 setFeatureBits(Mips::FeatureVirt,
"virt");
7601 getTargetStreamer().emitDirectiveSetVirt();
7603 case Mips::FeatureGINV:
7604 setFeatureBits(Mips::FeatureGINV,
"ginv");
7605 getTargetStreamer().emitDirectiveSetGINV();
7607 case Mips::FeatureEVA:
7608 setFeatureBits(Mips::FeatureEVA,
"eva");
7609 getTargetStreamer().emitDirectiveSetEVA();
7615bool MipsAsmParser::eatComma(StringRef ErrorStr) {
7616 MCAsmParser &Parser = getParser();
7618 SMLoc Loc = getLexer().getLoc();
7619 return Error(Loc, ErrorStr);
7630bool MipsAsmParser::isPicAndNotNxxAbi() {
7631 return inPicMode() && !(isABI_N32() || isABI_N64());
7634bool MipsAsmParser::parseDirectiveCpAdd(SMLoc Loc) {
7636 ParseStatus Res = parseAnyRegister(
Reg);
7638 reportParseError(
"expected register");
7642 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7643 if (!RegOpnd.isGPRAsmReg()) {
7644 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7650 reportParseError(
"unexpected token, expected end of statement");
7655 getTargetStreamer().emitDirectiveCpAdd(RegOpnd.getGPR32Reg());
7659bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
7660 if (AssemblerOptions.
back()->isReorder())
7661 Warning(Loc,
".cpload should be inside a noreorder section");
7663 if (inMips16Mode()) {
7664 reportParseError(
".cpload is not supported in Mips16 mode");
7669 ParseStatus Res = parseAnyRegister(
Reg);
7671 reportParseError(
"expected register containing function address");
7675 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7676 if (!RegOpnd.isGPRAsmReg()) {
7677 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7683 reportParseError(
"unexpected token, expected end of statement");
7687 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
7691bool MipsAsmParser::parseDirectiveCpLocal(SMLoc Loc) {
7692 if (!isABI_N32() && !isABI_N64()) {
7693 reportParseError(
".cplocal is allowed only in N32 or N64 mode");
7698 ParseStatus Res = parseAnyRegister(
Reg);
7700 reportParseError(
"expected register containing global pointer");
7704 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7705 if (!RegOpnd.isGPRAsmReg()) {
7706 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7712 reportParseError(
"unexpected token, expected end of statement");
7717 MCRegister NewReg = RegOpnd.getGPR32Reg();
7721 getTargetStreamer().emitDirectiveCpLocal(NewReg);
7725bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
7726 MCAsmParser &Parser = getParser();
7731 if (inMips16Mode()) {
7732 reportParseError(
".cprestore is not supported in Mips16 mode");
7737 const MCExpr *StackOffset;
7738 int64_t StackOffsetVal;
7740 reportParseError(
"expected stack offset value");
7744 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
7745 reportParseError(
"stack offset is not an absolute expression");
7749 if (StackOffsetVal < 0) {
7750 Warning(Loc,
".cprestore with negative stack offset has no effect");
7751 IsCpRestoreSet =
false;
7753 IsCpRestoreSet =
true;
7754 CpRestoreOffset = StackOffsetVal;
7759 reportParseError(
"unexpected token, expected end of statement");
7763 if (!getTargetStreamer().emitDirectiveCpRestore(
7764 CpRestoreOffset, [&]() {
return getATReg(Loc); }, Loc, STI))
7770bool MipsAsmParser::parseDirectiveCPSetup() {
7771 MCAsmParser &Parser = getParser();
7773 bool SaveIsReg =
true;
7776 ParseStatus Res = parseAnyRegister(TmpReg);
7778 reportParseError(
"expected register containing function address");
7782 MipsOperand &FuncRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7783 if (!FuncRegOpnd.isGPRAsmReg()) {
7784 reportParseError(FuncRegOpnd.getStartLoc(),
"invalid register");
7788 MCRegister FuncReg = FuncRegOpnd.getGPR32Reg();
7791 if (!eatComma(
"unexpected token, expected comma"))
7794 Res = parseAnyRegister(TmpReg);
7796 const MCExpr *OffsetExpr;
7798 SMLoc ExprLoc = getLexer().
getLoc();
7801 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
7802 reportParseError(ExprLoc,
"expected save register or stack offset");
7809 MipsOperand &SaveOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7810 if (!SaveOpnd.isGPRAsmReg()) {
7811 reportParseError(SaveOpnd.getStartLoc(),
"invalid register");
7814 Save = SaveOpnd.getGPR32Reg().id();
7817 if (!eatComma(
"unexpected token, expected comma"))
7822 reportParseError(
"expected expression");
7827 reportParseError(
"expected symbol");
7830 const MCSymbolRefExpr *
Ref =
static_cast<const MCSymbolRefExpr *
>(Expr);
7832 CpSaveLocation = Save;
7833 CpSaveLocationIsRegister = SaveIsReg;
7835 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save,
Ref->getSymbol(),
7840bool MipsAsmParser::parseDirectiveCPReturn() {
7841 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
7842 CpSaveLocationIsRegister);
7846bool MipsAsmParser::parseDirectiveNaN() {
7847 MCAsmParser &Parser = getParser();
7849 const AsmToken &Tok = Parser.
getTok();
7853 getTargetStreamer().emitDirectiveNaN2008();
7855 }
else if (Tok.
getString() ==
"legacy") {
7857 getTargetStreamer().emitDirectiveNaNLegacy();
7863 reportParseError(
"invalid option in .nan directive");
7867bool MipsAsmParser::parseDirectiveSet() {
7868 const AsmToken &Tok = getParser().getTok();
7870 SMLoc Loc = Tok.
getLoc();
7872 if (IdVal ==
"noat")
7873 return parseSetNoAtDirective();
7875 return parseSetAtDirective();
7876 if (IdVal ==
"arch")
7877 return parseSetArchDirective();
7878 if (IdVal ==
"bopt") {
7879 Warning(Loc,
"'bopt' feature is unsupported");
7883 if (IdVal ==
"nobopt") {
7889 return parseSetFpDirective();
7890 if (IdVal ==
"oddspreg")
7891 return parseSetOddSPRegDirective();
7892 if (IdVal ==
"nooddspreg")
7893 return parseSetNoOddSPRegDirective();
7895 return parseSetPopDirective();
7896 if (IdVal ==
"push")
7897 return parseSetPushDirective();
7898 if (IdVal ==
"reorder")
7899 return parseSetReorderDirective();
7900 if (IdVal ==
"noreorder")
7901 return parseSetNoReorderDirective();
7902 if (IdVal ==
"macro")
7903 return parseSetMacroDirective();
7904 if (IdVal ==
"nomacro")
7905 return parseSetNoMacroDirective();
7906 if (IdVal ==
"mips16")
7907 return parseSetMips16Directive();
7908 if (IdVal ==
"nomips16")
7909 return parseSetNoMips16Directive();
7910 if (IdVal ==
"nomicromips") {
7911 clearFeatureBits(Mips::FeatureMicroMips,
"micromips");
7912 getTargetStreamer().emitDirectiveSetNoMicroMips();
7913 getParser().eatToEndOfStatement();
7916 if (IdVal ==
"micromips") {
7917 if (hasMips64r6()) {
7918 Error(Loc,
".set micromips directive is not supported with MIPS64R6");
7921 return parseSetFeature(Mips::FeatureMicroMips);
7923 if (IdVal ==
"mips0")
7924 return parseSetMips0Directive();
7925 if (IdVal ==
"mips1")
7926 return parseSetFeature(Mips::FeatureMips1);
7927 if (IdVal ==
"mips2")
7928 return parseSetFeature(Mips::FeatureMips2);
7929 if (IdVal ==
"mips3")
7930 return parseSetFeature(Mips::FeatureMips3);
7931 if (IdVal ==
"mips4")
7932 return parseSetFeature(Mips::FeatureMips4);
7933 if (IdVal ==
"mips5")
7934 return parseSetFeature(Mips::FeatureMips5);
7935 if (IdVal ==
"mips32")
7936 return parseSetFeature(Mips::FeatureMips32);
7937 if (IdVal ==
"mips32r2")
7938 return parseSetFeature(Mips::FeatureMips32r2);
7939 if (IdVal ==
"mips32r3")
7940 return parseSetFeature(Mips::FeatureMips32r3);
7941 if (IdVal ==
"mips32r5")
7942 return parseSetFeature(Mips::FeatureMips32r5);
7943 if (IdVal ==
"mips32r6")
7944 return parseSetFeature(Mips::FeatureMips32r6);
7945 if (IdVal ==
"mips64")
7946 return parseSetFeature(Mips::FeatureMips64);
7947 if (IdVal ==
"mips64r2")
7948 return parseSetFeature(Mips::FeatureMips64r2);
7949 if (IdVal ==
"mips64r3")
7950 return parseSetFeature(Mips::FeatureMips64r3);
7951 if (IdVal ==
"mips64r5")
7952 return parseSetFeature(Mips::FeatureMips64r5);
7953 if (IdVal ==
"mips64r6") {
7954 if (inMicroMipsMode()) {
7955 Error(Loc,
"MIPS64R6 is not supported with microMIPS");
7958 return parseSetFeature(Mips::FeatureMips64r6);
7961 return parseSetFeature(Mips::FeatureDSP);
7962 if (IdVal ==
"dspr2")
7963 return parseSetFeature(Mips::FeatureDSPR2);
7964 if (IdVal ==
"nodsp")
7965 return parseSetNoDspDirective();
7966 if (IdVal ==
"mips3d")
7967 return parseSetFeature(Mips::FeatureMips3D);
7968 if (IdVal ==
"nomips3d")
7969 return parseSetNoMips3DDirective();
7971 return parseSetMsaDirective();
7972 if (IdVal ==
"nomsa")
7973 return parseSetNoMsaDirective();
7975 return parseSetMtDirective();
7976 if (IdVal ==
"nomt")
7977 return parseSetNoMtDirective();
7978 if (IdVal ==
"softfloat")
7979 return parseSetSoftFloatDirective();
7980 if (IdVal ==
"hardfloat")
7981 return parseSetHardFloatDirective();
7983 return parseSetFeature(Mips::FeatureCRC);
7984 if (IdVal ==
"nocrc")
7985 return parseSetNoCRCDirective();
7986 if (IdVal ==
"virt")
7987 return parseSetFeature(Mips::FeatureVirt);
7988 if (IdVal ==
"novirt")
7989 return parseSetNoVirtDirective();
7990 if (IdVal ==
"ginv")
7991 return parseSetFeature(Mips::FeatureGINV);
7992 if (IdVal ==
"noginv")
7993 return parseSetNoGINVDirective();
7995 return parseSetFeature(Mips::FeatureEVA);
7996 if (IdVal ==
"noeva")
7997 return parseSetNoEVADirective();
8000 return parseSetAssignment();
8005bool MipsAsmParser::parseDirectiveGpWord() {
8006 const MCExpr *
Value;
8007 if (getParser().parseExpression(
Value))
8009 getTargetStreamer().emitGPRel32Value(
Value);
8015bool MipsAsmParser::parseDirectiveGpDWord() {
8016 const MCExpr *
Value;
8017 if (getParser().parseExpression(
Value))
8019 getTargetStreamer().emitGPRel64Value(
Value);
8025bool MipsAsmParser::parseDirectiveDtpRelWord() {
8026 const MCExpr *
Value;
8027 if (getParser().parseExpression(
Value))
8029 getTargetStreamer().emitDTPRel32Value(
Value);
8035bool MipsAsmParser::parseDirectiveDtpRelDWord() {
8036 const MCExpr *
Value;
8037 if (getParser().parseExpression(
Value))
8039 getTargetStreamer().emitDTPRel64Value(
Value);
8045bool MipsAsmParser::parseDirectiveTpRelWord() {
8046 const MCExpr *
Value;
8047 if (getParser().parseExpression(
Value))
8049 getTargetStreamer().emitTPRel32Value(
Value);
8055bool MipsAsmParser::parseDirectiveTpRelDWord() {
8056 const MCExpr *
Value;
8057 if (getParser().parseExpression(
Value))
8059 getTargetStreamer().emitTPRel64Value(
Value);
8063bool MipsAsmParser::parseDirectiveOption() {
8064 MCAsmParser &Parser = getParser();
8066 AsmToken Tok = Parser.
getTok();
8070 "unexpected token, expected identifier");
8075 if (Option ==
"pic0") {
8077 IsPicEnabled =
false;
8079 getTargetStreamer().emitDirectiveOptionPic0();
8083 "unexpected token, expected end of statement");
8088 if (Option ==
"pic2") {
8090 IsPicEnabled =
true;
8092 getTargetStreamer().emitDirectiveOptionPic2();
8096 "unexpected token, expected end of statement");
8103 "unknown option, expected 'pic0' or 'pic2'");
8110bool MipsAsmParser::parseInsnDirective() {
8113 reportParseError(
"unexpected token, expected end of statement");
8119 getTargetStreamer().emitDirectiveInsn();
8127bool MipsAsmParser::parseRSectionDirective(StringRef Section) {
8130 reportParseError(
"unexpected token, expected end of statement");
8134 MCSection *ELFSection =
getContext().getELFSection(
8136 getParser().getStreamer().switchSection(ELFSection);
8145bool MipsAsmParser::parseSSectionDirective(StringRef Section,
unsigned Type) {
8148 reportParseError(
"unexpected token, expected end of statement");
8152 MCSection *ELFSection =
getContext().getELFSection(
8154 getParser().getStreamer().switchSection(ELFSection);
8173bool MipsAsmParser::parseDirectiveModule() {
8174 MCAsmParser &Parser = getParser();
8175 AsmLexer &Lexer = getLexer();
8178 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
8180 reportParseError(
".module directive must appear before any code");
8186 reportParseError(
"expected .module option identifier");
8190 if (Option ==
"oddspreg") {
8191 clearModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
8195 getTargetStreamer().updateABIInfo(*
this);
8200 getTargetStreamer().emitDirectiveModuleOddSPReg();
8204 reportParseError(
"unexpected token, expected end of statement");
8209 }
else if (Option ==
"nooddspreg") {
8211 return Error(L,
"'.module nooddspreg' requires the O32 ABI");
8214 setModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
8218 getTargetStreamer().updateABIInfo(*
this);
8223 getTargetStreamer().emitDirectiveModuleOddSPReg();
8227 reportParseError(
"unexpected token, expected end of statement");
8232 }
else if (Option ==
"fp") {
8233 return parseDirectiveModuleFP();
8234 }
else if (Option ==
"softfloat") {
8235 setModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
8239 getTargetStreamer().updateABIInfo(*
this);
8244 getTargetStreamer().emitDirectiveModuleSoftFloat();
8248 reportParseError(
"unexpected token, expected end of statement");
8253 }
else if (Option ==
"hardfloat") {
8254 clearModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
8258 getTargetStreamer().updateABIInfo(*
this);
8263 getTargetStreamer().emitDirectiveModuleHardFloat();
8267 reportParseError(
"unexpected token, expected end of statement");
8272 }
else if (Option ==
"mt") {
8273 setModuleFeatureBits(Mips::FeatureMT,
"mt");
8277 getTargetStreamer().updateABIInfo(*
this);
8282 getTargetStreamer().emitDirectiveModuleMT();
8286 reportParseError(
"unexpected token, expected end of statement");
8291 }
else if (Option ==
"crc") {
8292 setModuleFeatureBits(Mips::FeatureCRC,
"crc");
8296 getTargetStreamer().updateABIInfo(*
this);
8301 getTargetStreamer().emitDirectiveModuleCRC();
8305 reportParseError(
"unexpected token, expected end of statement");
8310 }
else if (Option ==
"nocrc") {
8311 clearModuleFeatureBits(Mips::FeatureCRC,
"crc");
8315 getTargetStreamer().updateABIInfo(*
this);
8320 getTargetStreamer().emitDirectiveModuleNoCRC();
8324 reportParseError(
"unexpected token, expected end of statement");
8329 }
else if (Option ==
"virt") {
8330 setModuleFeatureBits(Mips::FeatureVirt,
"virt");
8334 getTargetStreamer().updateABIInfo(*
this);
8339 getTargetStreamer().emitDirectiveModuleVirt();
8343 reportParseError(
"unexpected token, expected end of statement");
8348 }
else if (Option ==
"novirt") {
8349 clearModuleFeatureBits(Mips::FeatureVirt,
"virt");
8353 getTargetStreamer().updateABIInfo(*
this);
8358 getTargetStreamer().emitDirectiveModuleNoVirt();
8362 reportParseError(
"unexpected token, expected end of statement");
8367 }
else if (Option ==
"ginv") {
8368 setModuleFeatureBits(Mips::FeatureGINV,
"ginv");
8372 getTargetStreamer().updateABIInfo(*
this);
8377 getTargetStreamer().emitDirectiveModuleGINV();
8381 reportParseError(
"unexpected token, expected end of statement");
8386 }
else if (Option ==
"noginv") {
8387 clearModuleFeatureBits(Mips::FeatureGINV,
"ginv");
8391 getTargetStreamer().updateABIInfo(*
this);
8396 getTargetStreamer().emitDirectiveModuleNoGINV();
8400 reportParseError(
"unexpected token, expected end of statement");
8406 return Error(L,
"'" + Twine(Option) +
"' is not a valid .module option.");
8414bool MipsAsmParser::parseDirectiveModuleFP() {
8415 MCAsmParser &Parser = getParser();
8416 AsmLexer &Lexer = getLexer();
8419 reportParseError(
"unexpected token, expected equals sign '='");
8425 if (!parseFpABIValue(FpABI,
".module"))
8429 reportParseError(
"unexpected token, expected end of statement");
8435 getTargetStreamer().updateABIInfo(*
this);
8440 getTargetStreamer().emitDirectiveModuleFP();
8447 StringRef Directive) {
8448 MCAsmParser &Parser = getParser();
8449 AsmLexer &Lexer = getLexer();
8450 bool ModuleLevelOptions = Directive ==
".module";
8456 if (
Value !=
"xx") {
8457 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
8462 reportParseError(
"'" + Directive +
" fp=xx' requires the O32 ABI");
8466 FpABI = MipsABIFlagsSection::FpABIKind::XX;
8467 if (ModuleLevelOptions) {
8468 setModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8469 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8471 setFeatureBits(Mips::FeatureFPXX,
"fpxx");
8472 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8482 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
8488 reportParseError(
"'" + Directive +
" fp=32' requires the O32 ABI");
8492 FpABI = MipsABIFlagsSection::FpABIKind::S32;
8493 if (ModuleLevelOptions) {
8494 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8495 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8497 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
8498 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8501 FpABI = MipsABIFlagsSection::FpABIKind::S64;
8502 if (ModuleLevelOptions) {
8503 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8504 setModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8506 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
8507 setFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8517bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
8523 MCAsmParser &Parser = getParser();
8524 StringRef IDVal = DirectiveID.
getString();
8526 if (IDVal ==
".cpadd") {
8527 parseDirectiveCpAdd(DirectiveID.
getLoc());
8530 if (IDVal ==
".cpload") {
8531 parseDirectiveCpLoad(DirectiveID.
getLoc());
8534 if (IDVal ==
".cprestore") {
8535 parseDirectiveCpRestore(DirectiveID.
getLoc());
8538 if (IDVal ==
".cplocal") {
8539 parseDirectiveCpLocal(DirectiveID.
getLoc());
8542 if (IDVal ==
".ent") {
8546 reportParseError(
"expected identifier after .ent");
8560 reportParseError(
"unexpected token, expected end of statement");
8564 const MCExpr *DummyNumber;
8565 int64_t DummyNumberVal;
8569 reportParseError(
"expected number after comma");
8572 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
8573 reportParseError(
"expected an absolute expression after comma");
8580 reportParseError(
"unexpected token, expected end of statement");
8586 getTargetStreamer().emitDirectiveEnt(*Sym);
8588 IsCpRestoreSet =
false;
8592 if (IDVal ==
".end") {
8596 reportParseError(
"expected identifier after .end");
8601 reportParseError(
"unexpected token, expected end of statement");
8605 if (CurrentFn ==
nullptr) {
8606 reportParseError(
".end used without .ent");
8610 if ((SymbolName != CurrentFn->
getName())) {
8611 reportParseError(
".end symbol does not match .ent symbol");
8615 getTargetStreamer().emitDirectiveEnd(SymbolName);
8616 CurrentFn =
nullptr;
8617 IsCpRestoreSet =
false;
8621 if (IDVal ==
".frame") {
8624 ParseStatus Res = parseAnyRegister(TmpReg);
8626 reportParseError(
"expected stack register");
8630 MipsOperand &StackRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
8631 if (!StackRegOpnd.isGPRAsmReg()) {
8632 reportParseError(StackRegOpnd.getStartLoc(),
8633 "expected general purpose register");
8636 MCRegister StackReg = StackRegOpnd.getGPR32Reg();
8641 reportParseError(
"unexpected token, expected comma");
8646 const MCExpr *FrameSize;
8647 int64_t FrameSizeVal;
8650 reportParseError(
"expected frame size value");
8654 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
8655 reportParseError(
"frame size not an absolute expression");
8662 reportParseError(
"unexpected token, expected comma");
8668 Res = parseAnyRegister(TmpReg);
8670 reportParseError(
"expected return register");
8674 MipsOperand &ReturnRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
8675 if (!ReturnRegOpnd.isGPRAsmReg()) {
8676 reportParseError(ReturnRegOpnd.getStartLoc(),
8677 "expected general purpose register");
8683 reportParseError(
"unexpected token, expected end of statement");
8687 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
8688 ReturnRegOpnd.getGPR32Reg());
8689 IsCpRestoreSet =
false;
8693 if (IDVal ==
".set") {
8694 parseDirectiveSet();
8698 if (IDVal ==
".mask" || IDVal ==
".fmask") {
8709 const MCExpr *BitMask;
8713 reportParseError(
"expected bitmask value");
8717 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
8718 reportParseError(
"bitmask not an absolute expression");
8725 reportParseError(
"unexpected token, expected comma");
8730 const MCExpr *FrameOffset;
8731 int64_t FrameOffsetVal;
8734 reportParseError(
"expected frame offset value");
8738 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
8739 reportParseError(
"frame offset not an absolute expression");
8745 reportParseError(
"unexpected token, expected end of statement");
8749 if (IDVal ==
".mask")
8750 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
8752 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
8756 if (IDVal ==
".nan")
8757 return parseDirectiveNaN();
8759 if (IDVal ==
".gpword") {
8760 parseDirectiveGpWord();
8764 if (IDVal ==
".gpdword") {
8765 parseDirectiveGpDWord();
8769 if (IDVal ==
".dtprelword") {
8770 parseDirectiveDtpRelWord();
8774 if (IDVal ==
".dtpreldword") {
8775 parseDirectiveDtpRelDWord();
8779 if (IDVal ==
".tprelword") {
8780 parseDirectiveTpRelWord();
8784 if (IDVal ==
".tpreldword") {
8785 parseDirectiveTpRelDWord();
8789 if (IDVal ==
".option") {
8790 parseDirectiveOption();
8794 if (IDVal ==
".abicalls") {
8795 getTargetStreamer().emitDirectiveAbiCalls();
8798 "unexpected token, expected end of statement");
8803 if (IDVal ==
".cpsetup") {
8804 parseDirectiveCPSetup();
8807 if (IDVal ==
".cpreturn") {
8808 parseDirectiveCPReturn();
8811 if (IDVal ==
".module") {
8812 parseDirectiveModule();
8815 if (IDVal ==
".llvm_internal_mips_reallow_module_directive") {
8816 parseInternalDirectiveReallowModule();
8819 if (IDVal ==
".insn") {
8820 parseInsnDirective();
8823 if (IDVal ==
".rdata") {
8824 parseRSectionDirective(
".rodata");
8827 if (IDVal ==
".sbss") {
8831 if (IDVal ==
".sdata") {
8839bool MipsAsmParser::parseInternalDirectiveReallowModule() {
8842 reportParseError(
"unexpected token, expected end of statement");
8846 getTargetStreamer().reallowModuleDirective();
8860#define GET_REGISTER_MATCHER
8861#define GET_MATCHER_IMPLEMENTATION
8862#define GET_MNEMONIC_SPELL_CHECKER
8863#include "MipsGenAsmMatcher.inc"
8865bool MipsAsmParser::mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID) {
8867 const MatchEntry *Start, *
End;
8868 switch (VariantID) {
8870 case 0: Start = std::begin(MatchTable0);
End = std::end(MatchTable0);
break;
8873 auto MnemonicRange = std::equal_range(Start,
End, Mnemonic, LessOpcode());
8874 return MnemonicRange.first != MnemonicRange.second;
static const TargetRegisterClass * getRegClass(const MachineInstr &MI, Register Reg)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
This file declares a class to represent arbitrary precision floating point values and provide a varie...
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
static Value * expandAbs(CallInst *Orig)
std::pair< Instruction::BinaryOps, Value * > OffsetOp
Find all possible pairs (BinOp, RHS) that BinOp V, RHS can be simplified.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static FeatureBitset getFeatures(MCSubtargetInfo &STI, StringRef CPU, StringRef TuneCPU, StringRef FS, StringTable ProcNames, ArrayRef< SubtargetSubTypeKV > ProcDesc, ArrayRef< SubtargetFeatureKV > ProcFeatures)
static bool hasFeature(StringRef Feature, const FeatureBitset &FeatureBits, ArrayRef< SubtargetFeatureKV > ProcFeatures)
static unsigned countMCSymbolRefExpr(const MCExpr *Expr)
static std::string MipsMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, unsigned VariantID=0)
static uint64_t convertIntToDoubleImm(uint64_t ImmOp64)
static uint32_t covertDoubleImmToSingleImm(uint64_t ImmOp64)
static unsigned getRegisterForMxtrDSP(MCInst &Inst, bool IsMFDSP)
static bool hasShortDelaySlot(MCInst &Inst)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsAsmParser()
static bool needsExpandMemInst(MCInst &Inst, const MCInstrDesc &MCID)
static bool isShiftedUIntAtAnyPosition(uint64_t x)
Can the value be represented by a unsigned N-bit value and a shift left?
static bool isEvaluated(const MCExpr *Expr)
static const MCSymbol * getSingleMCSymbol(const MCExpr *Expr)
static MCRegister nextReg(MCRegister Reg)
static unsigned getRegisterForMxtrFP(MCInst &Inst, bool IsMFTC1)
static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands, uint64_t ErrorInfo)
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
MachineRegisterInfo & MRI
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static bool isMemOperand(const MCInst &MI, unsigned Op, unsigned RegClassID)
static const fltSemantics & IEEEdouble()
APInt bitcastToAPInt() const
uint64_t getZExtValue() const
Get zero extended value.
SMLoc getLoc() const
Get the current source location.
const AsmToken peekTok(bool ShouldSkipSpace=true)
Look ahead at the next token to be lexed.
bool is(AsmToken::TokenKind K) const
Check if the current token has kind K.
bool isNot(AsmToken::TokenKind K) const
Check if the current token has kind K.
Target independent representation for an assembler token.
LLVM_ABI SMLoc getLoc() const
int64_t getIntVal() const
bool isNot(TokenKind K) const
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
bool is(TokenKind K) const
TokenKind getKind() const
LLVM_ABI SMRange getLocRange() const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
Base class for user error types.
Container class for subtarget features.
void printExpr(raw_ostream &, const MCExpr &) const
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
bool parseToken(AsmToken::TokenKind T, const Twine &Msg="unexpected token")
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
Binary assembler expressions.
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Base class for the full range of assembler expressions which are needed for parsing.
LLVM_ABI bool evaluateAsRelocatable(MCValue &Res, const MCAssembler *Asm) const
Try to evaluate the expression to a relocatable value, i.e.
@ Unary
Unary expressions.
@ Constant
Constant expressions.
@ SymbolRef
References to labels and assigned expressions.
@ Target
Target specific expression.
@ Specifier
Expression with a relocation specifier.
@ Binary
Binary expressions.
Instances of this class represent a single low-level machine instruction.
unsigned getNumOperands() const
unsigned getOpcode() const
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
const MCOperand & getOperand(unsigned i) const
Describe properties that are true of each instruction in the target description file.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
ArrayRef< MCOperandInfo > operands() const
bool mayStore() const
Return true if this instruction could possibly modify memory.
bool mayLoad() const
Return true if this instruction could possibly read memory.
bool isBranch() const
Returns true if this is a conditional, unconditional, or indirect branch.
bool isCall() const
Return true if the instruction is a call.
bool hasDelaySlot() const
Returns true if the specified instruction has a delay slot which must be filled by the code generator...
Interface to description of machine instruction set.
This holds information about one operand of a machine instruction, indicating the register class for ...
uint8_t OperandType
Information about the type of the operand.
Instances of this class represent operands of the MCInst class.
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
MCRegister getReg() const
Returns the register number.
const MCExpr * getExpr() const
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual bool isReg() const =0
isReg - Is this a register operand?
virtual MCRegister getReg() const =0
MCRegister getRegister(unsigned i) const
getRegister - Return the specified register in the class.
Wrapper class representing physical registers. Should be passed by value.
constexpr bool isValid() const
constexpr unsigned id() const
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
Streaming machine code generation interface.
virtual void emitRelocDirective(const MCExpr &Offset, StringRef Name, const MCExpr *Expr, SMLoc Loc={})
Record a relocation described by the .reloc directive.
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
void setFeatureBits(const FeatureBitset &FeatureBits_)
const Triple & getTargetTriple() const
const FeatureBitset & getFeatureBits() const
const FeatureBitset & ToggleFeature(uint64_t FB)
Toggle a feature and return the re-computed feature bits.
virtual unsigned getHwMode(enum HwModeType type=HwMode_Default) const
HwMode ID corresponding to the 'type' parameter is retrieved from the HwMode bit set of the current s...
Represent a reference to a symbol from inside an expression.
uint16_t getSpecifier() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
bool isInSection() const
isInSection - Check if this symbol is defined in some section (i.e., it is defined but not absolute).
bool isUndefined() const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).
StringRef getName() const
getName - Get the symbol name.
bool isVariable() const
isVariable - Check if this is a variable symbol.
const MCExpr * getVariableValue() const
Get the expression of the variable symbol.
bool isTemporary() const
isTemporary - Check if this is an assembler temporary symbol.
MCTargetAsmParser - Generic interface to target specific assembly parsers.
MCStreamer & getStreamer()
Unary assembler expressions.
const MCSymbol * getAddSym() const
int64_t getConstant() const
const MCSymbol * getSubSym() const
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
static const char * getRegisterName(MCRegister Reg, unsigned AltIdx=Mips::NoRegAltName)
void emitRRX(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, MCOperand Op2, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveSetReorder()
void emitRRRX(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, MCRegister Reg2, MCOperand Op3, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRX(unsigned Opcode, MCRegister Reg0, MCOperand Op1, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitR(unsigned Opcode, MCRegister Reg0, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void setUsesMicroMips()
void emitRRI(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, int16_t Imm, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitEmptyDelaySlot(bool hasShortDelaySlot, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRI(unsigned Opcode, MCRegister Reg0, int32_t Imm, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRR(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, SMLoc IDLoc, const MCSubtargetInfo *STI)
void updateABIInfo(const PredicateLibrary &P)
void emitRRIII(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, int16_t Imm0, int16_t Imm1, int16_t Imm2, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitDSLL(MCRegister DstReg, MCRegister SrcReg, int16_t ShiftAmount, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitGPRestore(int Offset, SMLoc IDLoc, const MCSubtargetInfo *STI)
Emit the $gp restore operation for .cprestore.
void emitNop(SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRRR(unsigned Opcode, MCRegister Reg0, MCRegister Reg1, MCRegister Reg2, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void emitDirectiveSetNoReorder()
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
static constexpr StatusTy Failure
constexpr bool isSuccess() const
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
constexpr bool isNoMatch() const
constexpr unsigned id() const
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
void push_back(const T &Elt)
iterator find(StringRef Key)
Represent a constant reference to a string, i.e.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
Check if the string is empty.
LLVM_ABI bool isLittleEndian() const
Tests whether the target triple is little endian.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const AArch64MCOptions & getCLOpts(const MCTargetOptions &Options)
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
LLVM_ABI LLVM_READONLY ARMABI computeTargetABI(const Triple &TT, StringRef ABIName="")
LLVM_ABI bool parseAssignmentExpression(StringRef Name, bool allow_redef, MCAsmParser &Parser, MCSymbol *&Symbol, const MCExpr *&Value)
Parse a value expression and return whether it can be assigned to a symbol with the given name.
constexpr unsigned encodeCOP0Register(unsigned Reg, unsigned Sel)
COP0 hardware encodings reserve five bits each for REG and SEL.
MCRegister getCOP0Register(const MCRegisterInfo &MRI, unsigned Encoding)
MCRegister matchRegisterName(StringRef Name, const MCRegisterInfo &MRI, unsigned RegClassID, unsigned AltIdx)
Match a symbolic name in RegClassID, or return an invalid register.
constexpr unsigned getCOP0RegNum(unsigned Encoding)
int getCPURegisterIndex(StringRef Name, const MCRegisterInfo &MRI, unsigned AltIdx, bool *IsDeprecated=nullptr)
Return a GPR name's hardware index, or -1 if unknown.
constexpr unsigned getCOP0Sel(unsigned Encoding)
constexpr MCPhysReg FP_64
constexpr MCPhysReg GP_64
constexpr MCPhysReg RA_64
constexpr MCPhysReg SP_64
WebAssemblyABI getABI(StringRef Name)
Parse an ABI name into the corresponding enum.
@ CE
Windows NT (Windows on ARM)
LLVM_ABI StringRef getABIName()
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
unsigned getOpcode(const VPValue *V)
Return the instruction opcode for the recipe defining V or 0 for unsupported recipes and VPValues not...
This is an optimization pass for GlobalISel generic memory operations.
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Target & getTheMips64Target()
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
static StringRef getCPU(StringRef CPU)
Processes a CPU name.
int bit_width(T Value)
Returns the number of bits needed to represent Value if Value is nonzero.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
@ Success
The lock was released successfully.
Target & getTheMips64elTarget()
uint64_t offsetToAlignment(uint64_t Value, Align Alignment)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
@ Ref
The access may reference the value stored in memory.
To bit_cast(const From &from) noexcept
Target & getTheMipselTarget()
DWARFExpression::Operation Op
constexpr bool isShiftedInt(int64_t x)
Checks if a signed integer is an N bit number shifted left by S.
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
static uint16_t getSpecifier(const MCSymbolRefExpr *SRE)
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
Target & getTheMipsTarget()
@ End
Run the machine verifier once, at the end of the pipeline.
constexpr bool isShiftedUInt(uint64_t x)
Checks if a unsigned integer is an N bit number shifted left by S.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...