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 uint64_t AllArchRelatedMask =
82 Mips::FeatureMips1 | Mips::FeatureMips2 | Mips::FeatureMips3 |
83 Mips::FeatureMips3_32 | Mips::FeatureMips3_32r2 | Mips::FeatureMips4 |
84 Mips::FeatureMips4_32 | Mips::FeatureMips4_32r2 | Mips::FeatureMips5 |
85 Mips::FeatureMips5_32r2 | Mips::FeatureMips32 | Mips::FeatureMips32r2 |
86 Mips::FeatureMips32r3 | Mips::FeatureMips32r5 | Mips::FeatureMips32r6 |
87 Mips::FeatureMips64 | Mips::FeatureMips64r2 | Mips::FeatureMips64r3 |
88 Mips::FeatureMips64r5 | Mips::FeatureMips64r6 | Mips::FeatureCnMips |
89 Mips::FeatureFP64Bit | Mips::FeatureGP64Bit | Mips::FeatureNaN2008;
100 class MipsAsmParser : public MCTargetAsmParser {
101 MipsTargetStreamer &getTargetStreamer() {
102 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
103 return static_cast<MipsTargetStreamer &>(TS);
106 MCSubtargetInfo &STI;
108 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
109 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
110 // nullptr, which indicates that no function is currently
111 // selected. This usually happens after an '.end func'
114 // Print a warning along with its fix-it message at the given range.
115 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
116 SMRange Range, bool ShowColors = true);
118 #define GET_ASSEMBLER_HEADER
119 #include "MipsGenAsmMatcher.inc"
121 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
123 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
124 OperandVector &Operands, MCStreamer &Out,
126 bool MatchingInlineAsm) override;
128 /// Parse a register as used in CFI directives
129 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
131 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
133 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
135 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
136 SMLoc NameLoc, OperandVector &Operands) override;
138 bool ParseDirective(AsmToken DirectiveID) override;
140 MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
142 MipsAsmParser::OperandMatchResultTy
143 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
144 StringRef Identifier, SMLoc S);
146 MipsAsmParser::OperandMatchResultTy
147 matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
149 MipsAsmParser::OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
151 MipsAsmParser::OperandMatchResultTy parseImm(OperandVector &Operands);
153 MipsAsmParser::OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
155 MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
157 MipsAsmParser::OperandMatchResultTy parseLSAImm(OperandVector &Operands);
159 MipsAsmParser::OperandMatchResultTy
160 parseRegisterPair (OperandVector &Operands);
162 MipsAsmParser::OperandMatchResultTy
163 parseMovePRegPair(OperandVector &Operands);
165 MipsAsmParser::OperandMatchResultTy
166 parseRegisterList (OperandVector &Operands);
168 bool searchSymbolAlias(OperandVector &Operands);
170 bool parseOperand(OperandVector &, StringRef Mnemonic);
172 bool needsExpansion(MCInst &Inst);
174 // Expands assembly pseudo instructions.
175 // Returns false on success, true otherwise.
176 bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
177 SmallVectorImpl<MCInst> &Instructions);
179 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
180 SmallVectorImpl<MCInst> &Instructions);
182 bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
183 bool Is32BitImm, SMLoc IDLoc,
184 SmallVectorImpl<MCInst> &Instructions);
186 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
187 SmallVectorImpl<MCInst> &Instructions);
189 bool expandLoadAddressImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
190 SmallVectorImpl<MCInst> &Instructions);
192 bool expandLoadAddressReg(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
193 SmallVectorImpl<MCInst> &Instructions);
194 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
195 SmallVectorImpl<MCInst> &Instructions);
197 void expandLoadAddressSym(const MCOperand &DstRegOp, const MCOperand &SymOp,
198 bool Is32BitSym, SMLoc IDLoc,
199 SmallVectorImpl<MCInst> &Instructions);
201 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
202 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
205 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
206 SmallVectorImpl<MCInst> &Instructions);
208 void createNop(bool hasShortDelaySlot, SMLoc IDLoc,
209 SmallVectorImpl<MCInst> &Instructions);
211 void createAddu(unsigned DstReg, unsigned SrcReg, unsigned TrgReg,
212 SmallVectorImpl<MCInst> &Instructions);
214 bool reportParseError(Twine ErrorMsg);
215 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
217 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
218 bool parseRelocOperand(const MCExpr *&Res);
220 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
222 bool isEvaluated(const MCExpr *Expr);
223 bool parseSetMips0Directive();
224 bool parseSetArchDirective();
225 bool parseSetFeature(uint64_t Feature);
226 bool parseDirectiveCpLoad(SMLoc Loc);
227 bool parseDirectiveCPSetup();
228 bool parseDirectiveNaN();
229 bool parseDirectiveSet();
230 bool parseDirectiveOption();
231 bool parseInsnDirective();
233 bool parseSetAtDirective();
234 bool parseSetNoAtDirective();
235 bool parseSetMacroDirective();
236 bool parseSetNoMacroDirective();
237 bool parseSetMsaDirective();
238 bool parseSetNoMsaDirective();
239 bool parseSetNoDspDirective();
240 bool parseSetReorderDirective();
241 bool parseSetNoReorderDirective();
242 bool parseSetMips16Directive();
243 bool parseSetNoMips16Directive();
244 bool parseSetFpDirective();
245 bool parseSetPopDirective();
246 bool parseSetPushDirective();
248 bool parseSetAssignment();
250 bool parseDataDirective(unsigned Size, SMLoc L);
251 bool parseDirectiveGpWord();
252 bool parseDirectiveGpDWord();
253 bool parseDirectiveModule();
254 bool parseDirectiveModuleFP();
255 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
256 StringRef Directive);
258 bool parseInternalDirectiveReallowModule();
260 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
262 bool eatComma(StringRef ErrorStr);
264 int matchCPURegisterName(StringRef Symbol);
266 int matchHWRegsRegisterName(StringRef Symbol);
268 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
270 int matchFPURegisterName(StringRef Name);
272 int matchFCCRegisterName(StringRef Name);
274 int matchACRegisterName(StringRef Name);
276 int matchMSA128RegisterName(StringRef Name);
278 int matchMSA128CtrlRegisterName(StringRef Name);
280 unsigned getReg(int RC, int RegNo);
282 unsigned getGPR(int RegNo);
284 /// Returns the internal register number for the current AT. Also checks if
285 /// the current AT is unavailable (set to $0) and gives an error if it is.
286 /// This should be used in pseudo-instruction expansions which need AT.
287 unsigned getATReg(SMLoc Loc);
289 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
290 SmallVectorImpl<MCInst> &Instructions);
292 // Helper function that checks if the value of a vector index is within the
293 // boundaries of accepted values for each RegisterKind
294 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
295 bool validateMSAIndex(int Val, int RegKind);
297 // Selects a new architecture by updating the FeatureBits with the necessary
298 // info including implied dependencies.
299 // Internally, it clears all the feature bits related to *any* architecture
300 // and selects the new one using the ToggleFeature functionality of the
301 // MCSubtargetInfo object that handles implied dependencies. The reason we
302 // clear all the arch related bits manually is because ToggleFeature only
303 // clears the features that imply the feature being cleared and not the
304 // features implied by the feature being cleared. This is easier to see
306 // --------------------------------------------------
307 // | Feature | Implies |
308 // | -------------------------------------------------|
309 // | FeatureMips1 | None |
310 // | FeatureMips2 | FeatureMips1 |
311 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
312 // | FeatureMips4 | FeatureMips3 |
314 // --------------------------------------------------
316 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
317 // FeatureMipsGP64 | FeatureMips1)
318 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
319 void selectArch(StringRef ArchFeature) {
320 uint64_t FeatureBits = STI.getFeatureBits();
321 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
322 STI.setFeatureBits(FeatureBits);
323 setAvailableFeatures(
324 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
325 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
328 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
329 if (!(STI.getFeatureBits() & Feature)) {
330 setAvailableFeatures(
331 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
333 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
336 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
337 if (STI.getFeatureBits() & Feature) {
338 setAvailableFeatures(
339 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
341 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
345 enum MipsMatchResultTy {
346 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
347 #define GET_OPERAND_DIAGNOSTIC_TYPES
348 #include "MipsGenAsmMatcher.inc"
349 #undef GET_OPERAND_DIAGNOSTIC_TYPES
353 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
354 const MCInstrInfo &MII, const MCTargetOptions &Options)
355 : MCTargetAsmParser(), STI(sti),
356 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
357 sti.getCPU(), Options)) {
358 MCAsmParserExtension::Initialize(parser);
360 parser.addAliasForDirective(".asciiz", ".asciz");
362 // Initialize the set of available features.
363 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
365 // Remember the initial assembler options. The user can not modify these.
366 AssemblerOptions.push_back(
367 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
369 // Create an assembler options environment for the user to modify.
370 AssemblerOptions.push_back(
371 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
373 getTargetStreamer().updateABIInfo(*this);
375 if (!isABI_O32() && !useOddSPReg() != 0)
376 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
381 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
382 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
384 bool isGP64bit() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }
385 bool isFP64bit() const { return STI.getFeatureBits() & Mips::FeatureFP64Bit; }
386 const MipsABIInfo &getABI() const { return ABI; }
387 bool isABI_N32() const { return ABI.IsN32(); }
388 bool isABI_N64() const { return ABI.IsN64(); }
389 bool isABI_O32() const { return ABI.IsO32(); }
390 bool isABI_FPXX() const { return STI.getFeatureBits() & Mips::FeatureFPXX; }
392 bool useOddSPReg() const {
393 return !(STI.getFeatureBits() & Mips::FeatureNoOddSPReg);
396 bool inMicroMipsMode() const {
397 return STI.getFeatureBits() & Mips::FeatureMicroMips;
399 bool hasMips1() const { return STI.getFeatureBits() & Mips::FeatureMips1; }
400 bool hasMips2() const { return STI.getFeatureBits() & Mips::FeatureMips2; }
401 bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; }
402 bool hasMips4() const { return STI.getFeatureBits() & Mips::FeatureMips4; }
403 bool hasMips5() const { return STI.getFeatureBits() & Mips::FeatureMips5; }
404 bool hasMips32() const {
405 return (STI.getFeatureBits() & Mips::FeatureMips32);
407 bool hasMips64() const {
408 return (STI.getFeatureBits() & Mips::FeatureMips64);
410 bool hasMips32r2() const {
411 return (STI.getFeatureBits() & Mips::FeatureMips32r2);
413 bool hasMips64r2() const {
414 return (STI.getFeatureBits() & Mips::FeatureMips64r2);
416 bool hasMips32r3() const {
417 return (STI.getFeatureBits() & Mips::FeatureMips32r3);
419 bool hasMips64r3() const {
420 return (STI.getFeatureBits() & Mips::FeatureMips64r3);
422 bool hasMips32r5() const {
423 return (STI.getFeatureBits() & Mips::FeatureMips32r5);
425 bool hasMips64r5() const {
426 return (STI.getFeatureBits() & Mips::FeatureMips64r5);
428 bool hasMips32r6() const {
429 return (STI.getFeatureBits() & Mips::FeatureMips32r6);
431 bool hasMips64r6() const {
432 return (STI.getFeatureBits() & Mips::FeatureMips64r6);
434 bool hasCnMips() const {
435 return (STI.getFeatureBits() & Mips::FeatureCnMips);
437 bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); }
438 bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); }
439 bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); }
441 bool inMips16Mode() const {
442 return STI.getFeatureBits() & Mips::FeatureMips16;
445 bool useSoftFloat() const {
446 return (STI.getFeatureBits() & Mips::FeatureSoftFloat);
449 /// Warn if RegIndex is the same as the current AT.
450 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
452 void warnIfNoMacro(SMLoc Loc);
458 /// MipsOperand - Instances of this class represent a parsed Mips machine
460 class MipsOperand : public MCParsedAsmOperand {
462 /// Broad categories of register classes
463 /// The exact class is finalized by the render method.
465 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
466 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
468 RegKind_FCC = 4, /// FCC
469 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
470 RegKind_MSACtrl = 16, /// MSA control registers
471 RegKind_COP2 = 32, /// COP2
472 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
474 RegKind_CCR = 128, /// CCR
475 RegKind_HWRegs = 256, /// HWRegs
476 RegKind_COP3 = 512, /// COP3
478 /// Potentially any (e.g. $1)
479 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
480 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
481 RegKind_CCR | RegKind_HWRegs | RegKind_COP3
486 k_Immediate, /// An immediate (possibly involving symbol references)
487 k_Memory, /// Base + Offset Memory Address
488 k_PhysRegister, /// A physical register from the Mips namespace
489 k_RegisterIndex, /// A register index in one or more RegKind.
490 k_Token, /// A simple token
491 k_RegList, /// A physical register list
492 k_RegPair /// A pair of physical register
496 MipsOperand(KindTy K, MipsAsmParser &Parser)
497 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
500 /// For diagnostics, and checking the assembler temporary
501 MipsAsmParser &AsmParser;
509 unsigned Num; /// Register Number
513 unsigned Index; /// Index into the register class
514 RegKind Kind; /// Bitfield of the kinds it could possibly be
515 const MCRegisterInfo *RegInfo;
528 SmallVector<unsigned, 10> *List;
533 struct PhysRegOp PhysReg;
534 struct RegIdxOp RegIdx;
537 struct RegListOp RegList;
540 SMLoc StartLoc, EndLoc;
542 /// Internal constructor for register kinds
543 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
544 const MCRegisterInfo *RegInfo,
546 MipsAsmParser &Parser) {
547 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
548 Op->RegIdx.Index = Index;
549 Op->RegIdx.RegInfo = RegInfo;
550 Op->RegIdx.Kind = RegKind;
557 /// Coerce the register to GPR32 and return the real register for the current
559 unsigned getGPR32Reg() const {
560 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
561 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
562 unsigned ClassID = Mips::GPR32RegClassID;
563 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
566 /// Coerce the register to GPR32 and return the real register for the current
568 unsigned getGPRMM16Reg() const {
569 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
570 unsigned ClassID = Mips::GPR32RegClassID;
571 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
574 /// Coerce the register to GPR64 and return the real register for the current
576 unsigned getGPR64Reg() const {
577 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
578 unsigned ClassID = Mips::GPR64RegClassID;
579 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
583 /// Coerce the register to AFGR64 and return the real register for the current
585 unsigned getAFGR64Reg() const {
586 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
587 if (RegIdx.Index % 2 != 0)
588 AsmParser.Warning(StartLoc, "Float register should be even.");
589 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
590 .getRegister(RegIdx.Index / 2);
593 /// Coerce the register to FGR64 and return the real register for the current
595 unsigned getFGR64Reg() const {
596 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
597 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
598 .getRegister(RegIdx.Index);
601 /// Coerce the register to FGR32 and return the real register for the current
603 unsigned getFGR32Reg() const {
604 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
605 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
606 .getRegister(RegIdx.Index);
609 /// Coerce the register to FGRH32 and return the real register for the current
611 unsigned getFGRH32Reg() const {
612 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
613 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
614 .getRegister(RegIdx.Index);
617 /// Coerce the register to FCC and return the real register for the current
619 unsigned getFCCReg() const {
620 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
621 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
622 .getRegister(RegIdx.Index);
625 /// Coerce the register to MSA128 and return the real register for the current
627 unsigned getMSA128Reg() const {
628 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
629 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
631 unsigned ClassID = Mips::MSA128BRegClassID;
632 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
635 /// Coerce the register to MSACtrl and return the real register for the
637 unsigned getMSACtrlReg() const {
638 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
639 unsigned ClassID = Mips::MSACtrlRegClassID;
640 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
643 /// Coerce the register to COP2 and return the real register for the
645 unsigned getCOP2Reg() const {
646 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
647 unsigned ClassID = Mips::COP2RegClassID;
648 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
651 /// Coerce the register to COP3 and return the real register for the
653 unsigned getCOP3Reg() const {
654 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
655 unsigned ClassID = Mips::COP3RegClassID;
656 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
659 /// Coerce the register to ACC64DSP and return the real register for the
661 unsigned getACC64DSPReg() const {
662 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
663 unsigned ClassID = Mips::ACC64DSPRegClassID;
664 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
667 /// Coerce the register to HI32DSP and return the real register for the
669 unsigned getHI32DSPReg() const {
670 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
671 unsigned ClassID = Mips::HI32DSPRegClassID;
672 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
675 /// Coerce the register to LO32DSP and return the real register for the
677 unsigned getLO32DSPReg() const {
678 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
679 unsigned ClassID = Mips::LO32DSPRegClassID;
680 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
683 /// Coerce the register to CCR and return the real register for the
685 unsigned getCCRReg() const {
686 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
687 unsigned ClassID = Mips::CCRRegClassID;
688 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
691 /// Coerce the register to HWRegs and return the real register for the
693 unsigned getHWRegsReg() const {
694 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
695 unsigned ClassID = Mips::HWRegsRegClassID;
696 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
700 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
701 // Add as immediate when possible. Null MCExpr = 0.
703 Inst.addOperand(MCOperand::createImm(0));
704 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
705 Inst.addOperand(MCOperand::createImm(CE->getValue()));
707 Inst.addOperand(MCOperand::createExpr(Expr));
710 void addRegOperands(MCInst &Inst, unsigned N) const {
711 llvm_unreachable("Use a custom parser instead");
714 /// Render the operand to an MCInst as a GPR32
715 /// Asserts if the wrong number of operands are requested, or the operand
716 /// is not a k_RegisterIndex compatible with RegKind_GPR
717 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
718 assert(N == 1 && "Invalid number of operands!");
719 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
722 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
723 assert(N == 1 && "Invalid number of operands!");
724 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
727 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
728 assert(N == 1 && "Invalid number of operands!");
729 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
732 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
733 assert(N == 1 && "Invalid number of operands!");
734 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
737 /// Render the operand to an MCInst as a GPR64
738 /// Asserts if the wrong number of operands are requested, or the operand
739 /// is not a k_RegisterIndex compatible with RegKind_GPR
740 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
741 assert(N == 1 && "Invalid number of operands!");
742 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
745 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
746 assert(N == 1 && "Invalid number of operands!");
747 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
750 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
751 assert(N == 1 && "Invalid number of operands!");
752 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
755 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
756 assert(N == 1 && "Invalid number of operands!");
757 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
758 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
759 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
760 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
764 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
765 assert(N == 1 && "Invalid number of operands!");
766 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
769 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
770 assert(N == 1 && "Invalid number of operands!");
771 Inst.addOperand(MCOperand::createReg(getFCCReg()));
774 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
775 assert(N == 1 && "Invalid number of operands!");
776 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
779 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
780 assert(N == 1 && "Invalid number of operands!");
781 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
784 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
785 assert(N == 1 && "Invalid number of operands!");
786 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
789 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
790 assert(N == 1 && "Invalid number of operands!");
791 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
794 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
795 assert(N == 1 && "Invalid number of operands!");
796 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
799 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
800 assert(N == 1 && "Invalid number of operands!");
801 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
804 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
805 assert(N == 1 && "Invalid number of operands!");
806 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
809 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
810 assert(N == 1 && "Invalid number of operands!");
811 Inst.addOperand(MCOperand::createReg(getCCRReg()));
814 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
815 assert(N == 1 && "Invalid number of operands!");
816 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
819 void addImmOperands(MCInst &Inst, unsigned N) const {
820 assert(N == 1 && "Invalid number of operands!");
821 const MCExpr *Expr = getImm();
825 void addMemOperands(MCInst &Inst, unsigned N) const {
826 assert(N == 2 && "Invalid number of operands!");
828 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPR32Reg()));
830 const MCExpr *Expr = getMemOff();
834 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
835 assert(N == 2 && "Invalid number of operands!");
837 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
839 const MCExpr *Expr = getMemOff();
843 void addRegListOperands(MCInst &Inst, unsigned N) const {
844 assert(N == 1 && "Invalid number of operands!");
846 for (auto RegNo : getRegList())
847 Inst.addOperand(MCOperand::createReg(RegNo));
850 void addRegPairOperands(MCInst &Inst, unsigned N) const {
851 assert(N == 2 && "Invalid number of operands!");
852 unsigned RegNo = getRegPair();
853 Inst.addOperand(MCOperand::createReg(RegNo++));
854 Inst.addOperand(MCOperand::createReg(RegNo));
857 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
858 assert(N == 2 && "Invalid number of operands!");
859 for (auto RegNo : getRegList())
860 Inst.addOperand(MCOperand::createReg(RegNo));
863 bool isReg() const override {
864 // As a special case until we sort out the definition of div/divu, pretend
865 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
866 if (isGPRAsmReg() && RegIdx.Index == 0)
869 return Kind == k_PhysRegister;
871 bool isRegIdx() const { return Kind == k_RegisterIndex; }
872 bool isImm() const override { return Kind == k_Immediate; }
873 bool isConstantImm() const {
874 return isImm() && dyn_cast<MCConstantExpr>(getImm());
876 bool isToken() const override {
877 // Note: It's not possible to pretend that other operand kinds are tokens.
878 // The matcher emitter checks tokens first.
879 return Kind == k_Token;
881 bool isMem() const override { return Kind == k_Memory; }
882 bool isConstantMemOff() const {
883 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
885 template <unsigned Bits> bool isMemWithSimmOffset() const {
886 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
888 bool isMemWithGRPMM16Base() const {
889 return isMem() && getMemBase()->isMM16AsmReg();
891 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
892 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
893 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
895 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
896 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
897 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
898 && (getMemBase()->getGPR32Reg() == Mips::SP);
900 bool isRegList16() const {
904 int Size = RegList.List->size();
905 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
906 RegList.List->back() != Mips::RA)
909 int PrevReg = *RegList.List->begin();
910 for (int i = 1; i < Size - 1; i++) {
911 int Reg = (*(RegList.List))[i];
912 if ( Reg != PrevReg + 1)
919 bool isInvNum() const { return Kind == k_Immediate; }
920 bool isLSAImm() const {
921 if (!isConstantImm())
923 int64_t Val = getConstantImm();
924 return 1 <= Val && Val <= 4;
926 bool isRegList() const { return Kind == k_RegList; }
927 bool isMovePRegPair() const {
928 if (Kind != k_RegList || RegList.List->size() != 2)
931 unsigned R0 = RegList.List->front();
932 unsigned R1 = RegList.List->back();
934 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
935 (R0 == Mips::A1 && R1 == Mips::A3) ||
936 (R0 == Mips::A2 && R1 == Mips::A3) ||
937 (R0 == Mips::A0 && R1 == Mips::S5) ||
938 (R0 == Mips::A0 && R1 == Mips::S6) ||
939 (R0 == Mips::A0 && R1 == Mips::A1) ||
940 (R0 == Mips::A0 && R1 == Mips::A2) ||
941 (R0 == Mips::A0 && R1 == Mips::A3))
947 StringRef getToken() const {
948 assert(Kind == k_Token && "Invalid access!");
949 return StringRef(Tok.Data, Tok.Length);
951 bool isRegPair() const { return Kind == k_RegPair; }
953 unsigned getReg() const override {
954 // As a special case until we sort out the definition of div/divu, pretend
955 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
956 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
957 RegIdx.Kind & RegKind_GPR)
958 return getGPR32Reg(); // FIXME: GPR64 too
960 assert(Kind == k_PhysRegister && "Invalid access!");
964 const MCExpr *getImm() const {
965 assert((Kind == k_Immediate) && "Invalid access!");
969 int64_t getConstantImm() const {
970 const MCExpr *Val = getImm();
971 return static_cast<const MCConstantExpr *>(Val)->getValue();
974 MipsOperand *getMemBase() const {
975 assert((Kind == k_Memory) && "Invalid access!");
979 const MCExpr *getMemOff() const {
980 assert((Kind == k_Memory) && "Invalid access!");
984 int64_t getConstantMemOff() const {
985 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
988 const SmallVectorImpl<unsigned> &getRegList() const {
989 assert((Kind == k_RegList) && "Invalid access!");
990 return *(RegList.List);
993 unsigned getRegPair() const {
994 assert((Kind == k_RegPair) && "Invalid access!");
998 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
999 MipsAsmParser &Parser) {
1000 auto Op = make_unique<MipsOperand>(k_Token, Parser);
1001 Op->Tok.Data = Str.data();
1002 Op->Tok.Length = Str.size();
1008 /// Create a numeric register (e.g. $1). The exact register remains
1009 /// unresolved until an instruction successfully matches
1010 static std::unique_ptr<MipsOperand>
1011 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1012 SMLoc E, MipsAsmParser &Parser) {
1013 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1014 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1017 /// Create a register that is definitely a GPR.
1018 /// This is typically only used for named registers such as $gp.
1019 static std::unique_ptr<MipsOperand>
1020 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1021 MipsAsmParser &Parser) {
1022 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1025 /// Create a register that is definitely a FGR.
1026 /// This is typically only used for named registers such as $f0.
1027 static std::unique_ptr<MipsOperand>
1028 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1029 MipsAsmParser &Parser) {
1030 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1033 /// Create a register that is definitely a HWReg.
1034 /// This is typically only used for named registers such as $hwr_cpunum.
1035 static std::unique_ptr<MipsOperand>
1036 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1037 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1038 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1041 /// Create a register that is definitely an FCC.
1042 /// This is typically only used for named registers such as $fcc0.
1043 static std::unique_ptr<MipsOperand>
1044 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1045 MipsAsmParser &Parser) {
1046 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1049 /// Create a register that is definitely an ACC.
1050 /// This is typically only used for named registers such as $ac0.
1051 static std::unique_ptr<MipsOperand>
1052 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1053 MipsAsmParser &Parser) {
1054 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1057 /// Create a register that is definitely an MSA128.
1058 /// This is typically only used for named registers such as $w0.
1059 static std::unique_ptr<MipsOperand>
1060 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1061 SMLoc E, MipsAsmParser &Parser) {
1062 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1065 /// Create a register that is definitely an MSACtrl.
1066 /// This is typically only used for named registers such as $msaaccess.
1067 static std::unique_ptr<MipsOperand>
1068 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1069 SMLoc E, MipsAsmParser &Parser) {
1070 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1073 static std::unique_ptr<MipsOperand>
1074 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1075 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1082 static std::unique_ptr<MipsOperand>
1083 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1084 SMLoc E, MipsAsmParser &Parser) {
1085 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1086 Op->Mem.Base = Base.release();
1093 static std::unique_ptr<MipsOperand>
1094 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1095 MipsAsmParser &Parser) {
1096 assert (Regs.size() > 0 && "Empty list not allowed");
1098 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1099 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1100 Op->StartLoc = StartLoc;
1101 Op->EndLoc = EndLoc;
1105 static std::unique_ptr<MipsOperand>
1106 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1107 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1108 Op->RegIdx.Index = RegNo;
1114 bool isGPRAsmReg() const {
1115 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1117 bool isMM16AsmReg() const {
1118 if (!(isRegIdx() && RegIdx.Kind))
1120 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1121 || RegIdx.Index == 16 || RegIdx.Index == 17);
1123 bool isMM16AsmRegZero() const {
1124 if (!(isRegIdx() && RegIdx.Kind))
1126 return (RegIdx.Index == 0 ||
1127 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1128 RegIdx.Index == 17);
1130 bool isMM16AsmRegMoveP() const {
1131 if (!(isRegIdx() && RegIdx.Kind))
1133 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1134 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1136 bool isFGRAsmReg() const {
1137 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1138 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1140 bool isHWRegsAsmReg() const {
1141 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1143 bool isCCRAsmReg() const {
1144 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1146 bool isFCCAsmReg() const {
1147 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1149 if (!AsmParser.hasEightFccRegisters())
1150 return RegIdx.Index == 0;
1151 return RegIdx.Index <= 7;
1153 bool isACCAsmReg() const {
1154 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1156 bool isCOP2AsmReg() const {
1157 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1159 bool isCOP3AsmReg() const {
1160 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1162 bool isMSA128AsmReg() const {
1163 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1165 bool isMSACtrlAsmReg() const {
1166 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1169 /// getStartLoc - Get the location of the first token of this operand.
1170 SMLoc getStartLoc() const override { return StartLoc; }
1171 /// getEndLoc - Get the location of the last token of this operand.
1172 SMLoc getEndLoc() const override { return EndLoc; }
1174 virtual ~MipsOperand() {
1182 delete RegList.List;
1183 case k_PhysRegister:
1184 case k_RegisterIndex:
1191 void print(raw_ostream &OS) const override {
1200 Mem.Base->print(OS);
1205 case k_PhysRegister:
1206 OS << "PhysReg<" << PhysReg.Num << ">";
1208 case k_RegisterIndex:
1209 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1216 for (auto Reg : (*RegList.List))
1221 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1225 }; // class MipsOperand
1229 extern const MCInstrDesc MipsInsts[];
1231 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1232 return MipsInsts[Opcode];
1235 static bool hasShortDelaySlot(unsigned Opcode) {
1238 case Mips::JALRS_MM:
1239 case Mips::JALRS16_MM:
1240 case Mips::BGEZALS_MM:
1241 case Mips::BLTZALS_MM:
1248 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1249 SmallVectorImpl<MCInst> &Instructions) {
1250 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1254 if (MCID.isBranch() || MCID.isCall()) {
1255 const unsigned Opcode = Inst.getOpcode();
1265 assert(hasCnMips() && "instruction only valid for octeon cpus");
1272 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1273 Offset = Inst.getOperand(2);
1274 if (!Offset.isImm())
1275 break; // We'll deal with this situation later on when applying fixups.
1276 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1277 return Error(IDLoc, "branch target out of range");
1278 if (OffsetToAlignment(Offset.getImm(),
1279 1LL << (inMicroMipsMode() ? 1 : 2)))
1280 return Error(IDLoc, "branch to misaligned address");
1294 case Mips::BGEZAL_MM:
1295 case Mips::BLTZAL_MM:
1298 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1299 Offset = Inst.getOperand(1);
1300 if (!Offset.isImm())
1301 break; // We'll deal with this situation later on when applying fixups.
1302 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1303 return Error(IDLoc, "branch target out of range");
1304 if (OffsetToAlignment(Offset.getImm(),
1305 1LL << (inMicroMipsMode() ? 1 : 2)))
1306 return Error(IDLoc, "branch to misaligned address");
1308 case Mips::BEQZ16_MM:
1309 case Mips::BNEZ16_MM:
1310 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1311 Offset = Inst.getOperand(1);
1312 if (!Offset.isImm())
1313 break; // We'll deal with this situation later on when applying fixups.
1314 if (!isIntN(8, Offset.getImm()))
1315 return Error(IDLoc, "branch target out of range");
1316 if (OffsetToAlignment(Offset.getImm(), 2LL))
1317 return Error(IDLoc, "branch to misaligned address");
1322 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1323 // We still accept it but it is a normal nop.
1324 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1325 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1326 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1331 const unsigned Opcode = Inst.getOpcode();
1343 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1344 // The offset is handled above
1345 Opnd = Inst.getOperand(1);
1347 return Error(IDLoc, "expected immediate operand kind");
1348 Imm = Opnd.getImm();
1349 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1350 Opcode == Mips::BBIT1 ? 63 : 31))
1351 return Error(IDLoc, "immediate operand value out of range");
1353 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1355 Inst.getOperand(1).setImm(Imm - 32);
1363 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1365 Opnd = Inst.getOperand(3);
1367 return Error(IDLoc, "expected immediate operand kind");
1368 Imm = Opnd.getImm();
1369 if (Imm < 0 || Imm > 31)
1370 return Error(IDLoc, "immediate operand value out of range");
1372 Opnd = Inst.getOperand(2);
1374 return Error(IDLoc, "expected immediate operand kind");
1375 Imm = Opnd.getImm();
1376 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1377 Opcode == Mips::EXTS ? 63 : 31))
1378 return Error(IDLoc, "immediate operand value out of range");
1380 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1381 Inst.getOperand(2).setImm(Imm - 32);
1387 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1388 Opnd = Inst.getOperand(2);
1390 return Error(IDLoc, "expected immediate operand kind");
1391 Imm = Opnd.getImm();
1392 if (!isInt<10>(Imm))
1393 return Error(IDLoc, "immediate operand value out of range");
1398 if (MCID.mayLoad() || MCID.mayStore()) {
1399 // Check the offset of memory operand, if it is a symbol
1400 // reference or immediate we may have to expand instructions.
1401 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1402 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1403 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1404 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1405 MCOperand &Op = Inst.getOperand(i);
1407 int MemOffset = Op.getImm();
1408 if (MemOffset < -32768 || MemOffset > 32767) {
1409 // Offset can't exceed 16bit value.
1410 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1413 } else if (Op.isExpr()) {
1414 const MCExpr *Expr = Op.getExpr();
1415 if (Expr->getKind() == MCExpr::SymbolRef) {
1416 const MCSymbolRefExpr *SR =
1417 static_cast<const MCSymbolRefExpr *>(Expr);
1418 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1420 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1423 } else if (!isEvaluated(Expr)) {
1424 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1432 if (inMicroMipsMode()) {
1433 if (MCID.mayLoad()) {
1434 // Try to create 16-bit GP relative load instruction.
1435 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1436 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1437 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1438 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1439 MCOperand &Op = Inst.getOperand(i);
1441 int MemOffset = Op.getImm();
1442 MCOperand &DstReg = Inst.getOperand(0);
1443 MCOperand &BaseReg = Inst.getOperand(1);
1444 if (isIntN(9, MemOffset) && (MemOffset % 4 == 0) &&
1445 getContext().getRegisterInfo()->getRegClass(
1446 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1447 BaseReg.getReg() == Mips::GP) {
1449 TmpInst.setLoc(IDLoc);
1450 TmpInst.setOpcode(Mips::LWGP_MM);
1451 TmpInst.addOperand(MCOperand::createReg(DstReg.getReg()));
1452 TmpInst.addOperand(MCOperand::createReg(Mips::GP));
1453 TmpInst.addOperand(MCOperand::createImm(MemOffset));
1454 Instructions.push_back(TmpInst);
1462 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1467 switch (Inst.getOpcode()) {
1470 case Mips::ADDIUS5_MM:
1471 Opnd = Inst.getOperand(2);
1473 return Error(IDLoc, "expected immediate operand kind");
1474 Imm = Opnd.getImm();
1475 if (Imm < -8 || Imm > 7)
1476 return Error(IDLoc, "immediate operand value out of range");
1478 case Mips::ADDIUSP_MM:
1479 Opnd = Inst.getOperand(0);
1481 return Error(IDLoc, "expected immediate operand kind");
1482 Imm = Opnd.getImm();
1483 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1485 return Error(IDLoc, "immediate operand value out of range");
1487 case Mips::SLL16_MM:
1488 case Mips::SRL16_MM:
1489 Opnd = Inst.getOperand(2);
1491 return Error(IDLoc, "expected immediate operand kind");
1492 Imm = Opnd.getImm();
1493 if (Imm < 1 || Imm > 8)
1494 return Error(IDLoc, "immediate operand value out of range");
1497 Opnd = Inst.getOperand(1);
1499 return Error(IDLoc, "expected immediate operand kind");
1500 Imm = Opnd.getImm();
1501 if (Imm < -1 || Imm > 126)
1502 return Error(IDLoc, "immediate operand value out of range");
1504 case Mips::ADDIUR2_MM:
1505 Opnd = Inst.getOperand(2);
1507 return Error(IDLoc, "expected immediate operand kind");
1508 Imm = Opnd.getImm();
1509 if (!(Imm == 1 || Imm == -1 ||
1510 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1511 return Error(IDLoc, "immediate operand value out of range");
1513 case Mips::ADDIUR1SP_MM:
1514 Opnd = Inst.getOperand(1);
1516 return Error(IDLoc, "expected immediate operand kind");
1517 Imm = Opnd.getImm();
1518 if (OffsetToAlignment(Imm, 4LL))
1519 return Error(IDLoc, "misaligned immediate operand value");
1520 if (Imm < 0 || Imm > 255)
1521 return Error(IDLoc, "immediate operand value out of range");
1523 case Mips::ANDI16_MM:
1524 Opnd = Inst.getOperand(2);
1526 return Error(IDLoc, "expected immediate operand kind");
1527 Imm = Opnd.getImm();
1528 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1529 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1530 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1531 return Error(IDLoc, "immediate operand value out of range");
1533 case Mips::LBU16_MM:
1534 Opnd = Inst.getOperand(2);
1536 return Error(IDLoc, "expected immediate operand kind");
1537 Imm = Opnd.getImm();
1538 if (Imm < -1 || Imm > 14)
1539 return Error(IDLoc, "immediate operand value out of range");
1542 Opnd = Inst.getOperand(2);
1544 return Error(IDLoc, "expected immediate operand kind");
1545 Imm = Opnd.getImm();
1546 if (Imm < 0 || Imm > 15)
1547 return Error(IDLoc, "immediate operand value out of range");
1549 case Mips::LHU16_MM:
1551 Opnd = Inst.getOperand(2);
1553 return Error(IDLoc, "expected immediate operand kind");
1554 Imm = Opnd.getImm();
1555 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1556 return Error(IDLoc, "immediate operand value out of range");
1560 Opnd = Inst.getOperand(2);
1562 return Error(IDLoc, "expected immediate operand kind");
1563 Imm = Opnd.getImm();
1564 if (Imm < 0 || Imm > 60 || (Imm % 4 != 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 (!isUInt<5>(Imm))
1574 return Error(IDLoc, "immediate operand value out of range");
1576 case Mips::ADDIUPC_MM:
1577 MCOperand Opnd = Inst.getOperand(1);
1579 return Error(IDLoc, "expected immediate operand kind");
1580 int Imm = Opnd.getImm();
1581 if ((Imm % 4 != 0) || !isIntN(25, Imm))
1582 return Error(IDLoc, "immediate operand value out of range");
1587 if (needsExpansion(Inst)) {
1588 if (expandInstruction(Inst, IDLoc, Instructions))
1591 Instructions.push_back(Inst);
1593 // If this instruction has a delay slot and .set reorder is active,
1594 // emit a NOP after it.
1595 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1596 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1601 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1603 switch (Inst.getOpcode()) {
1604 case Mips::LoadImm32:
1605 case Mips::LoadImm64:
1606 case Mips::LoadAddrImm32:
1607 case Mips::LoadAddrReg32:
1608 case Mips::B_MM_Pseudo:
1611 case Mips::JalOneReg:
1612 case Mips::JalTwoReg:
1619 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1620 SmallVectorImpl<MCInst> &Instructions) {
1621 switch (Inst.getOpcode()) {
1622 default: llvm_unreachable("unimplemented expansion");
1623 case Mips::LoadImm32:
1624 return expandLoadImm(Inst, true, IDLoc, Instructions);
1625 case Mips::LoadImm64:
1626 return expandLoadImm(Inst, false, IDLoc, Instructions);
1627 case Mips::LoadAddrImm32:
1628 return expandLoadAddressImm(Inst, true, IDLoc, Instructions);
1629 case Mips::LoadAddrReg32:
1630 return expandLoadAddressReg(Inst, true, IDLoc, Instructions);
1631 case Mips::B_MM_Pseudo:
1632 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1635 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
1636 case Mips::JalOneReg:
1637 case Mips::JalTwoReg:
1638 return expandJalWithRegs(Inst, IDLoc, Instructions);
1643 template <unsigned ShiftAmount>
1644 void createLShiftOri(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1645 SmallVectorImpl<MCInst> &Instructions) {
1647 if (ShiftAmount >= 32) {
1648 tmpInst.setOpcode(Mips::DSLL32);
1649 tmpInst.addOperand(MCOperand::createReg(RegNo));
1650 tmpInst.addOperand(MCOperand::createReg(RegNo));
1651 tmpInst.addOperand(MCOperand::createImm(ShiftAmount - 32));
1652 tmpInst.setLoc(IDLoc);
1653 Instructions.push_back(tmpInst);
1655 } else if (ShiftAmount > 0) {
1656 tmpInst.setOpcode(Mips::DSLL);
1657 tmpInst.addOperand(MCOperand::createReg(RegNo));
1658 tmpInst.addOperand(MCOperand::createReg(RegNo));
1659 tmpInst.addOperand(MCOperand::createImm(ShiftAmount));
1660 tmpInst.setLoc(IDLoc);
1661 Instructions.push_back(tmpInst);
1664 // There's no need for an ORi if the immediate is 0.
1665 if (Operand.isImm() && Operand.getImm() == 0)
1668 tmpInst.setOpcode(Mips::ORi);
1669 tmpInst.addOperand(MCOperand::createReg(RegNo));
1670 tmpInst.addOperand(MCOperand::createReg(RegNo));
1671 tmpInst.addOperand(Operand);
1672 tmpInst.setLoc(IDLoc);
1673 Instructions.push_back(tmpInst);
1676 template <unsigned ShiftAmount>
1677 void createLShiftOri(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1678 SmallVectorImpl<MCInst> &Instructions) {
1679 createLShiftOri<ShiftAmount>(MCOperand::createImm(Value), RegNo, IDLoc,
1684 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
1685 SmallVectorImpl<MCInst> &Instructions) {
1686 // Create a JALR instruction which is going to replace the pseudo-JAL.
1688 JalrInst.setLoc(IDLoc);
1689 const MCOperand FirstRegOp = Inst.getOperand(0);
1690 const unsigned Opcode = Inst.getOpcode();
1692 if (Opcode == Mips::JalOneReg) {
1693 // jal $rs => jalr $rs
1694 if (inMicroMipsMode()) {
1695 JalrInst.setOpcode(Mips::JALR16_MM);
1696 JalrInst.addOperand(FirstRegOp);
1698 JalrInst.setOpcode(Mips::JALR);
1699 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1700 JalrInst.addOperand(FirstRegOp);
1702 } else if (Opcode == Mips::JalTwoReg) {
1703 // jal $rd, $rs => jalr $rd, $rs
1704 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1705 JalrInst.addOperand(FirstRegOp);
1706 const MCOperand SecondRegOp = Inst.getOperand(1);
1707 JalrInst.addOperand(SecondRegOp);
1709 Instructions.push_back(JalrInst);
1711 // If .set reorder is active, emit a NOP after it.
1712 if (AssemblerOptions.back()->isReorder()) {
1713 // This is a 32-bit NOP because these 2 pseudo-instructions
1714 // do not have a short delay slot.
1716 NopInst.setOpcode(Mips::SLL);
1717 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
1718 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
1719 NopInst.addOperand(MCOperand::createImm(0));
1720 Instructions.push_back(NopInst);
1726 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
1727 unsigned SrcReg, bool Is32BitImm, SMLoc IDLoc,
1728 SmallVectorImpl<MCInst> &Instructions) {
1729 if (!Is32BitImm && !isGP64bit()) {
1730 Error(IDLoc, "instruction requires a 64-bit architecture");
1734 bool UseSrcReg = false;
1735 if (SrcReg != Mips::NoRegister)
1740 tmpInst.setLoc(IDLoc);
1741 // FIXME: gas has a special case for values that are 000...1111, which
1742 // becomes a li -1 and then a dsrl
1743 if (0 <= ImmValue && ImmValue <= 65535) {
1744 // For unsigned and positive signed 16-bit values (0 <= j <= 65535):
1745 // li d,j => ori d,$zero,j
1747 SrcReg = isGP64bit() ? Mips::ZERO_64 : Mips::ZERO;
1748 tmpInst.setOpcode(Mips::ORi);
1749 tmpInst.addOperand(MCOperand::createReg(DstReg));
1750 tmpInst.addOperand(MCOperand::createReg(SrcReg));
1751 tmpInst.addOperand(MCOperand::createImm(ImmValue));
1752 Instructions.push_back(tmpInst);
1753 } else if (ImmValue < 0 && ImmValue >= -32768) {
1754 // For negative signed 16-bit values (-32768 <= j < 0):
1755 // li d,j => addiu d,$zero,j
1757 SrcReg = Mips::ZERO;
1758 tmpInst.setOpcode(Mips::ADDiu);
1759 tmpInst.addOperand(MCOperand::createReg(DstReg));
1760 tmpInst.addOperand(MCOperand::createReg(SrcReg));
1761 tmpInst.addOperand(MCOperand::createImm(ImmValue));
1762 Instructions.push_back(tmpInst);
1763 } else if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
1764 warnIfNoMacro(IDLoc);
1766 // For all other values which are representable as a 32-bit integer:
1767 // li d,j => lui d,hi16(j)
1769 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1770 uint16_t Bits15To0 = ImmValue & 0xffff;
1772 if (!Is32BitImm && !isInt<32>(ImmValue)) {
1773 // For DLI, expand to an ORi instead of a LUi to avoid sign-extending the
1775 tmpInst.setOpcode(Mips::ORi);
1776 tmpInst.addOperand(MCOperand::createReg(DstReg));
1777 tmpInst.addOperand(MCOperand::createReg(Mips::ZERO));
1778 tmpInst.addOperand(MCOperand::createImm(Bits31To16));
1779 tmpInst.setLoc(IDLoc);
1780 Instructions.push_back(tmpInst);
1781 // Move the value to the upper 16 bits by doing a 16-bit left shift.
1782 createLShiftOri<16>(0, DstReg, IDLoc, Instructions);
1784 tmpInst.setOpcode(Mips::LUi);
1785 tmpInst.addOperand(MCOperand::createReg(DstReg));
1786 tmpInst.addOperand(MCOperand::createImm(Bits31To16));
1787 Instructions.push_back(tmpInst);
1789 createLShiftOri<0>(Bits15To0, DstReg, IDLoc, Instructions);
1792 createAddu(DstReg, DstReg, SrcReg, Instructions);
1794 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1796 Error(IDLoc, "instruction requires a 32-bit immediate");
1799 warnIfNoMacro(IDLoc);
1801 // <------- lo32 ------>
1802 // <------- hi32 ------>
1803 // <- hi16 -> <- lo16 ->
1804 // _________________________________
1806 // | 16-bits | 16-bits | 16-bits |
1807 // |__________|__________|__________|
1809 // For any 64-bit value that is representable as a 48-bit integer:
1810 // li d,j => lui d,hi16(j)
1811 // ori d,d,hi16(lo32(j))
1813 // ori d,d,lo16(lo32(j))
1814 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1815 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1816 uint16_t Bits15To0 = ImmValue & 0xffff;
1818 tmpInst.setOpcode(Mips::LUi);
1819 tmpInst.addOperand(MCOperand::createReg(DstReg));
1820 tmpInst.addOperand(MCOperand::createImm(Bits47To32));
1821 Instructions.push_back(tmpInst);
1822 createLShiftOri<0>(Bits31To16, DstReg, IDLoc, Instructions);
1823 createLShiftOri<16>(Bits15To0, DstReg, IDLoc, Instructions);
1826 createAddu(DstReg, DstReg, SrcReg, Instructions);
1830 Error(IDLoc, "instruction requires a 32-bit immediate");
1833 warnIfNoMacro(IDLoc);
1835 // <------- hi32 ------> <------- lo32 ------>
1836 // <- hi16 -> <- lo16 ->
1837 // ___________________________________________
1839 // | 16-bits | 16-bits | 16-bits | 16-bits |
1840 // |__________|__________|__________|__________|
1842 // For all other values which are representable as a 64-bit integer:
1843 // li d,j => lui d,hi16(j)
1844 // ori d,d,lo16(hi32(j))
1846 // ori d,d,hi16(lo32(j))
1848 // ori d,d,lo16(lo32(j))
1849 uint16_t Bits63To48 = (ImmValue >> 48) & 0xffff;
1850 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1851 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1852 uint16_t Bits15To0 = ImmValue & 0xffff;
1854 tmpInst.setOpcode(Mips::LUi);
1855 tmpInst.addOperand(MCOperand::createReg(DstReg));
1856 tmpInst.addOperand(MCOperand::createImm(Bits63To48));
1857 Instructions.push_back(tmpInst);
1858 createLShiftOri<0>(Bits47To32, DstReg, IDLoc, Instructions);
1860 // When Bits31To16 is 0, do a left shift of 32 bits instead of doing
1861 // two left shifts of 16 bits.
1862 if (Bits31To16 == 0) {
1863 createLShiftOri<32>(Bits15To0, DstReg, IDLoc, Instructions);
1865 createLShiftOri<16>(Bits31To16, DstReg, IDLoc, Instructions);
1866 createLShiftOri<16>(Bits15To0, DstReg, IDLoc, Instructions);
1870 createAddu(DstReg, DstReg, SrcReg, Instructions);
1875 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1876 SmallVectorImpl<MCInst> &Instructions) {
1877 const MCOperand &ImmOp = Inst.getOperand(1);
1878 assert(ImmOp.isImm() && "expected immediate operand kind");
1879 const MCOperand &DstRegOp = Inst.getOperand(0);
1880 assert(DstRegOp.isReg() && "expected register operand kind");
1882 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
1883 Is32BitImm, IDLoc, Instructions))
1890 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1891 SmallVectorImpl<MCInst> &Instructions) {
1892 const MCOperand &DstRegOp = Inst.getOperand(0);
1893 assert(DstRegOp.isReg() && "expected register operand kind");
1895 const MCOperand &ImmOp = Inst.getOperand(2);
1896 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1897 "expected immediate operand kind");
1898 if (!ImmOp.isImm()) {
1899 expandLoadAddressSym(DstRegOp, ImmOp, Is32BitImm, IDLoc, Instructions);
1902 const MCOperand &SrcRegOp = Inst.getOperand(1);
1903 assert(SrcRegOp.isReg() && "expected register operand kind");
1905 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), SrcRegOp.getReg(),
1906 Is32BitImm, IDLoc, Instructions))
1913 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1914 SmallVectorImpl<MCInst> &Instructions) {
1915 const MCOperand &DstRegOp = Inst.getOperand(0);
1916 assert(DstRegOp.isReg() && "expected register operand kind");
1918 const MCOperand &ImmOp = Inst.getOperand(1);
1919 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1920 "expected immediate operand kind");
1921 if (!ImmOp.isImm()) {
1922 expandLoadAddressSym(DstRegOp, ImmOp, Is32BitImm, IDLoc, Instructions);
1926 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
1927 Is32BitImm, IDLoc, Instructions))
1933 void MipsAsmParser::expandLoadAddressSym(
1934 const MCOperand &DstRegOp, const MCOperand &SymOp, bool Is32BitSym,
1935 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1936 warnIfNoMacro(IDLoc);
1938 if (Is32BitSym && isABI_N64())
1939 Warning(IDLoc, "instruction loads the 32-bit address of a 64-bit symbol");
1942 unsigned RegNo = DstRegOp.getReg();
1943 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
1944 const MCSymbolRefExpr *HiExpr =
1945 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1946 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1947 const MCSymbolRefExpr *LoExpr =
1948 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1949 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1951 // If it's a 64-bit architecture, expand to:
1952 // la d,sym => lui d,highest(sym)
1953 // ori d,d,higher(sym)
1955 // ori d,d,hi16(sym)
1957 // ori d,d,lo16(sym)
1958 const MCSymbolRefExpr *HighestExpr =
1959 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1960 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1961 const MCSymbolRefExpr *HigherExpr =
1962 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1963 MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1965 tmpInst.setOpcode(Mips::LUi);
1966 tmpInst.addOperand(MCOperand::createReg(RegNo));
1967 tmpInst.addOperand(MCOperand::createExpr(HighestExpr));
1968 Instructions.push_back(tmpInst);
1970 createLShiftOri<0>(MCOperand::createExpr(HigherExpr), RegNo, SMLoc(),
1972 createLShiftOri<16>(MCOperand::createExpr(HiExpr), RegNo, SMLoc(),
1974 createLShiftOri<16>(MCOperand::createExpr(LoExpr), RegNo, SMLoc(),
1977 // Otherwise, expand to:
1978 // la d,sym => lui d,hi16(sym)
1979 // ori d,d,lo16(sym)
1980 tmpInst.setOpcode(Mips::LUi);
1981 tmpInst.addOperand(MCOperand::createReg(RegNo));
1982 tmpInst.addOperand(MCOperand::createExpr(HiExpr));
1983 Instructions.push_back(tmpInst);
1985 createLShiftOri<0>(MCOperand::createExpr(LoExpr), RegNo, SMLoc(),
1990 bool MipsAsmParser::expandUncondBranchMMPseudo(
1991 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1992 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
1993 "unexpected number of operands");
1995 MCOperand Offset = Inst.getOperand(0);
1996 if (Offset.isExpr()) {
1998 Inst.setOpcode(Mips::BEQ_MM);
1999 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2000 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2001 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2003 assert(Offset.isImm() && "expected immediate operand kind");
2004 if (isIntN(11, Offset.getImm())) {
2005 // If offset fits into 11 bits then this instruction becomes microMIPS
2006 // 16-bit unconditional branch instruction.
2007 Inst.setOpcode(Mips::B16_MM);
2009 if (!isIntN(17, Offset.getImm()))
2010 Error(IDLoc, "branch target out of range");
2011 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2012 Error(IDLoc, "branch to misaligned address");
2014 Inst.setOpcode(Mips::BEQ_MM);
2015 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2016 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2017 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2020 Instructions.push_back(Inst);
2022 // If .set reorder is active, emit a NOP after the branch instruction.
2023 if (AssemblerOptions.back()->isReorder())
2024 createNop(true, IDLoc, Instructions);
2029 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2030 SmallVectorImpl<MCInst> &Instructions,
2031 bool isLoad, bool isImmOpnd) {
2032 const MCSymbolRefExpr *SR;
2034 unsigned ImmOffset, HiOffset, LoOffset;
2035 const MCExpr *ExprOffset;
2037 // 1st operand is either the source or destination register.
2038 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2039 unsigned RegOpNum = Inst.getOperand(0).getReg();
2040 // 2nd operand is the base register.
2041 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2042 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2043 // 3rd operand is either an immediate or expression.
2045 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2046 ImmOffset = Inst.getOperand(2).getImm();
2047 LoOffset = ImmOffset & 0x0000ffff;
2048 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2049 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2050 if (LoOffset & 0x8000)
2053 ExprOffset = Inst.getOperand(2).getExpr();
2054 // All instructions will have the same location.
2055 TempInst.setLoc(IDLoc);
2056 // These are some of the types of expansions we perform here:
2057 // 1) lw $8, sym => lui $8, %hi(sym)
2058 // lw $8, %lo(sym)($8)
2059 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2061 // lw $8, %lo(offset)($9)
2062 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2064 // lw $8, %lo(offset)($at)
2065 // 4) sw $8, sym => lui $at, %hi(sym)
2066 // sw $8, %lo(sym)($at)
2067 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2069 // sw $8, %lo(offset)($at)
2070 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2071 // ldc1 $f0, %lo(sym)($at)
2073 // For load instructions we can use the destination register as a temporary
2074 // if base and dst are different (examples 1 and 2) and if the base register
2075 // is general purpose otherwise we must use $at (example 6) and error if it's
2076 // not available. For stores we must use $at (examples 4 and 5) because we
2077 // must not clobber the source register setting up the offset.
2078 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2079 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2080 unsigned RegClassIDOp0 =
2081 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2082 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2083 (RegClassIDOp0 == Mips::GPR64RegClassID);
2084 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2085 TmpRegNum = RegOpNum;
2087 // At this point we need AT to perform the expansions and we exit if it is
2089 TmpRegNum = getATReg(IDLoc);
2094 TempInst.setOpcode(Mips::LUi);
2095 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2097 TempInst.addOperand(MCOperand::createImm(HiOffset));
2099 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2100 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
2101 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
2102 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
2104 TempInst.addOperand(MCOperand::createExpr(HiExpr));
2106 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2107 TempInst.addOperand(MCOperand::createExpr(HiExpr));
2110 // Add the instruction to the list.
2111 Instructions.push_back(TempInst);
2112 // Prepare TempInst for next instruction.
2114 // Add temp register to base.
2115 if (BaseRegNum != Mips::ZERO) {
2116 TempInst.setOpcode(Mips::ADDu);
2117 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2118 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2119 TempInst.addOperand(MCOperand::createReg(BaseRegNum));
2120 Instructions.push_back(TempInst);
2123 // And finally, create original instruction with low part
2124 // of offset and new base.
2125 TempInst.setOpcode(Inst.getOpcode());
2126 TempInst.addOperand(MCOperand::createReg(RegOpNum));
2127 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2129 TempInst.addOperand(MCOperand::createImm(LoOffset));
2131 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2132 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
2133 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
2135 TempInst.addOperand(MCOperand::createExpr(LoExpr));
2137 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2138 TempInst.addOperand(MCOperand::createExpr(LoExpr));
2141 Instructions.push_back(TempInst);
2146 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2147 SmallVectorImpl<MCInst> &Instructions) {
2148 unsigned OpNum = Inst.getNumOperands();
2149 unsigned Opcode = Inst.getOpcode();
2150 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2152 assert (Inst.getOperand(OpNum - 1).isImm() &&
2153 Inst.getOperand(OpNum - 2).isReg() &&
2154 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2156 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2157 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2158 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2159 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2160 // It can be implemented as SWM16 or LWM16 instruction.
2161 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2163 Inst.setOpcode(NewOpcode);
2164 Instructions.push_back(Inst);
2168 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
2169 SmallVectorImpl<MCInst> &Instructions) {
2171 if (hasShortDelaySlot) {
2172 NopInst.setOpcode(Mips::MOVE16_MM);
2173 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2174 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2176 NopInst.setOpcode(Mips::SLL);
2177 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2178 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2179 NopInst.addOperand(MCOperand::createImm(0));
2181 Instructions.push_back(NopInst);
2184 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
2186 SmallVectorImpl<MCInst> &Instructions) {
2188 AdduInst.setOpcode(Mips::ADDu);
2189 AdduInst.addOperand(MCOperand::createReg(DstReg));
2190 AdduInst.addOperand(MCOperand::createReg(SrcReg));
2191 AdduInst.addOperand(MCOperand::createReg(TrgReg));
2192 Instructions.push_back(AdduInst);
2195 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
2196 // As described by the Mips32r2 spec, the registers Rd and Rs for
2197 // jalr.hb must be different.
2198 unsigned Opcode = Inst.getOpcode();
2200 if (Opcode == Mips::JALR_HB &&
2201 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
2202 return Match_RequiresDifferentSrcAndDst;
2204 return Match_Success;
2207 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2208 OperandVector &Operands,
2210 uint64_t &ErrorInfo,
2211 bool MatchingInlineAsm) {
2214 SmallVector<MCInst, 8> Instructions;
2215 unsigned MatchResult =
2216 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
2218 switch (MatchResult) {
2219 case Match_Success: {
2220 if (processInstruction(Inst, IDLoc, Instructions))
2222 for (unsigned i = 0; i < Instructions.size(); i++)
2223 Out.EmitInstruction(Instructions[i], STI);
2226 case Match_MissingFeature:
2227 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2229 case Match_InvalidOperand: {
2230 SMLoc ErrorLoc = IDLoc;
2231 if (ErrorInfo != ~0ULL) {
2232 if (ErrorInfo >= Operands.size())
2233 return Error(IDLoc, "too few operands for instruction");
2235 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
2236 if (ErrorLoc == SMLoc())
2240 return Error(ErrorLoc, "invalid operand for instruction");
2242 case Match_MnemonicFail:
2243 return Error(IDLoc, "invalid instruction");
2244 case Match_RequiresDifferentSrcAndDst:
2245 return Error(IDLoc, "source and destination must be different");
2248 llvm_unreachable("Implement any new match types added!");
2251 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
2252 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
2253 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
2254 ") without \".set noat\"");
2257 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
2258 if (!AssemblerOptions.back()->isMacro())
2259 Warning(Loc, "macro instruction expanded into multiple instructions");
2263 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
2264 SMRange Range, bool ShowColors) {
2265 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
2266 Range, SMFixIt(Range, FixMsg),
2270 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
2273 CC = StringSwitch<unsigned>(Name)
2309 if (!(isABI_N32() || isABI_N64()))
2312 if (12 <= CC && CC <= 15) {
2313 // Name is one of t4-t7
2314 AsmToken RegTok = getLexer().peekTok();
2315 SMRange RegRange = RegTok.getLocRange();
2317 StringRef FixedName = StringSwitch<StringRef>(Name)
2323 assert(FixedName != "" && "Register name is not one of t4-t7.");
2325 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
2326 "Did you mean $" + FixedName + "?", RegRange);
2329 // Although SGI documentation just cuts out t0-t3 for n32/n64,
2330 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
2331 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
2332 if (8 <= CC && CC <= 11)
2336 CC = StringSwitch<unsigned>(Name)
2348 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
2351 CC = StringSwitch<unsigned>(Name)
2352 .Case("hwr_cpunum", 0)
2353 .Case("hwr_synci_step", 1)
2355 .Case("hwr_ccres", 3)
2356 .Case("hwr_ulr", 29)
2362 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2364 if (Name[0] == 'f') {
2365 StringRef NumString = Name.substr(1);
2367 if (NumString.getAsInteger(10, IntVal))
2368 return -1; // This is not an integer.
2369 if (IntVal > 31) // Maximum index for fpu register.
2376 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2378 if (Name.startswith("fcc")) {
2379 StringRef NumString = Name.substr(3);
2381 if (NumString.getAsInteger(10, IntVal))
2382 return -1; // This is not an integer.
2383 if (IntVal > 7) // There are only 8 fcc registers.
2390 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2392 if (Name.startswith("ac")) {
2393 StringRef NumString = Name.substr(2);
2395 if (NumString.getAsInteger(10, IntVal))
2396 return -1; // This is not an integer.
2397 if (IntVal > 3) // There are only 3 acc registers.
2404 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2407 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
2416 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
2419 CC = StringSwitch<unsigned>(Name)
2422 .Case("msaaccess", 2)
2424 .Case("msamodify", 4)
2425 .Case("msarequest", 5)
2427 .Case("msaunmap", 7)
2433 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
2434 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
2436 reportParseError(Loc,
2437 "pseudo-instruction requires $at, which is not available");
2440 unsigned AT = getReg(
2441 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
2445 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2446 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2449 unsigned MipsAsmParser::getGPR(int RegNo) {
2450 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2454 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2456 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2459 return getReg(RegClass, RegNum);
2462 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2463 MCAsmParser &Parser = getParser();
2464 DEBUG(dbgs() << "parseOperand\n");
2466 // Check if the current operand has a custom associated parser, if so, try to
2467 // custom parse the operand, or fallback to the general approach.
2468 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2469 if (ResTy == MatchOperand_Success)
2471 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2472 // there was a match, but an error occurred, in which case, just return that
2473 // the operand parsing failed.
2474 if (ResTy == MatchOperand_ParseFail)
2477 DEBUG(dbgs() << ".. Generic Parser\n");
2479 switch (getLexer().getKind()) {
2481 Error(Parser.getTok().getLoc(), "unexpected token in operand");
2483 case AsmToken::Dollar: {
2484 // Parse the register.
2485 SMLoc S = Parser.getTok().getLoc();
2487 // Almost all registers have been parsed by custom parsers. There is only
2488 // one exception to this. $zero (and it's alias $0) will reach this point
2489 // for div, divu, and similar instructions because it is not an operand
2490 // to the instruction definition but an explicit register. Special case
2491 // this situation for now.
2492 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
2495 // Maybe it is a symbol reference.
2496 StringRef Identifier;
2497 if (Parser.parseIdentifier(Identifier))
2500 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2501 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
2502 // Otherwise create a symbol reference.
2504 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
2506 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
2509 // Else drop to expression parsing.
2510 case AsmToken::LParen:
2511 case AsmToken::Minus:
2512 case AsmToken::Plus:
2513 case AsmToken::Integer:
2514 case AsmToken::Tilde:
2515 case AsmToken::String: {
2516 DEBUG(dbgs() << ".. generic integer\n");
2517 OperandMatchResultTy ResTy = parseImm(Operands);
2518 return ResTy != MatchOperand_Success;
2520 case AsmToken::Percent: {
2521 // It is a symbol reference or constant expression.
2522 const MCExpr *IdVal;
2523 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
2524 if (parseRelocOperand(IdVal))
2527 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2529 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2531 } // case AsmToken::Percent
2532 } // switch(getLexer().getKind())
2536 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
2537 StringRef RelocStr) {
2539 // Check the type of the expression.
2540 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
2541 // It's a constant, evaluate reloc value.
2543 switch (getVariantKind(RelocStr)) {
2544 case MCSymbolRefExpr::VK_Mips_ABS_LO:
2545 // Get the 1st 16-bits.
2546 Val = MCE->getValue() & 0xffff;
2548 case MCSymbolRefExpr::VK_Mips_ABS_HI:
2549 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
2550 // 16 bits being negative.
2551 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
2553 case MCSymbolRefExpr::VK_Mips_HIGHER:
2554 // Get the 3rd 16-bits.
2555 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
2557 case MCSymbolRefExpr::VK_Mips_HIGHEST:
2558 // Get the 4th 16-bits.
2559 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
2562 report_fatal_error("unsupported reloc value");
2564 return MCConstantExpr::Create(Val, getContext());
2567 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
2568 // It's a symbol, create a symbolic expression from the symbol.
2569 StringRef Symbol = MSRE->getSymbol().getName();
2570 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2571 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
2575 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2576 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2578 // Try to create target expression.
2579 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
2580 return MipsMCExpr::Create(VK, Expr, getContext());
2582 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
2583 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
2584 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
2588 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
2589 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
2590 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
2593 // Just return the original expression.
2597 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
2599 switch (Expr->getKind()) {
2600 case MCExpr::Constant:
2602 case MCExpr::SymbolRef:
2603 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
2604 case MCExpr::Binary:
2605 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2606 if (!isEvaluated(BE->getLHS()))
2608 return isEvaluated(BE->getRHS());
2611 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
2612 case MCExpr::Target:
2618 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
2619 MCAsmParser &Parser = getParser();
2620 Parser.Lex(); // Eat the % token.
2621 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
2622 if (Tok.isNot(AsmToken::Identifier))
2625 std::string Str = Tok.getIdentifier();
2627 Parser.Lex(); // Eat the identifier.
2628 // Now make an expression from the rest of the operand.
2629 const MCExpr *IdVal;
2632 if (getLexer().getKind() == AsmToken::LParen) {
2634 Parser.Lex(); // Eat the '(' token.
2635 if (getLexer().getKind() == AsmToken::Percent) {
2636 Parser.Lex(); // Eat the % token.
2637 const AsmToken &nextTok = Parser.getTok();
2638 if (nextTok.isNot(AsmToken::Identifier))
2641 Str += nextTok.getIdentifier();
2642 Parser.Lex(); // Eat the identifier.
2643 if (getLexer().getKind() != AsmToken::LParen)
2648 if (getParser().parseParenExpression(IdVal, EndLoc))
2651 while (getLexer().getKind() == AsmToken::RParen)
2652 Parser.Lex(); // Eat the ')' token.
2655 return true; // Parenthesis must follow the relocation operand.
2657 Res = evaluateRelocExpr(IdVal, Str);
2661 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2663 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2664 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2665 if (ResTy == MatchOperand_Success) {
2666 assert(Operands.size() == 1);
2667 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2668 StartLoc = Operand.getStartLoc();
2669 EndLoc = Operand.getEndLoc();
2671 // AFAIK, we only support numeric registers and named GPR's in CFI
2673 // Don't worry about eating tokens before failing. Using an unrecognised
2674 // register is a parse error.
2675 if (Operand.isGPRAsmReg()) {
2676 // Resolve to GPR32 or GPR64 appropriately.
2677 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2680 return (RegNo == (unsigned)-1);
2683 assert(Operands.size() == 0);
2684 return (RegNo == (unsigned)-1);
2687 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2688 MCAsmParser &Parser = getParser();
2692 while (getLexer().getKind() == AsmToken::LParen)
2695 switch (getLexer().getKind()) {
2698 case AsmToken::Identifier:
2699 case AsmToken::LParen:
2700 case AsmToken::Integer:
2701 case AsmToken::Minus:
2702 case AsmToken::Plus:
2704 Result = getParser().parseParenExpression(Res, S);
2706 Result = (getParser().parseExpression(Res));
2707 while (getLexer().getKind() == AsmToken::RParen)
2710 case AsmToken::Percent:
2711 Result = parseRelocOperand(Res);
2716 MipsAsmParser::OperandMatchResultTy
2717 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
2718 MCAsmParser &Parser = getParser();
2719 DEBUG(dbgs() << "parseMemOperand\n");
2720 const MCExpr *IdVal = nullptr;
2722 bool isParenExpr = false;
2723 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
2724 // First operand is the offset.
2725 S = Parser.getTok().getLoc();
2727 if (getLexer().getKind() == AsmToken::LParen) {
2732 if (getLexer().getKind() != AsmToken::Dollar) {
2733 if (parseMemOffset(IdVal, isParenExpr))
2734 return MatchOperand_ParseFail;
2736 const AsmToken &Tok = Parser.getTok(); // Get the next token.
2737 if (Tok.isNot(AsmToken::LParen)) {
2738 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2739 if (Mnemonic.getToken() == "la") {
2741 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2742 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2743 return MatchOperand_Success;
2745 if (Tok.is(AsmToken::EndOfStatement)) {
2747 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2749 // Zero register assumed, add a memory operand with ZERO as its base.
2750 // "Base" will be managed by k_Memory.
2751 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
2754 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2755 return MatchOperand_Success;
2757 Error(Parser.getTok().getLoc(), "'(' expected");
2758 return MatchOperand_ParseFail;
2761 Parser.Lex(); // Eat the '(' token.
2764 Res = parseAnyRegister(Operands);
2765 if (Res != MatchOperand_Success)
2768 if (Parser.getTok().isNot(AsmToken::RParen)) {
2769 Error(Parser.getTok().getLoc(), "')' expected");
2770 return MatchOperand_ParseFail;
2773 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2775 Parser.Lex(); // Eat the ')' token.
2778 IdVal = MCConstantExpr::Create(0, getContext());
2780 // Replace the register operand with the memory operand.
2781 std::unique_ptr<MipsOperand> op(
2782 static_cast<MipsOperand *>(Operands.back().release()));
2783 // Remove the register from the operands.
2784 // "op" will be managed by k_Memory.
2785 Operands.pop_back();
2786 // Add the memory operand.
2787 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2789 if (IdVal->EvaluateAsAbsolute(Imm))
2790 IdVal = MCConstantExpr::Create(Imm, getContext());
2791 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2792 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2796 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2797 return MatchOperand_Success;
2800 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2801 MCAsmParser &Parser = getParser();
2802 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
2804 SMLoc S = Parser.getTok().getLoc();
2806 if (Sym->isVariable())
2807 Expr = Sym->getVariableValue();
2810 if (Expr->getKind() == MCExpr::SymbolRef) {
2811 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2812 StringRef DefSymbol = Ref->getSymbol().getName();
2813 if (DefSymbol.startswith("$")) {
2814 OperandMatchResultTy ResTy =
2815 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2816 if (ResTy == MatchOperand_Success) {
2819 } else if (ResTy == MatchOperand_ParseFail)
2820 llvm_unreachable("Should never ParseFail");
2823 } else if (Expr->getKind() == MCExpr::Constant) {
2825 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2827 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2834 MipsAsmParser::OperandMatchResultTy
2835 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2836 StringRef Identifier,
2838 int Index = matchCPURegisterName(Identifier);
2840 Operands.push_back(MipsOperand::createGPRReg(
2841 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2842 return MatchOperand_Success;
2845 Index = matchHWRegsRegisterName(Identifier);
2847 Operands.push_back(MipsOperand::createHWRegsReg(
2848 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2849 return MatchOperand_Success;
2852 Index = matchFPURegisterName(Identifier);
2854 Operands.push_back(MipsOperand::createFGRReg(
2855 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2856 return MatchOperand_Success;
2859 Index = matchFCCRegisterName(Identifier);
2861 Operands.push_back(MipsOperand::createFCCReg(
2862 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2863 return MatchOperand_Success;
2866 Index = matchACRegisterName(Identifier);
2868 Operands.push_back(MipsOperand::createACCReg(
2869 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2870 return MatchOperand_Success;
2873 Index = matchMSA128RegisterName(Identifier);
2875 Operands.push_back(MipsOperand::createMSA128Reg(
2876 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2877 return MatchOperand_Success;
2880 Index = matchMSA128CtrlRegisterName(Identifier);
2882 Operands.push_back(MipsOperand::createMSACtrlReg(
2883 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2884 return MatchOperand_Success;
2887 return MatchOperand_NoMatch;
2890 MipsAsmParser::OperandMatchResultTy
2891 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2892 MCAsmParser &Parser = getParser();
2893 auto Token = Parser.getLexer().peekTok(false);
2895 if (Token.is(AsmToken::Identifier)) {
2896 DEBUG(dbgs() << ".. identifier\n");
2897 StringRef Identifier = Token.getIdentifier();
2898 OperandMatchResultTy ResTy =
2899 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2901 } else if (Token.is(AsmToken::Integer)) {
2902 DEBUG(dbgs() << ".. integer\n");
2903 Operands.push_back(MipsOperand::createNumericReg(
2904 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2906 return MatchOperand_Success;
2909 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2911 return MatchOperand_NoMatch;
2914 MipsAsmParser::OperandMatchResultTy
2915 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
2916 MCAsmParser &Parser = getParser();
2917 DEBUG(dbgs() << "parseAnyRegister\n");
2919 auto Token = Parser.getTok();
2921 SMLoc S = Token.getLoc();
2923 if (Token.isNot(AsmToken::Dollar)) {
2924 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2925 if (Token.is(AsmToken::Identifier)) {
2926 if (searchSymbolAlias(Operands))
2927 return MatchOperand_Success;
2929 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2930 return MatchOperand_NoMatch;
2932 DEBUG(dbgs() << ".. $\n");
2934 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
2935 if (ResTy == MatchOperand_Success) {
2937 Parser.Lex(); // identifier
2942 MipsAsmParser::OperandMatchResultTy
2943 MipsAsmParser::parseImm(OperandVector &Operands) {
2944 MCAsmParser &Parser = getParser();
2945 switch (getLexer().getKind()) {
2947 return MatchOperand_NoMatch;
2948 case AsmToken::LParen:
2949 case AsmToken::Minus:
2950 case AsmToken::Plus:
2951 case AsmToken::Integer:
2952 case AsmToken::Tilde:
2953 case AsmToken::String:
2957 const MCExpr *IdVal;
2958 SMLoc S = Parser.getTok().getLoc();
2959 if (getParser().parseExpression(IdVal))
2960 return MatchOperand_ParseFail;
2962 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2963 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2964 return MatchOperand_Success;
2967 MipsAsmParser::OperandMatchResultTy
2968 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
2969 MCAsmParser &Parser = getParser();
2970 DEBUG(dbgs() << "parseJumpTarget\n");
2972 SMLoc S = getLexer().getLoc();
2974 // Integers and expressions are acceptable
2975 OperandMatchResultTy ResTy = parseImm(Operands);
2976 if (ResTy != MatchOperand_NoMatch)
2979 // Registers are a valid target and have priority over symbols.
2980 ResTy = parseAnyRegister(Operands);
2981 if (ResTy != MatchOperand_NoMatch)
2984 const MCExpr *Expr = nullptr;
2985 if (Parser.parseExpression(Expr)) {
2986 // We have no way of knowing if a symbol was consumed so we must ParseFail
2987 return MatchOperand_ParseFail;
2990 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2991 return MatchOperand_Success;
2994 MipsAsmParser::OperandMatchResultTy
2995 MipsAsmParser::parseInvNum(OperandVector &Operands) {
2996 MCAsmParser &Parser = getParser();
2997 const MCExpr *IdVal;
2998 // If the first token is '$' we may have register operand.
2999 if (Parser.getTok().is(AsmToken::Dollar))
3000 return MatchOperand_NoMatch;
3001 SMLoc S = Parser.getTok().getLoc();
3002 if (getParser().parseExpression(IdVal))
3003 return MatchOperand_ParseFail;
3004 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
3005 assert(MCE && "Unexpected MCExpr type.");
3006 int64_t Val = MCE->getValue();
3007 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3008 Operands.push_back(MipsOperand::CreateImm(
3009 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
3010 return MatchOperand_Success;
3013 MipsAsmParser::OperandMatchResultTy
3014 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
3015 MCAsmParser &Parser = getParser();
3016 switch (getLexer().getKind()) {
3018 return MatchOperand_NoMatch;
3019 case AsmToken::LParen:
3020 case AsmToken::Plus:
3021 case AsmToken::Minus:
3022 case AsmToken::Integer:
3027 SMLoc S = Parser.getTok().getLoc();
3029 if (getParser().parseExpression(Expr))
3030 return MatchOperand_ParseFail;
3033 if (!Expr->EvaluateAsAbsolute(Val)) {
3034 Error(S, "expected immediate value");
3035 return MatchOperand_ParseFail;
3038 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
3039 // and because the CPU always adds one to the immediate field, the allowed
3040 // range becomes 1..4. We'll only check the range here and will deal
3041 // with the addition/subtraction when actually decoding/encoding
3043 if (Val < 1 || Val > 4) {
3044 Error(S, "immediate not in range (1..4)");
3045 return MatchOperand_ParseFail;
3049 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
3050 return MatchOperand_Success;
3053 MipsAsmParser::OperandMatchResultTy
3054 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3055 MCAsmParser &Parser = getParser();
3056 SmallVector<unsigned, 10> Regs;
3058 unsigned PrevReg = Mips::NoRegister;
3059 bool RegRange = false;
3060 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3062 if (Parser.getTok().isNot(AsmToken::Dollar))
3063 return MatchOperand_ParseFail;
3065 SMLoc S = Parser.getTok().getLoc();
3066 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3067 SMLoc E = getLexer().getLoc();
3068 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3069 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3071 // Remove last register operand because registers from register range
3072 // should be inserted first.
3073 if (RegNo == Mips::RA) {
3074 Regs.push_back(RegNo);
3076 unsigned TmpReg = PrevReg + 1;
3077 while (TmpReg <= RegNo) {
3078 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3079 Error(E, "invalid register operand");
3080 return MatchOperand_ParseFail;
3084 Regs.push_back(TmpReg++);
3090 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
3091 (RegNo != Mips::RA)) {
3092 Error(E, "$16 or $31 expected");
3093 return MatchOperand_ParseFail;
3094 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
3095 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3096 Error(E, "invalid register operand");
3097 return MatchOperand_ParseFail;
3098 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
3099 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3100 Error(E, "consecutive register numbers expected");
3101 return MatchOperand_ParseFail;
3104 Regs.push_back(RegNo);
3107 if (Parser.getTok().is(AsmToken::Minus))
3110 if (!Parser.getTok().isNot(AsmToken::Minus) &&
3111 !Parser.getTok().isNot(AsmToken::Comma)) {
3112 Error(E, "',' or '-' expected");
3113 return MatchOperand_ParseFail;
3116 Lex(); // Consume comma or minus
3117 if (Parser.getTok().isNot(AsmToken::Dollar))
3123 SMLoc E = Parser.getTok().getLoc();
3124 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3125 parseMemOperand(Operands);
3126 return MatchOperand_Success;
3129 MipsAsmParser::OperandMatchResultTy
3130 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
3131 MCAsmParser &Parser = getParser();
3133 SMLoc S = Parser.getTok().getLoc();
3134 if (parseAnyRegister(Operands) != MatchOperand_Success)
3135 return MatchOperand_ParseFail;
3137 SMLoc E = Parser.getTok().getLoc();
3138 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
3139 unsigned Reg = Op.getGPR32Reg();
3140 Operands.pop_back();
3141 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
3142 return MatchOperand_Success;
3145 MipsAsmParser::OperandMatchResultTy
3146 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
3147 MCAsmParser &Parser = getParser();
3148 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3149 SmallVector<unsigned, 10> Regs;
3151 if (Parser.getTok().isNot(AsmToken::Dollar))
3152 return MatchOperand_ParseFail;
3154 SMLoc S = Parser.getTok().getLoc();
3156 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3157 return MatchOperand_ParseFail;
3159 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3160 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3161 Regs.push_back(RegNo);
3163 SMLoc E = Parser.getTok().getLoc();
3164 if (Parser.getTok().isNot(AsmToken::Comma)) {
3165 Error(E, "',' expected");
3166 return MatchOperand_ParseFail;
3172 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3173 return MatchOperand_ParseFail;
3175 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3176 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3177 Regs.push_back(RegNo);
3179 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3181 return MatchOperand_Success;
3184 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
3186 MCSymbolRefExpr::VariantKind VK =
3187 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
3188 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
3189 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
3190 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
3191 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
3192 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
3193 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
3194 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
3195 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
3196 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
3197 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
3198 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
3199 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
3200 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
3201 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
3202 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
3203 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
3204 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
3205 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
3206 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
3207 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
3208 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
3209 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
3210 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
3211 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
3212 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
3213 .Default(MCSymbolRefExpr::VK_None);
3215 assert(VK != MCSymbolRefExpr::VK_None);
3220 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
3222 /// ::= '(', register, ')'
3223 /// handle it before we iterate so we don't get tripped up by the lack of
3225 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
3226 MCAsmParser &Parser = getParser();
3227 if (getLexer().is(AsmToken::LParen)) {
3229 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
3231 if (parseOperand(Operands, Name)) {
3232 SMLoc Loc = getLexer().getLoc();
3233 Parser.eatToEndOfStatement();
3234 return Error(Loc, "unexpected token in argument list");
3236 if (Parser.getTok().isNot(AsmToken::RParen)) {
3237 SMLoc Loc = getLexer().getLoc();
3238 Parser.eatToEndOfStatement();
3239 return Error(Loc, "unexpected token, expected ')'");
3242 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
3248 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
3249 /// either one of these.
3250 /// ::= '[', register, ']'
3251 /// ::= '[', integer, ']'
3252 /// handle it before we iterate so we don't get tripped up by the lack of
3254 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
3255 OperandVector &Operands) {
3256 MCAsmParser &Parser = getParser();
3257 if (getLexer().is(AsmToken::LBrac)) {
3259 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
3261 if (parseOperand(Operands, Name)) {
3262 SMLoc Loc = getLexer().getLoc();
3263 Parser.eatToEndOfStatement();
3264 return Error(Loc, "unexpected token in argument list");
3266 if (Parser.getTok().isNot(AsmToken::RBrac)) {
3267 SMLoc Loc = getLexer().getLoc();
3268 Parser.eatToEndOfStatement();
3269 return Error(Loc, "unexpected token, expected ']'");
3272 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
3278 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
3279 SMLoc NameLoc, OperandVector &Operands) {
3280 MCAsmParser &Parser = getParser();
3281 DEBUG(dbgs() << "ParseInstruction\n");
3283 // We have reached first instruction, module directive are now forbidden.
3284 getTargetStreamer().forbidModuleDirective();
3286 // Check if we have valid mnemonic
3287 if (!mnemonicIsValid(Name, 0)) {
3288 Parser.eatToEndOfStatement();
3289 return Error(NameLoc, "unknown instruction");
3291 // First operand in MCInst is instruction mnemonic.
3292 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
3294 // Read the remaining operands.
3295 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3296 // Read the first operand.
3297 if (parseOperand(Operands, Name)) {
3298 SMLoc Loc = getLexer().getLoc();
3299 Parser.eatToEndOfStatement();
3300 return Error(Loc, "unexpected token in argument list");
3302 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
3304 // AFAIK, parenthesis suffixes are never on the first operand
3306 while (getLexer().is(AsmToken::Comma)) {
3307 Parser.Lex(); // Eat the comma.
3308 // Parse and remember the operand.
3309 if (parseOperand(Operands, Name)) {
3310 SMLoc Loc = getLexer().getLoc();
3311 Parser.eatToEndOfStatement();
3312 return Error(Loc, "unexpected token in argument list");
3314 // Parse bracket and parenthesis suffixes before we iterate
3315 if (getLexer().is(AsmToken::LBrac)) {
3316 if (parseBracketSuffix(Name, Operands))
3318 } else if (getLexer().is(AsmToken::LParen) &&
3319 parseParenSuffix(Name, Operands))
3323 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3324 SMLoc Loc = getLexer().getLoc();
3325 Parser.eatToEndOfStatement();
3326 return Error(Loc, "unexpected token in argument list");
3328 Parser.Lex(); // Consume the EndOfStatement.
3332 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
3333 MCAsmParser &Parser = getParser();
3334 SMLoc Loc = getLexer().getLoc();
3335 Parser.eatToEndOfStatement();
3336 return Error(Loc, ErrorMsg);
3339 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
3340 return Error(Loc, ErrorMsg);
3343 bool MipsAsmParser::parseSetNoAtDirective() {
3344 MCAsmParser &Parser = getParser();
3345 // Line should look like: ".set noat".
3347 // Set the $at register to $0.
3348 AssemblerOptions.back()->setATRegIndex(0);
3350 Parser.Lex(); // Eat "noat".
3352 // If this is not the end of the statement, report an error.
3353 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3354 reportParseError("unexpected token, expected end of statement");
3358 getTargetStreamer().emitDirectiveSetNoAt();
3359 Parser.Lex(); // Consume the EndOfStatement.
3363 bool MipsAsmParser::parseSetAtDirective() {
3364 // Line can be: ".set at", which sets $at to $1
3365 // or ".set at=$reg", which sets $at to $reg.
3366 MCAsmParser &Parser = getParser();
3367 Parser.Lex(); // Eat "at".
3369 if (getLexer().is(AsmToken::EndOfStatement)) {
3370 // No register was specified, so we set $at to $1.
3371 AssemblerOptions.back()->setATRegIndex(1);
3373 getTargetStreamer().emitDirectiveSetAt();
3374 Parser.Lex(); // Consume the EndOfStatement.
3378 if (getLexer().isNot(AsmToken::Equal)) {
3379 reportParseError("unexpected token, expected equals sign");
3382 Parser.Lex(); // Eat "=".
3384 if (getLexer().isNot(AsmToken::Dollar)) {
3385 if (getLexer().is(AsmToken::EndOfStatement)) {
3386 reportParseError("no register specified");
3389 reportParseError("unexpected token, expected dollar sign '$'");
3393 Parser.Lex(); // Eat "$".
3395 // Find out what "reg" is.
3397 const AsmToken &Reg = Parser.getTok();
3398 if (Reg.is(AsmToken::Identifier)) {
3399 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
3400 } else if (Reg.is(AsmToken::Integer)) {
3401 AtRegNo = Reg.getIntVal();
3403 reportParseError("unexpected token, expected identifier or integer");
3407 // Check if $reg is a valid register. If it is, set $at to $reg.
3408 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
3409 reportParseError("invalid register");
3412 Parser.Lex(); // Eat "reg".
3414 // If this is not the end of the statement, report an error.
3415 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3416 reportParseError("unexpected token, expected end of statement");
3420 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
3422 Parser.Lex(); // Consume the EndOfStatement.
3426 bool MipsAsmParser::parseSetReorderDirective() {
3427 MCAsmParser &Parser = getParser();
3429 // If this is not the end of the statement, report an error.
3430 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3431 reportParseError("unexpected token, expected end of statement");
3434 AssemblerOptions.back()->setReorder();
3435 getTargetStreamer().emitDirectiveSetReorder();
3436 Parser.Lex(); // Consume the EndOfStatement.
3440 bool MipsAsmParser::parseSetNoReorderDirective() {
3441 MCAsmParser &Parser = getParser();
3443 // If this is not the end of the statement, report an error.
3444 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3445 reportParseError("unexpected token, expected end of statement");
3448 AssemblerOptions.back()->setNoReorder();
3449 getTargetStreamer().emitDirectiveSetNoReorder();
3450 Parser.Lex(); // Consume the EndOfStatement.
3454 bool MipsAsmParser::parseSetMacroDirective() {
3455 MCAsmParser &Parser = getParser();
3457 // If this is not the end of the statement, report an error.
3458 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3459 reportParseError("unexpected token, expected end of statement");
3462 AssemblerOptions.back()->setMacro();
3463 getTargetStreamer().emitDirectiveSetMacro();
3464 Parser.Lex(); // Consume the EndOfStatement.
3468 bool MipsAsmParser::parseSetNoMacroDirective() {
3469 MCAsmParser &Parser = getParser();
3471 // If this is not the end of the statement, report an error.
3472 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3473 reportParseError("unexpected token, expected end of statement");
3476 if (AssemblerOptions.back()->isReorder()) {
3477 reportParseError("`noreorder' must be set before `nomacro'");
3480 AssemblerOptions.back()->setNoMacro();
3481 getTargetStreamer().emitDirectiveSetNoMacro();
3482 Parser.Lex(); // Consume the EndOfStatement.
3486 bool MipsAsmParser::parseSetMsaDirective() {
3487 MCAsmParser &Parser = getParser();
3490 // If this is not the end of the statement, report an error.
3491 if (getLexer().isNot(AsmToken::EndOfStatement))
3492 return reportParseError("unexpected token, expected end of statement");
3494 setFeatureBits(Mips::FeatureMSA, "msa");
3495 getTargetStreamer().emitDirectiveSetMsa();
3499 bool MipsAsmParser::parseSetNoMsaDirective() {
3500 MCAsmParser &Parser = getParser();
3503 // If this is not the end of the statement, report an error.
3504 if (getLexer().isNot(AsmToken::EndOfStatement))
3505 return reportParseError("unexpected token, expected end of statement");
3507 clearFeatureBits(Mips::FeatureMSA, "msa");
3508 getTargetStreamer().emitDirectiveSetNoMsa();
3512 bool MipsAsmParser::parseSetNoDspDirective() {
3513 MCAsmParser &Parser = getParser();
3514 Parser.Lex(); // Eat "nodsp".
3516 // If this is not the end of the statement, report an error.
3517 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3518 reportParseError("unexpected token, expected end of statement");
3522 clearFeatureBits(Mips::FeatureDSP, "dsp");
3523 getTargetStreamer().emitDirectiveSetNoDsp();
3527 bool MipsAsmParser::parseSetMips16Directive() {
3528 MCAsmParser &Parser = getParser();
3529 Parser.Lex(); // Eat "mips16".
3531 // If this is not the end of the statement, report an error.
3532 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3533 reportParseError("unexpected token, expected end of statement");
3537 setFeatureBits(Mips::FeatureMips16, "mips16");
3538 getTargetStreamer().emitDirectiveSetMips16();
3539 Parser.Lex(); // Consume the EndOfStatement.
3543 bool MipsAsmParser::parseSetNoMips16Directive() {
3544 MCAsmParser &Parser = getParser();
3545 Parser.Lex(); // Eat "nomips16".
3547 // If this is not the end of the statement, report an error.
3548 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3549 reportParseError("unexpected token, expected end of statement");
3553 clearFeatureBits(Mips::FeatureMips16, "mips16");
3554 getTargetStreamer().emitDirectiveSetNoMips16();
3555 Parser.Lex(); // Consume the EndOfStatement.
3559 bool MipsAsmParser::parseSetFpDirective() {
3560 MCAsmParser &Parser = getParser();
3561 MipsABIFlagsSection::FpABIKind FpAbiVal;
3562 // Line can be: .set fp=32
3565 Parser.Lex(); // Eat fp token
3566 AsmToken Tok = Parser.getTok();
3567 if (Tok.isNot(AsmToken::Equal)) {
3568 reportParseError("unexpected token, expected equals sign '='");
3571 Parser.Lex(); // Eat '=' token.
3572 Tok = Parser.getTok();
3574 if (!parseFpABIValue(FpAbiVal, ".set"))
3577 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3578 reportParseError("unexpected token, expected end of statement");
3581 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
3582 Parser.Lex(); // Consume the EndOfStatement.
3586 bool MipsAsmParser::parseSetPopDirective() {
3587 MCAsmParser &Parser = getParser();
3588 SMLoc Loc = getLexer().getLoc();
3591 if (getLexer().isNot(AsmToken::EndOfStatement))
3592 return reportParseError("unexpected token, expected end of statement");
3594 // Always keep an element on the options "stack" to prevent the user
3595 // from changing the initial options. This is how we remember them.
3596 if (AssemblerOptions.size() == 2)
3597 return reportParseError(Loc, ".set pop with no .set push");
3599 AssemblerOptions.pop_back();
3600 setAvailableFeatures(AssemblerOptions.back()->getFeatures());
3602 getTargetStreamer().emitDirectiveSetPop();
3606 bool MipsAsmParser::parseSetPushDirective() {
3607 MCAsmParser &Parser = getParser();
3609 if (getLexer().isNot(AsmToken::EndOfStatement))
3610 return reportParseError("unexpected token, expected end of statement");
3612 // Create a copy of the current assembler options environment and push it.
3613 AssemblerOptions.push_back(
3614 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
3616 getTargetStreamer().emitDirectiveSetPush();
3620 bool MipsAsmParser::parseSetAssignment() {
3622 const MCExpr *Value;
3623 MCAsmParser &Parser = getParser();
3625 if (Parser.parseIdentifier(Name))
3626 reportParseError("expected identifier after .set");
3628 if (getLexer().isNot(AsmToken::Comma))
3629 return reportParseError("unexpected token, expected comma");
3632 if (Parser.parseExpression(Value))
3633 return reportParseError("expected valid expression after comma");
3635 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
3636 Sym->setVariableValue(Value);
3641 bool MipsAsmParser::parseSetMips0Directive() {
3642 MCAsmParser &Parser = getParser();
3644 if (getLexer().isNot(AsmToken::EndOfStatement))
3645 return reportParseError("unexpected token, expected end of statement");
3647 // Reset assembler options to their initial values.
3648 setAvailableFeatures(AssemblerOptions.front()->getFeatures());
3649 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
3651 getTargetStreamer().emitDirectiveSetMips0();
3655 bool MipsAsmParser::parseSetArchDirective() {
3656 MCAsmParser &Parser = getParser();
3658 if (getLexer().isNot(AsmToken::Equal))
3659 return reportParseError("unexpected token, expected equals sign");
3663 if (Parser.parseIdentifier(Arch))
3664 return reportParseError("expected arch identifier");
3666 StringRef ArchFeatureName =
3667 StringSwitch<StringRef>(Arch)
3668 .Case("mips1", "mips1")
3669 .Case("mips2", "mips2")
3670 .Case("mips3", "mips3")
3671 .Case("mips4", "mips4")
3672 .Case("mips5", "mips5")
3673 .Case("mips32", "mips32")
3674 .Case("mips32r2", "mips32r2")
3675 .Case("mips32r3", "mips32r3")
3676 .Case("mips32r5", "mips32r5")
3677 .Case("mips32r6", "mips32r6")
3678 .Case("mips64", "mips64")
3679 .Case("mips64r2", "mips64r2")
3680 .Case("mips64r3", "mips64r3")
3681 .Case("mips64r5", "mips64r5")
3682 .Case("mips64r6", "mips64r6")
3683 .Case("cnmips", "cnmips")
3684 .Case("r4000", "mips3") // This is an implementation of Mips3.
3687 if (ArchFeatureName.empty())
3688 return reportParseError("unsupported architecture");
3690 selectArch(ArchFeatureName);
3691 getTargetStreamer().emitDirectiveSetArch(Arch);
3695 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
3696 MCAsmParser &Parser = getParser();
3698 if (getLexer().isNot(AsmToken::EndOfStatement))
3699 return reportParseError("unexpected token, expected end of statement");
3703 llvm_unreachable("Unimplemented feature");
3704 case Mips::FeatureDSP:
3705 setFeatureBits(Mips::FeatureDSP, "dsp");
3706 getTargetStreamer().emitDirectiveSetDsp();
3708 case Mips::FeatureMicroMips:
3709 getTargetStreamer().emitDirectiveSetMicroMips();
3711 case Mips::FeatureMips1:
3712 selectArch("mips1");
3713 getTargetStreamer().emitDirectiveSetMips1();
3715 case Mips::FeatureMips2:
3716 selectArch("mips2");
3717 getTargetStreamer().emitDirectiveSetMips2();
3719 case Mips::FeatureMips3:
3720 selectArch("mips3");
3721 getTargetStreamer().emitDirectiveSetMips3();
3723 case Mips::FeatureMips4:
3724 selectArch("mips4");
3725 getTargetStreamer().emitDirectiveSetMips4();
3727 case Mips::FeatureMips5:
3728 selectArch("mips5");
3729 getTargetStreamer().emitDirectiveSetMips5();
3731 case Mips::FeatureMips32:
3732 selectArch("mips32");
3733 getTargetStreamer().emitDirectiveSetMips32();
3735 case Mips::FeatureMips32r2:
3736 selectArch("mips32r2");
3737 getTargetStreamer().emitDirectiveSetMips32R2();
3739 case Mips::FeatureMips32r3:
3740 selectArch("mips32r3");
3741 getTargetStreamer().emitDirectiveSetMips32R3();
3743 case Mips::FeatureMips32r5:
3744 selectArch("mips32r5");
3745 getTargetStreamer().emitDirectiveSetMips32R5();
3747 case Mips::FeatureMips32r6:
3748 selectArch("mips32r6");
3749 getTargetStreamer().emitDirectiveSetMips32R6();
3751 case Mips::FeatureMips64:
3752 selectArch("mips64");
3753 getTargetStreamer().emitDirectiveSetMips64();
3755 case Mips::FeatureMips64r2:
3756 selectArch("mips64r2");
3757 getTargetStreamer().emitDirectiveSetMips64R2();
3759 case Mips::FeatureMips64r3:
3760 selectArch("mips64r3");
3761 getTargetStreamer().emitDirectiveSetMips64R3();
3763 case Mips::FeatureMips64r5:
3764 selectArch("mips64r5");
3765 getTargetStreamer().emitDirectiveSetMips64R5();
3767 case Mips::FeatureMips64r6:
3768 selectArch("mips64r6");
3769 getTargetStreamer().emitDirectiveSetMips64R6();
3775 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
3776 MCAsmParser &Parser = getParser();
3777 if (getLexer().isNot(AsmToken::Comma)) {
3778 SMLoc Loc = getLexer().getLoc();
3779 Parser.eatToEndOfStatement();
3780 return Error(Loc, ErrorStr);
3783 Parser.Lex(); // Eat the comma.
3787 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
3788 if (AssemblerOptions.back()->isReorder())
3789 Warning(Loc, ".cpload should be inside a noreorder section");
3791 if (inMips16Mode()) {
3792 reportParseError(".cpload is not supported in Mips16 mode");
3796 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
3797 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
3798 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3799 reportParseError("expected register containing function address");
3803 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
3804 if (!RegOpnd.isGPRAsmReg()) {
3805 reportParseError(RegOpnd.getStartLoc(), "invalid register");
3809 // If this is not the end of the statement, report an error.
3810 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3811 reportParseError("unexpected token, expected end of statement");
3815 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
3819 bool MipsAsmParser::parseDirectiveCPSetup() {
3820 MCAsmParser &Parser = getParser();
3823 bool SaveIsReg = true;
3825 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3826 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3827 if (ResTy == MatchOperand_NoMatch) {
3828 reportParseError("expected register containing function address");
3829 Parser.eatToEndOfStatement();
3833 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3834 if (!FuncRegOpnd.isGPRAsmReg()) {
3835 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
3836 Parser.eatToEndOfStatement();
3840 FuncReg = FuncRegOpnd.getGPR32Reg();
3843 if (!eatComma("unexpected token, expected comma"))
3846 ResTy = parseAnyRegister(TmpReg);
3847 if (ResTy == MatchOperand_NoMatch) {
3848 const AsmToken &Tok = Parser.getTok();
3849 if (Tok.is(AsmToken::Integer)) {
3850 Save = Tok.getIntVal();
3854 reportParseError("expected save register or stack offset");
3855 Parser.eatToEndOfStatement();
3859 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3860 if (!SaveOpnd.isGPRAsmReg()) {
3861 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
3862 Parser.eatToEndOfStatement();
3865 Save = SaveOpnd.getGPR32Reg();
3868 if (!eatComma("unexpected token, expected comma"))
3872 if (Parser.parseExpression(Expr)) {
3873 reportParseError("expected expression");
3877 if (Expr->getKind() != MCExpr::SymbolRef) {
3878 reportParseError("expected symbol");
3881 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3883 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
3888 bool MipsAsmParser::parseDirectiveNaN() {
3889 MCAsmParser &Parser = getParser();
3890 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3891 const AsmToken &Tok = Parser.getTok();
3893 if (Tok.getString() == "2008") {
3895 getTargetStreamer().emitDirectiveNaN2008();
3897 } else if (Tok.getString() == "legacy") {
3899 getTargetStreamer().emitDirectiveNaNLegacy();
3903 // If we don't recognize the option passed to the .nan
3904 // directive (e.g. no option or unknown option), emit an error.
3905 reportParseError("invalid option in .nan directive");
3909 bool MipsAsmParser::parseDirectiveSet() {
3910 MCAsmParser &Parser = getParser();
3911 // Get the next token.
3912 const AsmToken &Tok = Parser.getTok();
3914 if (Tok.getString() == "noat") {
3915 return parseSetNoAtDirective();
3916 } else if (Tok.getString() == "at") {
3917 return parseSetAtDirective();
3918 } else if (Tok.getString() == "arch") {
3919 return parseSetArchDirective();
3920 } else if (Tok.getString() == "fp") {
3921 return parseSetFpDirective();
3922 } else if (Tok.getString() == "pop") {
3923 return parseSetPopDirective();
3924 } else if (Tok.getString() == "push") {
3925 return parseSetPushDirective();
3926 } else if (Tok.getString() == "reorder") {
3927 return parseSetReorderDirective();
3928 } else if (Tok.getString() == "noreorder") {
3929 return parseSetNoReorderDirective();
3930 } else if (Tok.getString() == "macro") {
3931 return parseSetMacroDirective();
3932 } else if (Tok.getString() == "nomacro") {
3933 return parseSetNoMacroDirective();
3934 } else if (Tok.getString() == "mips16") {
3935 return parseSetMips16Directive();
3936 } else if (Tok.getString() == "nomips16") {
3937 return parseSetNoMips16Directive();
3938 } else if (Tok.getString() == "nomicromips") {
3939 getTargetStreamer().emitDirectiveSetNoMicroMips();
3940 Parser.eatToEndOfStatement();
3942 } else if (Tok.getString() == "micromips") {
3943 return parseSetFeature(Mips::FeatureMicroMips);
3944 } else if (Tok.getString() == "mips0") {
3945 return parseSetMips0Directive();
3946 } else if (Tok.getString() == "mips1") {
3947 return parseSetFeature(Mips::FeatureMips1);
3948 } else if (Tok.getString() == "mips2") {
3949 return parseSetFeature(Mips::FeatureMips2);
3950 } else if (Tok.getString() == "mips3") {
3951 return parseSetFeature(Mips::FeatureMips3);
3952 } else if (Tok.getString() == "mips4") {
3953 return parseSetFeature(Mips::FeatureMips4);
3954 } else if (Tok.getString() == "mips5") {
3955 return parseSetFeature(Mips::FeatureMips5);
3956 } else if (Tok.getString() == "mips32") {
3957 return parseSetFeature(Mips::FeatureMips32);
3958 } else if (Tok.getString() == "mips32r2") {
3959 return parseSetFeature(Mips::FeatureMips32r2);
3960 } else if (Tok.getString() == "mips32r3") {
3961 return parseSetFeature(Mips::FeatureMips32r3);
3962 } else if (Tok.getString() == "mips32r5") {
3963 return parseSetFeature(Mips::FeatureMips32r5);
3964 } else if (Tok.getString() == "mips32r6") {
3965 return parseSetFeature(Mips::FeatureMips32r6);
3966 } else if (Tok.getString() == "mips64") {
3967 return parseSetFeature(Mips::FeatureMips64);
3968 } else if (Tok.getString() == "mips64r2") {
3969 return parseSetFeature(Mips::FeatureMips64r2);
3970 } else if (Tok.getString() == "mips64r3") {
3971 return parseSetFeature(Mips::FeatureMips64r3);
3972 } else if (Tok.getString() == "mips64r5") {
3973 return parseSetFeature(Mips::FeatureMips64r5);
3974 } else if (Tok.getString() == "mips64r6") {
3975 return parseSetFeature(Mips::FeatureMips64r6);
3976 } else if (Tok.getString() == "dsp") {
3977 return parseSetFeature(Mips::FeatureDSP);
3978 } else if (Tok.getString() == "nodsp") {
3979 return parseSetNoDspDirective();
3980 } else if (Tok.getString() == "msa") {
3981 return parseSetMsaDirective();
3982 } else if (Tok.getString() == "nomsa") {
3983 return parseSetNoMsaDirective();
3985 // It is just an identifier, look for an assignment.
3986 parseSetAssignment();
3993 /// parseDataDirective
3994 /// ::= .word [ expression (, expression)* ]
3995 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
3996 MCAsmParser &Parser = getParser();
3997 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3999 const MCExpr *Value;
4000 if (getParser().parseExpression(Value))
4003 getParser().getStreamer().EmitValue(Value, Size);
4005 if (getLexer().is(AsmToken::EndOfStatement))
4008 if (getLexer().isNot(AsmToken::Comma))
4009 return Error(L, "unexpected token, expected comma");
4018 /// parseDirectiveGpWord
4019 /// ::= .gpword local_sym
4020 bool MipsAsmParser::parseDirectiveGpWord() {
4021 MCAsmParser &Parser = getParser();
4022 const MCExpr *Value;
4023 // EmitGPRel32Value requires an expression, so we are using base class
4024 // method to evaluate the expression.
4025 if (getParser().parseExpression(Value))
4027 getParser().getStreamer().EmitGPRel32Value(Value);
4029 if (getLexer().isNot(AsmToken::EndOfStatement))
4030 return Error(getLexer().getLoc(),
4031 "unexpected token, expected end of statement");
4032 Parser.Lex(); // Eat EndOfStatement token.
4036 /// parseDirectiveGpDWord
4037 /// ::= .gpdword local_sym
4038 bool MipsAsmParser::parseDirectiveGpDWord() {
4039 MCAsmParser &Parser = getParser();
4040 const MCExpr *Value;
4041 // EmitGPRel64Value requires an expression, so we are using base class
4042 // method to evaluate the expression.
4043 if (getParser().parseExpression(Value))
4045 getParser().getStreamer().EmitGPRel64Value(Value);
4047 if (getLexer().isNot(AsmToken::EndOfStatement))
4048 return Error(getLexer().getLoc(),
4049 "unexpected token, expected end of statement");
4050 Parser.Lex(); // Eat EndOfStatement token.
4054 bool MipsAsmParser::parseDirectiveOption() {
4055 MCAsmParser &Parser = getParser();
4056 // Get the option token.
4057 AsmToken Tok = Parser.getTok();
4058 // At the moment only identifiers are supported.
4059 if (Tok.isNot(AsmToken::Identifier)) {
4060 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
4061 Parser.eatToEndOfStatement();
4065 StringRef Option = Tok.getIdentifier();
4067 if (Option == "pic0") {
4068 getTargetStreamer().emitDirectiveOptionPic0();
4070 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4071 Error(Parser.getTok().getLoc(),
4072 "unexpected token, expected end of statement");
4073 Parser.eatToEndOfStatement();
4078 if (Option == "pic2") {
4079 getTargetStreamer().emitDirectiveOptionPic2();
4081 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4082 Error(Parser.getTok().getLoc(),
4083 "unexpected token, expected end of statement");
4084 Parser.eatToEndOfStatement();
4090 Warning(Parser.getTok().getLoc(),
4091 "unknown option, expected 'pic0' or 'pic2'");
4092 Parser.eatToEndOfStatement();
4096 /// parseInsnDirective
4098 bool MipsAsmParser::parseInsnDirective() {
4099 // If this is not the end of the statement, report an error.
4100 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4101 reportParseError("unexpected token, expected end of statement");
4105 // The actual label marking happens in
4106 // MipsELFStreamer::createPendingLabelRelocs().
4107 getTargetStreamer().emitDirectiveInsn();
4109 getParser().Lex(); // Eat EndOfStatement token.
4113 /// parseDirectiveModule
4114 /// ::= .module oddspreg
4115 /// ::= .module nooddspreg
4116 /// ::= .module fp=value
4117 bool MipsAsmParser::parseDirectiveModule() {
4118 MCAsmParser &Parser = getParser();
4119 MCAsmLexer &Lexer = getLexer();
4120 SMLoc L = Lexer.getLoc();
4122 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
4123 // TODO : get a better message.
4124 reportParseError(".module directive must appear before any code");
4129 if (Parser.parseIdentifier(Option)) {
4130 reportParseError("expected .module option identifier");
4134 if (Option == "oddspreg") {
4135 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
4136 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4138 // If this is not the end of the statement, report an error.
4139 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4140 reportParseError("unexpected token, expected end of statement");
4144 return false; // parseDirectiveModule has finished successfully.
4145 } else if (Option == "nooddspreg") {
4147 Error(L, "'.module nooddspreg' requires the O32 ABI");
4151 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
4152 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4154 // If this is not the end of the statement, report an error.
4155 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4156 reportParseError("unexpected token, expected end of statement");
4160 return false; // parseDirectiveModule has finished successfully.
4161 } else if (Option == "fp") {
4162 return parseDirectiveModuleFP();
4164 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
4168 /// parseDirectiveModuleFP
4172 bool MipsAsmParser::parseDirectiveModuleFP() {
4173 MCAsmParser &Parser = getParser();
4174 MCAsmLexer &Lexer = getLexer();
4176 if (Lexer.isNot(AsmToken::Equal)) {
4177 reportParseError("unexpected token, expected equals sign '='");
4180 Parser.Lex(); // Eat '=' token.
4182 MipsABIFlagsSection::FpABIKind FpABI;
4183 if (!parseFpABIValue(FpABI, ".module"))
4186 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4187 reportParseError("unexpected token, expected end of statement");
4191 // Emit appropriate flags.
4192 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
4193 Parser.Lex(); // Consume the EndOfStatement.
4197 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
4198 StringRef Directive) {
4199 MCAsmParser &Parser = getParser();
4200 MCAsmLexer &Lexer = getLexer();
4202 if (Lexer.is(AsmToken::Identifier)) {
4203 StringRef Value = Parser.getTok().getString();
4206 if (Value != "xx") {
4207 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4212 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
4216 FpABI = MipsABIFlagsSection::FpABIKind::XX;
4220 if (Lexer.is(AsmToken::Integer)) {
4221 unsigned Value = Parser.getTok().getIntVal();
4224 if (Value != 32 && Value != 64) {
4225 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4231 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
4235 FpABI = MipsABIFlagsSection::FpABIKind::S32;
4237 FpABI = MipsABIFlagsSection::FpABIKind::S64;
4245 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
4246 MCAsmParser &Parser = getParser();
4247 StringRef IDVal = DirectiveID.getString();
4249 if (IDVal == ".cpload")
4250 return parseDirectiveCpLoad(DirectiveID.getLoc());
4251 if (IDVal == ".dword") {
4252 parseDataDirective(8, DirectiveID.getLoc());
4255 if (IDVal == ".ent") {
4256 StringRef SymbolName;
4258 if (Parser.parseIdentifier(SymbolName)) {
4259 reportParseError("expected identifier after .ent");
4263 // There's an undocumented extension that allows an integer to
4264 // follow the name of the procedure which AFAICS is ignored by GAS.
4265 // Example: .ent foo,2
4266 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4267 if (getLexer().isNot(AsmToken::Comma)) {
4268 // Even though we accept this undocumented extension for compatibility
4269 // reasons, the additional integer argument does not actually change
4270 // the behaviour of the '.ent' directive, so we would like to discourage
4271 // its use. We do this by not referring to the extended version in
4272 // error messages which are not directly related to its use.
4273 reportParseError("unexpected token, expected end of statement");
4276 Parser.Lex(); // Eat the comma.
4277 const MCExpr *DummyNumber;
4278 int64_t DummyNumberVal;
4279 // If the user was explicitly trying to use the extended version,
4280 // we still give helpful extension-related error messages.
4281 if (Parser.parseExpression(DummyNumber)) {
4282 reportParseError("expected number after comma");
4285 if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) {
4286 reportParseError("expected an absolute expression after comma");
4291 // If this is not the end of the statement, report an error.
4292 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4293 reportParseError("unexpected token, expected end of statement");
4297 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
4299 getTargetStreamer().emitDirectiveEnt(*Sym);
4304 if (IDVal == ".end") {
4305 StringRef SymbolName;
4307 if (Parser.parseIdentifier(SymbolName)) {
4308 reportParseError("expected identifier after .end");
4312 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4313 reportParseError("unexpected token, expected end of statement");
4317 if (CurrentFn == nullptr) {
4318 reportParseError(".end used without .ent");
4322 if ((SymbolName != CurrentFn->getName())) {
4323 reportParseError(".end symbol does not match .ent symbol");
4327 getTargetStreamer().emitDirectiveEnd(SymbolName);
4328 CurrentFn = nullptr;
4332 if (IDVal == ".frame") {
4333 // .frame $stack_reg, frame_size_in_bytes, $return_reg
4334 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4335 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4336 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4337 reportParseError("expected stack register");
4341 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4342 if (!StackRegOpnd.isGPRAsmReg()) {
4343 reportParseError(StackRegOpnd.getStartLoc(),
4344 "expected general purpose register");
4347 unsigned StackReg = StackRegOpnd.getGPR32Reg();
4349 if (Parser.getTok().is(AsmToken::Comma))
4352 reportParseError("unexpected token, expected comma");
4356 // Parse the frame size.
4357 const MCExpr *FrameSize;
4358 int64_t FrameSizeVal;
4360 if (Parser.parseExpression(FrameSize)) {
4361 reportParseError("expected frame size value");
4365 if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) {
4366 reportParseError("frame size not an absolute expression");
4370 if (Parser.getTok().is(AsmToken::Comma))
4373 reportParseError("unexpected token, expected comma");
4377 // Parse the return register.
4379 ResTy = parseAnyRegister(TmpReg);
4380 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4381 reportParseError("expected return register");
4385 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4386 if (!ReturnRegOpnd.isGPRAsmReg()) {
4387 reportParseError(ReturnRegOpnd.getStartLoc(),
4388 "expected general purpose register");
4392 // If this is not the end of the statement, report an error.
4393 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4394 reportParseError("unexpected token, expected end of statement");
4398 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
4399 ReturnRegOpnd.getGPR32Reg());
4403 if (IDVal == ".set") {
4404 return parseDirectiveSet();
4407 if (IDVal == ".mask" || IDVal == ".fmask") {
4408 // .mask bitmask, frame_offset
4409 // bitmask: One bit for each register used.
4410 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
4411 // first register is expected to be saved.
4413 // .mask 0x80000000, -4
4414 // .fmask 0x80000000, -4
4417 // Parse the bitmask
4418 const MCExpr *BitMask;
4421 if (Parser.parseExpression(BitMask)) {
4422 reportParseError("expected bitmask value");
4426 if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) {
4427 reportParseError("bitmask not an absolute expression");
4431 if (Parser.getTok().is(AsmToken::Comma))
4434 reportParseError("unexpected token, expected comma");
4438 // Parse the frame_offset
4439 const MCExpr *FrameOffset;
4440 int64_t FrameOffsetVal;
4442 if (Parser.parseExpression(FrameOffset)) {
4443 reportParseError("expected frame offset value");
4447 if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) {
4448 reportParseError("frame offset not an absolute expression");
4452 // If this is not the end of the statement, report an error.
4453 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4454 reportParseError("unexpected token, expected end of statement");
4458 if (IDVal == ".mask")
4459 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
4461 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
4465 if (IDVal == ".nan")
4466 return parseDirectiveNaN();
4468 if (IDVal == ".gpword") {
4469 parseDirectiveGpWord();
4473 if (IDVal == ".gpdword") {
4474 parseDirectiveGpDWord();
4478 if (IDVal == ".word") {
4479 parseDataDirective(4, DirectiveID.getLoc());
4483 if (IDVal == ".option")
4484 return parseDirectiveOption();
4486 if (IDVal == ".abicalls") {
4487 getTargetStreamer().emitDirectiveAbiCalls();
4488 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4489 Error(Parser.getTok().getLoc(),
4490 "unexpected token, expected end of statement");
4492 Parser.eatToEndOfStatement();
4497 if (IDVal == ".cpsetup")
4498 return parseDirectiveCPSetup();
4500 if (IDVal == ".module")
4501 return parseDirectiveModule();
4503 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
4504 return parseInternalDirectiveReallowModule();
4506 if (IDVal == ".insn")
4507 return parseInsnDirective();
4512 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
4513 // If this is not the end of the statement, report an error.
4514 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4515 reportParseError("unexpected token, expected end of statement");
4519 getTargetStreamer().reallowModuleDirective();
4521 getParser().Lex(); // Eat EndOfStatement token.
4525 extern "C" void LLVMInitializeMipsAsmParser() {
4526 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
4527 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
4528 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
4529 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
4532 #define GET_REGISTER_MATCHER
4533 #define GET_MATCHER_IMPLEMENTATION
4534 #include "MipsGenAsmMatcher.inc"