1 //===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "MCTargetDesc/MipsABIInfo.h"
11 #include "MCTargetDesc/MipsMCExpr.h"
12 #include "MCTargetDesc/MipsMCTargetDesc.h"
13 #include "MipsRegisterInfo.h"
14 #include "MipsTargetObjectFile.h"
15 #include "MipsTargetStreamer.h"
16 #include "llvm/ADT/APInt.h"
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/ADT/StringSwitch.h"
19 #include "llvm/MC/MCContext.h"
20 #include "llvm/MC/MCExpr.h"
21 #include "llvm/MC/MCInst.h"
22 #include "llvm/MC/MCInstBuilder.h"
23 #include "llvm/MC/MCParser/MCAsmLexer.h"
24 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
25 #include "llvm/MC/MCStreamer.h"
26 #include "llvm/MC/MCSubtargetInfo.h"
27 #include "llvm/MC/MCSymbol.h"
28 #include "llvm/MC/MCTargetAsmParser.h"
29 #include "llvm/Support/Debug.h"
30 #include "llvm/Support/MathExtras.h"
31 #include "llvm/Support/SourceMgr.h"
32 #include "llvm/Support/TargetRegistry.h"
33 #include "llvm/Support/raw_ostream.h"
38 #define DEBUG_TYPE "mips-asm-parser"
45 class MipsAssemblerOptions {
47 MipsAssemblerOptions(const FeatureBitset &Features_) :
48 ATReg(1), Reorder(true), Macro(true), Features(Features_) {}
50 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
51 ATReg = Opts->getATRegIndex();
52 Reorder = Opts->isReorder();
53 Macro = Opts->isMacro();
54 Features = Opts->getFeatures();
57 unsigned getATRegIndex() const { return ATReg; }
58 bool setATRegIndex(unsigned Reg) {
66 bool isReorder() const { return Reorder; }
67 void setReorder() { Reorder = true; }
68 void setNoReorder() { Reorder = false; }
70 bool isMacro() const { return Macro; }
71 void setMacro() { Macro = true; }
72 void setNoMacro() { Macro = false; }
74 const FeatureBitset &getFeatures() const { return Features; }
75 void setFeatures(const FeatureBitset &Features_) { Features = Features_; }
77 // Set of features that are either architecture features or referenced
78 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
79 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
80 // The reason we need this mask is explained in the selectArch function.
81 // FIXME: Ideally we would like TableGen to generate this information.
82 static const FeatureBitset AllArchRelatedMask;
88 FeatureBitset Features;
92 const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
93 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
94 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
95 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
96 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
97 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
98 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
99 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
100 Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008
104 class MipsAsmParser : public MCTargetAsmParser {
105 MipsTargetStreamer &getTargetStreamer() {
106 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
107 return static_cast<MipsTargetStreamer &>(TS);
111 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
112 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
113 // nullptr, which indicates that no function is currently
114 // selected. This usually happens after an '.end func'
120 unsigned CpSaveLocation;
121 /// If true, then CpSaveLocation is a register, otherwise it's an offset.
122 bool CpSaveLocationIsRegister;
124 // Print a warning along with its fix-it message at the given range.
125 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
126 SMRange Range, bool ShowColors = true);
128 #define GET_ASSEMBLER_HEADER
129 #include "MipsGenAsmMatcher.inc"
131 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
133 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
134 OperandVector &Operands, MCStreamer &Out,
136 bool MatchingInlineAsm) override;
138 /// Parse a register as used in CFI directives
139 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
141 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
143 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
145 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
146 SMLoc NameLoc, OperandVector &Operands) override;
148 bool ParseDirective(AsmToken DirectiveID) override;
150 OperandMatchResultTy parseMemOperand(OperandVector &Operands);
152 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
153 StringRef Identifier, SMLoc S);
154 OperandMatchResultTy matchAnyRegisterWithoutDollar(OperandVector &Operands,
156 OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
157 OperandMatchResultTy parseImm(OperandVector &Operands);
158 OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
159 OperandMatchResultTy parseInvNum(OperandVector &Operands);
160 OperandMatchResultTy parseLSAImm(OperandVector &Operands);
161 OperandMatchResultTy parseRegisterPair(OperandVector &Operands);
162 OperandMatchResultTy parseMovePRegPair(OperandVector &Operands);
163 OperandMatchResultTy parseRegisterList(OperandVector &Operands);
165 bool searchSymbolAlias(OperandVector &Operands);
167 bool parseOperand(OperandVector &, StringRef Mnemonic);
169 enum MacroExpanderResultTy {
175 // Expands assembly pseudo instructions.
176 MacroExpanderResultTy
177 tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
178 SmallVectorImpl<MCInst> &Instructions);
180 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
181 SmallVectorImpl<MCInst> &Instructions);
183 bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
184 bool Is32BitImm, bool IsAddress, SMLoc IDLoc,
185 SmallVectorImpl<MCInst> &Instructions);
187 bool loadAndAddSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
188 unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc,
189 SmallVectorImpl<MCInst> &Instructions);
191 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
192 SmallVectorImpl<MCInst> &Instructions);
194 bool expandLoadAddress(unsigned DstReg, unsigned BaseReg,
195 const MCOperand &Offset, bool Is32BitAddress,
196 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions);
198 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
199 SmallVectorImpl<MCInst> &Instructions);
201 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
202 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
205 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
206 SmallVectorImpl<MCInst> &Instructions);
208 bool expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
209 SmallVectorImpl<MCInst> &Instructions);
211 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc,
212 SmallVectorImpl<MCInst> &Instructions);
214 bool expandCondBranches(MCInst &Inst, SMLoc IDLoc,
215 SmallVectorImpl<MCInst> &Instructions);
217 bool expandDiv(MCInst &Inst, SMLoc IDLoc,
218 SmallVectorImpl<MCInst> &Instructions, const bool IsMips64,
221 bool expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
222 SmallVectorImpl<MCInst> &Instructions);
224 bool expandUlw(MCInst &Inst, SMLoc IDLoc,
225 SmallVectorImpl<MCInst> &Instructions);
227 void createNop(bool hasShortDelaySlot, SMLoc IDLoc,
228 SmallVectorImpl<MCInst> &Instructions);
230 void createAddu(unsigned DstReg, unsigned SrcReg, unsigned TrgReg,
231 bool Is64Bit, SmallVectorImpl<MCInst> &Instructions);
233 void createCpRestoreMemOp(bool IsLoad, int StackOffset, SMLoc IDLoc,
234 SmallVectorImpl<MCInst> &Instructions);
236 bool reportParseError(Twine ErrorMsg);
237 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
239 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
240 bool parseRelocOperand(const MCExpr *&Res);
242 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
244 bool isEvaluated(const MCExpr *Expr);
245 bool parseSetMips0Directive();
246 bool parseSetArchDirective();
247 bool parseSetFeature(uint64_t Feature);
248 bool isPicAndNotNxxAbi(); // Used by .cpload, .cprestore, and .cpsetup.
249 bool parseDirectiveCpLoad(SMLoc Loc);
250 bool parseDirectiveCpRestore(SMLoc Loc);
251 bool parseDirectiveCPSetup();
252 bool parseDirectiveCPReturn();
253 bool parseDirectiveNaN();
254 bool parseDirectiveSet();
255 bool parseDirectiveOption();
256 bool parseInsnDirective();
258 bool parseSetAtDirective();
259 bool parseSetNoAtDirective();
260 bool parseSetMacroDirective();
261 bool parseSetNoMacroDirective();
262 bool parseSetMsaDirective();
263 bool parseSetNoMsaDirective();
264 bool parseSetNoDspDirective();
265 bool parseSetReorderDirective();
266 bool parseSetNoReorderDirective();
267 bool parseSetMips16Directive();
268 bool parseSetNoMips16Directive();
269 bool parseSetFpDirective();
270 bool parseSetOddSPRegDirective();
271 bool parseSetNoOddSPRegDirective();
272 bool parseSetPopDirective();
273 bool parseSetPushDirective();
274 bool parseSetSoftFloatDirective();
275 bool parseSetHardFloatDirective();
277 bool parseSetAssignment();
279 bool parseDataDirective(unsigned Size, SMLoc L);
280 bool parseDirectiveGpWord();
281 bool parseDirectiveGpDWord();
282 bool parseDirectiveModule();
283 bool parseDirectiveModuleFP();
284 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
285 StringRef Directive);
287 bool parseInternalDirectiveReallowModule();
289 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
291 bool eatComma(StringRef ErrorStr);
293 int matchCPURegisterName(StringRef Symbol);
295 int matchHWRegsRegisterName(StringRef Symbol);
297 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
299 int matchFPURegisterName(StringRef Name);
301 int matchFCCRegisterName(StringRef Name);
303 int matchACRegisterName(StringRef Name);
305 int matchMSA128RegisterName(StringRef Name);
307 int matchMSA128CtrlRegisterName(StringRef Name);
309 unsigned getReg(int RC, int RegNo);
311 unsigned getGPR(int RegNo);
313 /// Returns the internal register number for the current AT. Also checks if
314 /// the current AT is unavailable (set to $0) and gives an error if it is.
315 /// This should be used in pseudo-instruction expansions which need AT.
316 unsigned getATReg(SMLoc Loc);
318 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
319 SmallVectorImpl<MCInst> &Instructions);
321 // Helper function that checks if the value of a vector index is within the
322 // boundaries of accepted values for each RegisterKind
323 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
324 bool validateMSAIndex(int Val, int RegKind);
326 // Selects a new architecture by updating the FeatureBits with the necessary
327 // info including implied dependencies.
328 // Internally, it clears all the feature bits related to *any* architecture
329 // and selects the new one using the ToggleFeature functionality of the
330 // MCSubtargetInfo object that handles implied dependencies. The reason we
331 // clear all the arch related bits manually is because ToggleFeature only
332 // clears the features that imply the feature being cleared and not the
333 // features implied by the feature being cleared. This is easier to see
335 // --------------------------------------------------
336 // | Feature | Implies |
337 // | -------------------------------------------------|
338 // | FeatureMips1 | None |
339 // | FeatureMips2 | FeatureMips1 |
340 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
341 // | FeatureMips4 | FeatureMips3 |
343 // --------------------------------------------------
345 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
346 // FeatureMipsGP64 | FeatureMips1)
347 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
348 void selectArch(StringRef ArchFeature) {
349 FeatureBitset FeatureBits = STI.getFeatureBits();
350 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
351 STI.setFeatureBits(FeatureBits);
352 setAvailableFeatures(
353 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
354 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
357 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
358 if (!(getSTI().getFeatureBits()[Feature])) {
359 setAvailableFeatures(
360 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
361 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
365 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
366 if (getSTI().getFeatureBits()[Feature]) {
367 setAvailableFeatures(
368 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
369 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
373 void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
374 setFeatureBits(Feature, FeatureString);
375 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
378 void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
379 clearFeatureBits(Feature, FeatureString);
380 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
384 enum MipsMatchResultTy {
385 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
386 #define GET_OPERAND_DIAGNOSTIC_TYPES
387 #include "MipsGenAsmMatcher.inc"
388 #undef GET_OPERAND_DIAGNOSTIC_TYPES
391 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
392 const MCInstrInfo &MII, const MCTargetOptions &Options)
393 : MCTargetAsmParser(Options, sti),
394 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
395 sti.getCPU(), Options)) {
396 MCAsmParserExtension::Initialize(parser);
398 parser.addAliasForDirective(".asciiz", ".asciz");
400 // Initialize the set of available features.
401 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
403 // Remember the initial assembler options. The user can not modify these.
404 AssemblerOptions.push_back(
405 llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
407 // Create an assembler options environment for the user to modify.
408 AssemblerOptions.push_back(
409 llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
411 getTargetStreamer().updateABIInfo(*this);
413 if (!isABI_O32() && !useOddSPReg() != 0)
414 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
419 (getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_);
421 IsCpRestoreSet = false;
422 CpRestoreOffset = -1;
424 Triple TheTriple(sti.getTargetTriple());
425 if ((TheTriple.getArch() == Triple::mips) ||
426 (TheTriple.getArch() == Triple::mips64))
427 IsLittleEndian = false;
429 IsLittleEndian = true;
432 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
433 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
435 bool isGP64bit() const {
436 return getSTI().getFeatureBits()[Mips::FeatureGP64Bit];
438 bool isFP64bit() const {
439 return getSTI().getFeatureBits()[Mips::FeatureFP64Bit];
441 const MipsABIInfo &getABI() const { return ABI; }
442 bool isABI_N32() const { return ABI.IsN32(); }
443 bool isABI_N64() const { return ABI.IsN64(); }
444 bool isABI_O32() const { return ABI.IsO32(); }
445 bool isABI_FPXX() const {
446 return getSTI().getFeatureBits()[Mips::FeatureFPXX];
449 bool useOddSPReg() const {
450 return !(getSTI().getFeatureBits()[Mips::FeatureNoOddSPReg]);
453 bool inMicroMipsMode() const {
454 return getSTI().getFeatureBits()[Mips::FeatureMicroMips];
456 bool hasMips1() const {
457 return getSTI().getFeatureBits()[Mips::FeatureMips1];
459 bool hasMips2() const {
460 return getSTI().getFeatureBits()[Mips::FeatureMips2];
462 bool hasMips3() const {
463 return getSTI().getFeatureBits()[Mips::FeatureMips3];
465 bool hasMips4() const {
466 return getSTI().getFeatureBits()[Mips::FeatureMips4];
468 bool hasMips5() const {
469 return getSTI().getFeatureBits()[Mips::FeatureMips5];
471 bool hasMips32() const {
472 return getSTI().getFeatureBits()[Mips::FeatureMips32];
474 bool hasMips64() const {
475 return getSTI().getFeatureBits()[Mips::FeatureMips64];
477 bool hasMips32r2() const {
478 return getSTI().getFeatureBits()[Mips::FeatureMips32r2];
480 bool hasMips64r2() const {
481 return getSTI().getFeatureBits()[Mips::FeatureMips64r2];
483 bool hasMips32r3() const {
484 return (getSTI().getFeatureBits()[Mips::FeatureMips32r3]);
486 bool hasMips64r3() const {
487 return (getSTI().getFeatureBits()[Mips::FeatureMips64r3]);
489 bool hasMips32r5() const {
490 return (getSTI().getFeatureBits()[Mips::FeatureMips32r5]);
492 bool hasMips64r5() const {
493 return (getSTI().getFeatureBits()[Mips::FeatureMips64r5]);
495 bool hasMips32r6() const {
496 return getSTI().getFeatureBits()[Mips::FeatureMips32r6];
498 bool hasMips64r6() const {
499 return getSTI().getFeatureBits()[Mips::FeatureMips64r6];
502 bool hasDSP() const {
503 return getSTI().getFeatureBits()[Mips::FeatureDSP];
505 bool hasDSPR2() const {
506 return getSTI().getFeatureBits()[Mips::FeatureDSPR2];
508 bool hasDSPR3() const {
509 return getSTI().getFeatureBits()[Mips::FeatureDSPR3];
511 bool hasMSA() const {
512 return getSTI().getFeatureBits()[Mips::FeatureMSA];
514 bool hasCnMips() const {
515 return (getSTI().getFeatureBits()[Mips::FeatureCnMips]);
522 bool inMips16Mode() const {
523 return getSTI().getFeatureBits()[Mips::FeatureMips16];
526 bool useTraps() const {
527 return getSTI().getFeatureBits()[Mips::FeatureUseTCCInDIV];
530 bool useSoftFloat() const {
531 return getSTI().getFeatureBits()[Mips::FeatureSoftFloat];
534 /// Warn if RegIndex is the same as the current AT.
535 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
537 void warnIfNoMacro(SMLoc Loc);
539 bool isLittle() const { return IsLittleEndian; }
545 /// MipsOperand - Instances of this class represent a parsed Mips machine
547 class MipsOperand : public MCParsedAsmOperand {
549 /// Broad categories of register classes
550 /// The exact class is finalized by the render method.
552 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
553 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
555 RegKind_FCC = 4, /// FCC
556 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
557 RegKind_MSACtrl = 16, /// MSA control registers
558 RegKind_COP2 = 32, /// COP2
559 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
561 RegKind_CCR = 128, /// CCR
562 RegKind_HWRegs = 256, /// HWRegs
563 RegKind_COP3 = 512, /// COP3
564 RegKind_COP0 = 1024, /// COP0
565 /// Potentially any (e.g. $1)
566 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
567 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
568 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
573 k_Immediate, /// An immediate (possibly involving symbol references)
574 k_Memory, /// Base + Offset Memory Address
575 k_PhysRegister, /// A physical register from the Mips namespace
576 k_RegisterIndex, /// A register index in one or more RegKind.
577 k_Token, /// A simple token
578 k_RegList, /// A physical register list
579 k_RegPair /// A pair of physical register
583 MipsOperand(KindTy K, MipsAsmParser &Parser)
584 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
587 /// For diagnostics, and checking the assembler temporary
588 MipsAsmParser &AsmParser;
596 unsigned Num; /// Register Number
600 unsigned Index; /// Index into the register class
601 RegKind Kind; /// Bitfield of the kinds it could possibly be
602 const MCRegisterInfo *RegInfo;
615 SmallVector<unsigned, 10> *List;
620 struct PhysRegOp PhysReg;
621 struct RegIdxOp RegIdx;
624 struct RegListOp RegList;
627 SMLoc StartLoc, EndLoc;
629 /// Internal constructor for register kinds
630 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
631 const MCRegisterInfo *RegInfo,
633 MipsAsmParser &Parser) {
634 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
635 Op->RegIdx.Index = Index;
636 Op->RegIdx.RegInfo = RegInfo;
637 Op->RegIdx.Kind = RegKind;
644 /// Coerce the register to GPR32 and return the real register for the current
646 unsigned getGPR32Reg() const {
647 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
648 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
649 unsigned ClassID = Mips::GPR32RegClassID;
650 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
653 /// Coerce the register to GPR32 and return the real register for the current
655 unsigned getGPRMM16Reg() const {
656 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
657 unsigned ClassID = Mips::GPR32RegClassID;
658 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
661 /// Coerce the register to GPR64 and return the real register for the current
663 unsigned getGPR64Reg() const {
664 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
665 unsigned ClassID = Mips::GPR64RegClassID;
666 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
670 /// Coerce the register to AFGR64 and return the real register for the current
672 unsigned getAFGR64Reg() const {
673 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
674 if (RegIdx.Index % 2 != 0)
675 AsmParser.Warning(StartLoc, "Float register should be even.");
676 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
677 .getRegister(RegIdx.Index / 2);
680 /// Coerce the register to FGR64 and return the real register for the current
682 unsigned getFGR64Reg() const {
683 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
684 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
685 .getRegister(RegIdx.Index);
688 /// Coerce the register to FGR32 and return the real register for the current
690 unsigned getFGR32Reg() const {
691 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
692 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
693 .getRegister(RegIdx.Index);
696 /// Coerce the register to FGRH32 and return the real register for the current
698 unsigned getFGRH32Reg() const {
699 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
700 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
701 .getRegister(RegIdx.Index);
704 /// Coerce the register to FCC and return the real register for the current
706 unsigned getFCCReg() const {
707 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
708 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
709 .getRegister(RegIdx.Index);
712 /// Coerce the register to MSA128 and return the real register for the current
714 unsigned getMSA128Reg() const {
715 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
716 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
718 unsigned ClassID = Mips::MSA128BRegClassID;
719 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
722 /// Coerce the register to MSACtrl and return the real register for the
724 unsigned getMSACtrlReg() const {
725 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
726 unsigned ClassID = Mips::MSACtrlRegClassID;
727 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
730 /// Coerce the register to COP0 and return the real register for the
732 unsigned getCOP0Reg() const {
733 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!");
734 unsigned ClassID = Mips::COP0RegClassID;
735 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
738 /// Coerce the register to COP2 and return the real register for the
740 unsigned getCOP2Reg() const {
741 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
742 unsigned ClassID = Mips::COP2RegClassID;
743 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
746 /// Coerce the register to COP3 and return the real register for the
748 unsigned getCOP3Reg() const {
749 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
750 unsigned ClassID = Mips::COP3RegClassID;
751 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
754 /// Coerce the register to ACC64DSP and return the real register for the
756 unsigned getACC64DSPReg() const {
757 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
758 unsigned ClassID = Mips::ACC64DSPRegClassID;
759 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
762 /// Coerce the register to HI32DSP and return the real register for the
764 unsigned getHI32DSPReg() const {
765 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
766 unsigned ClassID = Mips::HI32DSPRegClassID;
767 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
770 /// Coerce the register to LO32DSP and return the real register for the
772 unsigned getLO32DSPReg() const {
773 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
774 unsigned ClassID = Mips::LO32DSPRegClassID;
775 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
778 /// Coerce the register to CCR and return the real register for the
780 unsigned getCCRReg() const {
781 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
782 unsigned ClassID = Mips::CCRRegClassID;
783 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
786 /// Coerce the register to HWRegs and return the real register for the
788 unsigned getHWRegsReg() const {
789 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
790 unsigned ClassID = Mips::HWRegsRegClassID;
791 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
795 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
796 // Add as immediate when possible. Null MCExpr = 0.
798 Inst.addOperand(MCOperand::createImm(0));
799 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
800 Inst.addOperand(MCOperand::createImm(CE->getValue()));
802 Inst.addOperand(MCOperand::createExpr(Expr));
805 void addRegOperands(MCInst &Inst, unsigned N) const {
806 llvm_unreachable("Use a custom parser instead");
809 /// Render the operand to an MCInst as a GPR32
810 /// Asserts if the wrong number of operands are requested, or the operand
811 /// is not a k_RegisterIndex compatible with RegKind_GPR
812 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
813 assert(N == 1 && "Invalid number of operands!");
814 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
817 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
818 assert(N == 1 && "Invalid number of operands!");
819 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
822 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
823 assert(N == 1 && "Invalid number of operands!");
824 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
827 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
828 assert(N == 1 && "Invalid number of operands!");
829 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
832 /// Render the operand to an MCInst as a GPR64
833 /// Asserts if the wrong number of operands are requested, or the operand
834 /// is not a k_RegisterIndex compatible with RegKind_GPR
835 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
836 assert(N == 1 && "Invalid number of operands!");
837 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
840 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
841 assert(N == 1 && "Invalid number of operands!");
842 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
845 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
846 assert(N == 1 && "Invalid number of operands!");
847 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
850 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
851 assert(N == 1 && "Invalid number of operands!");
852 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
853 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
854 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
855 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
859 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
860 assert(N == 1 && "Invalid number of operands!");
861 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
864 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
865 assert(N == 1 && "Invalid number of operands!");
866 Inst.addOperand(MCOperand::createReg(getFCCReg()));
869 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
870 assert(N == 1 && "Invalid number of operands!");
871 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
874 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
875 assert(N == 1 && "Invalid number of operands!");
876 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
879 void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
880 assert(N == 1 && "Invalid number of operands!");
881 Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
884 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
885 assert(N == 1 && "Invalid number of operands!");
886 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
889 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
890 assert(N == 1 && "Invalid number of operands!");
891 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
894 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
895 assert(N == 1 && "Invalid number of operands!");
896 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
899 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
900 assert(N == 1 && "Invalid number of operands!");
901 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
904 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
905 assert(N == 1 && "Invalid number of operands!");
906 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
909 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
910 assert(N == 1 && "Invalid number of operands!");
911 Inst.addOperand(MCOperand::createReg(getCCRReg()));
914 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
915 assert(N == 1 && "Invalid number of operands!");
916 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
919 template <unsigned Bits, int Offset = 0>
920 void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
921 assert(N == 1 && "Invalid number of operands!");
922 uint64_t Imm = getConstantImm() - Offset;
923 Imm &= (1 << Bits) - 1;
925 Inst.addOperand(MCOperand::createImm(Imm));
928 void addImmOperands(MCInst &Inst, unsigned N) const {
929 assert(N == 1 && "Invalid number of operands!");
930 const MCExpr *Expr = getImm();
934 void addMemOperands(MCInst &Inst, unsigned N) const {
935 assert(N == 2 && "Invalid number of operands!");
937 Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
938 ? getMemBase()->getGPR64Reg()
939 : getMemBase()->getGPR32Reg()));
941 const MCExpr *Expr = getMemOff();
945 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
946 assert(N == 2 && "Invalid number of operands!");
948 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
950 const MCExpr *Expr = getMemOff();
954 void addRegListOperands(MCInst &Inst, unsigned N) const {
955 assert(N == 1 && "Invalid number of operands!");
957 for (auto RegNo : getRegList())
958 Inst.addOperand(MCOperand::createReg(RegNo));
961 void addRegPairOperands(MCInst &Inst, unsigned N) const {
962 assert(N == 2 && "Invalid number of operands!");
963 unsigned RegNo = getRegPair();
964 Inst.addOperand(MCOperand::createReg(RegNo++));
965 Inst.addOperand(MCOperand::createReg(RegNo));
968 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
969 assert(N == 2 && "Invalid number of operands!");
970 for (auto RegNo : getRegList())
971 Inst.addOperand(MCOperand::createReg(RegNo));
974 bool isReg() const override {
975 // As a special case until we sort out the definition of div/divu, pretend
976 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
977 if (isGPRAsmReg() && RegIdx.Index == 0)
980 return Kind == k_PhysRegister;
982 bool isRegIdx() const { return Kind == k_RegisterIndex; }
983 bool isImm() const override { return Kind == k_Immediate; }
984 bool isConstantImm() const {
985 return isImm() && dyn_cast<MCConstantExpr>(getImm());
987 bool isConstantImmz() const {
988 return isConstantImm() && getConstantImm() == 0;
990 template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
991 return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
993 template <unsigned Bits> bool isUImm() const {
994 return isImm() && isConstantImm() && isUInt<Bits>(getConstantImm());
996 bool isToken() const override {
997 // Note: It's not possible to pretend that other operand kinds are tokens.
998 // The matcher emitter checks tokens first.
999 return Kind == k_Token;
1001 bool isMem() const override { return Kind == k_Memory; }
1002 bool isConstantMemOff() const {
1003 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
1005 template <unsigned Bits> bool isMemWithSimmOffset() const {
1006 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
1007 && getMemBase()->isGPRAsmReg();
1009 template <unsigned Bits> bool isMemWithSimmOffsetGPR() const {
1010 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff()) &&
1011 getMemBase()->isGPRAsmReg();
1013 bool isMemWithGRPMM16Base() const {
1014 return isMem() && getMemBase()->isMM16AsmReg();
1016 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
1017 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1018 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1020 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
1021 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1022 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1023 && (getMemBase()->getGPR32Reg() == Mips::SP);
1025 bool isUImm5Lsl2() const {
1026 return (isImm() && isConstantImm() && isShiftedUInt<5, 2>(getConstantImm()));
1028 bool isRegList16() const {
1032 int Size = RegList.List->size();
1033 if (Size < 2 || Size > 5)
1036 unsigned R0 = RegList.List->front();
1037 unsigned R1 = RegList.List->back();
1038 if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1039 (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1042 int PrevReg = *RegList.List->begin();
1043 for (int i = 1; i < Size - 1; i++) {
1044 int Reg = (*(RegList.List))[i];
1045 if ( Reg != PrevReg + 1)
1052 bool isInvNum() const { return Kind == k_Immediate; }
1053 bool isLSAImm() const {
1054 if (!isConstantImm())
1056 int64_t Val = getConstantImm();
1057 return 1 <= Val && Val <= 4;
1059 bool isRegList() const { return Kind == k_RegList; }
1060 bool isMovePRegPair() const {
1061 if (Kind != k_RegList || RegList.List->size() != 2)
1064 unsigned R0 = RegList.List->front();
1065 unsigned R1 = RegList.List->back();
1067 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
1068 (R0 == Mips::A1 && R1 == Mips::A3) ||
1069 (R0 == Mips::A2 && R1 == Mips::A3) ||
1070 (R0 == Mips::A0 && R1 == Mips::S5) ||
1071 (R0 == Mips::A0 && R1 == Mips::S6) ||
1072 (R0 == Mips::A0 && R1 == Mips::A1) ||
1073 (R0 == Mips::A0 && R1 == Mips::A2) ||
1074 (R0 == Mips::A0 && R1 == Mips::A3))
1080 StringRef getToken() const {
1081 assert(Kind == k_Token && "Invalid access!");
1082 return StringRef(Tok.Data, Tok.Length);
1084 bool isRegPair() const { return Kind == k_RegPair; }
1086 unsigned getReg() const override {
1087 // As a special case until we sort out the definition of div/divu, pretend
1088 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
1089 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1090 RegIdx.Kind & RegKind_GPR)
1091 return getGPR32Reg(); // FIXME: GPR64 too
1093 assert(Kind == k_PhysRegister && "Invalid access!");
1097 const MCExpr *getImm() const {
1098 assert((Kind == k_Immediate) && "Invalid access!");
1102 int64_t getConstantImm() const {
1103 const MCExpr *Val = getImm();
1104 return static_cast<const MCConstantExpr *>(Val)->getValue();
1107 MipsOperand *getMemBase() const {
1108 assert((Kind == k_Memory) && "Invalid access!");
1112 const MCExpr *getMemOff() const {
1113 assert((Kind == k_Memory) && "Invalid access!");
1117 int64_t getConstantMemOff() const {
1118 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1121 const SmallVectorImpl<unsigned> &getRegList() const {
1122 assert((Kind == k_RegList) && "Invalid access!");
1123 return *(RegList.List);
1126 unsigned getRegPair() const {
1127 assert((Kind == k_RegPair) && "Invalid access!");
1128 return RegIdx.Index;
1131 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1132 MipsAsmParser &Parser) {
1133 auto Op = make_unique<MipsOperand>(k_Token, Parser);
1134 Op->Tok.Data = Str.data();
1135 Op->Tok.Length = Str.size();
1141 /// Create a numeric register (e.g. $1). The exact register remains
1142 /// unresolved until an instruction successfully matches
1143 static std::unique_ptr<MipsOperand>
1144 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1145 SMLoc E, MipsAsmParser &Parser) {
1146 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1147 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1150 /// Create a register that is definitely a GPR.
1151 /// This is typically only used for named registers such as $gp.
1152 static std::unique_ptr<MipsOperand>
1153 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1154 MipsAsmParser &Parser) {
1155 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1158 /// Create a register that is definitely a FGR.
1159 /// This is typically only used for named registers such as $f0.
1160 static std::unique_ptr<MipsOperand>
1161 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1162 MipsAsmParser &Parser) {
1163 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1166 /// Create a register that is definitely a HWReg.
1167 /// This is typically only used for named registers such as $hwr_cpunum.
1168 static std::unique_ptr<MipsOperand>
1169 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1170 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1171 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1174 /// Create a register that is definitely an FCC.
1175 /// This is typically only used for named registers such as $fcc0.
1176 static std::unique_ptr<MipsOperand>
1177 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1178 MipsAsmParser &Parser) {
1179 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1182 /// Create a register that is definitely an ACC.
1183 /// This is typically only used for named registers such as $ac0.
1184 static std::unique_ptr<MipsOperand>
1185 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1186 MipsAsmParser &Parser) {
1187 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1190 /// Create a register that is definitely an MSA128.
1191 /// This is typically only used for named registers such as $w0.
1192 static std::unique_ptr<MipsOperand>
1193 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1194 SMLoc E, MipsAsmParser &Parser) {
1195 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1198 /// Create a register that is definitely an MSACtrl.
1199 /// This is typically only used for named registers such as $msaaccess.
1200 static std::unique_ptr<MipsOperand>
1201 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1202 SMLoc E, MipsAsmParser &Parser) {
1203 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1206 static std::unique_ptr<MipsOperand>
1207 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1208 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1215 static std::unique_ptr<MipsOperand>
1216 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1217 SMLoc E, MipsAsmParser &Parser) {
1218 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1219 Op->Mem.Base = Base.release();
1226 static std::unique_ptr<MipsOperand>
1227 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1228 MipsAsmParser &Parser) {
1229 assert (Regs.size() > 0 && "Empty list not allowed");
1231 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1232 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1233 Op->StartLoc = StartLoc;
1234 Op->EndLoc = EndLoc;
1238 static std::unique_ptr<MipsOperand>
1239 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1240 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1241 Op->RegIdx.Index = RegNo;
1247 bool isGPRAsmReg() const {
1248 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1250 bool isMM16AsmReg() const {
1251 if (!(isRegIdx() && RegIdx.Kind))
1253 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1254 || RegIdx.Index == 16 || RegIdx.Index == 17);
1256 bool isMM16AsmRegZero() const {
1257 if (!(isRegIdx() && RegIdx.Kind))
1259 return (RegIdx.Index == 0 ||
1260 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1261 RegIdx.Index == 17);
1263 bool isMM16AsmRegMoveP() const {
1264 if (!(isRegIdx() && RegIdx.Kind))
1266 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1267 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1269 bool isFGRAsmReg() const {
1270 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1271 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1273 bool isHWRegsAsmReg() const {
1274 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1276 bool isCCRAsmReg() const {
1277 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1279 bool isFCCAsmReg() const {
1280 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1282 if (!AsmParser.hasEightFccRegisters())
1283 return RegIdx.Index == 0;
1284 return RegIdx.Index <= 7;
1286 bool isACCAsmReg() const {
1287 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1289 bool isCOP0AsmReg() const {
1290 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1292 bool isCOP2AsmReg() const {
1293 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1295 bool isCOP3AsmReg() const {
1296 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1298 bool isMSA128AsmReg() const {
1299 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1301 bool isMSACtrlAsmReg() const {
1302 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1305 /// getStartLoc - Get the location of the first token of this operand.
1306 SMLoc getStartLoc() const override { return StartLoc; }
1307 /// getEndLoc - Get the location of the last token of this operand.
1308 SMLoc getEndLoc() const override { return EndLoc; }
1310 virtual ~MipsOperand() {
1318 delete RegList.List;
1319 case k_PhysRegister:
1320 case k_RegisterIndex:
1327 void print(raw_ostream &OS) const override {
1336 Mem.Base->print(OS);
1341 case k_PhysRegister:
1342 OS << "PhysReg<" << PhysReg.Num << ">";
1344 case k_RegisterIndex:
1345 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1352 for (auto Reg : (*RegList.List))
1357 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1361 }; // class MipsOperand
1365 extern const MCInstrDesc MipsInsts[];
1367 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1368 return MipsInsts[Opcode];
1371 static bool hasShortDelaySlot(unsigned Opcode) {
1374 case Mips::JALRS_MM:
1375 case Mips::JALRS16_MM:
1376 case Mips::BGEZALS_MM:
1377 case Mips::BLTZALS_MM:
1384 static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1385 if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1386 return &SRExpr->getSymbol();
1389 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1390 const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1391 const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1402 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1403 return getSingleMCSymbol(UExpr->getSubExpr());
1408 static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1409 if (isa<MCSymbolRefExpr>(Expr))
1412 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1413 return countMCSymbolRefExpr(BExpr->getLHS()) +
1414 countMCSymbolRefExpr(BExpr->getRHS());
1416 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1417 return countMCSymbolRefExpr(UExpr->getSubExpr());
1423 void emitRX(unsigned Opcode, unsigned Reg0, MCOperand Op1, SMLoc IDLoc,
1424 SmallVectorImpl<MCInst> &Instructions) {
1426 tmpInst.setOpcode(Opcode);
1427 tmpInst.addOperand(MCOperand::createReg(Reg0));
1428 tmpInst.addOperand(Op1);
1429 tmpInst.setLoc(IDLoc);
1430 Instructions.push_back(tmpInst);
1433 void emitRI(unsigned Opcode, unsigned Reg0, int32_t Imm, SMLoc IDLoc,
1434 SmallVectorImpl<MCInst> &Instructions) {
1435 emitRX(Opcode, Reg0, MCOperand::createImm(Imm), IDLoc, Instructions);
1438 void emitRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, SMLoc IDLoc,
1439 SmallVectorImpl<MCInst> &Instructions) {
1440 emitRX(Opcode, Reg0, MCOperand::createReg(Reg1), IDLoc, Instructions);
1443 void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc,
1444 SmallVectorImpl<MCInst> &Instructions) {
1446 tmpInst.setOpcode(Opcode);
1447 tmpInst.addOperand(MCOperand::createImm(Imm1));
1448 tmpInst.addOperand(MCOperand::createImm(Imm2));
1449 tmpInst.setLoc(IDLoc);
1450 Instructions.push_back(tmpInst);
1453 void emitR(unsigned Opcode, unsigned Reg0, SMLoc IDLoc,
1454 SmallVectorImpl<MCInst> &Instructions) {
1456 tmpInst.setOpcode(Opcode);
1457 tmpInst.addOperand(MCOperand::createReg(Reg0));
1458 tmpInst.setLoc(IDLoc);
1459 Instructions.push_back(tmpInst);
1462 void emitRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1, MCOperand Op2,
1463 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1465 tmpInst.setOpcode(Opcode);
1466 tmpInst.addOperand(MCOperand::createReg(Reg0));
1467 tmpInst.addOperand(MCOperand::createReg(Reg1));
1468 tmpInst.addOperand(Op2);
1469 tmpInst.setLoc(IDLoc);
1470 Instructions.push_back(tmpInst);
1473 void emitRRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, unsigned Reg2,
1474 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1475 emitRRX(Opcode, Reg0, Reg1, MCOperand::createReg(Reg2), IDLoc,
1479 void emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1, int16_t Imm,
1480 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1481 emitRRX(Opcode, Reg0, Reg1, MCOperand::createImm(Imm), IDLoc,
1485 void emitAppropriateDSLL(unsigned DstReg, unsigned SrcReg, int16_t ShiftAmount,
1486 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1487 if (ShiftAmount >= 32) {
1488 emitRRI(Mips::DSLL32, DstReg, SrcReg, ShiftAmount - 32, IDLoc,
1493 emitRRI(Mips::DSLL, DstReg, SrcReg, ShiftAmount, IDLoc, Instructions);
1495 } // end anonymous namespace.
1497 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1498 SmallVectorImpl<MCInst> &Instructions) {
1499 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1500 bool ExpandedJalSym = false;
1504 if (MCID.isBranch() || MCID.isCall()) {
1505 const unsigned Opcode = Inst.getOpcode();
1515 assert(hasCnMips() && "instruction only valid for octeon cpus");
1522 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1523 Offset = Inst.getOperand(2);
1524 if (!Offset.isImm())
1525 break; // We'll deal with this situation later on when applying fixups.
1526 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1527 return Error(IDLoc, "branch target out of range");
1528 if (OffsetToAlignment(Offset.getImm(),
1529 1LL << (inMicroMipsMode() ? 1 : 2)))
1530 return Error(IDLoc, "branch to misaligned address");
1544 case Mips::BGEZAL_MM:
1545 case Mips::BLTZAL_MM:
1548 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1549 Offset = Inst.getOperand(1);
1550 if (!Offset.isImm())
1551 break; // We'll deal with this situation later on when applying fixups.
1552 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1553 return Error(IDLoc, "branch target out of range");
1554 if (OffsetToAlignment(Offset.getImm(),
1555 1LL << (inMicroMipsMode() ? 1 : 2)))
1556 return Error(IDLoc, "branch to misaligned address");
1558 case Mips::BEQZ16_MM:
1559 case Mips::BEQZC16_MMR6:
1560 case Mips::BNEZ16_MM:
1561 case Mips::BNEZC16_MMR6:
1562 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1563 Offset = Inst.getOperand(1);
1564 if (!Offset.isImm())
1565 break; // We'll deal with this situation later on when applying fixups.
1566 if (!isInt<8>(Offset.getImm()))
1567 return Error(IDLoc, "branch target out of range");
1568 if (OffsetToAlignment(Offset.getImm(), 2LL))
1569 return Error(IDLoc, "branch to misaligned address");
1574 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1575 // We still accept it but it is a normal nop.
1576 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1577 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1578 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1583 const unsigned Opcode = Inst.getOpcode();
1595 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1596 // The offset is handled above
1597 Opnd = Inst.getOperand(1);
1599 return Error(IDLoc, "expected immediate operand kind");
1600 Imm = Opnd.getImm();
1601 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1602 Opcode == Mips::BBIT1 ? 63 : 31))
1603 return Error(IDLoc, "immediate operand value out of range");
1605 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1607 Inst.getOperand(1).setImm(Imm - 32);
1615 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1617 Opnd = Inst.getOperand(3);
1619 return Error(IDLoc, "expected immediate operand kind");
1620 Imm = Opnd.getImm();
1621 if (Imm < 0 || Imm > 31)
1622 return Error(IDLoc, "immediate operand value out of range");
1624 Opnd = Inst.getOperand(2);
1626 return Error(IDLoc, "expected immediate operand kind");
1627 Imm = Opnd.getImm();
1628 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1629 Opcode == Mips::EXTS ? 63 : 31))
1630 return Error(IDLoc, "immediate operand value out of range");
1632 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1633 Inst.getOperand(2).setImm(Imm - 32);
1639 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1640 Opnd = Inst.getOperand(2);
1642 return Error(IDLoc, "expected immediate operand kind");
1643 Imm = Opnd.getImm();
1644 if (!isInt<10>(Imm))
1645 return Error(IDLoc, "immediate operand value out of range");
1650 // This expansion is not in a function called by tryExpandInstruction()
1651 // because the pseudo-instruction doesn't have a distinct opcode.
1652 if ((Inst.getOpcode() == Mips::JAL || Inst.getOpcode() == Mips::JAL_MM) &&
1654 warnIfNoMacro(IDLoc);
1656 const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
1658 // We can do this expansion if there's only 1 symbol in the argument
1660 if (countMCSymbolRefExpr(JalExpr) > 1)
1661 return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
1663 // FIXME: This is checking the expression can be handled by the later stages
1664 // of the assembler. We ought to leave it to those later stages but
1665 // we can't do that until we stop evaluateRelocExpr() rewriting the
1666 // expressions into non-equivalent forms.
1667 const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
1669 // FIXME: Add support for label+offset operands (currently causes an error).
1670 // FIXME: Add support for forward-declared local symbols.
1671 // FIXME: Add expansion for when the LargeGOT option is enabled.
1672 if (JalSym->isInSection() || JalSym->isTemporary()) {
1674 // If it's a local symbol and the O32 ABI is being used, we expand to:
1676 // R_(MICRO)MIPS_GOT16 label
1677 // addiu $25, $25, 0
1678 // R_(MICRO)MIPS_LO16 label
1680 const MCExpr *Got16RelocExpr = evaluateRelocExpr(JalExpr, "got");
1681 const MCExpr *Lo16RelocExpr = evaluateRelocExpr(JalExpr, "lo");
1683 emitRRX(Mips::LW, Mips::T9, Mips::GP,
1684 MCOperand::createExpr(Got16RelocExpr), IDLoc, Instructions);
1685 emitRRX(Mips::ADDiu, Mips::T9, Mips::T9,
1686 MCOperand::createExpr(Lo16RelocExpr), IDLoc, Instructions);
1687 } else if (isABI_N32() || isABI_N64()) {
1688 // If it's a local symbol and the N32/N64 ABIs are being used,
1690 // lw/ld $25, 0($gp)
1691 // R_(MICRO)MIPS_GOT_DISP label
1693 const MCExpr *GotDispRelocExpr = evaluateRelocExpr(JalExpr, "got_disp");
1695 emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
1696 MCOperand::createExpr(GotDispRelocExpr), IDLoc, Instructions);
1699 // If it's an external/weak symbol, we expand to:
1700 // lw/ld $25, 0($gp)
1701 // R_(MICRO)MIPS_CALL16 label
1703 const MCExpr *Call16RelocExpr = evaluateRelocExpr(JalExpr, "call16");
1705 emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
1706 MCOperand::createExpr(Call16RelocExpr), IDLoc, Instructions);
1710 if (IsCpRestoreSet && inMicroMipsMode())
1711 JalrInst.setOpcode(Mips::JALRS_MM);
1713 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1714 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1715 JalrInst.addOperand(MCOperand::createReg(Mips::T9));
1717 // FIXME: Add an R_(MICRO)MIPS_JALR relocation after the JALR.
1718 // This relocation is supposed to be an optimization hint for the linker
1719 // and is not necessary for correctness.
1722 ExpandedJalSym = true;
1725 if (MCID.mayLoad() || MCID.mayStore()) {
1726 // Check the offset of memory operand, if it is a symbol
1727 // reference or immediate we may have to expand instructions.
1728 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1729 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1730 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1731 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1732 MCOperand &Op = Inst.getOperand(i);
1734 int MemOffset = Op.getImm();
1735 if (MemOffset < -32768 || MemOffset > 32767) {
1736 // Offset can't exceed 16bit value.
1737 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1740 } else if (Op.isExpr()) {
1741 const MCExpr *Expr = Op.getExpr();
1742 if (Expr->getKind() == MCExpr::SymbolRef) {
1743 const MCSymbolRefExpr *SR =
1744 static_cast<const MCSymbolRefExpr *>(Expr);
1745 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1747 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1750 } else if (!isEvaluated(Expr)) {
1751 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1759 if (inMicroMipsMode()) {
1760 if (MCID.mayLoad()) {
1761 // Try to create 16-bit GP relative load instruction.
1762 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1763 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1764 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1765 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1766 MCOperand &Op = Inst.getOperand(i);
1768 int MemOffset = Op.getImm();
1769 MCOperand &DstReg = Inst.getOperand(0);
1770 MCOperand &BaseReg = Inst.getOperand(1);
1771 if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
1772 getContext().getRegisterInfo()->getRegClass(
1773 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1774 (BaseReg.getReg() == Mips::GP ||
1775 BaseReg.getReg() == Mips::GP_64)) {
1777 emitRRI(Mips::LWGP_MM, DstReg.getReg(), Mips::GP, MemOffset,
1778 IDLoc, Instructions);
1786 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1791 switch (Inst.getOpcode()) {
1794 case Mips::ADDIUS5_MM:
1795 Opnd = Inst.getOperand(2);
1797 return Error(IDLoc, "expected immediate operand kind");
1798 Imm = Opnd.getImm();
1799 if (Imm < -8 || Imm > 7)
1800 return Error(IDLoc, "immediate operand value out of range");
1802 case Mips::ADDIUSP_MM:
1803 Opnd = Inst.getOperand(0);
1805 return Error(IDLoc, "expected immediate operand kind");
1806 Imm = Opnd.getImm();
1807 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1809 return Error(IDLoc, "immediate operand value out of range");
1811 case Mips::SLL16_MM:
1812 case Mips::SRL16_MM:
1813 Opnd = Inst.getOperand(2);
1815 return Error(IDLoc, "expected immediate operand kind");
1816 Imm = Opnd.getImm();
1817 if (Imm < 1 || Imm > 8)
1818 return Error(IDLoc, "immediate operand value out of range");
1821 Opnd = Inst.getOperand(1);
1823 return Error(IDLoc, "expected immediate operand kind");
1824 Imm = Opnd.getImm();
1825 if (Imm < -1 || Imm > 126)
1826 return Error(IDLoc, "immediate operand value out of range");
1828 case Mips::ADDIUR2_MM:
1829 Opnd = Inst.getOperand(2);
1831 return Error(IDLoc, "expected immediate operand kind");
1832 Imm = Opnd.getImm();
1833 if (!(Imm == 1 || Imm == -1 ||
1834 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1835 return Error(IDLoc, "immediate operand value out of range");
1837 case Mips::ADDIUR1SP_MM:
1838 Opnd = Inst.getOperand(1);
1840 return Error(IDLoc, "expected immediate operand kind");
1841 Imm = Opnd.getImm();
1842 if (OffsetToAlignment(Imm, 4LL))
1843 return Error(IDLoc, "misaligned immediate operand value");
1844 if (Imm < 0 || Imm > 255)
1845 return Error(IDLoc, "immediate operand value out of range");
1847 case Mips::ANDI16_MM:
1848 Opnd = Inst.getOperand(2);
1850 return Error(IDLoc, "expected immediate operand kind");
1851 Imm = Opnd.getImm();
1852 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1853 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1854 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1855 return Error(IDLoc, "immediate operand value out of range");
1857 case Mips::LBU16_MM:
1858 Opnd = Inst.getOperand(2);
1860 return Error(IDLoc, "expected immediate operand kind");
1861 Imm = Opnd.getImm();
1862 if (Imm < -1 || Imm > 14)
1863 return Error(IDLoc, "immediate operand value out of range");
1872 case Mips::SB16_MMR6:
1873 Opnd = Inst.getOperand(2);
1875 return Error(IDLoc, "expected immediate operand kind");
1876 Imm = Opnd.getImm();
1877 if (Imm < 0 || Imm > 15)
1878 return Error(IDLoc, "immediate operand value out of range");
1880 case Mips::LHU16_MM:
1882 case Mips::SH16_MMR6:
1883 Opnd = Inst.getOperand(2);
1885 return Error(IDLoc, "expected immediate operand kind");
1886 Imm = Opnd.getImm();
1887 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1888 return Error(IDLoc, "immediate operand value out of range");
1892 case Mips::SW16_MMR6:
1893 Opnd = Inst.getOperand(2);
1895 return Error(IDLoc, "expected immediate operand kind");
1896 Imm = Opnd.getImm();
1897 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1898 return Error(IDLoc, "immediate operand value out of range");
1900 case Mips::PREFX_MM:
1903 Opnd = Inst.getOperand(2);
1905 return Error(IDLoc, "expected immediate operand kind");
1906 Imm = Opnd.getImm();
1907 if (!isUInt<5>(Imm))
1908 return Error(IDLoc, "immediate operand value out of range");
1910 case Mips::ADDIUPC_MM:
1911 MCOperand Opnd = Inst.getOperand(1);
1913 return Error(IDLoc, "expected immediate operand kind");
1914 int Imm = Opnd.getImm();
1915 if ((Imm % 4 != 0) || !isInt<25>(Imm))
1916 return Error(IDLoc, "immediate operand value out of range");
1921 MacroExpanderResultTy ExpandResult =
1922 tryExpandInstruction(Inst, IDLoc, Instructions);
1923 switch (ExpandResult) {
1925 Instructions.push_back(Inst);
1933 // If this instruction has a delay slot and .set reorder is active,
1934 // emit a NOP after it.
1935 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1936 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1938 if ((Inst.getOpcode() == Mips::JalOneReg ||
1939 Inst.getOpcode() == Mips::JalTwoReg || ExpandedJalSym) &&
1940 isPicAndNotNxxAbi()) {
1941 if (IsCpRestoreSet) {
1942 // We need a NOP between the JALR and the LW:
1943 // If .set reorder has been used, we've already emitted a NOP.
1944 // If .set noreorder has been used, we need to emit a NOP at this point.
1945 if (!AssemblerOptions.back()->isReorder())
1946 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1948 // Load the $gp from the stack.
1949 SmallVector<MCInst, 3> LoadInsts;
1950 createCpRestoreMemOp(true /*IsLoad*/, CpRestoreOffset /*StackOffset*/,
1953 for (const MCInst &Inst : LoadInsts)
1954 Instructions.push_back(Inst);
1957 Warning(IDLoc, "no .cprestore used in PIC mode");
1963 MipsAsmParser::MacroExpanderResultTy
1964 MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
1965 SmallVectorImpl<MCInst> &Instructions) {
1966 switch (Inst.getOpcode()) {
1968 return MER_NotAMacro;
1969 case Mips::LoadImm32:
1970 return expandLoadImm(Inst, true, IDLoc, Instructions) ? MER_Fail
1972 case Mips::LoadImm64:
1973 return expandLoadImm(Inst, false, IDLoc, Instructions) ? MER_Fail
1975 case Mips::LoadAddrImm32:
1976 case Mips::LoadAddrImm64:
1977 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1978 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
1979 "expected immediate operand kind");
1981 return expandLoadAddress(Inst.getOperand(0).getReg(), Mips::NoRegister,
1983 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc,
1987 case Mips::LoadAddrReg32:
1988 case Mips::LoadAddrReg64:
1989 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1990 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1991 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
1992 "expected immediate operand kind");
1994 return expandLoadAddress(Inst.getOperand(0).getReg(),
1995 Inst.getOperand(1).getReg(), Inst.getOperand(2),
1996 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc,
2000 case Mips::B_MM_Pseudo:
2001 case Mips::B_MMR6_Pseudo:
2002 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions) ? MER_Fail
2006 return expandLoadStoreMultiple(Inst, IDLoc, Instructions) ? MER_Fail
2008 case Mips::JalOneReg:
2009 case Mips::JalTwoReg:
2010 return expandJalWithRegs(Inst, IDLoc, Instructions) ? MER_Fail
2014 return expandBranchImm(Inst, IDLoc, Instructions) ? MER_Fail : MER_Success;
2031 case Mips::BLTImmMacro:
2032 case Mips::BLEImmMacro:
2033 case Mips::BGEImmMacro:
2034 case Mips::BGTImmMacro:
2035 case Mips::BLTUImmMacro:
2036 case Mips::BLEUImmMacro:
2037 case Mips::BGEUImmMacro:
2038 case Mips::BGTUImmMacro:
2039 case Mips::BLTLImmMacro:
2040 case Mips::BLELImmMacro:
2041 case Mips::BGELImmMacro:
2042 case Mips::BGTLImmMacro:
2043 case Mips::BLTULImmMacro:
2044 case Mips::BLEULImmMacro:
2045 case Mips::BGEULImmMacro:
2046 case Mips::BGTULImmMacro:
2047 return expandCondBranches(Inst, IDLoc, Instructions) ? MER_Fail
2049 case Mips::SDivMacro:
2050 return expandDiv(Inst, IDLoc, Instructions, false, true) ? MER_Fail
2052 case Mips::DSDivMacro:
2053 return expandDiv(Inst, IDLoc, Instructions, true, true) ? MER_Fail
2055 case Mips::UDivMacro:
2056 return expandDiv(Inst, IDLoc, Instructions, false, false) ? MER_Fail
2058 case Mips::DUDivMacro:
2059 return expandDiv(Inst, IDLoc, Instructions, true, false) ? MER_Fail
2062 return expandUlh(Inst, true, IDLoc, Instructions) ? MER_Fail : MER_Success;
2064 return expandUlh(Inst, false, IDLoc, Instructions) ? MER_Fail : MER_Success;
2066 return expandUlw(Inst, IDLoc, Instructions) ? MER_Fail : MER_Success;
2068 return expandAliasImmediate(Inst, IDLoc, Instructions) ? MER_Fail
2074 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2075 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2076 int64_t ImmValue = Inst.getOperand(2).getImm();
2077 if (isInt<16>(ImmValue))
2078 return MER_NotAMacro;
2079 return expandAliasImmediate(Inst, IDLoc, Instructions) ? MER_Fail
2082 return MER_NotAMacro;
2086 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2087 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2088 int64_t ImmValue = Inst.getOperand(2).getImm();
2089 if (isUInt<16>(ImmValue))
2090 return MER_NotAMacro;
2091 return expandAliasImmediate(Inst, IDLoc, Instructions) ? MER_Fail
2094 return MER_NotAMacro;
2098 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2099 SmallVectorImpl<MCInst> &Instructions) {
2100 // Create a JALR instruction which is going to replace the pseudo-JAL.
2102 JalrInst.setLoc(IDLoc);
2103 const MCOperand FirstRegOp = Inst.getOperand(0);
2104 const unsigned Opcode = Inst.getOpcode();
2106 if (Opcode == Mips::JalOneReg) {
2107 // jal $rs => jalr $rs
2108 if (IsCpRestoreSet && inMicroMipsMode()) {
2109 JalrInst.setOpcode(Mips::JALRS16_MM);
2110 JalrInst.addOperand(FirstRegOp);
2111 } else if (inMicroMipsMode()) {
2112 JalrInst.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2113 JalrInst.addOperand(FirstRegOp);
2115 JalrInst.setOpcode(Mips::JALR);
2116 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2117 JalrInst.addOperand(FirstRegOp);
2119 } else if (Opcode == Mips::JalTwoReg) {
2120 // jal $rd, $rs => jalr $rd, $rs
2121 if (IsCpRestoreSet && inMicroMipsMode())
2122 JalrInst.setOpcode(Mips::JALRS_MM);
2124 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2125 JalrInst.addOperand(FirstRegOp);
2126 const MCOperand SecondRegOp = Inst.getOperand(1);
2127 JalrInst.addOperand(SecondRegOp);
2129 Instructions.push_back(JalrInst);
2131 // If .set reorder is active and branch instruction has a delay slot,
2132 // emit a NOP after it.
2133 const MCInstrDesc &MCID = getInstDesc(JalrInst.getOpcode());
2134 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) {
2135 createNop(hasShortDelaySlot(JalrInst.getOpcode()), IDLoc, Instructions);
2141 /// Can the value be represented by a unsigned N-bit value and a shift left?
2142 template <unsigned N> static bool isShiftedUIntAtAnyPosition(uint64_t x) {
2143 unsigned BitNum = findFirstSet(x);
2145 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2148 /// Load (or add) an immediate into a register.
2150 /// @param ImmValue The immediate to load.
2151 /// @param DstReg The register that will hold the immediate.
2152 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
2153 /// for a simple initialization.
2154 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2155 /// @param IsAddress True if the immediate represents an address. False if it
2157 /// @param IDLoc Location of the immediate in the source file.
2158 /// @param Instructions The instructions emitted by this expansion.
2159 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2160 unsigned SrcReg, bool Is32BitImm,
2161 bool IsAddress, SMLoc IDLoc,
2162 SmallVectorImpl<MCInst> &Instructions) {
2163 if (!Is32BitImm && !isGP64bit()) {
2164 Error(IDLoc, "instruction requires a 64-bit architecture");
2169 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2170 // Sign extend up to 64-bit so that the predicates match the hardware
2171 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2173 ImmValue = SignExtend64<32>(ImmValue);
2175 Error(IDLoc, "instruction requires a 32-bit immediate");
2180 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2181 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2183 bool UseSrcReg = false;
2184 if (SrcReg != Mips::NoRegister)
2187 unsigned TmpReg = DstReg;
2188 if (UseSrcReg && (DstReg == SrcReg)) {
2189 // At this point we need AT to perform the expansions and we exit if it is
2191 unsigned ATReg = getATReg(IDLoc);
2197 if (isInt<16>(ImmValue)) {
2201 // This doesn't quite follow the usual ABI expectations for N32 but matches
2202 // traditional assembler behaviour. N32 would normally use addiu for both
2203 // integers and addresses.
2204 if (IsAddress && !Is32BitImm) {
2205 emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2209 emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2213 if (isUInt<16>(ImmValue)) {
2214 unsigned TmpReg = DstReg;
2215 if (SrcReg == DstReg) {
2216 TmpReg = getATReg(IDLoc);
2221 emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, Instructions);
2223 emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2227 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2228 warnIfNoMacro(IDLoc);
2230 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2231 uint16_t Bits15To0 = ImmValue & 0xffff;
2233 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2234 // Traditional behaviour seems to special case this particular value. It's
2235 // not clear why other masks are handled differently.
2236 if (ImmValue == 0xffffffff) {
2237 emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, Instructions);
2238 emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, Instructions);
2240 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2244 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2246 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, Instructions);
2247 emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, Instructions);
2249 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2251 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2255 emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, Instructions);
2257 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2259 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2263 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2265 Error(IDLoc, "instruction requires a 32-bit immediate");
2269 // Traditionally, these immediates are shifted as little as possible and as
2270 // such we align the most significant bit to bit 15 of our temporary.
2271 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2272 unsigned LastSet = findLastSet((uint64_t)ImmValue);
2273 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2274 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2275 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, Instructions);
2276 emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, Instructions);
2279 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2284 warnIfNoMacro(IDLoc);
2286 // The remaining case is packed with a sequence of dsll and ori with zeros
2287 // being omitted and any neighbouring dsll's being coalesced.
2288 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2290 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2291 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2292 IDLoc, Instructions))
2295 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2296 // skip it and defer the shift to the next chunk.
2297 unsigned ShiftCarriedForwards = 16;
2298 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2299 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2301 if (ImmChunk != 0) {
2302 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2304 emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, Instructions);
2305 ShiftCarriedForwards = 0;
2308 ShiftCarriedForwards += 16;
2310 ShiftCarriedForwards -= 16;
2312 // Finish any remaining shifts left by trailing zeros.
2313 if (ShiftCarriedForwards)
2314 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2318 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2323 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2324 SmallVectorImpl<MCInst> &Instructions) {
2325 const MCOperand &ImmOp = Inst.getOperand(1);
2326 assert(ImmOp.isImm() && "expected immediate operand kind");
2327 const MCOperand &DstRegOp = Inst.getOperand(0);
2328 assert(DstRegOp.isReg() && "expected register operand kind");
2330 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2331 Is32BitImm, false, IDLoc, Instructions))
2337 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2338 const MCOperand &Offset,
2339 bool Is32BitAddress, SMLoc IDLoc,
2340 SmallVectorImpl<MCInst> &Instructions) {
2341 // la can't produce a usable address when addresses are 64-bit.
2342 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2343 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2344 // We currently can't do this because we depend on the equality
2345 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2346 Error(IDLoc, "la used to load 64-bit address");
2347 // Continue as if we had 'dla' instead.
2348 Is32BitAddress = false;
2351 // dla requires 64-bit addresses.
2352 if (!Is32BitAddress && !ABI.ArePtrs64bit()) {
2353 Error(IDLoc, "instruction requires a 64-bit architecture");
2357 if (!Offset.isImm())
2358 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2359 Is32BitAddress, IDLoc, Instructions);
2361 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2362 IDLoc, Instructions);
2365 bool MipsAsmParser::loadAndAddSymbolAddress(
2366 const MCExpr *SymExpr, unsigned DstReg, unsigned SrcReg, bool Is32BitSym,
2367 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2368 warnIfNoMacro(IDLoc);
2370 const MCExpr *Symbol = cast<MCExpr>(SymExpr);
2371 const MipsMCExpr *HiExpr = MipsMCExpr::create(
2372 MCSymbolRefExpr::VK_Mips_ABS_HI, Symbol, getContext());
2373 const MipsMCExpr *LoExpr = MipsMCExpr::create(
2374 MCSymbolRefExpr::VK_Mips_ABS_LO, Symbol, getContext());
2376 bool UseSrcReg = SrcReg != Mips::NoRegister;
2378 // This is the 64-bit symbol address expansion.
2379 if (ABI.ArePtrs64bit() && isGP64bit()) {
2380 // We always need AT for the 64-bit expansion.
2381 // If it is not available we exit.
2382 unsigned ATReg = getATReg(IDLoc);
2386 const MipsMCExpr *HighestExpr = MipsMCExpr::create(
2387 MCSymbolRefExpr::VK_Mips_HIGHEST, Symbol, getContext());
2388 const MipsMCExpr *HigherExpr = MipsMCExpr::create(
2389 MCSymbolRefExpr::VK_Mips_HIGHER, Symbol, getContext());
2391 if (UseSrcReg && (DstReg == SrcReg)) {
2392 // If $rs is the same as $rd:
2393 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
2394 // daddiu $at, $at, %higher(sym)
2395 // dsll $at, $at, 16
2396 // daddiu $at, $at, %hi(sym)
2397 // dsll $at, $at, 16
2398 // daddiu $at, $at, %lo(sym)
2399 // daddu $rd, $at, $rd
2400 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
2402 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HigherExpr),
2403 IDLoc, Instructions);
2404 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2405 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2407 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2408 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2410 emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, Instructions);
2415 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2416 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
2417 // lui $at, %hi(sym)
2418 // daddiu $rd, $rd, %higher(sym)
2419 // daddiu $at, $at, %lo(sym)
2420 // dsll32 $rd, $rd, 0
2421 // daddu $rd, $rd, $at
2422 // (daddu $rd, $rd, $rs)
2423 emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
2425 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2427 emitRRX(Mips::DADDiu, DstReg, DstReg, MCOperand::createExpr(HigherExpr),
2428 IDLoc, Instructions);
2429 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2431 emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, Instructions);
2432 emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, Instructions);
2434 emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, Instructions);
2439 // And now, the 32-bit symbol address expansion:
2440 // If $rs is the same as $rd:
2441 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
2442 // ori $at, $at, %lo(sym)
2443 // addu $rd, $at, $rd
2444 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2445 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
2446 // ori $rd, $rd, %lo(sym)
2447 // (addu $rd, $rd, $rs)
2448 unsigned TmpReg = DstReg;
2449 if (UseSrcReg && (DstReg == SrcReg)) {
2450 // If $rs is the same as $rd, we need to use AT.
2451 // If it is not available we exit.
2452 unsigned ATReg = getATReg(IDLoc);
2458 emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, Instructions);
2459 emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr), IDLoc,
2463 emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2465 assert(DstReg == TmpReg);
2470 bool MipsAsmParser::expandUncondBranchMMPseudo(
2471 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2472 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2473 "unexpected number of operands");
2475 MCOperand Offset = Inst.getOperand(0);
2476 if (Offset.isExpr()) {
2478 Inst.setOpcode(Mips::BEQ_MM);
2479 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2480 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2481 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2483 assert(Offset.isImm() && "expected immediate operand kind");
2484 if (isInt<11>(Offset.getImm())) {
2485 // If offset fits into 11 bits then this instruction becomes microMIPS
2486 // 16-bit unconditional branch instruction.
2487 if (inMicroMipsMode())
2488 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
2490 if (!isInt<17>(Offset.getImm()))
2491 Error(IDLoc, "branch target out of range");
2492 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2493 Error(IDLoc, "branch to misaligned address");
2495 Inst.setOpcode(Mips::BEQ_MM);
2496 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2497 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2498 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2501 Instructions.push_back(Inst);
2503 // If .set reorder is active and branch instruction has a delay slot,
2504 // emit a NOP after it.
2505 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
2506 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2507 createNop(true, IDLoc, Instructions);
2512 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc,
2513 SmallVectorImpl<MCInst> &Instructions) {
2514 const MCOperand &DstRegOp = Inst.getOperand(0);
2515 assert(DstRegOp.isReg() && "expected register operand kind");
2517 const MCOperand &ImmOp = Inst.getOperand(1);
2518 assert(ImmOp.isImm() && "expected immediate operand kind");
2520 const MCOperand &MemOffsetOp = Inst.getOperand(2);
2521 assert(MemOffsetOp.isImm() && "expected immediate operand kind");
2523 unsigned OpCode = 0;
2524 switch(Inst.getOpcode()) {
2532 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2536 int64_t ImmValue = ImmOp.getImm();
2538 emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
2541 warnIfNoMacro(IDLoc);
2543 unsigned ATReg = getATReg(IDLoc);
2547 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
2548 IDLoc, Instructions))
2551 emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, Instructions);
2556 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2557 SmallVectorImpl<MCInst> &Instructions,
2558 bool isLoad, bool isImmOpnd) {
2559 unsigned ImmOffset, HiOffset, LoOffset;
2560 const MCExpr *ExprOffset;
2562 // 1st operand is either the source or destination register.
2563 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2564 unsigned RegOpNum = Inst.getOperand(0).getReg();
2565 // 2nd operand is the base register.
2566 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2567 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2568 // 3rd operand is either an immediate or expression.
2570 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2571 ImmOffset = Inst.getOperand(2).getImm();
2572 LoOffset = ImmOffset & 0x0000ffff;
2573 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2574 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2575 if (LoOffset & 0x8000)
2578 ExprOffset = Inst.getOperand(2).getExpr();
2579 // These are some of the types of expansions we perform here:
2580 // 1) lw $8, sym => lui $8, %hi(sym)
2581 // lw $8, %lo(sym)($8)
2582 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2584 // lw $8, %lo(offset)($9)
2585 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2587 // lw $8, %lo(offset)($at)
2588 // 4) sw $8, sym => lui $at, %hi(sym)
2589 // sw $8, %lo(sym)($at)
2590 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2592 // sw $8, %lo(offset)($at)
2593 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2594 // ldc1 $f0, %lo(sym)($at)
2596 // For load instructions we can use the destination register as a temporary
2597 // if base and dst are different (examples 1 and 2) and if the base register
2598 // is general purpose otherwise we must use $at (example 6) and error if it's
2599 // not available. For stores we must use $at (examples 4 and 5) because we
2600 // must not clobber the source register setting up the offset.
2601 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2602 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2603 unsigned RegClassIDOp0 =
2604 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2605 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2606 (RegClassIDOp0 == Mips::GPR64RegClassID);
2607 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2608 TmpRegNum = RegOpNum;
2610 // At this point we need AT to perform the expansions and we exit if it is
2612 TmpRegNum = getATReg(IDLoc);
2617 emitRX(Mips::LUi, TmpRegNum,
2618 isImmOpnd ? MCOperand::createImm(HiOffset)
2619 : MCOperand::createExpr(evaluateRelocExpr(ExprOffset, "hi")),
2620 IDLoc, Instructions);
2621 // Add temp register to base.
2622 if (BaseRegNum != Mips::ZERO)
2623 emitRRR(Mips::ADDu, TmpRegNum, TmpRegNum, BaseRegNum, IDLoc, Instructions);
2624 // And finally, create original instruction with low part
2625 // of offset and new base.
2626 emitRRX(Inst.getOpcode(), RegOpNum, TmpRegNum,
2628 ? MCOperand::createImm(LoOffset)
2629 : MCOperand::createExpr(evaluateRelocExpr(ExprOffset, "lo")),
2630 IDLoc, Instructions);
2634 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2635 SmallVectorImpl<MCInst> &Instructions) {
2636 unsigned OpNum = Inst.getNumOperands();
2637 unsigned Opcode = Inst.getOpcode();
2638 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2640 assert (Inst.getOperand(OpNum - 1).isImm() &&
2641 Inst.getOperand(OpNum - 2).isReg() &&
2642 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2644 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2645 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2646 (Inst.getOperand(OpNum - 2).getReg() == Mips::SP ||
2647 Inst.getOperand(OpNum - 2).getReg() == Mips::SP_64) &&
2648 (Inst.getOperand(OpNum - 3).getReg() == Mips::RA ||
2649 Inst.getOperand(OpNum - 3).getReg() == Mips::RA_64)) {
2650 // It can be implemented as SWM16 or LWM16 instruction.
2651 if (inMicroMipsMode() && hasMips32r6())
2652 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
2654 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2657 Inst.setOpcode(NewOpcode);
2658 Instructions.push_back(Inst);
2662 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
2663 SmallVectorImpl<MCInst> &Instructions) {
2664 bool EmittedNoMacroWarning = false;
2665 unsigned PseudoOpcode = Inst.getOpcode();
2666 unsigned SrcReg = Inst.getOperand(0).getReg();
2667 const MCOperand &TrgOp = Inst.getOperand(1);
2668 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
2670 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2671 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
2675 TrgReg = TrgOp.getReg();
2676 else if (TrgOp.isImm()) {
2677 warnIfNoMacro(IDLoc);
2678 EmittedNoMacroWarning = true;
2680 TrgReg = getATReg(IDLoc);
2684 switch(PseudoOpcode) {
2686 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2687 case Mips::BLTImmMacro:
2688 PseudoOpcode = Mips::BLT;
2690 case Mips::BLEImmMacro:
2691 PseudoOpcode = Mips::BLE;
2693 case Mips::BGEImmMacro:
2694 PseudoOpcode = Mips::BGE;
2696 case Mips::BGTImmMacro:
2697 PseudoOpcode = Mips::BGT;
2699 case Mips::BLTUImmMacro:
2700 PseudoOpcode = Mips::BLTU;
2702 case Mips::BLEUImmMacro:
2703 PseudoOpcode = Mips::BLEU;
2705 case Mips::BGEUImmMacro:
2706 PseudoOpcode = Mips::BGEU;
2708 case Mips::BGTUImmMacro:
2709 PseudoOpcode = Mips::BGTU;
2711 case Mips::BLTLImmMacro:
2712 PseudoOpcode = Mips::BLTL;
2714 case Mips::BLELImmMacro:
2715 PseudoOpcode = Mips::BLEL;
2717 case Mips::BGELImmMacro:
2718 PseudoOpcode = Mips::BGEL;
2720 case Mips::BGTLImmMacro:
2721 PseudoOpcode = Mips::BGTL;
2723 case Mips::BLTULImmMacro:
2724 PseudoOpcode = Mips::BLTUL;
2726 case Mips::BLEULImmMacro:
2727 PseudoOpcode = Mips::BLEUL;
2729 case Mips::BGEULImmMacro:
2730 PseudoOpcode = Mips::BGEUL;
2732 case Mips::BGTULImmMacro:
2733 PseudoOpcode = Mips::BGTUL;
2737 if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
2738 false, IDLoc, Instructions))
2742 switch (PseudoOpcode) {
2747 AcceptsEquality = false;
2748 ReverseOrderSLT = false;
2749 IsUnsigned = ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
2750 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
2751 ZeroSrcOpcode = Mips::BGTZ;
2752 ZeroTrgOpcode = Mips::BLTZ;
2758 AcceptsEquality = true;
2759 ReverseOrderSLT = true;
2760 IsUnsigned = ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
2761 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
2762 ZeroSrcOpcode = Mips::BGEZ;
2763 ZeroTrgOpcode = Mips::BLEZ;
2769 AcceptsEquality = true;
2770 ReverseOrderSLT = false;
2771 IsUnsigned = ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
2772 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
2773 ZeroSrcOpcode = Mips::BLEZ;
2774 ZeroTrgOpcode = Mips::BGEZ;
2780 AcceptsEquality = false;
2781 ReverseOrderSLT = true;
2782 IsUnsigned = ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
2783 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
2784 ZeroSrcOpcode = Mips::BLTZ;
2785 ZeroTrgOpcode = Mips::BGTZ;
2788 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2791 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
2792 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
2793 if (IsSrcRegZero && IsTrgRegZero) {
2794 // FIXME: All of these Opcode-specific if's are needed for compatibility
2795 // with GAS' behaviour. However, they may not generate the most efficient
2796 // code in some circumstances.
2797 if (PseudoOpcode == Mips::BLT) {
2798 emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2802 if (PseudoOpcode == Mips::BLE) {
2803 emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2805 Warning(IDLoc, "branch is always taken");
2808 if (PseudoOpcode == Mips::BGE) {
2809 emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2811 Warning(IDLoc, "branch is always taken");
2814 if (PseudoOpcode == Mips::BGT) {
2815 emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2819 if (PseudoOpcode == Mips::BGTU) {
2820 emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
2821 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2824 if (AcceptsEquality) {
2825 // If both registers are $0 and the pseudo-branch accepts equality, it
2826 // will always be taken, so we emit an unconditional branch.
2827 emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
2828 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2829 Warning(IDLoc, "branch is always taken");
2832 // If both registers are $0 and the pseudo-branch does not accept
2833 // equality, it will never be taken, so we don't have to emit anything.
2836 if (IsSrcRegZero || IsTrgRegZero) {
2837 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
2838 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
2839 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
2840 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
2841 // the pseudo-branch will never be taken, so we don't emit anything.
2842 // This only applies to unsigned pseudo-branches.
2845 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
2846 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
2847 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
2848 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
2849 // the pseudo-branch will always be taken, so we emit an unconditional
2851 // This only applies to unsigned pseudo-branches.
2852 emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
2853 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2854 Warning(IDLoc, "branch is always taken");
2858 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
2859 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
2860 // the pseudo-branch will be taken only when the non-zero register is
2861 // different from 0, so we emit a BNEZ.
2863 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
2864 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
2865 // the pseudo-branch will be taken only when the non-zero register is
2866 // equal to 0, so we emit a BEQZ.
2868 // Because only BLEU and BGEU branch on equality, we can use the
2869 // AcceptsEquality variable to decide when to emit the BEQZ.
2870 emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
2871 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
2872 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2875 // If we have a signed pseudo-branch and one of the registers is $0,
2876 // we can use an appropriate compare-to-zero branch. We select which one
2877 // to use in the switch statement above.
2878 emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
2879 IsSrcRegZero ? TrgReg : SrcReg, MCOperand::createExpr(OffsetExpr),
2880 IDLoc, Instructions);
2884 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
2885 // expansions. If it is not available, we return.
2886 unsigned ATRegNum = getATReg(IDLoc);
2890 if (!EmittedNoMacroWarning)
2891 warnIfNoMacro(IDLoc);
2893 // SLT fits well with 2 of our 4 pseudo-branches:
2894 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
2895 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
2896 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
2897 // This is accomplished by using a BNEZ with the result of the SLT.
2899 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
2900 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
2901 // Because only BGE and BLE branch on equality, we can use the
2902 // AcceptsEquality variable to decide when to emit the BEQZ.
2903 // Note that the order of the SLT arguments doesn't change between
2906 // The same applies to the unsigned variants, except that SLTu is used
2908 emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
2909 ReverseOrderSLT ? TrgReg : SrcReg, ReverseOrderSLT ? SrcReg : TrgReg,
2910 IDLoc, Instructions);
2912 emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
2913 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
2914 ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2919 bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc,
2920 SmallVectorImpl<MCInst> &Instructions,
2921 const bool IsMips64, const bool Signed) {
2922 if (hasMips32r6()) {
2923 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2927 warnIfNoMacro(IDLoc);
2929 const MCOperand &RsRegOp = Inst.getOperand(0);
2930 assert(RsRegOp.isReg() && "expected register operand kind");
2931 unsigned RsReg = RsRegOp.getReg();
2933 const MCOperand &RtRegOp = Inst.getOperand(1);
2934 assert(RtRegOp.isReg() && "expected register operand kind");
2935 unsigned RtReg = RtRegOp.getReg();
2940 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
2941 ZeroReg = Mips::ZERO_64;
2943 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
2944 ZeroReg = Mips::ZERO;
2947 bool UseTraps = useTraps();
2949 if (RsReg == Mips::ZERO || RsReg == Mips::ZERO_64) {
2950 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)
2951 Warning(IDLoc, "dividing zero by zero");
2953 if (Signed && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
2955 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2959 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2963 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2968 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
2969 Warning(IDLoc, "division by zero");
2972 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2976 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2981 // FIXME: The values for these two BranchTarget variables may be different in
2982 // micromips. These magic numbers need to be removed.
2983 unsigned BranchTargetNoTraps;
2984 unsigned BranchTarget;
2987 BranchTarget = IsMips64 ? 12 : 8;
2988 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2990 BranchTarget = IsMips64 ? 20 : 16;
2991 BranchTargetNoTraps = 8;
2992 // Branch to the li instruction.
2993 emitRRI(Mips::BNE, RtReg, ZeroReg, BranchTargetNoTraps, IDLoc,
2997 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
3000 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
3003 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
3007 unsigned ATReg = getATReg(IDLoc);
3011 emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, Instructions);
3013 // Branch to the mflo instruction.
3014 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
3015 emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, Instructions);
3016 emitRRI(Mips::DSLL32, ATReg, ATReg, 0x1f, IDLoc, Instructions);
3018 // Branch to the mflo instruction.
3019 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
3020 emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, Instructions);
3024 emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, Instructions);
3026 // Branch to the mflo instruction.
3027 emitRRI(Mips::BNE, RsReg, ATReg, BranchTargetNoTraps, IDLoc, Instructions);
3028 emitRRI(Mips::SLL, ZeroReg, ZeroReg, 0, IDLoc, Instructions);
3029 emitII(Mips::BREAK, 0x6, 0, IDLoc, Instructions);
3031 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
3035 bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
3036 SmallVectorImpl<MCInst> &Instructions) {
3037 if (hasMips32r6() || hasMips64r6()) {
3038 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3042 warnIfNoMacro(IDLoc);
3044 const MCOperand &DstRegOp = Inst.getOperand(0);
3045 assert(DstRegOp.isReg() && "expected register operand kind");
3047 const MCOperand &SrcRegOp = Inst.getOperand(1);
3048 assert(SrcRegOp.isReg() && "expected register operand kind");
3050 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3051 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3053 unsigned DstReg = DstRegOp.getReg();
3054 unsigned SrcReg = SrcRegOp.getReg();
3055 int64_t OffsetValue = OffsetImmOp.getImm();
3057 // NOTE: We always need AT for ULHU, as it is always used as the source
3058 // register for one of the LBu's.
3059 unsigned ATReg = getATReg(IDLoc);
3063 // When the value of offset+1 does not fit in 16 bits, we have to load the
3064 // offset in AT, (D)ADDu the original source register (if there was one), and
3065 // then use AT as the source register for the 2 generated LBu's.
3066 bool LoadedOffsetInAT = false;
3067 if (!isInt<16>(OffsetValue + 1) || !isInt<16>(OffsetValue)) {
3068 LoadedOffsetInAT = true;
3070 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3071 true, IDLoc, Instructions))
3074 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3075 // because it will make our output more similar to GAS'. For example,
3076 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3077 // instead of just an "ori $1, $9, 32768".
3078 // NOTE: If there is no source register specified in the ULHU, the parser
3079 // will interpret it as $0.
3080 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3081 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
3084 unsigned FirstLbuDstReg = LoadedOffsetInAT ? DstReg : ATReg;
3085 unsigned SecondLbuDstReg = LoadedOffsetInAT ? ATReg : DstReg;
3086 unsigned LbuSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3088 int64_t FirstLbuOffset = 0, SecondLbuOffset = 0;
3090 FirstLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
3091 SecondLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3093 FirstLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3094 SecondLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
3097 unsigned SllReg = LoadedOffsetInAT ? DstReg : ATReg;
3099 emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
3100 FirstLbuOffset, IDLoc, Instructions);
3102 emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondLbuOffset, IDLoc,
3105 emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, Instructions);
3107 emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, Instructions);
3112 bool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc,
3113 SmallVectorImpl<MCInst> &Instructions) {
3114 if (hasMips32r6() || hasMips64r6()) {
3115 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3119 const MCOperand &DstRegOp = Inst.getOperand(0);
3120 assert(DstRegOp.isReg() && "expected register operand kind");
3122 const MCOperand &SrcRegOp = Inst.getOperand(1);
3123 assert(SrcRegOp.isReg() && "expected register operand kind");
3125 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3126 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3128 unsigned SrcReg = SrcRegOp.getReg();
3129 int64_t OffsetValue = OffsetImmOp.getImm();
3132 // When the value of offset+3 does not fit in 16 bits, we have to load the
3133 // offset in AT, (D)ADDu the original source register (if there was one), and
3134 // then use AT as the source register for the generated LWL and LWR.
3135 bool LoadedOffsetInAT = false;
3136 if (!isInt<16>(OffsetValue + 3) || !isInt<16>(OffsetValue)) {
3137 ATReg = getATReg(IDLoc);
3140 LoadedOffsetInAT = true;
3142 warnIfNoMacro(IDLoc);
3144 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3145 true, IDLoc, Instructions))
3148 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3149 // because it will make our output more similar to GAS'. For example,
3150 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3151 // instead of just an "ori $1, $9, 32768".
3152 // NOTE: If there is no source register specified in the ULW, the parser
3153 // will interpret it as $0.
3154 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3155 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
3158 unsigned FinalSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3159 int64_t LeftLoadOffset = 0, RightLoadOffset = 0;
3161 LeftLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3162 RightLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3164 LeftLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3165 RightLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3168 emitRRI(Mips::LWL, DstRegOp.getReg(), FinalSrcReg, LeftLoadOffset, IDLoc,
3171 emitRRI(Mips::LWR, DstRegOp.getReg(), FinalSrcReg, RightLoadOffset, IDLoc,
3177 bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
3178 SmallVectorImpl<MCInst> &Instructions) {
3180 assert (Inst.getNumOperands() == 3 && "Invalid operand count");
3181 assert (Inst.getOperand(0).isReg() &&
3182 Inst.getOperand(1).isReg() &&
3183 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
3185 unsigned ATReg = Mips::NoRegister;
3186 unsigned FinalDstReg = Mips::NoRegister;
3187 unsigned DstReg = Inst.getOperand(0).getReg();
3188 unsigned SrcReg = Inst.getOperand(1).getReg();
3189 int64_t ImmValue = Inst.getOperand(2).getImm();
3191 bool Is32Bit = isInt<32>(ImmValue) || isUInt<32>(ImmValue);
3193 unsigned FinalOpcode = Inst.getOpcode();
3195 if (DstReg == SrcReg) {
3196 ATReg = getATReg(Inst.getLoc());
3199 FinalDstReg = DstReg;
3203 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false, Inst.getLoc(), Instructions)) {
3204 switch (FinalOpcode) {
3206 llvm_unreachable("unimplemented expansion");
3208 FinalOpcode = Mips::ADD;
3211 FinalOpcode = Mips::ADDu;
3214 FinalOpcode = Mips::AND;
3216 case (Mips::NORImm):
3217 FinalOpcode = Mips::NOR;
3220 FinalOpcode = Mips::OR;
3223 FinalOpcode = Mips::SLT;
3226 FinalOpcode = Mips::SLTu;
3229 FinalOpcode = Mips::XOR;
3233 if (FinalDstReg == Mips::NoRegister)
3234 emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, Instructions);
3236 emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc,
3243 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
3244 SmallVectorImpl<MCInst> &Instructions) {
3245 if (hasShortDelaySlot)
3246 emitRR(Mips::MOVE16_MM, Mips::ZERO, Mips::ZERO, IDLoc, Instructions);
3248 emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, Instructions);
3251 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
3252 unsigned TrgReg, bool Is64Bit,
3253 SmallVectorImpl<MCInst> &Instructions) {
3254 emitRRR(Is64Bit ? Mips::DADDu : Mips::ADDu, DstReg, SrcReg, TrgReg, SMLoc(),
3258 void MipsAsmParser::createCpRestoreMemOp(
3259 bool IsLoad, int StackOffset, SMLoc IDLoc,
3260 SmallVectorImpl<MCInst> &Instructions) {
3261 // If the offset can not fit into 16 bits, we need to expand.
3262 if (!isInt<16>(StackOffset)) {
3264 MemInst.setOpcode(IsLoad ? Mips::LW : Mips::SW);
3265 MemInst.addOperand(MCOperand::createReg(Mips::GP));
3266 MemInst.addOperand(MCOperand::createReg(Mips::SP));
3267 MemInst.addOperand(MCOperand::createImm(StackOffset));
3268 expandMemInst(MemInst, IDLoc, Instructions, IsLoad, true /*HasImmOpnd*/);
3272 emitRRI(IsLoad ? Mips::LW : Mips::SW, Mips::GP, Mips::SP, StackOffset, IDLoc,
3276 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3277 // As described by the Mips32r2 spec, the registers Rd and Rs for
3278 // jalr.hb must be different.
3279 unsigned Opcode = Inst.getOpcode();
3281 if (Opcode == Mips::JALR_HB &&
3282 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
3283 return Match_RequiresDifferentSrcAndDst;
3285 return Match_Success;
3288 static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands,
3289 uint64_t ErrorInfo) {
3290 if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) {
3291 SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc();
3292 if (ErrorLoc == SMLoc())
3299 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
3300 OperandVector &Operands,
3302 uint64_t &ErrorInfo,
3303 bool MatchingInlineAsm) {
3306 SmallVector<MCInst, 8> Instructions;
3307 unsigned MatchResult =
3308 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
3310 switch (MatchResult) {
3311 case Match_Success: {
3312 if (processInstruction(Inst, IDLoc, Instructions))
3314 for (unsigned i = 0; i < Instructions.size(); i++)
3315 Out.EmitInstruction(Instructions[i], getSTI());
3318 case Match_MissingFeature:
3319 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
3321 case Match_InvalidOperand: {
3322 SMLoc ErrorLoc = IDLoc;
3323 if (ErrorInfo != ~0ULL) {
3324 if (ErrorInfo >= Operands.size())
3325 return Error(IDLoc, "too few operands for instruction");
3327 ErrorLoc = Operands[ErrorInfo]->getStartLoc();
3328 if (ErrorLoc == SMLoc())
3332 return Error(ErrorLoc, "invalid operand for instruction");
3334 case Match_MnemonicFail:
3335 return Error(IDLoc, "invalid instruction");
3336 case Match_RequiresDifferentSrcAndDst:
3337 return Error(IDLoc, "source and destination must be different");
3339 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'");
3341 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3342 "expected 1-bit unsigned immediate");
3344 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3345 "expected 2-bit unsigned immediate");
3347 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3348 "expected immediate in range 1 .. 4");
3350 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3351 "expected 3-bit unsigned immediate");
3353 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3354 "expected 4-bit unsigned immediate");
3357 llvm_unreachable("Implement any new match types added!");
3360 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
3361 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
3362 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
3363 ") without \".set noat\"");
3366 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
3367 if (!AssemblerOptions.back()->isMacro())
3368 Warning(Loc, "macro instruction expanded into multiple instructions");
3372 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
3373 SMRange Range, bool ShowColors) {
3374 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
3375 Range, SMFixIt(Range, FixMsg),
3379 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
3382 CC = StringSwitch<unsigned>(Name)
3418 if (!(isABI_N32() || isABI_N64()))
3421 if (12 <= CC && CC <= 15) {
3422 // Name is one of t4-t7
3423 AsmToken RegTok = getLexer().peekTok();
3424 SMRange RegRange = RegTok.getLocRange();
3426 StringRef FixedName = StringSwitch<StringRef>(Name)
3432 assert(FixedName != "" && "Register name is not one of t4-t7.");
3434 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
3435 "Did you mean $" + FixedName + "?", RegRange);
3438 // Although SGI documentation just cuts out t0-t3 for n32/n64,
3439 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
3440 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
3441 if (8 <= CC && CC <= 11)
3445 CC = StringSwitch<unsigned>(Name)
3457 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
3460 CC = StringSwitch<unsigned>(Name)
3461 .Case("hwr_cpunum", 0)
3462 .Case("hwr_synci_step", 1)
3464 .Case("hwr_ccres", 3)
3465 .Case("hwr_ulr", 29)
3471 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
3473 if (Name[0] == 'f') {
3474 StringRef NumString = Name.substr(1);
3476 if (NumString.getAsInteger(10, IntVal))
3477 return -1; // This is not an integer.
3478 if (IntVal > 31) // Maximum index for fpu register.
3485 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
3487 if (Name.startswith("fcc")) {
3488 StringRef NumString = Name.substr(3);
3490 if (NumString.getAsInteger(10, IntVal))
3491 return -1; // This is not an integer.
3492 if (IntVal > 7) // There are only 8 fcc registers.
3499 int MipsAsmParser::matchACRegisterName(StringRef Name) {
3501 if (Name.startswith("ac")) {
3502 StringRef NumString = Name.substr(2);
3504 if (NumString.getAsInteger(10, IntVal))
3505 return -1; // This is not an integer.
3506 if (IntVal > 3) // There are only 3 acc registers.
3513 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
3516 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
3525 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
3528 CC = StringSwitch<unsigned>(Name)
3531 .Case("msaaccess", 2)
3533 .Case("msamodify", 4)
3534 .Case("msarequest", 5)
3536 .Case("msaunmap", 7)
3542 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
3543 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
3545 reportParseError(Loc,
3546 "pseudo-instruction requires $at, which is not available");
3549 unsigned AT = getReg(
3550 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
3554 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
3555 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
3558 unsigned MipsAsmParser::getGPR(int RegNo) {
3559 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
3563 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
3565 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
3568 return getReg(RegClass, RegNum);
3571 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
3572 MCAsmParser &Parser = getParser();
3573 DEBUG(dbgs() << "parseOperand\n");
3575 // Check if the current operand has a custom associated parser, if so, try to
3576 // custom parse the operand, or fallback to the general approach.
3577 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
3578 if (ResTy == MatchOperand_Success)
3580 // If there wasn't a custom match, try the generic matcher below. Otherwise,
3581 // there was a match, but an error occurred, in which case, just return that
3582 // the operand parsing failed.
3583 if (ResTy == MatchOperand_ParseFail)
3586 DEBUG(dbgs() << ".. Generic Parser\n");
3588 switch (getLexer().getKind()) {
3590 Error(Parser.getTok().getLoc(), "unexpected token in operand");
3592 case AsmToken::Dollar: {
3593 // Parse the register.
3594 SMLoc S = Parser.getTok().getLoc();
3596 // Almost all registers have been parsed by custom parsers. There is only
3597 // one exception to this. $zero (and it's alias $0) will reach this point
3598 // for div, divu, and similar instructions because it is not an operand
3599 // to the instruction definition but an explicit register. Special case
3600 // this situation for now.
3601 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
3604 // Maybe it is a symbol reference.
3605 StringRef Identifier;
3606 if (Parser.parseIdentifier(Identifier))
3609 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3610 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
3611 // Otherwise create a symbol reference.
3613 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3615 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
3618 // Else drop to expression parsing.
3619 case AsmToken::LParen:
3620 case AsmToken::Minus:
3621 case AsmToken::Plus:
3622 case AsmToken::Integer:
3623 case AsmToken::Tilde:
3624 case AsmToken::String: {
3625 DEBUG(dbgs() << ".. generic integer\n");
3626 OperandMatchResultTy ResTy = parseImm(Operands);
3627 return ResTy != MatchOperand_Success;
3629 case AsmToken::Percent: {
3630 // It is a symbol reference or constant expression.
3631 const MCExpr *IdVal;
3632 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
3633 if (parseRelocOperand(IdVal))
3636 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3638 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3640 } // case AsmToken::Percent
3641 } // switch(getLexer().getKind())
3645 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
3646 StringRef RelocStr) {
3648 // Check the type of the expression.
3649 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
3650 // It's a constant, evaluate reloc value.
3652 switch (getVariantKind(RelocStr)) {
3653 case MCSymbolRefExpr::VK_Mips_ABS_LO:
3654 // Get the 1st 16-bits.
3655 Val = MCE->getValue() & 0xffff;
3657 case MCSymbolRefExpr::VK_Mips_ABS_HI:
3658 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
3659 // 16 bits being negative.
3660 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
3662 case MCSymbolRefExpr::VK_Mips_HIGHER:
3663 // Get the 3rd 16-bits.
3664 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
3666 case MCSymbolRefExpr::VK_Mips_HIGHEST:
3667 // Get the 4th 16-bits.
3668 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
3671 report_fatal_error("unsupported reloc value");
3673 return MCConstantExpr::create(Val, getContext());
3676 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
3677 // It's a symbol, create a symbolic expression from the symbol.
3678 const MCSymbol *Symbol = &MSRE->getSymbol();
3679 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3680 Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
3684 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3685 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3687 // Try to create target expression.
3688 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
3689 return MipsMCExpr::create(VK, Expr, getContext());
3691 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
3692 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
3693 Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
3697 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
3698 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
3699 Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
3702 // Just return the original expression.
3706 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
3708 switch (Expr->getKind()) {
3709 case MCExpr::Constant:
3711 case MCExpr::SymbolRef:
3712 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
3713 case MCExpr::Binary:
3714 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3715 if (!isEvaluated(BE->getLHS()))
3717 return isEvaluated(BE->getRHS());
3720 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
3721 case MCExpr::Target:
3727 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
3728 MCAsmParser &Parser = getParser();
3729 Parser.Lex(); // Eat the % token.
3730 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
3731 if (Tok.isNot(AsmToken::Identifier))
3734 std::string Str = Tok.getIdentifier();
3736 Parser.Lex(); // Eat the identifier.
3737 // Now make an expression from the rest of the operand.
3738 const MCExpr *IdVal;
3741 if (getLexer().getKind() == AsmToken::LParen) {
3743 Parser.Lex(); // Eat the '(' token.
3744 if (getLexer().getKind() == AsmToken::Percent) {
3745 Parser.Lex(); // Eat the % token.
3746 const AsmToken &nextTok = Parser.getTok();
3747 if (nextTok.isNot(AsmToken::Identifier))
3750 Str += nextTok.getIdentifier();
3751 Parser.Lex(); // Eat the identifier.
3752 if (getLexer().getKind() != AsmToken::LParen)
3757 if (getParser().parseParenExpression(IdVal, EndLoc))
3760 while (getLexer().getKind() == AsmToken::RParen)
3761 Parser.Lex(); // Eat the ')' token.
3764 return true; // Parenthesis must follow the relocation operand.
3766 Res = evaluateRelocExpr(IdVal, Str);
3770 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
3772 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
3773 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
3774 if (ResTy == MatchOperand_Success) {
3775 assert(Operands.size() == 1);
3776 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
3777 StartLoc = Operand.getStartLoc();
3778 EndLoc = Operand.getEndLoc();
3780 // AFAIK, we only support numeric registers and named GPR's in CFI
3782 // Don't worry about eating tokens before failing. Using an unrecognised
3783 // register is a parse error.
3784 if (Operand.isGPRAsmReg()) {
3785 // Resolve to GPR32 or GPR64 appropriately.
3786 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
3789 return (RegNo == (unsigned)-1);
3792 assert(Operands.size() == 0);
3793 return (RegNo == (unsigned)-1);
3796 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
3797 MCAsmParser &Parser = getParser();
3800 unsigned NumOfLParen = 0;
3802 while (getLexer().getKind() == AsmToken::LParen) {
3807 switch (getLexer().getKind()) {
3810 case AsmToken::Identifier:
3811 case AsmToken::LParen:
3812 case AsmToken::Integer:
3813 case AsmToken::Minus:
3814 case AsmToken::Plus:
3816 Result = getParser().parseParenExprOfDepth(NumOfLParen, Res, S);
3818 Result = (getParser().parseExpression(Res));
3819 while (getLexer().getKind() == AsmToken::RParen)
3822 case AsmToken::Percent:
3823 Result = parseRelocOperand(Res);
3828 MipsAsmParser::OperandMatchResultTy
3829 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
3830 MCAsmParser &Parser = getParser();
3831 DEBUG(dbgs() << "parseMemOperand\n");
3832 const MCExpr *IdVal = nullptr;
3834 bool isParenExpr = false;
3835 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
3836 // First operand is the offset.
3837 S = Parser.getTok().getLoc();
3839 if (getLexer().getKind() == AsmToken::LParen) {
3844 if (getLexer().getKind() != AsmToken::Dollar) {
3845 if (parseMemOffset(IdVal, isParenExpr))
3846 return MatchOperand_ParseFail;
3848 const AsmToken &Tok = Parser.getTok(); // Get the next token.
3849 if (Tok.isNot(AsmToken::LParen)) {
3850 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
3851 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
3853 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3854 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3855 return MatchOperand_Success;
3857 if (Tok.is(AsmToken::EndOfStatement)) {
3859 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3861 // Zero register assumed, add a memory operand with ZERO as its base.
3862 // "Base" will be managed by k_Memory.
3863 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
3866 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
3867 return MatchOperand_Success;
3869 Error(Parser.getTok().getLoc(), "'(' expected");
3870 return MatchOperand_ParseFail;
3873 Parser.Lex(); // Eat the '(' token.
3876 Res = parseAnyRegister(Operands);
3877 if (Res != MatchOperand_Success)
3880 if (Parser.getTok().isNot(AsmToken::RParen)) {
3881 Error(Parser.getTok().getLoc(), "')' expected");
3882 return MatchOperand_ParseFail;
3885 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3887 Parser.Lex(); // Eat the ')' token.
3890 IdVal = MCConstantExpr::create(0, getContext());
3892 // Replace the register operand with the memory operand.
3893 std::unique_ptr<MipsOperand> op(
3894 static_cast<MipsOperand *>(Operands.back().release()));
3895 // Remove the register from the operands.
3896 // "op" will be managed by k_Memory.
3897 Operands.pop_back();
3898 // Add the memory operand.
3899 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
3901 if (IdVal->evaluateAsAbsolute(Imm))
3902 IdVal = MCConstantExpr::create(Imm, getContext());
3903 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
3904 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
3908 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
3909 return MatchOperand_Success;
3912 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
3913 MCAsmParser &Parser = getParser();
3914 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
3916 SMLoc S = Parser.getTok().getLoc();
3918 if (Sym->isVariable())
3919 Expr = Sym->getVariableValue();
3922 if (Expr->getKind() == MCExpr::SymbolRef) {
3923 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3924 StringRef DefSymbol = Ref->getSymbol().getName();
3925 if (DefSymbol.startswith("$")) {
3926 OperandMatchResultTy ResTy =
3927 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
3928 if (ResTy == MatchOperand_Success) {
3931 } else if (ResTy == MatchOperand_ParseFail)
3932 llvm_unreachable("Should never ParseFail");
3935 } else if (Expr->getKind() == MCExpr::Constant) {
3937 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
3939 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
3946 MipsAsmParser::OperandMatchResultTy
3947 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
3948 StringRef Identifier,
3950 int Index = matchCPURegisterName(Identifier);
3952 Operands.push_back(MipsOperand::createGPRReg(
3953 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3954 return MatchOperand_Success;
3957 Index = matchHWRegsRegisterName(Identifier);
3959 Operands.push_back(MipsOperand::createHWRegsReg(
3960 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3961 return MatchOperand_Success;
3964 Index = matchFPURegisterName(Identifier);
3966 Operands.push_back(MipsOperand::createFGRReg(
3967 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3968 return MatchOperand_Success;
3971 Index = matchFCCRegisterName(Identifier);
3973 Operands.push_back(MipsOperand::createFCCReg(
3974 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3975 return MatchOperand_Success;
3978 Index = matchACRegisterName(Identifier);
3980 Operands.push_back(MipsOperand::createACCReg(
3981 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3982 return MatchOperand_Success;
3985 Index = matchMSA128RegisterName(Identifier);
3987 Operands.push_back(MipsOperand::createMSA128Reg(
3988 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3989 return MatchOperand_Success;
3992 Index = matchMSA128CtrlRegisterName(Identifier);
3994 Operands.push_back(MipsOperand::createMSACtrlReg(
3995 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3996 return MatchOperand_Success;
3999 return MatchOperand_NoMatch;
4002 MipsAsmParser::OperandMatchResultTy
4003 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
4004 MCAsmParser &Parser = getParser();
4005 auto Token = Parser.getLexer().peekTok(false);
4007 if (Token.is(AsmToken::Identifier)) {
4008 DEBUG(dbgs() << ".. identifier\n");
4009 StringRef Identifier = Token.getIdentifier();
4010 OperandMatchResultTy ResTy =
4011 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
4013 } else if (Token.is(AsmToken::Integer)) {
4014 DEBUG(dbgs() << ".. integer\n");
4015 Operands.push_back(MipsOperand::createNumericReg(
4016 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
4018 return MatchOperand_Success;
4021 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
4023 return MatchOperand_NoMatch;
4026 MipsAsmParser::OperandMatchResultTy
4027 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
4028 MCAsmParser &Parser = getParser();
4029 DEBUG(dbgs() << "parseAnyRegister\n");
4031 auto Token = Parser.getTok();
4033 SMLoc S = Token.getLoc();
4035 if (Token.isNot(AsmToken::Dollar)) {
4036 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
4037 if (Token.is(AsmToken::Identifier)) {
4038 if (searchSymbolAlias(Operands))
4039 return MatchOperand_Success;
4041 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
4042 return MatchOperand_NoMatch;
4044 DEBUG(dbgs() << ".. $\n");
4046 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
4047 if (ResTy == MatchOperand_Success) {
4049 Parser.Lex(); // identifier
4054 MipsAsmParser::OperandMatchResultTy
4055 MipsAsmParser::parseImm(OperandVector &Operands) {
4056 MCAsmParser &Parser = getParser();
4057 switch (getLexer().getKind()) {
4059 return MatchOperand_NoMatch;
4060 case AsmToken::LParen:
4061 case AsmToken::Minus:
4062 case AsmToken::Plus:
4063 case AsmToken::Integer:
4064 case AsmToken::Tilde:
4065 case AsmToken::String:
4069 const MCExpr *IdVal;
4070 SMLoc S = Parser.getTok().getLoc();
4071 if (getParser().parseExpression(IdVal))
4072 return MatchOperand_ParseFail;
4074 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4075 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
4076 return MatchOperand_Success;
4079 MipsAsmParser::OperandMatchResultTy
4080 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
4081 MCAsmParser &Parser = getParser();
4082 DEBUG(dbgs() << "parseJumpTarget\n");
4084 SMLoc S = getLexer().getLoc();
4086 // Integers and expressions are acceptable
4087 OperandMatchResultTy ResTy = parseImm(Operands);
4088 if (ResTy != MatchOperand_NoMatch)
4091 // Registers are a valid target and have priority over symbols.
4092 ResTy = parseAnyRegister(Operands);
4093 if (ResTy != MatchOperand_NoMatch)
4096 const MCExpr *Expr = nullptr;
4097 if (Parser.parseExpression(Expr)) {
4098 // We have no way of knowing if a symbol was consumed so we must ParseFail
4099 return MatchOperand_ParseFail;
4102 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
4103 return MatchOperand_Success;
4106 MipsAsmParser::OperandMatchResultTy
4107 MipsAsmParser::parseInvNum(OperandVector &Operands) {
4108 MCAsmParser &Parser = getParser();
4109 const MCExpr *IdVal;
4110 // If the first token is '$' we may have register operand.
4111 if (Parser.getTok().is(AsmToken::Dollar))
4112 return MatchOperand_NoMatch;
4113 SMLoc S = Parser.getTok().getLoc();
4114 if (getParser().parseExpression(IdVal))
4115 return MatchOperand_ParseFail;
4116 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
4117 assert(MCE && "Unexpected MCExpr type.");
4118 int64_t Val = MCE->getValue();
4119 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4120 Operands.push_back(MipsOperand::CreateImm(
4121 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
4122 return MatchOperand_Success;
4125 MipsAsmParser::OperandMatchResultTy
4126 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
4127 MCAsmParser &Parser = getParser();
4128 switch (getLexer().getKind()) {
4130 return MatchOperand_NoMatch;
4131 case AsmToken::LParen:
4132 case AsmToken::Plus:
4133 case AsmToken::Minus:
4134 case AsmToken::Integer:
4139 SMLoc S = Parser.getTok().getLoc();
4141 if (getParser().parseExpression(Expr))
4142 return MatchOperand_ParseFail;
4145 if (!Expr->evaluateAsAbsolute(Val)) {
4146 Error(S, "expected immediate value");
4147 return MatchOperand_ParseFail;
4150 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
4151 // and because the CPU always adds one to the immediate field, the allowed
4152 // range becomes 1..4. We'll only check the range here and will deal
4153 // with the addition/subtraction when actually decoding/encoding
4155 if (Val < 1 || Val > 4) {
4156 Error(S, "immediate not in range (1..4)");
4157 return MatchOperand_ParseFail;
4161 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
4162 return MatchOperand_Success;
4165 MipsAsmParser::OperandMatchResultTy
4166 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
4167 MCAsmParser &Parser = getParser();
4168 SmallVector<unsigned, 10> Regs;
4170 unsigned PrevReg = Mips::NoRegister;
4171 bool RegRange = false;
4172 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4174 if (Parser.getTok().isNot(AsmToken::Dollar))
4175 return MatchOperand_ParseFail;
4177 SMLoc S = Parser.getTok().getLoc();
4178 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
4179 SMLoc E = getLexer().getLoc();
4180 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
4181 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
4183 // Remove last register operand because registers from register range
4184 // should be inserted first.
4185 if ((isGP64bit() && RegNo == Mips::RA_64) ||
4186 (!isGP64bit() && RegNo == Mips::RA)) {
4187 Regs.push_back(RegNo);
4189 unsigned TmpReg = PrevReg + 1;
4190 while (TmpReg <= RegNo) {
4191 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
4192 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
4194 Error(E, "invalid register operand");
4195 return MatchOperand_ParseFail;
4199 Regs.push_back(TmpReg++);
4205 if ((PrevReg == Mips::NoRegister) &&
4206 ((isGP64bit() && (RegNo != Mips::S0_64) && (RegNo != Mips::RA_64)) ||
4207 (!isGP64bit() && (RegNo != Mips::S0) && (RegNo != Mips::RA)))) {
4208 Error(E, "$16 or $31 expected");
4209 return MatchOperand_ParseFail;
4210 } else if (!(((RegNo == Mips::FP || RegNo == Mips::RA ||
4211 (RegNo >= Mips::S0 && RegNo <= Mips::S7)) &&
4213 ((RegNo == Mips::FP_64 || RegNo == Mips::RA_64 ||
4214 (RegNo >= Mips::S0_64 && RegNo <= Mips::S7_64)) &&
4216 Error(E, "invalid register operand");
4217 return MatchOperand_ParseFail;
4218 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
4219 ((RegNo != Mips::FP && RegNo != Mips::RA && !isGP64bit()) ||
4220 (RegNo != Mips::FP_64 && RegNo != Mips::RA_64 &&
4222 Error(E, "consecutive register numbers expected");
4223 return MatchOperand_ParseFail;
4226 Regs.push_back(RegNo);
4229 if (Parser.getTok().is(AsmToken::Minus))
4232 if (!Parser.getTok().isNot(AsmToken::Minus) &&
4233 !Parser.getTok().isNot(AsmToken::Comma)) {
4234 Error(E, "',' or '-' expected");
4235 return MatchOperand_ParseFail;
4238 Lex(); // Consume comma or minus
4239 if (Parser.getTok().isNot(AsmToken::Dollar))
4245 SMLoc E = Parser.getTok().getLoc();
4246 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4247 parseMemOperand(Operands);
4248 return MatchOperand_Success;
4251 MipsAsmParser::OperandMatchResultTy
4252 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
4253 MCAsmParser &Parser = getParser();
4255 SMLoc S = Parser.getTok().getLoc();
4256 if (parseAnyRegister(Operands) != MatchOperand_Success)
4257 return MatchOperand_ParseFail;
4259 SMLoc E = Parser.getTok().getLoc();
4260 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
4261 unsigned Reg = Op.getGPR32Reg();
4262 Operands.pop_back();
4263 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
4264 return MatchOperand_Success;
4267 MipsAsmParser::OperandMatchResultTy
4268 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
4269 MCAsmParser &Parser = getParser();
4270 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4271 SmallVector<unsigned, 10> Regs;
4273 if (Parser.getTok().isNot(AsmToken::Dollar))
4274 return MatchOperand_ParseFail;
4276 SMLoc S = Parser.getTok().getLoc();
4278 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4279 return MatchOperand_ParseFail;
4281 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4282 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4283 Regs.push_back(RegNo);
4285 SMLoc E = Parser.getTok().getLoc();
4286 if (Parser.getTok().isNot(AsmToken::Comma)) {
4287 Error(E, "',' expected");
4288 return MatchOperand_ParseFail;
4294 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4295 return MatchOperand_ParseFail;
4297 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4298 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4299 Regs.push_back(RegNo);
4301 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4303 return MatchOperand_Success;
4306 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
4308 MCSymbolRefExpr::VariantKind VK =
4309 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
4310 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
4311 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
4312 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
4313 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
4314 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
4315 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
4316 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
4317 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
4318 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
4319 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
4320 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
4321 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
4322 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
4323 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
4324 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
4325 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
4326 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
4327 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
4328 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
4329 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
4330 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
4331 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
4332 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
4333 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
4334 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
4335 .Default(MCSymbolRefExpr::VK_None);
4337 assert(VK != MCSymbolRefExpr::VK_None);
4342 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
4344 /// ::= '(', register, ')'
4345 /// handle it before we iterate so we don't get tripped up by the lack of
4347 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
4348 MCAsmParser &Parser = getParser();
4349 if (getLexer().is(AsmToken::LParen)) {
4351 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
4353 if (parseOperand(Operands, Name)) {
4354 SMLoc Loc = getLexer().getLoc();
4355 Parser.eatToEndOfStatement();
4356 return Error(Loc, "unexpected token in argument list");
4358 if (Parser.getTok().isNot(AsmToken::RParen)) {
4359 SMLoc Loc = getLexer().getLoc();
4360 Parser.eatToEndOfStatement();
4361 return Error(Loc, "unexpected token, expected ')'");
4364 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
4370 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
4371 /// either one of these.
4372 /// ::= '[', register, ']'
4373 /// ::= '[', integer, ']'
4374 /// handle it before we iterate so we don't get tripped up by the lack of
4376 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
4377 OperandVector &Operands) {
4378 MCAsmParser &Parser = getParser();
4379 if (getLexer().is(AsmToken::LBrac)) {
4381 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
4383 if (parseOperand(Operands, Name)) {
4384 SMLoc Loc = getLexer().getLoc();
4385 Parser.eatToEndOfStatement();
4386 return Error(Loc, "unexpected token in argument list");
4388 if (Parser.getTok().isNot(AsmToken::RBrac)) {
4389 SMLoc Loc = getLexer().getLoc();
4390 Parser.eatToEndOfStatement();
4391 return Error(Loc, "unexpected token, expected ']'");
4394 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
4400 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
4401 SMLoc NameLoc, OperandVector &Operands) {
4402 MCAsmParser &Parser = getParser();
4403 DEBUG(dbgs() << "ParseInstruction\n");
4405 // We have reached first instruction, module directive are now forbidden.
4406 getTargetStreamer().forbidModuleDirective();
4408 // Check if we have valid mnemonic
4409 if (!mnemonicIsValid(Name, 0)) {
4410 Parser.eatToEndOfStatement();
4411 return Error(NameLoc, "unknown instruction");
4413 // First operand in MCInst is instruction mnemonic.
4414 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
4416 // Read the remaining operands.
4417 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4418 // Read the first operand.
4419 if (parseOperand(Operands, Name)) {
4420 SMLoc Loc = getLexer().getLoc();
4421 Parser.eatToEndOfStatement();
4422 return Error(Loc, "unexpected token in argument list");
4424 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
4426 // AFAIK, parenthesis suffixes are never on the first operand
4428 while (getLexer().is(AsmToken::Comma)) {
4429 Parser.Lex(); // Eat the comma.
4430 // Parse and remember the operand.
4431 if (parseOperand(Operands, Name)) {
4432 SMLoc Loc = getLexer().getLoc();
4433 Parser.eatToEndOfStatement();
4434 return Error(Loc, "unexpected token in argument list");
4436 // Parse bracket and parenthesis suffixes before we iterate
4437 if (getLexer().is(AsmToken::LBrac)) {
4438 if (parseBracketSuffix(Name, Operands))
4440 } else if (getLexer().is(AsmToken::LParen) &&
4441 parseParenSuffix(Name, Operands))
4445 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4446 SMLoc Loc = getLexer().getLoc();
4447 Parser.eatToEndOfStatement();
4448 return Error(Loc, "unexpected token in argument list");
4450 Parser.Lex(); // Consume the EndOfStatement.
4454 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
4455 MCAsmParser &Parser = getParser();
4456 SMLoc Loc = getLexer().getLoc();
4457 Parser.eatToEndOfStatement();
4458 return Error(Loc, ErrorMsg);
4461 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
4462 return Error(Loc, ErrorMsg);
4465 bool MipsAsmParser::parseSetNoAtDirective() {
4466 MCAsmParser &Parser = getParser();
4467 // Line should look like: ".set noat".
4469 // Set the $at register to $0.
4470 AssemblerOptions.back()->setATRegIndex(0);
4472 Parser.Lex(); // Eat "noat".
4474 // If this is not the end of the statement, report an error.
4475 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4476 reportParseError("unexpected token, expected end of statement");
4480 getTargetStreamer().emitDirectiveSetNoAt();
4481 Parser.Lex(); // Consume the EndOfStatement.
4485 bool MipsAsmParser::parseSetAtDirective() {
4486 // Line can be: ".set at", which sets $at to $1
4487 // or ".set at=$reg", which sets $at to $reg.
4488 MCAsmParser &Parser = getParser();
4489 Parser.Lex(); // Eat "at".
4491 if (getLexer().is(AsmToken::EndOfStatement)) {
4492 // No register was specified, so we set $at to $1.
4493 AssemblerOptions.back()->setATRegIndex(1);
4495 getTargetStreamer().emitDirectiveSetAt();
4496 Parser.Lex(); // Consume the EndOfStatement.
4500 if (getLexer().isNot(AsmToken::Equal)) {
4501 reportParseError("unexpected token, expected equals sign");
4504 Parser.Lex(); // Eat "=".
4506 if (getLexer().isNot(AsmToken::Dollar)) {
4507 if (getLexer().is(AsmToken::EndOfStatement)) {
4508 reportParseError("no register specified");
4511 reportParseError("unexpected token, expected dollar sign '$'");
4515 Parser.Lex(); // Eat "$".
4517 // Find out what "reg" is.
4519 const AsmToken &Reg = Parser.getTok();
4520 if (Reg.is(AsmToken::Identifier)) {
4521 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
4522 } else if (Reg.is(AsmToken::Integer)) {
4523 AtRegNo = Reg.getIntVal();
4525 reportParseError("unexpected token, expected identifier or integer");
4529 // Check if $reg is a valid register. If it is, set $at to $reg.
4530 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
4531 reportParseError("invalid register");
4534 Parser.Lex(); // Eat "reg".
4536 // If this is not the end of the statement, report an error.
4537 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4538 reportParseError("unexpected token, expected end of statement");
4542 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
4544 Parser.Lex(); // Consume the EndOfStatement.
4548 bool MipsAsmParser::parseSetReorderDirective() {
4549 MCAsmParser &Parser = getParser();
4551 // If this is not the end of the statement, report an error.
4552 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4553 reportParseError("unexpected token, expected end of statement");
4556 AssemblerOptions.back()->setReorder();
4557 getTargetStreamer().emitDirectiveSetReorder();
4558 Parser.Lex(); // Consume the EndOfStatement.
4562 bool MipsAsmParser::parseSetNoReorderDirective() {
4563 MCAsmParser &Parser = getParser();
4565 // If this is not the end of the statement, report an error.
4566 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4567 reportParseError("unexpected token, expected end of statement");
4570 AssemblerOptions.back()->setNoReorder();
4571 getTargetStreamer().emitDirectiveSetNoReorder();
4572 Parser.Lex(); // Consume the EndOfStatement.
4576 bool MipsAsmParser::parseSetMacroDirective() {
4577 MCAsmParser &Parser = getParser();
4579 // If this is not the end of the statement, report an error.
4580 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4581 reportParseError("unexpected token, expected end of statement");
4584 AssemblerOptions.back()->setMacro();
4585 getTargetStreamer().emitDirectiveSetMacro();
4586 Parser.Lex(); // Consume the EndOfStatement.
4590 bool MipsAsmParser::parseSetNoMacroDirective() {
4591 MCAsmParser &Parser = getParser();
4593 // If this is not the end of the statement, report an error.
4594 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4595 reportParseError("unexpected token, expected end of statement");
4598 if (AssemblerOptions.back()->isReorder()) {
4599 reportParseError("`noreorder' must be set before `nomacro'");
4602 AssemblerOptions.back()->setNoMacro();
4603 getTargetStreamer().emitDirectiveSetNoMacro();
4604 Parser.Lex(); // Consume the EndOfStatement.
4608 bool MipsAsmParser::parseSetMsaDirective() {
4609 MCAsmParser &Parser = getParser();
4612 // If this is not the end of the statement, report an error.
4613 if (getLexer().isNot(AsmToken::EndOfStatement))
4614 return reportParseError("unexpected token, expected end of statement");
4616 setFeatureBits(Mips::FeatureMSA, "msa");
4617 getTargetStreamer().emitDirectiveSetMsa();
4621 bool MipsAsmParser::parseSetNoMsaDirective() {
4622 MCAsmParser &Parser = getParser();
4625 // If this is not the end of the statement, report an error.
4626 if (getLexer().isNot(AsmToken::EndOfStatement))
4627 return reportParseError("unexpected token, expected end of statement");
4629 clearFeatureBits(Mips::FeatureMSA, "msa");
4630 getTargetStreamer().emitDirectiveSetNoMsa();
4634 bool MipsAsmParser::parseSetNoDspDirective() {
4635 MCAsmParser &Parser = getParser();
4636 Parser.Lex(); // Eat "nodsp".
4638 // If this is not the end of the statement, report an error.
4639 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4640 reportParseError("unexpected token, expected end of statement");
4644 clearFeatureBits(Mips::FeatureDSP, "dsp");
4645 getTargetStreamer().emitDirectiveSetNoDsp();
4649 bool MipsAsmParser::parseSetMips16Directive() {
4650 MCAsmParser &Parser = getParser();
4651 Parser.Lex(); // Eat "mips16".
4653 // If this is not the end of the statement, report an error.
4654 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4655 reportParseError("unexpected token, expected end of statement");
4659 setFeatureBits(Mips::FeatureMips16, "mips16");
4660 getTargetStreamer().emitDirectiveSetMips16();
4661 Parser.Lex(); // Consume the EndOfStatement.
4665 bool MipsAsmParser::parseSetNoMips16Directive() {
4666 MCAsmParser &Parser = getParser();
4667 Parser.Lex(); // Eat "nomips16".
4669 // If this is not the end of the statement, report an error.
4670 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4671 reportParseError("unexpected token, expected end of statement");
4675 clearFeatureBits(Mips::FeatureMips16, "mips16");
4676 getTargetStreamer().emitDirectiveSetNoMips16();
4677 Parser.Lex(); // Consume the EndOfStatement.
4681 bool MipsAsmParser::parseSetFpDirective() {
4682 MCAsmParser &Parser = getParser();
4683 MipsABIFlagsSection::FpABIKind FpAbiVal;
4684 // Line can be: .set fp=32
4687 Parser.Lex(); // Eat fp token
4688 AsmToken Tok = Parser.getTok();
4689 if (Tok.isNot(AsmToken::Equal)) {
4690 reportParseError("unexpected token, expected equals sign '='");
4693 Parser.Lex(); // Eat '=' token.
4694 Tok = Parser.getTok();
4696 if (!parseFpABIValue(FpAbiVal, ".set"))
4699 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4700 reportParseError("unexpected token, expected end of statement");
4703 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
4704 Parser.Lex(); // Consume the EndOfStatement.
4708 bool MipsAsmParser::parseSetOddSPRegDirective() {
4709 MCAsmParser &Parser = getParser();
4711 Parser.Lex(); // Eat "oddspreg".
4712 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4713 reportParseError("unexpected token, expected end of statement");
4717 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4718 getTargetStreamer().emitDirectiveSetOddSPReg();
4722 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
4723 MCAsmParser &Parser = getParser();
4725 Parser.Lex(); // Eat "nooddspreg".
4726 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4727 reportParseError("unexpected token, expected end of statement");
4731 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4732 getTargetStreamer().emitDirectiveSetNoOddSPReg();
4736 bool MipsAsmParser::parseSetPopDirective() {
4737 MCAsmParser &Parser = getParser();
4738 SMLoc Loc = getLexer().getLoc();
4741 if (getLexer().isNot(AsmToken::EndOfStatement))
4742 return reportParseError("unexpected token, expected end of statement");
4744 // Always keep an element on the options "stack" to prevent the user
4745 // from changing the initial options. This is how we remember them.
4746 if (AssemblerOptions.size() == 2)
4747 return reportParseError(Loc, ".set pop with no .set push");
4749 AssemblerOptions.pop_back();
4750 setAvailableFeatures(
4751 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
4752 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
4754 getTargetStreamer().emitDirectiveSetPop();
4758 bool MipsAsmParser::parseSetPushDirective() {
4759 MCAsmParser &Parser = getParser();
4761 if (getLexer().isNot(AsmToken::EndOfStatement))
4762 return reportParseError("unexpected token, expected end of statement");
4764 // Create a copy of the current assembler options environment and push it.
4765 AssemblerOptions.push_back(
4766 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
4768 getTargetStreamer().emitDirectiveSetPush();
4772 bool MipsAsmParser::parseSetSoftFloatDirective() {
4773 MCAsmParser &Parser = getParser();
4775 if (getLexer().isNot(AsmToken::EndOfStatement))
4776 return reportParseError("unexpected token, expected end of statement");
4778 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4779 getTargetStreamer().emitDirectiveSetSoftFloat();
4783 bool MipsAsmParser::parseSetHardFloatDirective() {
4784 MCAsmParser &Parser = getParser();
4786 if (getLexer().isNot(AsmToken::EndOfStatement))
4787 return reportParseError("unexpected token, expected end of statement");
4789 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4790 getTargetStreamer().emitDirectiveSetHardFloat();
4794 bool MipsAsmParser::parseSetAssignment() {
4796 const MCExpr *Value;
4797 MCAsmParser &Parser = getParser();
4799 if (Parser.parseIdentifier(Name))
4800 reportParseError("expected identifier after .set");
4802 if (getLexer().isNot(AsmToken::Comma))
4803 return reportParseError("unexpected token, expected comma");
4806 if (Parser.parseExpression(Value))
4807 return reportParseError("expected valid expression after comma");
4809 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4810 Sym->setVariableValue(Value);
4815 bool MipsAsmParser::parseSetMips0Directive() {
4816 MCAsmParser &Parser = getParser();
4818 if (getLexer().isNot(AsmToken::EndOfStatement))
4819 return reportParseError("unexpected token, expected end of statement");
4821 // Reset assembler options to their initial values.
4822 setAvailableFeatures(
4823 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
4824 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
4825 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
4827 getTargetStreamer().emitDirectiveSetMips0();
4831 bool MipsAsmParser::parseSetArchDirective() {
4832 MCAsmParser &Parser = getParser();
4834 if (getLexer().isNot(AsmToken::Equal))
4835 return reportParseError("unexpected token, expected equals sign");
4839 if (Parser.parseIdentifier(Arch))
4840 return reportParseError("expected arch identifier");
4842 StringRef ArchFeatureName =
4843 StringSwitch<StringRef>(Arch)
4844 .Case("mips1", "mips1")
4845 .Case("mips2", "mips2")
4846 .Case("mips3", "mips3")
4847 .Case("mips4", "mips4")
4848 .Case("mips5", "mips5")
4849 .Case("mips32", "mips32")
4850 .Case("mips32r2", "mips32r2")
4851 .Case("mips32r3", "mips32r3")
4852 .Case("mips32r5", "mips32r5")
4853 .Case("mips32r6", "mips32r6")
4854 .Case("mips64", "mips64")
4855 .Case("mips64r2", "mips64r2")
4856 .Case("mips64r3", "mips64r3")
4857 .Case("mips64r5", "mips64r5")
4858 .Case("mips64r6", "mips64r6")
4859 .Case("cnmips", "cnmips")
4860 .Case("r4000", "mips3") // This is an implementation of Mips3.
4863 if (ArchFeatureName.empty())
4864 return reportParseError("unsupported architecture");
4866 selectArch(ArchFeatureName);
4867 getTargetStreamer().emitDirectiveSetArch(Arch);
4871 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
4872 MCAsmParser &Parser = getParser();
4874 if (getLexer().isNot(AsmToken::EndOfStatement))
4875 return reportParseError("unexpected token, expected end of statement");
4879 llvm_unreachable("Unimplemented feature");
4880 case Mips::FeatureDSP:
4881 setFeatureBits(Mips::FeatureDSP, "dsp");
4882 getTargetStreamer().emitDirectiveSetDsp();
4884 case Mips::FeatureMicroMips:
4885 getTargetStreamer().emitDirectiveSetMicroMips();
4887 case Mips::FeatureMips1:
4888 selectArch("mips1");
4889 getTargetStreamer().emitDirectiveSetMips1();
4891 case Mips::FeatureMips2:
4892 selectArch("mips2");
4893 getTargetStreamer().emitDirectiveSetMips2();
4895 case Mips::FeatureMips3:
4896 selectArch("mips3");
4897 getTargetStreamer().emitDirectiveSetMips3();
4899 case Mips::FeatureMips4:
4900 selectArch("mips4");
4901 getTargetStreamer().emitDirectiveSetMips4();
4903 case Mips::FeatureMips5:
4904 selectArch("mips5");
4905 getTargetStreamer().emitDirectiveSetMips5();
4907 case Mips::FeatureMips32:
4908 selectArch("mips32");
4909 getTargetStreamer().emitDirectiveSetMips32();
4911 case Mips::FeatureMips32r2:
4912 selectArch("mips32r2");
4913 getTargetStreamer().emitDirectiveSetMips32R2();
4915 case Mips::FeatureMips32r3:
4916 selectArch("mips32r3");
4917 getTargetStreamer().emitDirectiveSetMips32R3();
4919 case Mips::FeatureMips32r5:
4920 selectArch("mips32r5");
4921 getTargetStreamer().emitDirectiveSetMips32R5();
4923 case Mips::FeatureMips32r6:
4924 selectArch("mips32r6");
4925 getTargetStreamer().emitDirectiveSetMips32R6();
4927 case Mips::FeatureMips64:
4928 selectArch("mips64");
4929 getTargetStreamer().emitDirectiveSetMips64();
4931 case Mips::FeatureMips64r2:
4932 selectArch("mips64r2");
4933 getTargetStreamer().emitDirectiveSetMips64R2();
4935 case Mips::FeatureMips64r3:
4936 selectArch("mips64r3");
4937 getTargetStreamer().emitDirectiveSetMips64R3();
4939 case Mips::FeatureMips64r5:
4940 selectArch("mips64r5");
4941 getTargetStreamer().emitDirectiveSetMips64R5();
4943 case Mips::FeatureMips64r6:
4944 selectArch("mips64r6");
4945 getTargetStreamer().emitDirectiveSetMips64R6();
4951 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
4952 MCAsmParser &Parser = getParser();
4953 if (getLexer().isNot(AsmToken::Comma)) {
4954 SMLoc Loc = getLexer().getLoc();
4955 Parser.eatToEndOfStatement();
4956 return Error(Loc, ErrorStr);
4959 Parser.Lex(); // Eat the comma.
4963 // Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
4964 // In this class, it is only used for .cprestore.
4965 // FIXME: Only keep track of IsPicEnabled in one place, instead of in both
4966 // MipsTargetELFStreamer and MipsAsmParser.
4967 bool MipsAsmParser::isPicAndNotNxxAbi() {
4968 return inPicMode() && !(isABI_N32() || isABI_N64());
4971 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
4972 if (AssemblerOptions.back()->isReorder())
4973 Warning(Loc, ".cpload should be inside a noreorder section");
4975 if (inMips16Mode()) {
4976 reportParseError(".cpload is not supported in Mips16 mode");
4980 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
4981 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
4982 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4983 reportParseError("expected register containing function address");
4987 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
4988 if (!RegOpnd.isGPRAsmReg()) {
4989 reportParseError(RegOpnd.getStartLoc(), "invalid register");
4993 // If this is not the end of the statement, report an error.
4994 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4995 reportParseError("unexpected token, expected end of statement");
4999 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
5003 bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
5004 MCAsmParser &Parser = getParser();
5006 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
5007 // is used in non-PIC mode.
5009 if (inMips16Mode()) {
5010 reportParseError(".cprestore is not supported in Mips16 mode");
5014 // Get the stack offset value.
5015 const MCExpr *StackOffset;
5016 int64_t StackOffsetVal;
5017 if (Parser.parseExpression(StackOffset)) {
5018 reportParseError("expected stack offset value");
5022 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
5023 reportParseError("stack offset is not an absolute expression");
5027 if (StackOffsetVal < 0) {
5028 Warning(Loc, ".cprestore with negative stack offset has no effect");
5029 IsCpRestoreSet = false;
5031 IsCpRestoreSet = true;
5032 CpRestoreOffset = StackOffsetVal;
5035 // If this is not the end of the statement, report an error.
5036 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5037 reportParseError("unexpected token, expected end of statement");
5041 // Store the $gp on the stack.
5042 SmallVector<MCInst, 3> StoreInsts;
5043 createCpRestoreMemOp(false /*IsLoad*/, CpRestoreOffset /*StackOffset*/, Loc,
5046 getTargetStreamer().emitDirectiveCpRestore(StoreInsts, CpRestoreOffset);
5047 Parser.Lex(); // Consume the EndOfStatement.
5051 bool MipsAsmParser::parseDirectiveCPSetup() {
5052 MCAsmParser &Parser = getParser();
5055 bool SaveIsReg = true;
5057 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5058 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5059 if (ResTy == MatchOperand_NoMatch) {
5060 reportParseError("expected register containing function address");
5061 Parser.eatToEndOfStatement();
5065 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5066 if (!FuncRegOpnd.isGPRAsmReg()) {
5067 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
5068 Parser.eatToEndOfStatement();
5072 FuncReg = FuncRegOpnd.getGPR32Reg();
5075 if (!eatComma("unexpected token, expected comma"))
5078 ResTy = parseAnyRegister(TmpReg);
5079 if (ResTy == MatchOperand_NoMatch) {
5080 const MCExpr *OffsetExpr;
5082 SMLoc ExprLoc = getLexer().getLoc();
5084 if (Parser.parseExpression(OffsetExpr) ||
5085 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
5086 reportParseError(ExprLoc, "expected save register or stack offset");
5087 Parser.eatToEndOfStatement();
5094 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5095 if (!SaveOpnd.isGPRAsmReg()) {
5096 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
5097 Parser.eatToEndOfStatement();
5100 Save = SaveOpnd.getGPR32Reg();
5103 if (!eatComma("unexpected token, expected comma"))
5107 if (Parser.parseExpression(Expr)) {
5108 reportParseError("expected expression");
5112 if (Expr->getKind() != MCExpr::SymbolRef) {
5113 reportParseError("expected symbol");
5116 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
5118 CpSaveLocation = Save;
5119 CpSaveLocationIsRegister = SaveIsReg;
5121 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
5126 bool MipsAsmParser::parseDirectiveCPReturn() {
5127 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
5128 CpSaveLocationIsRegister);
5132 bool MipsAsmParser::parseDirectiveNaN() {
5133 MCAsmParser &Parser = getParser();
5134 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5135 const AsmToken &Tok = Parser.getTok();
5137 if (Tok.getString() == "2008") {
5139 getTargetStreamer().emitDirectiveNaN2008();
5141 } else if (Tok.getString() == "legacy") {
5143 getTargetStreamer().emitDirectiveNaNLegacy();
5147 // If we don't recognize the option passed to the .nan
5148 // directive (e.g. no option or unknown option), emit an error.
5149 reportParseError("invalid option in .nan directive");
5153 bool MipsAsmParser::parseDirectiveSet() {
5154 MCAsmParser &Parser = getParser();
5155 // Get the next token.
5156 const AsmToken &Tok = Parser.getTok();
5158 if (Tok.getString() == "noat") {
5159 return parseSetNoAtDirective();
5160 } else if (Tok.getString() == "at") {
5161 return parseSetAtDirective();
5162 } else if (Tok.getString() == "arch") {
5163 return parseSetArchDirective();
5164 } else if (Tok.getString() == "fp") {
5165 return parseSetFpDirective();
5166 } else if (Tok.getString() == "oddspreg") {
5167 return parseSetOddSPRegDirective();
5168 } else if (Tok.getString() == "nooddspreg") {
5169 return parseSetNoOddSPRegDirective();
5170 } else if (Tok.getString() == "pop") {
5171 return parseSetPopDirective();
5172 } else if (Tok.getString() == "push") {
5173 return parseSetPushDirective();
5174 } else if (Tok.getString() == "reorder") {
5175 return parseSetReorderDirective();
5176 } else if (Tok.getString() == "noreorder") {
5177 return parseSetNoReorderDirective();
5178 } else if (Tok.getString() == "macro") {
5179 return parseSetMacroDirective();
5180 } else if (Tok.getString() == "nomacro") {
5181 return parseSetNoMacroDirective();
5182 } else if (Tok.getString() == "mips16") {
5183 return parseSetMips16Directive();
5184 } else if (Tok.getString() == "nomips16") {
5185 return parseSetNoMips16Directive();
5186 } else if (Tok.getString() == "nomicromips") {
5187 getTargetStreamer().emitDirectiveSetNoMicroMips();
5188 Parser.eatToEndOfStatement();
5190 } else if (Tok.getString() == "micromips") {
5191 return parseSetFeature(Mips::FeatureMicroMips);
5192 } else if (Tok.getString() == "mips0") {
5193 return parseSetMips0Directive();
5194 } else if (Tok.getString() == "mips1") {
5195 return parseSetFeature(Mips::FeatureMips1);
5196 } else if (Tok.getString() == "mips2") {
5197 return parseSetFeature(Mips::FeatureMips2);
5198 } else if (Tok.getString() == "mips3") {
5199 return parseSetFeature(Mips::FeatureMips3);
5200 } else if (Tok.getString() == "mips4") {
5201 return parseSetFeature(Mips::FeatureMips4);
5202 } else if (Tok.getString() == "mips5") {
5203 return parseSetFeature(Mips::FeatureMips5);
5204 } else if (Tok.getString() == "mips32") {
5205 return parseSetFeature(Mips::FeatureMips32);
5206 } else if (Tok.getString() == "mips32r2") {
5207 return parseSetFeature(Mips::FeatureMips32r2);
5208 } else if (Tok.getString() == "mips32r3") {
5209 return parseSetFeature(Mips::FeatureMips32r3);
5210 } else if (Tok.getString() == "mips32r5") {
5211 return parseSetFeature(Mips::FeatureMips32r5);
5212 } else if (Tok.getString() == "mips32r6") {
5213 return parseSetFeature(Mips::FeatureMips32r6);
5214 } else if (Tok.getString() == "mips64") {
5215 return parseSetFeature(Mips::FeatureMips64);
5216 } else if (Tok.getString() == "mips64r2") {
5217 return parseSetFeature(Mips::FeatureMips64r2);
5218 } else if (Tok.getString() == "mips64r3") {
5219 return parseSetFeature(Mips::FeatureMips64r3);
5220 } else if (Tok.getString() == "mips64r5") {
5221 return parseSetFeature(Mips::FeatureMips64r5);
5222 } else if (Tok.getString() == "mips64r6") {
5223 return parseSetFeature(Mips::FeatureMips64r6);
5224 } else if (Tok.getString() == "dsp") {
5225 return parseSetFeature(Mips::FeatureDSP);
5226 } else if (Tok.getString() == "nodsp") {
5227 return parseSetNoDspDirective();
5228 } else if (Tok.getString() == "msa") {
5229 return parseSetMsaDirective();
5230 } else if (Tok.getString() == "nomsa") {
5231 return parseSetNoMsaDirective();
5232 } else if (Tok.getString() == "softfloat") {
5233 return parseSetSoftFloatDirective();
5234 } else if (Tok.getString() == "hardfloat") {
5235 return parseSetHardFloatDirective();
5237 // It is just an identifier, look for an assignment.
5238 parseSetAssignment();
5245 /// parseDataDirective
5246 /// ::= .word [ expression (, expression)* ]
5247 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
5248 MCAsmParser &Parser = getParser();
5249 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5251 const MCExpr *Value;
5252 if (getParser().parseExpression(Value))
5255 getParser().getStreamer().EmitValue(Value, Size);
5257 if (getLexer().is(AsmToken::EndOfStatement))
5260 if (getLexer().isNot(AsmToken::Comma))
5261 return Error(L, "unexpected token, expected comma");
5270 /// parseDirectiveGpWord
5271 /// ::= .gpword local_sym
5272 bool MipsAsmParser::parseDirectiveGpWord() {
5273 MCAsmParser &Parser = getParser();
5274 const MCExpr *Value;
5275 // EmitGPRel32Value requires an expression, so we are using base class
5276 // method to evaluate the expression.
5277 if (getParser().parseExpression(Value))
5279 getParser().getStreamer().EmitGPRel32Value(Value);
5281 if (getLexer().isNot(AsmToken::EndOfStatement))
5282 return Error(getLexer().getLoc(),
5283 "unexpected token, expected end of statement");
5284 Parser.Lex(); // Eat EndOfStatement token.
5288 /// parseDirectiveGpDWord
5289 /// ::= .gpdword local_sym
5290 bool MipsAsmParser::parseDirectiveGpDWord() {
5291 MCAsmParser &Parser = getParser();
5292 const MCExpr *Value;
5293 // EmitGPRel64Value requires an expression, so we are using base class
5294 // method to evaluate the expression.
5295 if (getParser().parseExpression(Value))
5297 getParser().getStreamer().EmitGPRel64Value(Value);
5299 if (getLexer().isNot(AsmToken::EndOfStatement))
5300 return Error(getLexer().getLoc(),
5301 "unexpected token, expected end of statement");
5302 Parser.Lex(); // Eat EndOfStatement token.
5306 bool MipsAsmParser::parseDirectiveOption() {
5307 MCAsmParser &Parser = getParser();
5308 // Get the option token.
5309 AsmToken Tok = Parser.getTok();
5310 // At the moment only identifiers are supported.
5311 if (Tok.isNot(AsmToken::Identifier)) {
5312 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
5313 Parser.eatToEndOfStatement();
5317 StringRef Option = Tok.getIdentifier();
5319 if (Option == "pic0") {
5320 // MipsAsmParser needs to know if the current PIC mode changes.
5321 IsPicEnabled = false;
5323 getTargetStreamer().emitDirectiveOptionPic0();
5325 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5326 Error(Parser.getTok().getLoc(),
5327 "unexpected token, expected end of statement");
5328 Parser.eatToEndOfStatement();
5333 if (Option == "pic2") {
5334 // MipsAsmParser needs to know if the current PIC mode changes.
5335 IsPicEnabled = true;
5337 getTargetStreamer().emitDirectiveOptionPic2();
5339 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5340 Error(Parser.getTok().getLoc(),
5341 "unexpected token, expected end of statement");
5342 Parser.eatToEndOfStatement();
5348 Warning(Parser.getTok().getLoc(),
5349 "unknown option, expected 'pic0' or 'pic2'");
5350 Parser.eatToEndOfStatement();
5354 /// parseInsnDirective
5356 bool MipsAsmParser::parseInsnDirective() {
5357 // If this is not the end of the statement, report an error.
5358 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5359 reportParseError("unexpected token, expected end of statement");
5363 // The actual label marking happens in
5364 // MipsELFStreamer::createPendingLabelRelocs().
5365 getTargetStreamer().emitDirectiveInsn();
5367 getParser().Lex(); // Eat EndOfStatement token.
5371 /// parseDirectiveModule
5372 /// ::= .module oddspreg
5373 /// ::= .module nooddspreg
5374 /// ::= .module fp=value
5375 /// ::= .module softfloat
5376 /// ::= .module hardfloat
5377 bool MipsAsmParser::parseDirectiveModule() {
5378 MCAsmParser &Parser = getParser();
5379 MCAsmLexer &Lexer = getLexer();
5380 SMLoc L = Lexer.getLoc();
5382 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
5383 // TODO : get a better message.
5384 reportParseError(".module directive must appear before any code");
5389 if (Parser.parseIdentifier(Option)) {
5390 reportParseError("expected .module option identifier");
5394 if (Option == "oddspreg") {
5395 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5397 // Synchronize the abiflags information with the FeatureBits information we
5399 getTargetStreamer().updateABIInfo(*this);
5401 // If printing assembly, use the recently updated abiflags information.
5402 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5403 // emitted at the end).
5404 getTargetStreamer().emitDirectiveModuleOddSPReg();
5406 // If this is not the end of the statement, report an error.
5407 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5408 reportParseError("unexpected token, expected end of statement");
5412 return false; // parseDirectiveModule has finished successfully.
5413 } else if (Option == "nooddspreg") {
5415 Error(L, "'.module nooddspreg' requires the O32 ABI");
5419 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5421 // Synchronize the abiflags information with the FeatureBits information we
5423 getTargetStreamer().updateABIInfo(*this);
5425 // If printing assembly, use the recently updated abiflags information.
5426 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5427 // emitted at the end).
5428 getTargetStreamer().emitDirectiveModuleOddSPReg();
5430 // If this is not the end of the statement, report an error.
5431 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5432 reportParseError("unexpected token, expected end of statement");
5436 return false; // parseDirectiveModule has finished successfully.
5437 } else if (Option == "fp") {
5438 return parseDirectiveModuleFP();
5439 } else if (Option == "softfloat") {
5440 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5442 // Synchronize the ABI Flags information with the FeatureBits information we
5444 getTargetStreamer().updateABIInfo(*this);
5446 // If printing assembly, use the recently updated ABI Flags information.
5447 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5449 getTargetStreamer().emitDirectiveModuleSoftFloat();
5451 // If this is not the end of the statement, report an error.
5452 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5453 reportParseError("unexpected token, expected end of statement");
5457 return false; // parseDirectiveModule has finished successfully.
5458 } else if (Option == "hardfloat") {
5459 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5461 // Synchronize the ABI Flags information with the FeatureBits information we
5463 getTargetStreamer().updateABIInfo(*this);
5465 // If printing assembly, use the recently updated ABI Flags information.
5466 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5468 getTargetStreamer().emitDirectiveModuleHardFloat();
5470 // If this is not the end of the statement, report an error.
5471 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5472 reportParseError("unexpected token, expected end of statement");
5476 return false; // parseDirectiveModule has finished successfully.
5478 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
5482 /// parseDirectiveModuleFP
5486 bool MipsAsmParser::parseDirectiveModuleFP() {
5487 MCAsmParser &Parser = getParser();
5488 MCAsmLexer &Lexer = getLexer();
5490 if (Lexer.isNot(AsmToken::Equal)) {
5491 reportParseError("unexpected token, expected equals sign '='");
5494 Parser.Lex(); // Eat '=' token.
5496 MipsABIFlagsSection::FpABIKind FpABI;
5497 if (!parseFpABIValue(FpABI, ".module"))
5500 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5501 reportParseError("unexpected token, expected end of statement");
5505 // Synchronize the abiflags information with the FeatureBits information we
5507 getTargetStreamer().updateABIInfo(*this);
5509 // If printing assembly, use the recently updated abiflags information.
5510 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5511 // emitted at the end).
5512 getTargetStreamer().emitDirectiveModuleFP();
5514 Parser.Lex(); // Consume the EndOfStatement.
5518 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
5519 StringRef Directive) {
5520 MCAsmParser &Parser = getParser();
5521 MCAsmLexer &Lexer = getLexer();
5522 bool ModuleLevelOptions = Directive == ".module";
5524 if (Lexer.is(AsmToken::Identifier)) {
5525 StringRef Value = Parser.getTok().getString();
5528 if (Value != "xx") {
5529 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5534 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
5538 FpABI = MipsABIFlagsSection::FpABIKind::XX;
5539 if (ModuleLevelOptions) {
5540 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5541 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5543 setFeatureBits(Mips::FeatureFPXX, "fpxx");
5544 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5549 if (Lexer.is(AsmToken::Integer)) {
5550 unsigned Value = Parser.getTok().getIntVal();
5553 if (Value != 32 && Value != 64) {
5554 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5560 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
5564 FpABI = MipsABIFlagsSection::FpABIKind::S32;
5565 if (ModuleLevelOptions) {
5566 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5567 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5569 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5570 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5573 FpABI = MipsABIFlagsSection::FpABIKind::S64;
5574 if (ModuleLevelOptions) {
5575 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5576 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5578 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5579 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
5589 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
5590 MCAsmParser &Parser = getParser();
5591 StringRef IDVal = DirectiveID.getString();
5593 if (IDVal == ".cpload")
5594 return parseDirectiveCpLoad(DirectiveID.getLoc());
5595 if (IDVal == ".cprestore")
5596 return parseDirectiveCpRestore(DirectiveID.getLoc());
5597 if (IDVal == ".dword") {
5598 parseDataDirective(8, DirectiveID.getLoc());
5601 if (IDVal == ".ent") {
5602 StringRef SymbolName;
5604 if (Parser.parseIdentifier(SymbolName)) {
5605 reportParseError("expected identifier after .ent");
5609 // There's an undocumented extension that allows an integer to
5610 // follow the name of the procedure which AFAICS is ignored by GAS.
5611 // Example: .ent foo,2
5612 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5613 if (getLexer().isNot(AsmToken::Comma)) {
5614 // Even though we accept this undocumented extension for compatibility
5615 // reasons, the additional integer argument does not actually change
5616 // the behaviour of the '.ent' directive, so we would like to discourage
5617 // its use. We do this by not referring to the extended version in
5618 // error messages which are not directly related to its use.
5619 reportParseError("unexpected token, expected end of statement");
5622 Parser.Lex(); // Eat the comma.
5623 const MCExpr *DummyNumber;
5624 int64_t DummyNumberVal;
5625 // If the user was explicitly trying to use the extended version,
5626 // we still give helpful extension-related error messages.
5627 if (Parser.parseExpression(DummyNumber)) {
5628 reportParseError("expected number after comma");
5631 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
5632 reportParseError("expected an absolute expression after comma");
5637 // If this is not the end of the statement, report an error.
5638 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5639 reportParseError("unexpected token, expected end of statement");
5643 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
5645 getTargetStreamer().emitDirectiveEnt(*Sym);
5647 IsCpRestoreSet = false;
5651 if (IDVal == ".end") {
5652 StringRef SymbolName;
5654 if (Parser.parseIdentifier(SymbolName)) {
5655 reportParseError("expected identifier after .end");
5659 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5660 reportParseError("unexpected token, expected end of statement");
5664 if (CurrentFn == nullptr) {
5665 reportParseError(".end used without .ent");
5669 if ((SymbolName != CurrentFn->getName())) {
5670 reportParseError(".end symbol does not match .ent symbol");
5674 getTargetStreamer().emitDirectiveEnd(SymbolName);
5675 CurrentFn = nullptr;
5676 IsCpRestoreSet = false;
5680 if (IDVal == ".frame") {
5681 // .frame $stack_reg, frame_size_in_bytes, $return_reg
5682 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5683 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5684 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5685 reportParseError("expected stack register");
5689 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5690 if (!StackRegOpnd.isGPRAsmReg()) {
5691 reportParseError(StackRegOpnd.getStartLoc(),
5692 "expected general purpose register");
5695 unsigned StackReg = StackRegOpnd.getGPR32Reg();
5697 if (Parser.getTok().is(AsmToken::Comma))
5700 reportParseError("unexpected token, expected comma");
5704 // Parse the frame size.
5705 const MCExpr *FrameSize;
5706 int64_t FrameSizeVal;
5708 if (Parser.parseExpression(FrameSize)) {
5709 reportParseError("expected frame size value");
5713 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
5714 reportParseError("frame size not an absolute expression");
5718 if (Parser.getTok().is(AsmToken::Comma))
5721 reportParseError("unexpected token, expected comma");
5725 // Parse the return register.
5727 ResTy = parseAnyRegister(TmpReg);
5728 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5729 reportParseError("expected return register");
5733 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5734 if (!ReturnRegOpnd.isGPRAsmReg()) {
5735 reportParseError(ReturnRegOpnd.getStartLoc(),
5736 "expected general purpose register");
5740 // If this is not the end of the statement, report an error.
5741 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5742 reportParseError("unexpected token, expected end of statement");
5746 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
5747 ReturnRegOpnd.getGPR32Reg());
5748 IsCpRestoreSet = false;
5752 if (IDVal == ".set") {
5753 return parseDirectiveSet();
5756 if (IDVal == ".mask" || IDVal == ".fmask") {
5757 // .mask bitmask, frame_offset
5758 // bitmask: One bit for each register used.
5759 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
5760 // first register is expected to be saved.
5762 // .mask 0x80000000, -4
5763 // .fmask 0x80000000, -4
5766 // Parse the bitmask
5767 const MCExpr *BitMask;
5770 if (Parser.parseExpression(BitMask)) {
5771 reportParseError("expected bitmask value");
5775 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
5776 reportParseError("bitmask not an absolute expression");
5780 if (Parser.getTok().is(AsmToken::Comma))
5783 reportParseError("unexpected token, expected comma");
5787 // Parse the frame_offset
5788 const MCExpr *FrameOffset;
5789 int64_t FrameOffsetVal;
5791 if (Parser.parseExpression(FrameOffset)) {
5792 reportParseError("expected frame offset value");
5796 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
5797 reportParseError("frame offset not an absolute expression");
5801 // If this is not the end of the statement, report an error.
5802 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5803 reportParseError("unexpected token, expected end of statement");
5807 if (IDVal == ".mask")
5808 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
5810 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
5814 if (IDVal == ".nan")
5815 return parseDirectiveNaN();
5817 if (IDVal == ".gpword") {
5818 parseDirectiveGpWord();
5822 if (IDVal == ".gpdword") {
5823 parseDirectiveGpDWord();
5827 if (IDVal == ".word") {
5828 parseDataDirective(4, DirectiveID.getLoc());
5832 if (IDVal == ".option")
5833 return parseDirectiveOption();
5835 if (IDVal == ".abicalls") {
5836 getTargetStreamer().emitDirectiveAbiCalls();
5837 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5838 Error(Parser.getTok().getLoc(),
5839 "unexpected token, expected end of statement");
5841 Parser.eatToEndOfStatement();
5846 if (IDVal == ".cpsetup")
5847 return parseDirectiveCPSetup();
5849 if (IDVal == ".cpreturn")
5850 return parseDirectiveCPReturn();
5852 if (IDVal == ".module")
5853 return parseDirectiveModule();
5855 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
5856 return parseInternalDirectiveReallowModule();
5858 if (IDVal == ".insn")
5859 return parseInsnDirective();
5864 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
5865 // If this is not the end of the statement, report an error.
5866 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5867 reportParseError("unexpected token, expected end of statement");
5871 getTargetStreamer().reallowModuleDirective();
5873 getParser().Lex(); // Eat EndOfStatement token.
5877 extern "C" void LLVMInitializeMipsAsmParser() {
5878 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
5879 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
5880 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
5881 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
5884 #define GET_REGISTER_MATCHER
5885 #define GET_MATCHER_IMPLEMENTATION
5886 #include "MipsGenAsmMatcher.inc"