63#define DEBUG_TYPE "mips-asm-parser"
75class MipsAssemblerOptions {
77 MipsAssemblerOptions(
const FeatureBitset &Features_) : Features(Features_) {}
79 MipsAssemblerOptions(
const MipsAssemblerOptions *Opts) {
80 ATReg = Opts->getATRegIndex();
81 Reorder = Opts->isReorder();
82 Macro = Opts->isMacro();
83 Features = Opts->getFeatures();
86 unsigned getATRegIndex()
const {
return ATReg; }
87 bool setATRegIndex(
unsigned Reg) {
95 bool isReorder()
const {
return Reorder; }
96 void setReorder() { Reorder =
true; }
97 void setNoReorder() { Reorder =
false; }
99 bool isMacro()
const {
return Macro; }
100 void setMacro() {
Macro =
true; }
101 void setNoMacro() {
Macro =
false; }
104 void setFeatures(
const FeatureBitset &Features_) { Features = Features_; }
122const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
123 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
124 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
125 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
126 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
127 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
128 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
129 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
130 Mips::FeatureCnMipsP, Mips::FeatureFP64Bit, Mips::FeatureGP64Bit,
139 "do not have a target streamer");
153 bool CurForbiddenSlotAttr;
156 unsigned CpSaveLocation;
158 bool CpSaveLocationIsRegister;
164 void printWarningWithFixIt(
const Twine &Msg,
const Twine &FixMsg,
165 SMRange Range,
bool ShowColors =
true);
169#define GET_ASSEMBLER_HEADER
170#include "MipsGenAsmMatcher.inc"
180 bool MatchingInlineAsm)
override;
185 SMLoc &EndLoc)
override;
191 bool mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID);
214 enum MacroExpanderResultTy {
221 MacroExpanderResultTy tryExpandInstruction(
MCInst &Inst,
SMLoc IDLoc,
228 bool loadImmediate(int64_t ImmValue,
unsigned DstReg,
unsigned SrcReg,
229 bool Is32BitImm,
bool IsAddress,
SMLoc IDLoc,
232 bool loadAndAddSymbolAddress(
const MCExpr *SymExpr,
unsigned DstReg,
233 unsigned SrcReg,
bool Is32BitSym,
SMLoc IDLoc,
238 bool expandLoadImm(
MCInst &Inst,
bool Is32BitImm,
SMLoc IDLoc,
247 bool expandLoadDoubleImmToFPR(
MCInst &Inst,
bool Is64FPU,
SMLoc IDLoc,
250 bool expandLoadAddress(
unsigned DstReg,
unsigned BaseReg,
279 bool expandTrunc(
MCInst &Inst,
bool IsDouble,
bool Is64FPU,
SMLoc IDLoc,
354 bool reportParseError(
const Twine &ErrorMsg);
355 bool reportParseError(
SMLoc Loc,
const Twine &ErrorMsg);
357 bool parseMemOffset(
const MCExpr *&Res,
bool isParenExpr);
359 bool parseSetMips0Directive();
360 bool parseSetArchDirective();
361 bool parseSetFeature(
uint64_t Feature);
362 bool isPicAndNotNxxAbi();
363 bool parseDirectiveCpAdd(
SMLoc Loc);
364 bool parseDirectiveCpLoad(
SMLoc Loc);
365 bool parseDirectiveCpLocal(
SMLoc Loc);
366 bool parseDirectiveCpRestore(
SMLoc Loc);
367 bool parseDirectiveCPSetup();
368 bool parseDirectiveCPReturn();
369 bool parseDirectiveNaN();
370 bool parseDirectiveSet();
371 bool parseDirectiveOption();
372 bool parseInsnDirective();
373 bool parseRSectionDirective(
StringRef Section);
374 bool parseSSectionDirective(
StringRef Section,
unsigned Type);
376 bool parseSetAtDirective();
377 bool parseSetNoAtDirective();
378 bool parseSetMacroDirective();
379 bool parseSetNoMacroDirective();
380 bool parseSetMsaDirective();
381 bool parseSetNoMsaDirective();
382 bool parseSetNoDspDirective();
383 bool parseSetNoMips3DDirective();
384 bool parseSetReorderDirective();
385 bool parseSetNoReorderDirective();
386 bool parseSetMips16Directive();
387 bool parseSetNoMips16Directive();
388 bool parseSetFpDirective();
389 bool parseSetOddSPRegDirective();
390 bool parseSetNoOddSPRegDirective();
391 bool parseSetPopDirective();
392 bool parseSetPushDirective();
393 bool parseSetSoftFloatDirective();
394 bool parseSetHardFloatDirective();
395 bool parseSetMtDirective();
396 bool parseSetNoMtDirective();
397 bool parseSetNoCRCDirective();
398 bool parseSetNoVirtDirective();
399 bool parseSetNoGINVDirective();
401 bool parseSetAssignment();
403 bool parseDirectiveGpWord();
404 bool parseDirectiveGpDWord();
405 bool parseDirectiveDtpRelWord();
406 bool parseDirectiveDtpRelDWord();
407 bool parseDirectiveTpRelWord();
408 bool parseDirectiveTpRelDWord();
409 bool parseDirectiveModule();
410 bool parseDirectiveModuleFP();
414 bool parseInternalDirectiveReallowModule();
418 int matchCPURegisterName(
StringRef Symbol);
420 int matchHWRegsRegisterName(
StringRef Symbol);
432 unsigned getReg(
int RC,
int RegNo);
437 unsigned getATReg(
SMLoc Loc);
447 bool validateMSAIndex(
int Val,
int RegKind);
474 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
482 if (!(
getSTI().hasFeature(Feature))) {
491 if (
getSTI().hasFeature(Feature)) {
500 setFeatureBits(Feature, FeatureString);
501 AssemblerOptions.
front()->setFeatures(
getSTI().getFeatureBits());
505 clearFeatureBits(Feature, FeatureString);
506 AssemblerOptions.
front()->setFeatures(
getSTI().getFeatureBits());
510 enum MipsMatchResultTy {
512 Match_RequiresDifferentOperands,
513 Match_RequiresNoZeroRegister,
514 Match_RequiresSameSrcAndDst,
515 Match_NoFCCRegisterForCurrentISA,
516 Match_NonZeroOperandForSync,
517 Match_NonZeroOperandForMTCX,
518 Match_RequiresPosSizeRange0_32,
519 Match_RequiresPosSizeRange33_64,
520 Match_RequiresPosSizeUImm6,
521#define GET_OPERAND_DIAGNOSTIC_TYPES
522#include "MipsGenAsmMatcher.inc"
523#undef GET_OPERAND_DIAGNOSTIC_TYPES
543 std::make_unique<MipsAssemblerOptions>(
getSTI().getFeatureBits()));
547 std::make_unique<MipsAssemblerOptions>(
getSTI().getFeatureBits()));
549 getTargetStreamer().updateABIInfo(*
this);
551 if (!isABI_O32() && !useOddSPReg() != 0)
556 CurForbiddenSlotAttr =
false;
559 IsCpRestoreSet =
false;
560 CpRestoreOffset = -1;
561 GPReg =
ABI.GetGlobalPtr();
566 if (
getSTI().
getCPU() ==
"mips64r6" && inMicroMipsMode())
569 if (!isABI_O32() && inMicroMipsMode())
574 bool hasEightFccRegisters()
const {
return hasMips4() || hasMips32(); }
576 bool isGP64bit()
const {
580 bool isFP64bit()
const {
584 bool isJalrRelocAvailable(
const MCExpr *JalExpr) {
593 return ABI.IsN32() ||
ABI.IsN64();
598 bool isABI_N32()
const {
return ABI.IsN32(); }
599 bool isABI_N64()
const {
return ABI.IsN64(); }
600 bool isABI_O32()
const {
return ABI.IsO32(); }
601 bool isABI_FPXX()
const {
605 bool useOddSPReg()
const {
609 bool inMicroMipsMode()
const {
613 bool hasMips1()
const {
617 bool hasMips2()
const {
621 bool hasMips3()
const {
625 bool hasMips4()
const {
629 bool hasMips5()
const {
633 bool hasMips32()
const {
637 bool hasMips64()
const {
641 bool hasMips32r2()
const {
645 bool hasMips64r2()
const {
649 bool hasMips32r3()
const {
650 return (
getSTI().hasFeature(Mips::FeatureMips32r3));
653 bool hasMips64r3()
const {
654 return (
getSTI().hasFeature(Mips::FeatureMips64r3));
657 bool hasMips32r5()
const {
658 return (
getSTI().hasFeature(Mips::FeatureMips32r5));
661 bool hasMips64r5()
const {
662 return (
getSTI().hasFeature(Mips::FeatureMips64r5));
665 bool hasMips32r6()
const {
669 bool hasMips64r6()
const {
673 bool hasDSP()
const {
677 bool hasDSPR2()
const {
681 bool hasDSPR3()
const {
685 bool hasMSA()
const {
689 bool hasCnMips()
const {
690 return (
getSTI().hasFeature(Mips::FeatureCnMips));
693 bool hasCnMipsP()
const {
694 return (
getSTI().hasFeature(Mips::FeatureCnMipsP));
701 bool inMips16Mode()
const {
705 bool useTraps()
const {
709 bool useSoftFloat()
const {
716 bool hasCRC()
const {
720 bool hasVirt()
const {
724 bool hasGINV()
const {
728 bool hasForbiddenSlot(
const MCInstrDesc &MCID)
const {
732 bool SafeInForbiddenSlot(
const MCInstrDesc &MCID)
const {
739 void warnIfRegIndexIsAT(
unsigned RegIndex,
SMLoc Loc);
741 void warnIfNoMacro(
SMLoc Loc);
743 bool isLittle()
const {
return IsLittleEndian; }
748 switch(OperatorToken) {
819 RegKind_MSACtrl = 16,
824 RegKind_HWRegs = 256,
828 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
829 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
830 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
843 MipsOperand(KindTy K, MipsAsmParser &Parser) :
Kind(
K), AsmParser(Parser) {}
845 ~MipsOperand()
override {
854 case k_RegisterIndex:
862 MipsAsmParser &AsmParser;
891 struct RegIdxOp RegIdx;
894 struct RegListOp RegList;
897 SMLoc StartLoc, EndLoc;
900 static std::unique_ptr<MipsOperand> CreateReg(
unsigned Index,
StringRef Str,
904 MipsAsmParser &Parser) {
905 auto Op = std::make_unique<MipsOperand>(k_RegisterIndex, Parser);
908 Op->RegIdx.Kind = RegKind;
909 Op->RegIdx.Tok.Data = Str.data();
910 Op->RegIdx.Tok.Length = Str.size();
919 unsigned getGPR32Reg()
const {
920 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
921 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
922 unsigned ClassID = Mips::GPR32RegClassID;
923 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
928 unsigned getGPRMM16Reg()
const {
929 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
930 unsigned ClassID = Mips::GPR32RegClassID;
931 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
936 unsigned getGPR64Reg()
const {
937 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) &&
"Invalid access!");
938 unsigned ClassID = Mips::GPR64RegClassID;
939 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
945 unsigned getAFGR64Reg()
const {
946 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
947 if (RegIdx.Index % 2 != 0)
948 AsmParser.Warning(StartLoc,
"Float register should be even.");
949 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
950 .getRegister(RegIdx.Index / 2);
955 unsigned getFGR64Reg()
const {
956 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
957 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
958 .getRegister(RegIdx.Index);
963 unsigned getFGR32Reg()
const {
964 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) &&
"Invalid access!");
965 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
966 .getRegister(RegIdx.Index);
971 unsigned getFCCReg()
const {
972 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) &&
"Invalid access!");
973 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
974 .getRegister(RegIdx.Index);
979 unsigned getMSA128Reg()
const {
980 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) &&
"Invalid access!");
983 unsigned ClassID = Mips::MSA128BRegClassID;
984 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
989 unsigned getMSACtrlReg()
const {
990 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) &&
"Invalid access!");
991 unsigned ClassID = Mips::MSACtrlRegClassID;
992 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
997 unsigned getCOP0Reg()
const {
998 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) &&
"Invalid access!");
999 unsigned ClassID = Mips::COP0RegClassID;
1000 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1005 unsigned getCOP2Reg()
const {
1006 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) &&
"Invalid access!");
1007 unsigned ClassID = Mips::COP2RegClassID;
1008 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1013 unsigned getCOP3Reg()
const {
1014 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) &&
"Invalid access!");
1015 unsigned ClassID = Mips::COP3RegClassID;
1016 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1021 unsigned getACC64DSPReg()
const {
1022 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
1023 unsigned ClassID = Mips::ACC64DSPRegClassID;
1024 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1029 unsigned getHI32DSPReg()
const {
1030 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
1031 unsigned ClassID = Mips::HI32DSPRegClassID;
1032 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1037 unsigned getLO32DSPReg()
const {
1038 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) &&
"Invalid access!");
1039 unsigned ClassID = Mips::LO32DSPRegClassID;
1040 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1045 unsigned getCCRReg()
const {
1046 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) &&
"Invalid access!");
1047 unsigned ClassID = Mips::CCRRegClassID;
1048 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1053 unsigned getHWRegsReg()
const {
1054 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) &&
"Invalid access!");
1055 unsigned ClassID = Mips::HWRegsRegClassID;
1056 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1064 else if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
1070 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
1077 void addGPR32ZeroAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1078 assert(
N == 1 &&
"Invalid number of operands!");
1082 void addGPR32NonZeroAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1083 assert(
N == 1 &&
"Invalid number of operands!");
1087 void addGPR32AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1088 assert(
N == 1 &&
"Invalid number of operands!");
1092 void addGPRMM16AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1093 assert(
N == 1 &&
"Invalid number of operands!");
1097 void addGPRMM16AsmRegZeroOperands(
MCInst &Inst,
unsigned N)
const {
1098 assert(
N == 1 &&
"Invalid number of operands!");
1102 void addGPRMM16AsmRegMovePOperands(
MCInst &Inst,
unsigned N)
const {
1103 assert(
N == 1 &&
"Invalid number of operands!");
1107 void addGPRMM16AsmRegMovePPairFirstOperands(
MCInst &Inst,
unsigned N)
const {
1108 assert(
N == 1 &&
"Invalid number of operands!");
1112 void addGPRMM16AsmRegMovePPairSecondOperands(
MCInst &Inst,
1114 assert(
N == 1 &&
"Invalid number of operands!");
1121 void addGPR64AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1122 assert(
N == 1 &&
"Invalid number of operands!");
1126 void addAFGR64AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1127 assert(
N == 1 &&
"Invalid number of operands!");
1131 void addStrictlyAFGR64AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1132 assert(
N == 1 &&
"Invalid number of operands!");
1136 void addStrictlyFGR64AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1137 assert(
N == 1 &&
"Invalid number of operands!");
1141 void addFGR64AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1142 assert(
N == 1 &&
"Invalid number of operands!");
1146 void addFGR32AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1147 assert(
N == 1 &&
"Invalid number of operands!");
1151 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1152 AsmParser.getParser().printError(
1153 StartLoc,
"-mno-odd-spreg prohibits the use of odd FPU "
1157 void addStrictlyFGR32AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1158 assert(
N == 1 &&
"Invalid number of operands!");
1161 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1162 AsmParser.Error(StartLoc,
"-mno-odd-spreg prohibits the use of odd FPU "
1166 void addFCCAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1167 assert(
N == 1 &&
"Invalid number of operands!");
1171 void addMSA128AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1172 assert(
N == 1 &&
"Invalid number of operands!");
1176 void addMSACtrlAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1177 assert(
N == 1 &&
"Invalid number of operands!");
1181 void addCOP0AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1182 assert(
N == 1 &&
"Invalid number of operands!");
1186 void addCOP2AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1187 assert(
N == 1 &&
"Invalid number of operands!");
1191 void addCOP3AsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1192 assert(
N == 1 &&
"Invalid number of operands!");
1196 void addACC64DSPAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1197 assert(
N == 1 &&
"Invalid number of operands!");
1201 void addHI32DSPAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1202 assert(
N == 1 &&
"Invalid number of operands!");
1206 void addLO32DSPAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1207 assert(
N == 1 &&
"Invalid number of operands!");
1211 void addCCRAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1212 assert(
N == 1 &&
"Invalid number of operands!");
1216 void addHWRegsAsmRegOperands(
MCInst &Inst,
unsigned N)
const {
1217 assert(
N == 1 &&
"Invalid number of operands!");
1221 template <
unsigned Bits,
int Offset = 0,
int AdjustOffset = 0>
1222 void addConstantUImmOperands(
MCInst &Inst,
unsigned N)
const {
1223 assert(
N == 1 &&
"Invalid number of operands!");
1227 Imm += AdjustOffset;
1231 template <
unsigned Bits>
1232 void addSImmOperands(
MCInst &Inst,
unsigned N)
const {
1233 if (
isImm() && !isConstantImm()) {
1234 addExpr(Inst, getImm());
1237 addConstantSImmOperands<Bits, 0, 0>(Inst,
N);
1240 template <
unsigned Bits>
1241 void addUImmOperands(
MCInst &Inst,
unsigned N)
const {
1242 if (
isImm() && !isConstantImm()) {
1243 addExpr(Inst, getImm());
1246 addConstantUImmOperands<Bits, 0, 0>(Inst,
N);
1249 template <
unsigned Bits,
int Offset = 0,
int AdjustOffset = 0>
1250 void addConstantSImmOperands(
MCInst &Inst,
unsigned N)
const {
1251 assert(
N == 1 &&
"Invalid number of operands!");
1252 int64_t
Imm = getConstantImm() -
Offset;
1253 Imm = SignExtend64<Bits>(Imm);
1255 Imm += AdjustOffset;
1259 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
1260 assert(
N == 1 &&
"Invalid number of operands!");
1261 const MCExpr *Expr = getImm();
1262 addExpr(Inst, Expr);
1265 void addMemOperands(
MCInst &Inst,
unsigned N)
const {
1266 assert(
N == 2 &&
"Invalid number of operands!");
1269 ? getMemBase()->getGPR64Reg()
1270 : getMemBase()->getGPR32Reg()));
1272 const MCExpr *Expr = getMemOff();
1273 addExpr(Inst, Expr);
1276 void addMicroMipsMemOperands(
MCInst &Inst,
unsigned N)
const {
1277 assert(
N == 2 &&
"Invalid number of operands!");
1281 const MCExpr *Expr = getMemOff();
1282 addExpr(Inst, Expr);
1285 void addRegListOperands(
MCInst &Inst,
unsigned N)
const {
1286 assert(
N == 1 &&
"Invalid number of operands!");
1288 for (
auto RegNo : getRegList())
1292 bool isReg()
const override {
1295 return isGPRAsmReg() && RegIdx.Index == 0;
1298 bool isRegIdx()
const {
return Kind == k_RegisterIndex; }
1299 bool isImm()
const override {
return Kind == k_Immediate; }
1301 bool isConstantImm()
const {
1303 return isImm() && getImm()->evaluateAsAbsolute(Res);
1306 bool isConstantImmz()
const {
1307 return isConstantImm() && getConstantImm() == 0;
1310 template <
unsigned Bits,
int Offset = 0>
bool isConstantUImm()
const {
1311 return isConstantImm() && isUInt<Bits>(getConstantImm() -
Offset);
1314 template <
unsigned Bits>
bool isSImm()
const {
1315 return isConstantImm() ? isInt<Bits>(getConstantImm()) :
isImm();
1318 template <
unsigned Bits>
bool isUImm()
const {
1319 return isConstantImm() ? isUInt<Bits>(getConstantImm()) :
isImm();
1322 template <
unsigned Bits>
bool isAnyImm()
const {
1323 return isConstantImm() ? (isInt<Bits>(getConstantImm()) ||
1324 isUInt<Bits>(getConstantImm()))
1328 template <
unsigned Bits,
int Offset = 0>
bool isConstantSImm()
const {
1329 return isConstantImm() && isInt<Bits>(getConstantImm() -
Offset);
1332 template <
unsigned Bottom,
unsigned Top>
bool isConstantUImmRange()
const {
1333 return isConstantImm() && getConstantImm() >= Bottom &&
1334 getConstantImm() <= Top;
1337 bool isToken()
const override {
1340 return Kind == k_Token;
1343 bool isMem()
const override {
return Kind == k_Memory; }
1345 bool isConstantMemOff()
const {
1346 return isMem() && isa<MCConstantExpr>(getMemOff());
1350 template <
unsigned Bits,
unsigned ShiftAmount = 0>
1351 bool isMemWithSimmOffset()
const {
1354 if (!getMemBase()->isGPRAsmReg())
1356 if (isa<MCTargetExpr>(getMemOff()) ||
1357 (isConstantMemOff() &&
1358 isShiftedInt<Bits, ShiftAmount>(getConstantMemOff())))
1361 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res,
nullptr,
nullptr);
1362 return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.
getConstant());
1365 bool isMemWithPtrSizeOffset()
const {
1368 if (!getMemBase()->isGPRAsmReg())
1370 const unsigned PtrBits = AsmParser.getABI().ArePtrs64bit() ? 64 : 32;
1371 if (isa<MCTargetExpr>(getMemOff()) ||
1372 (isConstantMemOff() &&
isIntN(PtrBits, getConstantMemOff())))
1375 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res,
nullptr,
nullptr);
1379 bool isMemWithGRPMM16Base()
const {
1380 return isMem() && getMemBase()->isMM16AsmReg();
1383 template <
unsigned Bits>
bool isMemWithUimmOffsetSP()
const {
1384 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1385 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1388 template <
unsigned Bits>
bool isMemWithUimmWordAlignedOffsetSP()
const {
1389 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1390 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1391 && (getMemBase()->getGPR32Reg() == Mips::SP);
1394 template <
unsigned Bits>
bool isMemWithSimmWordAlignedOffsetGP()
const {
1395 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
1396 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1397 && (getMemBase()->getGPR32Reg() == Mips::GP);
1400 template <
unsigned Bits,
unsigned ShiftLeftAmount>
1401 bool isScaledUImm()
const {
1402 return isConstantImm() &&
1403 isShiftedUInt<Bits, ShiftLeftAmount>(getConstantImm());
1406 template <
unsigned Bits,
unsigned ShiftLeftAmount>
1407 bool isScaledSImm()
const {
1408 if (isConstantImm() &&
1409 isShiftedInt<Bits, ShiftLeftAmount>(getConstantImm()))
1413 if (Kind != k_Immediate)
1416 bool Success = getImm()->evaluateAsRelocatable(Res,
nullptr,
nullptr);
1420 bool isRegList16()
const {
1424 int Size = RegList.List->size();
1425 if (Size < 2 || Size > 5)
1428 unsigned R0 = RegList.List->front();
1429 unsigned R1 = RegList.List->back();
1430 if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1431 (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1434 int PrevReg = *RegList.List->begin();
1435 for (
int i = 1; i <
Size - 1; i++) {
1436 int Reg = (*(RegList.List))[i];
1437 if (
Reg != PrevReg + 1)
1445 bool isInvNum()
const {
return Kind == k_Immediate; }
1447 bool isLSAImm()
const {
1448 if (!isConstantImm())
1450 int64_t Val = getConstantImm();
1451 return 1 <= Val && Val <= 4;
1454 bool isRegList()
const {
return Kind == k_RegList; }
1457 assert(Kind == k_Token &&
"Invalid access!");
1461 unsigned getReg()
const override {
1464 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1465 RegIdx.Kind & RegKind_GPR)
1466 return getGPR32Reg();
1472 const MCExpr *getImm()
const {
1473 assert((Kind == k_Immediate) &&
"Invalid access!");
1477 int64_t getConstantImm()
const {
1478 const MCExpr *Val = getImm();
1480 (void)Val->evaluateAsAbsolute(
Value);
1484 MipsOperand *getMemBase()
const {
1485 assert((Kind == k_Memory) &&
"Invalid access!");
1489 const MCExpr *getMemOff()
const {
1490 assert((Kind == k_Memory) &&
"Invalid access!");
1494 int64_t getConstantMemOff()
const {
1495 return static_cast<const MCConstantExpr *
>(getMemOff())->getValue();
1499 assert((Kind == k_RegList) &&
"Invalid access!");
1500 return *(RegList.List);
1503 static std::unique_ptr<MipsOperand> CreateToken(
StringRef Str,
SMLoc S,
1504 MipsAsmParser &Parser) {
1505 auto Op = std::make_unique<MipsOperand>(k_Token, Parser);
1506 Op->Tok.Data = Str.data();
1507 Op->Tok.Length = Str.size();
1515 static std::unique_ptr<MipsOperand>
1519 return CreateReg(
Index, Str, RegKind_Numeric,
RegInfo, S,
E, Parser);
1524 static std::unique_ptr<MipsOperand>
1527 return CreateReg(
Index, Str, RegKind_GPR,
RegInfo, S,
E, Parser);
1532 static std::unique_ptr<MipsOperand>
1535 return CreateReg(
Index, Str, RegKind_FGR,
RegInfo, S,
E, Parser);
1540 static std::unique_ptr<MipsOperand>
1543 return CreateReg(
Index, Str, RegKind_HWRegs,
RegInfo, S,
E, Parser);
1548 static std::unique_ptr<MipsOperand>
1551 return CreateReg(
Index, Str, RegKind_FCC,
RegInfo, S,
E, Parser);
1556 static std::unique_ptr<MipsOperand>
1559 return CreateReg(
Index, Str, RegKind_ACC,
RegInfo, S,
E, Parser);
1564 static std::unique_ptr<MipsOperand>
1567 return CreateReg(
Index, Str, RegKind_MSA128,
RegInfo, S,
E, Parser);
1572 static std::unique_ptr<MipsOperand>
1575 return CreateReg(
Index, Str, RegKind_MSACtrl,
RegInfo, S,
E, Parser);
1578 static std::unique_ptr<MipsOperand>
1580 auto Op = std::make_unique<MipsOperand>(k_Immediate, Parser);
1587 static std::unique_ptr<MipsOperand>
1588 CreateMem(std::unique_ptr<MipsOperand>
Base,
const MCExpr *Off,
SMLoc S,
1589 SMLoc E, MipsAsmParser &Parser) {
1590 auto Op = std::make_unique<MipsOperand>(k_Memory, Parser);
1591 Op->Mem.Base =
Base.release();
1598 static std::unique_ptr<MipsOperand>
1600 MipsAsmParser &Parser) {
1601 assert(Regs.
size() > 0 &&
"Empty list not allowed");
1603 auto Op = std::make_unique<MipsOperand>(k_RegList, Parser);
1605 Op->StartLoc = StartLoc;
1606 Op->EndLoc = EndLoc;
1610 bool isGPRZeroAsmReg()
const {
1611 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
1614 bool isGPRNonZeroAsmReg()
const {
1615 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index > 0 &&
1619 bool isGPRAsmReg()
const {
1620 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1623 bool isMM16AsmReg()
const {
1624 if (!(isRegIdx() && RegIdx.Kind))
1626 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1627 || RegIdx.Index == 16 || RegIdx.Index == 17);
1630 bool isMM16AsmRegZero()
const {
1631 if (!(isRegIdx() && RegIdx.Kind))
1633 return (RegIdx.Index == 0 ||
1634 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1635 RegIdx.Index == 17);
1638 bool isMM16AsmRegMoveP()
const {
1639 if (!(isRegIdx() && RegIdx.Kind))
1641 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1642 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1645 bool isMM16AsmRegMovePPairFirst()
const {
1646 if (!(isRegIdx() && RegIdx.Kind))
1648 return RegIdx.Index >= 4 && RegIdx.Index <= 6;
1651 bool isMM16AsmRegMovePPairSecond()
const {
1652 if (!(isRegIdx() && RegIdx.Kind))
1654 return (RegIdx.Index == 21 || RegIdx.Index == 22 ||
1655 (RegIdx.Index >= 5 && RegIdx.Index <= 7));
1658 bool isFGRAsmReg()
const {
1660 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1663 bool isStrictlyFGRAsmReg()
const {
1665 return isRegIdx() && RegIdx.Kind == RegKind_FGR && RegIdx.Index <= 31;
1668 bool isHWRegsAsmReg()
const {
1669 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1672 bool isCCRAsmReg()
const {
1673 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1676 bool isFCCAsmReg()
const {
1677 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1679 return RegIdx.Index <= 7;
1682 bool isACCAsmReg()
const {
1683 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1686 bool isCOP0AsmReg()
const {
1687 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1690 bool isCOP2AsmReg()
const {
1691 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1694 bool isCOP3AsmReg()
const {
1695 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1698 bool isMSA128AsmReg()
const {
1699 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1702 bool isMSACtrlAsmReg()
const {
1703 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1707 SMLoc getStartLoc()
const override {
return StartLoc; }
1709 SMLoc getEndLoc()
const override {
return EndLoc; }
1720 Mem.Base->print(
OS);
1725 case k_RegisterIndex:
1726 OS <<
"RegIdx<" << RegIdx.Index <<
":" << RegIdx.Kind <<
", "
1727 <<
StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) <<
">";
1734 for (
auto Reg : (*RegList.List))
1741 bool isValidForTie(
const MipsOperand &
Other)
const {
1742 if (Kind !=
Other.Kind)
1749 case k_RegisterIndex: {
1750 StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length);
1752 return Token == OtherToken;
1768 case Mips::JRC16_MM:
1770 case Mips::JALRS_MM:
1771 case Mips::JALRS16_MM:
1772 case Mips::BGEZALS_MM:
1773 case Mips::BLTZALS_MM:
1783 if (
const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1784 return &SRExpr->getSymbol();
1787 if (
const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1800 if (
const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1807 if (isa<MCSymbolRefExpr>(Expr))
1810 if (
const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1814 if (
const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1833 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1842 if (NumOp != 3 && NumOp != 4)
1854 return !isInt<9>(
Op.getImm());
1856 return !isInt<16>(
Op.getImm());
1872bool MipsAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
1876 const unsigned Opcode = Inst.
getOpcode();
1878 bool ExpandedJalSym =
false;
1892 assert(hasCnMips() &&
"instruction only valid for octeon cpus");
1903 if (!
isIntN(inMicroMipsMode() ? 17 : 18,
Offset.getImm()))
1904 return Error(IDLoc,
"branch target out of range");
1907 return Error(IDLoc,
"branch to misaligned address");
1921 case Mips::BGEZAL_MM:
1922 case Mips::BLTZAL_MM:
1925 case Mips::BC1EQZC_MMR6:
1926 case Mips::BC1NEZC_MMR6:
1927 case Mips::BC2EQZC_MMR6:
1928 case Mips::BC2NEZC_MMR6:
1933 if (!
isIntN(inMicroMipsMode() ? 17 : 18,
Offset.getImm()))
1934 return Error(IDLoc,
"branch target out of range");
1937 return Error(IDLoc,
"branch to misaligned address");
1939 case Mips::BGEC:
case Mips::BGEC_MMR6:
1940 case Mips::BLTC:
case Mips::BLTC_MMR6:
1941 case Mips::BGEUC:
case Mips::BGEUC_MMR6:
1942 case Mips::BLTUC:
case Mips::BLTUC_MMR6:
1943 case Mips::BEQC:
case Mips::BEQC_MMR6:
1944 case Mips::BNEC:
case Mips::BNEC_MMR6:
1950 return Error(IDLoc,
"branch target out of range");
1952 return Error(IDLoc,
"branch to misaligned address");
1954 case Mips::BLEZC:
case Mips::BLEZC_MMR6:
1955 case Mips::BGEZC:
case Mips::BGEZC_MMR6:
1956 case Mips::BGTZC:
case Mips::BGTZC_MMR6:
1957 case Mips::BLTZC:
case Mips::BLTZC_MMR6:
1963 return Error(IDLoc,
"branch target out of range");
1965 return Error(IDLoc,
"branch to misaligned address");
1967 case Mips::BEQZC:
case Mips::BEQZC_MMR6:
1968 case Mips::BNEZC:
case Mips::BNEZC_MMR6:
1974 return Error(IDLoc,
"branch target out of range");
1976 return Error(IDLoc,
"branch to misaligned address");
1978 case Mips::BEQZ16_MM:
1979 case Mips::BEQZC16_MMR6:
1980 case Mips::BNEZ16_MM:
1981 case Mips::BNEZC16_MMR6:
1986 if (!isInt<8>(
Offset.getImm()))
1987 return Error(IDLoc,
"branch target out of range");
1989 return Error(IDLoc,
"branch to misaligned address");
1996 if (hasMips32r6() && Opcode == Mips::SSNOP) {
1997 std::string
ISA = hasMips64r6() ?
"MIPS64r6" :
"MIPS32r6";
1998 Warning(IDLoc,
"ssnop is deprecated for " + ISA +
" and is equivalent to a "
2018 return Error(IDLoc,
"expected immediate operand kind");
2020 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
2021 Opcode == Mips::BBIT1 ? 63 : 31))
2022 return Error(IDLoc,
"immediate operand value out of range");
2024 Inst.
setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
2035 return Error(IDLoc,
"expected immediate operand kind");
2037 if (!isInt<10>(Imm))
2038 return Error(IDLoc,
"immediate operand value out of range");
2050 unsigned FirstOp = 1;
2051 unsigned SecondOp = 2;
2055 case Mips::SDivIMacro:
2056 case Mips::UDivIMacro:
2057 case Mips::DSDivIMacro:
2058 case Mips::DUDivIMacro:
2062 Warning(IDLoc,
"dividing zero by zero");
2064 Warning(IDLoc,
"division by zero");
2076 case Mips::SDivMacro:
2077 case Mips::DSDivMacro:
2078 case Mips::UDivMacro:
2079 case Mips::DUDivMacro:
2084 case Mips::DIVU_MMR6:
2085 case Mips::DIV_MMR6:
2090 Warning(IDLoc,
"dividing zero by zero");
2092 Warning(IDLoc,
"division by zero");
2098 if ((Opcode == Mips::J || Opcode == Mips::J_MM) && inPicMode()) {
2100 BInst.
setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
2109 if ((Opcode == Mips::JAL || Opcode == Mips::JAL_MM) && inPicMode()) {
2110 warnIfNoMacro(IDLoc);
2117 return Error(IDLoc,
"jal doesn't support multiple symbols in PIC mode");
2123 if (expandLoadAddress(Mips::T9, Mips::NoRegister, Inst.
getOperand(0),
2124 !isGP64bit(), IDLoc, Out, STI))
2128 if (inMicroMipsMode())
2129 JalrInst.
setOpcode(IsCpRestoreSet ? Mips::JALRS_MM : Mips::JALR_MM);
2135 if (isJalrRelocAvailable(JalExpr)) {
2139 MCSymbol *TmpLabel = getContext().createTempSymbol();
2141 const MCExpr *RelocJalrExpr =
2143 getContext(), IDLoc);
2146 *TmpExpr, inMicroMipsMode() ?
"R_MICROMIPS_JALR" :
"R_MIPS_JALR",
2147 RelocJalrExpr, IDLoc, *STI);
2152 ExpandedJalSym =
true;
2161 expandMem9Inst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2164 expandMem16Inst(Inst, IDLoc, Out, STI, MCID.
mayLoad());
2167 return getParser().hasPendingError();
2171 if (inMicroMipsMode()) {
2172 if (MCID.
mayLoad() && Opcode != Mips::LWP_MM) {
2180 int MemOffset =
Op.getImm();
2183 if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
2186 (BaseReg.
getReg() == Mips::GP ||
2187 BaseReg.
getReg() == Mips::GP_64)) {
2189 TOut.
emitRRI(Mips::LWGP_MM, DstReg.
getReg(), Mips::GP, MemOffset,
2206 case Mips::ADDIUSP_MM:
2209 return Error(IDLoc,
"expected immediate operand kind");
2211 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
2213 return Error(IDLoc,
"immediate operand value out of range");
2215 case Mips::SLL16_MM:
2216 case Mips::SRL16_MM:
2219 return Error(IDLoc,
"expected immediate operand kind");
2221 if (Imm < 1 || Imm > 8)
2222 return Error(IDLoc,
"immediate operand value out of range");
2227 return Error(IDLoc,
"expected immediate operand kind");
2229 if (Imm < -1 || Imm > 126)
2230 return Error(IDLoc,
"immediate operand value out of range");
2232 case Mips::ADDIUR2_MM:
2235 return Error(IDLoc,
"expected immediate operand kind");
2237 if (!(Imm == 1 || Imm == -1 ||
2238 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
2239 return Error(IDLoc,
"immediate operand value out of range");
2241 case Mips::ANDI16_MM:
2244 return Error(IDLoc,
"expected immediate operand kind");
2246 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
2247 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
2248 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
2249 return Error(IDLoc,
"immediate operand value out of range");
2251 case Mips::LBU16_MM:
2254 return Error(IDLoc,
"expected immediate operand kind");
2256 if (Imm < -1 || Imm > 14)
2257 return Error(IDLoc,
"immediate operand value out of range");
2260 case Mips::SB16_MMR6:
2263 return Error(IDLoc,
"expected immediate operand kind");
2265 if (Imm < 0 || Imm > 15)
2266 return Error(IDLoc,
"immediate operand value out of range");
2268 case Mips::LHU16_MM:
2270 case Mips::SH16_MMR6:
2273 return Error(IDLoc,
"expected immediate operand kind");
2275 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
2276 return Error(IDLoc,
"immediate operand value out of range");
2280 case Mips::SW16_MMR6:
2283 return Error(IDLoc,
"expected immediate operand kind");
2285 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
2286 return Error(IDLoc,
"immediate operand value out of range");
2288 case Mips::ADDIUPC_MM:
2291 return Error(IDLoc,
"expected immediate operand kind");
2293 if ((Imm % 4 != 0) || !isInt<25>(Imm))
2294 return Error(IDLoc,
"immediate operand value out of range");
2299 return Error(IDLoc,
"invalid operand for instruction");
2301 case Mips::MOVEP_MM:
2302 case Mips::MOVEP_MMR6: {
2305 bool RegPair = ((R0 == Mips::A1 && R1 == Mips::A2) ||
2306 (R0 == Mips::A1 && R1 == Mips::A3) ||
2307 (R0 == Mips::A2 && R1 == Mips::A3) ||
2308 (R0 == Mips::A0 && R1 == Mips::S5) ||
2309 (R0 == Mips::A0 && R1 == Mips::S6) ||
2310 (R0 == Mips::A0 && R1 == Mips::A1) ||
2311 (R0 == Mips::A0 && R1 == Mips::A2) ||
2312 (R0 == Mips::A0 && R1 == Mips::A3));
2314 return Error(IDLoc,
"invalid operand for instruction");
2320 bool FillDelaySlot =
2325 bool PrevForbiddenSlotAttr = CurForbiddenSlotAttr;
2328 bool SetReorderAfterNop =
false;
2333 if (PrevForbiddenSlotAttr && !SafeInForbiddenSlot(MCID)) {
2343 if (AssemblerOptions.
back()->isReorder() && !FillDelaySlot) {
2344 SetReorderAfterNop =
true;
2353 CurForbiddenSlotAttr =
2354 hasForbiddenSlot(MCID) && AssemblerOptions.
back()->isReorder();
2356 if (FillDelaySlot || CurForbiddenSlotAttr)
2359 MacroExpanderResultTy ExpandResult =
2360 tryExpandInstruction(Inst, IDLoc, Out, STI);
2361 switch (ExpandResult) {
2377 if (PrevForbiddenSlotAttr && !SetReorderAfterNop && !FillDelaySlot &&
2378 AssemblerOptions.
back()->isReorder()) {
2384 if (inMicroMipsMode()) {
2399 if (FillDelaySlot) {
2404 if ((Opcode == Mips::JalOneReg || Opcode == Mips::JalTwoReg ||
2406 isPicAndNotNxxAbi()) {
2407 if (IsCpRestoreSet) {
2411 if (!AssemblerOptions.
back()->isReorder())
2418 Warning(IDLoc,
"no .cprestore used in PIC mode");
2424void MipsAsmParser::onEndOfFile() {
2428 if (CurForbiddenSlotAttr) {
2430 if (AssemblerOptions.
back()->isReorder())
2435MipsAsmParser::MacroExpanderResultTy
2440 return MER_NotAMacro;
2441 case Mips::LoadImm32:
2442 return expandLoadImm(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2443 case Mips::LoadImm64:
2444 return expandLoadImm(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2445 case Mips::LoadAddrImm32:
2446 case Mips::LoadAddrImm64:
2449 "expected immediate operand kind");
2453 Inst.
getOpcode() == Mips::LoadAddrImm32, IDLoc,
2457 case Mips::LoadAddrReg32:
2458 case Mips::LoadAddrReg64:
2462 "expected immediate operand kind");
2466 Inst.
getOpcode() == Mips::LoadAddrReg32, IDLoc,
2470 case Mips::B_MM_Pseudo:
2471 case Mips::B_MMR6_Pseudo:
2472 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2476 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2478 case Mips::JalOneReg:
2479 case Mips::JalTwoReg:
2480 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2483 case Mips::BEQLImmMacro:
2484 case Mips::BNELImmMacro:
2485 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2502 case Mips::BLTImmMacro:
2503 case Mips::BLEImmMacro:
2504 case Mips::BGEImmMacro:
2505 case Mips::BGTImmMacro:
2506 case Mips::BLTUImmMacro:
2507 case Mips::BLEUImmMacro:
2508 case Mips::BGEUImmMacro:
2509 case Mips::BGTUImmMacro:
2510 case Mips::BLTLImmMacro:
2511 case Mips::BLELImmMacro:
2512 case Mips::BGELImmMacro:
2513 case Mips::BGTLImmMacro:
2514 case Mips::BLTULImmMacro:
2515 case Mips::BLEULImmMacro:
2516 case Mips::BGEULImmMacro:
2517 case Mips::BGTULImmMacro:
2518 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2519 case Mips::SDivMacro:
2520 case Mips::SDivIMacro:
2521 case Mips::SRemMacro:
2522 case Mips::SRemIMacro:
2523 return expandDivRem(Inst, IDLoc, Out, STI,
false,
true) ? MER_Fail
2525 case Mips::DSDivMacro:
2526 case Mips::DSDivIMacro:
2527 case Mips::DSRemMacro:
2528 case Mips::DSRemIMacro:
2529 return expandDivRem(Inst, IDLoc, Out, STI,
true,
true) ? MER_Fail
2531 case Mips::UDivMacro:
2532 case Mips::UDivIMacro:
2533 case Mips::URemMacro:
2534 case Mips::URemIMacro:
2535 return expandDivRem(Inst, IDLoc, Out, STI,
false,
false) ? MER_Fail
2537 case Mips::DUDivMacro:
2538 case Mips::DUDivIMacro:
2539 case Mips::DURemMacro:
2540 case Mips::DURemIMacro:
2541 return expandDivRem(Inst, IDLoc, Out, STI,
true,
false) ? MER_Fail
2543 case Mips::PseudoTRUNC_W_S:
2544 return expandTrunc(Inst,
false,
false, IDLoc, Out, STI) ? MER_Fail
2546 case Mips::PseudoTRUNC_W_D32:
2547 return expandTrunc(Inst,
true,
false, IDLoc, Out, STI) ? MER_Fail
2549 case Mips::PseudoTRUNC_W_D:
2550 return expandTrunc(Inst,
true,
true, IDLoc, Out, STI) ? MER_Fail
2553 case Mips::LoadImmSingleGPR:
2554 return expandLoadSingleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2556 case Mips::LoadImmSingleFGR:
2557 return expandLoadSingleImmToFPR(Inst, IDLoc, Out, STI) ? MER_Fail
2559 case Mips::LoadImmDoubleGPR:
2560 return expandLoadDoubleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2562 case Mips::LoadImmDoubleFGR:
2563 return expandLoadDoubleImmToFPR(Inst,
true, IDLoc, Out, STI) ? MER_Fail
2565 case Mips::LoadImmDoubleFGR_32:
2566 return expandLoadDoubleImmToFPR(Inst,
false, IDLoc, Out, STI) ? MER_Fail
2570 return expandUlh(Inst,
true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2572 return expandUlh(Inst,
false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2574 return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2577 return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2579 case Mips::NORImm64:
2580 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2583 return expandSge(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2586 case Mips::SGEImm64:
2587 case Mips::SGEUImm64:
2588 return expandSgeImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2591 case Mips::SGTImm64:
2592 case Mips::SGTUImm64:
2593 return expandSgtImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2596 return expandSle(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2599 case Mips::SLEImm64:
2600 case Mips::SLEUImm64:
2601 return expandSleImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2602 case Mips::SLTImm64:
2605 return MER_NotAMacro;
2607 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2608 case Mips::SLTUImm64:
2611 return MER_NotAMacro;
2613 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2614 case Mips::ADDi:
case Mips::ADDi_MM:
2615 case Mips::ADDiu:
case Mips::ADDiu_MM:
2616 case Mips::SLTi:
case Mips::SLTi_MM:
2617 case Mips::SLTiu:
case Mips::SLTiu_MM:
2621 if (isInt<16>(ImmValue))
2622 return MER_NotAMacro;
2623 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2626 return MER_NotAMacro;
2627 case Mips::ANDi:
case Mips::ANDi_MM:
case Mips::ANDi64:
2628 case Mips::ORi:
case Mips::ORi_MM:
case Mips::ORi64:
2629 case Mips::XORi:
case Mips::XORi_MM:
case Mips::XORi64:
2633 if (isUInt<16>(ImmValue))
2634 return MER_NotAMacro;
2635 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2638 return MER_NotAMacro;
2641 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2644 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2647 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2650 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2651 case Mips::ABSMacro:
2652 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2653 case Mips::MULImmMacro:
2654 case Mips::DMULImmMacro:
2655 return expandMulImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2656 case Mips::MULOMacro:
2657 case Mips::DMULOMacro:
2658 return expandMulO(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2659 case Mips::MULOUMacro:
2660 case Mips::DMULOUMacro:
2661 return expandMulOU(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2662 case Mips::DMULMacro:
2663 return expandDMULMacro(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2666 return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2671 return expandStoreDM1Macro(Inst, IDLoc, Out, STI)
2674 case Mips::SEQMacro:
2675 return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2676 case Mips::SEQIMacro:
2677 return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2678 case Mips::SNEMacro:
2679 return expandSne(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2680 case Mips::SNEIMacro:
2681 return expandSneI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2682 case Mips::MFTC0:
case Mips::MTTC0:
2683 case Mips::MFTGPR:
case Mips::MTTGPR:
2684 case Mips::MFTLO:
case Mips::MTTLO:
2685 case Mips::MFTHI:
case Mips::MTTHI:
2686 case Mips::MFTACX:
case Mips::MTTACX:
2687 case Mips::MFTDSP:
case Mips::MTTDSP:
2688 case Mips::MFTC1:
case Mips::MTTC1:
2689 case Mips::MFTHC1:
case Mips::MTTHC1:
2690 case Mips::CFTC1:
case Mips::CTTC1:
2691 return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2693 case Mips::SaadAddr:
2694 return expandSaaAddr(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2698bool MipsAsmParser::expandJalWithRegs(
MCInst &Inst,
SMLoc IDLoc,
2707 const unsigned Opcode = Inst.
getOpcode();
2709 if (Opcode == Mips::JalOneReg) {
2711 if (IsCpRestoreSet && inMicroMipsMode()) {
2714 }
else if (inMicroMipsMode()) {
2715 JalrInst.
setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2722 }
else if (Opcode == Mips::JalTwoReg) {
2724 if (IsCpRestoreSet && inMicroMipsMode())
2727 JalrInst.
setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2759bool MipsAsmParser::loadImmediate(int64_t ImmValue,
unsigned DstReg,
2760 unsigned SrcReg,
bool Is32BitImm,
2765 if (!Is32BitImm && !isGP64bit()) {
2766 Error(IDLoc,
"instruction requires a 64-bit architecture");
2771 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2775 ImmValue = SignExtend64<32>(ImmValue);
2777 Error(IDLoc,
"instruction requires a 32-bit immediate");
2782 unsigned ZeroReg = IsAddress ?
ABI.GetNullPtr() :
ABI.GetZeroReg();
2783 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2785 bool UseSrcReg =
false;
2786 if (SrcReg != Mips::NoRegister)
2789 unsigned TmpReg = DstReg;
2791 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2794 unsigned ATReg = getATReg(IDLoc);
2800 if (isInt<16>(ImmValue)) {
2807 if (IsAddress && !Is32BitImm) {
2808 TOut.
emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2812 TOut.
emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2816 if (isUInt<16>(ImmValue)) {
2817 unsigned TmpReg = DstReg;
2818 if (SrcReg == DstReg) {
2819 TmpReg = getATReg(IDLoc);
2824 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2826 TOut.
emitRRR(
ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2830 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2831 warnIfNoMacro(IDLoc);
2833 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2834 uint16_t Bits15To0 = ImmValue & 0xffff;
2835 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2838 if (ImmValue == 0xffffffff) {
2839 TOut.
emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2840 TOut.
emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2842 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2848 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2849 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2851 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2853 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2857 TOut.
emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2859 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2861 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2865 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2867 Error(IDLoc,
"instruction requires a 32-bit immediate");
2874 assert(
BitWidth >= 17 &&
"ImmValue must be at least 17-bit wide");
2878 unsigned ShiftAmount =
BitWidth - 16;
2880 TOut.
emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2881 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2884 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2889 warnIfNoMacro(IDLoc);
2896 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister,
true,
false,
2902 unsigned ShiftCarriedForwards = 16;
2903 for (
int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2904 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2906 if (ImmChunk != 0) {
2907 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2908 TOut.
emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2909 ShiftCarriedForwards = 0;
2912 ShiftCarriedForwards += 16;
2914 ShiftCarriedForwards -= 16;
2917 if (ShiftCarriedForwards)
2918 TOut.
emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2921 TOut.
emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2926bool MipsAsmParser::expandLoadImm(
MCInst &Inst,
bool Is32BitImm,
SMLoc IDLoc,
2929 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
2931 assert(DstRegOp.
isReg() &&
"expected register operand kind");
2933 if (loadImmediate(ImmOp.
getImm(), DstRegOp.
getReg(), Mips::NoRegister,
2934 Is32BitImm,
false, IDLoc, Out, STI))
2940bool MipsAsmParser::expandLoadAddress(
unsigned DstReg,
unsigned BaseReg,
2942 bool Is32BitAddress,
SMLoc IDLoc,
2946 if (Is32BitAddress &&
ABI.ArePtrs64bit()) {
2947 Warning(IDLoc,
"la used to load 64-bit address");
2949 Is32BitAddress =
false;
2953 if (!Is32BitAddress && !hasMips3()) {
2954 Error(IDLoc,
"instruction requires a 64-bit architecture");
2959 return loadAndAddSymbolAddress(
Offset.getExpr(), DstReg, BaseReg,
2960 Is32BitAddress, IDLoc, Out, STI);
2962 if (!
ABI.ArePtrs64bit()) {
2964 Is32BitAddress =
true;
2967 return loadImmediate(
Offset.getImm(), DstReg, BaseReg, Is32BitAddress,
true,
2971bool MipsAsmParser::loadAndAddSymbolAddress(
const MCExpr *SymExpr,
2972 unsigned DstReg,
unsigned SrcReg,
2973 bool Is32BitSym,
SMLoc IDLoc,
2977 bool UseSrcReg = SrcReg != Mips::NoRegister && SrcReg != Mips::ZERO &&
2978 SrcReg != Mips::ZERO_64;
2979 warnIfNoMacro(IDLoc);
2984 Error(IDLoc,
"expected relocatable expression");
2987 if (Res.
getSymB() !=
nullptr) {
2988 Error(IDLoc,
"expected relocatable expression with only one symbol");
2992 bool IsPtr64 =
ABI.ArePtrs64bit();
3004 bool UseXGOT = STI->
hasFeature(Mips::FeatureXGOT) && !IsLocalSym;
3010 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
3014 SymExpr, getContext());
3016 SymExpr, getContext());
3019 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, DstReg, GPReg,
3021 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, DstReg,
3026 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, GPReg,
3032 unsigned TmpReg = DstReg;
3034 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
3038 unsigned ATReg = getATReg(IDLoc);
3057 const MCExpr *CallHiExpr =
3064 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg, GPReg,
3066 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, TmpReg,
3070 TOut.
emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3076 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3082 const MCExpr *LoExpr =
nullptr;
3083 if (
ABI.IsN32() ||
ABI.IsN64()) {
3102 Error(IDLoc,
"macro instruction uses large offset, which is not "
3103 "currently supported");
3133 TOut.
emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, GPReg,
3137 TOut.
emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3141 TOut.
emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3153 if (
ABI.ArePtrs64bit() && isGP64bit()) {
3168 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
3170 if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
3171 unsigned ATReg = getATReg(IDLoc);
3183 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3185 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3188 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3191 TOut.
emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
3194 }
else if (canUseATReg() && !RdRegIsRsReg && DstReg != getATReg(IDLoc)) {
3195 unsigned ATReg = getATReg(IDLoc);
3211 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3215 TOut.
emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3216 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3218 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3221 }
else if ((!canUseATReg() && !RdRegIsRsReg) ||
3222 (canUseATReg() && DstReg == getATReg(IDLoc))) {
3233 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3235 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3236 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3238 TOut.
emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3239 TOut.
emitRRX(Mips::DADDiu, DstReg, DstReg,
3242 TOut.
emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3248 assert(SrcReg == DstReg && !canUseATReg() &&
3249 "Could have expanded dla but didn't?");
3250 reportParseError(IDLoc,
3251 "pseudo-instruction requires $at, which is not available");
3265 unsigned TmpReg = DstReg;
3267 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
3270 unsigned ATReg = getATReg(IDLoc);
3281 TOut.
emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3284 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
3293 if (MipsMCRegisterClasses[Mips::FGR32RegClassID].
contains(
Reg))
3294 return Reg == (
unsigned)Mips::F31 ? (
unsigned)Mips::F0 :
Reg + 1;
3296 default:
llvm_unreachable(
"Unknown register in assembly macro expansion!");
3297 case Mips::ZERO:
return Mips::AT;
3298 case Mips::AT:
return Mips::V0;
3299 case Mips::V0:
return Mips::V1;
3300 case Mips::V1:
return Mips::A0;
3301 case Mips::A0:
return Mips::A1;
3302 case Mips::A1:
return Mips::A2;
3303 case Mips::A2:
return Mips::A3;
3304 case Mips::A3:
return Mips::T0;
3305 case Mips::T0:
return Mips::T1;
3306 case Mips::T1:
return Mips::T2;
3307 case Mips::T2:
return Mips::T3;
3308 case Mips::T3:
return Mips::T4;
3309 case Mips::T4:
return Mips::T5;
3310 case Mips::T5:
return Mips::T6;
3311 case Mips::T6:
return Mips::T7;
3312 case Mips::T7:
return Mips::S0;
3313 case Mips::S0:
return Mips::S1;
3314 case Mips::S1:
return Mips::S2;
3315 case Mips::S2:
return Mips::S3;
3316 case Mips::S3:
return Mips::S4;
3317 case Mips::S4:
return Mips::S5;
3318 case Mips::S5:
return Mips::S6;
3319 case Mips::S6:
return Mips::S7;
3320 case Mips::S7:
return Mips::T8;
3321 case Mips::T8:
return Mips::T9;
3322 case Mips::T9:
return Mips::K0;
3323 case Mips::K0:
return Mips::K1;
3324 case Mips::K1:
return Mips::GP;
3325 case Mips::GP:
return Mips::SP;
3326 case Mips::SP:
return Mips::FP;
3327 case Mips::FP:
return Mips::RA;
3328 case Mips::RA:
return Mips::ZERO;
3329 case Mips::D0:
return Mips::F1;
3330 case Mips::D1:
return Mips::F3;
3331 case Mips::D2:
return Mips::F5;
3332 case Mips::D3:
return Mips::F7;
3333 case Mips::D4:
return Mips::F9;
3334 case Mips::D5:
return Mips::F11;
3335 case Mips::D6:
return Mips::F13;
3336 case Mips::D7:
return Mips::F15;
3337 case Mips::D8:
return Mips::F17;
3338 case Mips::D9:
return Mips::F19;
3339 case Mips::D10:
return Mips::F21;
3340 case Mips::D11:
return Mips::F23;
3341 case Mips::D12:
return Mips::F25;
3342 case Mips::D13:
return Mips::F27;
3343 case Mips::D14:
return Mips::F29;
3344 case Mips::D15:
return Mips::F31;
3356 unsigned ATReg = getATReg(IDLoc);
3366 if(isABI_O32() || isABI_N32()) {
3385 if(isABI_O32() || isABI_N32()) {
3388 const MCExpr *HighestSym =
3392 const MCExpr *HigherSym =
3399 TOut.
emitRRX(Mips::DADDiu, ATReg, ATReg,
3401 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3404 TOut.
emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3413 if ((
Hi_32(ImmOp64) & 0x7ff00000) == 0) {
3414 APFloat RealVal(APFloat::IEEEdouble(), ImmOp64);
3423 double DoubleImm = llvm::bit_cast<double>(ImmOp64);
3424 float TmpFloat =
static_cast<float>(DoubleImm);
3425 return llvm::bit_cast<uint32_t>(TmpFloat);
3428bool MipsAsmParser::expandLoadSingleImmToGPR(
MCInst &Inst,
SMLoc IDLoc,
3433 "Invalid instruction operand.");
3440 return loadImmediate(ImmOp32, FirstReg, Mips::NoRegister,
true,
false, IDLoc,
3444bool MipsAsmParser::expandLoadSingleImmToFPR(
MCInst &Inst,
SMLoc IDLoc,
3450 "Invalid instruction operand.");
3459 unsigned TmpReg = Mips::ZERO;
3461 TmpReg = getATReg(IDLoc);
3466 if (
Lo_32(ImmOp64) == 0) {
3467 if (TmpReg != Mips::ZERO && loadImmediate(ImmOp32, TmpReg, Mips::NoRegister,
3468 true,
false, IDLoc, Out, STI))
3470 TOut.
emitRR(Mips::MTC1, FirstReg, TmpReg, IDLoc, STI);
3474 MCSection *CS = getStreamer().getCurrentSectionOnly();
3486 getStreamer().switchSection(ReadOnlySection);
3487 getStreamer().emitLabel(
Sym, IDLoc);
3488 getStreamer().emitInt32(ImmOp32);
3489 getStreamer().switchSection(CS);
3491 if (emitPartialAddress(TOut, IDLoc,
Sym))
3498bool MipsAsmParser::expandLoadDoubleImmToGPR(
MCInst &Inst,
SMLoc IDLoc,
3504 "Invalid instruction operand.");
3511 if (
Lo_32(ImmOp64) == 0) {
3513 if (loadImmediate(ImmOp64, FirstReg, Mips::NoRegister,
false,
false,
3517 if (loadImmediate(
Hi_32(ImmOp64), FirstReg, Mips::NoRegister,
true,
false,
3521 if (loadImmediate(0,
nextReg(FirstReg), Mips::NoRegister,
true,
false,
3528 MCSection *CS = getStreamer().getCurrentSectionOnly();
3538 getStreamer().switchSection(ReadOnlySection);
3539 getStreamer().emitLabel(
Sym, IDLoc);
3540 getStreamer().emitValueToAlignment(
Align(8));
3541 getStreamer().emitIntValue(ImmOp64, 8);
3542 getStreamer().switchSection(CS);
3544 unsigned TmpReg = getATReg(IDLoc);
3548 if (emitPartialAddress(TOut, IDLoc,
Sym))
3551 TOut.
emitRRX(isABI_N64() ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3555 TOut.
emitRRI(Mips::LD, FirstReg, TmpReg, 0, IDLoc, STI);
3557 TOut.
emitRRI(Mips::LW, FirstReg, TmpReg, 0, IDLoc, STI);
3558 TOut.
emitRRI(Mips::LW,
nextReg(FirstReg), TmpReg, 4, IDLoc, STI);
3563bool MipsAsmParser::expandLoadDoubleImmToFPR(
MCInst &Inst,
bool Is64FPU,
3569 "Invalid instruction operand.");
3576 unsigned TmpReg = Mips::ZERO;
3578 TmpReg = getATReg(IDLoc);
3583 if ((
Lo_32(ImmOp64) == 0) &&
3584 !((
Hi_32(ImmOp64) & 0xffff0000) && (
Hi_32(ImmOp64) & 0x0000ffff))) {
3586 if (TmpReg != Mips::ZERO &&
3587 loadImmediate(ImmOp64, TmpReg, Mips::NoRegister,
false,
false, IDLoc,
3590 TOut.
emitRR(Mips::DMTC1, FirstReg, TmpReg, IDLoc, STI);
3594 if (TmpReg != Mips::ZERO &&
3595 loadImmediate(
Hi_32(ImmOp64), TmpReg, Mips::NoRegister,
true,
false,
3599 if (hasMips32r2()) {
3600 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3601 TOut.
emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, TmpReg, IDLoc, STI);
3603 TOut.
emitRR(Mips::MTC1,
nextReg(FirstReg), TmpReg, IDLoc, STI);
3604 TOut.
emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3609 MCSection *CS = getStreamer().getCurrentSectionOnly();
3621 getStreamer().switchSection(ReadOnlySection);
3622 getStreamer().emitLabel(
Sym, IDLoc);
3623 getStreamer().emitValueToAlignment(
Align(8));
3624 getStreamer().emitIntValue(ImmOp64, 8);
3625 getStreamer().switchSection(CS);
3627 if (emitPartialAddress(TOut, IDLoc,
Sym))
3630 TOut.
emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, TmpReg,
3636bool MipsAsmParser::expandUncondBranchMMPseudo(
MCInst &Inst,
SMLoc IDLoc,
3642 "unexpected number of operands");
3652 assert(
Offset.isImm() &&
"expected immediate operand kind");
3653 if (isInt<11>(
Offset.getImm())) {
3656 if (inMicroMipsMode())
3657 Inst.
setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3659 if (!isInt<17>(
Offset.getImm()))
3660 return Error(IDLoc,
"branch target out of range");
3662 return Error(IDLoc,
"branch to misaligned address");
3685 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3688 assert(ImmOp.
isImm() &&
"expected immediate operand kind");
3692 "expected immediate or expression operand");
3694 bool IsLikely =
false;
3696 unsigned OpCode = 0;
3704 case Mips::BEQLImmMacro:
3705 OpCode = Mips::BEQL;
3708 case Mips::BNELImmMacro:
3709 OpCode = Mips::BNEL;
3717 int64_t ImmValue = ImmOp.
getImm();
3718 if (ImmValue == 0) {
3722 TOut.
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3724 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3727 warnIfNoMacro(IDLoc);
3729 unsigned ATReg = getATReg(IDLoc);
3733 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(),
true,
3740 TOut.
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3742 TOut.
emitRRX(OpCode, DstRegOp.
getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3750 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3751 unsigned StartOp = NumOp == 3 ? 0 : 1;
3754 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3756 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3761 unsigned DstReg = DstRegOp.
getReg();
3762 unsigned BaseReg = BaseRegOp.
getReg();
3763 unsigned TmpReg = DstReg;
3766 int16_t DstRegClass =
Desc.operands()[StartOp].RegClass;
3767 unsigned DstRegClassID =
3768 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3769 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3770 (DstRegClassID == Mips::GPR64RegClassID);
3772 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3775 TmpReg = getATReg(IDLoc);
3782 TOut.
emitRRX(OpCode, DstReg, TmpReg, Off, IDLoc, STI);
3784 TOut.
emitRRRX(OpCode, DstReg, DstReg, TmpReg, Off, IDLoc, STI);
3787 if (OffsetOp.
isImm()) {
3788 int64_t LoOffset = OffsetOp.
getImm() & 0xffff;
3789 int64_t HiOffset = OffsetOp.
getImm() & ~0xffff;
3793 if (LoOffset & 0x8000)
3794 HiOffset += 0x10000;
3796 bool IsLargeOffset = HiOffset != 0;
3798 if (IsLargeOffset) {
3799 bool Is32BitImm = isInt<32>(OffsetOp.
getImm());
3800 if (loadImmediate(HiOffset, TmpReg, Mips::NoRegister, Is32BitImm,
true,
3805 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3806 TOut.
emitRRR(
ABI.ArePtrs64bit() ? Mips::DADDu : Mips::ADDu, TmpReg,
3807 TmpReg, BaseReg, IDLoc, STI);
3822 Error(IDLoc,
"expected relocatable expression");
3825 if (Res.
getSymB() !=
nullptr) {
3826 Error(IDLoc,
"expected relocatable expression with only one symbol");
3830 loadAndAddSymbolAddress(Res.
getSymA(), TmpReg, BaseReg,
3831 !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3851 TOut.
emitRX(Mips::LUi, TmpReg, HighestOperand, IDLoc, STI);
3852 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HigherOperand, IDLoc, STI);
3853 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3854 TOut.
emitRRX(Mips::DADDiu, TmpReg, TmpReg, HiOperand, IDLoc, STI);
3855 TOut.
emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3856 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3857 TOut.
emitRRR(Mips::DADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3858 emitInstWithOffset(LoOperand);
3861 TOut.
emitRX(Mips::LUi, TmpReg, HiOperand, IDLoc, STI);
3862 if (BaseReg != Mips::ZERO)
3863 TOut.
emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3865 emitInstWithOffset(LoOperand);
3877 assert((NumOp == 3 || NumOp == 4) &&
"unexpected operands number");
3878 unsigned StartOp = NumOp == 3 ? 0 : 1;
3881 assert(DstRegOp.
isReg() &&
"expected register operand kind");
3883 assert(BaseRegOp.
isReg() &&
"expected register operand kind");
3888 unsigned DstReg = DstRegOp.
getReg();
3889 unsigned BaseReg = BaseRegOp.
getReg();
3890 unsigned TmpReg = DstReg;
3893 int16_t DstRegClass =
Desc.operands()[StartOp].RegClass;
3894 unsigned DstRegClassID =
3895 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3896 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3897 (DstRegClassID == Mips::GPR64RegClassID);
3899 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3902 TmpReg = getATReg(IDLoc);
3907 auto emitInst = [&]() {
3915 if (OffsetOp.
isImm()) {
3916 loadImmediate(OffsetOp.
getImm(), TmpReg, BaseReg, !
ABI.ArePtrs64bit(),
true,
3923 loadAndAddSymbolAddress(OffsetOp.
getExpr(), TmpReg, BaseReg,
3924 !
ABI.ArePtrs64bit(), IDLoc, Out, STI);
3932bool MipsAsmParser::expandLoadStoreMultiple(
MCInst &Inst,
SMLoc IDLoc,
3937 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3941 Inst.
getOperand(OpNum - 3).
isReg() &&
"Invalid instruction operand.");
3950 if (inMicroMipsMode() && hasMips32r6())
3951 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3953 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3961bool MipsAsmParser::expandCondBranches(
MCInst &Inst,
SMLoc IDLoc,
3965 bool EmittedNoMacroWarning =
false;
3966 unsigned PseudoOpcode = Inst.
getOpcode();
3971 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3972 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3977 else if (TrgOp.
isImm()) {
3978 warnIfNoMacro(IDLoc);
3979 EmittedNoMacroWarning =
true;
3981 TrgReg = getATReg(IDLoc);
3985 switch(PseudoOpcode) {
3988 case Mips::BLTImmMacro:
3989 PseudoOpcode = Mips::BLT;
3991 case Mips::BLEImmMacro:
3992 PseudoOpcode = Mips::BLE;
3994 case Mips::BGEImmMacro:
3995 PseudoOpcode = Mips::BGE;
3997 case Mips::BGTImmMacro:
3998 PseudoOpcode = Mips::BGT;
4000 case Mips::BLTUImmMacro:
4001 PseudoOpcode = Mips::BLTU;
4003 case Mips::BLEUImmMacro:
4004 PseudoOpcode = Mips::BLEU;
4006 case Mips::BGEUImmMacro:
4007 PseudoOpcode = Mips::BGEU;
4009 case Mips::BGTUImmMacro:
4010 PseudoOpcode = Mips::BGTU;
4012 case Mips::BLTLImmMacro:
4013 PseudoOpcode = Mips::BLTL;
4015 case Mips::BLELImmMacro:
4016 PseudoOpcode = Mips::BLEL;
4018 case Mips::BGELImmMacro:
4019 PseudoOpcode = Mips::BGEL;
4021 case Mips::BGTLImmMacro:
4022 PseudoOpcode = Mips::BGTL;
4024 case Mips::BLTULImmMacro:
4025 PseudoOpcode = Mips::BLTUL;
4027 case Mips::BLEULImmMacro:
4028 PseudoOpcode = Mips::BLEUL;
4030 case Mips::BGEULImmMacro:
4031 PseudoOpcode = Mips::BGEUL;
4033 case Mips::BGTULImmMacro:
4034 PseudoOpcode = Mips::BGTUL;
4038 if (loadImmediate(TrgOp.
getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
4039 false, IDLoc, Out, STI))
4043 switch (PseudoOpcode) {
4048 AcceptsEquality =
false;
4049 ReverseOrderSLT =
false;
4051 ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
4052 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
4053 ZeroSrcOpcode = Mips::BGTZ;
4054 ZeroTrgOpcode = Mips::BLTZ;
4060 AcceptsEquality =
true;
4061 ReverseOrderSLT =
true;
4063 ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
4064 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
4065 ZeroSrcOpcode = Mips::BGEZ;
4066 ZeroTrgOpcode = Mips::BLEZ;
4072 AcceptsEquality =
true;
4073 ReverseOrderSLT =
false;
4075 ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
4076 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
4077 ZeroSrcOpcode = Mips::BLEZ;
4078 ZeroTrgOpcode = Mips::BGEZ;
4084 AcceptsEquality =
false;
4085 ReverseOrderSLT =
true;
4087 ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
4088 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
4089 ZeroSrcOpcode = Mips::BLTZ;
4090 ZeroTrgOpcode = Mips::BGTZ;
4096 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
4097 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
4098 if (IsSrcRegZero && IsTrgRegZero) {
4102 if (PseudoOpcode == Mips::BLT) {
4107 if (PseudoOpcode == Mips::BLE) {
4110 Warning(IDLoc,
"branch is always taken");
4113 if (PseudoOpcode == Mips::BGE) {
4116 Warning(IDLoc,
"branch is always taken");
4119 if (PseudoOpcode == Mips::BGT) {
4124 if (PseudoOpcode == Mips::BGTU) {
4125 TOut.
emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
4129 if (AcceptsEquality) {
4132 TOut.
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4134 Warning(IDLoc,
"branch is always taken");
4141 if (IsSrcRegZero || IsTrgRegZero) {
4142 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
4143 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
4150 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
4151 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
4157 TOut.
emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4159 Warning(IDLoc,
"branch is always taken");
4175 TOut.
emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
4176 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
4183 TOut.
emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
4184 IsSrcRegZero ? TrgReg : SrcReg,
4191 unsigned ATRegNum = getATReg(IDLoc);
4195 if (!EmittedNoMacroWarning)
4196 warnIfNoMacro(IDLoc);
4213 TOut.
emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
4214 ReverseOrderSLT ? TrgReg : SrcReg,
4215 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
4217 TOut.
emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
4218 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
4234 const bool IsMips64,
const bool Signed) {
4237 warnIfNoMacro(IDLoc);
4240 assert(RdRegOp.
isReg() &&
"expected register operand kind");
4241 unsigned RdReg = RdRegOp.
getReg();
4244 assert(RsRegOp.
isReg() &&
"expected register operand kind");
4245 unsigned RsReg = RsRegOp.
getReg();
4252 "expected register or immediate operand kind");
4256 ImmValue = RtOp.
getImm();
4263 DivOp =
Signed ? Mips::DSDIV : Mips::DUDIV;
4264 ZeroReg = Mips::ZERO_64;
4267 DivOp =
Signed ? Mips::SDIV : Mips::UDIV;
4268 ZeroReg = Mips::ZERO;
4272 bool UseTraps = useTraps();
4275 bool isDiv = Opcode == Mips::SDivMacro || Opcode == Mips::SDivIMacro ||
4276 Opcode == Mips::UDivMacro || Opcode == Mips::UDivIMacro ||
4277 Opcode == Mips::DSDivMacro || Opcode == Mips::DSDivIMacro ||
4278 Opcode == Mips::DUDivMacro || Opcode == Mips::DUDivIMacro;
4280 bool isRem = Opcode == Mips::SRemMacro || Opcode == Mips::SRemIMacro ||
4281 Opcode == Mips::URemMacro || Opcode == Mips::URemIMacro ||
4282 Opcode == Mips::DSRemMacro || Opcode == Mips::DSRemIMacro ||
4283 Opcode == Mips::DURemMacro || Opcode == Mips::DURemIMacro;
4286 unsigned ATReg = getATReg(IDLoc);
4290 if (ImmValue == 0) {
4292 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4294 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4298 if (isRem && (ImmValue == 1 || (
Signed && (ImmValue == -1)))) {
4299 TOut.
emitRRR(Mips::OR, RdReg, ZeroReg, ZeroReg, IDLoc, STI);
4301 }
else if (isDiv && ImmValue == 1) {
4302 TOut.
emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI);
4304 }
else if (isDiv &&
Signed && ImmValue == -1) {
4305 TOut.
emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
4308 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, isInt<32>(ImmValue),
4309 false, Inst.
getLoc(), Out, STI))
4311 TOut.
emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
4312 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4322 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
4324 TOut.
emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4327 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4333 if (isRem && (RdReg == Mips::ZERO || RdReg == Mips::ZERO_64)) {
4334 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4344 TOut.
emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4347 BrTarget =
Context.createTempSymbol();
4349 TOut.
emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4352 TOut.
emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4355 TOut.
emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4361 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4365 unsigned ATReg = getATReg(IDLoc);
4372 TOut.
emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
4380 TOut.
emitRRX(Mips::BNE, RtReg, ATReg, LabelOpEnd, IDLoc, STI);
4383 TOut.
emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
4384 TOut.
emitDSLL(ATReg, ATReg, 63, IDLoc, STI);
4390 TOut.
emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
4393 TOut.
emitRRX(Mips::BNE, RsReg, ATReg, LabelOpEnd, IDLoc, STI);
4395 TOut.
emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
4399 TOut.
emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4403bool MipsAsmParser::expandTrunc(
MCInst &Inst,
bool IsDouble,
bool Is64FPU,
4416 if (hasMips1() && !hasMips2()) {
4417 unsigned ATReg = getATReg(IDLoc);
4420 TOut.
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4421 TOut.
emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4423 TOut.
emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4424 TOut.
emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4425 TOut.
emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4427 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4429 FirstReg, SecondReg, IDLoc, STI);
4430 TOut.
emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4435 TOut.
emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4437 FirstReg, SecondReg, IDLoc, STI);
4444 if (hasMips32r6() || hasMips64r6()) {
4445 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4449 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4451 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4453 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4456 unsigned DstReg = DstRegOp.
getReg();
4457 unsigned SrcReg = SrcRegOp.
getReg();
4458 int64_t OffsetValue = OffsetImmOp.
getImm();
4462 warnIfNoMacro(IDLoc);
4463 unsigned ATReg = getATReg(IDLoc);
4467 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4468 if (IsLargeOffset) {
4469 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4474 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4475 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4479 unsigned FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4480 unsigned SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4482 unsigned LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4483 unsigned SllReg = IsLargeOffset ? DstReg : ATReg;
4485 TOut.
emitRRI(
Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4486 FirstOffset, IDLoc, STI);
4487 TOut.
emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4488 TOut.
emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4489 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4496 if (hasMips32r6() || hasMips64r6()) {
4497 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4501 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4503 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4505 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4508 unsigned DstReg = DstRegOp.
getReg();
4509 unsigned SrcReg = SrcRegOp.
getReg();
4510 int64_t OffsetValue = OffsetImmOp.
getImm();
4512 warnIfNoMacro(IDLoc);
4513 unsigned ATReg = getATReg(IDLoc);
4517 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4518 if (IsLargeOffset) {
4519 if (loadImmediate(OffsetValue, ATReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4524 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4525 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4529 if (IsLargeOffset) {
4530 TOut.
emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4531 TOut.
emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4532 TOut.
emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4533 TOut.
emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4534 TOut.
emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4535 TOut.
emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4537 TOut.
emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4538 TOut.
emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4539 TOut.
emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4547 if (hasMips32r6() || hasMips64r6()) {
4548 return Error(IDLoc,
"instruction not supported on mips32r6 or mips64r6");
4552 assert(DstRegOp.
isReg() &&
"expected register operand kind");
4554 assert(SrcRegOp.
isReg() &&
"expected register operand kind");
4556 assert(OffsetImmOp.
isImm() &&
"expected immediate operand kind");
4559 unsigned DstReg = DstRegOp.
getReg();
4560 unsigned SrcReg = SrcRegOp.
getReg();
4561 int64_t OffsetValue = OffsetImmOp.
getImm();
4564 bool IsLargeOffset = !(isInt<16>(OffsetValue + 3) && isInt<16>(OffsetValue));
4565 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4566 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4570 bool IsLoadInst = (Inst.
getOpcode() == Mips::Ulw);
4571 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4572 unsigned TmpReg = SrcReg;
4573 if (IsLargeOffset || DoMove) {
4574 warnIfNoMacro(IDLoc);
4575 TmpReg = getATReg(IDLoc);
4580 if (IsLargeOffset) {
4581 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !
ABI.ArePtrs64bit(),
true,
4589 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4590 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4591 TOut.
emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4592 TOut.
emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4595 TOut.
emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4614 warnIfNoMacro(IDLoc);
4621 OpCode = Mips::SLTu;
4628 TOut.
emitRRR(OpCode, DstReg, SrcReg, OpReg, IDLoc, STI);
4629 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4646 unsigned OpRegCode, OpImmCode;
4648 warnIfNoMacro(IDLoc);
4652 case Mips::SGEImm64:
4653 OpRegCode = Mips::SLT;
4654 OpImmCode = Mips::SLTi;
4657 case Mips::SGEUImm64:
4658 OpRegCode = Mips::SLTu;
4659 OpImmCode = Mips::SLTiu;
4666 if (isInt<16>(ImmValue)) {
4668 TOut.
emitRRI(OpImmCode, DstReg, SrcReg, ImmValue, IDLoc, STI);
4669 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4671 unsigned ImmReg = DstReg;
4672 if (DstReg == SrcReg) {
4673 unsigned ATReg = getATReg(Inst.
getLoc());
4679 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4680 false, IDLoc, Out, STI))
4683 TOut.
emitRRR(OpRegCode, DstReg, SrcReg, ImmReg, IDLoc, STI);
4684 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4701 unsigned ImmReg = DstReg;
4705 warnIfNoMacro(IDLoc);
4709 case Mips::SGTImm64:
4713 case Mips::SGTUImm64:
4714 OpCode = Mips::SLTu;
4720 if (DstReg == SrcReg) {
4721 unsigned ATReg = getATReg(Inst.
getLoc());
4727 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4728 false, IDLoc, Out, STI))
4732 TOut.
emitRRR(OpCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4751 warnIfNoMacro(IDLoc);
4758 OpCode = Mips::SLTu;
4765 TOut.
emitRRR(OpCode, DstReg, OpReg, SrcReg, IDLoc, STI);
4766 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4785 warnIfNoMacro(IDLoc);
4789 case Mips::SLEImm64:
4790 OpRegCode = Mips::SLT;
4793 case Mips::SLEUImm64:
4794 OpRegCode = Mips::SLTu;
4801 unsigned ImmReg = DstReg;
4802 if (DstReg == SrcReg) {
4803 unsigned ATReg = getATReg(Inst.
getLoc());
4809 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4810 false, IDLoc, Out, STI))
4813 TOut.
emitRRR(OpRegCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4814 TOut.
emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4819bool MipsAsmParser::expandAliasImmediate(
MCInst &Inst,
SMLoc IDLoc,
4829 unsigned ATReg = Mips::NoRegister;
4830 unsigned FinalDstReg = Mips::NoRegister;
4835 bool Is32Bit = isInt<32>(ImmValue) || (!isGP64bit() && isUInt<32>(ImmValue));
4837 unsigned FinalOpcode = Inst.
getOpcode();
4839 if (DstReg == SrcReg) {
4840 ATReg = getATReg(Inst.
getLoc());
4843 FinalDstReg = DstReg;
4847 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit,
false,
4848 Inst.
getLoc(), Out, STI)) {
4849 switch (FinalOpcode) {
4853 FinalOpcode = Mips::ADD;
4856 FinalOpcode = Mips::ADDu;
4859 FinalOpcode = Mips::AND;
4862 FinalOpcode = Mips::NOR;
4865 FinalOpcode = Mips::OR;
4868 FinalOpcode = Mips::SLT;
4871 FinalOpcode = Mips::SLTu;
4874 FinalOpcode = Mips::XOR;
4877 FinalOpcode = Mips::ADD_MM;
4879 case Mips::ADDiu_MM:
4880 FinalOpcode = Mips::ADDu_MM;
4883 FinalOpcode = Mips::AND_MM;
4886 FinalOpcode = Mips::OR_MM;
4889 FinalOpcode = Mips::SLT_MM;
4891 case Mips::SLTiu_MM:
4892 FinalOpcode = Mips::SLTu_MM;
4895 FinalOpcode = Mips::XOR_MM;
4898 FinalOpcode = Mips::AND64;
4900 case Mips::NORImm64:
4901 FinalOpcode = Mips::NOR64;
4904 FinalOpcode = Mips::OR64;
4906 case Mips::SLTImm64:
4907 FinalOpcode = Mips::SLT64;
4909 case Mips::SLTUImm64:
4910 FinalOpcode = Mips::SLTu64;
4913 FinalOpcode = Mips::XOR64;
4917 if (FinalDstReg == Mips::NoRegister)
4918 TOut.
emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4920 TOut.
emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4929 unsigned ATReg = Mips::NoRegister;
4933 unsigned TmpReg =
DReg;
4935 unsigned FirstShift = Mips::NOP;
4936 unsigned SecondShift = Mips::NOP;
4938 if (hasMips32r2()) {
4940 TmpReg = getATReg(Inst.
getLoc());
4946 TOut.
emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4947 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
4952 TOut.
emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
4964 FirstShift = Mips::SRLV;
4965 SecondShift = Mips::SLLV;
4968 FirstShift = Mips::SLLV;
4969 SecondShift = Mips::SRLV;
4973 ATReg = getATReg(Inst.
getLoc());
4977 TOut.
emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
4978 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
4979 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
4980 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
4988bool MipsAsmParser::expandRotationImm(
MCInst &Inst,
SMLoc IDLoc,
4992 unsigned ATReg = Mips::NoRegister;
4997 unsigned FirstShift = Mips::NOP;
4998 unsigned SecondShift = Mips::NOP;
5000 if (hasMips32r2()) {
5005 ShiftValue = MaxShift - ImmValue;
5006 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
5011 TOut.
emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.
getLoc(), STI);
5019 if (ImmValue == 0) {
5028 FirstShift = Mips::SLL;
5029 SecondShift = Mips::SRL;
5032 FirstShift = Mips::SRL;
5033 SecondShift = Mips::SLL;
5037 ATReg = getATReg(Inst.
getLoc());
5041 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.
getLoc(), STI);
5042 TOut.
emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.
getLoc(), STI);
5043 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5054 unsigned ATReg = Mips::NoRegister;
5058 unsigned TmpReg =
DReg;
5060 unsigned FirstShift = Mips::NOP;
5061 unsigned SecondShift = Mips::NOP;
5063 if (hasMips64r2()) {
5064 if (TmpReg == SReg) {
5065 TmpReg = getATReg(Inst.
getLoc());
5071 TOut.
emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
5072 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.
getLoc(), STI);
5077 TOut.
emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.
getLoc(), STI);
5089 FirstShift = Mips::DSRLV;
5090 SecondShift = Mips::DSLLV;
5093 FirstShift = Mips::DSLLV;
5094 SecondShift = Mips::DSRLV;
5098 ATReg = getATReg(Inst.
getLoc());
5102 TOut.
emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.
getLoc(), STI);
5103 TOut.
emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.
getLoc(), STI);
5104 TOut.
emitRRR(SecondShift, DReg, SReg, TReg, Inst.
getLoc(), STI);
5105 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5113bool MipsAsmParser::expandDRotationImm(
MCInst &Inst,
SMLoc IDLoc,
5117 unsigned ATReg = Mips::NoRegister;
5122 unsigned FirstShift = Mips::NOP;
5123 unsigned SecondShift = Mips::NOP;
5127 if (hasMips64r2()) {
5128 unsigned FinalOpcode = Mips::NOP;
5130 FinalOpcode = Mips::DROTR;
5131 else if (ImmValue % 32 == 0)
5132 FinalOpcode = Mips::DROTR32;
5133 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
5135 FinalOpcode = Mips::DROTR32;
5137 FinalOpcode = Mips::DROTR;
5138 }
else if (ImmValue >= 33) {
5140 FinalOpcode = Mips::DROTR;
5142 FinalOpcode = Mips::DROTR32;
5145 uint64_t ShiftValue = ImmValue % 32;
5147 ShiftValue = (32 - ImmValue % 32) % 32;
5149 TOut.
emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.
getLoc(), STI);
5155 if (ImmValue == 0) {
5156 TOut.
emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.
getLoc(), STI);
5164 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5165 FirstShift = Mips::DSLL;
5166 SecondShift = Mips::DSRL32;
5168 if (ImmValue == 32) {
5169 FirstShift = Mips::DSLL32;
5170 SecondShift = Mips::DSRL32;
5172 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5173 FirstShift = Mips::DSLL32;
5174 SecondShift = Mips::DSRL;
5178 if ((ImmValue >= 1) && (ImmValue <= 31)) {
5179 FirstShift = Mips::DSRL;
5180 SecondShift = Mips::DSLL32;
5182 if (ImmValue == 32) {
5183 FirstShift = Mips::DSRL32;
5184 SecondShift = Mips::DSLL32;
5186 if ((ImmValue >= 33) && (ImmValue <= 63)) {
5187 FirstShift = Mips::DSRL32;
5188 SecondShift = Mips::DSLL;
5193 ATReg = getATReg(Inst.
getLoc());
5197 TOut.
emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.
getLoc(), STI);
5198 TOut.
emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
5200 TOut.
emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.
getLoc(), STI);
5214 TOut.
emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
5215 if (FirstRegOp != SecondRegOp)
5216 TOut.
emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
5219 TOut.
emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
5227 unsigned ATReg = Mips::NoRegister;
5232 ATReg = getATReg(IDLoc);
5236 loadImmediate(ImmValue, ATReg, Mips::NoRegister,
true,
false, IDLoc, Out,
5239 TOut.
emitRR(Inst.
getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
5240 SrcReg, ATReg, IDLoc, STI);
5242 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5250 unsigned ATReg = Mips::NoRegister;
5255 ATReg = getATReg(Inst.
getLoc());
5259 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
5260 SrcReg, TmpReg, IDLoc, STI);
5262 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5264 TOut.
emitRRI(Inst.
getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
5265 DstReg, DstReg, 0x1F, IDLoc, STI);
5267 TOut.
emitR(Mips::MFHI, ATReg, IDLoc, STI);
5270 TOut.
emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
5277 TOut.
emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
5278 if (AssemblerOptions.
back()->isReorder())
5280 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5284 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5292 unsigned ATReg = Mips::NoRegister;
5297 ATReg = getATReg(IDLoc);
5301 TOut.
emitRR(Inst.
getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
5302 SrcReg, TmpReg, IDLoc, STI);
5304 TOut.
emitR(Mips::MFHI, ATReg, IDLoc, STI);
5305 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5307 TOut.
emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);
5314 TOut.
emitRRX(Mips::BEQ, ATReg, Mips::ZERO, LabelOp, IDLoc, STI);
5315 if (AssemblerOptions.
back()->isReorder())
5317 TOut.
emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5332 TOut.
emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
5333 TOut.
emitR(Mips::MFLO, DstReg, IDLoc, STI);
5343bool MipsAsmParser::expandLoadStoreDMacro(
MCInst &Inst,
SMLoc IDLoc,
5350 warnIfNoMacro(IDLoc);
5353 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
5355 unsigned SecondReg =
nextReg(FirstReg);
5360 warnIfRegIndexIsAT(FirstReg, IDLoc);
5363 "Offset for load macro is not immediate!");
5366 signed NextOffset = FirstOffset.
getImm() + 4;
5369 if (!isInt<16>(FirstOffset.
getImm()) || !isInt<16>(NextOffset))
5374 if (FirstReg != BaseReg || !IsLoad) {
5375 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5376 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5378 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5379 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5391bool MipsAsmParser::expandStoreDM1Macro(
MCInst &Inst,
SMLoc IDLoc,
5397 warnIfNoMacro(IDLoc);
5400 unsigned Opcode = Mips::SWC1;
5402 unsigned SecondReg =
nextReg(FirstReg);
5407 warnIfRegIndexIsAT(FirstReg, IDLoc);
5410 "Offset for macro is not immediate!");
5413 signed NextOffset = FirstOffset.
getImm() + 4;
5416 if (!isInt<16>(FirstOffset.
getImm()) || !isInt<16>(NextOffset))
5419 if (!IsLittleEndian)
5422 TOut.
emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5423 TOut.
emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5441 warnIfNoMacro(IDLoc);
5443 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5444 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5445 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5449 unsigned Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5450 TOut.
emitRRI(Mips::SLTiu, DstReg,
Reg, 1, IDLoc, STI);
5467 warnIfNoMacro(IDLoc);
5470 TOut.
emitRRI(Mips::SLTiu, DstReg, SrcReg, 1, IDLoc, STI);
5474 if (SrcReg == Mips::ZERO) {
5475 Warning(IDLoc,
"comparison is always false");
5476 TOut.
emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
5477 DstReg, SrcReg, SrcReg, IDLoc, STI);
5482 if (Imm > -0x8000 && Imm < 0) {
5484 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5489 if (!isUInt<16>(Imm)) {
5490 unsigned ATReg = getATReg(IDLoc);
5494 if (loadImmediate(Imm, ATReg, Mips::NoRegister,
true, isGP64bit(), IDLoc,
5498 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5499 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5503 TOut.
emitRRI(Opc, DstReg, SrcReg, Imm, IDLoc, STI);
5504 TOut.
emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5522 warnIfNoMacro(IDLoc);
5524 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5525 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5526 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5530 unsigned Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5531 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO,
Reg, IDLoc, STI);
5548 warnIfNoMacro(IDLoc);
5550 if (ImmValue == 0) {
5551 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, SrcReg, IDLoc, STI);
5555 if (SrcReg == Mips::ZERO) {
5556 Warning(IDLoc,
"comparison is always true");
5557 if (loadImmediate(1, DstReg, Mips::NoRegister,
true,
false, IDLoc, Out,
5564 if (ImmValue > -0x8000 && ImmValue < 0) {
5565 ImmValue = -ImmValue;
5566 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5571 if (isUInt<16>(ImmValue)) {
5572 TOut.
emitRRI(Opc, DstReg, SrcReg, ImmValue, IDLoc, STI);
5573 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5577 unsigned ATReg = getATReg(IDLoc);
5581 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, isInt<32>(ImmValue),
5582 false, IDLoc, Out, STI))
5585 TOut.
emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5586 TOut.
emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5649 case Mips::F0:
return Mips::ZERO;
5650 case Mips::F1:
return Mips::AT;
5651 case Mips::F2:
return Mips::V0;
5652 case Mips::F3:
return Mips::V1;
5653 case Mips::F4:
return Mips::A0;
5654 case Mips::F5:
return Mips::A1;
5655 case Mips::F6:
return Mips::A2;
5656 case Mips::F7:
return Mips::A3;
5657 case Mips::F8:
return Mips::T0;
5658 case Mips::F9:
return Mips::T1;
5659 case Mips::F10:
return Mips::T2;
5660 case Mips::F11:
return Mips::T3;
5661 case Mips::F12:
return Mips::T4;
5662 case Mips::F13:
return Mips::T5;
5663 case Mips::F14:
return Mips::T6;
5664 case Mips::F15:
return Mips::T7;
5665 case Mips::F16:
return Mips::S0;
5666 case Mips::F17:
return Mips::S1;
5667 case Mips::F18:
return Mips::S2;
5668 case Mips::F19:
return Mips::S3;
5669 case Mips::F20:
return Mips::S4;
5670 case Mips::F21:
return Mips::S5;
5671 case Mips::F22:
return Mips::S6;
5672 case Mips::F23:
return Mips::S7;
5673 case Mips::F24:
return Mips::T8;
5674 case Mips::F25:
return Mips::T9;
5675 case Mips::F26:
return Mips::K0;
5676 case Mips::F27:
return Mips::K1;
5677 case Mips::F28:
return Mips::GP;
5678 case Mips::F29:
return Mips::SP;
5679 case Mips::F30:
return Mips::FP;
5680 case Mips::F31:
return Mips::RA;
5688 case Mips::COP00:
return Mips::ZERO;
5689 case Mips::COP01:
return Mips::AT;
5690 case Mips::COP02:
return Mips::V0;
5691 case Mips::COP03:
return Mips::V1;
5692 case Mips::COP04:
return Mips::A0;
5693 case Mips::COP05:
return Mips::A1;
5694 case Mips::COP06:
return Mips::A2;
5695 case Mips::COP07:
return Mips::A3;
5696 case Mips::COP08:
return Mips::T0;
5697 case Mips::COP09:
return Mips::T1;
5698 case Mips::COP010:
return Mips::T2;
5699 case Mips::COP011:
return Mips::T3;
5700 case Mips::COP012:
return Mips::T4;
5701 case Mips::COP013:
return Mips::T5;
5702 case Mips::COP014:
return Mips::T6;
5703 case Mips::COP015:
return Mips::T7;
5704 case Mips::COP016:
return Mips::S0;
5705 case Mips::COP017:
return Mips::S1;
5706 case Mips::COP018:
return Mips::S2;
5707 case Mips::COP019:
return Mips::S3;
5708 case Mips::COP020:
return Mips::S4;
5709 case Mips::COP021:
return Mips::S5;
5710 case Mips::COP022:
return Mips::S6;
5711 case Mips::COP023:
return Mips::S7;
5712 case Mips::COP024:
return Mips::T8;
5713 case Mips::COP025:
return Mips::T9;
5714 case Mips::COP026:
return Mips::K0;
5715 case Mips::COP027:
return Mips::K1;
5716 case Mips::COP028:
return Mips::GP;
5717 case Mips::COP029:
return Mips::SP;
5718 case Mips::COP030:
return Mips::FP;
5719 case Mips::COP031:
return Mips::RA;
5733 bool IsMFTR =
false;
5791 TOut.
emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, u, sel, h, IDLoc,
5802 warnIfNoMacro(IDLoc);
5805 unsigned Opcode = Inst.
getOpcode() == Mips::SaaAddr ? Mips::SAA : Mips::SAAD;
5810 if (BaseOp.
isImm()) {
5811 int64_t ImmValue = BaseOp.
getImm();
5812 if (ImmValue == 0) {
5813 TOut.
emitRR(Opcode, RtReg, BaseReg, IDLoc, STI);
5818 unsigned ATReg = getATReg(IDLoc);
5822 if (expandLoadAddress(ATReg, BaseReg, BaseOp, !isGP64bit(), IDLoc, Out, STI))
5825 TOut.
emitRR(Opcode, RtReg, ATReg, IDLoc, STI);
5830MipsAsmParser::checkEarlyTargetMatchPredicate(
MCInst &Inst,
5834 return Match_Success;
5837 if (
static_cast<MipsOperand &
>(*
Operands[1])
5838 .isValidForTie(
static_cast<MipsOperand &
>(*
Operands[2])))
5839 return Match_Success;
5840 return Match_RequiresSameSrcAndDst;
5844unsigned MipsAsmParser::checkTargetMatchPredicate(
MCInst &Inst) {
5851 return Match_RequiresNoZeroRegister;
5852 return Match_Success;
5858 case Mips::JALR_HB64:
5859 case Mips::JALRC_HB_MMR6:
5860 case Mips::JALRC_MMR6:
5862 return Match_RequiresDifferentSrcAndDst;
5863 return Match_Success;
5866 return Match_RequiresDifferentSrcAndDst;
5867 return Match_Success;
5870 return Match_NonZeroOperandForSync;
5871 return Match_Success;
5877 return Match_NonZeroOperandForMTCX;
5878 return Match_Success;
5891 case Mips::BLEZC:
case Mips::BLEZC_MMR6:
5892 case Mips::BGEZC:
case Mips::BGEZC_MMR6:
5893 case Mips::BGTZC:
case Mips::BGTZC_MMR6:
5894 case Mips::BLTZC:
case Mips::BLTZC_MMR6:
5895 case Mips::BEQZC:
case Mips::BEQZC_MMR6:
5896 case Mips::BNEZC:
case Mips::BNEZC_MMR6:
5905 return Match_RequiresNoZeroRegister;
5906 return Match_Success;
5907 case Mips::BGEC:
case Mips::BGEC_MMR6:
5908 case Mips::BLTC:
case Mips::BLTC_MMR6:
5909 case Mips::BGEUC:
case Mips::BGEUC_MMR6:
5910 case Mips::BLTUC:
case Mips::BLTUC_MMR6:
5911 case Mips::BEQC:
case Mips::BEQC_MMR6:
5912 case Mips::BNEC:
case Mips::BNEC_MMR6:
5921 return Match_RequiresNoZeroRegister;
5924 return Match_RequiresNoZeroRegister;
5926 return Match_RequiresDifferentOperands;
5927 return Match_Success;
5930 "Operands must be immediates for dins!");
5933 if ((0 > (Pos +
Size)) || ((Pos +
Size) > 32))
5934 return Match_RequiresPosSizeRange0_32;
5935 return Match_Success;
5940 "Operands must be immediates for dinsm/dinsu!");
5943 if ((32 >= (Pos +
Size)) || ((Pos +
Size) > 64))
5944 return Match_RequiresPosSizeRange33_64;
5945 return Match_Success;
5949 "Operands must be immediates for DEXTM!");
5952 if ((1 > (Pos +
Size)) || ((Pos +
Size) > 63))
5953 return Match_RequiresPosSizeUImm6;
5954 return Match_Success;
5959 "Operands must be immediates for dextm/dextu!");
5962 if ((32 > (Pos +
Size)) || ((Pos +
Size) > 64))
5963 return Match_RequiresPosSizeRange33_64;
5964 return Match_Success;
5966 case Mips::CRC32B:
case Mips::CRC32CB:
5967 case Mips::CRC32H:
case Mips::CRC32CH:
5968 case Mips::CRC32W:
case Mips::CRC32CW:
5969 case Mips::CRC32D:
case Mips::CRC32CD:
5971 return Match_RequiresSameSrcAndDst;
5972 return Match_Success;
5978 return Match_NoFCCRegisterForCurrentISA;
5980 return Match_Success;
5988 if (ErrorLoc ==
SMLoc())
5995bool MipsAsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
5999 bool MatchingInlineAsm) {
6001 unsigned MatchResult =
6004 switch (MatchResult) {
6006 if (processInstruction(Inst, IDLoc, Out, STI))
6009 case Match_MissingFeature:
6010 Error(IDLoc,
"instruction requires a CPU feature not currently enabled");
6012 case Match_InvalidTiedOperand:
6013 Error(IDLoc,
"operand must match destination register");
6015 case Match_InvalidOperand: {
6016 SMLoc ErrorLoc = IDLoc;
6019 return Error(IDLoc,
"too few operands for instruction");
6022 if (ErrorLoc ==
SMLoc())
6026 return Error(ErrorLoc,
"invalid operand for instruction");
6028 case Match_NonZeroOperandForSync:
6030 "s-type must be zero or unspecified for pre-MIPS32 ISAs");
6031 case Match_NonZeroOperandForMTCX:
6032 return Error(IDLoc,
"selector must be zero for pre-MIPS32 ISAs");
6033 case Match_MnemonicFail:
6034 return Error(IDLoc,
"invalid instruction");
6035 case Match_RequiresDifferentSrcAndDst:
6036 return Error(IDLoc,
"source and destination must be different");
6037 case Match_RequiresDifferentOperands:
6038 return Error(IDLoc,
"registers must be different");
6039 case Match_RequiresNoZeroRegister:
6040 return Error(IDLoc,
"invalid operand ($zero) for instruction");
6041 case Match_RequiresSameSrcAndDst:
6042 return Error(IDLoc,
"source and destination must match");
6043 case Match_NoFCCRegisterForCurrentISA:
6045 "non-zero fcc register doesn't exist in current ISA level");
6050 "expected 1-bit unsigned immediate");
6053 "expected 2-bit unsigned immediate");
6056 "expected immediate in range 1 .. 4");
6059 "expected 3-bit unsigned immediate");
6062 "expected 4-bit unsigned immediate");
6065 "expected 4-bit signed immediate");
6068 "expected 5-bit unsigned immediate");
6071 "expected 5-bit signed immediate");
6074 "expected immediate in range 1 .. 32");
6075 case Match_UImm5_32:
6077 "expected immediate in range 32 .. 63");
6078 case Match_UImm5_33:
6080 "expected immediate in range 33 .. 64");
6081 case Match_UImm5_0_Report_UImm6:
6085 "expected 6-bit unsigned immediate");
6086 case Match_UImm5_Lsl2:
6088 "expected both 7-bit unsigned immediate and multiple of 4");
6089 case Match_UImmRange2_64:
6091 "expected immediate in range 2 .. 64");
6094 "expected 6-bit unsigned immediate");
6095 case Match_UImm6_Lsl2:
6097 "expected both 8-bit unsigned immediate and multiple of 4");
6100 "expected 6-bit signed immediate");
6103 "expected 7-bit unsigned immediate");
6104 case Match_UImm7_N1:
6106 "expected immediate in range -1 .. 126");
6107 case Match_SImm7_Lsl2:
6109 "expected both 9-bit signed immediate and multiple of 4");
6112 "expected 8-bit unsigned immediate");
6113 case Match_UImm10_0:
6115 "expected 10-bit unsigned immediate");
6116 case Match_SImm10_0:
6118 "expected 10-bit signed immediate");
6119 case Match_SImm11_0:
6121 "expected 11-bit signed immediate");
6123 case Match_UImm16_Relaxed:
6124 case Match_UImm16_AltRelaxed:
6126 "expected 16-bit unsigned immediate");
6128 case Match_SImm16_Relaxed:
6130 "expected 16-bit signed immediate");
6131 case Match_SImm19_Lsl2:
6133 "expected both 19-bit signed immediate and multiple of 4");
6134 case Match_UImm20_0:
6136 "expected 20-bit unsigned immediate");
6137 case Match_UImm26_0:
6139 "expected 26-bit unsigned immediate");
6141 case Match_SImm32_Relaxed:
6143 "expected 32-bit signed immediate");
6144 case Match_UImm32_Coerced:
6146 "expected 32-bit immediate");
6147 case Match_MemSImm9:
6149 "expected memory with 9-bit signed offset");
6150 case Match_MemSImm10:
6152 "expected memory with 10-bit signed offset");
6153 case Match_MemSImm10Lsl1:
6155 "expected memory with 11-bit signed offset and multiple of 2");
6156 case Match_MemSImm10Lsl2:
6158 "expected memory with 12-bit signed offset and multiple of 4");
6159 case Match_MemSImm10Lsl3:
6161 "expected memory with 13-bit signed offset and multiple of 8");
6162 case Match_MemSImm11:
6164 "expected memory with 11-bit signed offset");
6165 case Match_MemSImm12:
6167 "expected memory with 12-bit signed offset");
6168 case Match_MemSImm16:
6170 "expected memory with 16-bit signed offset");
6171 case Match_MemSImmPtr:
6173 "expected memory with 32-bit signed offset");
6174 case Match_RequiresPosSizeRange0_32: {
6177 return Error(ErrorStart,
"size plus position are not in the range 0 .. 32",
6178 SMRange(ErrorStart, ErrorEnd));
6180 case Match_RequiresPosSizeUImm6: {
6183 return Error(ErrorStart,
"size plus position are not in the range 1 .. 63",
6184 SMRange(ErrorStart, ErrorEnd));
6186 case Match_RequiresPosSizeRange33_64: {
6189 return Error(ErrorStart,
"size plus position are not in the range 33 .. 64",
6190 SMRange(ErrorStart, ErrorEnd));
6197void MipsAsmParser::warnIfRegIndexIsAT(
unsigned RegIndex,
SMLoc Loc) {
6198 if (RegIndex != 0 && AssemblerOptions.
back()->getATRegIndex() == RegIndex)
6199 Warning(Loc,
"used $at (currently $" +
Twine(RegIndex) +
6200 ") without \".set noat\"");
6203void MipsAsmParser::warnIfNoMacro(
SMLoc Loc) {
6204 if (!AssemblerOptions.
back()->isMacro())
6205 Warning(Loc,
"macro instruction expanded into multiple instructions");
6208void MipsAsmParser::ConvertXWPOperands(
MCInst &Inst,
6212 "Unexpected instruction!");
6213 ((MipsOperand &)*
Operands[1]).addGPR32ZeroAsmRegOperands(Inst, 1);
6216 ((MipsOperand &)*
Operands[2]).addMemOperands(Inst, 2);
6220MipsAsmParser::printWarningWithFixIt(
const Twine &Msg,
const Twine &FixMsg,
6221 SMRange Range,
bool ShowColors) {
6223 Range,
SMFixIt(Range, FixMsg),
6232 .
Cases(
"at",
"AT", 1)
6266 if (!(isABI_N32() || isABI_N64()))
6269 if (12 <=
CC &&
CC <= 15) {
6271 AsmToken RegTok = getLexer().peekTok();
6280 assert(FixedName !=
"" &&
"Register name is not one of t4-t7.");
6282 printWarningWithFixIt(
"register names $t4-$t7 are only available in O32.",
6283 "Did you mean $" + FixedName +
"?", RegRange);
6289 if (8 <=
CC &&
CC <= 11)
6309 .
Case(
"hwr_cpunum", 0)
6310 .
Case(
"hwr_synci_step", 1)
6312 .
Case(
"hwr_ccres", 3)
6313 .
Case(
"hwr_ulr", 29)
6320 if (
Name[0] ==
'f') {
6333 if (
Name.starts_with(
"fcc")) {
6346 if (
Name.starts_with(
"ac")) {
6361 if (
Name.front() !=
'w' ||
Name.drop_front(1).getAsInteger(10, IntVal))
6370int MipsAsmParser::matchMSA128CtrlRegisterName(
StringRef Name) {
6376 .
Case(
"msaaccess", 2)
6378 .
Case(
"msamodify", 4)
6379 .
Case(
"msarequest", 5)
6381 .
Case(
"msaunmap", 7)
6387bool MipsAsmParser::canUseATReg() {
6388 return AssemblerOptions.
back()->getATRegIndex() != 0;
6391unsigned MipsAsmParser::getATReg(
SMLoc Loc) {
6392 unsigned ATIndex = AssemblerOptions.
back()->getATRegIndex();
6394 reportParseError(Loc,
6395 "pseudo-instruction requires $at, which is not available");
6399 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
6403unsigned MipsAsmParser::getReg(
int RC,
int RegNo) {
6404 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
6424 switch (getLexer().getKind()) {
6434 if (!parseAnyRegister(
Operands).isNoMatch())
6443 MCSymbol *
Sym = getContext().getOrCreateSymbol(Identifier);
6448 Operands.push_back(MipsOperand::CreateImm(SymRef, S,
E, *
this));
6456 if (getParser().parseExpression(Expr))
6461 Operands.push_back(MipsOperand::CreateImm(Expr, S,
E, *
this));
6470 return !tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess();
6479 MipsOperand &Operand =
static_cast<MipsOperand &
>(*
Operands.front());
6480 StartLoc = Operand.getStartLoc();
6481 EndLoc = Operand.getEndLoc();
6487 if (Operand.isGPRAsmReg()) {
6489 Reg = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
6499bool MipsAsmParser::parseMemOffset(
const MCExpr *&Res,
bool isParenExpr) {
6503 return getParser().parseParenExprOfDepth(0, Res, S);
6504 return getParser().parseExpression(Res);
6510 const MCExpr *IdVal =
nullptr;
6512 bool isParenExpr =
false;
6523 if (parseMemOffset(IdVal, isParenExpr))
6528 MipsOperand &Mnemonic =
static_cast<MipsOperand &
>(*
Operands[0]);
6529 if (Mnemonic.getToken() ==
"la" || Mnemonic.getToken() ==
"dla") {
6532 Operands.push_back(MipsOperand::CreateImm(IdVal, S,
E, *
this));
6541 auto Base = MipsOperand::createGPRReg(
6542 0,
"0", getContext().getRegisterInfo(), S,
E, *
this);
6544 MipsOperand::CreateMem(std::move(
Base), IdVal, S,
E, *
this));
6597 if (getParser().parseExpression(NextExpr))
6620 std::unique_ptr<MipsOperand>
op(
6621 static_cast<MipsOperand *
>(
Operands.back().release()));
6626 if (
const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
6628 if (IdVal->evaluateAsAbsolute(Imm))
6635 Operands.push_back(MipsOperand::CreateMem(std::move(
op), IdVal, S,
E, *
this));
6646 if (
Sym->isVariable()) {
6647 const MCExpr *Expr =
Sym->getVariableValue();
6653 matchAnyRegisterNameWithoutDollar(
Operands, DefSymbol.
substr(1), S);
6662 }
else if (
Sym->isUnset()) {
6666 auto Entry = RegisterSets.
find(
Sym->getName());
6667 if (Entry != RegisterSets.
end()) {
6669 matchAnyRegisterWithoutDollar(
Operands, Entry->getValue(), S);
6680ParseStatus MipsAsmParser::matchAnyRegisterNameWithoutDollar(
6682 int Index = matchCPURegisterName(Identifier);
6684 Operands.push_back(MipsOperand::createGPRReg(
6685 Index, Identifier, getContext().getRegisterInfo(), S,
6686 getLexer().getLoc(), *
this));
6690 Index = matchHWRegsRegisterName(Identifier);
6692 Operands.push_back(MipsOperand::createHWRegsReg(
6693 Index, Identifier, getContext().getRegisterInfo(), S,
6694 getLexer().getLoc(), *
this));
6698 Index = matchFPURegisterName(Identifier);
6700 Operands.push_back(MipsOperand::createFGRReg(
6701 Index, Identifier, getContext().getRegisterInfo(), S,
6702 getLexer().getLoc(), *
this));
6706 Index = matchFCCRegisterName(Identifier);
6708 Operands.push_back(MipsOperand::createFCCReg(
6709 Index, Identifier, getContext().getRegisterInfo(), S,
6710 getLexer().getLoc(), *
this));
6714 Index = matchACRegisterName(Identifier);
6716 Operands.push_back(MipsOperand::createACCReg(
6717 Index, Identifier, getContext().getRegisterInfo(), S,
6718 getLexer().getLoc(), *
this));
6722 Index = matchMSA128RegisterName(Identifier);
6724 Operands.push_back(MipsOperand::createMSA128Reg(
6725 Index, Identifier, getContext().getRegisterInfo(), S,
6726 getLexer().getLoc(), *
this));
6730 Index = matchMSA128CtrlRegisterName(Identifier);
6732 Operands.push_back(MipsOperand::createMSACtrlReg(
6733 Index, Identifier, getContext().getRegisterInfo(), S,
6734 getLexer().getLoc(), *
this));
6747 return matchAnyRegisterNameWithoutDollar(
Operands, Identifier, S);
6752 if (RegNum < 0 || RegNum > 31) {
6756 Error(getLexer().getLoc(),
"invalid register number");
6758 Operands.push_back(MipsOperand::createNumericReg(
6759 RegNum, Token.
getString(), getContext().getRegisterInfo(), S,
6771 auto Token = getLexer().peekTok(
false);
6772 return matchAnyRegisterWithoutDollar(
Operands, Token, S);
6779 auto Token = Parser.
getTok();
6806 SMLoc S = getLexer().getLoc();
6814 const MCExpr *Expr =
nullptr;
6820 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *
this));
6837 if (getParser().parseExpression(IdVal))
6844 Operands.push_back(MipsOperand::CreateImm(
6853 unsigned PrevReg = Mips::NoRegister;
6854 bool RegRange =
false;
6861 while (parseAnyRegister(TmpOperands).isSuccess()) {
6862 SMLoc E = getLexer().getLoc();
6863 MipsOperand &
Reg =
static_cast<MipsOperand &
>(*TmpOperands.
back());
6864 RegNo = isGP64bit() ?
Reg.getGPR64Reg() :
Reg.getGPR32Reg();
6868 if ((isGP64bit() && RegNo == Mips::RA_64) ||
6869 (!isGP64bit() && RegNo == Mips::RA)) {
6872 unsigned TmpReg = PrevReg + 1;
6873 while (TmpReg <= RegNo) {
6874 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
6875 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
6877 return Error(
E,
"invalid register operand");
6886 if ((PrevReg == Mips::NoRegister) &&
6887 ((isGP64bit() && (RegNo != Mips::S0_64) && (RegNo != Mips::RA_64)) ||
6888 (!isGP64bit() && (RegNo != Mips::S0) && (RegNo != Mips::RA))))
6889 return Error(
E,
"$16 or $31 expected");
6890 if (!(((RegNo == Mips::FP || RegNo == Mips::RA ||
6891 (RegNo >= Mips::S0 && RegNo <= Mips::S7)) &&
6893 ((RegNo == Mips::FP_64 || RegNo == Mips::RA_64 ||
6894 (RegNo >= Mips::S0_64 && RegNo <= Mips::S7_64)) &&
6896 return Error(
E,
"invalid register operand");
6897 if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
6898 ((RegNo != Mips::FP && RegNo != Mips::RA && !isGP64bit()) ||
6899 (RegNo != Mips::FP_64 && RegNo != Mips::RA_64 && isGP64bit())))
6900 return Error(
E,
"consecutive register numbers expected");
6910 return Error(
E,
"',' or '-' expected");
6920 Operands.push_back(MipsOperand::CreateRegList(Regs, S,
E, *
this));
6934 MipsOperand::CreateToken(
"(", getLexer().getLoc(), *
this));
6937 SMLoc Loc = getLexer().getLoc();
6938 return Error(Loc,
"unexpected token in argument list");
6941 SMLoc Loc = getLexer().getLoc();
6942 return Error(Loc,
"unexpected token, expected ')'");
6945 MipsOperand::CreateToken(
")", getLexer().getLoc(), *
this));
6962 MipsOperand::CreateToken(
"[", getLexer().getLoc(), *
this));
6965 SMLoc Loc = getLexer().getLoc();
6966 return Error(Loc,
"unexpected token in argument list");
6969 SMLoc Loc = getLexer().getLoc();
6970 return Error(Loc,
"unexpected token, expected ']'");
6973 MipsOperand::CreateToken(
"]", getLexer().getLoc(), *
this));
6980 unsigned VariantID = 0);
7001 getTargetStreamer().forbidModuleDirective();
7004 if (!mnemonicIsValid(
Name, 0)) {
7005 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
7007 return Error(NameLoc,
"unknown instruction" + Suggestion);
7010 Operands.push_back(MipsOperand::CreateToken(
Name, NameLoc, *
this));
7016 SMLoc Loc = getLexer().getLoc();
7017 return Error(Loc,
"unexpected token in argument list");
7027 SMLoc Loc = getLexer().getLoc();
7028 return Error(Loc,
"unexpected token in argument list");
7040 SMLoc Loc = getLexer().getLoc();
7041 return Error(Loc,
"unexpected token in argument list");
7049bool MipsAsmParser::reportParseError(
const Twine &ErrorMsg) {
7050 SMLoc Loc = getLexer().getLoc();
7051 return Error(Loc, ErrorMsg);
7054bool MipsAsmParser::reportParseError(
SMLoc Loc,
const Twine &ErrorMsg) {
7055 return Error(Loc, ErrorMsg);
7058bool MipsAsmParser::parseSetNoAtDirective() {
7063 AssemblerOptions.
back()->setATRegIndex(0);
7069 reportParseError(
"unexpected token, expected end of statement");
7073 getTargetStreamer().emitDirectiveSetNoAt();
7078bool MipsAsmParser::parseSetAtDirective() {
7086 AssemblerOptions.
back()->setATRegIndex(1);
7088 getTargetStreamer().emitDirectiveSetAt();
7094 reportParseError(
"unexpected token, expected equals sign");
7101 reportParseError(
"no register specified");
7104 reportParseError(
"unexpected token, expected dollar sign '$'");
7114 AtRegNo = matchCPURegisterName(
Reg.getIdentifier());
7116 AtRegNo =
Reg.getIntVal();
7118 reportParseError(
"unexpected token, expected identifier or integer");
7123 if (!AssemblerOptions.
back()->setATRegIndex(AtRegNo)) {
7124 reportParseError(
"invalid register");
7131 reportParseError(
"unexpected token, expected end of statement");
7135 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
7141bool MipsAsmParser::parseSetReorderDirective() {
7146 reportParseError(
"unexpected token, expected end of statement");
7149 AssemblerOptions.
back()->setReorder();
7150 getTargetStreamer().emitDirectiveSetReorder();
7155bool MipsAsmParser::parseSetNoReorderDirective() {
7160 reportParseError(
"unexpected token, expected end of statement");
7163 AssemblerOptions.
back()->setNoReorder();
7164 getTargetStreamer().emitDirectiveSetNoReorder();
7169bool MipsAsmParser::parseSetMacroDirective() {
7174 reportParseError(
"unexpected token, expected end of statement");
7177 AssemblerOptions.
back()->setMacro();
7178 getTargetStreamer().emitDirectiveSetMacro();
7183bool MipsAsmParser::parseSetNoMacroDirective() {
7188 reportParseError(
"unexpected token, expected end of statement");
7191 if (AssemblerOptions.
back()->isReorder()) {
7192 reportParseError(
"`noreorder' must be set before `nomacro'");
7195 AssemblerOptions.
back()->setNoMacro();
7196 getTargetStreamer().emitDirectiveSetNoMacro();
7201bool MipsAsmParser::parseSetMsaDirective() {
7207 return reportParseError(
"unexpected token, expected end of statement");
7209 setFeatureBits(Mips::FeatureMSA,
"msa");
7210 getTargetStreamer().emitDirectiveSetMsa();
7214bool MipsAsmParser::parseSetNoMsaDirective() {
7220 return reportParseError(
"unexpected token, expected end of statement");
7222 clearFeatureBits(Mips::FeatureMSA,
"msa");
7223 getTargetStreamer().emitDirectiveSetNoMsa();
7227bool MipsAsmParser::parseSetNoDspDirective() {
7233 reportParseError(
"unexpected token, expected end of statement");
7237 clearFeatureBits(Mips::FeatureDSP,
"dsp");
7238 getTargetStreamer().emitDirectiveSetNoDsp();
7242bool MipsAsmParser::parseSetNoMips3DDirective() {
7248 reportParseError(
"unexpected token, expected end of statement");
7252 clearFeatureBits(Mips::FeatureMips3D,
"mips3d");
7253 getTargetStreamer().emitDirectiveSetNoMips3D();
7257bool MipsAsmParser::parseSetMips16Directive() {
7263 reportParseError(
"unexpected token, expected end of statement");
7267 setFeatureBits(Mips::FeatureMips16,
"mips16");
7268 getTargetStreamer().emitDirectiveSetMips16();
7273bool MipsAsmParser::parseSetNoMips16Directive() {
7279 reportParseError(
"unexpected token, expected end of statement");
7283 clearFeatureBits(Mips::FeatureMips16,
"mips16");
7284 getTargetStreamer().emitDirectiveSetNoMips16();
7289bool MipsAsmParser::parseSetFpDirective() {
7298 reportParseError(
"unexpected token, expected equals sign '='");
7304 if (!parseFpABIValue(FpAbiVal,
".set"))
7308 reportParseError(
"unexpected token, expected end of statement");
7311 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
7316bool MipsAsmParser::parseSetOddSPRegDirective() {
7321 reportParseError(
"unexpected token, expected end of statement");
7325 clearFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
7326 getTargetStreamer().emitDirectiveSetOddSPReg();
7330bool MipsAsmParser::parseSetNoOddSPRegDirective() {
7335 reportParseError(
"unexpected token, expected end of statement");
7339 setFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
7340 getTargetStreamer().emitDirectiveSetNoOddSPReg();
7344bool MipsAsmParser::parseSetMtDirective() {
7350 reportParseError(
"unexpected token, expected end of statement");
7354 setFeatureBits(Mips::FeatureMT,
"mt");
7355 getTargetStreamer().emitDirectiveSetMt();
7360bool MipsAsmParser::parseSetNoMtDirective() {
7366 reportParseError(
"unexpected token, expected end of statement");
7370 clearFeatureBits(Mips::FeatureMT,
"mt");
7372 getTargetStreamer().emitDirectiveSetNoMt();
7377bool MipsAsmParser::parseSetNoCRCDirective() {
7383 reportParseError(
"unexpected token, expected end of statement");
7387 clearFeatureBits(Mips::FeatureCRC,
"crc");
7389 getTargetStreamer().emitDirectiveSetNoCRC();
7394bool MipsAsmParser::parseSetNoVirtDirective() {
7400 reportParseError(
"unexpected token, expected end of statement");
7404 clearFeatureBits(Mips::FeatureVirt,
"virt");
7406 getTargetStreamer().emitDirectiveSetNoVirt();
7411bool MipsAsmParser::parseSetNoGINVDirective() {
7417 reportParseError(
"unexpected token, expected end of statement");
7421 clearFeatureBits(Mips::FeatureGINV,
"ginv");
7423 getTargetStreamer().emitDirectiveSetNoGINV();
7428bool MipsAsmParser::parseSetPopDirective() {
7430 SMLoc Loc = getLexer().getLoc();
7434 return reportParseError(
"unexpected token, expected end of statement");
7438 if (AssemblerOptions.
size() == 2)
7439 return reportParseError(Loc,
".set pop with no .set push");
7443 setAvailableFeatures(
7444 ComputeAvailableFeatures(AssemblerOptions.
back()->getFeatures()));
7447 getTargetStreamer().emitDirectiveSetPop();
7451bool MipsAsmParser::parseSetPushDirective() {
7455 return reportParseError(
"unexpected token, expected end of statement");
7459 std::make_unique<MipsAssemblerOptions>(AssemblerOptions.
back().get()));
7461 getTargetStreamer().emitDirectiveSetPush();
7465bool MipsAsmParser::parseSetSoftFloatDirective() {
7469 return reportParseError(
"unexpected token, expected end of statement");
7471 setFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
7472 getTargetStreamer().emitDirectiveSetSoftFloat();
7476bool MipsAsmParser::parseSetHardFloatDirective() {
7480 return reportParseError(
"unexpected token, expected end of statement");
7482 clearFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
7483 getTargetStreamer().emitDirectiveSetHardFloat();
7487bool MipsAsmParser::parseSetAssignment() {
7492 return reportParseError(
"expected identifier after .set");
7495 return reportParseError(
"unexpected token, expected comma");
7505 getContext().getOrCreateSymbol(
Name);
7519bool MipsAsmParser::parseSetMips0Directive() {
7523 return reportParseError(
"unexpected token, expected end of statement");
7527 setAvailableFeatures(
7528 ComputeAvailableFeatures(AssemblerOptions.
front()->getFeatures()));
7530 AssemblerOptions.
back()->setFeatures(AssemblerOptions.
front()->getFeatures());
7532 getTargetStreamer().emitDirectiveSetMips0();
7536bool MipsAsmParser::parseSetArchDirective() {
7540 return reportParseError(
"unexpected token, expected equals sign");
7543 StringRef Arch = getParser().parseStringToEndOfStatement().
trim();
7545 return reportParseError(
"expected arch identifier");
7549 .
Case(
"mips1",
"mips1")
7550 .
Case(
"mips2",
"mips2")
7551 .
Case(
"mips3",
"mips3")
7552 .
Case(
"mips4",
"mips4")
7553 .
Case(
"mips5",
"mips5")
7554 .
Case(
"mips32",
"mips32")
7555 .
Case(
"mips32r2",
"mips32r2")
7556 .
Case(
"mips32r3",
"mips32r3")
7557 .
Case(
"mips32r5",
"mips32r5")
7558 .
Case(
"mips32r6",
"mips32r6")
7559 .
Case(
"mips64",
"mips64")
7560 .
Case(
"mips64r2",
"mips64r2")
7561 .
Case(
"mips64r3",
"mips64r3")
7562 .
Case(
"mips64r5",
"mips64r5")
7563 .
Case(
"mips64r6",
"mips64r6")
7564 .
Case(
"octeon",
"cnmips")
7565 .
Case(
"octeon+",
"cnmipsp")
7566 .
Case(
"r4000",
"mips3")
7569 if (ArchFeatureName.
empty())
7570 return reportParseError(
"unsupported architecture");
7572 if (ArchFeatureName ==
"mips64r6" && inMicroMipsMode())
7573 return reportParseError(
"mips64r6 does not support microMIPS");
7575 selectArch(ArchFeatureName);
7576 getTargetStreamer().emitDirectiveSetArch(Arch);
7580bool MipsAsmParser::parseSetFeature(
uint64_t Feature) {
7584 return reportParseError(
"unexpected token, expected end of statement");
7589 case Mips::FeatureMips3D:
7590 setFeatureBits(Mips::FeatureMips3D,
"mips3d");
7591 getTargetStreamer().emitDirectiveSetMips3D();
7593 case Mips::FeatureDSP:
7594 setFeatureBits(Mips::FeatureDSP,
"dsp");
7595 getTargetStreamer().emitDirectiveSetDsp();
7597 case Mips::FeatureDSPR2:
7598 setFeatureBits(Mips::FeatureDSPR2,
"dspr2");
7599 getTargetStreamer().emitDirectiveSetDspr2();
7601 case Mips::FeatureMicroMips:
7602 setFeatureBits(Mips::FeatureMicroMips,
"micromips");
7603 getTargetStreamer().emitDirectiveSetMicroMips();
7605 case Mips::FeatureMips1:
7606 selectArch(
"mips1");
7607 getTargetStreamer().emitDirectiveSetMips1();
7609 case Mips::FeatureMips2:
7610 selectArch(
"mips2");
7611 getTargetStreamer().emitDirectiveSetMips2();
7613 case Mips::FeatureMips3:
7614 selectArch(
"mips3");
7615 getTargetStreamer().emitDirectiveSetMips3();
7617 case Mips::FeatureMips4:
7618 selectArch(
"mips4");
7619 getTargetStreamer().emitDirectiveSetMips4();
7621 case Mips::FeatureMips5:
7622 selectArch(
"mips5");
7623 getTargetStreamer().emitDirectiveSetMips5();
7625 case Mips::FeatureMips32:
7626 selectArch(
"mips32");
7627 getTargetStreamer().emitDirectiveSetMips32();
7629 case Mips::FeatureMips32r2:
7630 selectArch(
"mips32r2");
7631 getTargetStreamer().emitDirectiveSetMips32R2();
7633 case Mips::FeatureMips32r3:
7634 selectArch(
"mips32r3");
7635 getTargetStreamer().emitDirectiveSetMips32R3();
7637 case Mips::FeatureMips32r5:
7638 selectArch(
"mips32r5");
7639 getTargetStreamer().emitDirectiveSetMips32R5();
7641 case Mips::FeatureMips32r6:
7642 selectArch(
"mips32r6");
7643 getTargetStreamer().emitDirectiveSetMips32R6();
7645 case Mips::FeatureMips64:
7646 selectArch(
"mips64");
7647 getTargetStreamer().emitDirectiveSetMips64();
7649 case Mips::FeatureMips64r2:
7650 selectArch(
"mips64r2");
7651 getTargetStreamer().emitDirectiveSetMips64R2();
7653 case Mips::FeatureMips64r3:
7654 selectArch(
"mips64r3");
7655 getTargetStreamer().emitDirectiveSetMips64R3();
7657 case Mips::FeatureMips64r5:
7658 selectArch(
"mips64r5");
7659 getTargetStreamer().emitDirectiveSetMips64R5();
7661 case Mips::FeatureMips64r6:
7662 selectArch(
"mips64r6");
7663 getTargetStreamer().emitDirectiveSetMips64R6();
7665 case Mips::FeatureCRC:
7666 setFeatureBits(Mips::FeatureCRC,
"crc");
7667 getTargetStreamer().emitDirectiveSetCRC();
7669 case Mips::FeatureVirt:
7670 setFeatureBits(Mips::FeatureVirt,
"virt");
7671 getTargetStreamer().emitDirectiveSetVirt();
7673 case Mips::FeatureGINV:
7674 setFeatureBits(Mips::FeatureGINV,
"ginv");
7675 getTargetStreamer().emitDirectiveSetGINV();
7681bool MipsAsmParser::eatComma(
StringRef ErrorStr) {
7684 SMLoc Loc = getLexer().getLoc();
7685 return Error(Loc, ErrorStr);
7696bool MipsAsmParser::isPicAndNotNxxAbi() {
7697 return inPicMode() && !(isABI_N32() || isABI_N64());
7700bool MipsAsmParser::parseDirectiveCpAdd(
SMLoc Loc) {
7704 reportParseError(
"expected register");
7708 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7709 if (!RegOpnd.isGPRAsmReg()) {
7710 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7716 reportParseError(
"unexpected token, expected end of statement");
7721 getTargetStreamer().emitDirectiveCpAdd(RegOpnd.getGPR32Reg());
7725bool MipsAsmParser::parseDirectiveCpLoad(
SMLoc Loc) {
7726 if (AssemblerOptions.
back()->isReorder())
7727 Warning(Loc,
".cpload should be inside a noreorder section");
7729 if (inMips16Mode()) {
7730 reportParseError(
".cpload is not supported in Mips16 mode");
7737 reportParseError(
"expected register containing function address");
7741 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7742 if (!RegOpnd.isGPRAsmReg()) {
7743 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7749 reportParseError(
"unexpected token, expected end of statement");
7753 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
7757bool MipsAsmParser::parseDirectiveCpLocal(
SMLoc Loc) {
7758 if (!isABI_N32() && !isABI_N64()) {
7759 reportParseError(
".cplocal is allowed only in N32 or N64 mode");
7766 reportParseError(
"expected register containing global pointer");
7770 MipsOperand &RegOpnd =
static_cast<MipsOperand &
>(*
Reg[0]);
7771 if (!RegOpnd.isGPRAsmReg()) {
7772 reportParseError(RegOpnd.getStartLoc(),
"invalid register");
7778 reportParseError(
"unexpected token, expected end of statement");
7783 unsigned NewReg = RegOpnd.getGPR32Reg();
7787 getTargetStreamer().emitDirectiveCpLocal(NewReg);
7791bool MipsAsmParser::parseDirectiveCpRestore(
SMLoc Loc) {
7797 if (inMips16Mode()) {
7798 reportParseError(
".cprestore is not supported in Mips16 mode");
7804 int64_t StackOffsetVal;
7806 reportParseError(
"expected stack offset value");
7810 if (!
StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
7811 reportParseError(
"stack offset is not an absolute expression");
7815 if (StackOffsetVal < 0) {
7816 Warning(Loc,
".cprestore with negative stack offset has no effect");
7817 IsCpRestoreSet =
false;
7819 IsCpRestoreSet =
true;
7820 CpRestoreOffset = StackOffsetVal;
7825 reportParseError(
"unexpected token, expected end of statement");
7829 if (!getTargetStreamer().emitDirectiveCpRestore(
7830 CpRestoreOffset, [&]() {
return getATReg(Loc); }, Loc, STI))
7836bool MipsAsmParser::parseDirectiveCPSetup() {
7840 bool SaveIsReg =
true;
7845 reportParseError(
"expected register containing function address");
7849 MipsOperand &FuncRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7850 if (!FuncRegOpnd.isGPRAsmReg()) {
7851 reportParseError(FuncRegOpnd.getStartLoc(),
"invalid register");
7855 FuncReg = FuncRegOpnd.getGPR32Reg();
7858 if (!eatComma(
"unexpected token, expected comma"))
7861 Res = parseAnyRegister(TmpReg);
7863 const MCExpr *OffsetExpr;
7865 SMLoc ExprLoc = getLexer().getLoc();
7868 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
7869 reportParseError(ExprLoc,
"expected save register or stack offset");
7876 MipsOperand &SaveOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
7877 if (!SaveOpnd.isGPRAsmReg()) {
7878 reportParseError(SaveOpnd.getStartLoc(),
"invalid register");
7881 Save = SaveOpnd.getGPR32Reg();
7884 if (!eatComma(
"unexpected token, expected comma"))
7889 reportParseError(
"expected expression");
7894 reportParseError(
"expected symbol");
7899 CpSaveLocation = Save;
7900 CpSaveLocationIsRegister = SaveIsReg;
7902 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save,
Ref->getSymbol(),
7907bool MipsAsmParser::parseDirectiveCPReturn() {
7908 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
7909 CpSaveLocationIsRegister);
7913bool MipsAsmParser::parseDirectiveNaN() {
7920 getTargetStreamer().emitDirectiveNaN2008();
7922 }
else if (Tok.
getString() ==
"legacy") {
7924 getTargetStreamer().emitDirectiveNaNLegacy();
7930 reportParseError(
"invalid option in .nan directive");
7934bool MipsAsmParser::parseDirectiveSet() {
7935 const AsmToken &Tok = getParser().getTok();
7939 if (IdVal ==
"noat")
7940 return parseSetNoAtDirective();
7942 return parseSetAtDirective();
7943 if (IdVal ==
"arch")
7944 return parseSetArchDirective();
7945 if (IdVal ==
"bopt") {
7946 Warning(Loc,
"'bopt' feature is unsupported");
7950 if (IdVal ==
"nobopt") {
7956 return parseSetFpDirective();
7957 if (IdVal ==
"oddspreg")
7958 return parseSetOddSPRegDirective();
7959 if (IdVal ==
"nooddspreg")
7960 return parseSetNoOddSPRegDirective();
7962 return parseSetPopDirective();
7963 if (IdVal ==
"push")
7964 return parseSetPushDirective();
7965 if (IdVal ==
"reorder")
7966 return parseSetReorderDirective();
7967 if (IdVal ==
"noreorder")
7968 return parseSetNoReorderDirective();
7969 if (IdVal ==
"macro")
7970 return parseSetMacroDirective();
7971 if (IdVal ==
"nomacro")
7972 return parseSetNoMacroDirective();
7973 if (IdVal ==
"mips16")
7974 return parseSetMips16Directive();
7975 if (IdVal ==
"nomips16")
7976 return parseSetNoMips16Directive();
7977 if (IdVal ==
"nomicromips") {
7978 clearFeatureBits(Mips::FeatureMicroMips,
"micromips");
7979 getTargetStreamer().emitDirectiveSetNoMicroMips();
7980 getParser().eatToEndOfStatement();
7983 if (IdVal ==
"micromips") {
7984 if (hasMips64r6()) {
7985 Error(Loc,
".set micromips directive is not supported with MIPS64R6");
7988 return parseSetFeature(Mips::FeatureMicroMips);
7990 if (IdVal ==
"mips0")
7991 return parseSetMips0Directive();
7992 if (IdVal ==
"mips1")
7993 return parseSetFeature(Mips::FeatureMips1);
7994 if (IdVal ==
"mips2")
7995 return parseSetFeature(Mips::FeatureMips2);
7996 if (IdVal ==
"mips3")
7997 return parseSetFeature(Mips::FeatureMips3);
7998 if (IdVal ==
"mips4")
7999 return parseSetFeature(Mips::FeatureMips4);
8000 if (IdVal ==
"mips5")
8001 return parseSetFeature(Mips::FeatureMips5);
8002 if (IdVal ==
"mips32")
8003 return parseSetFeature(Mips::FeatureMips32);
8004 if (IdVal ==
"mips32r2")
8005 return parseSetFeature(Mips::FeatureMips32r2);
8006 if (IdVal ==
"mips32r3")
8007 return parseSetFeature(Mips::FeatureMips32r3);
8008 if (IdVal ==
"mips32r5")
8009 return parseSetFeature(Mips::FeatureMips32r5);
8010 if (IdVal ==
"mips32r6")
8011 return parseSetFeature(Mips::FeatureMips32r6);
8012 if (IdVal ==
"mips64")
8013 return parseSetFeature(Mips::FeatureMips64);
8014 if (IdVal ==
"mips64r2")
8015 return parseSetFeature(Mips::FeatureMips64r2);
8016 if (IdVal ==
"mips64r3")
8017 return parseSetFeature(Mips::FeatureMips64r3);
8018 if (IdVal ==
"mips64r5")
8019 return parseSetFeature(Mips::FeatureMips64r5);
8020 if (IdVal ==
"mips64r6") {
8021 if (inMicroMipsMode()) {
8022 Error(Loc,
"MIPS64R6 is not supported with microMIPS");
8025 return parseSetFeature(Mips::FeatureMips64r6);
8028 return parseSetFeature(Mips::FeatureDSP);
8029 if (IdVal ==
"dspr2")
8030 return parseSetFeature(Mips::FeatureDSPR2);
8031 if (IdVal ==
"nodsp")
8032 return parseSetNoDspDirective();
8033 if (IdVal ==
"mips3d")
8034 return parseSetFeature(Mips::FeatureMips3D);
8035 if (IdVal ==
"nomips3d")
8036 return parseSetNoMips3DDirective();
8038 return parseSetMsaDirective();
8039 if (IdVal ==
"nomsa")
8040 return parseSetNoMsaDirective();
8042 return parseSetMtDirective();
8043 if (IdVal ==
"nomt")
8044 return parseSetNoMtDirective();
8045 if (IdVal ==
"softfloat")
8046 return parseSetSoftFloatDirective();
8047 if (IdVal ==
"hardfloat")
8048 return parseSetHardFloatDirective();
8050 return parseSetFeature(Mips::FeatureCRC);
8051 if (IdVal ==
"nocrc")
8052 return parseSetNoCRCDirective();
8053 if (IdVal ==
"virt")
8054 return parseSetFeature(Mips::FeatureVirt);
8055 if (IdVal ==
"novirt")
8056 return parseSetNoVirtDirective();
8057 if (IdVal ==
"ginv")
8058 return parseSetFeature(Mips::FeatureGINV);
8059 if (IdVal ==
"noginv")
8060 return parseSetNoGINVDirective();
8063 return parseSetAssignment();
8068bool MipsAsmParser::parseDirectiveGpWord() {
8073 if (getParser().parseExpression(
Value))
8075 getParser().getStreamer().emitGPRel32Value(
Value);
8078 return Error(getLexer().getLoc(),
8079 "unexpected token, expected end of statement");
8086bool MipsAsmParser::parseDirectiveGpDWord() {
8091 if (getParser().parseExpression(
Value))
8093 getParser().getStreamer().emitGPRel64Value(
Value);
8096 return Error(getLexer().getLoc(),
8097 "unexpected token, expected end of statement");
8104bool MipsAsmParser::parseDirectiveDtpRelWord() {
8109 if (getParser().parseExpression(
Value))
8111 getParser().getStreamer().emitDTPRel32Value(
Value);
8114 return Error(getLexer().getLoc(),
8115 "unexpected token, expected end of statement");
8122bool MipsAsmParser::parseDirectiveDtpRelDWord() {
8127 if (getParser().parseExpression(
Value))
8129 getParser().getStreamer().emitDTPRel64Value(
Value);
8132 return Error(getLexer().getLoc(),
8133 "unexpected token, expected end of statement");
8140bool MipsAsmParser::parseDirectiveTpRelWord() {
8145 if (getParser().parseExpression(
Value))
8147 getParser().getStreamer().emitTPRel32Value(
Value);
8150 return Error(getLexer().getLoc(),
8151 "unexpected token, expected end of statement");
8158bool MipsAsmParser::parseDirectiveTpRelDWord() {
8163 if (getParser().parseExpression(
Value))
8165 getParser().getStreamer().emitTPRel64Value(
Value);
8168 return Error(getLexer().getLoc(),
8169 "unexpected token, expected end of statement");
8174bool MipsAsmParser::parseDirectiveOption() {
8181 "unexpected token, expected identifier");
8186 if (Option ==
"pic0") {
8188 IsPicEnabled =
false;
8190 getTargetStreamer().emitDirectiveOptionPic0();
8194 "unexpected token, expected end of statement");
8199 if (Option ==
"pic2") {
8201 IsPicEnabled =
true;
8203 getTargetStreamer().emitDirectiveOptionPic2();
8207 "unexpected token, expected end of statement");
8214 "unknown option, expected 'pic0' or 'pic2'");
8221bool MipsAsmParser::parseInsnDirective() {
8224 reportParseError(
"unexpected token, expected end of statement");
8230 getTargetStreamer().emitDirectiveInsn();
8238bool MipsAsmParser::parseRSectionDirective(
StringRef Section) {
8241 reportParseError(
"unexpected token, expected end of statement");
8245 MCSection *ELFSection = getContext().getELFSection(
8247 getParser().getStreamer().switchSection(ELFSection);
8256bool MipsAsmParser::parseSSectionDirective(
StringRef Section,
unsigned Type) {
8259 reportParseError(
"unexpected token, expected end of statement");
8263 MCSection *ELFSection = getContext().getELFSection(
8265 getParser().getStreamer().switchSection(ELFSection);
8284bool MipsAsmParser::parseDirectiveModule() {
8289 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
8291 reportParseError(
".module directive must appear before any code");
8297 reportParseError(
"expected .module option identifier");
8301 if (Option ==
"oddspreg") {
8302 clearModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
8306 getTargetStreamer().updateABIInfo(*
this);
8311 getTargetStreamer().emitDirectiveModuleOddSPReg();
8315 reportParseError(
"unexpected token, expected end of statement");
8320 }
else if (Option ==
"nooddspreg") {
8322 return Error(L,
"'.module nooddspreg' requires the O32 ABI");
8325 setModuleFeatureBits(Mips::FeatureNoOddSPReg,
"nooddspreg");
8329 getTargetStreamer().updateABIInfo(*
this);
8334 getTargetStreamer().emitDirectiveModuleOddSPReg();
8338 reportParseError(
"unexpected token, expected end of statement");
8343 }
else if (Option ==
"fp") {
8344 return parseDirectiveModuleFP();
8345 }
else if (Option ==
"softfloat") {
8346 setModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
8350 getTargetStreamer().updateABIInfo(*
this);
8355 getTargetStreamer().emitDirectiveModuleSoftFloat();
8359 reportParseError(
"unexpected token, expected end of statement");
8364 }
else if (Option ==
"hardfloat") {
8365 clearModuleFeatureBits(Mips::FeatureSoftFloat,
"soft-float");
8369 getTargetStreamer().updateABIInfo(*
this);
8374 getTargetStreamer().emitDirectiveModuleHardFloat();
8378 reportParseError(
"unexpected token, expected end of statement");
8383 }
else if (Option ==
"mt") {
8384 setModuleFeatureBits(Mips::FeatureMT,
"mt");
8388 getTargetStreamer().updateABIInfo(*
this);
8393 getTargetStreamer().emitDirectiveModuleMT();
8397 reportParseError(
"unexpected token, expected end of statement");
8402 }
else if (Option ==
"crc") {
8403 setModuleFeatureBits(Mips::FeatureCRC,
"crc");
8407 getTargetStreamer().updateABIInfo(*
this);
8412 getTargetStreamer().emitDirectiveModuleCRC();
8416 reportParseError(
"unexpected token, expected end of statement");
8421 }
else if (Option ==
"nocrc") {
8422 clearModuleFeatureBits(Mips::FeatureCRC,
"crc");
8426 getTargetStreamer().updateABIInfo(*
this);
8431 getTargetStreamer().emitDirectiveModuleNoCRC();
8435 reportParseError(
"unexpected token, expected end of statement");
8440 }
else if (Option ==
"virt") {
8441 setModuleFeatureBits(Mips::FeatureVirt,
"virt");
8445 getTargetStreamer().updateABIInfo(*
this);
8450 getTargetStreamer().emitDirectiveModuleVirt();
8454 reportParseError(
"unexpected token, expected end of statement");
8459 }
else if (Option ==
"novirt") {
8460 clearModuleFeatureBits(Mips::FeatureVirt,
"virt");
8464 getTargetStreamer().updateABIInfo(*
this);
8469 getTargetStreamer().emitDirectiveModuleNoVirt();
8473 reportParseError(
"unexpected token, expected end of statement");
8478 }
else if (Option ==
"ginv") {
8479 setModuleFeatureBits(Mips::FeatureGINV,
"ginv");
8483 getTargetStreamer().updateABIInfo(*
this);
8488 getTargetStreamer().emitDirectiveModuleGINV();
8492 reportParseError(
"unexpected token, expected end of statement");
8497 }
else if (Option ==
"noginv") {
8498 clearModuleFeatureBits(Mips::FeatureGINV,
"ginv");
8502 getTargetStreamer().updateABIInfo(*
this);
8507 getTargetStreamer().emitDirectiveModuleNoGINV();
8511 reportParseError(
"unexpected token, expected end of statement");
8517 return Error(L,
"'" +
Twine(Option) +
"' is not a valid .module option.");
8525bool MipsAsmParser::parseDirectiveModuleFP() {
8530 reportParseError(
"unexpected token, expected equals sign '='");
8536 if (!parseFpABIValue(FpABI,
".module"))
8540 reportParseError(
"unexpected token, expected end of statement");
8546 getTargetStreamer().updateABIInfo(*
this);
8551 getTargetStreamer().emitDirectiveModuleFP();
8561 bool ModuleLevelOptions =
Directive ==
".module";
8567 if (
Value !=
"xx") {
8568 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
8573 reportParseError(
"'" +
Directive +
" fp=xx' requires the O32 ABI");
8577 FpABI = MipsABIFlagsSection::FpABIKind::XX;
8578 if (ModuleLevelOptions) {
8579 setModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8580 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8582 setFeatureBits(Mips::FeatureFPXX,
"fpxx");
8583 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8593 reportParseError(
"unsupported value, expected 'xx', '32' or '64'");
8599 reportParseError(
"'" +
Directive +
" fp=32' requires the O32 ABI");
8603 FpABI = MipsABIFlagsSection::FpABIKind::S32;
8604 if (ModuleLevelOptions) {
8605 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8606 clearModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8608 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
8609 clearFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8612 FpABI = MipsABIFlagsSection::FpABIKind::S64;
8613 if (ModuleLevelOptions) {
8614 clearModuleFeatureBits(Mips::FeatureFPXX,
"fpxx");
8615 setModuleFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8617 clearFeatureBits(Mips::FeatureFPXX,
"fpxx");
8618 setFeatureBits(Mips::FeatureFP64Bit,
"fp64");
8628bool MipsAsmParser::ParseDirective(
AsmToken DirectiveID) {
8637 if (IDVal ==
".cpadd") {
8638 parseDirectiveCpAdd(DirectiveID.
getLoc());
8641 if (IDVal ==
".cpload") {
8642 parseDirectiveCpLoad(DirectiveID.
getLoc());
8645 if (IDVal ==
".cprestore") {
8646 parseDirectiveCpRestore(DirectiveID.
getLoc());
8649 if (IDVal ==
".cplocal") {
8650 parseDirectiveCpLocal(DirectiveID.
getLoc());
8653 if (IDVal ==
".ent") {
8657 reportParseError(
"expected identifier after .ent");
8671 reportParseError(
"unexpected token, expected end of statement");
8675 const MCExpr *DummyNumber;
8676 int64_t DummyNumberVal;
8680 reportParseError(
"expected number after comma");
8683 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
8684 reportParseError(
"expected an absolute expression after comma");
8691 reportParseError(
"unexpected token, expected end of statement");
8695 MCSymbol *
Sym = getContext().getOrCreateSymbol(SymbolName);
8697 getTargetStreamer().emitDirectiveEnt(*
Sym);
8699 IsCpRestoreSet =
false;
8703 if (IDVal ==
".end") {
8707 reportParseError(
"expected identifier after .end");
8712 reportParseError(
"unexpected token, expected end of statement");
8716 if (CurrentFn ==
nullptr) {
8717 reportParseError(
".end used without .ent");
8721 if ((SymbolName != CurrentFn->
getName())) {
8722 reportParseError(
".end symbol does not match .ent symbol");
8726 getTargetStreamer().emitDirectiveEnd(SymbolName);
8727 CurrentFn =
nullptr;
8728 IsCpRestoreSet =
false;
8732 if (IDVal ==
".frame") {
8737 reportParseError(
"expected stack register");
8741 MipsOperand &StackRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
8742 if (!StackRegOpnd.isGPRAsmReg()) {
8743 reportParseError(StackRegOpnd.getStartLoc(),
8744 "expected general purpose register");
8747 unsigned StackReg = StackRegOpnd.getGPR32Reg();
8752 reportParseError(
"unexpected token, expected comma");
8758 int64_t FrameSizeVal;
8761 reportParseError(
"expected frame size value");
8765 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
8766 reportParseError(
"frame size not an absolute expression");
8773 reportParseError(
"unexpected token, expected comma");
8779 Res = parseAnyRegister(TmpReg);
8781 reportParseError(
"expected return register");
8785 MipsOperand &ReturnRegOpnd =
static_cast<MipsOperand &
>(*TmpReg[0]);
8786 if (!ReturnRegOpnd.isGPRAsmReg()) {
8787 reportParseError(ReturnRegOpnd.getStartLoc(),
8788 "expected general purpose register");
8794 reportParseError(
"unexpected token, expected end of statement");
8798 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
8799 ReturnRegOpnd.getGPR32Reg());
8800 IsCpRestoreSet =
false;
8804 if (IDVal ==
".set") {
8805 parseDirectiveSet();
8809 if (IDVal ==
".mask" || IDVal ==
".fmask") {
8824 reportParseError(
"expected bitmask value");
8828 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
8829 reportParseError(
"bitmask not an absolute expression");
8836 reportParseError(
"unexpected token, expected comma");
8841 const MCExpr *FrameOffset;
8842 int64_t FrameOffsetVal;
8845 reportParseError(
"expected frame offset value");
8849 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
8850 reportParseError(
"frame offset not an absolute expression");
8856 reportParseError(
"unexpected token, expected end of statement");
8860 if (IDVal ==
".mask")
8861 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
8863 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
8867 if (IDVal ==
".nan")
8868 return parseDirectiveNaN();
8870 if (IDVal ==
".gpword") {
8871 parseDirectiveGpWord();
8875 if (IDVal ==
".gpdword") {
8876 parseDirectiveGpDWord();
8880 if (IDVal ==
".dtprelword") {
8881 parseDirectiveDtpRelWord();
8885 if (IDVal ==
".dtpreldword") {
8886 parseDirectiveDtpRelDWord();
8890 if (IDVal ==
".tprelword") {
8891 parseDirectiveTpRelWord();
8895 if (IDVal ==
".tpreldword") {
8896 parseDirectiveTpRelDWord();
8900 if (IDVal ==
".option") {
8901 parseDirectiveOption();
8905 if (IDVal ==
".abicalls") {
8906 getTargetStreamer().emitDirectiveAbiCalls();
8909 "unexpected token, expected end of statement");
8914 if (IDVal ==
".cpsetup") {
8915 parseDirectiveCPSetup();
8918 if (IDVal ==
".cpreturn") {
8919 parseDirectiveCPReturn();
8922 if (IDVal ==
".module") {
8923 parseDirectiveModule();
8926 if (IDVal ==
".llvm_internal_mips_reallow_module_directive") {
8927 parseInternalDirectiveReallowModule();
8930 if (IDVal ==
".insn") {
8931 parseInsnDirective();
8934 if (IDVal ==
".rdata") {
8935 parseRSectionDirective(
".rodata");
8938 if (IDVal ==
".sbss") {
8942 if (IDVal ==
".sdata") {
8950bool MipsAsmParser::parseInternalDirectiveReallowModule() {
8953 reportParseError(
"unexpected token, expected end of statement");
8957 getTargetStreamer().reallowModuleDirective();
8970#define GET_REGISTER_MATCHER
8971#define GET_MATCHER_IMPLEMENTATION
8972#define GET_MNEMONIC_SPELL_CHECKER
8973#include "MipsGenAsmMatcher.inc"
8975bool MipsAsmParser::mnemonicIsValid(
StringRef Mnemonic,
unsigned VariantID) {
8977 const MatchEntry *Start, *
End;
8978 switch (VariantID) {
8980 case 0: Start = std::begin(MatchTable0);
End = std::end(MatchTable0);
break;
8983 auto MnemonicRange = std::equal_range(Start,
End, Mnemonic, LessOpcode());
8984 return MnemonicRange.first != MnemonicRange.second;
static const TargetRegisterClass * getRegClass(const MachineInstr &MI, Register Reg)
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 ARMBaseTargetMachine::ARMABI computeTargetABI(const Triple &TT, StringRef CPU, const TargetOptions &Options)
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Analysis containing CSE Info
#define LLVM_EXTERNAL_VISIBILITY
std::optional< std::vector< StOtherPiece > > Other
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
static FeatureBitset getFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS, ArrayRef< SubtargetSubTypeKV > ProcDesc, ArrayRef< SubtargetFeatureKV > ProcFeatures)
mir Rename Register Operands
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)
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsAsmParser()
static unsigned getRegisterForMxtrDSP(MCInst &Inst, bool IsMFDSP)
static unsigned nextReg(unsigned Reg)
static bool hasShortDelaySlot(MCInst &Inst)
static bool needsExpandMemInst(MCInst &Inst, const MCInstrDesc &MCID)
cl::opt< bool > EmitJalrReloc
static bool isShiftedUIntAtAnyPosition(uint64_t x)
Can the value be represented by a unsigned N-bit value and a shift left?
static bool isEvaluated(const MCExpr *Expr)
static unsigned getRegisterForMxtrC0(MCInst &Inst, bool IsMFTC0)
static const MCSymbol * getSingleMCSymbol(const MCExpr *Expr)
static unsigned getRegisterForMxtrFP(MCInst &Inst, bool IsMFTC1)
static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands, uint64_t ErrorInfo)
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isImm(const MachineOperand &MO, MachineRegisterInfo *MRI)
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
APInt bitcastToAPInt() const
uint64_t getZExtValue() const
Get zero extended value.
Target independent representation for an assembler token.
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
SMRange getLocRange() const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
This class represents an Operation in the Expression.
Base class for user error types.
Lightweight error class with error context and mandatory checking.
Container class for subtarget features.
Generic assembler lexer interface, for use by target specific assembly lexers.
const AsmToken peekTok(bool ShouldSkipSpace=true)
Look ahead at the next token to be lexed.
bool isNot(AsmToken::TokenKind K) const
Check if the current token has kind K.
SMLoc getLoc() const
Get the current source location.
bool is(AsmToken::TokenKind K) const
Check if the current token has kind K.
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
MCStreamer & getStreamer()
MCAsmParser & getParser()
Generic assembler parser interface, for use by target specific assembly parsers.
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
virtual MCStreamer & getStreamer()=0
Return the output streamer for the assembler.
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 MCAsmLexer & getLexer()=0
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 const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
@ LShr
Logical shift right.
@ Xor
Bitwise exclusive or.
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
const MCObjectFileInfo * getObjectFileInfo() const
Base class for the full range of assembler expressions which are needed for parsing.
@ Unary
Unary expressions.
@ Constant
Constant expressions.
@ SymbolRef
References to labels and assigned expressions.
@ Target
Target specific expression.
@ Binary
Binary expressions.
bool evaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout, const MCFixup *Fixup) const
Try to evaluate the expression to a relocatable value, i.e.
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.
bool isPositionIndependent() const
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 createReg(unsigned Reg)
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createImm(int64_t Val)
unsigned getReg() const
Returns the register number.
const MCExpr * getExpr() const
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual unsigned getReg() const =0
virtual bool isReg() const =0
isReg - Is this a register operand?
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Wrapper class representing physical registers. Should be passed by value.
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Streaming machine code generation interface.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
MCContext & getContext() const
virtual std::optional< std::pair< bool, std::string > > emitRelocDirective(const MCExpr &Offset, StringRef Name, const MCExpr *Expr, SMLoc Loc, const MCSubtargetInfo &STI)
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.
MCTargetStreamer * getTargetStreamer()
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
FeatureBitset ToggleFeature(uint64_t FB)
Toggle a feature and return the re-computed feature bits.
Represent a reference to a symbol from inside an expression.
const MCSymbol & getSymbol() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
VariantKind getKind() const
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).
StringRef getName() const
getName - Get the symbol name.
bool isTemporary() const
isTemporary - Check if this is an assembler temporary symbol.
MCTargetAsmParser - Generic interface to target specific assembly parsers.
MCSubtargetInfo & copySTI()
Create a copy of STI and return a non-const reference to it.
@ FIRST_TARGET_MATCH_RESULT_TY
virtual bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
virtual bool ParseDirective(AsmToken DirectiveID)
ParseDirective - Parse a target specific assembler directive This method is deprecated,...
virtual unsigned checkEarlyTargetMatchPredicate(MCInst &Inst, const OperandVector &Operands)
Validate the instruction match against any complex target predicates before rendering any operands to...
virtual ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
tryParseRegister - parse one register if possible
virtual void onEndOfFile()
void setAvailableFeatures(const FeatureBitset &Value)
const MCSubtargetInfo & getSTI() const
virtual const MCExpr * createTargetUnaryExpr(const MCExpr *E, AsmToken::TokenKind OperatorToken, MCContext &Ctx)
virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands)=0
ParseInstruction - Parse one assembly instruction.
virtual unsigned checkTargetMatchPredicate(MCInst &Inst)
checkTargetMatchPredicate - Validate the instruction match against any complex target predicates not ...
virtual bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm)=0
MatchAndEmitInstruction - Recognize a series of operands of a parsed instruction as an actual MCInst ...
virtual bool areEqualRegs(const MCParsedAsmOperand &Op1, const MCParsedAsmOperand &Op2) const
Returns whether two operands are registers and are equal.
Target specific streamer interface.
MCStreamer & getStreamer()
Unary assembler expressions.
This represents an "assembler immediate".
int64_t getConstant() const
const MCSymbolRefExpr * getSymB() const
const MCSymbolRefExpr * getSymA() const
static const MipsMCExpr * create(MipsExprKind Kind, const MCExpr *Expr, MCContext &Ctx)
virtual void emitDirectiveSetReorder()
void emitRRIII(unsigned Opcode, unsigned Reg0, unsigned Reg1, int16_t Imm0, int16_t Imm1, int16_t Imm2, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1, int16_t Imm, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRX(unsigned Opcode, unsigned Reg0, MCOperand Op1, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitR(unsigned Opcode, unsigned Reg0, SMLoc IDLoc, const MCSubtargetInfo *STI)
virtual void setUsesMicroMips()
void emitEmptyDelaySlot(bool hasShortDelaySlot, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1, MCOperand Op2, SMLoc IDLoc, const MCSubtargetInfo *STI)
void updateABIInfo(const PredicateLibrary &P)
void emitRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRI(unsigned Opcode, unsigned Reg0, int32_t Imm, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, unsigned Reg2, SMLoc IDLoc, const MCSubtargetInfo *STI)
void emitRRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1, unsigned Reg2, MCOperand Op3, 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)
virtual void emitDirectiveSetNoReorder()
void emitDSLL(unsigned DstReg, unsigned SrcReg, int16_t ShiftAmount, SMLoc IDLoc, const MCSubtargetInfo *STI)
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
Represents a single fixit, a replacement of one range of text with another.
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
Represents a range in source code.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StackOffset holds a fixed and a scalable offset in bytes.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
iterator find(StringRef Key)
StringRef - 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
empty - Check if the string is empty.
StringRef trim(char Char) const
Return string with consecutive Char characters starting from the left and right removed.
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
StringSwitch & Cases(StringLiteral S0, StringLiteral S1, T Value)
Triple - Helper class for working with autoconf configuration names.
bool isLittleEndian() const
Tests whether the target triple is little endian.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
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.
@ IsCTI
IsCTI - Instruction is a Control Transfer Instruction.
@ HasFCCRegOperand
HasFCCRegOperand - Instruction uses an $fcc<x> register.
@ HasForbiddenSlot
HasForbiddenSlot - Instruction has a forbidden slot.
@ CE
Windows NT (Windows on ARM)
This is an optimization pass for GlobalISel generic memory operations.
Target & getTheMips64Target()
static bool isMem(const MachineInstr &MI, unsigned Op)
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.
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
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.
bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
Target & getTheMipselTarget()
DWARFExpression::Operation Op
constexpr unsigned BitWidth
Target & getTheMipsTarget()
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Description of the encoding of one expression Op.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...