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);
456 /// MipsOperand - Instances of this class represent a parsed Mips machine
458 class MipsOperand : public MCParsedAsmOperand {
460 /// Broad categories of register classes
461 /// The exact class is finalized by the render method.
463 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
464 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
466 RegKind_FCC = 4, /// FCC
467 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
468 RegKind_MSACtrl = 16, /// MSA control registers
469 RegKind_COP2 = 32, /// COP2
470 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
472 RegKind_CCR = 128, /// CCR
473 RegKind_HWRegs = 256, /// HWRegs
474 RegKind_COP3 = 512, /// COP3
476 /// Potentially any (e.g. $1)
477 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
478 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
479 RegKind_CCR | RegKind_HWRegs | RegKind_COP3
484 k_Immediate, /// An immediate (possibly involving symbol references)
485 k_Memory, /// Base + Offset Memory Address
486 k_PhysRegister, /// A physical register from the Mips namespace
487 k_RegisterIndex, /// A register index in one or more RegKind.
488 k_Token, /// A simple token
489 k_RegList, /// A physical register list
490 k_RegPair /// A pair of physical register
494 MipsOperand(KindTy K, MipsAsmParser &Parser)
495 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
498 /// For diagnostics, and checking the assembler temporary
499 MipsAsmParser &AsmParser;
507 unsigned Num; /// Register Number
511 unsigned Index; /// Index into the register class
512 RegKind Kind; /// Bitfield of the kinds it could possibly be
513 const MCRegisterInfo *RegInfo;
526 SmallVector<unsigned, 10> *List;
531 struct PhysRegOp PhysReg;
532 struct RegIdxOp RegIdx;
535 struct RegListOp RegList;
538 SMLoc StartLoc, EndLoc;
540 /// Internal constructor for register kinds
541 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
542 const MCRegisterInfo *RegInfo,
544 MipsAsmParser &Parser) {
545 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
546 Op->RegIdx.Index = Index;
547 Op->RegIdx.RegInfo = RegInfo;
548 Op->RegIdx.Kind = RegKind;
555 /// Coerce the register to GPR32 and return the real register for the current
557 unsigned getGPR32Reg() const {
558 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
559 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
560 unsigned ClassID = Mips::GPR32RegClassID;
561 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
564 /// Coerce the register to GPR32 and return the real register for the current
566 unsigned getGPRMM16Reg() const {
567 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
568 unsigned ClassID = Mips::GPR32RegClassID;
569 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
572 /// Coerce the register to GPR64 and return the real register for the current
574 unsigned getGPR64Reg() const {
575 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
576 unsigned ClassID = Mips::GPR64RegClassID;
577 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
581 /// Coerce the register to AFGR64 and return the real register for the current
583 unsigned getAFGR64Reg() const {
584 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
585 if (RegIdx.Index % 2 != 0)
586 AsmParser.Warning(StartLoc, "Float register should be even.");
587 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
588 .getRegister(RegIdx.Index / 2);
591 /// Coerce the register to FGR64 and return the real register for the current
593 unsigned getFGR64Reg() const {
594 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
595 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
596 .getRegister(RegIdx.Index);
599 /// Coerce the register to FGR32 and return the real register for the current
601 unsigned getFGR32Reg() const {
602 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
603 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
604 .getRegister(RegIdx.Index);
607 /// Coerce the register to FGRH32 and return the real register for the current
609 unsigned getFGRH32Reg() const {
610 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
611 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
612 .getRegister(RegIdx.Index);
615 /// Coerce the register to FCC and return the real register for the current
617 unsigned getFCCReg() const {
618 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
619 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
620 .getRegister(RegIdx.Index);
623 /// Coerce the register to MSA128 and return the real register for the current
625 unsigned getMSA128Reg() const {
626 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
627 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
629 unsigned ClassID = Mips::MSA128BRegClassID;
630 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
633 /// Coerce the register to MSACtrl and return the real register for the
635 unsigned getMSACtrlReg() const {
636 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
637 unsigned ClassID = Mips::MSACtrlRegClassID;
638 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
641 /// Coerce the register to COP2 and return the real register for the
643 unsigned getCOP2Reg() const {
644 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
645 unsigned ClassID = Mips::COP2RegClassID;
646 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
649 /// Coerce the register to COP3 and return the real register for the
651 unsigned getCOP3Reg() const {
652 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
653 unsigned ClassID = Mips::COP3RegClassID;
654 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
657 /// Coerce the register to ACC64DSP and return the real register for the
659 unsigned getACC64DSPReg() const {
660 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
661 unsigned ClassID = Mips::ACC64DSPRegClassID;
662 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
665 /// Coerce the register to HI32DSP and return the real register for the
667 unsigned getHI32DSPReg() const {
668 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
669 unsigned ClassID = Mips::HI32DSPRegClassID;
670 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
673 /// Coerce the register to LO32DSP and return the real register for the
675 unsigned getLO32DSPReg() const {
676 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
677 unsigned ClassID = Mips::LO32DSPRegClassID;
678 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
681 /// Coerce the register to CCR and return the real register for the
683 unsigned getCCRReg() const {
684 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
685 unsigned ClassID = Mips::CCRRegClassID;
686 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
689 /// Coerce the register to HWRegs and return the real register for the
691 unsigned getHWRegsReg() const {
692 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
693 unsigned ClassID = Mips::HWRegsRegClassID;
694 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
698 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
699 // Add as immediate when possible. Null MCExpr = 0.
701 Inst.addOperand(MCOperand::createImm(0));
702 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
703 Inst.addOperand(MCOperand::createImm(CE->getValue()));
705 Inst.addOperand(MCOperand::createExpr(Expr));
708 void addRegOperands(MCInst &Inst, unsigned N) const {
709 llvm_unreachable("Use a custom parser instead");
712 /// Render the operand to an MCInst as a GPR32
713 /// Asserts if the wrong number of operands are requested, or the operand
714 /// is not a k_RegisterIndex compatible with RegKind_GPR
715 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
716 assert(N == 1 && "Invalid number of operands!");
717 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
720 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
721 assert(N == 1 && "Invalid number of operands!");
722 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
725 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
726 assert(N == 1 && "Invalid number of operands!");
727 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
730 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
731 assert(N == 1 && "Invalid number of operands!");
732 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
735 /// Render the operand to an MCInst as a GPR64
736 /// Asserts if the wrong number of operands are requested, or the operand
737 /// is not a k_RegisterIndex compatible with RegKind_GPR
738 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
739 assert(N == 1 && "Invalid number of operands!");
740 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
743 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
744 assert(N == 1 && "Invalid number of operands!");
745 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
748 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
749 assert(N == 1 && "Invalid number of operands!");
750 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
753 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
754 assert(N == 1 && "Invalid number of operands!");
755 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
756 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
757 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
758 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
762 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
763 assert(N == 1 && "Invalid number of operands!");
764 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
767 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
768 assert(N == 1 && "Invalid number of operands!");
769 Inst.addOperand(MCOperand::createReg(getFCCReg()));
772 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
773 assert(N == 1 && "Invalid number of operands!");
774 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
777 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
778 assert(N == 1 && "Invalid number of operands!");
779 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
782 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
783 assert(N == 1 && "Invalid number of operands!");
784 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
787 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
788 assert(N == 1 && "Invalid number of operands!");
789 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
792 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
793 assert(N == 1 && "Invalid number of operands!");
794 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
797 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
798 assert(N == 1 && "Invalid number of operands!");
799 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
802 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
803 assert(N == 1 && "Invalid number of operands!");
804 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
807 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
808 assert(N == 1 && "Invalid number of operands!");
809 Inst.addOperand(MCOperand::createReg(getCCRReg()));
812 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
813 assert(N == 1 && "Invalid number of operands!");
814 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
817 void addImmOperands(MCInst &Inst, unsigned N) const {
818 assert(N == 1 && "Invalid number of operands!");
819 const MCExpr *Expr = getImm();
823 void addMemOperands(MCInst &Inst, unsigned N) const {
824 assert(N == 2 && "Invalid number of operands!");
826 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPR32Reg()));
828 const MCExpr *Expr = getMemOff();
832 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
833 assert(N == 2 && "Invalid number of operands!");
835 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
837 const MCExpr *Expr = getMemOff();
841 void addRegListOperands(MCInst &Inst, unsigned N) const {
842 assert(N == 1 && "Invalid number of operands!");
844 for (auto RegNo : getRegList())
845 Inst.addOperand(MCOperand::createReg(RegNo));
848 void addRegPairOperands(MCInst &Inst, unsigned N) const {
849 assert(N == 2 && "Invalid number of operands!");
850 unsigned RegNo = getRegPair();
851 Inst.addOperand(MCOperand::createReg(RegNo++));
852 Inst.addOperand(MCOperand::createReg(RegNo));
855 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
856 assert(N == 2 && "Invalid number of operands!");
857 for (auto RegNo : getRegList())
858 Inst.addOperand(MCOperand::createReg(RegNo));
861 bool isReg() const override {
862 // As a special case until we sort out the definition of div/divu, pretend
863 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
864 if (isGPRAsmReg() && RegIdx.Index == 0)
867 return Kind == k_PhysRegister;
869 bool isRegIdx() const { return Kind == k_RegisterIndex; }
870 bool isImm() const override { return Kind == k_Immediate; }
871 bool isConstantImm() const {
872 return isImm() && dyn_cast<MCConstantExpr>(getImm());
874 bool isToken() const override {
875 // Note: It's not possible to pretend that other operand kinds are tokens.
876 // The matcher emitter checks tokens first.
877 return Kind == k_Token;
879 bool isMem() const override { return Kind == k_Memory; }
880 bool isConstantMemOff() const {
881 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
883 template <unsigned Bits> bool isMemWithSimmOffset() const {
884 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
886 bool isMemWithGRPMM16Base() const {
887 return isMem() && getMemBase()->isMM16AsmReg();
889 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
890 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
891 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
893 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
894 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
895 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
896 && (getMemBase()->getGPR32Reg() == Mips::SP);
898 bool isRegList16() const {
902 int Size = RegList.List->size();
903 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
904 RegList.List->back() != Mips::RA)
907 int PrevReg = *RegList.List->begin();
908 for (int i = 1; i < Size - 1; i++) {
909 int Reg = (*(RegList.List))[i];
910 if ( Reg != PrevReg + 1)
917 bool isInvNum() const { return Kind == k_Immediate; }
918 bool isLSAImm() const {
919 if (!isConstantImm())
921 int64_t Val = getConstantImm();
922 return 1 <= Val && Val <= 4;
924 bool isRegList() const { return Kind == k_RegList; }
925 bool isMovePRegPair() const {
926 if (Kind != k_RegList || RegList.List->size() != 2)
929 unsigned R0 = RegList.List->front();
930 unsigned R1 = RegList.List->back();
932 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
933 (R0 == Mips::A1 && R1 == Mips::A3) ||
934 (R0 == Mips::A2 && R1 == Mips::A3) ||
935 (R0 == Mips::A0 && R1 == Mips::S5) ||
936 (R0 == Mips::A0 && R1 == Mips::S6) ||
937 (R0 == Mips::A0 && R1 == Mips::A1) ||
938 (R0 == Mips::A0 && R1 == Mips::A2) ||
939 (R0 == Mips::A0 && R1 == Mips::A3))
945 StringRef getToken() const {
946 assert(Kind == k_Token && "Invalid access!");
947 return StringRef(Tok.Data, Tok.Length);
949 bool isRegPair() const { return Kind == k_RegPair; }
951 unsigned getReg() const override {
952 // As a special case until we sort out the definition of div/divu, pretend
953 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
954 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
955 RegIdx.Kind & RegKind_GPR)
956 return getGPR32Reg(); // FIXME: GPR64 too
958 assert(Kind == k_PhysRegister && "Invalid access!");
962 const MCExpr *getImm() const {
963 assert((Kind == k_Immediate) && "Invalid access!");
967 int64_t getConstantImm() const {
968 const MCExpr *Val = getImm();
969 return static_cast<const MCConstantExpr *>(Val)->getValue();
972 MipsOperand *getMemBase() const {
973 assert((Kind == k_Memory) && "Invalid access!");
977 const MCExpr *getMemOff() const {
978 assert((Kind == k_Memory) && "Invalid access!");
982 int64_t getConstantMemOff() const {
983 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
986 const SmallVectorImpl<unsigned> &getRegList() const {
987 assert((Kind == k_RegList) && "Invalid access!");
988 return *(RegList.List);
991 unsigned getRegPair() const {
992 assert((Kind == k_RegPair) && "Invalid access!");
996 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
997 MipsAsmParser &Parser) {
998 auto Op = make_unique<MipsOperand>(k_Token, Parser);
999 Op->Tok.Data = Str.data();
1000 Op->Tok.Length = Str.size();
1006 /// Create a numeric register (e.g. $1). The exact register remains
1007 /// unresolved until an instruction successfully matches
1008 static std::unique_ptr<MipsOperand>
1009 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1010 SMLoc E, MipsAsmParser &Parser) {
1011 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1012 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1015 /// Create a register that is definitely a GPR.
1016 /// This is typically only used for named registers such as $gp.
1017 static std::unique_ptr<MipsOperand>
1018 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1019 MipsAsmParser &Parser) {
1020 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1023 /// Create a register that is definitely a FGR.
1024 /// This is typically only used for named registers such as $f0.
1025 static std::unique_ptr<MipsOperand>
1026 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1027 MipsAsmParser &Parser) {
1028 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1031 /// Create a register that is definitely a HWReg.
1032 /// This is typically only used for named registers such as $hwr_cpunum.
1033 static std::unique_ptr<MipsOperand>
1034 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1035 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1036 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1039 /// Create a register that is definitely an FCC.
1040 /// This is typically only used for named registers such as $fcc0.
1041 static std::unique_ptr<MipsOperand>
1042 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1043 MipsAsmParser &Parser) {
1044 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1047 /// Create a register that is definitely an ACC.
1048 /// This is typically only used for named registers such as $ac0.
1049 static std::unique_ptr<MipsOperand>
1050 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1051 MipsAsmParser &Parser) {
1052 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1055 /// Create a register that is definitely an MSA128.
1056 /// This is typically only used for named registers such as $w0.
1057 static std::unique_ptr<MipsOperand>
1058 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1059 SMLoc E, MipsAsmParser &Parser) {
1060 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1063 /// Create a register that is definitely an MSACtrl.
1064 /// This is typically only used for named registers such as $msaaccess.
1065 static std::unique_ptr<MipsOperand>
1066 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1067 SMLoc E, MipsAsmParser &Parser) {
1068 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1071 static std::unique_ptr<MipsOperand>
1072 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1073 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1080 static std::unique_ptr<MipsOperand>
1081 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1082 SMLoc E, MipsAsmParser &Parser) {
1083 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1084 Op->Mem.Base = Base.release();
1091 static std::unique_ptr<MipsOperand>
1092 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1093 MipsAsmParser &Parser) {
1094 assert (Regs.size() > 0 && "Empty list not allowed");
1096 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1097 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1098 Op->StartLoc = StartLoc;
1099 Op->EndLoc = EndLoc;
1103 static std::unique_ptr<MipsOperand>
1104 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1105 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1106 Op->RegIdx.Index = RegNo;
1112 bool isGPRAsmReg() const {
1113 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1115 bool isMM16AsmReg() const {
1116 if (!(isRegIdx() && RegIdx.Kind))
1118 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1119 || RegIdx.Index == 16 || RegIdx.Index == 17);
1121 bool isMM16AsmRegZero() const {
1122 if (!(isRegIdx() && RegIdx.Kind))
1124 return (RegIdx.Index == 0 ||
1125 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1126 RegIdx.Index == 17);
1128 bool isMM16AsmRegMoveP() const {
1129 if (!(isRegIdx() && RegIdx.Kind))
1131 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1132 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1134 bool isFGRAsmReg() const {
1135 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1136 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1138 bool isHWRegsAsmReg() const {
1139 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1141 bool isCCRAsmReg() const {
1142 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1144 bool isFCCAsmReg() const {
1145 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1147 if (!AsmParser.hasEightFccRegisters())
1148 return RegIdx.Index == 0;
1149 return RegIdx.Index <= 7;
1151 bool isACCAsmReg() const {
1152 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1154 bool isCOP2AsmReg() const {
1155 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1157 bool isCOP3AsmReg() const {
1158 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1160 bool isMSA128AsmReg() const {
1161 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1163 bool isMSACtrlAsmReg() const {
1164 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1167 /// getStartLoc - Get the location of the first token of this operand.
1168 SMLoc getStartLoc() const override { return StartLoc; }
1169 /// getEndLoc - Get the location of the last token of this operand.
1170 SMLoc getEndLoc() const override { return EndLoc; }
1172 virtual ~MipsOperand() {
1180 delete RegList.List;
1181 case k_PhysRegister:
1182 case k_RegisterIndex:
1189 void print(raw_ostream &OS) const override {
1198 Mem.Base->print(OS);
1203 case k_PhysRegister:
1204 OS << "PhysReg<" << PhysReg.Num << ">";
1206 case k_RegisterIndex:
1207 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1214 for (auto Reg : (*RegList.List))
1219 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1223 }; // class MipsOperand
1227 extern const MCInstrDesc MipsInsts[];
1229 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1230 return MipsInsts[Opcode];
1233 static bool hasShortDelaySlot(unsigned Opcode) {
1236 case Mips::JALRS_MM:
1237 case Mips::JALRS16_MM:
1238 case Mips::BGEZALS_MM:
1239 case Mips::BLTZALS_MM:
1246 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1247 SmallVectorImpl<MCInst> &Instructions) {
1248 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1252 if (MCID.isBranch() || MCID.isCall()) {
1253 const unsigned Opcode = Inst.getOpcode();
1263 assert(hasCnMips() && "instruction only valid for octeon cpus");
1270 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1271 Offset = Inst.getOperand(2);
1272 if (!Offset.isImm())
1273 break; // We'll deal with this situation later on when applying fixups.
1274 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1275 return Error(IDLoc, "branch target out of range");
1276 if (OffsetToAlignment(Offset.getImm(),
1277 1LL << (inMicroMipsMode() ? 1 : 2)))
1278 return Error(IDLoc, "branch to misaligned address");
1292 case Mips::BGEZAL_MM:
1293 case Mips::BLTZAL_MM:
1296 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1297 Offset = Inst.getOperand(1);
1298 if (!Offset.isImm())
1299 break; // We'll deal with this situation later on when applying fixups.
1300 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1301 return Error(IDLoc, "branch target out of range");
1302 if (OffsetToAlignment(Offset.getImm(),
1303 1LL << (inMicroMipsMode() ? 1 : 2)))
1304 return Error(IDLoc, "branch to misaligned address");
1306 case Mips::BEQZ16_MM:
1307 case Mips::BNEZ16_MM:
1308 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1309 Offset = Inst.getOperand(1);
1310 if (!Offset.isImm())
1311 break; // We'll deal with this situation later on when applying fixups.
1312 if (!isIntN(8, Offset.getImm()))
1313 return Error(IDLoc, "branch target out of range");
1314 if (OffsetToAlignment(Offset.getImm(), 2LL))
1315 return Error(IDLoc, "branch to misaligned address");
1320 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1321 // We still accept it but it is a normal nop.
1322 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1323 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1324 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1329 const unsigned Opcode = Inst.getOpcode();
1341 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1342 // The offset is handled above
1343 Opnd = Inst.getOperand(1);
1345 return Error(IDLoc, "expected immediate operand kind");
1346 Imm = Opnd.getImm();
1347 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1348 Opcode == Mips::BBIT1 ? 63 : 31))
1349 return Error(IDLoc, "immediate operand value out of range");
1351 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1353 Inst.getOperand(1).setImm(Imm - 32);
1361 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1363 Opnd = Inst.getOperand(3);
1365 return Error(IDLoc, "expected immediate operand kind");
1366 Imm = Opnd.getImm();
1367 if (Imm < 0 || Imm > 31)
1368 return Error(IDLoc, "immediate operand value out of range");
1370 Opnd = Inst.getOperand(2);
1372 return Error(IDLoc, "expected immediate operand kind");
1373 Imm = Opnd.getImm();
1374 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1375 Opcode == Mips::EXTS ? 63 : 31))
1376 return Error(IDLoc, "immediate operand value out of range");
1378 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1379 Inst.getOperand(2).setImm(Imm - 32);
1385 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1386 Opnd = Inst.getOperand(2);
1388 return Error(IDLoc, "expected immediate operand kind");
1389 Imm = Opnd.getImm();
1390 if (!isInt<10>(Imm))
1391 return Error(IDLoc, "immediate operand value out of range");
1396 if (MCID.mayLoad() || MCID.mayStore()) {
1397 // Check the offset of memory operand, if it is a symbol
1398 // reference or immediate we may have to expand instructions.
1399 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1400 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1401 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1402 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1403 MCOperand &Op = Inst.getOperand(i);
1405 int MemOffset = Op.getImm();
1406 if (MemOffset < -32768 || MemOffset > 32767) {
1407 // Offset can't exceed 16bit value.
1408 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1411 } else if (Op.isExpr()) {
1412 const MCExpr *Expr = Op.getExpr();
1413 if (Expr->getKind() == MCExpr::SymbolRef) {
1414 const MCSymbolRefExpr *SR =
1415 static_cast<const MCSymbolRefExpr *>(Expr);
1416 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1418 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1421 } else if (!isEvaluated(Expr)) {
1422 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1430 if (inMicroMipsMode()) {
1431 if (MCID.mayLoad()) {
1432 // Try to create 16-bit GP relative load instruction.
1433 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1434 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1435 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1436 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1437 MCOperand &Op = Inst.getOperand(i);
1439 int MemOffset = Op.getImm();
1440 MCOperand &DstReg = Inst.getOperand(0);
1441 MCOperand &BaseReg = Inst.getOperand(1);
1442 if (isIntN(9, MemOffset) && (MemOffset % 4 == 0) &&
1443 getContext().getRegisterInfo()->getRegClass(
1444 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1445 BaseReg.getReg() == Mips::GP) {
1447 TmpInst.setLoc(IDLoc);
1448 TmpInst.setOpcode(Mips::LWGP_MM);
1449 TmpInst.addOperand(MCOperand::createReg(DstReg.getReg()));
1450 TmpInst.addOperand(MCOperand::createReg(Mips::GP));
1451 TmpInst.addOperand(MCOperand::createImm(MemOffset));
1452 Instructions.push_back(TmpInst);
1460 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1465 switch (Inst.getOpcode()) {
1468 case Mips::ADDIUS5_MM:
1469 Opnd = Inst.getOperand(2);
1471 return Error(IDLoc, "expected immediate operand kind");
1472 Imm = Opnd.getImm();
1473 if (Imm < -8 || Imm > 7)
1474 return Error(IDLoc, "immediate operand value out of range");
1476 case Mips::ADDIUSP_MM:
1477 Opnd = Inst.getOperand(0);
1479 return Error(IDLoc, "expected immediate operand kind");
1480 Imm = Opnd.getImm();
1481 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1483 return Error(IDLoc, "immediate operand value out of range");
1485 case Mips::SLL16_MM:
1486 case Mips::SRL16_MM:
1487 Opnd = Inst.getOperand(2);
1489 return Error(IDLoc, "expected immediate operand kind");
1490 Imm = Opnd.getImm();
1491 if (Imm < 1 || Imm > 8)
1492 return Error(IDLoc, "immediate operand value out of range");
1495 Opnd = Inst.getOperand(1);
1497 return Error(IDLoc, "expected immediate operand kind");
1498 Imm = Opnd.getImm();
1499 if (Imm < -1 || Imm > 126)
1500 return Error(IDLoc, "immediate operand value out of range");
1502 case Mips::ADDIUR2_MM:
1503 Opnd = Inst.getOperand(2);
1505 return Error(IDLoc, "expected immediate operand kind");
1506 Imm = Opnd.getImm();
1507 if (!(Imm == 1 || Imm == -1 ||
1508 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1509 return Error(IDLoc, "immediate operand value out of range");
1511 case Mips::ADDIUR1SP_MM:
1512 Opnd = Inst.getOperand(1);
1514 return Error(IDLoc, "expected immediate operand kind");
1515 Imm = Opnd.getImm();
1516 if (OffsetToAlignment(Imm, 4LL))
1517 return Error(IDLoc, "misaligned immediate operand value");
1518 if (Imm < 0 || Imm > 255)
1519 return Error(IDLoc, "immediate operand value out of range");
1521 case Mips::ANDI16_MM:
1522 Opnd = Inst.getOperand(2);
1524 return Error(IDLoc, "expected immediate operand kind");
1525 Imm = Opnd.getImm();
1526 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1527 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1528 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1529 return Error(IDLoc, "immediate operand value out of range");
1531 case Mips::LBU16_MM:
1532 Opnd = Inst.getOperand(2);
1534 return Error(IDLoc, "expected immediate operand kind");
1535 Imm = Opnd.getImm();
1536 if (Imm < -1 || Imm > 14)
1537 return Error(IDLoc, "immediate operand value out of range");
1540 Opnd = Inst.getOperand(2);
1542 return Error(IDLoc, "expected immediate operand kind");
1543 Imm = Opnd.getImm();
1544 if (Imm < 0 || Imm > 15)
1545 return Error(IDLoc, "immediate operand value out of range");
1547 case Mips::LHU16_MM:
1549 Opnd = Inst.getOperand(2);
1551 return Error(IDLoc, "expected immediate operand kind");
1552 Imm = Opnd.getImm();
1553 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1554 return Error(IDLoc, "immediate operand value out of range");
1558 Opnd = Inst.getOperand(2);
1560 return Error(IDLoc, "expected immediate operand kind");
1561 Imm = Opnd.getImm();
1562 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1563 return Error(IDLoc, "immediate operand value out of range");
1567 Opnd = Inst.getOperand(2);
1569 return Error(IDLoc, "expected immediate operand kind");
1570 Imm = Opnd.getImm();
1571 if (!isUInt<5>(Imm))
1572 return Error(IDLoc, "immediate operand value out of range");
1574 case Mips::ADDIUPC_MM:
1575 MCOperand Opnd = Inst.getOperand(1);
1577 return Error(IDLoc, "expected immediate operand kind");
1578 int Imm = Opnd.getImm();
1579 if ((Imm % 4 != 0) || !isIntN(25, Imm))
1580 return Error(IDLoc, "immediate operand value out of range");
1585 if (needsExpansion(Inst)) {
1586 if (expandInstruction(Inst, IDLoc, Instructions))
1589 Instructions.push_back(Inst);
1591 // If this instruction has a delay slot and .set reorder is active,
1592 // emit a NOP after it.
1593 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1594 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1599 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1601 switch (Inst.getOpcode()) {
1602 case Mips::LoadImm32:
1603 case Mips::LoadImm64:
1604 case Mips::LoadAddrImm32:
1605 case Mips::LoadAddrReg32:
1606 case Mips::B_MM_Pseudo:
1609 case Mips::JalOneReg:
1610 case Mips::JalTwoReg:
1617 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1618 SmallVectorImpl<MCInst> &Instructions) {
1619 switch (Inst.getOpcode()) {
1620 default: llvm_unreachable("unimplemented expansion");
1621 case Mips::LoadImm32:
1622 return expandLoadImm(Inst, true, IDLoc, Instructions);
1623 case Mips::LoadImm64:
1624 return expandLoadImm(Inst, false, IDLoc, Instructions);
1625 case Mips::LoadAddrImm32:
1626 return expandLoadAddressImm(Inst, true, IDLoc, Instructions);
1627 case Mips::LoadAddrReg32:
1628 return expandLoadAddressReg(Inst, true, IDLoc, Instructions);
1629 case Mips::B_MM_Pseudo:
1630 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1633 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
1634 case Mips::JalOneReg:
1635 case Mips::JalTwoReg:
1636 return expandJalWithRegs(Inst, IDLoc, Instructions);
1641 template <unsigned ShiftAmount>
1642 void createLShiftOri(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1643 SmallVectorImpl<MCInst> &Instructions) {
1645 if (ShiftAmount >= 32) {
1646 tmpInst.setOpcode(Mips::DSLL32);
1647 tmpInst.addOperand(MCOperand::createReg(RegNo));
1648 tmpInst.addOperand(MCOperand::createReg(RegNo));
1649 tmpInst.addOperand(MCOperand::createImm(ShiftAmount - 32));
1650 tmpInst.setLoc(IDLoc);
1651 Instructions.push_back(tmpInst);
1653 } else if (ShiftAmount > 0) {
1654 tmpInst.setOpcode(Mips::DSLL);
1655 tmpInst.addOperand(MCOperand::createReg(RegNo));
1656 tmpInst.addOperand(MCOperand::createReg(RegNo));
1657 tmpInst.addOperand(MCOperand::createImm(ShiftAmount));
1658 tmpInst.setLoc(IDLoc);
1659 Instructions.push_back(tmpInst);
1662 // There's no need for an ORi if the immediate is 0.
1663 if (Operand.isImm() && Operand.getImm() == 0)
1666 tmpInst.setOpcode(Mips::ORi);
1667 tmpInst.addOperand(MCOperand::createReg(RegNo));
1668 tmpInst.addOperand(MCOperand::createReg(RegNo));
1669 tmpInst.addOperand(Operand);
1670 tmpInst.setLoc(IDLoc);
1671 Instructions.push_back(tmpInst);
1674 template <unsigned ShiftAmount>
1675 void createLShiftOri(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1676 SmallVectorImpl<MCInst> &Instructions) {
1677 createLShiftOri<ShiftAmount>(MCOperand::createImm(Value), RegNo, IDLoc,
1682 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
1683 SmallVectorImpl<MCInst> &Instructions) {
1684 // Create a JALR instruction which is going to replace the pseudo-JAL.
1686 JalrInst.setLoc(IDLoc);
1687 const MCOperand FirstRegOp = Inst.getOperand(0);
1688 const unsigned Opcode = Inst.getOpcode();
1690 if (Opcode == Mips::JalOneReg) {
1691 // jal $rs => jalr $rs
1692 if (inMicroMipsMode()) {
1693 JalrInst.setOpcode(Mips::JALR16_MM);
1694 JalrInst.addOperand(FirstRegOp);
1696 JalrInst.setOpcode(Mips::JALR);
1697 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1698 JalrInst.addOperand(FirstRegOp);
1700 } else if (Opcode == Mips::JalTwoReg) {
1701 // jal $rd, $rs => jalr $rd, $rs
1702 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1703 JalrInst.addOperand(FirstRegOp);
1704 const MCOperand SecondRegOp = Inst.getOperand(1);
1705 JalrInst.addOperand(SecondRegOp);
1707 Instructions.push_back(JalrInst);
1709 // If .set reorder is active, emit a NOP after it.
1710 if (AssemblerOptions.back()->isReorder()) {
1711 // This is a 32-bit NOP because these 2 pseudo-instructions
1712 // do not have a short delay slot.
1714 NopInst.setOpcode(Mips::SLL);
1715 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
1716 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
1717 NopInst.addOperand(MCOperand::createImm(0));
1718 Instructions.push_back(NopInst);
1724 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
1725 unsigned SrcReg, bool Is32BitImm, SMLoc IDLoc,
1726 SmallVectorImpl<MCInst> &Instructions) {
1727 if (!Is32BitImm && !isGP64bit()) {
1728 Error(IDLoc, "instruction requires a 64-bit architecture");
1732 bool UseSrcReg = false;
1733 if (SrcReg != Mips::NoRegister)
1738 tmpInst.setLoc(IDLoc);
1739 // FIXME: gas has a special case for values that are 000...1111, which
1740 // becomes a li -1 and then a dsrl
1741 if (0 <= ImmValue && ImmValue <= 65535) {
1742 // For unsigned and positive signed 16-bit values (0 <= j <= 65535):
1743 // li d,j => ori d,$zero,j
1745 SrcReg = isGP64bit() ? Mips::ZERO_64 : Mips::ZERO;
1746 tmpInst.setOpcode(Mips::ORi);
1747 tmpInst.addOperand(MCOperand::createReg(DstReg));
1748 tmpInst.addOperand(MCOperand::createReg(SrcReg));
1749 tmpInst.addOperand(MCOperand::createImm(ImmValue));
1750 Instructions.push_back(tmpInst);
1751 } else if (ImmValue < 0 && ImmValue >= -32768) {
1752 // For negative signed 16-bit values (-32768 <= j < 0):
1753 // li d,j => addiu d,$zero,j
1755 SrcReg = Mips::ZERO;
1756 tmpInst.setOpcode(Mips::ADDiu);
1757 tmpInst.addOperand(MCOperand::createReg(DstReg));
1758 tmpInst.addOperand(MCOperand::createReg(SrcReg));
1759 tmpInst.addOperand(MCOperand::createImm(ImmValue));
1760 Instructions.push_back(tmpInst);
1761 } else if ((ImmValue & 0xffffffff) == ImmValue) {
1762 // For all other values which are representable as a 32-bit integer:
1763 // li d,j => lui d,hi16(j)
1765 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1766 uint16_t Bits15To0 = ImmValue & 0xffff;
1768 tmpInst.setOpcode(Mips::LUi);
1769 tmpInst.addOperand(MCOperand::createReg(DstReg));
1770 tmpInst.addOperand(MCOperand::createImm(Bits31To16));
1771 Instructions.push_back(tmpInst);
1772 createLShiftOri<0>(Bits15To0, DstReg, IDLoc, Instructions);
1775 createAddu(DstReg, DstReg, SrcReg, Instructions);
1777 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1779 Error(IDLoc, "instruction requires a 32-bit immediate");
1783 // <------- lo32 ------>
1784 // <------- hi32 ------>
1785 // <- hi16 -> <- lo16 ->
1786 // _________________________________
1788 // | 16-bits | 16-bits | 16-bits |
1789 // |__________|__________|__________|
1791 // For any 64-bit value that is representable as a 48-bit integer:
1792 // li d,j => lui d,hi16(j)
1793 // ori d,d,hi16(lo32(j))
1795 // ori d,d,lo16(lo32(j))
1796 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1797 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1798 uint16_t Bits15To0 = ImmValue & 0xffff;
1800 tmpInst.setOpcode(Mips::LUi);
1801 tmpInst.addOperand(MCOperand::createReg(DstReg));
1802 tmpInst.addOperand(MCOperand::createImm(Bits47To32));
1803 Instructions.push_back(tmpInst);
1804 createLShiftOri<0>(Bits31To16, DstReg, IDLoc, Instructions);
1805 createLShiftOri<16>(Bits15To0, DstReg, IDLoc, Instructions);
1808 createAddu(DstReg, DstReg, SrcReg, Instructions);
1812 Error(IDLoc, "instruction requires a 32-bit immediate");
1816 // <------- hi32 ------> <------- lo32 ------>
1817 // <- hi16 -> <- lo16 ->
1818 // ___________________________________________
1820 // | 16-bits | 16-bits | 16-bits | 16-bits |
1821 // |__________|__________|__________|__________|
1823 // For all other values which are representable as a 64-bit integer:
1824 // li d,j => lui d,hi16(j)
1825 // ori d,d,lo16(hi32(j))
1827 // ori d,d,hi16(lo32(j))
1829 // ori d,d,lo16(lo32(j))
1830 uint16_t Bits63To48 = (ImmValue >> 48) & 0xffff;
1831 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1832 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1833 uint16_t Bits15To0 = ImmValue & 0xffff;
1835 tmpInst.setOpcode(Mips::LUi);
1836 tmpInst.addOperand(MCOperand::createReg(DstReg));
1837 tmpInst.addOperand(MCOperand::createImm(Bits63To48));
1838 Instructions.push_back(tmpInst);
1839 createLShiftOri<0>(Bits47To32, DstReg, IDLoc, Instructions);
1841 // When Bits31To16 is 0, do a left shift of 32 bits instead of doing
1842 // two left shifts of 16 bits.
1843 if (Bits31To16 == 0) {
1844 createLShiftOri<32>(Bits15To0, DstReg, IDLoc, Instructions);
1846 createLShiftOri<16>(Bits31To16, DstReg, IDLoc, Instructions);
1847 createLShiftOri<16>(Bits15To0, DstReg, IDLoc, Instructions);
1851 createAddu(DstReg, DstReg, SrcReg, Instructions);
1856 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1857 SmallVectorImpl<MCInst> &Instructions) {
1858 const MCOperand &ImmOp = Inst.getOperand(1);
1859 assert(ImmOp.isImm() && "expected immediate operand kind");
1860 const MCOperand &DstRegOp = Inst.getOperand(0);
1861 assert(DstRegOp.isReg() && "expected register operand kind");
1863 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
1864 Is32BitImm, IDLoc, Instructions))
1871 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1872 SmallVectorImpl<MCInst> &Instructions) {
1873 const MCOperand &DstRegOp = Inst.getOperand(0);
1874 assert(DstRegOp.isReg() && "expected register operand kind");
1876 const MCOperand &ImmOp = Inst.getOperand(2);
1877 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1878 "expected immediate operand kind");
1879 if (!ImmOp.isImm()) {
1880 expandLoadAddressSym(DstRegOp, ImmOp, Is32BitImm, IDLoc, Instructions);
1883 const MCOperand &SrcRegOp = Inst.getOperand(1);
1884 assert(SrcRegOp.isReg() && "expected register operand kind");
1886 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), SrcRegOp.getReg(),
1887 Is32BitImm, IDLoc, Instructions))
1894 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1895 SmallVectorImpl<MCInst> &Instructions) {
1896 const MCOperand &DstRegOp = Inst.getOperand(0);
1897 assert(DstRegOp.isReg() && "expected register operand kind");
1899 const MCOperand &ImmOp = Inst.getOperand(1);
1900 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1901 "expected immediate operand kind");
1902 if (!ImmOp.isImm()) {
1903 expandLoadAddressSym(DstRegOp, ImmOp, Is32BitImm, IDLoc, Instructions);
1907 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
1908 Is32BitImm, IDLoc, Instructions))
1914 void MipsAsmParser::expandLoadAddressSym(
1915 const MCOperand &DstRegOp, const MCOperand &SymOp, bool Is32BitSym,
1916 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1917 if (Is32BitSym && isABI_N64())
1918 Warning(IDLoc, "instruction loads the 32-bit address of a 64-bit symbol");
1921 unsigned RegNo = DstRegOp.getReg();
1922 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
1923 const MCSymbolRefExpr *HiExpr =
1924 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1925 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1926 const MCSymbolRefExpr *LoExpr =
1927 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1928 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1930 // If it's a 64-bit architecture, expand to:
1931 // la d,sym => lui d,highest(sym)
1932 // ori d,d,higher(sym)
1934 // ori d,d,hi16(sym)
1936 // ori d,d,lo16(sym)
1937 const MCSymbolRefExpr *HighestExpr =
1938 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1939 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1940 const MCSymbolRefExpr *HigherExpr =
1941 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1942 MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1944 tmpInst.setOpcode(Mips::LUi);
1945 tmpInst.addOperand(MCOperand::createReg(RegNo));
1946 tmpInst.addOperand(MCOperand::createExpr(HighestExpr));
1947 Instructions.push_back(tmpInst);
1949 createLShiftOri<0>(MCOperand::createExpr(HigherExpr), RegNo, SMLoc(),
1951 createLShiftOri<16>(MCOperand::createExpr(HiExpr), RegNo, SMLoc(),
1953 createLShiftOri<16>(MCOperand::createExpr(LoExpr), RegNo, SMLoc(),
1956 // Otherwise, expand to:
1957 // la d,sym => lui d,hi16(sym)
1958 // ori d,d,lo16(sym)
1959 tmpInst.setOpcode(Mips::LUi);
1960 tmpInst.addOperand(MCOperand::createReg(RegNo));
1961 tmpInst.addOperand(MCOperand::createExpr(HiExpr));
1962 Instructions.push_back(tmpInst);
1964 createLShiftOri<0>(MCOperand::createExpr(LoExpr), RegNo, SMLoc(),
1969 bool MipsAsmParser::expandUncondBranchMMPseudo(
1970 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1971 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
1972 "unexpected number of operands");
1974 MCOperand Offset = Inst.getOperand(0);
1975 if (Offset.isExpr()) {
1977 Inst.setOpcode(Mips::BEQ_MM);
1978 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
1979 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
1980 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
1982 assert(Offset.isImm() && "expected immediate operand kind");
1983 if (isIntN(11, Offset.getImm())) {
1984 // If offset fits into 11 bits then this instruction becomes microMIPS
1985 // 16-bit unconditional branch instruction.
1986 Inst.setOpcode(Mips::B16_MM);
1988 if (!isIntN(17, Offset.getImm()))
1989 Error(IDLoc, "branch target out of range");
1990 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
1991 Error(IDLoc, "branch to misaligned address");
1993 Inst.setOpcode(Mips::BEQ_MM);
1994 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
1995 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
1996 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
1999 Instructions.push_back(Inst);
2001 // If .set reorder is active, emit a NOP after the branch instruction.
2002 if (AssemblerOptions.back()->isReorder())
2003 createNop(true, IDLoc, Instructions);
2008 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2009 SmallVectorImpl<MCInst> &Instructions,
2010 bool isLoad, bool isImmOpnd) {
2011 const MCSymbolRefExpr *SR;
2013 unsigned ImmOffset, HiOffset, LoOffset;
2014 const MCExpr *ExprOffset;
2016 // 1st operand is either the source or destination register.
2017 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2018 unsigned RegOpNum = Inst.getOperand(0).getReg();
2019 // 2nd operand is the base register.
2020 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2021 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2022 // 3rd operand is either an immediate or expression.
2024 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2025 ImmOffset = Inst.getOperand(2).getImm();
2026 LoOffset = ImmOffset & 0x0000ffff;
2027 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2028 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2029 if (LoOffset & 0x8000)
2032 ExprOffset = Inst.getOperand(2).getExpr();
2033 // All instructions will have the same location.
2034 TempInst.setLoc(IDLoc);
2035 // These are some of the types of expansions we perform here:
2036 // 1) lw $8, sym => lui $8, %hi(sym)
2037 // lw $8, %lo(sym)($8)
2038 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2040 // lw $8, %lo(offset)($9)
2041 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2043 // lw $8, %lo(offset)($at)
2044 // 4) sw $8, sym => lui $at, %hi(sym)
2045 // sw $8, %lo(sym)($at)
2046 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2048 // sw $8, %lo(offset)($at)
2049 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2050 // ldc1 $f0, %lo(sym)($at)
2052 // For load instructions we can use the destination register as a temporary
2053 // if base and dst are different (examples 1 and 2) and if the base register
2054 // is general purpose otherwise we must use $at (example 6) and error if it's
2055 // not available. For stores we must use $at (examples 4 and 5) because we
2056 // must not clobber the source register setting up the offset.
2057 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2058 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2059 unsigned RegClassIDOp0 =
2060 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2061 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2062 (RegClassIDOp0 == Mips::GPR64RegClassID);
2063 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2064 TmpRegNum = RegOpNum;
2066 // At this point we need AT to perform the expansions and we exit if it is
2068 TmpRegNum = getATReg(IDLoc);
2073 TempInst.setOpcode(Mips::LUi);
2074 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2076 TempInst.addOperand(MCOperand::createImm(HiOffset));
2078 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2079 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
2080 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
2081 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
2083 TempInst.addOperand(MCOperand::createExpr(HiExpr));
2085 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2086 TempInst.addOperand(MCOperand::createExpr(HiExpr));
2089 // Add the instruction to the list.
2090 Instructions.push_back(TempInst);
2091 // Prepare TempInst for next instruction.
2093 // Add temp register to base.
2094 if (BaseRegNum != Mips::ZERO) {
2095 TempInst.setOpcode(Mips::ADDu);
2096 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2097 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2098 TempInst.addOperand(MCOperand::createReg(BaseRegNum));
2099 Instructions.push_back(TempInst);
2102 // And finally, create original instruction with low part
2103 // of offset and new base.
2104 TempInst.setOpcode(Inst.getOpcode());
2105 TempInst.addOperand(MCOperand::createReg(RegOpNum));
2106 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2108 TempInst.addOperand(MCOperand::createImm(LoOffset));
2110 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2111 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
2112 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
2114 TempInst.addOperand(MCOperand::createExpr(LoExpr));
2116 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2117 TempInst.addOperand(MCOperand::createExpr(LoExpr));
2120 Instructions.push_back(TempInst);
2125 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2126 SmallVectorImpl<MCInst> &Instructions) {
2127 unsigned OpNum = Inst.getNumOperands();
2128 unsigned Opcode = Inst.getOpcode();
2129 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2131 assert (Inst.getOperand(OpNum - 1).isImm() &&
2132 Inst.getOperand(OpNum - 2).isReg() &&
2133 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2135 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2136 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2137 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2138 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2139 // It can be implemented as SWM16 or LWM16 instruction.
2140 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2142 Inst.setOpcode(NewOpcode);
2143 Instructions.push_back(Inst);
2147 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
2148 SmallVectorImpl<MCInst> &Instructions) {
2150 if (hasShortDelaySlot) {
2151 NopInst.setOpcode(Mips::MOVE16_MM);
2152 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2153 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2155 NopInst.setOpcode(Mips::SLL);
2156 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2157 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2158 NopInst.addOperand(MCOperand::createImm(0));
2160 Instructions.push_back(NopInst);
2163 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
2165 SmallVectorImpl<MCInst> &Instructions) {
2167 AdduInst.setOpcode(Mips::ADDu);
2168 AdduInst.addOperand(MCOperand::createReg(DstReg));
2169 AdduInst.addOperand(MCOperand::createReg(SrcReg));
2170 AdduInst.addOperand(MCOperand::createReg(TrgReg));
2171 Instructions.push_back(AdduInst);
2174 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
2175 // As described by the Mips32r2 spec, the registers Rd and Rs for
2176 // jalr.hb must be different.
2177 unsigned Opcode = Inst.getOpcode();
2179 if (Opcode == Mips::JALR_HB &&
2180 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
2181 return Match_RequiresDifferentSrcAndDst;
2183 return Match_Success;
2186 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2187 OperandVector &Operands,
2189 uint64_t &ErrorInfo,
2190 bool MatchingInlineAsm) {
2193 SmallVector<MCInst, 8> Instructions;
2194 unsigned MatchResult =
2195 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
2197 switch (MatchResult) {
2198 case Match_Success: {
2199 if (processInstruction(Inst, IDLoc, Instructions))
2201 for (unsigned i = 0; i < Instructions.size(); i++)
2202 Out.EmitInstruction(Instructions[i], STI);
2205 case Match_MissingFeature:
2206 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2208 case Match_InvalidOperand: {
2209 SMLoc ErrorLoc = IDLoc;
2210 if (ErrorInfo != ~0ULL) {
2211 if (ErrorInfo >= Operands.size())
2212 return Error(IDLoc, "too few operands for instruction");
2214 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
2215 if (ErrorLoc == SMLoc())
2219 return Error(ErrorLoc, "invalid operand for instruction");
2221 case Match_MnemonicFail:
2222 return Error(IDLoc, "invalid instruction");
2223 case Match_RequiresDifferentSrcAndDst:
2224 return Error(IDLoc, "source and destination must be different");
2227 llvm_unreachable("Implement any new match types added!");
2230 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
2231 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
2232 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
2233 ") without \".set noat\"");
2237 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
2238 SMRange Range, bool ShowColors) {
2239 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
2240 Range, SMFixIt(Range, FixMsg),
2244 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
2247 CC = StringSwitch<unsigned>(Name)
2283 if (!(isABI_N32() || isABI_N64()))
2286 if (12 <= CC && CC <= 15) {
2287 // Name is one of t4-t7
2288 AsmToken RegTok = getLexer().peekTok();
2289 SMRange RegRange = RegTok.getLocRange();
2291 StringRef FixedName = StringSwitch<StringRef>(Name)
2297 assert(FixedName != "" && "Register name is not one of t4-t7.");
2299 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
2300 "Did you mean $" + FixedName + "?", RegRange);
2303 // Although SGI documentation just cuts out t0-t3 for n32/n64,
2304 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
2305 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
2306 if (8 <= CC && CC <= 11)
2310 CC = StringSwitch<unsigned>(Name)
2322 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
2325 CC = StringSwitch<unsigned>(Name)
2326 .Case("hwr_cpunum", 0)
2327 .Case("hwr_synci_step", 1)
2329 .Case("hwr_ccres", 3)
2330 .Case("hwr_ulr", 29)
2336 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2338 if (Name[0] == 'f') {
2339 StringRef NumString = Name.substr(1);
2341 if (NumString.getAsInteger(10, IntVal))
2342 return -1; // This is not an integer.
2343 if (IntVal > 31) // Maximum index for fpu register.
2350 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2352 if (Name.startswith("fcc")) {
2353 StringRef NumString = Name.substr(3);
2355 if (NumString.getAsInteger(10, IntVal))
2356 return -1; // This is not an integer.
2357 if (IntVal > 7) // There are only 8 fcc registers.
2364 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2366 if (Name.startswith("ac")) {
2367 StringRef NumString = Name.substr(2);
2369 if (NumString.getAsInteger(10, IntVal))
2370 return -1; // This is not an integer.
2371 if (IntVal > 3) // There are only 3 acc registers.
2378 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2381 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
2390 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
2393 CC = StringSwitch<unsigned>(Name)
2396 .Case("msaaccess", 2)
2398 .Case("msamodify", 4)
2399 .Case("msarequest", 5)
2401 .Case("msaunmap", 7)
2407 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
2408 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
2410 reportParseError(Loc,
2411 "pseudo-instruction requires $at, which is not available");
2414 unsigned AT = getReg(
2415 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
2419 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2420 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2423 unsigned MipsAsmParser::getGPR(int RegNo) {
2424 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2428 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2430 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2433 return getReg(RegClass, RegNum);
2436 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2437 MCAsmParser &Parser = getParser();
2438 DEBUG(dbgs() << "parseOperand\n");
2440 // Check if the current operand has a custom associated parser, if so, try to
2441 // custom parse the operand, or fallback to the general approach.
2442 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2443 if (ResTy == MatchOperand_Success)
2445 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2446 // there was a match, but an error occurred, in which case, just return that
2447 // the operand parsing failed.
2448 if (ResTy == MatchOperand_ParseFail)
2451 DEBUG(dbgs() << ".. Generic Parser\n");
2453 switch (getLexer().getKind()) {
2455 Error(Parser.getTok().getLoc(), "unexpected token in operand");
2457 case AsmToken::Dollar: {
2458 // Parse the register.
2459 SMLoc S = Parser.getTok().getLoc();
2461 // Almost all registers have been parsed by custom parsers. There is only
2462 // one exception to this. $zero (and it's alias $0) will reach this point
2463 // for div, divu, and similar instructions because it is not an operand
2464 // to the instruction definition but an explicit register. Special case
2465 // this situation for now.
2466 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
2469 // Maybe it is a symbol reference.
2470 StringRef Identifier;
2471 if (Parser.parseIdentifier(Identifier))
2474 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2475 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
2476 // Otherwise create a symbol reference.
2478 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
2480 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
2483 // Else drop to expression parsing.
2484 case AsmToken::LParen:
2485 case AsmToken::Minus:
2486 case AsmToken::Plus:
2487 case AsmToken::Integer:
2488 case AsmToken::Tilde:
2489 case AsmToken::String: {
2490 DEBUG(dbgs() << ".. generic integer\n");
2491 OperandMatchResultTy ResTy = parseImm(Operands);
2492 return ResTy != MatchOperand_Success;
2494 case AsmToken::Percent: {
2495 // It is a symbol reference or constant expression.
2496 const MCExpr *IdVal;
2497 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
2498 if (parseRelocOperand(IdVal))
2501 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2503 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2505 } // case AsmToken::Percent
2506 } // switch(getLexer().getKind())
2510 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
2511 StringRef RelocStr) {
2513 // Check the type of the expression.
2514 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
2515 // It's a constant, evaluate reloc value.
2517 switch (getVariantKind(RelocStr)) {
2518 case MCSymbolRefExpr::VK_Mips_ABS_LO:
2519 // Get the 1st 16-bits.
2520 Val = MCE->getValue() & 0xffff;
2522 case MCSymbolRefExpr::VK_Mips_ABS_HI:
2523 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
2524 // 16 bits being negative.
2525 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
2527 case MCSymbolRefExpr::VK_Mips_HIGHER:
2528 // Get the 3rd 16-bits.
2529 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
2531 case MCSymbolRefExpr::VK_Mips_HIGHEST:
2532 // Get the 4th 16-bits.
2533 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
2536 report_fatal_error("unsupported reloc value");
2538 return MCConstantExpr::Create(Val, getContext());
2541 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
2542 // It's a symbol, create a symbolic expression from the symbol.
2543 StringRef Symbol = MSRE->getSymbol().getName();
2544 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2545 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
2549 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2550 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2552 // Try to create target expression.
2553 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
2554 return MipsMCExpr::Create(VK, Expr, getContext());
2556 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
2557 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
2558 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
2562 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
2563 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
2564 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
2567 // Just return the original expression.
2571 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
2573 switch (Expr->getKind()) {
2574 case MCExpr::Constant:
2576 case MCExpr::SymbolRef:
2577 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
2578 case MCExpr::Binary:
2579 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2580 if (!isEvaluated(BE->getLHS()))
2582 return isEvaluated(BE->getRHS());
2585 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
2586 case MCExpr::Target:
2592 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
2593 MCAsmParser &Parser = getParser();
2594 Parser.Lex(); // Eat the % token.
2595 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
2596 if (Tok.isNot(AsmToken::Identifier))
2599 std::string Str = Tok.getIdentifier();
2601 Parser.Lex(); // Eat the identifier.
2602 // Now make an expression from the rest of the operand.
2603 const MCExpr *IdVal;
2606 if (getLexer().getKind() == AsmToken::LParen) {
2608 Parser.Lex(); // Eat the '(' token.
2609 if (getLexer().getKind() == AsmToken::Percent) {
2610 Parser.Lex(); // Eat the % token.
2611 const AsmToken &nextTok = Parser.getTok();
2612 if (nextTok.isNot(AsmToken::Identifier))
2615 Str += nextTok.getIdentifier();
2616 Parser.Lex(); // Eat the identifier.
2617 if (getLexer().getKind() != AsmToken::LParen)
2622 if (getParser().parseParenExpression(IdVal, EndLoc))
2625 while (getLexer().getKind() == AsmToken::RParen)
2626 Parser.Lex(); // Eat the ')' token.
2629 return true; // Parenthesis must follow the relocation operand.
2631 Res = evaluateRelocExpr(IdVal, Str);
2635 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2637 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2638 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2639 if (ResTy == MatchOperand_Success) {
2640 assert(Operands.size() == 1);
2641 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2642 StartLoc = Operand.getStartLoc();
2643 EndLoc = Operand.getEndLoc();
2645 // AFAIK, we only support numeric registers and named GPR's in CFI
2647 // Don't worry about eating tokens before failing. Using an unrecognised
2648 // register is a parse error.
2649 if (Operand.isGPRAsmReg()) {
2650 // Resolve to GPR32 or GPR64 appropriately.
2651 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2654 return (RegNo == (unsigned)-1);
2657 assert(Operands.size() == 0);
2658 return (RegNo == (unsigned)-1);
2661 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2662 MCAsmParser &Parser = getParser();
2666 while (getLexer().getKind() == AsmToken::LParen)
2669 switch (getLexer().getKind()) {
2672 case AsmToken::Identifier:
2673 case AsmToken::LParen:
2674 case AsmToken::Integer:
2675 case AsmToken::Minus:
2676 case AsmToken::Plus:
2678 Result = getParser().parseParenExpression(Res, S);
2680 Result = (getParser().parseExpression(Res));
2681 while (getLexer().getKind() == AsmToken::RParen)
2684 case AsmToken::Percent:
2685 Result = parseRelocOperand(Res);
2690 MipsAsmParser::OperandMatchResultTy
2691 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
2692 MCAsmParser &Parser = getParser();
2693 DEBUG(dbgs() << "parseMemOperand\n");
2694 const MCExpr *IdVal = nullptr;
2696 bool isParenExpr = false;
2697 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
2698 // First operand is the offset.
2699 S = Parser.getTok().getLoc();
2701 if (getLexer().getKind() == AsmToken::LParen) {
2706 if (getLexer().getKind() != AsmToken::Dollar) {
2707 if (parseMemOffset(IdVal, isParenExpr))
2708 return MatchOperand_ParseFail;
2710 const AsmToken &Tok = Parser.getTok(); // Get the next token.
2711 if (Tok.isNot(AsmToken::LParen)) {
2712 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2713 if (Mnemonic.getToken() == "la") {
2715 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2716 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2717 return MatchOperand_Success;
2719 if (Tok.is(AsmToken::EndOfStatement)) {
2721 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2723 // Zero register assumed, add a memory operand with ZERO as its base.
2724 // "Base" will be managed by k_Memory.
2725 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
2728 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2729 return MatchOperand_Success;
2731 Error(Parser.getTok().getLoc(), "'(' expected");
2732 return MatchOperand_ParseFail;
2735 Parser.Lex(); // Eat the '(' token.
2738 Res = parseAnyRegister(Operands);
2739 if (Res != MatchOperand_Success)
2742 if (Parser.getTok().isNot(AsmToken::RParen)) {
2743 Error(Parser.getTok().getLoc(), "')' expected");
2744 return MatchOperand_ParseFail;
2747 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2749 Parser.Lex(); // Eat the ')' token.
2752 IdVal = MCConstantExpr::Create(0, getContext());
2754 // Replace the register operand with the memory operand.
2755 std::unique_ptr<MipsOperand> op(
2756 static_cast<MipsOperand *>(Operands.back().release()));
2757 // Remove the register from the operands.
2758 // "op" will be managed by k_Memory.
2759 Operands.pop_back();
2760 // Add the memory operand.
2761 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2763 if (IdVal->EvaluateAsAbsolute(Imm))
2764 IdVal = MCConstantExpr::Create(Imm, getContext());
2765 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2766 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2770 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2771 return MatchOperand_Success;
2774 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2775 MCAsmParser &Parser = getParser();
2776 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2778 SMLoc S = Parser.getTok().getLoc();
2780 if (Sym->isVariable())
2781 Expr = Sym->getVariableValue();
2784 if (Expr->getKind() == MCExpr::SymbolRef) {
2785 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2786 StringRef DefSymbol = Ref->getSymbol().getName();
2787 if (DefSymbol.startswith("$")) {
2788 OperandMatchResultTy ResTy =
2789 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2790 if (ResTy == MatchOperand_Success) {
2793 } else if (ResTy == MatchOperand_ParseFail)
2794 llvm_unreachable("Should never ParseFail");
2797 } else if (Expr->getKind() == MCExpr::Constant) {
2799 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2801 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2808 MipsAsmParser::OperandMatchResultTy
2809 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2810 StringRef Identifier,
2812 int Index = matchCPURegisterName(Identifier);
2814 Operands.push_back(MipsOperand::createGPRReg(
2815 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2816 return MatchOperand_Success;
2819 Index = matchHWRegsRegisterName(Identifier);
2821 Operands.push_back(MipsOperand::createHWRegsReg(
2822 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2823 return MatchOperand_Success;
2826 Index = matchFPURegisterName(Identifier);
2828 Operands.push_back(MipsOperand::createFGRReg(
2829 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2830 return MatchOperand_Success;
2833 Index = matchFCCRegisterName(Identifier);
2835 Operands.push_back(MipsOperand::createFCCReg(
2836 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2837 return MatchOperand_Success;
2840 Index = matchACRegisterName(Identifier);
2842 Operands.push_back(MipsOperand::createACCReg(
2843 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2844 return MatchOperand_Success;
2847 Index = matchMSA128RegisterName(Identifier);
2849 Operands.push_back(MipsOperand::createMSA128Reg(
2850 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2851 return MatchOperand_Success;
2854 Index = matchMSA128CtrlRegisterName(Identifier);
2856 Operands.push_back(MipsOperand::createMSACtrlReg(
2857 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2858 return MatchOperand_Success;
2861 return MatchOperand_NoMatch;
2864 MipsAsmParser::OperandMatchResultTy
2865 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2866 MCAsmParser &Parser = getParser();
2867 auto Token = Parser.getLexer().peekTok(false);
2869 if (Token.is(AsmToken::Identifier)) {
2870 DEBUG(dbgs() << ".. identifier\n");
2871 StringRef Identifier = Token.getIdentifier();
2872 OperandMatchResultTy ResTy =
2873 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2875 } else if (Token.is(AsmToken::Integer)) {
2876 DEBUG(dbgs() << ".. integer\n");
2877 Operands.push_back(MipsOperand::createNumericReg(
2878 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2880 return MatchOperand_Success;
2883 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2885 return MatchOperand_NoMatch;
2888 MipsAsmParser::OperandMatchResultTy
2889 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
2890 MCAsmParser &Parser = getParser();
2891 DEBUG(dbgs() << "parseAnyRegister\n");
2893 auto Token = Parser.getTok();
2895 SMLoc S = Token.getLoc();
2897 if (Token.isNot(AsmToken::Dollar)) {
2898 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2899 if (Token.is(AsmToken::Identifier)) {
2900 if (searchSymbolAlias(Operands))
2901 return MatchOperand_Success;
2903 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2904 return MatchOperand_NoMatch;
2906 DEBUG(dbgs() << ".. $\n");
2908 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
2909 if (ResTy == MatchOperand_Success) {
2911 Parser.Lex(); // identifier
2916 MipsAsmParser::OperandMatchResultTy
2917 MipsAsmParser::parseImm(OperandVector &Operands) {
2918 MCAsmParser &Parser = getParser();
2919 switch (getLexer().getKind()) {
2921 return MatchOperand_NoMatch;
2922 case AsmToken::LParen:
2923 case AsmToken::Minus:
2924 case AsmToken::Plus:
2925 case AsmToken::Integer:
2926 case AsmToken::Tilde:
2927 case AsmToken::String:
2931 const MCExpr *IdVal;
2932 SMLoc S = Parser.getTok().getLoc();
2933 if (getParser().parseExpression(IdVal))
2934 return MatchOperand_ParseFail;
2936 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2937 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2938 return MatchOperand_Success;
2941 MipsAsmParser::OperandMatchResultTy
2942 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
2943 MCAsmParser &Parser = getParser();
2944 DEBUG(dbgs() << "parseJumpTarget\n");
2946 SMLoc S = getLexer().getLoc();
2948 // Integers and expressions are acceptable
2949 OperandMatchResultTy ResTy = parseImm(Operands);
2950 if (ResTy != MatchOperand_NoMatch)
2953 // Registers are a valid target and have priority over symbols.
2954 ResTy = parseAnyRegister(Operands);
2955 if (ResTy != MatchOperand_NoMatch)
2958 const MCExpr *Expr = nullptr;
2959 if (Parser.parseExpression(Expr)) {
2960 // We have no way of knowing if a symbol was consumed so we must ParseFail
2961 return MatchOperand_ParseFail;
2964 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2965 return MatchOperand_Success;
2968 MipsAsmParser::OperandMatchResultTy
2969 MipsAsmParser::parseInvNum(OperandVector &Operands) {
2970 MCAsmParser &Parser = getParser();
2971 const MCExpr *IdVal;
2972 // If the first token is '$' we may have register operand.
2973 if (Parser.getTok().is(AsmToken::Dollar))
2974 return MatchOperand_NoMatch;
2975 SMLoc S = Parser.getTok().getLoc();
2976 if (getParser().parseExpression(IdVal))
2977 return MatchOperand_ParseFail;
2978 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2979 assert(MCE && "Unexpected MCExpr type.");
2980 int64_t Val = MCE->getValue();
2981 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2982 Operands.push_back(MipsOperand::CreateImm(
2983 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
2984 return MatchOperand_Success;
2987 MipsAsmParser::OperandMatchResultTy
2988 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
2989 MCAsmParser &Parser = getParser();
2990 switch (getLexer().getKind()) {
2992 return MatchOperand_NoMatch;
2993 case AsmToken::LParen:
2994 case AsmToken::Plus:
2995 case AsmToken::Minus:
2996 case AsmToken::Integer:
3001 SMLoc S = Parser.getTok().getLoc();
3003 if (getParser().parseExpression(Expr))
3004 return MatchOperand_ParseFail;
3007 if (!Expr->EvaluateAsAbsolute(Val)) {
3008 Error(S, "expected immediate value");
3009 return MatchOperand_ParseFail;
3012 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
3013 // and because the CPU always adds one to the immediate field, the allowed
3014 // range becomes 1..4. We'll only check the range here and will deal
3015 // with the addition/subtraction when actually decoding/encoding
3017 if (Val < 1 || Val > 4) {
3018 Error(S, "immediate not in range (1..4)");
3019 return MatchOperand_ParseFail;
3023 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
3024 return MatchOperand_Success;
3027 MipsAsmParser::OperandMatchResultTy
3028 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3029 MCAsmParser &Parser = getParser();
3030 SmallVector<unsigned, 10> Regs;
3032 unsigned PrevReg = Mips::NoRegister;
3033 bool RegRange = false;
3034 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3036 if (Parser.getTok().isNot(AsmToken::Dollar))
3037 return MatchOperand_ParseFail;
3039 SMLoc S = Parser.getTok().getLoc();
3040 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3041 SMLoc E = getLexer().getLoc();
3042 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3043 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3045 // Remove last register operand because registers from register range
3046 // should be inserted first.
3047 if (RegNo == Mips::RA) {
3048 Regs.push_back(RegNo);
3050 unsigned TmpReg = PrevReg + 1;
3051 while (TmpReg <= RegNo) {
3052 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3053 Error(E, "invalid register operand");
3054 return MatchOperand_ParseFail;
3058 Regs.push_back(TmpReg++);
3064 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
3065 (RegNo != Mips::RA)) {
3066 Error(E, "$16 or $31 expected");
3067 return MatchOperand_ParseFail;
3068 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
3069 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3070 Error(E, "invalid register operand");
3071 return MatchOperand_ParseFail;
3072 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
3073 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3074 Error(E, "consecutive register numbers expected");
3075 return MatchOperand_ParseFail;
3078 Regs.push_back(RegNo);
3081 if (Parser.getTok().is(AsmToken::Minus))
3084 if (!Parser.getTok().isNot(AsmToken::Minus) &&
3085 !Parser.getTok().isNot(AsmToken::Comma)) {
3086 Error(E, "',' or '-' expected");
3087 return MatchOperand_ParseFail;
3090 Lex(); // Consume comma or minus
3091 if (Parser.getTok().isNot(AsmToken::Dollar))
3097 SMLoc E = Parser.getTok().getLoc();
3098 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3099 parseMemOperand(Operands);
3100 return MatchOperand_Success;
3103 MipsAsmParser::OperandMatchResultTy
3104 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
3105 MCAsmParser &Parser = getParser();
3107 SMLoc S = Parser.getTok().getLoc();
3108 if (parseAnyRegister(Operands) != MatchOperand_Success)
3109 return MatchOperand_ParseFail;
3111 SMLoc E = Parser.getTok().getLoc();
3112 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
3113 unsigned Reg = Op.getGPR32Reg();
3114 Operands.pop_back();
3115 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
3116 return MatchOperand_Success;
3119 MipsAsmParser::OperandMatchResultTy
3120 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
3121 MCAsmParser &Parser = getParser();
3122 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3123 SmallVector<unsigned, 10> Regs;
3125 if (Parser.getTok().isNot(AsmToken::Dollar))
3126 return MatchOperand_ParseFail;
3128 SMLoc S = Parser.getTok().getLoc();
3130 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3131 return MatchOperand_ParseFail;
3133 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3134 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3135 Regs.push_back(RegNo);
3137 SMLoc E = Parser.getTok().getLoc();
3138 if (Parser.getTok().isNot(AsmToken::Comma)) {
3139 Error(E, "',' expected");
3140 return MatchOperand_ParseFail;
3146 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3147 return MatchOperand_ParseFail;
3149 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3150 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3151 Regs.push_back(RegNo);
3153 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3155 return MatchOperand_Success;
3158 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
3160 MCSymbolRefExpr::VariantKind VK =
3161 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
3162 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
3163 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
3164 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
3165 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
3166 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
3167 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
3168 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
3169 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
3170 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
3171 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
3172 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
3173 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
3174 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
3175 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
3176 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
3177 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
3178 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
3179 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
3180 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
3181 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
3182 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
3183 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
3184 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
3185 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
3186 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
3187 .Default(MCSymbolRefExpr::VK_None);
3189 assert(VK != MCSymbolRefExpr::VK_None);
3194 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
3196 /// ::= '(', register, ')'
3197 /// handle it before we iterate so we don't get tripped up by the lack of
3199 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
3200 MCAsmParser &Parser = getParser();
3201 if (getLexer().is(AsmToken::LParen)) {
3203 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
3205 if (parseOperand(Operands, Name)) {
3206 SMLoc Loc = getLexer().getLoc();
3207 Parser.eatToEndOfStatement();
3208 return Error(Loc, "unexpected token in argument list");
3210 if (Parser.getTok().isNot(AsmToken::RParen)) {
3211 SMLoc Loc = getLexer().getLoc();
3212 Parser.eatToEndOfStatement();
3213 return Error(Loc, "unexpected token, expected ')'");
3216 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
3222 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
3223 /// either one of these.
3224 /// ::= '[', register, ']'
3225 /// ::= '[', integer, ']'
3226 /// handle it before we iterate so we don't get tripped up by the lack of
3228 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
3229 OperandVector &Operands) {
3230 MCAsmParser &Parser = getParser();
3231 if (getLexer().is(AsmToken::LBrac)) {
3233 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
3235 if (parseOperand(Operands, Name)) {
3236 SMLoc Loc = getLexer().getLoc();
3237 Parser.eatToEndOfStatement();
3238 return Error(Loc, "unexpected token in argument list");
3240 if (Parser.getTok().isNot(AsmToken::RBrac)) {
3241 SMLoc Loc = getLexer().getLoc();
3242 Parser.eatToEndOfStatement();
3243 return Error(Loc, "unexpected token, expected ']'");
3246 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
3252 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
3253 SMLoc NameLoc, OperandVector &Operands) {
3254 MCAsmParser &Parser = getParser();
3255 DEBUG(dbgs() << "ParseInstruction\n");
3257 // We have reached first instruction, module directive are now forbidden.
3258 getTargetStreamer().forbidModuleDirective();
3260 // Check if we have valid mnemonic
3261 if (!mnemonicIsValid(Name, 0)) {
3262 Parser.eatToEndOfStatement();
3263 return Error(NameLoc, "unknown instruction");
3265 // First operand in MCInst is instruction mnemonic.
3266 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
3268 // Read the remaining operands.
3269 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3270 // Read the first operand.
3271 if (parseOperand(Operands, Name)) {
3272 SMLoc Loc = getLexer().getLoc();
3273 Parser.eatToEndOfStatement();
3274 return Error(Loc, "unexpected token in argument list");
3276 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
3278 // AFAIK, parenthesis suffixes are never on the first operand
3280 while (getLexer().is(AsmToken::Comma)) {
3281 Parser.Lex(); // Eat the comma.
3282 // Parse and remember the operand.
3283 if (parseOperand(Operands, Name)) {
3284 SMLoc Loc = getLexer().getLoc();
3285 Parser.eatToEndOfStatement();
3286 return Error(Loc, "unexpected token in argument list");
3288 // Parse bracket and parenthesis suffixes before we iterate
3289 if (getLexer().is(AsmToken::LBrac)) {
3290 if (parseBracketSuffix(Name, Operands))
3292 } else if (getLexer().is(AsmToken::LParen) &&
3293 parseParenSuffix(Name, Operands))
3297 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3298 SMLoc Loc = getLexer().getLoc();
3299 Parser.eatToEndOfStatement();
3300 return Error(Loc, "unexpected token in argument list");
3302 Parser.Lex(); // Consume the EndOfStatement.
3306 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
3307 MCAsmParser &Parser = getParser();
3308 SMLoc Loc = getLexer().getLoc();
3309 Parser.eatToEndOfStatement();
3310 return Error(Loc, ErrorMsg);
3313 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
3314 return Error(Loc, ErrorMsg);
3317 bool MipsAsmParser::parseSetNoAtDirective() {
3318 MCAsmParser &Parser = getParser();
3319 // Line should look like: ".set noat".
3321 // Set the $at register to $0.
3322 AssemblerOptions.back()->setATRegIndex(0);
3324 Parser.Lex(); // Eat "noat".
3326 // If this is not the end of the statement, report an error.
3327 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3328 reportParseError("unexpected token, expected end of statement");
3332 getTargetStreamer().emitDirectiveSetNoAt();
3333 Parser.Lex(); // Consume the EndOfStatement.
3337 bool MipsAsmParser::parseSetAtDirective() {
3338 // Line can be: ".set at", which sets $at to $1
3339 // or ".set at=$reg", which sets $at to $reg.
3340 MCAsmParser &Parser = getParser();
3341 Parser.Lex(); // Eat "at".
3343 if (getLexer().is(AsmToken::EndOfStatement)) {
3344 // No register was specified, so we set $at to $1.
3345 AssemblerOptions.back()->setATRegIndex(1);
3347 getTargetStreamer().emitDirectiveSetAt();
3348 Parser.Lex(); // Consume the EndOfStatement.
3352 if (getLexer().isNot(AsmToken::Equal)) {
3353 reportParseError("unexpected token, expected equals sign");
3356 Parser.Lex(); // Eat "=".
3358 if (getLexer().isNot(AsmToken::Dollar)) {
3359 if (getLexer().is(AsmToken::EndOfStatement)) {
3360 reportParseError("no register specified");
3363 reportParseError("unexpected token, expected dollar sign '$'");
3367 Parser.Lex(); // Eat "$".
3369 // Find out what "reg" is.
3371 const AsmToken &Reg = Parser.getTok();
3372 if (Reg.is(AsmToken::Identifier)) {
3373 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
3374 } else if (Reg.is(AsmToken::Integer)) {
3375 AtRegNo = Reg.getIntVal();
3377 reportParseError("unexpected token, expected identifier or integer");
3381 // Check if $reg is a valid register. If it is, set $at to $reg.
3382 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
3383 reportParseError("invalid register");
3386 Parser.Lex(); // Eat "reg".
3388 // If this is not the end of the statement, report an error.
3389 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3390 reportParseError("unexpected token, expected end of statement");
3394 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
3396 Parser.Lex(); // Consume the EndOfStatement.
3400 bool MipsAsmParser::parseSetReorderDirective() {
3401 MCAsmParser &Parser = getParser();
3403 // If this is not the end of the statement, report an error.
3404 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3405 reportParseError("unexpected token, expected end of statement");
3408 AssemblerOptions.back()->setReorder();
3409 getTargetStreamer().emitDirectiveSetReorder();
3410 Parser.Lex(); // Consume the EndOfStatement.
3414 bool MipsAsmParser::parseSetNoReorderDirective() {
3415 MCAsmParser &Parser = getParser();
3417 // If this is not the end of the statement, report an error.
3418 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3419 reportParseError("unexpected token, expected end of statement");
3422 AssemblerOptions.back()->setNoReorder();
3423 getTargetStreamer().emitDirectiveSetNoReorder();
3424 Parser.Lex(); // Consume the EndOfStatement.
3428 bool MipsAsmParser::parseSetMacroDirective() {
3429 MCAsmParser &Parser = getParser();
3431 // If this is not the end of the statement, report an error.
3432 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3433 reportParseError("unexpected token, expected end of statement");
3436 AssemblerOptions.back()->setMacro();
3437 Parser.Lex(); // Consume the EndOfStatement.
3441 bool MipsAsmParser::parseSetNoMacroDirective() {
3442 MCAsmParser &Parser = getParser();
3444 // If this is not the end of the statement, report an error.
3445 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3446 reportParseError("unexpected token, expected end of statement");
3449 if (AssemblerOptions.back()->isReorder()) {
3450 reportParseError("`noreorder' must be set before `nomacro'");
3453 AssemblerOptions.back()->setNoMacro();
3454 Parser.Lex(); // Consume the EndOfStatement.
3458 bool MipsAsmParser::parseSetMsaDirective() {
3459 MCAsmParser &Parser = getParser();
3462 // If this is not the end of the statement, report an error.
3463 if (getLexer().isNot(AsmToken::EndOfStatement))
3464 return reportParseError("unexpected token, expected end of statement");
3466 setFeatureBits(Mips::FeatureMSA, "msa");
3467 getTargetStreamer().emitDirectiveSetMsa();
3471 bool MipsAsmParser::parseSetNoMsaDirective() {
3472 MCAsmParser &Parser = getParser();
3475 // If this is not the end of the statement, report an error.
3476 if (getLexer().isNot(AsmToken::EndOfStatement))
3477 return reportParseError("unexpected token, expected end of statement");
3479 clearFeatureBits(Mips::FeatureMSA, "msa");
3480 getTargetStreamer().emitDirectiveSetNoMsa();
3484 bool MipsAsmParser::parseSetNoDspDirective() {
3485 MCAsmParser &Parser = getParser();
3486 Parser.Lex(); // Eat "nodsp".
3488 // If this is not the end of the statement, report an error.
3489 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3490 reportParseError("unexpected token, expected end of statement");
3494 clearFeatureBits(Mips::FeatureDSP, "dsp");
3495 getTargetStreamer().emitDirectiveSetNoDsp();
3499 bool MipsAsmParser::parseSetMips16Directive() {
3500 MCAsmParser &Parser = getParser();
3501 Parser.Lex(); // Eat "mips16".
3503 // If this is not the end of the statement, report an error.
3504 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3505 reportParseError("unexpected token, expected end of statement");
3509 setFeatureBits(Mips::FeatureMips16, "mips16");
3510 getTargetStreamer().emitDirectiveSetMips16();
3511 Parser.Lex(); // Consume the EndOfStatement.
3515 bool MipsAsmParser::parseSetNoMips16Directive() {
3516 MCAsmParser &Parser = getParser();
3517 Parser.Lex(); // Eat "nomips16".
3519 // If this is not the end of the statement, report an error.
3520 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3521 reportParseError("unexpected token, expected end of statement");
3525 clearFeatureBits(Mips::FeatureMips16, "mips16");
3526 getTargetStreamer().emitDirectiveSetNoMips16();
3527 Parser.Lex(); // Consume the EndOfStatement.
3531 bool MipsAsmParser::parseSetFpDirective() {
3532 MCAsmParser &Parser = getParser();
3533 MipsABIFlagsSection::FpABIKind FpAbiVal;
3534 // Line can be: .set fp=32
3537 Parser.Lex(); // Eat fp token
3538 AsmToken Tok = Parser.getTok();
3539 if (Tok.isNot(AsmToken::Equal)) {
3540 reportParseError("unexpected token, expected equals sign '='");
3543 Parser.Lex(); // Eat '=' token.
3544 Tok = Parser.getTok();
3546 if (!parseFpABIValue(FpAbiVal, ".set"))
3549 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3550 reportParseError("unexpected token, expected end of statement");
3553 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
3554 Parser.Lex(); // Consume the EndOfStatement.
3558 bool MipsAsmParser::parseSetPopDirective() {
3559 MCAsmParser &Parser = getParser();
3560 SMLoc Loc = getLexer().getLoc();
3563 if (getLexer().isNot(AsmToken::EndOfStatement))
3564 return reportParseError("unexpected token, expected end of statement");
3566 // Always keep an element on the options "stack" to prevent the user
3567 // from changing the initial options. This is how we remember them.
3568 if (AssemblerOptions.size() == 2)
3569 return reportParseError(Loc, ".set pop with no .set push");
3571 AssemblerOptions.pop_back();
3572 setAvailableFeatures(AssemblerOptions.back()->getFeatures());
3574 getTargetStreamer().emitDirectiveSetPop();
3578 bool MipsAsmParser::parseSetPushDirective() {
3579 MCAsmParser &Parser = getParser();
3581 if (getLexer().isNot(AsmToken::EndOfStatement))
3582 return reportParseError("unexpected token, expected end of statement");
3584 // Create a copy of the current assembler options environment and push it.
3585 AssemblerOptions.push_back(
3586 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
3588 getTargetStreamer().emitDirectiveSetPush();
3592 bool MipsAsmParser::parseSetAssignment() {
3594 const MCExpr *Value;
3595 MCAsmParser &Parser = getParser();
3597 if (Parser.parseIdentifier(Name))
3598 reportParseError("expected identifier after .set");
3600 if (getLexer().isNot(AsmToken::Comma))
3601 return reportParseError("unexpected token, expected comma");
3604 if (Parser.parseExpression(Value))
3605 return reportParseError("expected valid expression after comma");
3607 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
3608 Sym->setVariableValue(Value);
3613 bool MipsAsmParser::parseSetMips0Directive() {
3614 MCAsmParser &Parser = getParser();
3616 if (getLexer().isNot(AsmToken::EndOfStatement))
3617 return reportParseError("unexpected token, expected end of statement");
3619 // Reset assembler options to their initial values.
3620 setAvailableFeatures(AssemblerOptions.front()->getFeatures());
3621 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
3623 getTargetStreamer().emitDirectiveSetMips0();
3627 bool MipsAsmParser::parseSetArchDirective() {
3628 MCAsmParser &Parser = getParser();
3630 if (getLexer().isNot(AsmToken::Equal))
3631 return reportParseError("unexpected token, expected equals sign");
3635 if (Parser.parseIdentifier(Arch))
3636 return reportParseError("expected arch identifier");
3638 StringRef ArchFeatureName =
3639 StringSwitch<StringRef>(Arch)
3640 .Case("mips1", "mips1")
3641 .Case("mips2", "mips2")
3642 .Case("mips3", "mips3")
3643 .Case("mips4", "mips4")
3644 .Case("mips5", "mips5")
3645 .Case("mips32", "mips32")
3646 .Case("mips32r2", "mips32r2")
3647 .Case("mips32r3", "mips32r3")
3648 .Case("mips32r5", "mips32r5")
3649 .Case("mips32r6", "mips32r6")
3650 .Case("mips64", "mips64")
3651 .Case("mips64r2", "mips64r2")
3652 .Case("mips64r3", "mips64r3")
3653 .Case("mips64r5", "mips64r5")
3654 .Case("mips64r6", "mips64r6")
3655 .Case("cnmips", "cnmips")
3656 .Case("r4000", "mips3") // This is an implementation of Mips3.
3659 if (ArchFeatureName.empty())
3660 return reportParseError("unsupported architecture");
3662 selectArch(ArchFeatureName);
3663 getTargetStreamer().emitDirectiveSetArch(Arch);
3667 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
3668 MCAsmParser &Parser = getParser();
3670 if (getLexer().isNot(AsmToken::EndOfStatement))
3671 return reportParseError("unexpected token, expected end of statement");
3675 llvm_unreachable("Unimplemented feature");
3676 case Mips::FeatureDSP:
3677 setFeatureBits(Mips::FeatureDSP, "dsp");
3678 getTargetStreamer().emitDirectiveSetDsp();
3680 case Mips::FeatureMicroMips:
3681 getTargetStreamer().emitDirectiveSetMicroMips();
3683 case Mips::FeatureMips1:
3684 selectArch("mips1");
3685 getTargetStreamer().emitDirectiveSetMips1();
3687 case Mips::FeatureMips2:
3688 selectArch("mips2");
3689 getTargetStreamer().emitDirectiveSetMips2();
3691 case Mips::FeatureMips3:
3692 selectArch("mips3");
3693 getTargetStreamer().emitDirectiveSetMips3();
3695 case Mips::FeatureMips4:
3696 selectArch("mips4");
3697 getTargetStreamer().emitDirectiveSetMips4();
3699 case Mips::FeatureMips5:
3700 selectArch("mips5");
3701 getTargetStreamer().emitDirectiveSetMips5();
3703 case Mips::FeatureMips32:
3704 selectArch("mips32");
3705 getTargetStreamer().emitDirectiveSetMips32();
3707 case Mips::FeatureMips32r2:
3708 selectArch("mips32r2");
3709 getTargetStreamer().emitDirectiveSetMips32R2();
3711 case Mips::FeatureMips32r3:
3712 selectArch("mips32r3");
3713 getTargetStreamer().emitDirectiveSetMips32R3();
3715 case Mips::FeatureMips32r5:
3716 selectArch("mips32r5");
3717 getTargetStreamer().emitDirectiveSetMips32R5();
3719 case Mips::FeatureMips32r6:
3720 selectArch("mips32r6");
3721 getTargetStreamer().emitDirectiveSetMips32R6();
3723 case Mips::FeatureMips64:
3724 selectArch("mips64");
3725 getTargetStreamer().emitDirectiveSetMips64();
3727 case Mips::FeatureMips64r2:
3728 selectArch("mips64r2");
3729 getTargetStreamer().emitDirectiveSetMips64R2();
3731 case Mips::FeatureMips64r3:
3732 selectArch("mips64r3");
3733 getTargetStreamer().emitDirectiveSetMips64R3();
3735 case Mips::FeatureMips64r5:
3736 selectArch("mips64r5");
3737 getTargetStreamer().emitDirectiveSetMips64R5();
3739 case Mips::FeatureMips64r6:
3740 selectArch("mips64r6");
3741 getTargetStreamer().emitDirectiveSetMips64R6();
3747 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
3748 MCAsmParser &Parser = getParser();
3749 if (getLexer().isNot(AsmToken::Comma)) {
3750 SMLoc Loc = getLexer().getLoc();
3751 Parser.eatToEndOfStatement();
3752 return Error(Loc, ErrorStr);
3755 Parser.Lex(); // Eat the comma.
3759 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
3760 if (AssemblerOptions.back()->isReorder())
3761 Warning(Loc, ".cpload should be inside a noreorder section");
3763 if (inMips16Mode()) {
3764 reportParseError(".cpload is not supported in Mips16 mode");
3768 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
3769 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
3770 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3771 reportParseError("expected register containing function address");
3775 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
3776 if (!RegOpnd.isGPRAsmReg()) {
3777 reportParseError(RegOpnd.getStartLoc(), "invalid register");
3781 // If this is not the end of the statement, report an error.
3782 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3783 reportParseError("unexpected token, expected end of statement");
3787 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
3791 bool MipsAsmParser::parseDirectiveCPSetup() {
3792 MCAsmParser &Parser = getParser();
3795 bool SaveIsReg = true;
3797 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3798 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3799 if (ResTy == MatchOperand_NoMatch) {
3800 reportParseError("expected register containing function address");
3801 Parser.eatToEndOfStatement();
3805 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3806 if (!FuncRegOpnd.isGPRAsmReg()) {
3807 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
3808 Parser.eatToEndOfStatement();
3812 FuncReg = FuncRegOpnd.getGPR32Reg();
3815 if (!eatComma("unexpected token, expected comma"))
3818 ResTy = parseAnyRegister(TmpReg);
3819 if (ResTy == MatchOperand_NoMatch) {
3820 const AsmToken &Tok = Parser.getTok();
3821 if (Tok.is(AsmToken::Integer)) {
3822 Save = Tok.getIntVal();
3826 reportParseError("expected save register or stack offset");
3827 Parser.eatToEndOfStatement();
3831 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3832 if (!SaveOpnd.isGPRAsmReg()) {
3833 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
3834 Parser.eatToEndOfStatement();
3837 Save = SaveOpnd.getGPR32Reg();
3840 if (!eatComma("unexpected token, expected comma"))
3844 if (Parser.parseExpression(Expr)) {
3845 reportParseError("expected expression");
3849 if (Expr->getKind() != MCExpr::SymbolRef) {
3850 reportParseError("expected symbol");
3853 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3855 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
3860 bool MipsAsmParser::parseDirectiveNaN() {
3861 MCAsmParser &Parser = getParser();
3862 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3863 const AsmToken &Tok = Parser.getTok();
3865 if (Tok.getString() == "2008") {
3867 getTargetStreamer().emitDirectiveNaN2008();
3869 } else if (Tok.getString() == "legacy") {
3871 getTargetStreamer().emitDirectiveNaNLegacy();
3875 // If we don't recognize the option passed to the .nan
3876 // directive (e.g. no option or unknown option), emit an error.
3877 reportParseError("invalid option in .nan directive");
3881 bool MipsAsmParser::parseDirectiveSet() {
3882 MCAsmParser &Parser = getParser();
3883 // Get the next token.
3884 const AsmToken &Tok = Parser.getTok();
3886 if (Tok.getString() == "noat") {
3887 return parseSetNoAtDirective();
3888 } else if (Tok.getString() == "at") {
3889 return parseSetAtDirective();
3890 } else if (Tok.getString() == "arch") {
3891 return parseSetArchDirective();
3892 } else if (Tok.getString() == "fp") {
3893 return parseSetFpDirective();
3894 } else if (Tok.getString() == "pop") {
3895 return parseSetPopDirective();
3896 } else if (Tok.getString() == "push") {
3897 return parseSetPushDirective();
3898 } else if (Tok.getString() == "reorder") {
3899 return parseSetReorderDirective();
3900 } else if (Tok.getString() == "noreorder") {
3901 return parseSetNoReorderDirective();
3902 } else if (Tok.getString() == "macro") {
3903 return parseSetMacroDirective();
3904 } else if (Tok.getString() == "nomacro") {
3905 return parseSetNoMacroDirective();
3906 } else if (Tok.getString() == "mips16") {
3907 return parseSetMips16Directive();
3908 } else if (Tok.getString() == "nomips16") {
3909 return parseSetNoMips16Directive();
3910 } else if (Tok.getString() == "nomicromips") {
3911 getTargetStreamer().emitDirectiveSetNoMicroMips();
3912 Parser.eatToEndOfStatement();
3914 } else if (Tok.getString() == "micromips") {
3915 return parseSetFeature(Mips::FeatureMicroMips);
3916 } else if (Tok.getString() == "mips0") {
3917 return parseSetMips0Directive();
3918 } else if (Tok.getString() == "mips1") {
3919 return parseSetFeature(Mips::FeatureMips1);
3920 } else if (Tok.getString() == "mips2") {
3921 return parseSetFeature(Mips::FeatureMips2);
3922 } else if (Tok.getString() == "mips3") {
3923 return parseSetFeature(Mips::FeatureMips3);
3924 } else if (Tok.getString() == "mips4") {
3925 return parseSetFeature(Mips::FeatureMips4);
3926 } else if (Tok.getString() == "mips5") {
3927 return parseSetFeature(Mips::FeatureMips5);
3928 } else if (Tok.getString() == "mips32") {
3929 return parseSetFeature(Mips::FeatureMips32);
3930 } else if (Tok.getString() == "mips32r2") {
3931 return parseSetFeature(Mips::FeatureMips32r2);
3932 } else if (Tok.getString() == "mips32r3") {
3933 return parseSetFeature(Mips::FeatureMips32r3);
3934 } else if (Tok.getString() == "mips32r5") {
3935 return parseSetFeature(Mips::FeatureMips32r5);
3936 } else if (Tok.getString() == "mips32r6") {
3937 return parseSetFeature(Mips::FeatureMips32r6);
3938 } else if (Tok.getString() == "mips64") {
3939 return parseSetFeature(Mips::FeatureMips64);
3940 } else if (Tok.getString() == "mips64r2") {
3941 return parseSetFeature(Mips::FeatureMips64r2);
3942 } else if (Tok.getString() == "mips64r3") {
3943 return parseSetFeature(Mips::FeatureMips64r3);
3944 } else if (Tok.getString() == "mips64r5") {
3945 return parseSetFeature(Mips::FeatureMips64r5);
3946 } else if (Tok.getString() == "mips64r6") {
3947 return parseSetFeature(Mips::FeatureMips64r6);
3948 } else if (Tok.getString() == "dsp") {
3949 return parseSetFeature(Mips::FeatureDSP);
3950 } else if (Tok.getString() == "nodsp") {
3951 return parseSetNoDspDirective();
3952 } else if (Tok.getString() == "msa") {
3953 return parseSetMsaDirective();
3954 } else if (Tok.getString() == "nomsa") {
3955 return parseSetNoMsaDirective();
3957 // It is just an identifier, look for an assignment.
3958 parseSetAssignment();
3965 /// parseDataDirective
3966 /// ::= .word [ expression (, expression)* ]
3967 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
3968 MCAsmParser &Parser = getParser();
3969 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3971 const MCExpr *Value;
3972 if (getParser().parseExpression(Value))
3975 getParser().getStreamer().EmitValue(Value, Size);
3977 if (getLexer().is(AsmToken::EndOfStatement))
3980 if (getLexer().isNot(AsmToken::Comma))
3981 return Error(L, "unexpected token, expected comma");
3990 /// parseDirectiveGpWord
3991 /// ::= .gpword local_sym
3992 bool MipsAsmParser::parseDirectiveGpWord() {
3993 MCAsmParser &Parser = getParser();
3994 const MCExpr *Value;
3995 // EmitGPRel32Value requires an expression, so we are using base class
3996 // method to evaluate the expression.
3997 if (getParser().parseExpression(Value))
3999 getParser().getStreamer().EmitGPRel32Value(Value);
4001 if (getLexer().isNot(AsmToken::EndOfStatement))
4002 return Error(getLexer().getLoc(),
4003 "unexpected token, expected end of statement");
4004 Parser.Lex(); // Eat EndOfStatement token.
4008 /// parseDirectiveGpDWord
4009 /// ::= .gpdword local_sym
4010 bool MipsAsmParser::parseDirectiveGpDWord() {
4011 MCAsmParser &Parser = getParser();
4012 const MCExpr *Value;
4013 // EmitGPRel64Value requires an expression, so we are using base class
4014 // method to evaluate the expression.
4015 if (getParser().parseExpression(Value))
4017 getParser().getStreamer().EmitGPRel64Value(Value);
4019 if (getLexer().isNot(AsmToken::EndOfStatement))
4020 return Error(getLexer().getLoc(),
4021 "unexpected token, expected end of statement");
4022 Parser.Lex(); // Eat EndOfStatement token.
4026 bool MipsAsmParser::parseDirectiveOption() {
4027 MCAsmParser &Parser = getParser();
4028 // Get the option token.
4029 AsmToken Tok = Parser.getTok();
4030 // At the moment only identifiers are supported.
4031 if (Tok.isNot(AsmToken::Identifier)) {
4032 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
4033 Parser.eatToEndOfStatement();
4037 StringRef Option = Tok.getIdentifier();
4039 if (Option == "pic0") {
4040 getTargetStreamer().emitDirectiveOptionPic0();
4042 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4043 Error(Parser.getTok().getLoc(),
4044 "unexpected token, expected end of statement");
4045 Parser.eatToEndOfStatement();
4050 if (Option == "pic2") {
4051 getTargetStreamer().emitDirectiveOptionPic2();
4053 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4054 Error(Parser.getTok().getLoc(),
4055 "unexpected token, expected end of statement");
4056 Parser.eatToEndOfStatement();
4062 Warning(Parser.getTok().getLoc(),
4063 "unknown option, expected 'pic0' or 'pic2'");
4064 Parser.eatToEndOfStatement();
4068 /// parseInsnDirective
4070 bool MipsAsmParser::parseInsnDirective() {
4071 // If this is not the end of the statement, report an error.
4072 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4073 reportParseError("unexpected token, expected end of statement");
4077 // The actual label marking happens in
4078 // MipsELFStreamer::createPendingLabelRelocs().
4079 getTargetStreamer().emitDirectiveInsn();
4081 getParser().Lex(); // Eat EndOfStatement token.
4085 /// parseDirectiveModule
4086 /// ::= .module oddspreg
4087 /// ::= .module nooddspreg
4088 /// ::= .module fp=value
4089 bool MipsAsmParser::parseDirectiveModule() {
4090 MCAsmParser &Parser = getParser();
4091 MCAsmLexer &Lexer = getLexer();
4092 SMLoc L = Lexer.getLoc();
4094 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
4095 // TODO : get a better message.
4096 reportParseError(".module directive must appear before any code");
4101 if (Parser.parseIdentifier(Option)) {
4102 reportParseError("expected .module option identifier");
4106 if (Option == "oddspreg") {
4107 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
4108 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4110 // If this is not the end of the statement, report an error.
4111 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4112 reportParseError("unexpected token, expected end of statement");
4116 return false; // parseDirectiveModule has finished successfully.
4117 } else if (Option == "nooddspreg") {
4119 Error(L, "'.module nooddspreg' requires the O32 ABI");
4123 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
4124 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4126 // If this is not the end of the statement, report an error.
4127 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4128 reportParseError("unexpected token, expected end of statement");
4132 return false; // parseDirectiveModule has finished successfully.
4133 } else if (Option == "fp") {
4134 return parseDirectiveModuleFP();
4136 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
4140 /// parseDirectiveModuleFP
4144 bool MipsAsmParser::parseDirectiveModuleFP() {
4145 MCAsmParser &Parser = getParser();
4146 MCAsmLexer &Lexer = getLexer();
4148 if (Lexer.isNot(AsmToken::Equal)) {
4149 reportParseError("unexpected token, expected equals sign '='");
4152 Parser.Lex(); // Eat '=' token.
4154 MipsABIFlagsSection::FpABIKind FpABI;
4155 if (!parseFpABIValue(FpABI, ".module"))
4158 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4159 reportParseError("unexpected token, expected end of statement");
4163 // Emit appropriate flags.
4164 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
4165 Parser.Lex(); // Consume the EndOfStatement.
4169 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
4170 StringRef Directive) {
4171 MCAsmParser &Parser = getParser();
4172 MCAsmLexer &Lexer = getLexer();
4174 if (Lexer.is(AsmToken::Identifier)) {
4175 StringRef Value = Parser.getTok().getString();
4178 if (Value != "xx") {
4179 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4184 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
4188 FpABI = MipsABIFlagsSection::FpABIKind::XX;
4192 if (Lexer.is(AsmToken::Integer)) {
4193 unsigned Value = Parser.getTok().getIntVal();
4196 if (Value != 32 && Value != 64) {
4197 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4203 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
4207 FpABI = MipsABIFlagsSection::FpABIKind::S32;
4209 FpABI = MipsABIFlagsSection::FpABIKind::S64;
4217 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
4218 MCAsmParser &Parser = getParser();
4219 StringRef IDVal = DirectiveID.getString();
4221 if (IDVal == ".cpload")
4222 return parseDirectiveCpLoad(DirectiveID.getLoc());
4223 if (IDVal == ".dword") {
4224 parseDataDirective(8, DirectiveID.getLoc());
4227 if (IDVal == ".ent") {
4228 StringRef SymbolName;
4230 if (Parser.parseIdentifier(SymbolName)) {
4231 reportParseError("expected identifier after .ent");
4235 // There's an undocumented extension that allows an integer to
4236 // follow the name of the procedure which AFAICS is ignored by GAS.
4237 // Example: .ent foo,2
4238 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4239 if (getLexer().isNot(AsmToken::Comma)) {
4240 // Even though we accept this undocumented extension for compatibility
4241 // reasons, the additional integer argument does not actually change
4242 // the behaviour of the '.ent' directive, so we would like to discourage
4243 // its use. We do this by not referring to the extended version in
4244 // error messages which are not directly related to its use.
4245 reportParseError("unexpected token, expected end of statement");
4248 Parser.Lex(); // Eat the comma.
4249 const MCExpr *DummyNumber;
4250 int64_t DummyNumberVal;
4251 // If the user was explicitly trying to use the extended version,
4252 // we still give helpful extension-related error messages.
4253 if (Parser.parseExpression(DummyNumber)) {
4254 reportParseError("expected number after comma");
4257 if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) {
4258 reportParseError("expected an absolute expression after comma");
4263 // If this is not the end of the statement, report an error.
4264 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4265 reportParseError("unexpected token, expected end of statement");
4269 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
4271 getTargetStreamer().emitDirectiveEnt(*Sym);
4276 if (IDVal == ".end") {
4277 StringRef SymbolName;
4279 if (Parser.parseIdentifier(SymbolName)) {
4280 reportParseError("expected identifier after .end");
4284 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4285 reportParseError("unexpected token, expected end of statement");
4289 if (CurrentFn == nullptr) {
4290 reportParseError(".end used without .ent");
4294 if ((SymbolName != CurrentFn->getName())) {
4295 reportParseError(".end symbol does not match .ent symbol");
4299 getTargetStreamer().emitDirectiveEnd(SymbolName);
4300 CurrentFn = nullptr;
4304 if (IDVal == ".frame") {
4305 // .frame $stack_reg, frame_size_in_bytes, $return_reg
4306 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4307 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4308 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4309 reportParseError("expected stack register");
4313 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4314 if (!StackRegOpnd.isGPRAsmReg()) {
4315 reportParseError(StackRegOpnd.getStartLoc(),
4316 "expected general purpose register");
4319 unsigned StackReg = StackRegOpnd.getGPR32Reg();
4321 if (Parser.getTok().is(AsmToken::Comma))
4324 reportParseError("unexpected token, expected comma");
4328 // Parse the frame size.
4329 const MCExpr *FrameSize;
4330 int64_t FrameSizeVal;
4332 if (Parser.parseExpression(FrameSize)) {
4333 reportParseError("expected frame size value");
4337 if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) {
4338 reportParseError("frame size not an absolute expression");
4342 if (Parser.getTok().is(AsmToken::Comma))
4345 reportParseError("unexpected token, expected comma");
4349 // Parse the return register.
4351 ResTy = parseAnyRegister(TmpReg);
4352 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4353 reportParseError("expected return register");
4357 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4358 if (!ReturnRegOpnd.isGPRAsmReg()) {
4359 reportParseError(ReturnRegOpnd.getStartLoc(),
4360 "expected general purpose register");
4364 // If this is not the end of the statement, report an error.
4365 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4366 reportParseError("unexpected token, expected end of statement");
4370 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
4371 ReturnRegOpnd.getGPR32Reg());
4375 if (IDVal == ".set") {
4376 return parseDirectiveSet();
4379 if (IDVal == ".mask" || IDVal == ".fmask") {
4380 // .mask bitmask, frame_offset
4381 // bitmask: One bit for each register used.
4382 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
4383 // first register is expected to be saved.
4385 // .mask 0x80000000, -4
4386 // .fmask 0x80000000, -4
4389 // Parse the bitmask
4390 const MCExpr *BitMask;
4393 if (Parser.parseExpression(BitMask)) {
4394 reportParseError("expected bitmask value");
4398 if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) {
4399 reportParseError("bitmask not an absolute expression");
4403 if (Parser.getTok().is(AsmToken::Comma))
4406 reportParseError("unexpected token, expected comma");
4410 // Parse the frame_offset
4411 const MCExpr *FrameOffset;
4412 int64_t FrameOffsetVal;
4414 if (Parser.parseExpression(FrameOffset)) {
4415 reportParseError("expected frame offset value");
4419 if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) {
4420 reportParseError("frame offset not an absolute expression");
4424 // If this is not the end of the statement, report an error.
4425 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4426 reportParseError("unexpected token, expected end of statement");
4430 if (IDVal == ".mask")
4431 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
4433 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
4437 if (IDVal == ".nan")
4438 return parseDirectiveNaN();
4440 if (IDVal == ".gpword") {
4441 parseDirectiveGpWord();
4445 if (IDVal == ".gpdword") {
4446 parseDirectiveGpDWord();
4450 if (IDVal == ".word") {
4451 parseDataDirective(4, DirectiveID.getLoc());
4455 if (IDVal == ".option")
4456 return parseDirectiveOption();
4458 if (IDVal == ".abicalls") {
4459 getTargetStreamer().emitDirectiveAbiCalls();
4460 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4461 Error(Parser.getTok().getLoc(),
4462 "unexpected token, expected end of statement");
4464 Parser.eatToEndOfStatement();
4469 if (IDVal == ".cpsetup")
4470 return parseDirectiveCPSetup();
4472 if (IDVal == ".module")
4473 return parseDirectiveModule();
4475 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
4476 return parseInternalDirectiveReallowModule();
4478 if (IDVal == ".insn")
4479 return parseInsnDirective();
4484 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
4485 // If this is not the end of the statement, report an error.
4486 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4487 reportParseError("unexpected token, expected end of statement");
4491 getTargetStreamer().reallowModuleDirective();
4493 getParser().Lex(); // Eat EndOfStatement token.
4497 extern "C" void LLVMInitializeMipsAsmParser() {
4498 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
4499 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
4500 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
4501 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
4504 #define GET_REGISTER_MATCHER
4505 #define GET_MATCHER_IMPLEMENTATION
4506 #include "MipsGenAsmMatcher.inc"