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 "MipsTargetStreamer.h"
15 #include "llvm/ADT/APInt.h"
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/ADT/StringSwitch.h"
18 #include "llvm/MC/MCContext.h"
19 #include "llvm/MC/MCExpr.h"
20 #include "llvm/MC/MCInst.h"
21 #include "llvm/MC/MCInstBuilder.h"
22 #include "llvm/MC/MCParser/MCAsmLexer.h"
23 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
24 #include "llvm/MC/MCStreamer.h"
25 #include "llvm/MC/MCSubtargetInfo.h"
26 #include "llvm/MC/MCSymbol.h"
27 #include "llvm/MC/MCTargetAsmParser.h"
28 #include "llvm/Support/Debug.h"
29 #include "llvm/Support/MathExtras.h"
30 #include "llvm/Support/SourceMgr.h"
31 #include "llvm/Support/TargetRegistry.h"
32 #include "llvm/Support/raw_ostream.h"
37 #define DEBUG_TYPE "mips-asm-parser"
44 class MipsAssemblerOptions {
46 MipsAssemblerOptions(uint64_t Features_) :
47 ATReg(1), Reorder(true), Macro(true), Features(Features_) {}
49 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
50 ATReg = Opts->getATRegIndex();
51 Reorder = Opts->isReorder();
52 Macro = Opts->isMacro();
53 Features = Opts->getFeatures();
56 unsigned getATRegIndex() const { return ATReg; }
57 bool setATRegIndex(unsigned Reg) {
65 bool isReorder() const { return Reorder; }
66 void setReorder() { Reorder = true; }
67 void setNoReorder() { Reorder = false; }
69 bool isMacro() const { return Macro; }
70 void setMacro() { Macro = true; }
71 void setNoMacro() { Macro = false; }
73 uint64_t getFeatures() const { return Features; }
74 void setFeatures(uint64_t Features_) { Features = Features_; }
76 // Set of features that are either architecture features or referenced
77 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
78 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
79 // The reason we need this mask is explained in the selectArch function.
80 // FIXME: Ideally we would like TableGen to generate this information.
81 static const FeatureBitset AllArchRelatedMask;
91 const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
92 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
93 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
94 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
95 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
96 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
97 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
98 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
99 Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008
103 class MipsAsmParser : public MCTargetAsmParser {
104 MipsTargetStreamer &getTargetStreamer() {
105 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
106 return static_cast<MipsTargetStreamer &>(TS);
109 MCSubtargetInfo &STI;
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'
117 // Print a warning along with its fix-it message at the given range.
118 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
119 SMRange Range, bool ShowColors = true);
121 #define GET_ASSEMBLER_HEADER
122 #include "MipsGenAsmMatcher.inc"
124 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
126 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
127 OperandVector &Operands, MCStreamer &Out,
129 bool MatchingInlineAsm) override;
131 /// Parse a register as used in CFI directives
132 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
134 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
136 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
138 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
139 SMLoc NameLoc, OperandVector &Operands) override;
141 bool ParseDirective(AsmToken DirectiveID) override;
143 MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
145 MipsAsmParser::OperandMatchResultTy
146 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
147 StringRef Identifier, SMLoc S);
149 MipsAsmParser::OperandMatchResultTy
150 matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
152 MipsAsmParser::OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
154 MipsAsmParser::OperandMatchResultTy parseImm(OperandVector &Operands);
156 MipsAsmParser::OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
158 MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
160 MipsAsmParser::OperandMatchResultTy parseLSAImm(OperandVector &Operands);
162 MipsAsmParser::OperandMatchResultTy
163 parseRegisterPair (OperandVector &Operands);
165 MipsAsmParser::OperandMatchResultTy
166 parseMovePRegPair(OperandVector &Operands);
168 MipsAsmParser::OperandMatchResultTy
169 parseRegisterList (OperandVector &Operands);
171 bool searchSymbolAlias(OperandVector &Operands);
173 bool parseOperand(OperandVector &, StringRef Mnemonic);
175 bool needsExpansion(MCInst &Inst);
177 // Expands assembly pseudo instructions.
178 // Returns false on success, true otherwise.
179 bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
180 SmallVectorImpl<MCInst> &Instructions);
182 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
183 SmallVectorImpl<MCInst> &Instructions);
185 bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
186 bool Is32BitImm, SMLoc IDLoc,
187 SmallVectorImpl<MCInst> &Instructions);
189 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
190 SmallVectorImpl<MCInst> &Instructions);
192 bool expandLoadAddressImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
193 SmallVectorImpl<MCInst> &Instructions);
195 bool expandLoadAddressReg(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
196 SmallVectorImpl<MCInst> &Instructions);
197 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
198 SmallVectorImpl<MCInst> &Instructions);
200 void expandLoadAddressSym(const MCOperand &DstRegOp, const MCOperand &SymOp,
201 bool Is32BitSym, SMLoc IDLoc,
202 SmallVectorImpl<MCInst> &Instructions);
204 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
205 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
208 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
209 SmallVectorImpl<MCInst> &Instructions);
211 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc,
212 SmallVectorImpl<MCInst> &Instructions);
214 void createNop(bool hasShortDelaySlot, SMLoc IDLoc,
215 SmallVectorImpl<MCInst> &Instructions);
217 void createAddu(unsigned DstReg, unsigned SrcReg, unsigned TrgReg,
218 SmallVectorImpl<MCInst> &Instructions);
220 bool reportParseError(Twine ErrorMsg);
221 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
223 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
224 bool parseRelocOperand(const MCExpr *&Res);
226 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
228 bool isEvaluated(const MCExpr *Expr);
229 bool parseSetMips0Directive();
230 bool parseSetArchDirective();
231 bool parseSetFeature(uint64_t Feature);
232 bool parseDirectiveCpLoad(SMLoc Loc);
233 bool parseDirectiveCPSetup();
234 bool parseDirectiveNaN();
235 bool parseDirectiveSet();
236 bool parseDirectiveOption();
237 bool parseInsnDirective();
239 bool parseSetAtDirective();
240 bool parseSetNoAtDirective();
241 bool parseSetMacroDirective();
242 bool parseSetNoMacroDirective();
243 bool parseSetMsaDirective();
244 bool parseSetNoMsaDirective();
245 bool parseSetNoDspDirective();
246 bool parseSetReorderDirective();
247 bool parseSetNoReorderDirective();
248 bool parseSetMips16Directive();
249 bool parseSetNoMips16Directive();
250 bool parseSetFpDirective();
251 bool parseSetPopDirective();
252 bool parseSetPushDirective();
253 bool parseSetSoftFloatDirective();
254 bool parseSetHardFloatDirective();
256 bool parseSetAssignment();
258 bool parseDataDirective(unsigned Size, SMLoc L);
259 bool parseDirectiveGpWord();
260 bool parseDirectiveGpDWord();
261 bool parseDirectiveModule();
262 bool parseDirectiveModuleFP();
263 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
264 StringRef Directive);
266 bool parseInternalDirectiveReallowModule();
268 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
270 bool eatComma(StringRef ErrorStr);
272 int matchCPURegisterName(StringRef Symbol);
274 int matchHWRegsRegisterName(StringRef Symbol);
276 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
278 int matchFPURegisterName(StringRef Name);
280 int matchFCCRegisterName(StringRef Name);
282 int matchACRegisterName(StringRef Name);
284 int matchMSA128RegisterName(StringRef Name);
286 int matchMSA128CtrlRegisterName(StringRef Name);
288 unsigned getReg(int RC, int RegNo);
290 unsigned getGPR(int RegNo);
292 /// Returns the internal register number for the current AT. Also checks if
293 /// the current AT is unavailable (set to $0) and gives an error if it is.
294 /// This should be used in pseudo-instruction expansions which need AT.
295 unsigned getATReg(SMLoc Loc);
297 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
298 SmallVectorImpl<MCInst> &Instructions);
300 // Helper function that checks if the value of a vector index is within the
301 // boundaries of accepted values for each RegisterKind
302 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
303 bool validateMSAIndex(int Val, int RegKind);
305 // Selects a new architecture by updating the FeatureBits with the necessary
306 // info including implied dependencies.
307 // Internally, it clears all the feature bits related to *any* architecture
308 // and selects the new one using the ToggleFeature functionality of the
309 // MCSubtargetInfo object that handles implied dependencies. The reason we
310 // clear all the arch related bits manually is because ToggleFeature only
311 // clears the features that imply the feature being cleared and not the
312 // features implied by the feature being cleared. This is easier to see
314 // --------------------------------------------------
315 // | Feature | Implies |
316 // | -------------------------------------------------|
317 // | FeatureMips1 | None |
318 // | FeatureMips2 | FeatureMips1 |
319 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
320 // | FeatureMips4 | FeatureMips3 |
322 // --------------------------------------------------
324 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
325 // FeatureMipsGP64 | FeatureMips1)
326 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
327 void selectArch(StringRef ArchFeature) {
328 FeatureBitset FeatureBits = STI.getFeatureBits();
329 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
330 STI.setFeatureBits(FeatureBits);
331 setAvailableFeatures(
332 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
333 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
336 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
337 if (!(STI.getFeatureBits()[Feature])) {
338 setAvailableFeatures(
339 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
341 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
344 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
345 if (STI.getFeatureBits()[Feature]) {
346 setAvailableFeatures(
347 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
349 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
353 enum MipsMatchResultTy {
354 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
355 #define GET_OPERAND_DIAGNOSTIC_TYPES
356 #include "MipsGenAsmMatcher.inc"
357 #undef GET_OPERAND_DIAGNOSTIC_TYPES
361 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
362 const MCInstrInfo &MII, const MCTargetOptions &Options)
363 : MCTargetAsmParser(), STI(sti),
364 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
365 sti.getCPU(), Options)) {
366 MCAsmParserExtension::Initialize(parser);
368 parser.addAliasForDirective(".asciiz", ".asciz");
370 // Initialize the set of available features.
371 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
373 // Remember the initial assembler options. The user can not modify these.
374 AssemblerOptions.push_back(
375 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
377 // Create an assembler options environment for the user to modify.
378 AssemblerOptions.push_back(
379 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
381 getTargetStreamer().updateABIInfo(*this);
383 if (!isABI_O32() && !useOddSPReg() != 0)
384 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
389 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
390 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
392 bool isGP64bit() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
393 bool isFP64bit() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }
394 const MipsABIInfo &getABI() const { return ABI; }
395 bool isABI_N32() const { return ABI.IsN32(); }
396 bool isABI_N64() const { return ABI.IsN64(); }
397 bool isABI_O32() const { return ABI.IsO32(); }
398 bool isABI_FPXX() const { return STI.getFeatureBits()[Mips::FeatureFPXX]; }
400 bool useOddSPReg() const {
401 return !(STI.getFeatureBits()[Mips::FeatureNoOddSPReg]);
404 bool inMicroMipsMode() const {
405 return STI.getFeatureBits()[Mips::FeatureMicroMips];
407 bool hasMips1() const { return STI.getFeatureBits()[Mips::FeatureMips1]; }
408 bool hasMips2() const { return STI.getFeatureBits()[Mips::FeatureMips2]; }
409 bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
410 bool hasMips4() const { return STI.getFeatureBits()[Mips::FeatureMips4]; }
411 bool hasMips5() const { return STI.getFeatureBits()[Mips::FeatureMips5]; }
412 bool hasMips32() const {
413 return STI.getFeatureBits()[Mips::FeatureMips32];
415 bool hasMips64() const {
416 return STI.getFeatureBits()[Mips::FeatureMips64];
418 bool hasMips32r2() const {
419 return STI.getFeatureBits()[Mips::FeatureMips32r2];
421 bool hasMips64r2() const {
422 return STI.getFeatureBits()[Mips::FeatureMips64r2];
424 bool hasMips32r3() const {
425 return (STI.getFeatureBits()[Mips::FeatureMips32r3]);
427 bool hasMips64r3() const {
428 return (STI.getFeatureBits()[Mips::FeatureMips64r3]);
430 bool hasMips32r5() const {
431 return (STI.getFeatureBits()[Mips::FeatureMips32r5]);
433 bool hasMips64r5() const {
434 return (STI.getFeatureBits()[Mips::FeatureMips64r5]);
436 bool hasMips32r6() const {
437 return STI.getFeatureBits()[Mips::FeatureMips32r6];
439 bool hasMips64r6() const {
440 return STI.getFeatureBits()[Mips::FeatureMips64r6];
443 bool hasDSP() const { return STI.getFeatureBits()[Mips::FeatureDSP]; }
444 bool hasDSPR2() const { return STI.getFeatureBits()[Mips::FeatureDSPR2]; }
445 bool hasMSA() const { return STI.getFeatureBits()[Mips::FeatureMSA]; }
446 bool hasCnMips() const {
447 return (STI.getFeatureBits()[Mips::FeatureCnMips]);
450 bool inMips16Mode() const {
451 return STI.getFeatureBits()[Mips::FeatureMips16];
454 bool useSoftFloat() const {
455 return STI.getFeatureBits()[Mips::FeatureSoftFloat];
458 /// Warn if RegIndex is the same as the current AT.
459 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
461 void warnIfNoMacro(SMLoc Loc);
467 /// MipsOperand - Instances of this class represent a parsed Mips machine
469 class MipsOperand : public MCParsedAsmOperand {
471 /// Broad categories of register classes
472 /// The exact class is finalized by the render method.
474 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
475 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
477 RegKind_FCC = 4, /// FCC
478 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
479 RegKind_MSACtrl = 16, /// MSA control registers
480 RegKind_COP2 = 32, /// COP2
481 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
483 RegKind_CCR = 128, /// CCR
484 RegKind_HWRegs = 256, /// HWRegs
485 RegKind_COP3 = 512, /// COP3
487 /// Potentially any (e.g. $1)
488 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
489 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
490 RegKind_CCR | RegKind_HWRegs | RegKind_COP3
495 k_Immediate, /// An immediate (possibly involving symbol references)
496 k_Memory, /// Base + Offset Memory Address
497 k_PhysRegister, /// A physical register from the Mips namespace
498 k_RegisterIndex, /// A register index in one or more RegKind.
499 k_Token, /// A simple token
500 k_RegList, /// A physical register list
501 k_RegPair /// A pair of physical register
505 MipsOperand(KindTy K, MipsAsmParser &Parser)
506 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
509 /// For diagnostics, and checking the assembler temporary
510 MipsAsmParser &AsmParser;
518 unsigned Num; /// Register Number
522 unsigned Index; /// Index into the register class
523 RegKind Kind; /// Bitfield of the kinds it could possibly be
524 const MCRegisterInfo *RegInfo;
537 SmallVector<unsigned, 10> *List;
542 struct PhysRegOp PhysReg;
543 struct RegIdxOp RegIdx;
546 struct RegListOp RegList;
549 SMLoc StartLoc, EndLoc;
551 /// Internal constructor for register kinds
552 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
553 const MCRegisterInfo *RegInfo,
555 MipsAsmParser &Parser) {
556 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
557 Op->RegIdx.Index = Index;
558 Op->RegIdx.RegInfo = RegInfo;
559 Op->RegIdx.Kind = RegKind;
566 /// Coerce the register to GPR32 and return the real register for the current
568 unsigned getGPR32Reg() const {
569 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
570 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
571 unsigned ClassID = Mips::GPR32RegClassID;
572 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
575 /// Coerce the register to GPR32 and return the real register for the current
577 unsigned getGPRMM16Reg() const {
578 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
579 unsigned ClassID = Mips::GPR32RegClassID;
580 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
583 /// Coerce the register to GPR64 and return the real register for the current
585 unsigned getGPR64Reg() const {
586 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
587 unsigned ClassID = Mips::GPR64RegClassID;
588 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
592 /// Coerce the register to AFGR64 and return the real register for the current
594 unsigned getAFGR64Reg() const {
595 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
596 if (RegIdx.Index % 2 != 0)
597 AsmParser.Warning(StartLoc, "Float register should be even.");
598 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
599 .getRegister(RegIdx.Index / 2);
602 /// Coerce the register to FGR64 and return the real register for the current
604 unsigned getFGR64Reg() const {
605 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
606 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
607 .getRegister(RegIdx.Index);
610 /// Coerce the register to FGR32 and return the real register for the current
612 unsigned getFGR32Reg() const {
613 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
614 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
615 .getRegister(RegIdx.Index);
618 /// Coerce the register to FGRH32 and return the real register for the current
620 unsigned getFGRH32Reg() const {
621 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
622 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
623 .getRegister(RegIdx.Index);
626 /// Coerce the register to FCC and return the real register for the current
628 unsigned getFCCReg() const {
629 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
630 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
631 .getRegister(RegIdx.Index);
634 /// Coerce the register to MSA128 and return the real register for the current
636 unsigned getMSA128Reg() const {
637 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
638 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
640 unsigned ClassID = Mips::MSA128BRegClassID;
641 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
644 /// Coerce the register to MSACtrl and return the real register for the
646 unsigned getMSACtrlReg() const {
647 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
648 unsigned ClassID = Mips::MSACtrlRegClassID;
649 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
652 /// Coerce the register to COP2 and return the real register for the
654 unsigned getCOP2Reg() const {
655 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
656 unsigned ClassID = Mips::COP2RegClassID;
657 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
660 /// Coerce the register to COP3 and return the real register for the
662 unsigned getCOP3Reg() const {
663 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
664 unsigned ClassID = Mips::COP3RegClassID;
665 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
668 /// Coerce the register to ACC64DSP and return the real register for the
670 unsigned getACC64DSPReg() const {
671 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
672 unsigned ClassID = Mips::ACC64DSPRegClassID;
673 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
676 /// Coerce the register to HI32DSP and return the real register for the
678 unsigned getHI32DSPReg() const {
679 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
680 unsigned ClassID = Mips::HI32DSPRegClassID;
681 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
684 /// Coerce the register to LO32DSP and return the real register for the
686 unsigned getLO32DSPReg() const {
687 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
688 unsigned ClassID = Mips::LO32DSPRegClassID;
689 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
692 /// Coerce the register to CCR and return the real register for the
694 unsigned getCCRReg() const {
695 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
696 unsigned ClassID = Mips::CCRRegClassID;
697 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
700 /// Coerce the register to HWRegs and return the real register for the
702 unsigned getHWRegsReg() const {
703 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
704 unsigned ClassID = Mips::HWRegsRegClassID;
705 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
709 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
710 // Add as immediate when possible. Null MCExpr = 0.
712 Inst.addOperand(MCOperand::createImm(0));
713 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
714 Inst.addOperand(MCOperand::createImm(CE->getValue()));
716 Inst.addOperand(MCOperand::createExpr(Expr));
719 void addRegOperands(MCInst &Inst, unsigned N) const {
720 llvm_unreachable("Use a custom parser instead");
723 /// Render the operand to an MCInst as a GPR32
724 /// Asserts if the wrong number of operands are requested, or the operand
725 /// is not a k_RegisterIndex compatible with RegKind_GPR
726 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
727 assert(N == 1 && "Invalid number of operands!");
728 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
731 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
732 assert(N == 1 && "Invalid number of operands!");
733 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
736 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
737 assert(N == 1 && "Invalid number of operands!");
738 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
741 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
742 assert(N == 1 && "Invalid number of operands!");
743 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
746 /// Render the operand to an MCInst as a GPR64
747 /// Asserts if the wrong number of operands are requested, or the operand
748 /// is not a k_RegisterIndex compatible with RegKind_GPR
749 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
750 assert(N == 1 && "Invalid number of operands!");
751 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
754 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
755 assert(N == 1 && "Invalid number of operands!");
756 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
759 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
760 assert(N == 1 && "Invalid number of operands!");
761 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
764 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
765 assert(N == 1 && "Invalid number of operands!");
766 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
767 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
768 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
769 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
773 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
774 assert(N == 1 && "Invalid number of operands!");
775 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
778 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
779 assert(N == 1 && "Invalid number of operands!");
780 Inst.addOperand(MCOperand::createReg(getFCCReg()));
783 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
784 assert(N == 1 && "Invalid number of operands!");
785 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
788 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
789 assert(N == 1 && "Invalid number of operands!");
790 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
793 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
794 assert(N == 1 && "Invalid number of operands!");
795 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
798 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
799 assert(N == 1 && "Invalid number of operands!");
800 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
803 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
804 assert(N == 1 && "Invalid number of operands!");
805 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
808 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
809 assert(N == 1 && "Invalid number of operands!");
810 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
813 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
814 assert(N == 1 && "Invalid number of operands!");
815 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
818 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
819 assert(N == 1 && "Invalid number of operands!");
820 Inst.addOperand(MCOperand::createReg(getCCRReg()));
823 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
824 assert(N == 1 && "Invalid number of operands!");
825 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
828 void addImmOperands(MCInst &Inst, unsigned N) const {
829 assert(N == 1 && "Invalid number of operands!");
830 const MCExpr *Expr = getImm();
834 void addMemOperands(MCInst &Inst, unsigned N) const {
835 assert(N == 2 && "Invalid number of operands!");
837 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPR32Reg()));
839 const MCExpr *Expr = getMemOff();
843 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
844 assert(N == 2 && "Invalid number of operands!");
846 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
848 const MCExpr *Expr = getMemOff();
852 void addRegListOperands(MCInst &Inst, unsigned N) const {
853 assert(N == 1 && "Invalid number of operands!");
855 for (auto RegNo : getRegList())
856 Inst.addOperand(MCOperand::createReg(RegNo));
859 void addRegPairOperands(MCInst &Inst, unsigned N) const {
860 assert(N == 2 && "Invalid number of operands!");
861 unsigned RegNo = getRegPair();
862 Inst.addOperand(MCOperand::createReg(RegNo++));
863 Inst.addOperand(MCOperand::createReg(RegNo));
866 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
867 assert(N == 2 && "Invalid number of operands!");
868 for (auto RegNo : getRegList())
869 Inst.addOperand(MCOperand::createReg(RegNo));
872 bool isReg() const override {
873 // As a special case until we sort out the definition of div/divu, pretend
874 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
875 if (isGPRAsmReg() && RegIdx.Index == 0)
878 return Kind == k_PhysRegister;
880 bool isRegIdx() const { return Kind == k_RegisterIndex; }
881 bool isImm() const override { return Kind == k_Immediate; }
882 bool isConstantImm() const {
883 return isImm() && dyn_cast<MCConstantExpr>(getImm());
885 bool isToken() const override {
886 // Note: It's not possible to pretend that other operand kinds are tokens.
887 // The matcher emitter checks tokens first.
888 return Kind == k_Token;
890 bool isMem() const override { return Kind == k_Memory; }
891 bool isConstantMemOff() const {
892 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
894 template <unsigned Bits> bool isMemWithSimmOffset() const {
895 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
897 bool isMemWithGRPMM16Base() const {
898 return isMem() && getMemBase()->isMM16AsmReg();
900 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
901 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
902 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
904 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
905 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
906 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
907 && (getMemBase()->getGPR32Reg() == Mips::SP);
909 bool isRegList16() const {
913 int Size = RegList.List->size();
914 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
915 RegList.List->back() != Mips::RA)
918 int PrevReg = *RegList.List->begin();
919 for (int i = 1; i < Size - 1; i++) {
920 int Reg = (*(RegList.List))[i];
921 if ( Reg != PrevReg + 1)
928 bool isInvNum() const { return Kind == k_Immediate; }
929 bool isLSAImm() const {
930 if (!isConstantImm())
932 int64_t Val = getConstantImm();
933 return 1 <= Val && Val <= 4;
935 bool isRegList() const { return Kind == k_RegList; }
936 bool isMovePRegPair() const {
937 if (Kind != k_RegList || RegList.List->size() != 2)
940 unsigned R0 = RegList.List->front();
941 unsigned R1 = RegList.List->back();
943 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
944 (R0 == Mips::A1 && R1 == Mips::A3) ||
945 (R0 == Mips::A2 && R1 == Mips::A3) ||
946 (R0 == Mips::A0 && R1 == Mips::S5) ||
947 (R0 == Mips::A0 && R1 == Mips::S6) ||
948 (R0 == Mips::A0 && R1 == Mips::A1) ||
949 (R0 == Mips::A0 && R1 == Mips::A2) ||
950 (R0 == Mips::A0 && R1 == Mips::A3))
956 StringRef getToken() const {
957 assert(Kind == k_Token && "Invalid access!");
958 return StringRef(Tok.Data, Tok.Length);
960 bool isRegPair() const { return Kind == k_RegPair; }
962 unsigned getReg() const override {
963 // As a special case until we sort out the definition of div/divu, pretend
964 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
965 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
966 RegIdx.Kind & RegKind_GPR)
967 return getGPR32Reg(); // FIXME: GPR64 too
969 assert(Kind == k_PhysRegister && "Invalid access!");
973 const MCExpr *getImm() const {
974 assert((Kind == k_Immediate) && "Invalid access!");
978 int64_t getConstantImm() const {
979 const MCExpr *Val = getImm();
980 return static_cast<const MCConstantExpr *>(Val)->getValue();
983 MipsOperand *getMemBase() const {
984 assert((Kind == k_Memory) && "Invalid access!");
988 const MCExpr *getMemOff() const {
989 assert((Kind == k_Memory) && "Invalid access!");
993 int64_t getConstantMemOff() const {
994 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
997 const SmallVectorImpl<unsigned> &getRegList() const {
998 assert((Kind == k_RegList) && "Invalid access!");
999 return *(RegList.List);
1002 unsigned getRegPair() const {
1003 assert((Kind == k_RegPair) && "Invalid access!");
1004 return RegIdx.Index;
1007 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1008 MipsAsmParser &Parser) {
1009 auto Op = make_unique<MipsOperand>(k_Token, Parser);
1010 Op->Tok.Data = Str.data();
1011 Op->Tok.Length = Str.size();
1017 /// Create a numeric register (e.g. $1). The exact register remains
1018 /// unresolved until an instruction successfully matches
1019 static std::unique_ptr<MipsOperand>
1020 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1021 SMLoc E, MipsAsmParser &Parser) {
1022 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1023 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1026 /// Create a register that is definitely a GPR.
1027 /// This is typically only used for named registers such as $gp.
1028 static std::unique_ptr<MipsOperand>
1029 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1030 MipsAsmParser &Parser) {
1031 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1034 /// Create a register that is definitely a FGR.
1035 /// This is typically only used for named registers such as $f0.
1036 static std::unique_ptr<MipsOperand>
1037 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1038 MipsAsmParser &Parser) {
1039 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1042 /// Create a register that is definitely a HWReg.
1043 /// This is typically only used for named registers such as $hwr_cpunum.
1044 static std::unique_ptr<MipsOperand>
1045 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1046 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1047 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1050 /// Create a register that is definitely an FCC.
1051 /// This is typically only used for named registers such as $fcc0.
1052 static std::unique_ptr<MipsOperand>
1053 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1054 MipsAsmParser &Parser) {
1055 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1058 /// Create a register that is definitely an ACC.
1059 /// This is typically only used for named registers such as $ac0.
1060 static std::unique_ptr<MipsOperand>
1061 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1062 MipsAsmParser &Parser) {
1063 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1066 /// Create a register that is definitely an MSA128.
1067 /// This is typically only used for named registers such as $w0.
1068 static std::unique_ptr<MipsOperand>
1069 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1070 SMLoc E, MipsAsmParser &Parser) {
1071 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1074 /// Create a register that is definitely an MSACtrl.
1075 /// This is typically only used for named registers such as $msaaccess.
1076 static std::unique_ptr<MipsOperand>
1077 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1078 SMLoc E, MipsAsmParser &Parser) {
1079 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1082 static std::unique_ptr<MipsOperand>
1083 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1084 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1091 static std::unique_ptr<MipsOperand>
1092 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1093 SMLoc E, MipsAsmParser &Parser) {
1094 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1095 Op->Mem.Base = Base.release();
1102 static std::unique_ptr<MipsOperand>
1103 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1104 MipsAsmParser &Parser) {
1105 assert (Regs.size() > 0 && "Empty list not allowed");
1107 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1108 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1109 Op->StartLoc = StartLoc;
1110 Op->EndLoc = EndLoc;
1114 static std::unique_ptr<MipsOperand>
1115 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1116 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1117 Op->RegIdx.Index = RegNo;
1123 bool isGPRAsmReg() const {
1124 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1126 bool isMM16AsmReg() const {
1127 if (!(isRegIdx() && RegIdx.Kind))
1129 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1130 || RegIdx.Index == 16 || RegIdx.Index == 17);
1132 bool isMM16AsmRegZero() const {
1133 if (!(isRegIdx() && RegIdx.Kind))
1135 return (RegIdx.Index == 0 ||
1136 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1137 RegIdx.Index == 17);
1139 bool isMM16AsmRegMoveP() const {
1140 if (!(isRegIdx() && RegIdx.Kind))
1142 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1143 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1145 bool isFGRAsmReg() const {
1146 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1147 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1149 bool isHWRegsAsmReg() const {
1150 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1152 bool isCCRAsmReg() const {
1153 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1155 bool isFCCAsmReg() const {
1156 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1158 if (!AsmParser.hasEightFccRegisters())
1159 return RegIdx.Index == 0;
1160 return RegIdx.Index <= 7;
1162 bool isACCAsmReg() const {
1163 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1165 bool isCOP2AsmReg() const {
1166 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1168 bool isCOP3AsmReg() const {
1169 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1171 bool isMSA128AsmReg() const {
1172 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1174 bool isMSACtrlAsmReg() const {
1175 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1178 /// getStartLoc - Get the location of the first token of this operand.
1179 SMLoc getStartLoc() const override { return StartLoc; }
1180 /// getEndLoc - Get the location of the last token of this operand.
1181 SMLoc getEndLoc() const override { return EndLoc; }
1183 virtual ~MipsOperand() {
1191 delete RegList.List;
1192 case k_PhysRegister:
1193 case k_RegisterIndex:
1200 void print(raw_ostream &OS) const override {
1209 Mem.Base->print(OS);
1214 case k_PhysRegister:
1215 OS << "PhysReg<" << PhysReg.Num << ">";
1217 case k_RegisterIndex:
1218 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1225 for (auto Reg : (*RegList.List))
1230 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1234 }; // class MipsOperand
1238 extern const MCInstrDesc MipsInsts[];
1240 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1241 return MipsInsts[Opcode];
1244 static bool hasShortDelaySlot(unsigned Opcode) {
1247 case Mips::JALRS_MM:
1248 case Mips::JALRS16_MM:
1249 case Mips::BGEZALS_MM:
1250 case Mips::BLTZALS_MM:
1257 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1258 SmallVectorImpl<MCInst> &Instructions) {
1259 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1263 if (MCID.isBranch() || MCID.isCall()) {
1264 const unsigned Opcode = Inst.getOpcode();
1274 assert(hasCnMips() && "instruction only valid for octeon cpus");
1281 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1282 Offset = Inst.getOperand(2);
1283 if (!Offset.isImm())
1284 break; // We'll deal with this situation later on when applying fixups.
1285 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1286 return Error(IDLoc, "branch target out of range");
1287 if (OffsetToAlignment(Offset.getImm(),
1288 1LL << (inMicroMipsMode() ? 1 : 2)))
1289 return Error(IDLoc, "branch to misaligned address");
1303 case Mips::BGEZAL_MM:
1304 case Mips::BLTZAL_MM:
1307 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1308 Offset = Inst.getOperand(1);
1309 if (!Offset.isImm())
1310 break; // We'll deal with this situation later on when applying fixups.
1311 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1312 return Error(IDLoc, "branch target out of range");
1313 if (OffsetToAlignment(Offset.getImm(),
1314 1LL << (inMicroMipsMode() ? 1 : 2)))
1315 return Error(IDLoc, "branch to misaligned address");
1317 case Mips::BEQZ16_MM:
1318 case Mips::BNEZ16_MM:
1319 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1320 Offset = Inst.getOperand(1);
1321 if (!Offset.isImm())
1322 break; // We'll deal with this situation later on when applying fixups.
1323 if (!isIntN(8, Offset.getImm()))
1324 return Error(IDLoc, "branch target out of range");
1325 if (OffsetToAlignment(Offset.getImm(), 2LL))
1326 return Error(IDLoc, "branch to misaligned address");
1331 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1332 // We still accept it but it is a normal nop.
1333 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1334 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1335 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1340 const unsigned Opcode = Inst.getOpcode();
1352 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1353 // The offset is handled above
1354 Opnd = Inst.getOperand(1);
1356 return Error(IDLoc, "expected immediate operand kind");
1357 Imm = Opnd.getImm();
1358 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1359 Opcode == Mips::BBIT1 ? 63 : 31))
1360 return Error(IDLoc, "immediate operand value out of range");
1362 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1364 Inst.getOperand(1).setImm(Imm - 32);
1372 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1374 Opnd = Inst.getOperand(3);
1376 return Error(IDLoc, "expected immediate operand kind");
1377 Imm = Opnd.getImm();
1378 if (Imm < 0 || Imm > 31)
1379 return Error(IDLoc, "immediate operand value out of range");
1381 Opnd = Inst.getOperand(2);
1383 return Error(IDLoc, "expected immediate operand kind");
1384 Imm = Opnd.getImm();
1385 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1386 Opcode == Mips::EXTS ? 63 : 31))
1387 return Error(IDLoc, "immediate operand value out of range");
1389 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1390 Inst.getOperand(2).setImm(Imm - 32);
1396 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1397 Opnd = Inst.getOperand(2);
1399 return Error(IDLoc, "expected immediate operand kind");
1400 Imm = Opnd.getImm();
1401 if (!isInt<10>(Imm))
1402 return Error(IDLoc, "immediate operand value out of range");
1407 if (MCID.mayLoad() || MCID.mayStore()) {
1408 // Check the offset of memory operand, if it is a symbol
1409 // reference or immediate we may have to expand instructions.
1410 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1411 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1412 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1413 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1414 MCOperand &Op = Inst.getOperand(i);
1416 int MemOffset = Op.getImm();
1417 if (MemOffset < -32768 || MemOffset > 32767) {
1418 // Offset can't exceed 16bit value.
1419 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1422 } else if (Op.isExpr()) {
1423 const MCExpr *Expr = Op.getExpr();
1424 if (Expr->getKind() == MCExpr::SymbolRef) {
1425 const MCSymbolRefExpr *SR =
1426 static_cast<const MCSymbolRefExpr *>(Expr);
1427 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1429 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1432 } else if (!isEvaluated(Expr)) {
1433 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1441 if (inMicroMipsMode()) {
1442 if (MCID.mayLoad()) {
1443 // Try to create 16-bit GP relative load instruction.
1444 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1445 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1446 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1447 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1448 MCOperand &Op = Inst.getOperand(i);
1450 int MemOffset = Op.getImm();
1451 MCOperand &DstReg = Inst.getOperand(0);
1452 MCOperand &BaseReg = Inst.getOperand(1);
1453 if (isIntN(9, MemOffset) && (MemOffset % 4 == 0) &&
1454 getContext().getRegisterInfo()->getRegClass(
1455 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1456 BaseReg.getReg() == Mips::GP) {
1458 TmpInst.setLoc(IDLoc);
1459 TmpInst.setOpcode(Mips::LWGP_MM);
1460 TmpInst.addOperand(MCOperand::createReg(DstReg.getReg()));
1461 TmpInst.addOperand(MCOperand::createReg(Mips::GP));
1462 TmpInst.addOperand(MCOperand::createImm(MemOffset));
1463 Instructions.push_back(TmpInst);
1471 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1476 switch (Inst.getOpcode()) {
1479 case Mips::ADDIUS5_MM:
1480 Opnd = Inst.getOperand(2);
1482 return Error(IDLoc, "expected immediate operand kind");
1483 Imm = Opnd.getImm();
1484 if (Imm < -8 || Imm > 7)
1485 return Error(IDLoc, "immediate operand value out of range");
1487 case Mips::ADDIUSP_MM:
1488 Opnd = Inst.getOperand(0);
1490 return Error(IDLoc, "expected immediate operand kind");
1491 Imm = Opnd.getImm();
1492 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1494 return Error(IDLoc, "immediate operand value out of range");
1496 case Mips::SLL16_MM:
1497 case Mips::SRL16_MM:
1498 Opnd = Inst.getOperand(2);
1500 return Error(IDLoc, "expected immediate operand kind");
1501 Imm = Opnd.getImm();
1502 if (Imm < 1 || Imm > 8)
1503 return Error(IDLoc, "immediate operand value out of range");
1506 Opnd = Inst.getOperand(1);
1508 return Error(IDLoc, "expected immediate operand kind");
1509 Imm = Opnd.getImm();
1510 if (Imm < -1 || Imm > 126)
1511 return Error(IDLoc, "immediate operand value out of range");
1513 case Mips::ADDIUR2_MM:
1514 Opnd = Inst.getOperand(2);
1516 return Error(IDLoc, "expected immediate operand kind");
1517 Imm = Opnd.getImm();
1518 if (!(Imm == 1 || Imm == -1 ||
1519 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1520 return Error(IDLoc, "immediate operand value out of range");
1522 case Mips::ADDIUR1SP_MM:
1523 Opnd = Inst.getOperand(1);
1525 return Error(IDLoc, "expected immediate operand kind");
1526 Imm = Opnd.getImm();
1527 if (OffsetToAlignment(Imm, 4LL))
1528 return Error(IDLoc, "misaligned immediate operand value");
1529 if (Imm < 0 || Imm > 255)
1530 return Error(IDLoc, "immediate operand value out of range");
1532 case Mips::ANDI16_MM:
1533 Opnd = Inst.getOperand(2);
1535 return Error(IDLoc, "expected immediate operand kind");
1536 Imm = Opnd.getImm();
1537 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1538 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1539 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1540 return Error(IDLoc, "immediate operand value out of range");
1542 case Mips::LBU16_MM:
1543 Opnd = Inst.getOperand(2);
1545 return Error(IDLoc, "expected immediate operand kind");
1546 Imm = Opnd.getImm();
1547 if (Imm < -1 || Imm > 14)
1548 return Error(IDLoc, "immediate operand value out of range");
1551 Opnd = Inst.getOperand(2);
1553 return Error(IDLoc, "expected immediate operand kind");
1554 Imm = Opnd.getImm();
1555 if (Imm < 0 || Imm > 15)
1556 return Error(IDLoc, "immediate operand value out of range");
1558 case Mips::LHU16_MM:
1560 Opnd = Inst.getOperand(2);
1562 return Error(IDLoc, "expected immediate operand kind");
1563 Imm = Opnd.getImm();
1564 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1565 return Error(IDLoc, "immediate operand value out of range");
1569 Opnd = Inst.getOperand(2);
1571 return Error(IDLoc, "expected immediate operand kind");
1572 Imm = Opnd.getImm();
1573 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1574 return Error(IDLoc, "immediate operand value out of range");
1578 Opnd = Inst.getOperand(2);
1580 return Error(IDLoc, "expected immediate operand kind");
1581 Imm = Opnd.getImm();
1582 if (!isUInt<5>(Imm))
1583 return Error(IDLoc, "immediate operand value out of range");
1585 case Mips::ADDIUPC_MM:
1586 MCOperand Opnd = Inst.getOperand(1);
1588 return Error(IDLoc, "expected immediate operand kind");
1589 int Imm = Opnd.getImm();
1590 if ((Imm % 4 != 0) || !isIntN(25, Imm))
1591 return Error(IDLoc, "immediate operand value out of range");
1596 if (needsExpansion(Inst)) {
1597 if (expandInstruction(Inst, IDLoc, Instructions))
1600 Instructions.push_back(Inst);
1602 // If this instruction has a delay slot and .set reorder is active,
1603 // emit a NOP after it.
1604 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1605 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1610 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1612 switch (Inst.getOpcode()) {
1613 case Mips::LoadImm32:
1614 case Mips::LoadImm64:
1615 case Mips::LoadAddrImm32:
1616 case Mips::LoadAddrReg32:
1617 case Mips::B_MM_Pseudo:
1620 case Mips::JalOneReg:
1621 case Mips::JalTwoReg:
1630 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1631 SmallVectorImpl<MCInst> &Instructions) {
1632 switch (Inst.getOpcode()) {
1633 default: llvm_unreachable("unimplemented expansion");
1634 case Mips::LoadImm32:
1635 return expandLoadImm(Inst, true, IDLoc, Instructions);
1636 case Mips::LoadImm64:
1637 return expandLoadImm(Inst, false, IDLoc, Instructions);
1638 case Mips::LoadAddrImm32:
1639 return expandLoadAddressImm(Inst, true, IDLoc, Instructions);
1640 case Mips::LoadAddrReg32:
1641 return expandLoadAddressReg(Inst, true, IDLoc, Instructions);
1642 case Mips::B_MM_Pseudo:
1643 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1646 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
1647 case Mips::JalOneReg:
1648 case Mips::JalTwoReg:
1649 return expandJalWithRegs(Inst, IDLoc, Instructions);
1652 return expandBranchImm(Inst, IDLoc, Instructions);
1657 template <unsigned ShiftAmount>
1658 void createLShiftOri(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1659 SmallVectorImpl<MCInst> &Instructions) {
1661 if (ShiftAmount >= 32) {
1662 tmpInst.setOpcode(Mips::DSLL32);
1663 tmpInst.addOperand(MCOperand::createReg(RegNo));
1664 tmpInst.addOperand(MCOperand::createReg(RegNo));
1665 tmpInst.addOperand(MCOperand::createImm(ShiftAmount - 32));
1666 tmpInst.setLoc(IDLoc);
1667 Instructions.push_back(tmpInst);
1669 } else if (ShiftAmount > 0) {
1670 tmpInst.setOpcode(Mips::DSLL);
1671 tmpInst.addOperand(MCOperand::createReg(RegNo));
1672 tmpInst.addOperand(MCOperand::createReg(RegNo));
1673 tmpInst.addOperand(MCOperand::createImm(ShiftAmount));
1674 tmpInst.setLoc(IDLoc);
1675 Instructions.push_back(tmpInst);
1678 // There's no need for an ORi if the immediate is 0.
1679 if (Operand.isImm() && Operand.getImm() == 0)
1682 tmpInst.setOpcode(Mips::ORi);
1683 tmpInst.addOperand(MCOperand::createReg(RegNo));
1684 tmpInst.addOperand(MCOperand::createReg(RegNo));
1685 tmpInst.addOperand(Operand);
1686 tmpInst.setLoc(IDLoc);
1687 Instructions.push_back(tmpInst);
1690 template <unsigned ShiftAmount>
1691 void createLShiftOri(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1692 SmallVectorImpl<MCInst> &Instructions) {
1693 createLShiftOri<ShiftAmount>(MCOperand::createImm(Value), RegNo, IDLoc,
1698 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
1699 SmallVectorImpl<MCInst> &Instructions) {
1700 // Create a JALR instruction which is going to replace the pseudo-JAL.
1702 JalrInst.setLoc(IDLoc);
1703 const MCOperand FirstRegOp = Inst.getOperand(0);
1704 const unsigned Opcode = Inst.getOpcode();
1706 if (Opcode == Mips::JalOneReg) {
1707 // jal $rs => jalr $rs
1708 if (inMicroMipsMode()) {
1709 JalrInst.setOpcode(Mips::JALR16_MM);
1710 JalrInst.addOperand(FirstRegOp);
1712 JalrInst.setOpcode(Mips::JALR);
1713 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1714 JalrInst.addOperand(FirstRegOp);
1716 } else if (Opcode == Mips::JalTwoReg) {
1717 // jal $rd, $rs => jalr $rd, $rs
1718 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1719 JalrInst.addOperand(FirstRegOp);
1720 const MCOperand SecondRegOp = Inst.getOperand(1);
1721 JalrInst.addOperand(SecondRegOp);
1723 Instructions.push_back(JalrInst);
1725 // If .set reorder is active, emit a NOP after it.
1726 if (AssemblerOptions.back()->isReorder()) {
1727 // This is a 32-bit NOP because these 2 pseudo-instructions
1728 // do not have a short delay slot.
1730 NopInst.setOpcode(Mips::SLL);
1731 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
1732 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
1733 NopInst.addOperand(MCOperand::createImm(0));
1734 Instructions.push_back(NopInst);
1740 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
1741 unsigned SrcReg, bool Is32BitImm, SMLoc IDLoc,
1742 SmallVectorImpl<MCInst> &Instructions) {
1743 if (!Is32BitImm && !isGP64bit()) {
1744 Error(IDLoc, "instruction requires a 64-bit architecture");
1748 bool UseSrcReg = false;
1749 if (SrcReg != Mips::NoRegister)
1754 tmpInst.setLoc(IDLoc);
1755 // FIXME: gas has a special case for values that are 000...1111, which
1756 // becomes a li -1 and then a dsrl
1757 if (0 <= ImmValue && ImmValue <= 65535) {
1758 // For unsigned and positive signed 16-bit values (0 <= j <= 65535):
1759 // li d,j => ori d,$zero,j
1761 SrcReg = isGP64bit() ? Mips::ZERO_64 : Mips::ZERO;
1762 tmpInst.setOpcode(Mips::ORi);
1763 tmpInst.addOperand(MCOperand::createReg(DstReg));
1764 tmpInst.addOperand(MCOperand::createReg(SrcReg));
1765 tmpInst.addOperand(MCOperand::createImm(ImmValue));
1766 Instructions.push_back(tmpInst);
1767 } else if (ImmValue < 0 && ImmValue >= -32768) {
1768 // For negative signed 16-bit values (-32768 <= j < 0):
1769 // li d,j => addiu d,$zero,j
1771 SrcReg = Mips::ZERO;
1772 tmpInst.setOpcode(Mips::ADDiu);
1773 tmpInst.addOperand(MCOperand::createReg(DstReg));
1774 tmpInst.addOperand(MCOperand::createReg(SrcReg));
1775 tmpInst.addOperand(MCOperand::createImm(ImmValue));
1776 Instructions.push_back(tmpInst);
1777 } else if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
1778 warnIfNoMacro(IDLoc);
1780 // For all other values which are representable as a 32-bit integer:
1781 // li d,j => lui d,hi16(j)
1783 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1784 uint16_t Bits15To0 = ImmValue & 0xffff;
1786 if (!Is32BitImm && !isInt<32>(ImmValue)) {
1787 // For DLI, expand to an ORi instead of a LUi to avoid sign-extending the
1789 tmpInst.setOpcode(Mips::ORi);
1790 tmpInst.addOperand(MCOperand::createReg(DstReg));
1791 tmpInst.addOperand(MCOperand::createReg(Mips::ZERO));
1792 tmpInst.addOperand(MCOperand::createImm(Bits31To16));
1793 tmpInst.setLoc(IDLoc);
1794 Instructions.push_back(tmpInst);
1795 // Move the value to the upper 16 bits by doing a 16-bit left shift.
1796 createLShiftOri<16>(0, DstReg, IDLoc, Instructions);
1798 tmpInst.setOpcode(Mips::LUi);
1799 tmpInst.addOperand(MCOperand::createReg(DstReg));
1800 tmpInst.addOperand(MCOperand::createImm(Bits31To16));
1801 Instructions.push_back(tmpInst);
1803 createLShiftOri<0>(Bits15To0, DstReg, IDLoc, Instructions);
1806 createAddu(DstReg, DstReg, SrcReg, Instructions);
1808 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1810 Error(IDLoc, "instruction requires a 32-bit immediate");
1813 warnIfNoMacro(IDLoc);
1815 // <------- lo32 ------>
1816 // <------- hi32 ------>
1817 // <- hi16 -> <- lo16 ->
1818 // _________________________________
1820 // | 16-bits | 16-bits | 16-bits |
1821 // |__________|__________|__________|
1823 // For any 64-bit value that is representable as a 48-bit integer:
1824 // li d,j => lui d,hi16(j)
1825 // ori d,d,hi16(lo32(j))
1827 // ori d,d,lo16(lo32(j))
1828 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1829 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1830 uint16_t Bits15To0 = ImmValue & 0xffff;
1832 tmpInst.setOpcode(Mips::LUi);
1833 tmpInst.addOperand(MCOperand::createReg(DstReg));
1834 tmpInst.addOperand(MCOperand::createImm(Bits47To32));
1835 Instructions.push_back(tmpInst);
1836 createLShiftOri<0>(Bits31To16, DstReg, IDLoc, Instructions);
1837 createLShiftOri<16>(Bits15To0, DstReg, IDLoc, Instructions);
1840 createAddu(DstReg, DstReg, SrcReg, Instructions);
1844 Error(IDLoc, "instruction requires a 32-bit immediate");
1847 warnIfNoMacro(IDLoc);
1849 // <------- hi32 ------> <------- lo32 ------>
1850 // <- hi16 -> <- lo16 ->
1851 // ___________________________________________
1853 // | 16-bits | 16-bits | 16-bits | 16-bits |
1854 // |__________|__________|__________|__________|
1856 // For all other values which are representable as a 64-bit integer:
1857 // li d,j => lui d,hi16(j)
1858 // ori d,d,lo16(hi32(j))
1860 // ori d,d,hi16(lo32(j))
1862 // ori d,d,lo16(lo32(j))
1863 uint16_t Bits63To48 = (ImmValue >> 48) & 0xffff;
1864 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1865 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1866 uint16_t Bits15To0 = ImmValue & 0xffff;
1868 tmpInst.setOpcode(Mips::LUi);
1869 tmpInst.addOperand(MCOperand::createReg(DstReg));
1870 tmpInst.addOperand(MCOperand::createImm(Bits63To48));
1871 Instructions.push_back(tmpInst);
1872 createLShiftOri<0>(Bits47To32, DstReg, IDLoc, Instructions);
1874 // When Bits31To16 is 0, do a left shift of 32 bits instead of doing
1875 // two left shifts of 16 bits.
1876 if (Bits31To16 == 0) {
1877 createLShiftOri<32>(Bits15To0, DstReg, IDLoc, Instructions);
1879 createLShiftOri<16>(Bits31To16, DstReg, IDLoc, Instructions);
1880 createLShiftOri<16>(Bits15To0, DstReg, IDLoc, Instructions);
1884 createAddu(DstReg, DstReg, SrcReg, Instructions);
1889 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1890 SmallVectorImpl<MCInst> &Instructions) {
1891 const MCOperand &ImmOp = Inst.getOperand(1);
1892 assert(ImmOp.isImm() && "expected immediate operand kind");
1893 const MCOperand &DstRegOp = Inst.getOperand(0);
1894 assert(DstRegOp.isReg() && "expected register operand kind");
1896 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
1897 Is32BitImm, IDLoc, Instructions))
1904 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1905 SmallVectorImpl<MCInst> &Instructions) {
1906 const MCOperand &DstRegOp = Inst.getOperand(0);
1907 assert(DstRegOp.isReg() && "expected register operand kind");
1909 const MCOperand &ImmOp = Inst.getOperand(2);
1910 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1911 "expected immediate operand kind");
1912 if (!ImmOp.isImm()) {
1913 expandLoadAddressSym(DstRegOp, ImmOp, Is32BitImm, IDLoc, Instructions);
1916 const MCOperand &SrcRegOp = Inst.getOperand(1);
1917 assert(SrcRegOp.isReg() && "expected register operand kind");
1919 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), SrcRegOp.getReg(),
1920 Is32BitImm, IDLoc, Instructions))
1927 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1928 SmallVectorImpl<MCInst> &Instructions) {
1929 const MCOperand &DstRegOp = Inst.getOperand(0);
1930 assert(DstRegOp.isReg() && "expected register operand kind");
1932 const MCOperand &ImmOp = Inst.getOperand(1);
1933 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1934 "expected immediate operand kind");
1935 if (!ImmOp.isImm()) {
1936 expandLoadAddressSym(DstRegOp, ImmOp, Is32BitImm, IDLoc, Instructions);
1940 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
1941 Is32BitImm, IDLoc, Instructions))
1947 void MipsAsmParser::expandLoadAddressSym(
1948 const MCOperand &DstRegOp, const MCOperand &SymOp, bool Is32BitSym,
1949 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1950 warnIfNoMacro(IDLoc);
1952 if (Is32BitSym && isABI_N64())
1953 Warning(IDLoc, "instruction loads the 32-bit address of a 64-bit symbol");
1956 unsigned RegNo = DstRegOp.getReg();
1957 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
1958 const MCSymbolRefExpr *HiExpr =
1959 MCSymbolRefExpr::create(Symbol->getSymbol().getName(),
1960 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1961 const MCSymbolRefExpr *LoExpr =
1962 MCSymbolRefExpr::create(Symbol->getSymbol().getName(),
1963 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1965 // If it's a 64-bit architecture, expand to:
1966 // la d,sym => lui d,highest(sym)
1967 // ori d,d,higher(sym)
1969 // ori d,d,hi16(sym)
1971 // ori d,d,lo16(sym)
1972 const MCSymbolRefExpr *HighestExpr =
1973 MCSymbolRefExpr::create(Symbol->getSymbol().getName(),
1974 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1975 const MCSymbolRefExpr *HigherExpr =
1976 MCSymbolRefExpr::create(Symbol->getSymbol().getName(),
1977 MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1979 tmpInst.setOpcode(Mips::LUi);
1980 tmpInst.addOperand(MCOperand::createReg(RegNo));
1981 tmpInst.addOperand(MCOperand::createExpr(HighestExpr));
1982 Instructions.push_back(tmpInst);
1984 createLShiftOri<0>(MCOperand::createExpr(HigherExpr), RegNo, SMLoc(),
1986 createLShiftOri<16>(MCOperand::createExpr(HiExpr), RegNo, SMLoc(),
1988 createLShiftOri<16>(MCOperand::createExpr(LoExpr), RegNo, SMLoc(),
1991 // Otherwise, expand to:
1992 // la d,sym => lui d,hi16(sym)
1993 // ori d,d,lo16(sym)
1994 tmpInst.setOpcode(Mips::LUi);
1995 tmpInst.addOperand(MCOperand::createReg(RegNo));
1996 tmpInst.addOperand(MCOperand::createExpr(HiExpr));
1997 Instructions.push_back(tmpInst);
1999 createLShiftOri<0>(MCOperand::createExpr(LoExpr), RegNo, SMLoc(),
2004 bool MipsAsmParser::expandUncondBranchMMPseudo(
2005 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2006 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2007 "unexpected number of operands");
2009 MCOperand Offset = Inst.getOperand(0);
2010 if (Offset.isExpr()) {
2012 Inst.setOpcode(Mips::BEQ_MM);
2013 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2014 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2015 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2017 assert(Offset.isImm() && "expected immediate operand kind");
2018 if (isIntN(11, Offset.getImm())) {
2019 // If offset fits into 11 bits then this instruction becomes microMIPS
2020 // 16-bit unconditional branch instruction.
2021 Inst.setOpcode(Mips::B16_MM);
2023 if (!isIntN(17, Offset.getImm()))
2024 Error(IDLoc, "branch target out of range");
2025 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2026 Error(IDLoc, "branch to misaligned address");
2028 Inst.setOpcode(Mips::BEQ_MM);
2029 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2030 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2031 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2034 Instructions.push_back(Inst);
2036 // If .set reorder is active, emit a NOP after the branch instruction.
2037 if (AssemblerOptions.back()->isReorder())
2038 createNop(true, IDLoc, Instructions);
2043 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc,
2044 SmallVectorImpl<MCInst> &Instructions) {
2045 const MCOperand &DstRegOp = Inst.getOperand(0);
2046 assert(DstRegOp.isReg() && "expected register operand kind");
2048 const MCOperand &ImmOp = Inst.getOperand(1);
2049 assert(ImmOp.isImm() && "expected immediate operand kind");
2051 const MCOperand &MemOffsetOp = Inst.getOperand(2);
2052 assert(MemOffsetOp.isImm() && "expected immediate operand kind");
2054 unsigned OpCode = 0;
2055 switch(Inst.getOpcode()) {
2063 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2067 int64_t ImmValue = ImmOp.getImm();
2068 if (ImmValue == 0) {
2070 BranchInst.setOpcode(OpCode);
2071 BranchInst.addOperand(DstRegOp);
2072 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2073 BranchInst.addOperand(MemOffsetOp);
2074 Instructions.push_back(BranchInst);
2076 warnIfNoMacro(IDLoc);
2078 unsigned ATReg = getATReg(IDLoc);
2082 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), IDLoc,
2087 BranchInst.setOpcode(OpCode);
2088 BranchInst.addOperand(DstRegOp);
2089 BranchInst.addOperand(MCOperand::createReg(ATReg));
2090 BranchInst.addOperand(MemOffsetOp);
2091 Instructions.push_back(BranchInst);
2096 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2097 SmallVectorImpl<MCInst> &Instructions,
2098 bool isLoad, bool isImmOpnd) {
2099 const MCSymbolRefExpr *SR;
2101 unsigned ImmOffset, HiOffset, LoOffset;
2102 const MCExpr *ExprOffset;
2104 // 1st operand is either the source or destination register.
2105 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2106 unsigned RegOpNum = Inst.getOperand(0).getReg();
2107 // 2nd operand is the base register.
2108 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2109 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2110 // 3rd operand is either an immediate or expression.
2112 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2113 ImmOffset = Inst.getOperand(2).getImm();
2114 LoOffset = ImmOffset & 0x0000ffff;
2115 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2116 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2117 if (LoOffset & 0x8000)
2120 ExprOffset = Inst.getOperand(2).getExpr();
2121 // All instructions will have the same location.
2122 TempInst.setLoc(IDLoc);
2123 // These are some of the types of expansions we perform here:
2124 // 1) lw $8, sym => lui $8, %hi(sym)
2125 // lw $8, %lo(sym)($8)
2126 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2128 // lw $8, %lo(offset)($9)
2129 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2131 // lw $8, %lo(offset)($at)
2132 // 4) sw $8, sym => lui $at, %hi(sym)
2133 // sw $8, %lo(sym)($at)
2134 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2136 // sw $8, %lo(offset)($at)
2137 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2138 // ldc1 $f0, %lo(sym)($at)
2140 // For load instructions we can use the destination register as a temporary
2141 // if base and dst are different (examples 1 and 2) and if the base register
2142 // is general purpose otherwise we must use $at (example 6) and error if it's
2143 // not available. For stores we must use $at (examples 4 and 5) because we
2144 // must not clobber the source register setting up the offset.
2145 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2146 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2147 unsigned RegClassIDOp0 =
2148 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2149 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2150 (RegClassIDOp0 == Mips::GPR64RegClassID);
2151 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2152 TmpRegNum = RegOpNum;
2154 // At this point we need AT to perform the expansions and we exit if it is
2156 TmpRegNum = getATReg(IDLoc);
2161 TempInst.setOpcode(Mips::LUi);
2162 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2164 TempInst.addOperand(MCOperand::createImm(HiOffset));
2166 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2167 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
2168 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::create(
2169 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
2171 TempInst.addOperand(MCOperand::createExpr(HiExpr));
2173 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2174 TempInst.addOperand(MCOperand::createExpr(HiExpr));
2177 // Add the instruction to the list.
2178 Instructions.push_back(TempInst);
2179 // Prepare TempInst for next instruction.
2181 // Add temp register to base.
2182 if (BaseRegNum != Mips::ZERO) {
2183 TempInst.setOpcode(Mips::ADDu);
2184 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2185 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2186 TempInst.addOperand(MCOperand::createReg(BaseRegNum));
2187 Instructions.push_back(TempInst);
2190 // And finally, create original instruction with low part
2191 // of offset and new base.
2192 TempInst.setOpcode(Inst.getOpcode());
2193 TempInst.addOperand(MCOperand::createReg(RegOpNum));
2194 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2196 TempInst.addOperand(MCOperand::createImm(LoOffset));
2198 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2199 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::create(
2200 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
2202 TempInst.addOperand(MCOperand::createExpr(LoExpr));
2204 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2205 TempInst.addOperand(MCOperand::createExpr(LoExpr));
2208 Instructions.push_back(TempInst);
2213 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2214 SmallVectorImpl<MCInst> &Instructions) {
2215 unsigned OpNum = Inst.getNumOperands();
2216 unsigned Opcode = Inst.getOpcode();
2217 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2219 assert (Inst.getOperand(OpNum - 1).isImm() &&
2220 Inst.getOperand(OpNum - 2).isReg() &&
2221 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2223 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2224 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2225 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2226 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2227 // It can be implemented as SWM16 or LWM16 instruction.
2228 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2230 Inst.setOpcode(NewOpcode);
2231 Instructions.push_back(Inst);
2235 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
2236 SmallVectorImpl<MCInst> &Instructions) {
2238 if (hasShortDelaySlot) {
2239 NopInst.setOpcode(Mips::MOVE16_MM);
2240 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2241 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2243 NopInst.setOpcode(Mips::SLL);
2244 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2245 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2246 NopInst.addOperand(MCOperand::createImm(0));
2248 Instructions.push_back(NopInst);
2251 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
2253 SmallVectorImpl<MCInst> &Instructions) {
2255 AdduInst.setOpcode(Mips::ADDu);
2256 AdduInst.addOperand(MCOperand::createReg(DstReg));
2257 AdduInst.addOperand(MCOperand::createReg(SrcReg));
2258 AdduInst.addOperand(MCOperand::createReg(TrgReg));
2259 Instructions.push_back(AdduInst);
2262 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
2263 // As described by the Mips32r2 spec, the registers Rd and Rs for
2264 // jalr.hb must be different.
2265 unsigned Opcode = Inst.getOpcode();
2267 if (Opcode == Mips::JALR_HB &&
2268 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
2269 return Match_RequiresDifferentSrcAndDst;
2271 return Match_Success;
2274 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2275 OperandVector &Operands,
2277 uint64_t &ErrorInfo,
2278 bool MatchingInlineAsm) {
2281 SmallVector<MCInst, 8> Instructions;
2282 unsigned MatchResult =
2283 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
2285 switch (MatchResult) {
2286 case Match_Success: {
2287 if (processInstruction(Inst, IDLoc, Instructions))
2289 for (unsigned i = 0; i < Instructions.size(); i++)
2290 Out.EmitInstruction(Instructions[i], STI);
2293 case Match_MissingFeature:
2294 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2296 case Match_InvalidOperand: {
2297 SMLoc ErrorLoc = IDLoc;
2298 if (ErrorInfo != ~0ULL) {
2299 if (ErrorInfo >= Operands.size())
2300 return Error(IDLoc, "too few operands for instruction");
2302 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
2303 if (ErrorLoc == SMLoc())
2307 return Error(ErrorLoc, "invalid operand for instruction");
2309 case Match_MnemonicFail:
2310 return Error(IDLoc, "invalid instruction");
2311 case Match_RequiresDifferentSrcAndDst:
2312 return Error(IDLoc, "source and destination must be different");
2315 llvm_unreachable("Implement any new match types added!");
2318 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
2319 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
2320 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
2321 ") without \".set noat\"");
2324 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
2325 if (!AssemblerOptions.back()->isMacro())
2326 Warning(Loc, "macro instruction expanded into multiple instructions");
2330 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
2331 SMRange Range, bool ShowColors) {
2332 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
2333 Range, SMFixIt(Range, FixMsg),
2337 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
2340 CC = StringSwitch<unsigned>(Name)
2376 if (!(isABI_N32() || isABI_N64()))
2379 if (12 <= CC && CC <= 15) {
2380 // Name is one of t4-t7
2381 AsmToken RegTok = getLexer().peekTok();
2382 SMRange RegRange = RegTok.getLocRange();
2384 StringRef FixedName = StringSwitch<StringRef>(Name)
2390 assert(FixedName != "" && "Register name is not one of t4-t7.");
2392 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
2393 "Did you mean $" + FixedName + "?", RegRange);
2396 // Although SGI documentation just cuts out t0-t3 for n32/n64,
2397 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
2398 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
2399 if (8 <= CC && CC <= 11)
2403 CC = StringSwitch<unsigned>(Name)
2415 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
2418 CC = StringSwitch<unsigned>(Name)
2419 .Case("hwr_cpunum", 0)
2420 .Case("hwr_synci_step", 1)
2422 .Case("hwr_ccres", 3)
2423 .Case("hwr_ulr", 29)
2429 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2431 if (Name[0] == 'f') {
2432 StringRef NumString = Name.substr(1);
2434 if (NumString.getAsInteger(10, IntVal))
2435 return -1; // This is not an integer.
2436 if (IntVal > 31) // Maximum index for fpu register.
2443 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2445 if (Name.startswith("fcc")) {
2446 StringRef NumString = Name.substr(3);
2448 if (NumString.getAsInteger(10, IntVal))
2449 return -1; // This is not an integer.
2450 if (IntVal > 7) // There are only 8 fcc registers.
2457 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2459 if (Name.startswith("ac")) {
2460 StringRef NumString = Name.substr(2);
2462 if (NumString.getAsInteger(10, IntVal))
2463 return -1; // This is not an integer.
2464 if (IntVal > 3) // There are only 3 acc registers.
2471 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2474 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
2483 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
2486 CC = StringSwitch<unsigned>(Name)
2489 .Case("msaaccess", 2)
2491 .Case("msamodify", 4)
2492 .Case("msarequest", 5)
2494 .Case("msaunmap", 7)
2500 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
2501 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
2503 reportParseError(Loc,
2504 "pseudo-instruction requires $at, which is not available");
2507 unsigned AT = getReg(
2508 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
2512 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2513 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2516 unsigned MipsAsmParser::getGPR(int RegNo) {
2517 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2521 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2523 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2526 return getReg(RegClass, RegNum);
2529 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2530 MCAsmParser &Parser = getParser();
2531 DEBUG(dbgs() << "parseOperand\n");
2533 // Check if the current operand has a custom associated parser, if so, try to
2534 // custom parse the operand, or fallback to the general approach.
2535 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2536 if (ResTy == MatchOperand_Success)
2538 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2539 // there was a match, but an error occurred, in which case, just return that
2540 // the operand parsing failed.
2541 if (ResTy == MatchOperand_ParseFail)
2544 DEBUG(dbgs() << ".. Generic Parser\n");
2546 switch (getLexer().getKind()) {
2548 Error(Parser.getTok().getLoc(), "unexpected token in operand");
2550 case AsmToken::Dollar: {
2551 // Parse the register.
2552 SMLoc S = Parser.getTok().getLoc();
2554 // Almost all registers have been parsed by custom parsers. There is only
2555 // one exception to this. $zero (and it's alias $0) will reach this point
2556 // for div, divu, and similar instructions because it is not an operand
2557 // to the instruction definition but an explicit register. Special case
2558 // this situation for now.
2559 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
2562 // Maybe it is a symbol reference.
2563 StringRef Identifier;
2564 if (Parser.parseIdentifier(Identifier))
2567 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2568 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
2569 // Otherwise create a symbol reference.
2571 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
2573 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
2576 // Else drop to expression parsing.
2577 case AsmToken::LParen:
2578 case AsmToken::Minus:
2579 case AsmToken::Plus:
2580 case AsmToken::Integer:
2581 case AsmToken::Tilde:
2582 case AsmToken::String: {
2583 DEBUG(dbgs() << ".. generic integer\n");
2584 OperandMatchResultTy ResTy = parseImm(Operands);
2585 return ResTy != MatchOperand_Success;
2587 case AsmToken::Percent: {
2588 // It is a symbol reference or constant expression.
2589 const MCExpr *IdVal;
2590 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
2591 if (parseRelocOperand(IdVal))
2594 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2596 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2598 } // case AsmToken::Percent
2599 } // switch(getLexer().getKind())
2603 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
2604 StringRef RelocStr) {
2606 // Check the type of the expression.
2607 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
2608 // It's a constant, evaluate reloc value.
2610 switch (getVariantKind(RelocStr)) {
2611 case MCSymbolRefExpr::VK_Mips_ABS_LO:
2612 // Get the 1st 16-bits.
2613 Val = MCE->getValue() & 0xffff;
2615 case MCSymbolRefExpr::VK_Mips_ABS_HI:
2616 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
2617 // 16 bits being negative.
2618 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
2620 case MCSymbolRefExpr::VK_Mips_HIGHER:
2621 // Get the 3rd 16-bits.
2622 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
2624 case MCSymbolRefExpr::VK_Mips_HIGHEST:
2625 // Get the 4th 16-bits.
2626 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
2629 report_fatal_error("unsupported reloc value");
2631 return MCConstantExpr::create(Val, getContext());
2634 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
2635 // It's a symbol, create a symbolic expression from the symbol.
2636 StringRef Symbol = MSRE->getSymbol().getName();
2637 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2638 Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
2642 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2643 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2645 // Try to create target expression.
2646 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
2647 return MipsMCExpr::create(VK, Expr, getContext());
2649 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
2650 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
2651 Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
2655 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
2656 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
2657 Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
2660 // Just return the original expression.
2664 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
2666 switch (Expr->getKind()) {
2667 case MCExpr::Constant:
2669 case MCExpr::SymbolRef:
2670 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
2671 case MCExpr::Binary:
2672 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2673 if (!isEvaluated(BE->getLHS()))
2675 return isEvaluated(BE->getRHS());
2678 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
2679 case MCExpr::Target:
2685 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
2686 MCAsmParser &Parser = getParser();
2687 Parser.Lex(); // Eat the % token.
2688 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
2689 if (Tok.isNot(AsmToken::Identifier))
2692 std::string Str = Tok.getIdentifier();
2694 Parser.Lex(); // Eat the identifier.
2695 // Now make an expression from the rest of the operand.
2696 const MCExpr *IdVal;
2699 if (getLexer().getKind() == AsmToken::LParen) {
2701 Parser.Lex(); // Eat the '(' token.
2702 if (getLexer().getKind() == AsmToken::Percent) {
2703 Parser.Lex(); // Eat the % token.
2704 const AsmToken &nextTok = Parser.getTok();
2705 if (nextTok.isNot(AsmToken::Identifier))
2708 Str += nextTok.getIdentifier();
2709 Parser.Lex(); // Eat the identifier.
2710 if (getLexer().getKind() != AsmToken::LParen)
2715 if (getParser().parseParenExpression(IdVal, EndLoc))
2718 while (getLexer().getKind() == AsmToken::RParen)
2719 Parser.Lex(); // Eat the ')' token.
2722 return true; // Parenthesis must follow the relocation operand.
2724 Res = evaluateRelocExpr(IdVal, Str);
2728 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2730 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2731 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2732 if (ResTy == MatchOperand_Success) {
2733 assert(Operands.size() == 1);
2734 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2735 StartLoc = Operand.getStartLoc();
2736 EndLoc = Operand.getEndLoc();
2738 // AFAIK, we only support numeric registers and named GPR's in CFI
2740 // Don't worry about eating tokens before failing. Using an unrecognised
2741 // register is a parse error.
2742 if (Operand.isGPRAsmReg()) {
2743 // Resolve to GPR32 or GPR64 appropriately.
2744 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2747 return (RegNo == (unsigned)-1);
2750 assert(Operands.size() == 0);
2751 return (RegNo == (unsigned)-1);
2754 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2755 MCAsmParser &Parser = getParser();
2759 while (getLexer().getKind() == AsmToken::LParen)
2762 switch (getLexer().getKind()) {
2765 case AsmToken::Identifier:
2766 case AsmToken::LParen:
2767 case AsmToken::Integer:
2768 case AsmToken::Minus:
2769 case AsmToken::Plus:
2771 Result = getParser().parseParenExpression(Res, S);
2773 Result = (getParser().parseExpression(Res));
2774 while (getLexer().getKind() == AsmToken::RParen)
2777 case AsmToken::Percent:
2778 Result = parseRelocOperand(Res);
2783 MipsAsmParser::OperandMatchResultTy
2784 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
2785 MCAsmParser &Parser = getParser();
2786 DEBUG(dbgs() << "parseMemOperand\n");
2787 const MCExpr *IdVal = nullptr;
2789 bool isParenExpr = false;
2790 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
2791 // First operand is the offset.
2792 S = Parser.getTok().getLoc();
2794 if (getLexer().getKind() == AsmToken::LParen) {
2799 if (getLexer().getKind() != AsmToken::Dollar) {
2800 if (parseMemOffset(IdVal, isParenExpr))
2801 return MatchOperand_ParseFail;
2803 const AsmToken &Tok = Parser.getTok(); // Get the next token.
2804 if (Tok.isNot(AsmToken::LParen)) {
2805 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2806 if (Mnemonic.getToken() == "la") {
2808 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2809 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2810 return MatchOperand_Success;
2812 if (Tok.is(AsmToken::EndOfStatement)) {
2814 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2816 // Zero register assumed, add a memory operand with ZERO as its base.
2817 // "Base" will be managed by k_Memory.
2818 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
2821 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2822 return MatchOperand_Success;
2824 Error(Parser.getTok().getLoc(), "'(' expected");
2825 return MatchOperand_ParseFail;
2828 Parser.Lex(); // Eat the '(' token.
2831 Res = parseAnyRegister(Operands);
2832 if (Res != MatchOperand_Success)
2835 if (Parser.getTok().isNot(AsmToken::RParen)) {
2836 Error(Parser.getTok().getLoc(), "')' expected");
2837 return MatchOperand_ParseFail;
2840 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2842 Parser.Lex(); // Eat the ')' token.
2845 IdVal = MCConstantExpr::create(0, getContext());
2847 // Replace the register operand with the memory operand.
2848 std::unique_ptr<MipsOperand> op(
2849 static_cast<MipsOperand *>(Operands.back().release()));
2850 // Remove the register from the operands.
2851 // "op" will be managed by k_Memory.
2852 Operands.pop_back();
2853 // Add the memory operand.
2854 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2856 if (IdVal->evaluateAsAbsolute(Imm))
2857 IdVal = MCConstantExpr::create(Imm, getContext());
2858 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2859 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2863 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2864 return MatchOperand_Success;
2867 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2868 MCAsmParser &Parser = getParser();
2869 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
2871 SMLoc S = Parser.getTok().getLoc();
2873 if (Sym->isVariable())
2874 Expr = Sym->getVariableValue();
2877 if (Expr->getKind() == MCExpr::SymbolRef) {
2878 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2879 StringRef DefSymbol = Ref->getSymbol().getName();
2880 if (DefSymbol.startswith("$")) {
2881 OperandMatchResultTy ResTy =
2882 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2883 if (ResTy == MatchOperand_Success) {
2886 } else if (ResTy == MatchOperand_ParseFail)
2887 llvm_unreachable("Should never ParseFail");
2890 } else if (Expr->getKind() == MCExpr::Constant) {
2892 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2894 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2901 MipsAsmParser::OperandMatchResultTy
2902 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2903 StringRef Identifier,
2905 int Index = matchCPURegisterName(Identifier);
2907 Operands.push_back(MipsOperand::createGPRReg(
2908 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2909 return MatchOperand_Success;
2912 Index = matchHWRegsRegisterName(Identifier);
2914 Operands.push_back(MipsOperand::createHWRegsReg(
2915 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2916 return MatchOperand_Success;
2919 Index = matchFPURegisterName(Identifier);
2921 Operands.push_back(MipsOperand::createFGRReg(
2922 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2923 return MatchOperand_Success;
2926 Index = matchFCCRegisterName(Identifier);
2928 Operands.push_back(MipsOperand::createFCCReg(
2929 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2930 return MatchOperand_Success;
2933 Index = matchACRegisterName(Identifier);
2935 Operands.push_back(MipsOperand::createACCReg(
2936 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2937 return MatchOperand_Success;
2940 Index = matchMSA128RegisterName(Identifier);
2942 Operands.push_back(MipsOperand::createMSA128Reg(
2943 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2944 return MatchOperand_Success;
2947 Index = matchMSA128CtrlRegisterName(Identifier);
2949 Operands.push_back(MipsOperand::createMSACtrlReg(
2950 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2951 return MatchOperand_Success;
2954 return MatchOperand_NoMatch;
2957 MipsAsmParser::OperandMatchResultTy
2958 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2959 MCAsmParser &Parser = getParser();
2960 auto Token = Parser.getLexer().peekTok(false);
2962 if (Token.is(AsmToken::Identifier)) {
2963 DEBUG(dbgs() << ".. identifier\n");
2964 StringRef Identifier = Token.getIdentifier();
2965 OperandMatchResultTy ResTy =
2966 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2968 } else if (Token.is(AsmToken::Integer)) {
2969 DEBUG(dbgs() << ".. integer\n");
2970 Operands.push_back(MipsOperand::createNumericReg(
2971 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2973 return MatchOperand_Success;
2976 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2978 return MatchOperand_NoMatch;
2981 MipsAsmParser::OperandMatchResultTy
2982 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
2983 MCAsmParser &Parser = getParser();
2984 DEBUG(dbgs() << "parseAnyRegister\n");
2986 auto Token = Parser.getTok();
2988 SMLoc S = Token.getLoc();
2990 if (Token.isNot(AsmToken::Dollar)) {
2991 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2992 if (Token.is(AsmToken::Identifier)) {
2993 if (searchSymbolAlias(Operands))
2994 return MatchOperand_Success;
2996 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2997 return MatchOperand_NoMatch;
2999 DEBUG(dbgs() << ".. $\n");
3001 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
3002 if (ResTy == MatchOperand_Success) {
3004 Parser.Lex(); // identifier
3009 MipsAsmParser::OperandMatchResultTy
3010 MipsAsmParser::parseImm(OperandVector &Operands) {
3011 MCAsmParser &Parser = getParser();
3012 switch (getLexer().getKind()) {
3014 return MatchOperand_NoMatch;
3015 case AsmToken::LParen:
3016 case AsmToken::Minus:
3017 case AsmToken::Plus:
3018 case AsmToken::Integer:
3019 case AsmToken::Tilde:
3020 case AsmToken::String:
3024 const MCExpr *IdVal;
3025 SMLoc S = Parser.getTok().getLoc();
3026 if (getParser().parseExpression(IdVal))
3027 return MatchOperand_ParseFail;
3029 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3030 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3031 return MatchOperand_Success;
3034 MipsAsmParser::OperandMatchResultTy
3035 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
3036 MCAsmParser &Parser = getParser();
3037 DEBUG(dbgs() << "parseJumpTarget\n");
3039 SMLoc S = getLexer().getLoc();
3041 // Integers and expressions are acceptable
3042 OperandMatchResultTy ResTy = parseImm(Operands);
3043 if (ResTy != MatchOperand_NoMatch)
3046 // Registers are a valid target and have priority over symbols.
3047 ResTy = parseAnyRegister(Operands);
3048 if (ResTy != MatchOperand_NoMatch)
3051 const MCExpr *Expr = nullptr;
3052 if (Parser.parseExpression(Expr)) {
3053 // We have no way of knowing if a symbol was consumed so we must ParseFail
3054 return MatchOperand_ParseFail;
3057 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
3058 return MatchOperand_Success;
3061 MipsAsmParser::OperandMatchResultTy
3062 MipsAsmParser::parseInvNum(OperandVector &Operands) {
3063 MCAsmParser &Parser = getParser();
3064 const MCExpr *IdVal;
3065 // If the first token is '$' we may have register operand.
3066 if (Parser.getTok().is(AsmToken::Dollar))
3067 return MatchOperand_NoMatch;
3068 SMLoc S = Parser.getTok().getLoc();
3069 if (getParser().parseExpression(IdVal))
3070 return MatchOperand_ParseFail;
3071 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
3072 assert(MCE && "Unexpected MCExpr type.");
3073 int64_t Val = MCE->getValue();
3074 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3075 Operands.push_back(MipsOperand::CreateImm(
3076 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
3077 return MatchOperand_Success;
3080 MipsAsmParser::OperandMatchResultTy
3081 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
3082 MCAsmParser &Parser = getParser();
3083 switch (getLexer().getKind()) {
3085 return MatchOperand_NoMatch;
3086 case AsmToken::LParen:
3087 case AsmToken::Plus:
3088 case AsmToken::Minus:
3089 case AsmToken::Integer:
3094 SMLoc S = Parser.getTok().getLoc();
3096 if (getParser().parseExpression(Expr))
3097 return MatchOperand_ParseFail;
3100 if (!Expr->evaluateAsAbsolute(Val)) {
3101 Error(S, "expected immediate value");
3102 return MatchOperand_ParseFail;
3105 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
3106 // and because the CPU always adds one to the immediate field, the allowed
3107 // range becomes 1..4. We'll only check the range here and will deal
3108 // with the addition/subtraction when actually decoding/encoding
3110 if (Val < 1 || Val > 4) {
3111 Error(S, "immediate not in range (1..4)");
3112 return MatchOperand_ParseFail;
3116 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
3117 return MatchOperand_Success;
3120 MipsAsmParser::OperandMatchResultTy
3121 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3122 MCAsmParser &Parser = getParser();
3123 SmallVector<unsigned, 10> Regs;
3125 unsigned PrevReg = Mips::NoRegister;
3126 bool RegRange = false;
3127 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3129 if (Parser.getTok().isNot(AsmToken::Dollar))
3130 return MatchOperand_ParseFail;
3132 SMLoc S = Parser.getTok().getLoc();
3133 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3134 SMLoc E = getLexer().getLoc();
3135 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3136 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3138 // Remove last register operand because registers from register range
3139 // should be inserted first.
3140 if (RegNo == Mips::RA) {
3141 Regs.push_back(RegNo);
3143 unsigned TmpReg = PrevReg + 1;
3144 while (TmpReg <= RegNo) {
3145 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3146 Error(E, "invalid register operand");
3147 return MatchOperand_ParseFail;
3151 Regs.push_back(TmpReg++);
3157 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
3158 (RegNo != Mips::RA)) {
3159 Error(E, "$16 or $31 expected");
3160 return MatchOperand_ParseFail;
3161 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
3162 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3163 Error(E, "invalid register operand");
3164 return MatchOperand_ParseFail;
3165 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
3166 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3167 Error(E, "consecutive register numbers expected");
3168 return MatchOperand_ParseFail;
3171 Regs.push_back(RegNo);
3174 if (Parser.getTok().is(AsmToken::Minus))
3177 if (!Parser.getTok().isNot(AsmToken::Minus) &&
3178 !Parser.getTok().isNot(AsmToken::Comma)) {
3179 Error(E, "',' or '-' expected");
3180 return MatchOperand_ParseFail;
3183 Lex(); // Consume comma or minus
3184 if (Parser.getTok().isNot(AsmToken::Dollar))
3190 SMLoc E = Parser.getTok().getLoc();
3191 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3192 parseMemOperand(Operands);
3193 return MatchOperand_Success;
3196 MipsAsmParser::OperandMatchResultTy
3197 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
3198 MCAsmParser &Parser = getParser();
3200 SMLoc S = Parser.getTok().getLoc();
3201 if (parseAnyRegister(Operands) != MatchOperand_Success)
3202 return MatchOperand_ParseFail;
3204 SMLoc E = Parser.getTok().getLoc();
3205 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
3206 unsigned Reg = Op.getGPR32Reg();
3207 Operands.pop_back();
3208 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
3209 return MatchOperand_Success;
3212 MipsAsmParser::OperandMatchResultTy
3213 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
3214 MCAsmParser &Parser = getParser();
3215 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3216 SmallVector<unsigned, 10> Regs;
3218 if (Parser.getTok().isNot(AsmToken::Dollar))
3219 return MatchOperand_ParseFail;
3221 SMLoc S = Parser.getTok().getLoc();
3223 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3224 return MatchOperand_ParseFail;
3226 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3227 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3228 Regs.push_back(RegNo);
3230 SMLoc E = Parser.getTok().getLoc();
3231 if (Parser.getTok().isNot(AsmToken::Comma)) {
3232 Error(E, "',' expected");
3233 return MatchOperand_ParseFail;
3239 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3240 return MatchOperand_ParseFail;
3242 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3243 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3244 Regs.push_back(RegNo);
3246 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3248 return MatchOperand_Success;
3251 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
3253 MCSymbolRefExpr::VariantKind VK =
3254 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
3255 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
3256 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
3257 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
3258 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
3259 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
3260 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
3261 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
3262 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
3263 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
3264 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
3265 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
3266 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
3267 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
3268 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
3269 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
3270 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
3271 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
3272 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
3273 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
3274 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
3275 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
3276 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
3277 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
3278 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
3279 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
3280 .Default(MCSymbolRefExpr::VK_None);
3282 assert(VK != MCSymbolRefExpr::VK_None);
3287 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
3289 /// ::= '(', register, ')'
3290 /// handle it before we iterate so we don't get tripped up by the lack of
3292 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
3293 MCAsmParser &Parser = getParser();
3294 if (getLexer().is(AsmToken::LParen)) {
3296 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
3298 if (parseOperand(Operands, Name)) {
3299 SMLoc Loc = getLexer().getLoc();
3300 Parser.eatToEndOfStatement();
3301 return Error(Loc, "unexpected token in argument list");
3303 if (Parser.getTok().isNot(AsmToken::RParen)) {
3304 SMLoc Loc = getLexer().getLoc();
3305 Parser.eatToEndOfStatement();
3306 return Error(Loc, "unexpected token, expected ')'");
3309 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
3315 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
3316 /// either one of these.
3317 /// ::= '[', register, ']'
3318 /// ::= '[', integer, ']'
3319 /// handle it before we iterate so we don't get tripped up by the lack of
3321 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
3322 OperandVector &Operands) {
3323 MCAsmParser &Parser = getParser();
3324 if (getLexer().is(AsmToken::LBrac)) {
3326 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
3328 if (parseOperand(Operands, Name)) {
3329 SMLoc Loc = getLexer().getLoc();
3330 Parser.eatToEndOfStatement();
3331 return Error(Loc, "unexpected token in argument list");
3333 if (Parser.getTok().isNot(AsmToken::RBrac)) {
3334 SMLoc Loc = getLexer().getLoc();
3335 Parser.eatToEndOfStatement();
3336 return Error(Loc, "unexpected token, expected ']'");
3339 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
3345 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
3346 SMLoc NameLoc, OperandVector &Operands) {
3347 MCAsmParser &Parser = getParser();
3348 DEBUG(dbgs() << "ParseInstruction\n");
3350 // We have reached first instruction, module directive are now forbidden.
3351 getTargetStreamer().forbidModuleDirective();
3353 // Check if we have valid mnemonic
3354 if (!mnemonicIsValid(Name, 0)) {
3355 Parser.eatToEndOfStatement();
3356 return Error(NameLoc, "unknown instruction");
3358 // First operand in MCInst is instruction mnemonic.
3359 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
3361 // Read the remaining operands.
3362 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3363 // Read the first operand.
3364 if (parseOperand(Operands, Name)) {
3365 SMLoc Loc = getLexer().getLoc();
3366 Parser.eatToEndOfStatement();
3367 return Error(Loc, "unexpected token in argument list");
3369 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
3371 // AFAIK, parenthesis suffixes are never on the first operand
3373 while (getLexer().is(AsmToken::Comma)) {
3374 Parser.Lex(); // Eat the comma.
3375 // Parse and remember the operand.
3376 if (parseOperand(Operands, Name)) {
3377 SMLoc Loc = getLexer().getLoc();
3378 Parser.eatToEndOfStatement();
3379 return Error(Loc, "unexpected token in argument list");
3381 // Parse bracket and parenthesis suffixes before we iterate
3382 if (getLexer().is(AsmToken::LBrac)) {
3383 if (parseBracketSuffix(Name, Operands))
3385 } else if (getLexer().is(AsmToken::LParen) &&
3386 parseParenSuffix(Name, Operands))
3390 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3391 SMLoc Loc = getLexer().getLoc();
3392 Parser.eatToEndOfStatement();
3393 return Error(Loc, "unexpected token in argument list");
3395 Parser.Lex(); // Consume the EndOfStatement.
3399 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
3400 MCAsmParser &Parser = getParser();
3401 SMLoc Loc = getLexer().getLoc();
3402 Parser.eatToEndOfStatement();
3403 return Error(Loc, ErrorMsg);
3406 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
3407 return Error(Loc, ErrorMsg);
3410 bool MipsAsmParser::parseSetNoAtDirective() {
3411 MCAsmParser &Parser = getParser();
3412 // Line should look like: ".set noat".
3414 // Set the $at register to $0.
3415 AssemblerOptions.back()->setATRegIndex(0);
3417 Parser.Lex(); // Eat "noat".
3419 // If this is not the end of the statement, report an error.
3420 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3421 reportParseError("unexpected token, expected end of statement");
3425 getTargetStreamer().emitDirectiveSetNoAt();
3426 Parser.Lex(); // Consume the EndOfStatement.
3430 bool MipsAsmParser::parseSetAtDirective() {
3431 // Line can be: ".set at", which sets $at to $1
3432 // or ".set at=$reg", which sets $at to $reg.
3433 MCAsmParser &Parser = getParser();
3434 Parser.Lex(); // Eat "at".
3436 if (getLexer().is(AsmToken::EndOfStatement)) {
3437 // No register was specified, so we set $at to $1.
3438 AssemblerOptions.back()->setATRegIndex(1);
3440 getTargetStreamer().emitDirectiveSetAt();
3441 Parser.Lex(); // Consume the EndOfStatement.
3445 if (getLexer().isNot(AsmToken::Equal)) {
3446 reportParseError("unexpected token, expected equals sign");
3449 Parser.Lex(); // Eat "=".
3451 if (getLexer().isNot(AsmToken::Dollar)) {
3452 if (getLexer().is(AsmToken::EndOfStatement)) {
3453 reportParseError("no register specified");
3456 reportParseError("unexpected token, expected dollar sign '$'");
3460 Parser.Lex(); // Eat "$".
3462 // Find out what "reg" is.
3464 const AsmToken &Reg = Parser.getTok();
3465 if (Reg.is(AsmToken::Identifier)) {
3466 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
3467 } else if (Reg.is(AsmToken::Integer)) {
3468 AtRegNo = Reg.getIntVal();
3470 reportParseError("unexpected token, expected identifier or integer");
3474 // Check if $reg is a valid register. If it is, set $at to $reg.
3475 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
3476 reportParseError("invalid register");
3479 Parser.Lex(); // Eat "reg".
3481 // If this is not the end of the statement, report an error.
3482 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3483 reportParseError("unexpected token, expected end of statement");
3487 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
3489 Parser.Lex(); // Consume the EndOfStatement.
3493 bool MipsAsmParser::parseSetReorderDirective() {
3494 MCAsmParser &Parser = getParser();
3496 // If this is not the end of the statement, report an error.
3497 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3498 reportParseError("unexpected token, expected end of statement");
3501 AssemblerOptions.back()->setReorder();
3502 getTargetStreamer().emitDirectiveSetReorder();
3503 Parser.Lex(); // Consume the EndOfStatement.
3507 bool MipsAsmParser::parseSetNoReorderDirective() {
3508 MCAsmParser &Parser = getParser();
3510 // If this is not the end of the statement, report an error.
3511 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3512 reportParseError("unexpected token, expected end of statement");
3515 AssemblerOptions.back()->setNoReorder();
3516 getTargetStreamer().emitDirectiveSetNoReorder();
3517 Parser.Lex(); // Consume the EndOfStatement.
3521 bool MipsAsmParser::parseSetMacroDirective() {
3522 MCAsmParser &Parser = getParser();
3524 // If this is not the end of the statement, report an error.
3525 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3526 reportParseError("unexpected token, expected end of statement");
3529 AssemblerOptions.back()->setMacro();
3530 getTargetStreamer().emitDirectiveSetMacro();
3531 Parser.Lex(); // Consume the EndOfStatement.
3535 bool MipsAsmParser::parseSetNoMacroDirective() {
3536 MCAsmParser &Parser = getParser();
3538 // If this is not the end of the statement, report an error.
3539 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3540 reportParseError("unexpected token, expected end of statement");
3543 if (AssemblerOptions.back()->isReorder()) {
3544 reportParseError("`noreorder' must be set before `nomacro'");
3547 AssemblerOptions.back()->setNoMacro();
3548 getTargetStreamer().emitDirectiveSetNoMacro();
3549 Parser.Lex(); // Consume the EndOfStatement.
3553 bool MipsAsmParser::parseSetMsaDirective() {
3554 MCAsmParser &Parser = getParser();
3557 // If this is not the end of the statement, report an error.
3558 if (getLexer().isNot(AsmToken::EndOfStatement))
3559 return reportParseError("unexpected token, expected end of statement");
3561 setFeatureBits(Mips::FeatureMSA, "msa");
3562 getTargetStreamer().emitDirectiveSetMsa();
3566 bool MipsAsmParser::parseSetNoMsaDirective() {
3567 MCAsmParser &Parser = getParser();
3570 // If this is not the end of the statement, report an error.
3571 if (getLexer().isNot(AsmToken::EndOfStatement))
3572 return reportParseError("unexpected token, expected end of statement");
3574 clearFeatureBits(Mips::FeatureMSA, "msa");
3575 getTargetStreamer().emitDirectiveSetNoMsa();
3579 bool MipsAsmParser::parseSetNoDspDirective() {
3580 MCAsmParser &Parser = getParser();
3581 Parser.Lex(); // Eat "nodsp".
3583 // If this is not the end of the statement, report an error.
3584 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3585 reportParseError("unexpected token, expected end of statement");
3589 clearFeatureBits(Mips::FeatureDSP, "dsp");
3590 getTargetStreamer().emitDirectiveSetNoDsp();
3594 bool MipsAsmParser::parseSetMips16Directive() {
3595 MCAsmParser &Parser = getParser();
3596 Parser.Lex(); // Eat "mips16".
3598 // If this is not the end of the statement, report an error.
3599 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3600 reportParseError("unexpected token, expected end of statement");
3604 setFeatureBits(Mips::FeatureMips16, "mips16");
3605 getTargetStreamer().emitDirectiveSetMips16();
3606 Parser.Lex(); // Consume the EndOfStatement.
3610 bool MipsAsmParser::parseSetNoMips16Directive() {
3611 MCAsmParser &Parser = getParser();
3612 Parser.Lex(); // Eat "nomips16".
3614 // If this is not the end of the statement, report an error.
3615 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3616 reportParseError("unexpected token, expected end of statement");
3620 clearFeatureBits(Mips::FeatureMips16, "mips16");
3621 getTargetStreamer().emitDirectiveSetNoMips16();
3622 Parser.Lex(); // Consume the EndOfStatement.
3626 bool MipsAsmParser::parseSetFpDirective() {
3627 MCAsmParser &Parser = getParser();
3628 MipsABIFlagsSection::FpABIKind FpAbiVal;
3629 // Line can be: .set fp=32
3632 Parser.Lex(); // Eat fp token
3633 AsmToken Tok = Parser.getTok();
3634 if (Tok.isNot(AsmToken::Equal)) {
3635 reportParseError("unexpected token, expected equals sign '='");
3638 Parser.Lex(); // Eat '=' token.
3639 Tok = Parser.getTok();
3641 if (!parseFpABIValue(FpAbiVal, ".set"))
3644 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3645 reportParseError("unexpected token, expected end of statement");
3648 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
3649 Parser.Lex(); // Consume the EndOfStatement.
3653 bool MipsAsmParser::parseSetPopDirective() {
3654 MCAsmParser &Parser = getParser();
3655 SMLoc Loc = getLexer().getLoc();
3658 if (getLexer().isNot(AsmToken::EndOfStatement))
3659 return reportParseError("unexpected token, expected end of statement");
3661 // Always keep an element on the options "stack" to prevent the user
3662 // from changing the initial options. This is how we remember them.
3663 if (AssemblerOptions.size() == 2)
3664 return reportParseError(Loc, ".set pop with no .set push");
3666 AssemblerOptions.pop_back();
3667 setAvailableFeatures(AssemblerOptions.back()->getFeatures());
3669 getTargetStreamer().emitDirectiveSetPop();
3673 bool MipsAsmParser::parseSetPushDirective() {
3674 MCAsmParser &Parser = getParser();
3676 if (getLexer().isNot(AsmToken::EndOfStatement))
3677 return reportParseError("unexpected token, expected end of statement");
3679 // Create a copy of the current assembler options environment and push it.
3680 AssemblerOptions.push_back(
3681 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
3683 getTargetStreamer().emitDirectiveSetPush();
3687 bool MipsAsmParser::parseSetSoftFloatDirective() {
3688 MCAsmParser &Parser = getParser();
3690 if (getLexer().isNot(AsmToken::EndOfStatement))
3691 return reportParseError("unexpected token, expected end of statement");
3693 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
3694 getTargetStreamer().emitDirectiveSetSoftFloat();
3698 bool MipsAsmParser::parseSetHardFloatDirective() {
3699 MCAsmParser &Parser = getParser();
3701 if (getLexer().isNot(AsmToken::EndOfStatement))
3702 return reportParseError("unexpected token, expected end of statement");
3704 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
3705 getTargetStreamer().emitDirectiveSetHardFloat();
3709 bool MipsAsmParser::parseSetAssignment() {
3711 const MCExpr *Value;
3712 MCAsmParser &Parser = getParser();
3714 if (Parser.parseIdentifier(Name))
3715 reportParseError("expected identifier after .set");
3717 if (getLexer().isNot(AsmToken::Comma))
3718 return reportParseError("unexpected token, expected comma");
3721 if (Parser.parseExpression(Value))
3722 return reportParseError("expected valid expression after comma");
3724 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
3725 Sym->setVariableValue(Value);
3730 bool MipsAsmParser::parseSetMips0Directive() {
3731 MCAsmParser &Parser = getParser();
3733 if (getLexer().isNot(AsmToken::EndOfStatement))
3734 return reportParseError("unexpected token, expected end of statement");
3736 // Reset assembler options to their initial values.
3737 setAvailableFeatures(AssemblerOptions.front()->getFeatures());
3738 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
3740 getTargetStreamer().emitDirectiveSetMips0();
3744 bool MipsAsmParser::parseSetArchDirective() {
3745 MCAsmParser &Parser = getParser();
3747 if (getLexer().isNot(AsmToken::Equal))
3748 return reportParseError("unexpected token, expected equals sign");
3752 if (Parser.parseIdentifier(Arch))
3753 return reportParseError("expected arch identifier");
3755 StringRef ArchFeatureName =
3756 StringSwitch<StringRef>(Arch)
3757 .Case("mips1", "mips1")
3758 .Case("mips2", "mips2")
3759 .Case("mips3", "mips3")
3760 .Case("mips4", "mips4")
3761 .Case("mips5", "mips5")
3762 .Case("mips32", "mips32")
3763 .Case("mips32r2", "mips32r2")
3764 .Case("mips32r3", "mips32r3")
3765 .Case("mips32r5", "mips32r5")
3766 .Case("mips32r6", "mips32r6")
3767 .Case("mips64", "mips64")
3768 .Case("mips64r2", "mips64r2")
3769 .Case("mips64r3", "mips64r3")
3770 .Case("mips64r5", "mips64r5")
3771 .Case("mips64r6", "mips64r6")
3772 .Case("cnmips", "cnmips")
3773 .Case("r4000", "mips3") // This is an implementation of Mips3.
3776 if (ArchFeatureName.empty())
3777 return reportParseError("unsupported architecture");
3779 selectArch(ArchFeatureName);
3780 getTargetStreamer().emitDirectiveSetArch(Arch);
3784 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
3785 MCAsmParser &Parser = getParser();
3787 if (getLexer().isNot(AsmToken::EndOfStatement))
3788 return reportParseError("unexpected token, expected end of statement");
3792 llvm_unreachable("Unimplemented feature");
3793 case Mips::FeatureDSP:
3794 setFeatureBits(Mips::FeatureDSP, "dsp");
3795 getTargetStreamer().emitDirectiveSetDsp();
3797 case Mips::FeatureMicroMips:
3798 getTargetStreamer().emitDirectiveSetMicroMips();
3800 case Mips::FeatureMips1:
3801 selectArch("mips1");
3802 getTargetStreamer().emitDirectiveSetMips1();
3804 case Mips::FeatureMips2:
3805 selectArch("mips2");
3806 getTargetStreamer().emitDirectiveSetMips2();
3808 case Mips::FeatureMips3:
3809 selectArch("mips3");
3810 getTargetStreamer().emitDirectiveSetMips3();
3812 case Mips::FeatureMips4:
3813 selectArch("mips4");
3814 getTargetStreamer().emitDirectiveSetMips4();
3816 case Mips::FeatureMips5:
3817 selectArch("mips5");
3818 getTargetStreamer().emitDirectiveSetMips5();
3820 case Mips::FeatureMips32:
3821 selectArch("mips32");
3822 getTargetStreamer().emitDirectiveSetMips32();
3824 case Mips::FeatureMips32r2:
3825 selectArch("mips32r2");
3826 getTargetStreamer().emitDirectiveSetMips32R2();
3828 case Mips::FeatureMips32r3:
3829 selectArch("mips32r3");
3830 getTargetStreamer().emitDirectiveSetMips32R3();
3832 case Mips::FeatureMips32r5:
3833 selectArch("mips32r5");
3834 getTargetStreamer().emitDirectiveSetMips32R5();
3836 case Mips::FeatureMips32r6:
3837 selectArch("mips32r6");
3838 getTargetStreamer().emitDirectiveSetMips32R6();
3840 case Mips::FeatureMips64:
3841 selectArch("mips64");
3842 getTargetStreamer().emitDirectiveSetMips64();
3844 case Mips::FeatureMips64r2:
3845 selectArch("mips64r2");
3846 getTargetStreamer().emitDirectiveSetMips64R2();
3848 case Mips::FeatureMips64r3:
3849 selectArch("mips64r3");
3850 getTargetStreamer().emitDirectiveSetMips64R3();
3852 case Mips::FeatureMips64r5:
3853 selectArch("mips64r5");
3854 getTargetStreamer().emitDirectiveSetMips64R5();
3856 case Mips::FeatureMips64r6:
3857 selectArch("mips64r6");
3858 getTargetStreamer().emitDirectiveSetMips64R6();
3864 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
3865 MCAsmParser &Parser = getParser();
3866 if (getLexer().isNot(AsmToken::Comma)) {
3867 SMLoc Loc = getLexer().getLoc();
3868 Parser.eatToEndOfStatement();
3869 return Error(Loc, ErrorStr);
3872 Parser.Lex(); // Eat the comma.
3876 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
3877 if (AssemblerOptions.back()->isReorder())
3878 Warning(Loc, ".cpload should be inside a noreorder section");
3880 if (inMips16Mode()) {
3881 reportParseError(".cpload is not supported in Mips16 mode");
3885 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
3886 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
3887 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3888 reportParseError("expected register containing function address");
3892 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
3893 if (!RegOpnd.isGPRAsmReg()) {
3894 reportParseError(RegOpnd.getStartLoc(), "invalid register");
3898 // If this is not the end of the statement, report an error.
3899 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3900 reportParseError("unexpected token, expected end of statement");
3904 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
3908 bool MipsAsmParser::parseDirectiveCPSetup() {
3909 MCAsmParser &Parser = getParser();
3912 bool SaveIsReg = true;
3914 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3915 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3916 if (ResTy == MatchOperand_NoMatch) {
3917 reportParseError("expected register containing function address");
3918 Parser.eatToEndOfStatement();
3922 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3923 if (!FuncRegOpnd.isGPRAsmReg()) {
3924 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
3925 Parser.eatToEndOfStatement();
3929 FuncReg = FuncRegOpnd.getGPR32Reg();
3932 if (!eatComma("unexpected token, expected comma"))
3935 ResTy = parseAnyRegister(TmpReg);
3936 if (ResTy == MatchOperand_NoMatch) {
3937 const AsmToken &Tok = Parser.getTok();
3938 if (Tok.is(AsmToken::Integer)) {
3939 Save = Tok.getIntVal();
3943 reportParseError("expected save register or stack offset");
3944 Parser.eatToEndOfStatement();
3948 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3949 if (!SaveOpnd.isGPRAsmReg()) {
3950 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
3951 Parser.eatToEndOfStatement();
3954 Save = SaveOpnd.getGPR32Reg();
3957 if (!eatComma("unexpected token, expected comma"))
3961 if (Parser.parseExpression(Expr)) {
3962 reportParseError("expected expression");
3966 if (Expr->getKind() != MCExpr::SymbolRef) {
3967 reportParseError("expected symbol");
3970 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3972 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
3977 bool MipsAsmParser::parseDirectiveNaN() {
3978 MCAsmParser &Parser = getParser();
3979 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3980 const AsmToken &Tok = Parser.getTok();
3982 if (Tok.getString() == "2008") {
3984 getTargetStreamer().emitDirectiveNaN2008();
3986 } else if (Tok.getString() == "legacy") {
3988 getTargetStreamer().emitDirectiveNaNLegacy();
3992 // If we don't recognize the option passed to the .nan
3993 // directive (e.g. no option or unknown option), emit an error.
3994 reportParseError("invalid option in .nan directive");
3998 bool MipsAsmParser::parseDirectiveSet() {
3999 MCAsmParser &Parser = getParser();
4000 // Get the next token.
4001 const AsmToken &Tok = Parser.getTok();
4003 if (Tok.getString() == "noat") {
4004 return parseSetNoAtDirective();
4005 } else if (Tok.getString() == "at") {
4006 return parseSetAtDirective();
4007 } else if (Tok.getString() == "arch") {
4008 return parseSetArchDirective();
4009 } else if (Tok.getString() == "fp") {
4010 return parseSetFpDirective();
4011 } else if (Tok.getString() == "pop") {
4012 return parseSetPopDirective();
4013 } else if (Tok.getString() == "push") {
4014 return parseSetPushDirective();
4015 } else if (Tok.getString() == "reorder") {
4016 return parseSetReorderDirective();
4017 } else if (Tok.getString() == "noreorder") {
4018 return parseSetNoReorderDirective();
4019 } else if (Tok.getString() == "macro") {
4020 return parseSetMacroDirective();
4021 } else if (Tok.getString() == "nomacro") {
4022 return parseSetNoMacroDirective();
4023 } else if (Tok.getString() == "mips16") {
4024 return parseSetMips16Directive();
4025 } else if (Tok.getString() == "nomips16") {
4026 return parseSetNoMips16Directive();
4027 } else if (Tok.getString() == "nomicromips") {
4028 getTargetStreamer().emitDirectiveSetNoMicroMips();
4029 Parser.eatToEndOfStatement();
4031 } else if (Tok.getString() == "micromips") {
4032 return parseSetFeature(Mips::FeatureMicroMips);
4033 } else if (Tok.getString() == "mips0") {
4034 return parseSetMips0Directive();
4035 } else if (Tok.getString() == "mips1") {
4036 return parseSetFeature(Mips::FeatureMips1);
4037 } else if (Tok.getString() == "mips2") {
4038 return parseSetFeature(Mips::FeatureMips2);
4039 } else if (Tok.getString() == "mips3") {
4040 return parseSetFeature(Mips::FeatureMips3);
4041 } else if (Tok.getString() == "mips4") {
4042 return parseSetFeature(Mips::FeatureMips4);
4043 } else if (Tok.getString() == "mips5") {
4044 return parseSetFeature(Mips::FeatureMips5);
4045 } else if (Tok.getString() == "mips32") {
4046 return parseSetFeature(Mips::FeatureMips32);
4047 } else if (Tok.getString() == "mips32r2") {
4048 return parseSetFeature(Mips::FeatureMips32r2);
4049 } else if (Tok.getString() == "mips32r3") {
4050 return parseSetFeature(Mips::FeatureMips32r3);
4051 } else if (Tok.getString() == "mips32r5") {
4052 return parseSetFeature(Mips::FeatureMips32r5);
4053 } else if (Tok.getString() == "mips32r6") {
4054 return parseSetFeature(Mips::FeatureMips32r6);
4055 } else if (Tok.getString() == "mips64") {
4056 return parseSetFeature(Mips::FeatureMips64);
4057 } else if (Tok.getString() == "mips64r2") {
4058 return parseSetFeature(Mips::FeatureMips64r2);
4059 } else if (Tok.getString() == "mips64r3") {
4060 return parseSetFeature(Mips::FeatureMips64r3);
4061 } else if (Tok.getString() == "mips64r5") {
4062 return parseSetFeature(Mips::FeatureMips64r5);
4063 } else if (Tok.getString() == "mips64r6") {
4064 return parseSetFeature(Mips::FeatureMips64r6);
4065 } else if (Tok.getString() == "dsp") {
4066 return parseSetFeature(Mips::FeatureDSP);
4067 } else if (Tok.getString() == "nodsp") {
4068 return parseSetNoDspDirective();
4069 } else if (Tok.getString() == "msa") {
4070 return parseSetMsaDirective();
4071 } else if (Tok.getString() == "nomsa") {
4072 return parseSetNoMsaDirective();
4073 } else if (Tok.getString() == "softfloat") {
4074 return parseSetSoftFloatDirective();
4075 } else if (Tok.getString() == "hardfloat") {
4076 return parseSetHardFloatDirective();
4078 // It is just an identifier, look for an assignment.
4079 parseSetAssignment();
4086 /// parseDataDirective
4087 /// ::= .word [ expression (, expression)* ]
4088 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
4089 MCAsmParser &Parser = getParser();
4090 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4092 const MCExpr *Value;
4093 if (getParser().parseExpression(Value))
4096 getParser().getStreamer().EmitValue(Value, Size);
4098 if (getLexer().is(AsmToken::EndOfStatement))
4101 if (getLexer().isNot(AsmToken::Comma))
4102 return Error(L, "unexpected token, expected comma");
4111 /// parseDirectiveGpWord
4112 /// ::= .gpword local_sym
4113 bool MipsAsmParser::parseDirectiveGpWord() {
4114 MCAsmParser &Parser = getParser();
4115 const MCExpr *Value;
4116 // EmitGPRel32Value requires an expression, so we are using base class
4117 // method to evaluate the expression.
4118 if (getParser().parseExpression(Value))
4120 getParser().getStreamer().EmitGPRel32Value(Value);
4122 if (getLexer().isNot(AsmToken::EndOfStatement))
4123 return Error(getLexer().getLoc(),
4124 "unexpected token, expected end of statement");
4125 Parser.Lex(); // Eat EndOfStatement token.
4129 /// parseDirectiveGpDWord
4130 /// ::= .gpdword local_sym
4131 bool MipsAsmParser::parseDirectiveGpDWord() {
4132 MCAsmParser &Parser = getParser();
4133 const MCExpr *Value;
4134 // EmitGPRel64Value requires an expression, so we are using base class
4135 // method to evaluate the expression.
4136 if (getParser().parseExpression(Value))
4138 getParser().getStreamer().EmitGPRel64Value(Value);
4140 if (getLexer().isNot(AsmToken::EndOfStatement))
4141 return Error(getLexer().getLoc(),
4142 "unexpected token, expected end of statement");
4143 Parser.Lex(); // Eat EndOfStatement token.
4147 bool MipsAsmParser::parseDirectiveOption() {
4148 MCAsmParser &Parser = getParser();
4149 // Get the option token.
4150 AsmToken Tok = Parser.getTok();
4151 // At the moment only identifiers are supported.
4152 if (Tok.isNot(AsmToken::Identifier)) {
4153 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
4154 Parser.eatToEndOfStatement();
4158 StringRef Option = Tok.getIdentifier();
4160 if (Option == "pic0") {
4161 getTargetStreamer().emitDirectiveOptionPic0();
4163 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4164 Error(Parser.getTok().getLoc(),
4165 "unexpected token, expected end of statement");
4166 Parser.eatToEndOfStatement();
4171 if (Option == "pic2") {
4172 getTargetStreamer().emitDirectiveOptionPic2();
4174 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4175 Error(Parser.getTok().getLoc(),
4176 "unexpected token, expected end of statement");
4177 Parser.eatToEndOfStatement();
4183 Warning(Parser.getTok().getLoc(),
4184 "unknown option, expected 'pic0' or 'pic2'");
4185 Parser.eatToEndOfStatement();
4189 /// parseInsnDirective
4191 bool MipsAsmParser::parseInsnDirective() {
4192 // If this is not the end of the statement, report an error.
4193 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4194 reportParseError("unexpected token, expected end of statement");
4198 // The actual label marking happens in
4199 // MipsELFStreamer::createPendingLabelRelocs().
4200 getTargetStreamer().emitDirectiveInsn();
4202 getParser().Lex(); // Eat EndOfStatement token.
4206 /// parseDirectiveModule
4207 /// ::= .module oddspreg
4208 /// ::= .module nooddspreg
4209 /// ::= .module fp=value
4210 bool MipsAsmParser::parseDirectiveModule() {
4211 MCAsmParser &Parser = getParser();
4212 MCAsmLexer &Lexer = getLexer();
4213 SMLoc L = Lexer.getLoc();
4215 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
4216 // TODO : get a better message.
4217 reportParseError(".module directive must appear before any code");
4222 if (Parser.parseIdentifier(Option)) {
4223 reportParseError("expected .module option identifier");
4227 if (Option == "oddspreg") {
4228 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
4229 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4231 // If this is not the end of the statement, report an error.
4232 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4233 reportParseError("unexpected token, expected end of statement");
4237 return false; // parseDirectiveModule has finished successfully.
4238 } else if (Option == "nooddspreg") {
4240 Error(L, "'.module nooddspreg' requires the O32 ABI");
4244 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
4245 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4247 // If this is not the end of the statement, report an error.
4248 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4249 reportParseError("unexpected token, expected end of statement");
4253 return false; // parseDirectiveModule has finished successfully.
4254 } else if (Option == "fp") {
4255 return parseDirectiveModuleFP();
4257 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
4261 /// parseDirectiveModuleFP
4265 bool MipsAsmParser::parseDirectiveModuleFP() {
4266 MCAsmParser &Parser = getParser();
4267 MCAsmLexer &Lexer = getLexer();
4269 if (Lexer.isNot(AsmToken::Equal)) {
4270 reportParseError("unexpected token, expected equals sign '='");
4273 Parser.Lex(); // Eat '=' token.
4275 MipsABIFlagsSection::FpABIKind FpABI;
4276 if (!parseFpABIValue(FpABI, ".module"))
4279 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4280 reportParseError("unexpected token, expected end of statement");
4284 // Emit appropriate flags.
4285 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
4286 Parser.Lex(); // Consume the EndOfStatement.
4290 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
4291 StringRef Directive) {
4292 MCAsmParser &Parser = getParser();
4293 MCAsmLexer &Lexer = getLexer();
4295 if (Lexer.is(AsmToken::Identifier)) {
4296 StringRef Value = Parser.getTok().getString();
4299 if (Value != "xx") {
4300 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4305 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
4309 FpABI = MipsABIFlagsSection::FpABIKind::XX;
4313 if (Lexer.is(AsmToken::Integer)) {
4314 unsigned Value = Parser.getTok().getIntVal();
4317 if (Value != 32 && Value != 64) {
4318 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4324 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
4328 FpABI = MipsABIFlagsSection::FpABIKind::S32;
4330 FpABI = MipsABIFlagsSection::FpABIKind::S64;
4338 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
4339 MCAsmParser &Parser = getParser();
4340 StringRef IDVal = DirectiveID.getString();
4342 if (IDVal == ".cpload")
4343 return parseDirectiveCpLoad(DirectiveID.getLoc());
4344 if (IDVal == ".dword") {
4345 parseDataDirective(8, DirectiveID.getLoc());
4348 if (IDVal == ".ent") {
4349 StringRef SymbolName;
4351 if (Parser.parseIdentifier(SymbolName)) {
4352 reportParseError("expected identifier after .ent");
4356 // There's an undocumented extension that allows an integer to
4357 // follow the name of the procedure which AFAICS is ignored by GAS.
4358 // Example: .ent foo,2
4359 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4360 if (getLexer().isNot(AsmToken::Comma)) {
4361 // Even though we accept this undocumented extension for compatibility
4362 // reasons, the additional integer argument does not actually change
4363 // the behaviour of the '.ent' directive, so we would like to discourage
4364 // its use. We do this by not referring to the extended version in
4365 // error messages which are not directly related to its use.
4366 reportParseError("unexpected token, expected end of statement");
4369 Parser.Lex(); // Eat the comma.
4370 const MCExpr *DummyNumber;
4371 int64_t DummyNumberVal;
4372 // If the user was explicitly trying to use the extended version,
4373 // we still give helpful extension-related error messages.
4374 if (Parser.parseExpression(DummyNumber)) {
4375 reportParseError("expected number after comma");
4378 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
4379 reportParseError("expected an absolute expression after comma");
4384 // If this is not the end of the statement, report an error.
4385 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4386 reportParseError("unexpected token, expected end of statement");
4390 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
4392 getTargetStreamer().emitDirectiveEnt(*Sym);
4397 if (IDVal == ".end") {
4398 StringRef SymbolName;
4400 if (Parser.parseIdentifier(SymbolName)) {
4401 reportParseError("expected identifier after .end");
4405 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4406 reportParseError("unexpected token, expected end of statement");
4410 if (CurrentFn == nullptr) {
4411 reportParseError(".end used without .ent");
4415 if ((SymbolName != CurrentFn->getName())) {
4416 reportParseError(".end symbol does not match .ent symbol");
4420 getTargetStreamer().emitDirectiveEnd(SymbolName);
4421 CurrentFn = nullptr;
4425 if (IDVal == ".frame") {
4426 // .frame $stack_reg, frame_size_in_bytes, $return_reg
4427 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4428 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4429 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4430 reportParseError("expected stack register");
4434 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4435 if (!StackRegOpnd.isGPRAsmReg()) {
4436 reportParseError(StackRegOpnd.getStartLoc(),
4437 "expected general purpose register");
4440 unsigned StackReg = StackRegOpnd.getGPR32Reg();
4442 if (Parser.getTok().is(AsmToken::Comma))
4445 reportParseError("unexpected token, expected comma");
4449 // Parse the frame size.
4450 const MCExpr *FrameSize;
4451 int64_t FrameSizeVal;
4453 if (Parser.parseExpression(FrameSize)) {
4454 reportParseError("expected frame size value");
4458 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
4459 reportParseError("frame size not an absolute expression");
4463 if (Parser.getTok().is(AsmToken::Comma))
4466 reportParseError("unexpected token, expected comma");
4470 // Parse the return register.
4472 ResTy = parseAnyRegister(TmpReg);
4473 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4474 reportParseError("expected return register");
4478 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4479 if (!ReturnRegOpnd.isGPRAsmReg()) {
4480 reportParseError(ReturnRegOpnd.getStartLoc(),
4481 "expected general purpose register");
4485 // If this is not the end of the statement, report an error.
4486 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4487 reportParseError("unexpected token, expected end of statement");
4491 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
4492 ReturnRegOpnd.getGPR32Reg());
4496 if (IDVal == ".set") {
4497 return parseDirectiveSet();
4500 if (IDVal == ".mask" || IDVal == ".fmask") {
4501 // .mask bitmask, frame_offset
4502 // bitmask: One bit for each register used.
4503 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
4504 // first register is expected to be saved.
4506 // .mask 0x80000000, -4
4507 // .fmask 0x80000000, -4
4510 // Parse the bitmask
4511 const MCExpr *BitMask;
4514 if (Parser.parseExpression(BitMask)) {
4515 reportParseError("expected bitmask value");
4519 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
4520 reportParseError("bitmask not an absolute expression");
4524 if (Parser.getTok().is(AsmToken::Comma))
4527 reportParseError("unexpected token, expected comma");
4531 // Parse the frame_offset
4532 const MCExpr *FrameOffset;
4533 int64_t FrameOffsetVal;
4535 if (Parser.parseExpression(FrameOffset)) {
4536 reportParseError("expected frame offset value");
4540 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
4541 reportParseError("frame offset not an absolute expression");
4545 // If this is not the end of the statement, report an error.
4546 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4547 reportParseError("unexpected token, expected end of statement");
4551 if (IDVal == ".mask")
4552 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
4554 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
4558 if (IDVal == ".nan")
4559 return parseDirectiveNaN();
4561 if (IDVal == ".gpword") {
4562 parseDirectiveGpWord();
4566 if (IDVal == ".gpdword") {
4567 parseDirectiveGpDWord();
4571 if (IDVal == ".word") {
4572 parseDataDirective(4, DirectiveID.getLoc());
4576 if (IDVal == ".option")
4577 return parseDirectiveOption();
4579 if (IDVal == ".abicalls") {
4580 getTargetStreamer().emitDirectiveAbiCalls();
4581 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4582 Error(Parser.getTok().getLoc(),
4583 "unexpected token, expected end of statement");
4585 Parser.eatToEndOfStatement();
4590 if (IDVal == ".cpsetup")
4591 return parseDirectiveCPSetup();
4593 if (IDVal == ".module")
4594 return parseDirectiveModule();
4596 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
4597 return parseInternalDirectiveReallowModule();
4599 if (IDVal == ".insn")
4600 return parseInsnDirective();
4605 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
4606 // If this is not the end of the statement, report an error.
4607 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4608 reportParseError("unexpected token, expected end of statement");
4612 getTargetStreamer().reallowModuleDirective();
4614 getParser().Lex(); // Eat EndOfStatement token.
4618 extern "C" void LLVMInitializeMipsAsmParser() {
4619 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
4620 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
4621 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
4622 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
4625 #define GET_REGISTER_MATCHER
4626 #define GET_MATCHER_IMPLEMENTATION
4627 #include "MipsGenAsmMatcher.inc"