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 MCSubtargetInfo &STI = copySTI();
350 FeatureBitset FeatureBits = STI.getFeatureBits();
351 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
352 STI.setFeatureBits(FeatureBits);
353 setAvailableFeatures(
354 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
355 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
358 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
359 if (!(getSTI().getFeatureBits()[Feature])) {
360 MCSubtargetInfo &STI = copySTI();
361 setAvailableFeatures(
362 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
363 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
367 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
368 if (getSTI().getFeatureBits()[Feature]) {
369 MCSubtargetInfo &STI = copySTI();
370 setAvailableFeatures(
371 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
372 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
376 void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
377 setFeatureBits(Feature, FeatureString);
378 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
381 void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
382 clearFeatureBits(Feature, FeatureString);
383 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
387 enum MipsMatchResultTy {
388 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
389 #define GET_OPERAND_DIAGNOSTIC_TYPES
390 #include "MipsGenAsmMatcher.inc"
391 #undef GET_OPERAND_DIAGNOSTIC_TYPES
394 MipsAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
395 const MCInstrInfo &MII, const MCTargetOptions &Options)
396 : MCTargetAsmParser(Options, sti),
397 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
398 sti.getCPU(), Options)) {
399 MCAsmParserExtension::Initialize(parser);
401 parser.addAliasForDirective(".asciiz", ".asciz");
403 // Initialize the set of available features.
404 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
406 // Remember the initial assembler options. The user can not modify these.
407 AssemblerOptions.push_back(
408 llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
410 // Create an assembler options environment for the user to modify.
411 AssemblerOptions.push_back(
412 llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
414 getTargetStreamer().updateABIInfo(*this);
416 if (!isABI_O32() && !useOddSPReg() != 0)
417 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
422 (getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_);
424 IsCpRestoreSet = false;
425 CpRestoreOffset = -1;
427 Triple TheTriple(sti.getTargetTriple());
428 if ((TheTriple.getArch() == Triple::mips) ||
429 (TheTriple.getArch() == Triple::mips64))
430 IsLittleEndian = false;
432 IsLittleEndian = true;
435 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
436 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
438 bool isGP64bit() const {
439 return getSTI().getFeatureBits()[Mips::FeatureGP64Bit];
441 bool isFP64bit() const {
442 return getSTI().getFeatureBits()[Mips::FeatureFP64Bit];
444 const MipsABIInfo &getABI() const { return ABI; }
445 bool isABI_N32() const { return ABI.IsN32(); }
446 bool isABI_N64() const { return ABI.IsN64(); }
447 bool isABI_O32() const { return ABI.IsO32(); }
448 bool isABI_FPXX() const {
449 return getSTI().getFeatureBits()[Mips::FeatureFPXX];
452 bool useOddSPReg() const {
453 return !(getSTI().getFeatureBits()[Mips::FeatureNoOddSPReg]);
456 bool inMicroMipsMode() const {
457 return getSTI().getFeatureBits()[Mips::FeatureMicroMips];
459 bool hasMips1() const {
460 return getSTI().getFeatureBits()[Mips::FeatureMips1];
462 bool hasMips2() const {
463 return getSTI().getFeatureBits()[Mips::FeatureMips2];
465 bool hasMips3() const {
466 return getSTI().getFeatureBits()[Mips::FeatureMips3];
468 bool hasMips4() const {
469 return getSTI().getFeatureBits()[Mips::FeatureMips4];
471 bool hasMips5() const {
472 return getSTI().getFeatureBits()[Mips::FeatureMips5];
474 bool hasMips32() const {
475 return getSTI().getFeatureBits()[Mips::FeatureMips32];
477 bool hasMips64() const {
478 return getSTI().getFeatureBits()[Mips::FeatureMips64];
480 bool hasMips32r2() const {
481 return getSTI().getFeatureBits()[Mips::FeatureMips32r2];
483 bool hasMips64r2() const {
484 return getSTI().getFeatureBits()[Mips::FeatureMips64r2];
486 bool hasMips32r3() const {
487 return (getSTI().getFeatureBits()[Mips::FeatureMips32r3]);
489 bool hasMips64r3() const {
490 return (getSTI().getFeatureBits()[Mips::FeatureMips64r3]);
492 bool hasMips32r5() const {
493 return (getSTI().getFeatureBits()[Mips::FeatureMips32r5]);
495 bool hasMips64r5() const {
496 return (getSTI().getFeatureBits()[Mips::FeatureMips64r5]);
498 bool hasMips32r6() const {
499 return getSTI().getFeatureBits()[Mips::FeatureMips32r6];
501 bool hasMips64r6() const {
502 return getSTI().getFeatureBits()[Mips::FeatureMips64r6];
505 bool hasDSP() const {
506 return getSTI().getFeatureBits()[Mips::FeatureDSP];
508 bool hasDSPR2() const {
509 return getSTI().getFeatureBits()[Mips::FeatureDSPR2];
511 bool hasDSPR3() const {
512 return getSTI().getFeatureBits()[Mips::FeatureDSPR3];
514 bool hasMSA() const {
515 return getSTI().getFeatureBits()[Mips::FeatureMSA];
517 bool hasCnMips() const {
518 return (getSTI().getFeatureBits()[Mips::FeatureCnMips]);
525 bool inMips16Mode() const {
526 return getSTI().getFeatureBits()[Mips::FeatureMips16];
529 bool useTraps() const {
530 return getSTI().getFeatureBits()[Mips::FeatureUseTCCInDIV];
533 bool useSoftFloat() const {
534 return getSTI().getFeatureBits()[Mips::FeatureSoftFloat];
537 /// Warn if RegIndex is the same as the current AT.
538 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
540 void warnIfNoMacro(SMLoc Loc);
542 bool isLittle() const { return IsLittleEndian; }
548 /// MipsOperand - Instances of this class represent a parsed Mips machine
550 class MipsOperand : public MCParsedAsmOperand {
552 /// Broad categories of register classes
553 /// The exact class is finalized by the render method.
555 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
556 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
558 RegKind_FCC = 4, /// FCC
559 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
560 RegKind_MSACtrl = 16, /// MSA control registers
561 RegKind_COP2 = 32, /// COP2
562 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
564 RegKind_CCR = 128, /// CCR
565 RegKind_HWRegs = 256, /// HWRegs
566 RegKind_COP3 = 512, /// COP3
567 RegKind_COP0 = 1024, /// COP0
568 /// Potentially any (e.g. $1)
569 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
570 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
571 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
576 k_Immediate, /// An immediate (possibly involving symbol references)
577 k_Memory, /// Base + Offset Memory Address
578 k_PhysRegister, /// A physical register from the Mips namespace
579 k_RegisterIndex, /// A register index in one or more RegKind.
580 k_Token, /// A simple token
581 k_RegList, /// A physical register list
582 k_RegPair /// A pair of physical register
586 MipsOperand(KindTy K, MipsAsmParser &Parser)
587 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
590 /// For diagnostics, and checking the assembler temporary
591 MipsAsmParser &AsmParser;
599 unsigned Num; /// Register Number
603 unsigned Index; /// Index into the register class
604 RegKind Kind; /// Bitfield of the kinds it could possibly be
605 const MCRegisterInfo *RegInfo;
618 SmallVector<unsigned, 10> *List;
623 struct PhysRegOp PhysReg;
624 struct RegIdxOp RegIdx;
627 struct RegListOp RegList;
630 SMLoc StartLoc, EndLoc;
632 /// Internal constructor for register kinds
633 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
634 const MCRegisterInfo *RegInfo,
636 MipsAsmParser &Parser) {
637 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
638 Op->RegIdx.Index = Index;
639 Op->RegIdx.RegInfo = RegInfo;
640 Op->RegIdx.Kind = RegKind;
647 /// Coerce the register to GPR32 and return the real register for the current
649 unsigned getGPR32Reg() const {
650 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
651 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
652 unsigned ClassID = Mips::GPR32RegClassID;
653 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
656 /// Coerce the register to GPR32 and return the real register for the current
658 unsigned getGPRMM16Reg() const {
659 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
660 unsigned ClassID = Mips::GPR32RegClassID;
661 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
664 /// Coerce the register to GPR64 and return the real register for the current
666 unsigned getGPR64Reg() const {
667 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
668 unsigned ClassID = Mips::GPR64RegClassID;
669 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
673 /// Coerce the register to AFGR64 and return the real register for the current
675 unsigned getAFGR64Reg() const {
676 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
677 if (RegIdx.Index % 2 != 0)
678 AsmParser.Warning(StartLoc, "Float register should be even.");
679 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
680 .getRegister(RegIdx.Index / 2);
683 /// Coerce the register to FGR64 and return the real register for the current
685 unsigned getFGR64Reg() const {
686 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
687 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
688 .getRegister(RegIdx.Index);
691 /// Coerce the register to FGR32 and return the real register for the current
693 unsigned getFGR32Reg() const {
694 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
695 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
696 .getRegister(RegIdx.Index);
699 /// Coerce the register to FGRH32 and return the real register for the current
701 unsigned getFGRH32Reg() const {
702 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
703 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
704 .getRegister(RegIdx.Index);
707 /// Coerce the register to FCC and return the real register for the current
709 unsigned getFCCReg() const {
710 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
711 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
712 .getRegister(RegIdx.Index);
715 /// Coerce the register to MSA128 and return the real register for the current
717 unsigned getMSA128Reg() const {
718 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
719 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
721 unsigned ClassID = Mips::MSA128BRegClassID;
722 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
725 /// Coerce the register to MSACtrl and return the real register for the
727 unsigned getMSACtrlReg() const {
728 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
729 unsigned ClassID = Mips::MSACtrlRegClassID;
730 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
733 /// Coerce the register to COP0 and return the real register for the
735 unsigned getCOP0Reg() const {
736 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!");
737 unsigned ClassID = Mips::COP0RegClassID;
738 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
741 /// Coerce the register to COP2 and return the real register for the
743 unsigned getCOP2Reg() const {
744 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
745 unsigned ClassID = Mips::COP2RegClassID;
746 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
749 /// Coerce the register to COP3 and return the real register for the
751 unsigned getCOP3Reg() const {
752 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
753 unsigned ClassID = Mips::COP3RegClassID;
754 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
757 /// Coerce the register to ACC64DSP and return the real register for the
759 unsigned getACC64DSPReg() const {
760 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
761 unsigned ClassID = Mips::ACC64DSPRegClassID;
762 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
765 /// Coerce the register to HI32DSP and return the real register for the
767 unsigned getHI32DSPReg() const {
768 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
769 unsigned ClassID = Mips::HI32DSPRegClassID;
770 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
773 /// Coerce the register to LO32DSP and return the real register for the
775 unsigned getLO32DSPReg() const {
776 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
777 unsigned ClassID = Mips::LO32DSPRegClassID;
778 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
781 /// Coerce the register to CCR and return the real register for the
783 unsigned getCCRReg() const {
784 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
785 unsigned ClassID = Mips::CCRRegClassID;
786 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
789 /// Coerce the register to HWRegs and return the real register for the
791 unsigned getHWRegsReg() const {
792 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
793 unsigned ClassID = Mips::HWRegsRegClassID;
794 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
798 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
799 // Add as immediate when possible. Null MCExpr = 0.
801 Inst.addOperand(MCOperand::createImm(0));
802 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
803 Inst.addOperand(MCOperand::createImm(CE->getValue()));
805 Inst.addOperand(MCOperand::createExpr(Expr));
808 void addRegOperands(MCInst &Inst, unsigned N) const {
809 llvm_unreachable("Use a custom parser instead");
812 /// Render the operand to an MCInst as a GPR32
813 /// Asserts if the wrong number of operands are requested, or the operand
814 /// is not a k_RegisterIndex compatible with RegKind_GPR
815 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
816 assert(N == 1 && "Invalid number of operands!");
817 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
820 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
821 assert(N == 1 && "Invalid number of operands!");
822 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
825 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
826 assert(N == 1 && "Invalid number of operands!");
827 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
830 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
831 assert(N == 1 && "Invalid number of operands!");
832 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
835 /// Render the operand to an MCInst as a GPR64
836 /// Asserts if the wrong number of operands are requested, or the operand
837 /// is not a k_RegisterIndex compatible with RegKind_GPR
838 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
839 assert(N == 1 && "Invalid number of operands!");
840 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
843 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
844 assert(N == 1 && "Invalid number of operands!");
845 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
848 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
849 assert(N == 1 && "Invalid number of operands!");
850 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
853 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
854 assert(N == 1 && "Invalid number of operands!");
855 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
856 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
857 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
858 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
862 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
863 assert(N == 1 && "Invalid number of operands!");
864 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
867 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
868 assert(N == 1 && "Invalid number of operands!");
869 Inst.addOperand(MCOperand::createReg(getFCCReg()));
872 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
873 assert(N == 1 && "Invalid number of operands!");
874 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
877 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
878 assert(N == 1 && "Invalid number of operands!");
879 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
882 void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
883 assert(N == 1 && "Invalid number of operands!");
884 Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
887 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
888 assert(N == 1 && "Invalid number of operands!");
889 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
892 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
893 assert(N == 1 && "Invalid number of operands!");
894 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
897 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
898 assert(N == 1 && "Invalid number of operands!");
899 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
902 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
903 assert(N == 1 && "Invalid number of operands!");
904 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
907 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
908 assert(N == 1 && "Invalid number of operands!");
909 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
912 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
913 assert(N == 1 && "Invalid number of operands!");
914 Inst.addOperand(MCOperand::createReg(getCCRReg()));
917 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
918 assert(N == 1 && "Invalid number of operands!");
919 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
922 template <unsigned Bits, int Offset = 0>
923 void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
924 assert(N == 1 && "Invalid number of operands!");
925 uint64_t Imm = getConstantImm() - Offset;
926 Imm &= (1 << Bits) - 1;
928 Inst.addOperand(MCOperand::createImm(Imm));
931 void addImmOperands(MCInst &Inst, unsigned N) const {
932 assert(N == 1 && "Invalid number of operands!");
933 const MCExpr *Expr = getImm();
937 void addMemOperands(MCInst &Inst, unsigned N) const {
938 assert(N == 2 && "Invalid number of operands!");
940 Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
941 ? getMemBase()->getGPR64Reg()
942 : getMemBase()->getGPR32Reg()));
944 const MCExpr *Expr = getMemOff();
948 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
949 assert(N == 2 && "Invalid number of operands!");
951 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
953 const MCExpr *Expr = getMemOff();
957 void addRegListOperands(MCInst &Inst, unsigned N) const {
958 assert(N == 1 && "Invalid number of operands!");
960 for (auto RegNo : getRegList())
961 Inst.addOperand(MCOperand::createReg(RegNo));
964 void addRegPairOperands(MCInst &Inst, unsigned N) const {
965 assert(N == 2 && "Invalid number of operands!");
966 unsigned RegNo = getRegPair();
967 Inst.addOperand(MCOperand::createReg(RegNo++));
968 Inst.addOperand(MCOperand::createReg(RegNo));
971 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
972 assert(N == 2 && "Invalid number of operands!");
973 for (auto RegNo : getRegList())
974 Inst.addOperand(MCOperand::createReg(RegNo));
977 bool isReg() const override {
978 // As a special case until we sort out the definition of div/divu, pretend
979 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
980 if (isGPRAsmReg() && RegIdx.Index == 0)
983 return Kind == k_PhysRegister;
985 bool isRegIdx() const { return Kind == k_RegisterIndex; }
986 bool isImm() const override { return Kind == k_Immediate; }
987 bool isConstantImm() const {
988 return isImm() && isa<MCConstantExpr>(getImm());
990 bool isConstantImmz() const {
991 return isConstantImm() && getConstantImm() == 0;
993 template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
994 return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
996 template <unsigned Bits> bool isUImm() const {
997 return isImm() && isConstantImm() && isUInt<Bits>(getConstantImm());
999 bool isToken() const override {
1000 // Note: It's not possible to pretend that other operand kinds are tokens.
1001 // The matcher emitter checks tokens first.
1002 return Kind == k_Token;
1004 bool isMem() const override { return Kind == k_Memory; }
1005 bool isConstantMemOff() const {
1006 return isMem() && isa<MCConstantExpr>(getMemOff());
1008 template <unsigned Bits> bool isMemWithSimmOffset() const {
1009 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
1010 && getMemBase()->isGPRAsmReg();
1012 template <unsigned Bits> bool isMemWithSimmOffsetGPR() const {
1013 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff()) &&
1014 getMemBase()->isGPRAsmReg();
1016 bool isMemWithGRPMM16Base() const {
1017 return isMem() && getMemBase()->isMM16AsmReg();
1019 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
1020 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1021 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1023 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
1024 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1025 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1026 && (getMemBase()->getGPR32Reg() == Mips::SP);
1028 bool isUImm5Lsl2() const {
1029 return (isImm() && isConstantImm() && isShiftedUInt<5, 2>(getConstantImm()));
1031 bool isRegList16() const {
1035 int Size = RegList.List->size();
1036 if (Size < 2 || Size > 5)
1039 unsigned R0 = RegList.List->front();
1040 unsigned R1 = RegList.List->back();
1041 if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1042 (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1045 int PrevReg = *RegList.List->begin();
1046 for (int i = 1; i < Size - 1; i++) {
1047 int Reg = (*(RegList.List))[i];
1048 if ( Reg != PrevReg + 1)
1055 bool isInvNum() const { return Kind == k_Immediate; }
1056 bool isLSAImm() const {
1057 if (!isConstantImm())
1059 int64_t Val = getConstantImm();
1060 return 1 <= Val && Val <= 4;
1062 bool isRegList() const { return Kind == k_RegList; }
1063 bool isMovePRegPair() const {
1064 if (Kind != k_RegList || RegList.List->size() != 2)
1067 unsigned R0 = RegList.List->front();
1068 unsigned R1 = RegList.List->back();
1070 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
1071 (R0 == Mips::A1 && R1 == Mips::A3) ||
1072 (R0 == Mips::A2 && R1 == Mips::A3) ||
1073 (R0 == Mips::A0 && R1 == Mips::S5) ||
1074 (R0 == Mips::A0 && R1 == Mips::S6) ||
1075 (R0 == Mips::A0 && R1 == Mips::A1) ||
1076 (R0 == Mips::A0 && R1 == Mips::A2) ||
1077 (R0 == Mips::A0 && R1 == Mips::A3))
1083 StringRef getToken() const {
1084 assert(Kind == k_Token && "Invalid access!");
1085 return StringRef(Tok.Data, Tok.Length);
1087 bool isRegPair() const { return Kind == k_RegPair; }
1089 unsigned getReg() const override {
1090 // As a special case until we sort out the definition of div/divu, pretend
1091 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
1092 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1093 RegIdx.Kind & RegKind_GPR)
1094 return getGPR32Reg(); // FIXME: GPR64 too
1096 assert(Kind == k_PhysRegister && "Invalid access!");
1100 const MCExpr *getImm() const {
1101 assert((Kind == k_Immediate) && "Invalid access!");
1105 int64_t getConstantImm() const {
1106 const MCExpr *Val = getImm();
1107 return static_cast<const MCConstantExpr *>(Val)->getValue();
1110 MipsOperand *getMemBase() const {
1111 assert((Kind == k_Memory) && "Invalid access!");
1115 const MCExpr *getMemOff() const {
1116 assert((Kind == k_Memory) && "Invalid access!");
1120 int64_t getConstantMemOff() const {
1121 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1124 const SmallVectorImpl<unsigned> &getRegList() const {
1125 assert((Kind == k_RegList) && "Invalid access!");
1126 return *(RegList.List);
1129 unsigned getRegPair() const {
1130 assert((Kind == k_RegPair) && "Invalid access!");
1131 return RegIdx.Index;
1134 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1135 MipsAsmParser &Parser) {
1136 auto Op = make_unique<MipsOperand>(k_Token, Parser);
1137 Op->Tok.Data = Str.data();
1138 Op->Tok.Length = Str.size();
1144 /// Create a numeric register (e.g. $1). The exact register remains
1145 /// unresolved until an instruction successfully matches
1146 static std::unique_ptr<MipsOperand>
1147 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1148 SMLoc E, MipsAsmParser &Parser) {
1149 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1150 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1153 /// Create a register that is definitely a GPR.
1154 /// This is typically only used for named registers such as $gp.
1155 static std::unique_ptr<MipsOperand>
1156 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1157 MipsAsmParser &Parser) {
1158 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1161 /// Create a register that is definitely a FGR.
1162 /// This is typically only used for named registers such as $f0.
1163 static std::unique_ptr<MipsOperand>
1164 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1165 MipsAsmParser &Parser) {
1166 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1169 /// Create a register that is definitely a HWReg.
1170 /// This is typically only used for named registers such as $hwr_cpunum.
1171 static std::unique_ptr<MipsOperand>
1172 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1173 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1174 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1177 /// Create a register that is definitely an FCC.
1178 /// This is typically only used for named registers such as $fcc0.
1179 static std::unique_ptr<MipsOperand>
1180 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1181 MipsAsmParser &Parser) {
1182 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1185 /// Create a register that is definitely an ACC.
1186 /// This is typically only used for named registers such as $ac0.
1187 static std::unique_ptr<MipsOperand>
1188 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1189 MipsAsmParser &Parser) {
1190 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1193 /// Create a register that is definitely an MSA128.
1194 /// This is typically only used for named registers such as $w0.
1195 static std::unique_ptr<MipsOperand>
1196 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1197 SMLoc E, MipsAsmParser &Parser) {
1198 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1201 /// Create a register that is definitely an MSACtrl.
1202 /// This is typically only used for named registers such as $msaaccess.
1203 static std::unique_ptr<MipsOperand>
1204 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1205 SMLoc E, MipsAsmParser &Parser) {
1206 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1209 static std::unique_ptr<MipsOperand>
1210 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1211 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1218 static std::unique_ptr<MipsOperand>
1219 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1220 SMLoc E, MipsAsmParser &Parser) {
1221 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1222 Op->Mem.Base = Base.release();
1229 static std::unique_ptr<MipsOperand>
1230 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1231 MipsAsmParser &Parser) {
1232 assert (Regs.size() > 0 && "Empty list not allowed");
1234 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1235 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1236 Op->StartLoc = StartLoc;
1237 Op->EndLoc = EndLoc;
1241 static std::unique_ptr<MipsOperand>
1242 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1243 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1244 Op->RegIdx.Index = RegNo;
1250 bool isGPRAsmReg() const {
1251 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1253 bool isMM16AsmReg() const {
1254 if (!(isRegIdx() && RegIdx.Kind))
1256 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1257 || RegIdx.Index == 16 || RegIdx.Index == 17);
1259 bool isMM16AsmRegZero() const {
1260 if (!(isRegIdx() && RegIdx.Kind))
1262 return (RegIdx.Index == 0 ||
1263 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1264 RegIdx.Index == 17);
1266 bool isMM16AsmRegMoveP() const {
1267 if (!(isRegIdx() && RegIdx.Kind))
1269 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1270 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1272 bool isFGRAsmReg() const {
1273 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1274 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1276 bool isHWRegsAsmReg() const {
1277 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1279 bool isCCRAsmReg() const {
1280 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1282 bool isFCCAsmReg() const {
1283 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1285 if (!AsmParser.hasEightFccRegisters())
1286 return RegIdx.Index == 0;
1287 return RegIdx.Index <= 7;
1289 bool isACCAsmReg() const {
1290 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1292 bool isCOP0AsmReg() const {
1293 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1295 bool isCOP2AsmReg() const {
1296 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1298 bool isCOP3AsmReg() const {
1299 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1301 bool isMSA128AsmReg() const {
1302 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1304 bool isMSACtrlAsmReg() const {
1305 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1308 /// getStartLoc - Get the location of the first token of this operand.
1309 SMLoc getStartLoc() const override { return StartLoc; }
1310 /// getEndLoc - Get the location of the last token of this operand.
1311 SMLoc getEndLoc() const override { return EndLoc; }
1313 virtual ~MipsOperand() {
1321 delete RegList.List;
1322 case k_PhysRegister:
1323 case k_RegisterIndex:
1330 void print(raw_ostream &OS) const override {
1339 Mem.Base->print(OS);
1344 case k_PhysRegister:
1345 OS << "PhysReg<" << PhysReg.Num << ">";
1347 case k_RegisterIndex:
1348 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1355 for (auto Reg : (*RegList.List))
1360 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1364 }; // class MipsOperand
1368 extern const MCInstrDesc MipsInsts[];
1370 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1371 return MipsInsts[Opcode];
1374 static bool hasShortDelaySlot(unsigned Opcode) {
1377 case Mips::JALRS_MM:
1378 case Mips::JALRS16_MM:
1379 case Mips::BGEZALS_MM:
1380 case Mips::BLTZALS_MM:
1387 static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1388 if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1389 return &SRExpr->getSymbol();
1392 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1393 const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1394 const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1405 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1406 return getSingleMCSymbol(UExpr->getSubExpr());
1411 static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1412 if (isa<MCSymbolRefExpr>(Expr))
1415 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1416 return countMCSymbolRefExpr(BExpr->getLHS()) +
1417 countMCSymbolRefExpr(BExpr->getRHS());
1419 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1420 return countMCSymbolRefExpr(UExpr->getSubExpr());
1426 void emitRX(unsigned Opcode, unsigned Reg0, MCOperand Op1, SMLoc IDLoc,
1427 SmallVectorImpl<MCInst> &Instructions) {
1429 tmpInst.setOpcode(Opcode);
1430 tmpInst.addOperand(MCOperand::createReg(Reg0));
1431 tmpInst.addOperand(Op1);
1432 tmpInst.setLoc(IDLoc);
1433 Instructions.push_back(tmpInst);
1436 void emitRI(unsigned Opcode, unsigned Reg0, int32_t Imm, SMLoc IDLoc,
1437 SmallVectorImpl<MCInst> &Instructions) {
1438 emitRX(Opcode, Reg0, MCOperand::createImm(Imm), IDLoc, Instructions);
1441 void emitRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, SMLoc IDLoc,
1442 SmallVectorImpl<MCInst> &Instructions) {
1443 emitRX(Opcode, Reg0, MCOperand::createReg(Reg1), IDLoc, Instructions);
1446 void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc,
1447 SmallVectorImpl<MCInst> &Instructions) {
1449 tmpInst.setOpcode(Opcode);
1450 tmpInst.addOperand(MCOperand::createImm(Imm1));
1451 tmpInst.addOperand(MCOperand::createImm(Imm2));
1452 tmpInst.setLoc(IDLoc);
1453 Instructions.push_back(tmpInst);
1456 void emitR(unsigned Opcode, unsigned Reg0, SMLoc IDLoc,
1457 SmallVectorImpl<MCInst> &Instructions) {
1459 tmpInst.setOpcode(Opcode);
1460 tmpInst.addOperand(MCOperand::createReg(Reg0));
1461 tmpInst.setLoc(IDLoc);
1462 Instructions.push_back(tmpInst);
1465 void emitRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1, MCOperand Op2,
1466 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1468 tmpInst.setOpcode(Opcode);
1469 tmpInst.addOperand(MCOperand::createReg(Reg0));
1470 tmpInst.addOperand(MCOperand::createReg(Reg1));
1471 tmpInst.addOperand(Op2);
1472 tmpInst.setLoc(IDLoc);
1473 Instructions.push_back(tmpInst);
1476 void emitRRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, unsigned Reg2,
1477 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1478 emitRRX(Opcode, Reg0, Reg1, MCOperand::createReg(Reg2), IDLoc,
1482 void emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1, int16_t Imm,
1483 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1484 emitRRX(Opcode, Reg0, Reg1, MCOperand::createImm(Imm), IDLoc,
1488 void emitAppropriateDSLL(unsigned DstReg, unsigned SrcReg, int16_t ShiftAmount,
1489 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1490 if (ShiftAmount >= 32) {
1491 emitRRI(Mips::DSLL32, DstReg, SrcReg, ShiftAmount - 32, IDLoc,
1496 emitRRI(Mips::DSLL, DstReg, SrcReg, ShiftAmount, IDLoc, Instructions);
1498 } // end anonymous namespace.
1500 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1501 SmallVectorImpl<MCInst> &Instructions) {
1502 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1503 bool ExpandedJalSym = false;
1507 if (MCID.isBranch() || MCID.isCall()) {
1508 const unsigned Opcode = Inst.getOpcode();
1518 assert(hasCnMips() && "instruction only valid for octeon cpus");
1525 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1526 Offset = Inst.getOperand(2);
1527 if (!Offset.isImm())
1528 break; // We'll deal with this situation later on when applying fixups.
1529 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1530 return Error(IDLoc, "branch target out of range");
1531 if (OffsetToAlignment(Offset.getImm(),
1532 1LL << (inMicroMipsMode() ? 1 : 2)))
1533 return Error(IDLoc, "branch to misaligned address");
1547 case Mips::BGEZAL_MM:
1548 case Mips::BLTZAL_MM:
1551 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1552 Offset = Inst.getOperand(1);
1553 if (!Offset.isImm())
1554 break; // We'll deal with this situation later on when applying fixups.
1555 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1556 return Error(IDLoc, "branch target out of range");
1557 if (OffsetToAlignment(Offset.getImm(),
1558 1LL << (inMicroMipsMode() ? 1 : 2)))
1559 return Error(IDLoc, "branch to misaligned address");
1561 case Mips::BEQZ16_MM:
1562 case Mips::BEQZC16_MMR6:
1563 case Mips::BNEZ16_MM:
1564 case Mips::BNEZC16_MMR6:
1565 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1566 Offset = Inst.getOperand(1);
1567 if (!Offset.isImm())
1568 break; // We'll deal with this situation later on when applying fixups.
1569 if (!isInt<8>(Offset.getImm()))
1570 return Error(IDLoc, "branch target out of range");
1571 if (OffsetToAlignment(Offset.getImm(), 2LL))
1572 return Error(IDLoc, "branch to misaligned address");
1577 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1578 // We still accept it but it is a normal nop.
1579 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1580 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1581 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1586 const unsigned Opcode = Inst.getOpcode();
1598 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1599 // The offset is handled above
1600 Opnd = Inst.getOperand(1);
1602 return Error(IDLoc, "expected immediate operand kind");
1603 Imm = Opnd.getImm();
1604 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1605 Opcode == Mips::BBIT1 ? 63 : 31))
1606 return Error(IDLoc, "immediate operand value out of range");
1608 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1610 Inst.getOperand(1).setImm(Imm - 32);
1618 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1620 Opnd = Inst.getOperand(3);
1622 return Error(IDLoc, "expected immediate operand kind");
1623 Imm = Opnd.getImm();
1624 if (Imm < 0 || Imm > 31)
1625 return Error(IDLoc, "immediate operand value out of range");
1627 Opnd = Inst.getOperand(2);
1629 return Error(IDLoc, "expected immediate operand kind");
1630 Imm = Opnd.getImm();
1631 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1632 Opcode == Mips::EXTS ? 63 : 31))
1633 return Error(IDLoc, "immediate operand value out of range");
1635 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1636 Inst.getOperand(2).setImm(Imm - 32);
1642 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1643 Opnd = Inst.getOperand(2);
1645 return Error(IDLoc, "expected immediate operand kind");
1646 Imm = Opnd.getImm();
1647 if (!isInt<10>(Imm))
1648 return Error(IDLoc, "immediate operand value out of range");
1653 // This expansion is not in a function called by tryExpandInstruction()
1654 // because the pseudo-instruction doesn't have a distinct opcode.
1655 if ((Inst.getOpcode() == Mips::JAL || Inst.getOpcode() == Mips::JAL_MM) &&
1657 warnIfNoMacro(IDLoc);
1659 const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
1661 // We can do this expansion if there's only 1 symbol in the argument
1663 if (countMCSymbolRefExpr(JalExpr) > 1)
1664 return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
1666 // FIXME: This is checking the expression can be handled by the later stages
1667 // of the assembler. We ought to leave it to those later stages but
1668 // we can't do that until we stop evaluateRelocExpr() rewriting the
1669 // expressions into non-equivalent forms.
1670 const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
1672 // FIXME: Add support for label+offset operands (currently causes an error).
1673 // FIXME: Add support for forward-declared local symbols.
1674 // FIXME: Add expansion for when the LargeGOT option is enabled.
1675 if (JalSym->isInSection() || JalSym->isTemporary()) {
1677 // If it's a local symbol and the O32 ABI is being used, we expand to:
1679 // R_(MICRO)MIPS_GOT16 label
1680 // addiu $25, $25, 0
1681 // R_(MICRO)MIPS_LO16 label
1683 const MCExpr *Got16RelocExpr = evaluateRelocExpr(JalExpr, "got");
1684 const MCExpr *Lo16RelocExpr = evaluateRelocExpr(JalExpr, "lo");
1686 emitRRX(Mips::LW, Mips::T9, Mips::GP,
1687 MCOperand::createExpr(Got16RelocExpr), IDLoc, Instructions);
1688 emitRRX(Mips::ADDiu, Mips::T9, Mips::T9,
1689 MCOperand::createExpr(Lo16RelocExpr), IDLoc, Instructions);
1690 } else if (isABI_N32() || isABI_N64()) {
1691 // If it's a local symbol and the N32/N64 ABIs are being used,
1693 // lw/ld $25, 0($gp)
1694 // R_(MICRO)MIPS_GOT_DISP label
1696 const MCExpr *GotDispRelocExpr = evaluateRelocExpr(JalExpr, "got_disp");
1698 emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
1699 MCOperand::createExpr(GotDispRelocExpr), IDLoc, Instructions);
1702 // If it's an external/weak symbol, we expand to:
1703 // lw/ld $25, 0($gp)
1704 // R_(MICRO)MIPS_CALL16 label
1706 const MCExpr *Call16RelocExpr = evaluateRelocExpr(JalExpr, "call16");
1708 emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
1709 MCOperand::createExpr(Call16RelocExpr), IDLoc, Instructions);
1713 if (IsCpRestoreSet && inMicroMipsMode())
1714 JalrInst.setOpcode(Mips::JALRS_MM);
1716 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1717 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1718 JalrInst.addOperand(MCOperand::createReg(Mips::T9));
1720 // FIXME: Add an R_(MICRO)MIPS_JALR relocation after the JALR.
1721 // This relocation is supposed to be an optimization hint for the linker
1722 // and is not necessary for correctness.
1725 ExpandedJalSym = true;
1728 if (MCID.mayLoad() || MCID.mayStore()) {
1729 // Check the offset of memory operand, if it is a symbol
1730 // reference or immediate we may have to expand instructions.
1731 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1732 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1733 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1734 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1735 MCOperand &Op = Inst.getOperand(i);
1737 int MemOffset = Op.getImm();
1738 if (MemOffset < -32768 || MemOffset > 32767) {
1739 // Offset can't exceed 16bit value.
1740 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1743 } else if (Op.isExpr()) {
1744 const MCExpr *Expr = Op.getExpr();
1745 if (Expr->getKind() == MCExpr::SymbolRef) {
1746 const MCSymbolRefExpr *SR =
1747 static_cast<const MCSymbolRefExpr *>(Expr);
1748 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1750 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1753 } else if (!isEvaluated(Expr)) {
1754 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1762 if (inMicroMipsMode()) {
1763 if (MCID.mayLoad()) {
1764 // Try to create 16-bit GP relative load instruction.
1765 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1766 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1767 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1768 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1769 MCOperand &Op = Inst.getOperand(i);
1771 int MemOffset = Op.getImm();
1772 MCOperand &DstReg = Inst.getOperand(0);
1773 MCOperand &BaseReg = Inst.getOperand(1);
1774 if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
1775 getContext().getRegisterInfo()->getRegClass(
1776 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1777 (BaseReg.getReg() == Mips::GP ||
1778 BaseReg.getReg() == Mips::GP_64)) {
1780 emitRRI(Mips::LWGP_MM, DstReg.getReg(), Mips::GP, MemOffset,
1781 IDLoc, Instructions);
1789 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1794 switch (Inst.getOpcode()) {
1797 case Mips::ADDIUS5_MM:
1798 Opnd = Inst.getOperand(2);
1800 return Error(IDLoc, "expected immediate operand kind");
1801 Imm = Opnd.getImm();
1802 if (Imm < -8 || Imm > 7)
1803 return Error(IDLoc, "immediate operand value out of range");
1805 case Mips::ADDIUSP_MM:
1806 Opnd = Inst.getOperand(0);
1808 return Error(IDLoc, "expected immediate operand kind");
1809 Imm = Opnd.getImm();
1810 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1812 return Error(IDLoc, "immediate operand value out of range");
1814 case Mips::SLL16_MM:
1815 case Mips::SRL16_MM:
1816 Opnd = Inst.getOperand(2);
1818 return Error(IDLoc, "expected immediate operand kind");
1819 Imm = Opnd.getImm();
1820 if (Imm < 1 || Imm > 8)
1821 return Error(IDLoc, "immediate operand value out of range");
1824 Opnd = Inst.getOperand(1);
1826 return Error(IDLoc, "expected immediate operand kind");
1827 Imm = Opnd.getImm();
1828 if (Imm < -1 || Imm > 126)
1829 return Error(IDLoc, "immediate operand value out of range");
1831 case Mips::ADDIUR2_MM:
1832 Opnd = Inst.getOperand(2);
1834 return Error(IDLoc, "expected immediate operand kind");
1835 Imm = Opnd.getImm();
1836 if (!(Imm == 1 || Imm == -1 ||
1837 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1838 return Error(IDLoc, "immediate operand value out of range");
1840 case Mips::ADDIUR1SP_MM:
1841 Opnd = Inst.getOperand(1);
1843 return Error(IDLoc, "expected immediate operand kind");
1844 Imm = Opnd.getImm();
1845 if (OffsetToAlignment(Imm, 4LL))
1846 return Error(IDLoc, "misaligned immediate operand value");
1847 if (Imm < 0 || Imm > 255)
1848 return Error(IDLoc, "immediate operand value out of range");
1850 case Mips::ANDI16_MM:
1851 Opnd = Inst.getOperand(2);
1853 return Error(IDLoc, "expected immediate operand kind");
1854 Imm = Opnd.getImm();
1855 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1856 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1857 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1858 return Error(IDLoc, "immediate operand value out of range");
1860 case Mips::LBU16_MM:
1861 Opnd = Inst.getOperand(2);
1863 return Error(IDLoc, "expected immediate operand kind");
1864 Imm = Opnd.getImm();
1865 if (Imm < -1 || Imm > 14)
1866 return Error(IDLoc, "immediate operand value out of range");
1875 case Mips::SB16_MMR6:
1876 Opnd = Inst.getOperand(2);
1878 return Error(IDLoc, "expected immediate operand kind");
1879 Imm = Opnd.getImm();
1880 if (Imm < 0 || Imm > 15)
1881 return Error(IDLoc, "immediate operand value out of range");
1883 case Mips::LHU16_MM:
1885 case Mips::SH16_MMR6:
1886 Opnd = Inst.getOperand(2);
1888 return Error(IDLoc, "expected immediate operand kind");
1889 Imm = Opnd.getImm();
1890 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1891 return Error(IDLoc, "immediate operand value out of range");
1895 case Mips::SW16_MMR6:
1896 Opnd = Inst.getOperand(2);
1898 return Error(IDLoc, "expected immediate operand kind");
1899 Imm = Opnd.getImm();
1900 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1901 return Error(IDLoc, "immediate operand value out of range");
1903 case Mips::PREFX_MM:
1906 Opnd = Inst.getOperand(2);
1908 return Error(IDLoc, "expected immediate operand kind");
1909 Imm = Opnd.getImm();
1910 if (!isUInt<5>(Imm))
1911 return Error(IDLoc, "immediate operand value out of range");
1913 case Mips::ADDIUPC_MM:
1914 MCOperand Opnd = Inst.getOperand(1);
1916 return Error(IDLoc, "expected immediate operand kind");
1917 int Imm = Opnd.getImm();
1918 if ((Imm % 4 != 0) || !isInt<25>(Imm))
1919 return Error(IDLoc, "immediate operand value out of range");
1924 MacroExpanderResultTy ExpandResult =
1925 tryExpandInstruction(Inst, IDLoc, Instructions);
1926 switch (ExpandResult) {
1928 Instructions.push_back(Inst);
1936 // If this instruction has a delay slot and .set reorder is active,
1937 // emit a NOP after it.
1938 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1939 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1941 if ((Inst.getOpcode() == Mips::JalOneReg ||
1942 Inst.getOpcode() == Mips::JalTwoReg || ExpandedJalSym) &&
1943 isPicAndNotNxxAbi()) {
1944 if (IsCpRestoreSet) {
1945 // We need a NOP between the JALR and the LW:
1946 // If .set reorder has been used, we've already emitted a NOP.
1947 // If .set noreorder has been used, we need to emit a NOP at this point.
1948 if (!AssemblerOptions.back()->isReorder())
1949 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1951 // Load the $gp from the stack.
1952 SmallVector<MCInst, 3> LoadInsts;
1953 createCpRestoreMemOp(true /*IsLoad*/, CpRestoreOffset /*StackOffset*/,
1956 for (const MCInst &Inst : LoadInsts)
1957 Instructions.push_back(Inst);
1960 Warning(IDLoc, "no .cprestore used in PIC mode");
1966 MipsAsmParser::MacroExpanderResultTy
1967 MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
1968 SmallVectorImpl<MCInst> &Instructions) {
1969 switch (Inst.getOpcode()) {
1971 return MER_NotAMacro;
1972 case Mips::LoadImm32:
1973 return expandLoadImm(Inst, true, IDLoc, Instructions) ? MER_Fail
1975 case Mips::LoadImm64:
1976 return expandLoadImm(Inst, false, IDLoc, Instructions) ? MER_Fail
1978 case Mips::LoadAddrImm32:
1979 case Mips::LoadAddrImm64:
1980 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1981 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
1982 "expected immediate operand kind");
1984 return expandLoadAddress(Inst.getOperand(0).getReg(), Mips::NoRegister,
1986 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc,
1990 case Mips::LoadAddrReg32:
1991 case Mips::LoadAddrReg64:
1992 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1993 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1994 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
1995 "expected immediate operand kind");
1997 return expandLoadAddress(Inst.getOperand(0).getReg(),
1998 Inst.getOperand(1).getReg(), Inst.getOperand(2),
1999 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc,
2003 case Mips::B_MM_Pseudo:
2004 case Mips::B_MMR6_Pseudo:
2005 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions) ? MER_Fail
2009 return expandLoadStoreMultiple(Inst, IDLoc, Instructions) ? MER_Fail
2011 case Mips::JalOneReg:
2012 case Mips::JalTwoReg:
2013 return expandJalWithRegs(Inst, IDLoc, Instructions) ? MER_Fail
2017 return expandBranchImm(Inst, IDLoc, Instructions) ? MER_Fail : MER_Success;
2034 case Mips::BLTImmMacro:
2035 case Mips::BLEImmMacro:
2036 case Mips::BGEImmMacro:
2037 case Mips::BGTImmMacro:
2038 case Mips::BLTUImmMacro:
2039 case Mips::BLEUImmMacro:
2040 case Mips::BGEUImmMacro:
2041 case Mips::BGTUImmMacro:
2042 case Mips::BLTLImmMacro:
2043 case Mips::BLELImmMacro:
2044 case Mips::BGELImmMacro:
2045 case Mips::BGTLImmMacro:
2046 case Mips::BLTULImmMacro:
2047 case Mips::BLEULImmMacro:
2048 case Mips::BGEULImmMacro:
2049 case Mips::BGTULImmMacro:
2050 return expandCondBranches(Inst, IDLoc, Instructions) ? MER_Fail
2052 case Mips::SDivMacro:
2053 return expandDiv(Inst, IDLoc, Instructions, false, true) ? MER_Fail
2055 case Mips::DSDivMacro:
2056 return expandDiv(Inst, IDLoc, Instructions, true, true) ? MER_Fail
2058 case Mips::UDivMacro:
2059 return expandDiv(Inst, IDLoc, Instructions, false, false) ? MER_Fail
2061 case Mips::DUDivMacro:
2062 return expandDiv(Inst, IDLoc, Instructions, true, false) ? MER_Fail
2065 return expandUlh(Inst, true, IDLoc, Instructions) ? MER_Fail : MER_Success;
2067 return expandUlh(Inst, false, IDLoc, Instructions) ? MER_Fail : MER_Success;
2069 return expandUlw(Inst, IDLoc, Instructions) ? MER_Fail : MER_Success;
2071 return expandAliasImmediate(Inst, IDLoc, Instructions) ? MER_Fail
2077 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2078 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2079 int64_t ImmValue = Inst.getOperand(2).getImm();
2080 if (isInt<16>(ImmValue))
2081 return MER_NotAMacro;
2082 return expandAliasImmediate(Inst, IDLoc, Instructions) ? MER_Fail
2085 return MER_NotAMacro;
2089 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2090 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2091 int64_t ImmValue = Inst.getOperand(2).getImm();
2092 if (isUInt<16>(ImmValue))
2093 return MER_NotAMacro;
2094 return expandAliasImmediate(Inst, IDLoc, Instructions) ? MER_Fail
2097 return MER_NotAMacro;
2101 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2102 SmallVectorImpl<MCInst> &Instructions) {
2103 // Create a JALR instruction which is going to replace the pseudo-JAL.
2105 JalrInst.setLoc(IDLoc);
2106 const MCOperand FirstRegOp = Inst.getOperand(0);
2107 const unsigned Opcode = Inst.getOpcode();
2109 if (Opcode == Mips::JalOneReg) {
2110 // jal $rs => jalr $rs
2111 if (IsCpRestoreSet && inMicroMipsMode()) {
2112 JalrInst.setOpcode(Mips::JALRS16_MM);
2113 JalrInst.addOperand(FirstRegOp);
2114 } else if (inMicroMipsMode()) {
2115 JalrInst.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2116 JalrInst.addOperand(FirstRegOp);
2118 JalrInst.setOpcode(Mips::JALR);
2119 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2120 JalrInst.addOperand(FirstRegOp);
2122 } else if (Opcode == Mips::JalTwoReg) {
2123 // jal $rd, $rs => jalr $rd, $rs
2124 if (IsCpRestoreSet && inMicroMipsMode())
2125 JalrInst.setOpcode(Mips::JALRS_MM);
2127 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2128 JalrInst.addOperand(FirstRegOp);
2129 const MCOperand SecondRegOp = Inst.getOperand(1);
2130 JalrInst.addOperand(SecondRegOp);
2132 Instructions.push_back(JalrInst);
2134 // If .set reorder is active and branch instruction has a delay slot,
2135 // emit a NOP after it.
2136 const MCInstrDesc &MCID = getInstDesc(JalrInst.getOpcode());
2137 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) {
2138 createNop(hasShortDelaySlot(JalrInst.getOpcode()), IDLoc, Instructions);
2144 /// Can the value be represented by a unsigned N-bit value and a shift left?
2145 template <unsigned N> static bool isShiftedUIntAtAnyPosition(uint64_t x) {
2146 unsigned BitNum = findFirstSet(x);
2148 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2151 /// Load (or add) an immediate into a register.
2153 /// @param ImmValue The immediate to load.
2154 /// @param DstReg The register that will hold the immediate.
2155 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
2156 /// for a simple initialization.
2157 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2158 /// @param IsAddress True if the immediate represents an address. False if it
2160 /// @param IDLoc Location of the immediate in the source file.
2161 /// @param Instructions The instructions emitted by this expansion.
2162 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2163 unsigned SrcReg, bool Is32BitImm,
2164 bool IsAddress, SMLoc IDLoc,
2165 SmallVectorImpl<MCInst> &Instructions) {
2166 if (!Is32BitImm && !isGP64bit()) {
2167 Error(IDLoc, "instruction requires a 64-bit architecture");
2172 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2173 // Sign extend up to 64-bit so that the predicates match the hardware
2174 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2176 ImmValue = SignExtend64<32>(ImmValue);
2178 Error(IDLoc, "instruction requires a 32-bit immediate");
2183 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2184 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2186 bool UseSrcReg = false;
2187 if (SrcReg != Mips::NoRegister)
2190 unsigned TmpReg = DstReg;
2191 if (UseSrcReg && (DstReg == SrcReg)) {
2192 // At this point we need AT to perform the expansions and we exit if it is
2194 unsigned ATReg = getATReg(IDLoc);
2200 if (isInt<16>(ImmValue)) {
2204 // This doesn't quite follow the usual ABI expectations for N32 but matches
2205 // traditional assembler behaviour. N32 would normally use addiu for both
2206 // integers and addresses.
2207 if (IsAddress && !Is32BitImm) {
2208 emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2212 emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2216 if (isUInt<16>(ImmValue)) {
2217 unsigned TmpReg = DstReg;
2218 if (SrcReg == DstReg) {
2219 TmpReg = getATReg(IDLoc);
2224 emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, Instructions);
2226 emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2230 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2231 warnIfNoMacro(IDLoc);
2233 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2234 uint16_t Bits15To0 = ImmValue & 0xffff;
2236 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2237 // Traditional behaviour seems to special case this particular value. It's
2238 // not clear why other masks are handled differently.
2239 if (ImmValue == 0xffffffff) {
2240 emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, Instructions);
2241 emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, Instructions);
2243 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2247 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2249 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, Instructions);
2250 emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, Instructions);
2252 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2254 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2258 emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, Instructions);
2260 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2262 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2266 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2268 Error(IDLoc, "instruction requires a 32-bit immediate");
2272 // Traditionally, these immediates are shifted as little as possible and as
2273 // such we align the most significant bit to bit 15 of our temporary.
2274 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2275 unsigned LastSet = findLastSet((uint64_t)ImmValue);
2276 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2277 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2278 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, Instructions);
2279 emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, Instructions);
2282 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2287 warnIfNoMacro(IDLoc);
2289 // The remaining case is packed with a sequence of dsll and ori with zeros
2290 // being omitted and any neighbouring dsll's being coalesced.
2291 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2293 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2294 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2295 IDLoc, Instructions))
2298 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2299 // skip it and defer the shift to the next chunk.
2300 unsigned ShiftCarriedForwards = 16;
2301 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2302 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2304 if (ImmChunk != 0) {
2305 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2307 emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, Instructions);
2308 ShiftCarriedForwards = 0;
2311 ShiftCarriedForwards += 16;
2313 ShiftCarriedForwards -= 16;
2315 // Finish any remaining shifts left by trailing zeros.
2316 if (ShiftCarriedForwards)
2317 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2321 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2326 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2327 SmallVectorImpl<MCInst> &Instructions) {
2328 const MCOperand &ImmOp = Inst.getOperand(1);
2329 assert(ImmOp.isImm() && "expected immediate operand kind");
2330 const MCOperand &DstRegOp = Inst.getOperand(0);
2331 assert(DstRegOp.isReg() && "expected register operand kind");
2333 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2334 Is32BitImm, false, IDLoc, Instructions))
2340 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2341 const MCOperand &Offset,
2342 bool Is32BitAddress, SMLoc IDLoc,
2343 SmallVectorImpl<MCInst> &Instructions) {
2344 // la can't produce a usable address when addresses are 64-bit.
2345 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2346 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2347 // We currently can't do this because we depend on the equality
2348 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2349 Error(IDLoc, "la used to load 64-bit address");
2350 // Continue as if we had 'dla' instead.
2351 Is32BitAddress = false;
2354 // dla requires 64-bit addresses.
2355 if (!Is32BitAddress && !ABI.ArePtrs64bit()) {
2356 Error(IDLoc, "instruction requires a 64-bit architecture");
2360 if (!Offset.isImm())
2361 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2362 Is32BitAddress, IDLoc, Instructions);
2364 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2365 IDLoc, Instructions);
2368 bool MipsAsmParser::loadAndAddSymbolAddress(
2369 const MCExpr *SymExpr, unsigned DstReg, unsigned SrcReg, bool Is32BitSym,
2370 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2371 warnIfNoMacro(IDLoc);
2373 const MCExpr *Symbol = cast<MCExpr>(SymExpr);
2374 const MipsMCExpr *HiExpr = MipsMCExpr::create(
2375 MCSymbolRefExpr::VK_Mips_ABS_HI, Symbol, getContext());
2376 const MipsMCExpr *LoExpr = MipsMCExpr::create(
2377 MCSymbolRefExpr::VK_Mips_ABS_LO, Symbol, getContext());
2379 bool UseSrcReg = SrcReg != Mips::NoRegister;
2381 // This is the 64-bit symbol address expansion.
2382 if (ABI.ArePtrs64bit() && isGP64bit()) {
2383 // We always need AT for the 64-bit expansion.
2384 // If it is not available we exit.
2385 unsigned ATReg = getATReg(IDLoc);
2389 const MipsMCExpr *HighestExpr = MipsMCExpr::create(
2390 MCSymbolRefExpr::VK_Mips_HIGHEST, Symbol, getContext());
2391 const MipsMCExpr *HigherExpr = MipsMCExpr::create(
2392 MCSymbolRefExpr::VK_Mips_HIGHER, Symbol, getContext());
2394 if (UseSrcReg && (DstReg == SrcReg)) {
2395 // If $rs is the same as $rd:
2396 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
2397 // daddiu $at, $at, %higher(sym)
2398 // dsll $at, $at, 16
2399 // daddiu $at, $at, %hi(sym)
2400 // dsll $at, $at, 16
2401 // daddiu $at, $at, %lo(sym)
2402 // daddu $rd, $at, $rd
2403 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
2405 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HigherExpr),
2406 IDLoc, Instructions);
2407 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2408 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2410 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2411 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2413 emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, Instructions);
2418 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2419 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
2420 // lui $at, %hi(sym)
2421 // daddiu $rd, $rd, %higher(sym)
2422 // daddiu $at, $at, %lo(sym)
2423 // dsll32 $rd, $rd, 0
2424 // daddu $rd, $rd, $at
2425 // (daddu $rd, $rd, $rs)
2426 emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
2428 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2430 emitRRX(Mips::DADDiu, DstReg, DstReg, MCOperand::createExpr(HigherExpr),
2431 IDLoc, Instructions);
2432 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2434 emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, Instructions);
2435 emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, Instructions);
2437 emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, Instructions);
2442 // And now, the 32-bit symbol address expansion:
2443 // If $rs is the same as $rd:
2444 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
2445 // ori $at, $at, %lo(sym)
2446 // addu $rd, $at, $rd
2447 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2448 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
2449 // ori $rd, $rd, %lo(sym)
2450 // (addu $rd, $rd, $rs)
2451 unsigned TmpReg = DstReg;
2452 if (UseSrcReg && (DstReg == SrcReg)) {
2453 // If $rs is the same as $rd, we need to use AT.
2454 // If it is not available we exit.
2455 unsigned ATReg = getATReg(IDLoc);
2461 emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, Instructions);
2462 emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr), IDLoc,
2466 emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2468 assert(DstReg == TmpReg);
2473 bool MipsAsmParser::expandUncondBranchMMPseudo(
2474 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2475 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2476 "unexpected number of operands");
2478 MCOperand Offset = Inst.getOperand(0);
2479 if (Offset.isExpr()) {
2481 Inst.setOpcode(Mips::BEQ_MM);
2482 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2483 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2484 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2486 assert(Offset.isImm() && "expected immediate operand kind");
2487 if (isInt<11>(Offset.getImm())) {
2488 // If offset fits into 11 bits then this instruction becomes microMIPS
2489 // 16-bit unconditional branch instruction.
2490 if (inMicroMipsMode())
2491 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
2493 if (!isInt<17>(Offset.getImm()))
2494 Error(IDLoc, "branch target out of range");
2495 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2496 Error(IDLoc, "branch to misaligned address");
2498 Inst.setOpcode(Mips::BEQ_MM);
2499 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2500 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2501 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2504 Instructions.push_back(Inst);
2506 // If .set reorder is active and branch instruction has a delay slot,
2507 // emit a NOP after it.
2508 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
2509 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2510 createNop(true, IDLoc, Instructions);
2515 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc,
2516 SmallVectorImpl<MCInst> &Instructions) {
2517 const MCOperand &DstRegOp = Inst.getOperand(0);
2518 assert(DstRegOp.isReg() && "expected register operand kind");
2520 const MCOperand &ImmOp = Inst.getOperand(1);
2521 assert(ImmOp.isImm() && "expected immediate operand kind");
2523 const MCOperand &MemOffsetOp = Inst.getOperand(2);
2524 assert(MemOffsetOp.isImm() && "expected immediate operand kind");
2526 unsigned OpCode = 0;
2527 switch(Inst.getOpcode()) {
2535 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2539 int64_t ImmValue = ImmOp.getImm();
2541 emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
2544 warnIfNoMacro(IDLoc);
2546 unsigned ATReg = getATReg(IDLoc);
2550 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
2551 IDLoc, Instructions))
2554 emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, Instructions);
2559 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2560 SmallVectorImpl<MCInst> &Instructions,
2561 bool isLoad, bool isImmOpnd) {
2562 unsigned ImmOffset, HiOffset, LoOffset;
2563 const MCExpr *ExprOffset;
2565 // 1st operand is either the source or destination register.
2566 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2567 unsigned RegOpNum = Inst.getOperand(0).getReg();
2568 // 2nd operand is the base register.
2569 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2570 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2571 // 3rd operand is either an immediate or expression.
2573 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2574 ImmOffset = Inst.getOperand(2).getImm();
2575 LoOffset = ImmOffset & 0x0000ffff;
2576 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2577 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2578 if (LoOffset & 0x8000)
2581 ExprOffset = Inst.getOperand(2).getExpr();
2582 // These are some of the types of expansions we perform here:
2583 // 1) lw $8, sym => lui $8, %hi(sym)
2584 // lw $8, %lo(sym)($8)
2585 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2587 // lw $8, %lo(offset)($9)
2588 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2590 // lw $8, %lo(offset)($at)
2591 // 4) sw $8, sym => lui $at, %hi(sym)
2592 // sw $8, %lo(sym)($at)
2593 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2595 // sw $8, %lo(offset)($at)
2596 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2597 // ldc1 $f0, %lo(sym)($at)
2599 // For load instructions we can use the destination register as a temporary
2600 // if base and dst are different (examples 1 and 2) and if the base register
2601 // is general purpose otherwise we must use $at (example 6) and error if it's
2602 // not available. For stores we must use $at (examples 4 and 5) because we
2603 // must not clobber the source register setting up the offset.
2604 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2605 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2606 unsigned RegClassIDOp0 =
2607 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2608 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2609 (RegClassIDOp0 == Mips::GPR64RegClassID);
2610 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2611 TmpRegNum = RegOpNum;
2613 // At this point we need AT to perform the expansions and we exit if it is
2615 TmpRegNum = getATReg(IDLoc);
2620 emitRX(Mips::LUi, TmpRegNum,
2621 isImmOpnd ? MCOperand::createImm(HiOffset)
2622 : MCOperand::createExpr(evaluateRelocExpr(ExprOffset, "hi")),
2623 IDLoc, Instructions);
2624 // Add temp register to base.
2625 if (BaseRegNum != Mips::ZERO)
2626 emitRRR(Mips::ADDu, TmpRegNum, TmpRegNum, BaseRegNum, IDLoc, Instructions);
2627 // And finally, create original instruction with low part
2628 // of offset and new base.
2629 emitRRX(Inst.getOpcode(), RegOpNum, TmpRegNum,
2631 ? MCOperand::createImm(LoOffset)
2632 : MCOperand::createExpr(evaluateRelocExpr(ExprOffset, "lo")),
2633 IDLoc, Instructions);
2637 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2638 SmallVectorImpl<MCInst> &Instructions) {
2639 unsigned OpNum = Inst.getNumOperands();
2640 unsigned Opcode = Inst.getOpcode();
2641 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2643 assert (Inst.getOperand(OpNum - 1).isImm() &&
2644 Inst.getOperand(OpNum - 2).isReg() &&
2645 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2647 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2648 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2649 (Inst.getOperand(OpNum - 2).getReg() == Mips::SP ||
2650 Inst.getOperand(OpNum - 2).getReg() == Mips::SP_64) &&
2651 (Inst.getOperand(OpNum - 3).getReg() == Mips::RA ||
2652 Inst.getOperand(OpNum - 3).getReg() == Mips::RA_64)) {
2653 // It can be implemented as SWM16 or LWM16 instruction.
2654 if (inMicroMipsMode() && hasMips32r6())
2655 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
2657 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2660 Inst.setOpcode(NewOpcode);
2661 Instructions.push_back(Inst);
2665 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
2666 SmallVectorImpl<MCInst> &Instructions) {
2667 bool EmittedNoMacroWarning = false;
2668 unsigned PseudoOpcode = Inst.getOpcode();
2669 unsigned SrcReg = Inst.getOperand(0).getReg();
2670 const MCOperand &TrgOp = Inst.getOperand(1);
2671 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
2673 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2674 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
2678 TrgReg = TrgOp.getReg();
2679 else if (TrgOp.isImm()) {
2680 warnIfNoMacro(IDLoc);
2681 EmittedNoMacroWarning = true;
2683 TrgReg = getATReg(IDLoc);
2687 switch(PseudoOpcode) {
2689 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2690 case Mips::BLTImmMacro:
2691 PseudoOpcode = Mips::BLT;
2693 case Mips::BLEImmMacro:
2694 PseudoOpcode = Mips::BLE;
2696 case Mips::BGEImmMacro:
2697 PseudoOpcode = Mips::BGE;
2699 case Mips::BGTImmMacro:
2700 PseudoOpcode = Mips::BGT;
2702 case Mips::BLTUImmMacro:
2703 PseudoOpcode = Mips::BLTU;
2705 case Mips::BLEUImmMacro:
2706 PseudoOpcode = Mips::BLEU;
2708 case Mips::BGEUImmMacro:
2709 PseudoOpcode = Mips::BGEU;
2711 case Mips::BGTUImmMacro:
2712 PseudoOpcode = Mips::BGTU;
2714 case Mips::BLTLImmMacro:
2715 PseudoOpcode = Mips::BLTL;
2717 case Mips::BLELImmMacro:
2718 PseudoOpcode = Mips::BLEL;
2720 case Mips::BGELImmMacro:
2721 PseudoOpcode = Mips::BGEL;
2723 case Mips::BGTLImmMacro:
2724 PseudoOpcode = Mips::BGTL;
2726 case Mips::BLTULImmMacro:
2727 PseudoOpcode = Mips::BLTUL;
2729 case Mips::BLEULImmMacro:
2730 PseudoOpcode = Mips::BLEUL;
2732 case Mips::BGEULImmMacro:
2733 PseudoOpcode = Mips::BGEUL;
2735 case Mips::BGTULImmMacro:
2736 PseudoOpcode = Mips::BGTUL;
2740 if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
2741 false, IDLoc, Instructions))
2745 switch (PseudoOpcode) {
2750 AcceptsEquality = false;
2751 ReverseOrderSLT = false;
2752 IsUnsigned = ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
2753 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
2754 ZeroSrcOpcode = Mips::BGTZ;
2755 ZeroTrgOpcode = Mips::BLTZ;
2761 AcceptsEquality = true;
2762 ReverseOrderSLT = true;
2763 IsUnsigned = ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
2764 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
2765 ZeroSrcOpcode = Mips::BGEZ;
2766 ZeroTrgOpcode = Mips::BLEZ;
2772 AcceptsEquality = true;
2773 ReverseOrderSLT = false;
2774 IsUnsigned = ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
2775 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
2776 ZeroSrcOpcode = Mips::BLEZ;
2777 ZeroTrgOpcode = Mips::BGEZ;
2783 AcceptsEquality = false;
2784 ReverseOrderSLT = true;
2785 IsUnsigned = ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
2786 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
2787 ZeroSrcOpcode = Mips::BLTZ;
2788 ZeroTrgOpcode = Mips::BGTZ;
2791 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2794 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
2795 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
2796 if (IsSrcRegZero && IsTrgRegZero) {
2797 // FIXME: All of these Opcode-specific if's are needed for compatibility
2798 // with GAS' behaviour. However, they may not generate the most efficient
2799 // code in some circumstances.
2800 if (PseudoOpcode == Mips::BLT) {
2801 emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2805 if (PseudoOpcode == Mips::BLE) {
2806 emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2808 Warning(IDLoc, "branch is always taken");
2811 if (PseudoOpcode == Mips::BGE) {
2812 emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2814 Warning(IDLoc, "branch is always taken");
2817 if (PseudoOpcode == Mips::BGT) {
2818 emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2822 if (PseudoOpcode == Mips::BGTU) {
2823 emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
2824 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2827 if (AcceptsEquality) {
2828 // If both registers are $0 and the pseudo-branch accepts equality, it
2829 // will always be taken, so we emit an unconditional branch.
2830 emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
2831 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2832 Warning(IDLoc, "branch is always taken");
2835 // If both registers are $0 and the pseudo-branch does not accept
2836 // equality, it will never be taken, so we don't have to emit anything.
2839 if (IsSrcRegZero || IsTrgRegZero) {
2840 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
2841 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
2842 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
2843 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
2844 // the pseudo-branch will never be taken, so we don't emit anything.
2845 // This only applies to unsigned pseudo-branches.
2848 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
2849 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
2850 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
2851 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
2852 // the pseudo-branch will always be taken, so we emit an unconditional
2854 // This only applies to unsigned pseudo-branches.
2855 emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
2856 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2857 Warning(IDLoc, "branch is always taken");
2861 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
2862 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
2863 // the pseudo-branch will be taken only when the non-zero register is
2864 // different from 0, so we emit a BNEZ.
2866 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
2867 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
2868 // the pseudo-branch will be taken only when the non-zero register is
2869 // equal to 0, so we emit a BEQZ.
2871 // Because only BLEU and BGEU branch on equality, we can use the
2872 // AcceptsEquality variable to decide when to emit the BEQZ.
2873 emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
2874 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
2875 MCOperand::createExpr(OffsetExpr), IDLoc, Instructions);
2878 // If we have a signed pseudo-branch and one of the registers is $0,
2879 // we can use an appropriate compare-to-zero branch. We select which one
2880 // to use in the switch statement above.
2881 emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
2882 IsSrcRegZero ? TrgReg : SrcReg, MCOperand::createExpr(OffsetExpr),
2883 IDLoc, Instructions);
2887 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
2888 // expansions. If it is not available, we return.
2889 unsigned ATRegNum = getATReg(IDLoc);
2893 if (!EmittedNoMacroWarning)
2894 warnIfNoMacro(IDLoc);
2896 // SLT fits well with 2 of our 4 pseudo-branches:
2897 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
2898 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
2899 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
2900 // This is accomplished by using a BNEZ with the result of the SLT.
2902 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
2903 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
2904 // Because only BGE and BLE branch on equality, we can use the
2905 // AcceptsEquality variable to decide when to emit the BEQZ.
2906 // Note that the order of the SLT arguments doesn't change between
2909 // The same applies to the unsigned variants, except that SLTu is used
2911 emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
2912 ReverseOrderSLT ? TrgReg : SrcReg, ReverseOrderSLT ? SrcReg : TrgReg,
2913 IDLoc, Instructions);
2915 emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
2916 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
2917 ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
2922 bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc,
2923 SmallVectorImpl<MCInst> &Instructions,
2924 const bool IsMips64, const bool Signed) {
2925 if (hasMips32r6()) {
2926 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2930 warnIfNoMacro(IDLoc);
2932 const MCOperand &RsRegOp = Inst.getOperand(0);
2933 assert(RsRegOp.isReg() && "expected register operand kind");
2934 unsigned RsReg = RsRegOp.getReg();
2936 const MCOperand &RtRegOp = Inst.getOperand(1);
2937 assert(RtRegOp.isReg() && "expected register operand kind");
2938 unsigned RtReg = RtRegOp.getReg();
2943 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
2944 ZeroReg = Mips::ZERO_64;
2946 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
2947 ZeroReg = Mips::ZERO;
2950 bool UseTraps = useTraps();
2952 if (RsReg == Mips::ZERO || RsReg == Mips::ZERO_64) {
2953 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)
2954 Warning(IDLoc, "dividing zero by zero");
2956 if (Signed && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
2958 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2962 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2966 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2971 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
2972 Warning(IDLoc, "division by zero");
2975 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2979 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2984 // FIXME: The values for these two BranchTarget variables may be different in
2985 // micromips. These magic numbers need to be removed.
2986 unsigned BranchTargetNoTraps;
2987 unsigned BranchTarget;
2990 BranchTarget = IsMips64 ? 12 : 8;
2991 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2993 BranchTarget = IsMips64 ? 20 : 16;
2994 BranchTargetNoTraps = 8;
2995 // Branch to the li instruction.
2996 emitRRI(Mips::BNE, RtReg, ZeroReg, BranchTargetNoTraps, IDLoc,
3000 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
3003 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
3006 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
3010 unsigned ATReg = getATReg(IDLoc);
3014 emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, Instructions);
3016 // Branch to the mflo instruction.
3017 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
3018 emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, Instructions);
3019 emitRRI(Mips::DSLL32, ATReg, ATReg, 0x1f, IDLoc, Instructions);
3021 // Branch to the mflo instruction.
3022 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
3023 emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, Instructions);
3027 emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, Instructions);
3029 // Branch to the mflo instruction.
3030 emitRRI(Mips::BNE, RsReg, ATReg, BranchTargetNoTraps, IDLoc, Instructions);
3031 emitRRI(Mips::SLL, ZeroReg, ZeroReg, 0, IDLoc, Instructions);
3032 emitII(Mips::BREAK, 0x6, 0, IDLoc, Instructions);
3034 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
3038 bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
3039 SmallVectorImpl<MCInst> &Instructions) {
3040 if (hasMips32r6() || hasMips64r6()) {
3041 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3045 warnIfNoMacro(IDLoc);
3047 const MCOperand &DstRegOp = Inst.getOperand(0);
3048 assert(DstRegOp.isReg() && "expected register operand kind");
3050 const MCOperand &SrcRegOp = Inst.getOperand(1);
3051 assert(SrcRegOp.isReg() && "expected register operand kind");
3053 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3054 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3056 unsigned DstReg = DstRegOp.getReg();
3057 unsigned SrcReg = SrcRegOp.getReg();
3058 int64_t OffsetValue = OffsetImmOp.getImm();
3060 // NOTE: We always need AT for ULHU, as it is always used as the source
3061 // register for one of the LBu's.
3062 unsigned ATReg = getATReg(IDLoc);
3066 // When the value of offset+1 does not fit in 16 bits, we have to load the
3067 // offset in AT, (D)ADDu the original source register (if there was one), and
3068 // then use AT as the source register for the 2 generated LBu's.
3069 bool LoadedOffsetInAT = false;
3070 if (!isInt<16>(OffsetValue + 1) || !isInt<16>(OffsetValue)) {
3071 LoadedOffsetInAT = true;
3073 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3074 true, IDLoc, Instructions))
3077 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3078 // because it will make our output more similar to GAS'. For example,
3079 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3080 // instead of just an "ori $1, $9, 32768".
3081 // NOTE: If there is no source register specified in the ULHU, the parser
3082 // will interpret it as $0.
3083 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3084 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
3087 unsigned FirstLbuDstReg = LoadedOffsetInAT ? DstReg : ATReg;
3088 unsigned SecondLbuDstReg = LoadedOffsetInAT ? ATReg : DstReg;
3089 unsigned LbuSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3091 int64_t FirstLbuOffset = 0, SecondLbuOffset = 0;
3093 FirstLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
3094 SecondLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3096 FirstLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3097 SecondLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
3100 unsigned SllReg = LoadedOffsetInAT ? DstReg : ATReg;
3102 emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
3103 FirstLbuOffset, IDLoc, Instructions);
3105 emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondLbuOffset, IDLoc,
3108 emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, Instructions);
3110 emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, Instructions);
3115 bool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc,
3116 SmallVectorImpl<MCInst> &Instructions) {
3117 if (hasMips32r6() || hasMips64r6()) {
3118 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3122 const MCOperand &DstRegOp = Inst.getOperand(0);
3123 assert(DstRegOp.isReg() && "expected register operand kind");
3125 const MCOperand &SrcRegOp = Inst.getOperand(1);
3126 assert(SrcRegOp.isReg() && "expected register operand kind");
3128 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3129 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3131 unsigned SrcReg = SrcRegOp.getReg();
3132 int64_t OffsetValue = OffsetImmOp.getImm();
3135 // When the value of offset+3 does not fit in 16 bits, we have to load the
3136 // offset in AT, (D)ADDu the original source register (if there was one), and
3137 // then use AT as the source register for the generated LWL and LWR.
3138 bool LoadedOffsetInAT = false;
3139 if (!isInt<16>(OffsetValue + 3) || !isInt<16>(OffsetValue)) {
3140 ATReg = getATReg(IDLoc);
3143 LoadedOffsetInAT = true;
3145 warnIfNoMacro(IDLoc);
3147 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3148 true, IDLoc, Instructions))
3151 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3152 // because it will make our output more similar to GAS'. For example,
3153 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3154 // instead of just an "ori $1, $9, 32768".
3155 // NOTE: If there is no source register specified in the ULW, the parser
3156 // will interpret it as $0.
3157 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3158 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
3161 unsigned FinalSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3162 int64_t LeftLoadOffset = 0, RightLoadOffset = 0;
3164 LeftLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3165 RightLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3167 LeftLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3168 RightLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3171 emitRRI(Mips::LWL, DstRegOp.getReg(), FinalSrcReg, LeftLoadOffset, IDLoc,
3174 emitRRI(Mips::LWR, DstRegOp.getReg(), FinalSrcReg, RightLoadOffset, IDLoc,
3180 bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
3181 SmallVectorImpl<MCInst> &Instructions) {
3183 assert (Inst.getNumOperands() == 3 && "Invalid operand count");
3184 assert (Inst.getOperand(0).isReg() &&
3185 Inst.getOperand(1).isReg() &&
3186 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
3188 unsigned ATReg = Mips::NoRegister;
3189 unsigned FinalDstReg = Mips::NoRegister;
3190 unsigned DstReg = Inst.getOperand(0).getReg();
3191 unsigned SrcReg = Inst.getOperand(1).getReg();
3192 int64_t ImmValue = Inst.getOperand(2).getImm();
3194 bool Is32Bit = isInt<32>(ImmValue) || isUInt<32>(ImmValue);
3196 unsigned FinalOpcode = Inst.getOpcode();
3198 if (DstReg == SrcReg) {
3199 ATReg = getATReg(Inst.getLoc());
3202 FinalDstReg = DstReg;
3206 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false, Inst.getLoc(), Instructions)) {
3207 switch (FinalOpcode) {
3209 llvm_unreachable("unimplemented expansion");
3211 FinalOpcode = Mips::ADD;
3214 FinalOpcode = Mips::ADDu;
3217 FinalOpcode = Mips::AND;
3219 case (Mips::NORImm):
3220 FinalOpcode = Mips::NOR;
3223 FinalOpcode = Mips::OR;
3226 FinalOpcode = Mips::SLT;
3229 FinalOpcode = Mips::SLTu;
3232 FinalOpcode = Mips::XOR;
3236 if (FinalDstReg == Mips::NoRegister)
3237 emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, Instructions);
3239 emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc,
3246 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
3247 SmallVectorImpl<MCInst> &Instructions) {
3248 if (hasShortDelaySlot)
3249 emitRR(Mips::MOVE16_MM, Mips::ZERO, Mips::ZERO, IDLoc, Instructions);
3251 emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, Instructions);
3254 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
3255 unsigned TrgReg, bool Is64Bit,
3256 SmallVectorImpl<MCInst> &Instructions) {
3257 emitRRR(Is64Bit ? Mips::DADDu : Mips::ADDu, DstReg, SrcReg, TrgReg, SMLoc(),
3261 void MipsAsmParser::createCpRestoreMemOp(
3262 bool IsLoad, int StackOffset, SMLoc IDLoc,
3263 SmallVectorImpl<MCInst> &Instructions) {
3264 // If the offset can not fit into 16 bits, we need to expand.
3265 if (!isInt<16>(StackOffset)) {
3267 MemInst.setOpcode(IsLoad ? Mips::LW : Mips::SW);
3268 MemInst.addOperand(MCOperand::createReg(Mips::GP));
3269 MemInst.addOperand(MCOperand::createReg(Mips::SP));
3270 MemInst.addOperand(MCOperand::createImm(StackOffset));
3271 expandMemInst(MemInst, IDLoc, Instructions, IsLoad, true /*HasImmOpnd*/);
3275 emitRRI(IsLoad ? Mips::LW : Mips::SW, Mips::GP, Mips::SP, StackOffset, IDLoc,
3279 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3280 // As described by the Mips32r2 spec, the registers Rd and Rs for
3281 // jalr.hb must be different.
3282 unsigned Opcode = Inst.getOpcode();
3284 if (Opcode == Mips::JALR_HB &&
3285 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
3286 return Match_RequiresDifferentSrcAndDst;
3288 return Match_Success;
3291 static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands,
3292 uint64_t ErrorInfo) {
3293 if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) {
3294 SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc();
3295 if (ErrorLoc == SMLoc())
3302 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
3303 OperandVector &Operands,
3305 uint64_t &ErrorInfo,
3306 bool MatchingInlineAsm) {
3309 SmallVector<MCInst, 8> Instructions;
3310 unsigned MatchResult =
3311 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
3313 switch (MatchResult) {
3314 case Match_Success: {
3315 if (processInstruction(Inst, IDLoc, Instructions))
3317 for (unsigned i = 0; i < Instructions.size(); i++)
3318 Out.EmitInstruction(Instructions[i], getSTI());
3321 case Match_MissingFeature:
3322 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
3324 case Match_InvalidOperand: {
3325 SMLoc ErrorLoc = IDLoc;
3326 if (ErrorInfo != ~0ULL) {
3327 if (ErrorInfo >= Operands.size())
3328 return Error(IDLoc, "too few operands for instruction");
3330 ErrorLoc = Operands[ErrorInfo]->getStartLoc();
3331 if (ErrorLoc == SMLoc())
3335 return Error(ErrorLoc, "invalid operand for instruction");
3337 case Match_MnemonicFail:
3338 return Error(IDLoc, "invalid instruction");
3339 case Match_RequiresDifferentSrcAndDst:
3340 return Error(IDLoc, "source and destination must be different");
3342 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'");
3344 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3345 "expected 1-bit unsigned immediate");
3347 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3348 "expected 2-bit unsigned immediate");
3350 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3351 "expected immediate in range 1 .. 4");
3353 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3354 "expected 3-bit unsigned immediate");
3356 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3357 "expected 4-bit unsigned immediate");
3360 llvm_unreachable("Implement any new match types added!");
3363 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
3364 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
3365 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
3366 ") without \".set noat\"");
3369 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
3370 if (!AssemblerOptions.back()->isMacro())
3371 Warning(Loc, "macro instruction expanded into multiple instructions");
3375 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
3376 SMRange Range, bool ShowColors) {
3377 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
3378 Range, SMFixIt(Range, FixMsg),
3382 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
3385 CC = StringSwitch<unsigned>(Name)
3421 if (!(isABI_N32() || isABI_N64()))
3424 if (12 <= CC && CC <= 15) {
3425 // Name is one of t4-t7
3426 AsmToken RegTok = getLexer().peekTok();
3427 SMRange RegRange = RegTok.getLocRange();
3429 StringRef FixedName = StringSwitch<StringRef>(Name)
3435 assert(FixedName != "" && "Register name is not one of t4-t7.");
3437 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
3438 "Did you mean $" + FixedName + "?", RegRange);
3441 // Although SGI documentation just cuts out t0-t3 for n32/n64,
3442 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
3443 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
3444 if (8 <= CC && CC <= 11)
3448 CC = StringSwitch<unsigned>(Name)
3460 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
3463 CC = StringSwitch<unsigned>(Name)
3464 .Case("hwr_cpunum", 0)
3465 .Case("hwr_synci_step", 1)
3467 .Case("hwr_ccres", 3)
3468 .Case("hwr_ulr", 29)
3474 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
3476 if (Name[0] == 'f') {
3477 StringRef NumString = Name.substr(1);
3479 if (NumString.getAsInteger(10, IntVal))
3480 return -1; // This is not an integer.
3481 if (IntVal > 31) // Maximum index for fpu register.
3488 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
3490 if (Name.startswith("fcc")) {
3491 StringRef NumString = Name.substr(3);
3493 if (NumString.getAsInteger(10, IntVal))
3494 return -1; // This is not an integer.
3495 if (IntVal > 7) // There are only 8 fcc registers.
3502 int MipsAsmParser::matchACRegisterName(StringRef Name) {
3504 if (Name.startswith("ac")) {
3505 StringRef NumString = Name.substr(2);
3507 if (NumString.getAsInteger(10, IntVal))
3508 return -1; // This is not an integer.
3509 if (IntVal > 3) // There are only 3 acc registers.
3516 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
3519 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
3528 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
3531 CC = StringSwitch<unsigned>(Name)
3534 .Case("msaaccess", 2)
3536 .Case("msamodify", 4)
3537 .Case("msarequest", 5)
3539 .Case("msaunmap", 7)
3545 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
3546 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
3548 reportParseError(Loc,
3549 "pseudo-instruction requires $at, which is not available");
3552 unsigned AT = getReg(
3553 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
3557 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
3558 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
3561 unsigned MipsAsmParser::getGPR(int RegNo) {
3562 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
3566 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
3568 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
3571 return getReg(RegClass, RegNum);
3574 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
3575 MCAsmParser &Parser = getParser();
3576 DEBUG(dbgs() << "parseOperand\n");
3578 // Check if the current operand has a custom associated parser, if so, try to
3579 // custom parse the operand, or fallback to the general approach.
3580 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
3581 if (ResTy == MatchOperand_Success)
3583 // If there wasn't a custom match, try the generic matcher below. Otherwise,
3584 // there was a match, but an error occurred, in which case, just return that
3585 // the operand parsing failed.
3586 if (ResTy == MatchOperand_ParseFail)
3589 DEBUG(dbgs() << ".. Generic Parser\n");
3591 switch (getLexer().getKind()) {
3593 Error(Parser.getTok().getLoc(), "unexpected token in operand");
3595 case AsmToken::Dollar: {
3596 // Parse the register.
3597 SMLoc S = Parser.getTok().getLoc();
3599 // Almost all registers have been parsed by custom parsers. There is only
3600 // one exception to this. $zero (and it's alias $0) will reach this point
3601 // for div, divu, and similar instructions because it is not an operand
3602 // to the instruction definition but an explicit register. Special case
3603 // this situation for now.
3604 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
3607 // Maybe it is a symbol reference.
3608 StringRef Identifier;
3609 if (Parser.parseIdentifier(Identifier))
3612 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3613 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
3614 // Otherwise create a symbol reference.
3616 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3618 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
3621 // Else drop to expression parsing.
3622 case AsmToken::LParen:
3623 case AsmToken::Minus:
3624 case AsmToken::Plus:
3625 case AsmToken::Integer:
3626 case AsmToken::Tilde:
3627 case AsmToken::String: {
3628 DEBUG(dbgs() << ".. generic integer\n");
3629 OperandMatchResultTy ResTy = parseImm(Operands);
3630 return ResTy != MatchOperand_Success;
3632 case AsmToken::Percent: {
3633 // It is a symbol reference or constant expression.
3634 const MCExpr *IdVal;
3635 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
3636 if (parseRelocOperand(IdVal))
3639 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3641 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3643 } // case AsmToken::Percent
3644 } // switch(getLexer().getKind())
3648 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
3649 StringRef RelocStr) {
3651 // Check the type of the expression.
3652 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
3653 // It's a constant, evaluate reloc value.
3655 switch (getVariantKind(RelocStr)) {
3656 case MCSymbolRefExpr::VK_Mips_ABS_LO:
3657 // Get the 1st 16-bits.
3658 Val = MCE->getValue() & 0xffff;
3660 case MCSymbolRefExpr::VK_Mips_ABS_HI:
3661 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
3662 // 16 bits being negative.
3663 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
3665 case MCSymbolRefExpr::VK_Mips_HIGHER:
3666 // Get the 3rd 16-bits.
3667 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
3669 case MCSymbolRefExpr::VK_Mips_HIGHEST:
3670 // Get the 4th 16-bits.
3671 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
3674 report_fatal_error("unsupported reloc value");
3676 return MCConstantExpr::create(Val, getContext());
3679 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
3680 // It's a symbol, create a symbolic expression from the symbol.
3681 const MCSymbol *Symbol = &MSRE->getSymbol();
3682 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3683 Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
3687 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3688 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3690 // Try to create target expression.
3691 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
3692 return MipsMCExpr::create(VK, Expr, getContext());
3694 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
3695 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
3696 Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
3700 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
3701 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
3702 Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
3705 // Just return the original expression.
3709 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
3711 switch (Expr->getKind()) {
3712 case MCExpr::Constant:
3714 case MCExpr::SymbolRef:
3715 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
3716 case MCExpr::Binary:
3717 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3718 if (!isEvaluated(BE->getLHS()))
3720 return isEvaluated(BE->getRHS());
3723 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
3724 case MCExpr::Target:
3730 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
3731 MCAsmParser &Parser = getParser();
3732 Parser.Lex(); // Eat the % token.
3733 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
3734 if (Tok.isNot(AsmToken::Identifier))
3737 std::string Str = Tok.getIdentifier();
3739 Parser.Lex(); // Eat the identifier.
3740 // Now make an expression from the rest of the operand.
3741 const MCExpr *IdVal;
3744 if (getLexer().getKind() == AsmToken::LParen) {
3746 Parser.Lex(); // Eat the '(' token.
3747 if (getLexer().getKind() == AsmToken::Percent) {
3748 Parser.Lex(); // Eat the % token.
3749 const AsmToken &nextTok = Parser.getTok();
3750 if (nextTok.isNot(AsmToken::Identifier))
3753 Str += nextTok.getIdentifier();
3754 Parser.Lex(); // Eat the identifier.
3755 if (getLexer().getKind() != AsmToken::LParen)
3760 if (getParser().parseParenExpression(IdVal, EndLoc))
3763 while (getLexer().getKind() == AsmToken::RParen)
3764 Parser.Lex(); // Eat the ')' token.
3767 return true; // Parenthesis must follow the relocation operand.
3769 Res = evaluateRelocExpr(IdVal, Str);
3773 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
3775 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
3776 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
3777 if (ResTy == MatchOperand_Success) {
3778 assert(Operands.size() == 1);
3779 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
3780 StartLoc = Operand.getStartLoc();
3781 EndLoc = Operand.getEndLoc();
3783 // AFAIK, we only support numeric registers and named GPR's in CFI
3785 // Don't worry about eating tokens before failing. Using an unrecognised
3786 // register is a parse error.
3787 if (Operand.isGPRAsmReg()) {
3788 // Resolve to GPR32 or GPR64 appropriately.
3789 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
3792 return (RegNo == (unsigned)-1);
3795 assert(Operands.size() == 0);
3796 return (RegNo == (unsigned)-1);
3799 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
3800 MCAsmParser &Parser = getParser();
3803 unsigned NumOfLParen = 0;
3805 while (getLexer().getKind() == AsmToken::LParen) {
3810 switch (getLexer().getKind()) {
3813 case AsmToken::Identifier:
3814 case AsmToken::LParen:
3815 case AsmToken::Integer:
3816 case AsmToken::Minus:
3817 case AsmToken::Plus:
3819 Result = getParser().parseParenExprOfDepth(NumOfLParen, Res, S);
3821 Result = (getParser().parseExpression(Res));
3822 while (getLexer().getKind() == AsmToken::RParen)
3825 case AsmToken::Percent:
3826 Result = parseRelocOperand(Res);
3831 MipsAsmParser::OperandMatchResultTy
3832 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
3833 MCAsmParser &Parser = getParser();
3834 DEBUG(dbgs() << "parseMemOperand\n");
3835 const MCExpr *IdVal = nullptr;
3837 bool isParenExpr = false;
3838 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
3839 // First operand is the offset.
3840 S = Parser.getTok().getLoc();
3842 if (getLexer().getKind() == AsmToken::LParen) {
3847 if (getLexer().getKind() != AsmToken::Dollar) {
3848 if (parseMemOffset(IdVal, isParenExpr))
3849 return MatchOperand_ParseFail;
3851 const AsmToken &Tok = Parser.getTok(); // Get the next token.
3852 if (Tok.isNot(AsmToken::LParen)) {
3853 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
3854 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
3856 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3857 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3858 return MatchOperand_Success;
3860 if (Tok.is(AsmToken::EndOfStatement)) {
3862 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3864 // Zero register assumed, add a memory operand with ZERO as its base.
3865 // "Base" will be managed by k_Memory.
3866 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
3869 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
3870 return MatchOperand_Success;
3872 Error(Parser.getTok().getLoc(), "'(' expected");
3873 return MatchOperand_ParseFail;
3876 Parser.Lex(); // Eat the '(' token.
3879 Res = parseAnyRegister(Operands);
3880 if (Res != MatchOperand_Success)
3883 if (Parser.getTok().isNot(AsmToken::RParen)) {
3884 Error(Parser.getTok().getLoc(), "')' expected");
3885 return MatchOperand_ParseFail;
3888 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3890 Parser.Lex(); // Eat the ')' token.
3893 IdVal = MCConstantExpr::create(0, getContext());
3895 // Replace the register operand with the memory operand.
3896 std::unique_ptr<MipsOperand> op(
3897 static_cast<MipsOperand *>(Operands.back().release()));
3898 // Remove the register from the operands.
3899 // "op" will be managed by k_Memory.
3900 Operands.pop_back();
3901 // Add the memory operand.
3902 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
3904 if (IdVal->evaluateAsAbsolute(Imm))
3905 IdVal = MCConstantExpr::create(Imm, getContext());
3906 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
3907 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
3911 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
3912 return MatchOperand_Success;
3915 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
3916 MCAsmParser &Parser = getParser();
3917 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
3919 SMLoc S = Parser.getTok().getLoc();
3921 if (Sym->isVariable())
3922 Expr = Sym->getVariableValue();
3925 if (Expr->getKind() == MCExpr::SymbolRef) {
3926 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3927 StringRef DefSymbol = Ref->getSymbol().getName();
3928 if (DefSymbol.startswith("$")) {
3929 OperandMatchResultTy ResTy =
3930 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
3931 if (ResTy == MatchOperand_Success) {
3934 } else if (ResTy == MatchOperand_ParseFail)
3935 llvm_unreachable("Should never ParseFail");
3938 } else if (Expr->getKind() == MCExpr::Constant) {
3940 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
3942 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
3949 MipsAsmParser::OperandMatchResultTy
3950 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
3951 StringRef Identifier,
3953 int Index = matchCPURegisterName(Identifier);
3955 Operands.push_back(MipsOperand::createGPRReg(
3956 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3957 return MatchOperand_Success;
3960 Index = matchHWRegsRegisterName(Identifier);
3962 Operands.push_back(MipsOperand::createHWRegsReg(
3963 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3964 return MatchOperand_Success;
3967 Index = matchFPURegisterName(Identifier);
3969 Operands.push_back(MipsOperand::createFGRReg(
3970 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3971 return MatchOperand_Success;
3974 Index = matchFCCRegisterName(Identifier);
3976 Operands.push_back(MipsOperand::createFCCReg(
3977 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3978 return MatchOperand_Success;
3981 Index = matchACRegisterName(Identifier);
3983 Operands.push_back(MipsOperand::createACCReg(
3984 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3985 return MatchOperand_Success;
3988 Index = matchMSA128RegisterName(Identifier);
3990 Operands.push_back(MipsOperand::createMSA128Reg(
3991 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3992 return MatchOperand_Success;
3995 Index = matchMSA128CtrlRegisterName(Identifier);
3997 Operands.push_back(MipsOperand::createMSACtrlReg(
3998 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3999 return MatchOperand_Success;
4002 return MatchOperand_NoMatch;
4005 MipsAsmParser::OperandMatchResultTy
4006 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
4007 MCAsmParser &Parser = getParser();
4008 auto Token = Parser.getLexer().peekTok(false);
4010 if (Token.is(AsmToken::Identifier)) {
4011 DEBUG(dbgs() << ".. identifier\n");
4012 StringRef Identifier = Token.getIdentifier();
4013 OperandMatchResultTy ResTy =
4014 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
4016 } else if (Token.is(AsmToken::Integer)) {
4017 DEBUG(dbgs() << ".. integer\n");
4018 Operands.push_back(MipsOperand::createNumericReg(
4019 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
4021 return MatchOperand_Success;
4024 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
4026 return MatchOperand_NoMatch;
4029 MipsAsmParser::OperandMatchResultTy
4030 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
4031 MCAsmParser &Parser = getParser();
4032 DEBUG(dbgs() << "parseAnyRegister\n");
4034 auto Token = Parser.getTok();
4036 SMLoc S = Token.getLoc();
4038 if (Token.isNot(AsmToken::Dollar)) {
4039 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
4040 if (Token.is(AsmToken::Identifier)) {
4041 if (searchSymbolAlias(Operands))
4042 return MatchOperand_Success;
4044 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
4045 return MatchOperand_NoMatch;
4047 DEBUG(dbgs() << ".. $\n");
4049 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
4050 if (ResTy == MatchOperand_Success) {
4052 Parser.Lex(); // identifier
4057 MipsAsmParser::OperandMatchResultTy
4058 MipsAsmParser::parseImm(OperandVector &Operands) {
4059 MCAsmParser &Parser = getParser();
4060 switch (getLexer().getKind()) {
4062 return MatchOperand_NoMatch;
4063 case AsmToken::LParen:
4064 case AsmToken::Minus:
4065 case AsmToken::Plus:
4066 case AsmToken::Integer:
4067 case AsmToken::Tilde:
4068 case AsmToken::String:
4072 const MCExpr *IdVal;
4073 SMLoc S = Parser.getTok().getLoc();
4074 if (getParser().parseExpression(IdVal))
4075 return MatchOperand_ParseFail;
4077 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4078 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
4079 return MatchOperand_Success;
4082 MipsAsmParser::OperandMatchResultTy
4083 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
4084 MCAsmParser &Parser = getParser();
4085 DEBUG(dbgs() << "parseJumpTarget\n");
4087 SMLoc S = getLexer().getLoc();
4089 // Integers and expressions are acceptable
4090 OperandMatchResultTy ResTy = parseImm(Operands);
4091 if (ResTy != MatchOperand_NoMatch)
4094 // Registers are a valid target and have priority over symbols.
4095 ResTy = parseAnyRegister(Operands);
4096 if (ResTy != MatchOperand_NoMatch)
4099 const MCExpr *Expr = nullptr;
4100 if (Parser.parseExpression(Expr)) {
4101 // We have no way of knowing if a symbol was consumed so we must ParseFail
4102 return MatchOperand_ParseFail;
4105 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
4106 return MatchOperand_Success;
4109 MipsAsmParser::OperandMatchResultTy
4110 MipsAsmParser::parseInvNum(OperandVector &Operands) {
4111 MCAsmParser &Parser = getParser();
4112 const MCExpr *IdVal;
4113 // If the first token is '$' we may have register operand.
4114 if (Parser.getTok().is(AsmToken::Dollar))
4115 return MatchOperand_NoMatch;
4116 SMLoc S = Parser.getTok().getLoc();
4117 if (getParser().parseExpression(IdVal))
4118 return MatchOperand_ParseFail;
4119 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
4120 assert(MCE && "Unexpected MCExpr type.");
4121 int64_t Val = MCE->getValue();
4122 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4123 Operands.push_back(MipsOperand::CreateImm(
4124 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
4125 return MatchOperand_Success;
4128 MipsAsmParser::OperandMatchResultTy
4129 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
4130 MCAsmParser &Parser = getParser();
4131 switch (getLexer().getKind()) {
4133 return MatchOperand_NoMatch;
4134 case AsmToken::LParen:
4135 case AsmToken::Plus:
4136 case AsmToken::Minus:
4137 case AsmToken::Integer:
4142 SMLoc S = Parser.getTok().getLoc();
4144 if (getParser().parseExpression(Expr))
4145 return MatchOperand_ParseFail;
4148 if (!Expr->evaluateAsAbsolute(Val)) {
4149 Error(S, "expected immediate value");
4150 return MatchOperand_ParseFail;
4153 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
4154 // and because the CPU always adds one to the immediate field, the allowed
4155 // range becomes 1..4. We'll only check the range here and will deal
4156 // with the addition/subtraction when actually decoding/encoding
4158 if (Val < 1 || Val > 4) {
4159 Error(S, "immediate not in range (1..4)");
4160 return MatchOperand_ParseFail;
4164 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
4165 return MatchOperand_Success;
4168 MipsAsmParser::OperandMatchResultTy
4169 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
4170 MCAsmParser &Parser = getParser();
4171 SmallVector<unsigned, 10> Regs;
4173 unsigned PrevReg = Mips::NoRegister;
4174 bool RegRange = false;
4175 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4177 if (Parser.getTok().isNot(AsmToken::Dollar))
4178 return MatchOperand_ParseFail;
4180 SMLoc S = Parser.getTok().getLoc();
4181 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
4182 SMLoc E = getLexer().getLoc();
4183 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
4184 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
4186 // Remove last register operand because registers from register range
4187 // should be inserted first.
4188 if ((isGP64bit() && RegNo == Mips::RA_64) ||
4189 (!isGP64bit() && RegNo == Mips::RA)) {
4190 Regs.push_back(RegNo);
4192 unsigned TmpReg = PrevReg + 1;
4193 while (TmpReg <= RegNo) {
4194 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
4195 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
4197 Error(E, "invalid register operand");
4198 return MatchOperand_ParseFail;
4202 Regs.push_back(TmpReg++);
4208 if ((PrevReg == Mips::NoRegister) &&
4209 ((isGP64bit() && (RegNo != Mips::S0_64) && (RegNo != Mips::RA_64)) ||
4210 (!isGP64bit() && (RegNo != Mips::S0) && (RegNo != Mips::RA)))) {
4211 Error(E, "$16 or $31 expected");
4212 return MatchOperand_ParseFail;
4213 } else if (!(((RegNo == Mips::FP || RegNo == Mips::RA ||
4214 (RegNo >= Mips::S0 && RegNo <= Mips::S7)) &&
4216 ((RegNo == Mips::FP_64 || RegNo == Mips::RA_64 ||
4217 (RegNo >= Mips::S0_64 && RegNo <= Mips::S7_64)) &&
4219 Error(E, "invalid register operand");
4220 return MatchOperand_ParseFail;
4221 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
4222 ((RegNo != Mips::FP && RegNo != Mips::RA && !isGP64bit()) ||
4223 (RegNo != Mips::FP_64 && RegNo != Mips::RA_64 &&
4225 Error(E, "consecutive register numbers expected");
4226 return MatchOperand_ParseFail;
4229 Regs.push_back(RegNo);
4232 if (Parser.getTok().is(AsmToken::Minus))
4235 if (!Parser.getTok().isNot(AsmToken::Minus) &&
4236 !Parser.getTok().isNot(AsmToken::Comma)) {
4237 Error(E, "',' or '-' expected");
4238 return MatchOperand_ParseFail;
4241 Lex(); // Consume comma or minus
4242 if (Parser.getTok().isNot(AsmToken::Dollar))
4248 SMLoc E = Parser.getTok().getLoc();
4249 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4250 parseMemOperand(Operands);
4251 return MatchOperand_Success;
4254 MipsAsmParser::OperandMatchResultTy
4255 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
4256 MCAsmParser &Parser = getParser();
4258 SMLoc S = Parser.getTok().getLoc();
4259 if (parseAnyRegister(Operands) != MatchOperand_Success)
4260 return MatchOperand_ParseFail;
4262 SMLoc E = Parser.getTok().getLoc();
4263 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
4264 unsigned Reg = Op.getGPR32Reg();
4265 Operands.pop_back();
4266 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
4267 return MatchOperand_Success;
4270 MipsAsmParser::OperandMatchResultTy
4271 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
4272 MCAsmParser &Parser = getParser();
4273 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4274 SmallVector<unsigned, 10> Regs;
4276 if (Parser.getTok().isNot(AsmToken::Dollar))
4277 return MatchOperand_ParseFail;
4279 SMLoc S = Parser.getTok().getLoc();
4281 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4282 return MatchOperand_ParseFail;
4284 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4285 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4286 Regs.push_back(RegNo);
4288 SMLoc E = Parser.getTok().getLoc();
4289 if (Parser.getTok().isNot(AsmToken::Comma)) {
4290 Error(E, "',' expected");
4291 return MatchOperand_ParseFail;
4297 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4298 return MatchOperand_ParseFail;
4300 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4301 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4302 Regs.push_back(RegNo);
4304 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4306 return MatchOperand_Success;
4309 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
4311 MCSymbolRefExpr::VariantKind VK =
4312 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
4313 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
4314 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
4315 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
4316 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
4317 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
4318 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
4319 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
4320 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
4321 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
4322 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
4323 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
4324 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
4325 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
4326 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
4327 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
4328 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
4329 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
4330 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
4331 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
4332 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
4333 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
4334 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
4335 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
4336 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
4337 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
4338 .Default(MCSymbolRefExpr::VK_None);
4340 assert(VK != MCSymbolRefExpr::VK_None);
4345 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
4347 /// ::= '(', register, ')'
4348 /// handle it before we iterate so we don't get tripped up by the lack of
4350 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
4351 MCAsmParser &Parser = getParser();
4352 if (getLexer().is(AsmToken::LParen)) {
4354 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
4356 if (parseOperand(Operands, Name)) {
4357 SMLoc Loc = getLexer().getLoc();
4358 Parser.eatToEndOfStatement();
4359 return Error(Loc, "unexpected token in argument list");
4361 if (Parser.getTok().isNot(AsmToken::RParen)) {
4362 SMLoc Loc = getLexer().getLoc();
4363 Parser.eatToEndOfStatement();
4364 return Error(Loc, "unexpected token, expected ')'");
4367 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
4373 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
4374 /// either one of these.
4375 /// ::= '[', register, ']'
4376 /// ::= '[', integer, ']'
4377 /// handle it before we iterate so we don't get tripped up by the lack of
4379 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
4380 OperandVector &Operands) {
4381 MCAsmParser &Parser = getParser();
4382 if (getLexer().is(AsmToken::LBrac)) {
4384 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
4386 if (parseOperand(Operands, Name)) {
4387 SMLoc Loc = getLexer().getLoc();
4388 Parser.eatToEndOfStatement();
4389 return Error(Loc, "unexpected token in argument list");
4391 if (Parser.getTok().isNot(AsmToken::RBrac)) {
4392 SMLoc Loc = getLexer().getLoc();
4393 Parser.eatToEndOfStatement();
4394 return Error(Loc, "unexpected token, expected ']'");
4397 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
4403 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
4404 SMLoc NameLoc, OperandVector &Operands) {
4405 MCAsmParser &Parser = getParser();
4406 DEBUG(dbgs() << "ParseInstruction\n");
4408 // We have reached first instruction, module directive are now forbidden.
4409 getTargetStreamer().forbidModuleDirective();
4411 // Check if we have valid mnemonic
4412 if (!mnemonicIsValid(Name, 0)) {
4413 Parser.eatToEndOfStatement();
4414 return Error(NameLoc, "unknown instruction");
4416 // First operand in MCInst is instruction mnemonic.
4417 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
4419 // Read the remaining operands.
4420 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4421 // Read the first operand.
4422 if (parseOperand(Operands, Name)) {
4423 SMLoc Loc = getLexer().getLoc();
4424 Parser.eatToEndOfStatement();
4425 return Error(Loc, "unexpected token in argument list");
4427 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
4429 // AFAIK, parenthesis suffixes are never on the first operand
4431 while (getLexer().is(AsmToken::Comma)) {
4432 Parser.Lex(); // Eat the comma.
4433 // Parse and remember the operand.
4434 if (parseOperand(Operands, Name)) {
4435 SMLoc Loc = getLexer().getLoc();
4436 Parser.eatToEndOfStatement();
4437 return Error(Loc, "unexpected token in argument list");
4439 // Parse bracket and parenthesis suffixes before we iterate
4440 if (getLexer().is(AsmToken::LBrac)) {
4441 if (parseBracketSuffix(Name, Operands))
4443 } else if (getLexer().is(AsmToken::LParen) &&
4444 parseParenSuffix(Name, Operands))
4448 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4449 SMLoc Loc = getLexer().getLoc();
4450 Parser.eatToEndOfStatement();
4451 return Error(Loc, "unexpected token in argument list");
4453 Parser.Lex(); // Consume the EndOfStatement.
4457 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
4458 MCAsmParser &Parser = getParser();
4459 SMLoc Loc = getLexer().getLoc();
4460 Parser.eatToEndOfStatement();
4461 return Error(Loc, ErrorMsg);
4464 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
4465 return Error(Loc, ErrorMsg);
4468 bool MipsAsmParser::parseSetNoAtDirective() {
4469 MCAsmParser &Parser = getParser();
4470 // Line should look like: ".set noat".
4472 // Set the $at register to $0.
4473 AssemblerOptions.back()->setATRegIndex(0);
4475 Parser.Lex(); // Eat "noat".
4477 // If this is not the end of the statement, report an error.
4478 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4479 reportParseError("unexpected token, expected end of statement");
4483 getTargetStreamer().emitDirectiveSetNoAt();
4484 Parser.Lex(); // Consume the EndOfStatement.
4488 bool MipsAsmParser::parseSetAtDirective() {
4489 // Line can be: ".set at", which sets $at to $1
4490 // or ".set at=$reg", which sets $at to $reg.
4491 MCAsmParser &Parser = getParser();
4492 Parser.Lex(); // Eat "at".
4494 if (getLexer().is(AsmToken::EndOfStatement)) {
4495 // No register was specified, so we set $at to $1.
4496 AssemblerOptions.back()->setATRegIndex(1);
4498 getTargetStreamer().emitDirectiveSetAt();
4499 Parser.Lex(); // Consume the EndOfStatement.
4503 if (getLexer().isNot(AsmToken::Equal)) {
4504 reportParseError("unexpected token, expected equals sign");
4507 Parser.Lex(); // Eat "=".
4509 if (getLexer().isNot(AsmToken::Dollar)) {
4510 if (getLexer().is(AsmToken::EndOfStatement)) {
4511 reportParseError("no register specified");
4514 reportParseError("unexpected token, expected dollar sign '$'");
4518 Parser.Lex(); // Eat "$".
4520 // Find out what "reg" is.
4522 const AsmToken &Reg = Parser.getTok();
4523 if (Reg.is(AsmToken::Identifier)) {
4524 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
4525 } else if (Reg.is(AsmToken::Integer)) {
4526 AtRegNo = Reg.getIntVal();
4528 reportParseError("unexpected token, expected identifier or integer");
4532 // Check if $reg is a valid register. If it is, set $at to $reg.
4533 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
4534 reportParseError("invalid register");
4537 Parser.Lex(); // Eat "reg".
4539 // If this is not the end of the statement, report an error.
4540 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4541 reportParseError("unexpected token, expected end of statement");
4545 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
4547 Parser.Lex(); // Consume the EndOfStatement.
4551 bool MipsAsmParser::parseSetReorderDirective() {
4552 MCAsmParser &Parser = getParser();
4554 // If this is not the end of the statement, report an error.
4555 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4556 reportParseError("unexpected token, expected end of statement");
4559 AssemblerOptions.back()->setReorder();
4560 getTargetStreamer().emitDirectiveSetReorder();
4561 Parser.Lex(); // Consume the EndOfStatement.
4565 bool MipsAsmParser::parseSetNoReorderDirective() {
4566 MCAsmParser &Parser = getParser();
4568 // If this is not the end of the statement, report an error.
4569 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4570 reportParseError("unexpected token, expected end of statement");
4573 AssemblerOptions.back()->setNoReorder();
4574 getTargetStreamer().emitDirectiveSetNoReorder();
4575 Parser.Lex(); // Consume the EndOfStatement.
4579 bool MipsAsmParser::parseSetMacroDirective() {
4580 MCAsmParser &Parser = getParser();
4582 // If this is not the end of the statement, report an error.
4583 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4584 reportParseError("unexpected token, expected end of statement");
4587 AssemblerOptions.back()->setMacro();
4588 getTargetStreamer().emitDirectiveSetMacro();
4589 Parser.Lex(); // Consume the EndOfStatement.
4593 bool MipsAsmParser::parseSetNoMacroDirective() {
4594 MCAsmParser &Parser = getParser();
4596 // If this is not the end of the statement, report an error.
4597 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4598 reportParseError("unexpected token, expected end of statement");
4601 if (AssemblerOptions.back()->isReorder()) {
4602 reportParseError("`noreorder' must be set before `nomacro'");
4605 AssemblerOptions.back()->setNoMacro();
4606 getTargetStreamer().emitDirectiveSetNoMacro();
4607 Parser.Lex(); // Consume the EndOfStatement.
4611 bool MipsAsmParser::parseSetMsaDirective() {
4612 MCAsmParser &Parser = getParser();
4615 // If this is not the end of the statement, report an error.
4616 if (getLexer().isNot(AsmToken::EndOfStatement))
4617 return reportParseError("unexpected token, expected end of statement");
4619 setFeatureBits(Mips::FeatureMSA, "msa");
4620 getTargetStreamer().emitDirectiveSetMsa();
4624 bool MipsAsmParser::parseSetNoMsaDirective() {
4625 MCAsmParser &Parser = getParser();
4628 // If this is not the end of the statement, report an error.
4629 if (getLexer().isNot(AsmToken::EndOfStatement))
4630 return reportParseError("unexpected token, expected end of statement");
4632 clearFeatureBits(Mips::FeatureMSA, "msa");
4633 getTargetStreamer().emitDirectiveSetNoMsa();
4637 bool MipsAsmParser::parseSetNoDspDirective() {
4638 MCAsmParser &Parser = getParser();
4639 Parser.Lex(); // Eat "nodsp".
4641 // If this is not the end of the statement, report an error.
4642 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4643 reportParseError("unexpected token, expected end of statement");
4647 clearFeatureBits(Mips::FeatureDSP, "dsp");
4648 getTargetStreamer().emitDirectiveSetNoDsp();
4652 bool MipsAsmParser::parseSetMips16Directive() {
4653 MCAsmParser &Parser = getParser();
4654 Parser.Lex(); // Eat "mips16".
4656 // If this is not the end of the statement, report an error.
4657 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4658 reportParseError("unexpected token, expected end of statement");
4662 setFeatureBits(Mips::FeatureMips16, "mips16");
4663 getTargetStreamer().emitDirectiveSetMips16();
4664 Parser.Lex(); // Consume the EndOfStatement.
4668 bool MipsAsmParser::parseSetNoMips16Directive() {
4669 MCAsmParser &Parser = getParser();
4670 Parser.Lex(); // Eat "nomips16".
4672 // If this is not the end of the statement, report an error.
4673 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4674 reportParseError("unexpected token, expected end of statement");
4678 clearFeatureBits(Mips::FeatureMips16, "mips16");
4679 getTargetStreamer().emitDirectiveSetNoMips16();
4680 Parser.Lex(); // Consume the EndOfStatement.
4684 bool MipsAsmParser::parseSetFpDirective() {
4685 MCAsmParser &Parser = getParser();
4686 MipsABIFlagsSection::FpABIKind FpAbiVal;
4687 // Line can be: .set fp=32
4690 Parser.Lex(); // Eat fp token
4691 AsmToken Tok = Parser.getTok();
4692 if (Tok.isNot(AsmToken::Equal)) {
4693 reportParseError("unexpected token, expected equals sign '='");
4696 Parser.Lex(); // Eat '=' token.
4697 Tok = Parser.getTok();
4699 if (!parseFpABIValue(FpAbiVal, ".set"))
4702 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4703 reportParseError("unexpected token, expected end of statement");
4706 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
4707 Parser.Lex(); // Consume the EndOfStatement.
4711 bool MipsAsmParser::parseSetOddSPRegDirective() {
4712 MCAsmParser &Parser = getParser();
4714 Parser.Lex(); // Eat "oddspreg".
4715 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4716 reportParseError("unexpected token, expected end of statement");
4720 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4721 getTargetStreamer().emitDirectiveSetOddSPReg();
4725 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
4726 MCAsmParser &Parser = getParser();
4728 Parser.Lex(); // Eat "nooddspreg".
4729 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4730 reportParseError("unexpected token, expected end of statement");
4734 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4735 getTargetStreamer().emitDirectiveSetNoOddSPReg();
4739 bool MipsAsmParser::parseSetPopDirective() {
4740 MCAsmParser &Parser = getParser();
4741 SMLoc Loc = getLexer().getLoc();
4744 if (getLexer().isNot(AsmToken::EndOfStatement))
4745 return reportParseError("unexpected token, expected end of statement");
4747 // Always keep an element on the options "stack" to prevent the user
4748 // from changing the initial options. This is how we remember them.
4749 if (AssemblerOptions.size() == 2)
4750 return reportParseError(Loc, ".set pop with no .set push");
4752 MCSubtargetInfo &STI = copySTI();
4753 AssemblerOptions.pop_back();
4754 setAvailableFeatures(
4755 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
4756 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
4758 getTargetStreamer().emitDirectiveSetPop();
4762 bool MipsAsmParser::parseSetPushDirective() {
4763 MCAsmParser &Parser = getParser();
4765 if (getLexer().isNot(AsmToken::EndOfStatement))
4766 return reportParseError("unexpected token, expected end of statement");
4768 // Create a copy of the current assembler options environment and push it.
4769 AssemblerOptions.push_back(
4770 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
4772 getTargetStreamer().emitDirectiveSetPush();
4776 bool MipsAsmParser::parseSetSoftFloatDirective() {
4777 MCAsmParser &Parser = getParser();
4779 if (getLexer().isNot(AsmToken::EndOfStatement))
4780 return reportParseError("unexpected token, expected end of statement");
4782 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4783 getTargetStreamer().emitDirectiveSetSoftFloat();
4787 bool MipsAsmParser::parseSetHardFloatDirective() {
4788 MCAsmParser &Parser = getParser();
4790 if (getLexer().isNot(AsmToken::EndOfStatement))
4791 return reportParseError("unexpected token, expected end of statement");
4793 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4794 getTargetStreamer().emitDirectiveSetHardFloat();
4798 bool MipsAsmParser::parseSetAssignment() {
4800 const MCExpr *Value;
4801 MCAsmParser &Parser = getParser();
4803 if (Parser.parseIdentifier(Name))
4804 reportParseError("expected identifier after .set");
4806 if (getLexer().isNot(AsmToken::Comma))
4807 return reportParseError("unexpected token, expected comma");
4810 if (Parser.parseExpression(Value))
4811 return reportParseError("expected valid expression after comma");
4813 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4814 Sym->setVariableValue(Value);
4819 bool MipsAsmParser::parseSetMips0Directive() {
4820 MCAsmParser &Parser = getParser();
4822 if (getLexer().isNot(AsmToken::EndOfStatement))
4823 return reportParseError("unexpected token, expected end of statement");
4825 // Reset assembler options to their initial values.
4826 MCSubtargetInfo &STI = copySTI();
4827 setAvailableFeatures(
4828 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
4829 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
4830 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
4832 getTargetStreamer().emitDirectiveSetMips0();
4836 bool MipsAsmParser::parseSetArchDirective() {
4837 MCAsmParser &Parser = getParser();
4839 if (getLexer().isNot(AsmToken::Equal))
4840 return reportParseError("unexpected token, expected equals sign");
4844 if (Parser.parseIdentifier(Arch))
4845 return reportParseError("expected arch identifier");
4847 StringRef ArchFeatureName =
4848 StringSwitch<StringRef>(Arch)
4849 .Case("mips1", "mips1")
4850 .Case("mips2", "mips2")
4851 .Case("mips3", "mips3")
4852 .Case("mips4", "mips4")
4853 .Case("mips5", "mips5")
4854 .Case("mips32", "mips32")
4855 .Case("mips32r2", "mips32r2")
4856 .Case("mips32r3", "mips32r3")
4857 .Case("mips32r5", "mips32r5")
4858 .Case("mips32r6", "mips32r6")
4859 .Case("mips64", "mips64")
4860 .Case("mips64r2", "mips64r2")
4861 .Case("mips64r3", "mips64r3")
4862 .Case("mips64r5", "mips64r5")
4863 .Case("mips64r6", "mips64r6")
4864 .Case("cnmips", "cnmips")
4865 .Case("r4000", "mips3") // This is an implementation of Mips3.
4868 if (ArchFeatureName.empty())
4869 return reportParseError("unsupported architecture");
4871 selectArch(ArchFeatureName);
4872 getTargetStreamer().emitDirectiveSetArch(Arch);
4876 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
4877 MCAsmParser &Parser = getParser();
4879 if (getLexer().isNot(AsmToken::EndOfStatement))
4880 return reportParseError("unexpected token, expected end of statement");
4884 llvm_unreachable("Unimplemented feature");
4885 case Mips::FeatureDSP:
4886 setFeatureBits(Mips::FeatureDSP, "dsp");
4887 getTargetStreamer().emitDirectiveSetDsp();
4889 case Mips::FeatureMicroMips:
4890 getTargetStreamer().emitDirectiveSetMicroMips();
4892 case Mips::FeatureMips1:
4893 selectArch("mips1");
4894 getTargetStreamer().emitDirectiveSetMips1();
4896 case Mips::FeatureMips2:
4897 selectArch("mips2");
4898 getTargetStreamer().emitDirectiveSetMips2();
4900 case Mips::FeatureMips3:
4901 selectArch("mips3");
4902 getTargetStreamer().emitDirectiveSetMips3();
4904 case Mips::FeatureMips4:
4905 selectArch("mips4");
4906 getTargetStreamer().emitDirectiveSetMips4();
4908 case Mips::FeatureMips5:
4909 selectArch("mips5");
4910 getTargetStreamer().emitDirectiveSetMips5();
4912 case Mips::FeatureMips32:
4913 selectArch("mips32");
4914 getTargetStreamer().emitDirectiveSetMips32();
4916 case Mips::FeatureMips32r2:
4917 selectArch("mips32r2");
4918 getTargetStreamer().emitDirectiveSetMips32R2();
4920 case Mips::FeatureMips32r3:
4921 selectArch("mips32r3");
4922 getTargetStreamer().emitDirectiveSetMips32R3();
4924 case Mips::FeatureMips32r5:
4925 selectArch("mips32r5");
4926 getTargetStreamer().emitDirectiveSetMips32R5();
4928 case Mips::FeatureMips32r6:
4929 selectArch("mips32r6");
4930 getTargetStreamer().emitDirectiveSetMips32R6();
4932 case Mips::FeatureMips64:
4933 selectArch("mips64");
4934 getTargetStreamer().emitDirectiveSetMips64();
4936 case Mips::FeatureMips64r2:
4937 selectArch("mips64r2");
4938 getTargetStreamer().emitDirectiveSetMips64R2();
4940 case Mips::FeatureMips64r3:
4941 selectArch("mips64r3");
4942 getTargetStreamer().emitDirectiveSetMips64R3();
4944 case Mips::FeatureMips64r5:
4945 selectArch("mips64r5");
4946 getTargetStreamer().emitDirectiveSetMips64R5();
4948 case Mips::FeatureMips64r6:
4949 selectArch("mips64r6");
4950 getTargetStreamer().emitDirectiveSetMips64R6();
4956 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
4957 MCAsmParser &Parser = getParser();
4958 if (getLexer().isNot(AsmToken::Comma)) {
4959 SMLoc Loc = getLexer().getLoc();
4960 Parser.eatToEndOfStatement();
4961 return Error(Loc, ErrorStr);
4964 Parser.Lex(); // Eat the comma.
4968 // Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
4969 // In this class, it is only used for .cprestore.
4970 // FIXME: Only keep track of IsPicEnabled in one place, instead of in both
4971 // MipsTargetELFStreamer and MipsAsmParser.
4972 bool MipsAsmParser::isPicAndNotNxxAbi() {
4973 return inPicMode() && !(isABI_N32() || isABI_N64());
4976 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
4977 if (AssemblerOptions.back()->isReorder())
4978 Warning(Loc, ".cpload should be inside a noreorder section");
4980 if (inMips16Mode()) {
4981 reportParseError(".cpload is not supported in Mips16 mode");
4985 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
4986 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
4987 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4988 reportParseError("expected register containing function address");
4992 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
4993 if (!RegOpnd.isGPRAsmReg()) {
4994 reportParseError(RegOpnd.getStartLoc(), "invalid register");
4998 // If this is not the end of the statement, report an error.
4999 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5000 reportParseError("unexpected token, expected end of statement");
5004 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
5008 bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
5009 MCAsmParser &Parser = getParser();
5011 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
5012 // is used in non-PIC mode.
5014 if (inMips16Mode()) {
5015 reportParseError(".cprestore is not supported in Mips16 mode");
5019 // Get the stack offset value.
5020 const MCExpr *StackOffset;
5021 int64_t StackOffsetVal;
5022 if (Parser.parseExpression(StackOffset)) {
5023 reportParseError("expected stack offset value");
5027 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
5028 reportParseError("stack offset is not an absolute expression");
5032 if (StackOffsetVal < 0) {
5033 Warning(Loc, ".cprestore with negative stack offset has no effect");
5034 IsCpRestoreSet = false;
5036 IsCpRestoreSet = true;
5037 CpRestoreOffset = StackOffsetVal;
5040 // If this is not the end of the statement, report an error.
5041 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5042 reportParseError("unexpected token, expected end of statement");
5046 // Store the $gp on the stack.
5047 SmallVector<MCInst, 3> StoreInsts;
5048 createCpRestoreMemOp(false /*IsLoad*/, CpRestoreOffset /*StackOffset*/, Loc,
5051 getTargetStreamer().emitDirectiveCpRestore(StoreInsts, CpRestoreOffset);
5052 Parser.Lex(); // Consume the EndOfStatement.
5056 bool MipsAsmParser::parseDirectiveCPSetup() {
5057 MCAsmParser &Parser = getParser();
5060 bool SaveIsReg = true;
5062 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5063 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5064 if (ResTy == MatchOperand_NoMatch) {
5065 reportParseError("expected register containing function address");
5066 Parser.eatToEndOfStatement();
5070 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5071 if (!FuncRegOpnd.isGPRAsmReg()) {
5072 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
5073 Parser.eatToEndOfStatement();
5077 FuncReg = FuncRegOpnd.getGPR32Reg();
5080 if (!eatComma("unexpected token, expected comma"))
5083 ResTy = parseAnyRegister(TmpReg);
5084 if (ResTy == MatchOperand_NoMatch) {
5085 const MCExpr *OffsetExpr;
5087 SMLoc ExprLoc = getLexer().getLoc();
5089 if (Parser.parseExpression(OffsetExpr) ||
5090 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
5091 reportParseError(ExprLoc, "expected save register or stack offset");
5092 Parser.eatToEndOfStatement();
5099 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5100 if (!SaveOpnd.isGPRAsmReg()) {
5101 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
5102 Parser.eatToEndOfStatement();
5105 Save = SaveOpnd.getGPR32Reg();
5108 if (!eatComma("unexpected token, expected comma"))
5112 if (Parser.parseExpression(Expr)) {
5113 reportParseError("expected expression");
5117 if (Expr->getKind() != MCExpr::SymbolRef) {
5118 reportParseError("expected symbol");
5121 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
5123 CpSaveLocation = Save;
5124 CpSaveLocationIsRegister = SaveIsReg;
5126 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
5131 bool MipsAsmParser::parseDirectiveCPReturn() {
5132 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
5133 CpSaveLocationIsRegister);
5137 bool MipsAsmParser::parseDirectiveNaN() {
5138 MCAsmParser &Parser = getParser();
5139 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5140 const AsmToken &Tok = Parser.getTok();
5142 if (Tok.getString() == "2008") {
5144 getTargetStreamer().emitDirectiveNaN2008();
5146 } else if (Tok.getString() == "legacy") {
5148 getTargetStreamer().emitDirectiveNaNLegacy();
5152 // If we don't recognize the option passed to the .nan
5153 // directive (e.g. no option or unknown option), emit an error.
5154 reportParseError("invalid option in .nan directive");
5158 bool MipsAsmParser::parseDirectiveSet() {
5159 MCAsmParser &Parser = getParser();
5160 // Get the next token.
5161 const AsmToken &Tok = Parser.getTok();
5163 if (Tok.getString() == "noat") {
5164 return parseSetNoAtDirective();
5165 } else if (Tok.getString() == "at") {
5166 return parseSetAtDirective();
5167 } else if (Tok.getString() == "arch") {
5168 return parseSetArchDirective();
5169 } else if (Tok.getString() == "fp") {
5170 return parseSetFpDirective();
5171 } else if (Tok.getString() == "oddspreg") {
5172 return parseSetOddSPRegDirective();
5173 } else if (Tok.getString() == "nooddspreg") {
5174 return parseSetNoOddSPRegDirective();
5175 } else if (Tok.getString() == "pop") {
5176 return parseSetPopDirective();
5177 } else if (Tok.getString() == "push") {
5178 return parseSetPushDirective();
5179 } else if (Tok.getString() == "reorder") {
5180 return parseSetReorderDirective();
5181 } else if (Tok.getString() == "noreorder") {
5182 return parseSetNoReorderDirective();
5183 } else if (Tok.getString() == "macro") {
5184 return parseSetMacroDirective();
5185 } else if (Tok.getString() == "nomacro") {
5186 return parseSetNoMacroDirective();
5187 } else if (Tok.getString() == "mips16") {
5188 return parseSetMips16Directive();
5189 } else if (Tok.getString() == "nomips16") {
5190 return parseSetNoMips16Directive();
5191 } else if (Tok.getString() == "nomicromips") {
5192 getTargetStreamer().emitDirectiveSetNoMicroMips();
5193 Parser.eatToEndOfStatement();
5195 } else if (Tok.getString() == "micromips") {
5196 return parseSetFeature(Mips::FeatureMicroMips);
5197 } else if (Tok.getString() == "mips0") {
5198 return parseSetMips0Directive();
5199 } else if (Tok.getString() == "mips1") {
5200 return parseSetFeature(Mips::FeatureMips1);
5201 } else if (Tok.getString() == "mips2") {
5202 return parseSetFeature(Mips::FeatureMips2);
5203 } else if (Tok.getString() == "mips3") {
5204 return parseSetFeature(Mips::FeatureMips3);
5205 } else if (Tok.getString() == "mips4") {
5206 return parseSetFeature(Mips::FeatureMips4);
5207 } else if (Tok.getString() == "mips5") {
5208 return parseSetFeature(Mips::FeatureMips5);
5209 } else if (Tok.getString() == "mips32") {
5210 return parseSetFeature(Mips::FeatureMips32);
5211 } else if (Tok.getString() == "mips32r2") {
5212 return parseSetFeature(Mips::FeatureMips32r2);
5213 } else if (Tok.getString() == "mips32r3") {
5214 return parseSetFeature(Mips::FeatureMips32r3);
5215 } else if (Tok.getString() == "mips32r5") {
5216 return parseSetFeature(Mips::FeatureMips32r5);
5217 } else if (Tok.getString() == "mips32r6") {
5218 return parseSetFeature(Mips::FeatureMips32r6);
5219 } else if (Tok.getString() == "mips64") {
5220 return parseSetFeature(Mips::FeatureMips64);
5221 } else if (Tok.getString() == "mips64r2") {
5222 return parseSetFeature(Mips::FeatureMips64r2);
5223 } else if (Tok.getString() == "mips64r3") {
5224 return parseSetFeature(Mips::FeatureMips64r3);
5225 } else if (Tok.getString() == "mips64r5") {
5226 return parseSetFeature(Mips::FeatureMips64r5);
5227 } else if (Tok.getString() == "mips64r6") {
5228 return parseSetFeature(Mips::FeatureMips64r6);
5229 } else if (Tok.getString() == "dsp") {
5230 return parseSetFeature(Mips::FeatureDSP);
5231 } else if (Tok.getString() == "nodsp") {
5232 return parseSetNoDspDirective();
5233 } else if (Tok.getString() == "msa") {
5234 return parseSetMsaDirective();
5235 } else if (Tok.getString() == "nomsa") {
5236 return parseSetNoMsaDirective();
5237 } else if (Tok.getString() == "softfloat") {
5238 return parseSetSoftFloatDirective();
5239 } else if (Tok.getString() == "hardfloat") {
5240 return parseSetHardFloatDirective();
5242 // It is just an identifier, look for an assignment.
5243 parseSetAssignment();
5250 /// parseDataDirective
5251 /// ::= .word [ expression (, expression)* ]
5252 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
5253 MCAsmParser &Parser = getParser();
5254 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5256 const MCExpr *Value;
5257 if (getParser().parseExpression(Value))
5260 getParser().getStreamer().EmitValue(Value, Size);
5262 if (getLexer().is(AsmToken::EndOfStatement))
5265 if (getLexer().isNot(AsmToken::Comma))
5266 return Error(L, "unexpected token, expected comma");
5275 /// parseDirectiveGpWord
5276 /// ::= .gpword local_sym
5277 bool MipsAsmParser::parseDirectiveGpWord() {
5278 MCAsmParser &Parser = getParser();
5279 const MCExpr *Value;
5280 // EmitGPRel32Value requires an expression, so we are using base class
5281 // method to evaluate the expression.
5282 if (getParser().parseExpression(Value))
5284 getParser().getStreamer().EmitGPRel32Value(Value);
5286 if (getLexer().isNot(AsmToken::EndOfStatement))
5287 return Error(getLexer().getLoc(),
5288 "unexpected token, expected end of statement");
5289 Parser.Lex(); // Eat EndOfStatement token.
5293 /// parseDirectiveGpDWord
5294 /// ::= .gpdword local_sym
5295 bool MipsAsmParser::parseDirectiveGpDWord() {
5296 MCAsmParser &Parser = getParser();
5297 const MCExpr *Value;
5298 // EmitGPRel64Value requires an expression, so we are using base class
5299 // method to evaluate the expression.
5300 if (getParser().parseExpression(Value))
5302 getParser().getStreamer().EmitGPRel64Value(Value);
5304 if (getLexer().isNot(AsmToken::EndOfStatement))
5305 return Error(getLexer().getLoc(),
5306 "unexpected token, expected end of statement");
5307 Parser.Lex(); // Eat EndOfStatement token.
5311 bool MipsAsmParser::parseDirectiveOption() {
5312 MCAsmParser &Parser = getParser();
5313 // Get the option token.
5314 AsmToken Tok = Parser.getTok();
5315 // At the moment only identifiers are supported.
5316 if (Tok.isNot(AsmToken::Identifier)) {
5317 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
5318 Parser.eatToEndOfStatement();
5322 StringRef Option = Tok.getIdentifier();
5324 if (Option == "pic0") {
5325 // MipsAsmParser needs to know if the current PIC mode changes.
5326 IsPicEnabled = false;
5328 getTargetStreamer().emitDirectiveOptionPic0();
5330 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5331 Error(Parser.getTok().getLoc(),
5332 "unexpected token, expected end of statement");
5333 Parser.eatToEndOfStatement();
5338 if (Option == "pic2") {
5339 // MipsAsmParser needs to know if the current PIC mode changes.
5340 IsPicEnabled = true;
5342 getTargetStreamer().emitDirectiveOptionPic2();
5344 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5345 Error(Parser.getTok().getLoc(),
5346 "unexpected token, expected end of statement");
5347 Parser.eatToEndOfStatement();
5353 Warning(Parser.getTok().getLoc(),
5354 "unknown option, expected 'pic0' or 'pic2'");
5355 Parser.eatToEndOfStatement();
5359 /// parseInsnDirective
5361 bool MipsAsmParser::parseInsnDirective() {
5362 // If this is not the end of the statement, report an error.
5363 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5364 reportParseError("unexpected token, expected end of statement");
5368 // The actual label marking happens in
5369 // MipsELFStreamer::createPendingLabelRelocs().
5370 getTargetStreamer().emitDirectiveInsn();
5372 getParser().Lex(); // Eat EndOfStatement token.
5376 /// parseDirectiveModule
5377 /// ::= .module oddspreg
5378 /// ::= .module nooddspreg
5379 /// ::= .module fp=value
5380 /// ::= .module softfloat
5381 /// ::= .module hardfloat
5382 bool MipsAsmParser::parseDirectiveModule() {
5383 MCAsmParser &Parser = getParser();
5384 MCAsmLexer &Lexer = getLexer();
5385 SMLoc L = Lexer.getLoc();
5387 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
5388 // TODO : get a better message.
5389 reportParseError(".module directive must appear before any code");
5394 if (Parser.parseIdentifier(Option)) {
5395 reportParseError("expected .module option identifier");
5399 if (Option == "oddspreg") {
5400 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5402 // Synchronize the abiflags information with the FeatureBits information we
5404 getTargetStreamer().updateABIInfo(*this);
5406 // If printing assembly, use the recently updated abiflags information.
5407 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5408 // emitted at the end).
5409 getTargetStreamer().emitDirectiveModuleOddSPReg();
5411 // If this is not the end of the statement, report an error.
5412 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5413 reportParseError("unexpected token, expected end of statement");
5417 return false; // parseDirectiveModule has finished successfully.
5418 } else if (Option == "nooddspreg") {
5420 Error(L, "'.module nooddspreg' requires the O32 ABI");
5424 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5426 // Synchronize the abiflags information with the FeatureBits information we
5428 getTargetStreamer().updateABIInfo(*this);
5430 // If printing assembly, use the recently updated abiflags information.
5431 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5432 // emitted at the end).
5433 getTargetStreamer().emitDirectiveModuleOddSPReg();
5435 // If this is not the end of the statement, report an error.
5436 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5437 reportParseError("unexpected token, expected end of statement");
5441 return false; // parseDirectiveModule has finished successfully.
5442 } else if (Option == "fp") {
5443 return parseDirectiveModuleFP();
5444 } else if (Option == "softfloat") {
5445 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5447 // Synchronize the ABI Flags information with the FeatureBits information we
5449 getTargetStreamer().updateABIInfo(*this);
5451 // If printing assembly, use the recently updated ABI Flags information.
5452 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5454 getTargetStreamer().emitDirectiveModuleSoftFloat();
5456 // If this is not the end of the statement, report an error.
5457 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5458 reportParseError("unexpected token, expected end of statement");
5462 return false; // parseDirectiveModule has finished successfully.
5463 } else if (Option == "hardfloat") {
5464 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5466 // Synchronize the ABI Flags information with the FeatureBits information we
5468 getTargetStreamer().updateABIInfo(*this);
5470 // If printing assembly, use the recently updated ABI Flags information.
5471 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5473 getTargetStreamer().emitDirectiveModuleHardFloat();
5475 // If this is not the end of the statement, report an error.
5476 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5477 reportParseError("unexpected token, expected end of statement");
5481 return false; // parseDirectiveModule has finished successfully.
5483 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
5487 /// parseDirectiveModuleFP
5491 bool MipsAsmParser::parseDirectiveModuleFP() {
5492 MCAsmParser &Parser = getParser();
5493 MCAsmLexer &Lexer = getLexer();
5495 if (Lexer.isNot(AsmToken::Equal)) {
5496 reportParseError("unexpected token, expected equals sign '='");
5499 Parser.Lex(); // Eat '=' token.
5501 MipsABIFlagsSection::FpABIKind FpABI;
5502 if (!parseFpABIValue(FpABI, ".module"))
5505 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5506 reportParseError("unexpected token, expected end of statement");
5510 // Synchronize the abiflags information with the FeatureBits information we
5512 getTargetStreamer().updateABIInfo(*this);
5514 // If printing assembly, use the recently updated abiflags information.
5515 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5516 // emitted at the end).
5517 getTargetStreamer().emitDirectiveModuleFP();
5519 Parser.Lex(); // Consume the EndOfStatement.
5523 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
5524 StringRef Directive) {
5525 MCAsmParser &Parser = getParser();
5526 MCAsmLexer &Lexer = getLexer();
5527 bool ModuleLevelOptions = Directive == ".module";
5529 if (Lexer.is(AsmToken::Identifier)) {
5530 StringRef Value = Parser.getTok().getString();
5533 if (Value != "xx") {
5534 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5539 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
5543 FpABI = MipsABIFlagsSection::FpABIKind::XX;
5544 if (ModuleLevelOptions) {
5545 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5546 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5548 setFeatureBits(Mips::FeatureFPXX, "fpxx");
5549 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5554 if (Lexer.is(AsmToken::Integer)) {
5555 unsigned Value = Parser.getTok().getIntVal();
5558 if (Value != 32 && Value != 64) {
5559 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5565 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
5569 FpABI = MipsABIFlagsSection::FpABIKind::S32;
5570 if (ModuleLevelOptions) {
5571 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5572 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5574 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5575 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5578 FpABI = MipsABIFlagsSection::FpABIKind::S64;
5579 if (ModuleLevelOptions) {
5580 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5581 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5583 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5584 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
5594 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
5595 MCAsmParser &Parser = getParser();
5596 StringRef IDVal = DirectiveID.getString();
5598 if (IDVal == ".cpload")
5599 return parseDirectiveCpLoad(DirectiveID.getLoc());
5600 if (IDVal == ".cprestore")
5601 return parseDirectiveCpRestore(DirectiveID.getLoc());
5602 if (IDVal == ".dword") {
5603 parseDataDirective(8, DirectiveID.getLoc());
5606 if (IDVal == ".ent") {
5607 StringRef SymbolName;
5609 if (Parser.parseIdentifier(SymbolName)) {
5610 reportParseError("expected identifier after .ent");
5614 // There's an undocumented extension that allows an integer to
5615 // follow the name of the procedure which AFAICS is ignored by GAS.
5616 // Example: .ent foo,2
5617 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5618 if (getLexer().isNot(AsmToken::Comma)) {
5619 // Even though we accept this undocumented extension for compatibility
5620 // reasons, the additional integer argument does not actually change
5621 // the behaviour of the '.ent' directive, so we would like to discourage
5622 // its use. We do this by not referring to the extended version in
5623 // error messages which are not directly related to its use.
5624 reportParseError("unexpected token, expected end of statement");
5627 Parser.Lex(); // Eat the comma.
5628 const MCExpr *DummyNumber;
5629 int64_t DummyNumberVal;
5630 // If the user was explicitly trying to use the extended version,
5631 // we still give helpful extension-related error messages.
5632 if (Parser.parseExpression(DummyNumber)) {
5633 reportParseError("expected number after comma");
5636 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
5637 reportParseError("expected an absolute expression after comma");
5642 // If this is not the end of the statement, report an error.
5643 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5644 reportParseError("unexpected token, expected end of statement");
5648 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
5650 getTargetStreamer().emitDirectiveEnt(*Sym);
5652 IsCpRestoreSet = false;
5656 if (IDVal == ".end") {
5657 StringRef SymbolName;
5659 if (Parser.parseIdentifier(SymbolName)) {
5660 reportParseError("expected identifier after .end");
5664 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5665 reportParseError("unexpected token, expected end of statement");
5669 if (CurrentFn == nullptr) {
5670 reportParseError(".end used without .ent");
5674 if ((SymbolName != CurrentFn->getName())) {
5675 reportParseError(".end symbol does not match .ent symbol");
5679 getTargetStreamer().emitDirectiveEnd(SymbolName);
5680 CurrentFn = nullptr;
5681 IsCpRestoreSet = false;
5685 if (IDVal == ".frame") {
5686 // .frame $stack_reg, frame_size_in_bytes, $return_reg
5687 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5688 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5689 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5690 reportParseError("expected stack register");
5694 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5695 if (!StackRegOpnd.isGPRAsmReg()) {
5696 reportParseError(StackRegOpnd.getStartLoc(),
5697 "expected general purpose register");
5700 unsigned StackReg = StackRegOpnd.getGPR32Reg();
5702 if (Parser.getTok().is(AsmToken::Comma))
5705 reportParseError("unexpected token, expected comma");
5709 // Parse the frame size.
5710 const MCExpr *FrameSize;
5711 int64_t FrameSizeVal;
5713 if (Parser.parseExpression(FrameSize)) {
5714 reportParseError("expected frame size value");
5718 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
5719 reportParseError("frame size not an absolute expression");
5723 if (Parser.getTok().is(AsmToken::Comma))
5726 reportParseError("unexpected token, expected comma");
5730 // Parse the return register.
5732 ResTy = parseAnyRegister(TmpReg);
5733 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5734 reportParseError("expected return register");
5738 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5739 if (!ReturnRegOpnd.isGPRAsmReg()) {
5740 reportParseError(ReturnRegOpnd.getStartLoc(),
5741 "expected general purpose register");
5745 // If this is not the end of the statement, report an error.
5746 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5747 reportParseError("unexpected token, expected end of statement");
5751 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
5752 ReturnRegOpnd.getGPR32Reg());
5753 IsCpRestoreSet = false;
5757 if (IDVal == ".set") {
5758 return parseDirectiveSet();
5761 if (IDVal == ".mask" || IDVal == ".fmask") {
5762 // .mask bitmask, frame_offset
5763 // bitmask: One bit for each register used.
5764 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
5765 // first register is expected to be saved.
5767 // .mask 0x80000000, -4
5768 // .fmask 0x80000000, -4
5771 // Parse the bitmask
5772 const MCExpr *BitMask;
5775 if (Parser.parseExpression(BitMask)) {
5776 reportParseError("expected bitmask value");
5780 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
5781 reportParseError("bitmask not an absolute expression");
5785 if (Parser.getTok().is(AsmToken::Comma))
5788 reportParseError("unexpected token, expected comma");
5792 // Parse the frame_offset
5793 const MCExpr *FrameOffset;
5794 int64_t FrameOffsetVal;
5796 if (Parser.parseExpression(FrameOffset)) {
5797 reportParseError("expected frame offset value");
5801 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
5802 reportParseError("frame offset not an absolute expression");
5806 // If this is not the end of the statement, report an error.
5807 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5808 reportParseError("unexpected token, expected end of statement");
5812 if (IDVal == ".mask")
5813 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
5815 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
5819 if (IDVal == ".nan")
5820 return parseDirectiveNaN();
5822 if (IDVal == ".gpword") {
5823 parseDirectiveGpWord();
5827 if (IDVal == ".gpdword") {
5828 parseDirectiveGpDWord();
5832 if (IDVal == ".word") {
5833 parseDataDirective(4, DirectiveID.getLoc());
5837 if (IDVal == ".option")
5838 return parseDirectiveOption();
5840 if (IDVal == ".abicalls") {
5841 getTargetStreamer().emitDirectiveAbiCalls();
5842 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5843 Error(Parser.getTok().getLoc(),
5844 "unexpected token, expected end of statement");
5846 Parser.eatToEndOfStatement();
5851 if (IDVal == ".cpsetup")
5852 return parseDirectiveCPSetup();
5854 if (IDVal == ".cpreturn")
5855 return parseDirectiveCPReturn();
5857 if (IDVal == ".module")
5858 return parseDirectiveModule();
5860 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
5861 return parseInternalDirectiveReallowModule();
5863 if (IDVal == ".insn")
5864 return parseInsnDirective();
5869 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
5870 // If this is not the end of the statement, report an error.
5871 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5872 reportParseError("unexpected token, expected end of statement");
5876 getTargetStreamer().reallowModuleDirective();
5878 getParser().Lex(); // Eat EndOfStatement token.
5882 extern "C" void LLVMInitializeMipsAsmParser() {
5883 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
5884 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
5885 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
5886 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
5889 #define GET_REGISTER_MATCHER
5890 #define GET_MATCHER_IMPLEMENTATION
5891 #include "MipsGenAsmMatcher.inc"