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 (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
1762 if (!AssemblerOptions.back()->isMacro())
1763 Warning(IDLoc, "macro instruction expanded into multiple instructions");
1765 // For all other values which are representable as a 32-bit integer:
1766 // li d,j => lui d,hi16(j)
1768 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1769 uint16_t Bits15To0 = ImmValue & 0xffff;
1771 if (!Is32BitImm && !isInt<32>(ImmValue)) {
1772 // For DLI, expand to an ORi instead of a LUi to avoid sign-extending the
1774 tmpInst.setOpcode(Mips::ORi);
1775 tmpInst.addOperand(MCOperand::createReg(DstReg));
1776 tmpInst.addOperand(MCOperand::createReg(Mips::ZERO));
1777 tmpInst.addOperand(MCOperand::createImm(Bits31To16));
1778 tmpInst.setLoc(IDLoc);
1779 Instructions.push_back(tmpInst);
1780 // Move the value to the upper 16 bits by doing a 16-bit left shift.
1781 createLShiftOri<16>(0, DstReg, IDLoc, Instructions);
1783 tmpInst.setOpcode(Mips::LUi);
1784 tmpInst.addOperand(MCOperand::createReg(DstReg));
1785 tmpInst.addOperand(MCOperand::createImm(Bits31To16));
1786 Instructions.push_back(tmpInst);
1788 createLShiftOri<0>(Bits15To0, DstReg, IDLoc, Instructions);
1791 createAddu(DstReg, DstReg, SrcReg, Instructions);
1793 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1795 Error(IDLoc, "instruction requires a 32-bit immediate");
1798 if (!AssemblerOptions.back()->isMacro())
1799 Warning(IDLoc, "macro instruction expanded into multiple instructions");
1801 // <------- lo32 ------>
1802 // <------- hi32 ------>
1803 // <- hi16 -> <- lo16 ->
1804 // _________________________________
1806 // | 16-bits | 16-bits | 16-bits |
1807 // |__________|__________|__________|
1809 // For any 64-bit value that is representable as a 48-bit integer:
1810 // li d,j => lui d,hi16(j)
1811 // ori d,d,hi16(lo32(j))
1813 // ori d,d,lo16(lo32(j))
1814 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1815 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1816 uint16_t Bits15To0 = ImmValue & 0xffff;
1818 tmpInst.setOpcode(Mips::LUi);
1819 tmpInst.addOperand(MCOperand::createReg(DstReg));
1820 tmpInst.addOperand(MCOperand::createImm(Bits47To32));
1821 Instructions.push_back(tmpInst);
1822 createLShiftOri<0>(Bits31To16, DstReg, IDLoc, Instructions);
1823 createLShiftOri<16>(Bits15To0, DstReg, IDLoc, Instructions);
1826 createAddu(DstReg, DstReg, SrcReg, Instructions);
1830 Error(IDLoc, "instruction requires a 32-bit immediate");
1833 if (!AssemblerOptions.back()->isMacro())
1834 Warning(IDLoc, "macro instruction expanded into multiple instructions");
1836 // <------- hi32 ------> <------- lo32 ------>
1837 // <- hi16 -> <- lo16 ->
1838 // ___________________________________________
1840 // | 16-bits | 16-bits | 16-bits | 16-bits |
1841 // |__________|__________|__________|__________|
1843 // For all other values which are representable as a 64-bit integer:
1844 // li d,j => lui d,hi16(j)
1845 // ori d,d,lo16(hi32(j))
1847 // ori d,d,hi16(lo32(j))
1849 // ori d,d,lo16(lo32(j))
1850 uint16_t Bits63To48 = (ImmValue >> 48) & 0xffff;
1851 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1852 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1853 uint16_t Bits15To0 = ImmValue & 0xffff;
1855 tmpInst.setOpcode(Mips::LUi);
1856 tmpInst.addOperand(MCOperand::createReg(DstReg));
1857 tmpInst.addOperand(MCOperand::createImm(Bits63To48));
1858 Instructions.push_back(tmpInst);
1859 createLShiftOri<0>(Bits47To32, DstReg, IDLoc, Instructions);
1861 // When Bits31To16 is 0, do a left shift of 32 bits instead of doing
1862 // two left shifts of 16 bits.
1863 if (Bits31To16 == 0) {
1864 createLShiftOri<32>(Bits15To0, DstReg, IDLoc, Instructions);
1866 createLShiftOri<16>(Bits31To16, DstReg, IDLoc, Instructions);
1867 createLShiftOri<16>(Bits15To0, DstReg, IDLoc, Instructions);
1871 createAddu(DstReg, DstReg, SrcReg, Instructions);
1876 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1877 SmallVectorImpl<MCInst> &Instructions) {
1878 const MCOperand &ImmOp = Inst.getOperand(1);
1879 assert(ImmOp.isImm() && "expected immediate operand kind");
1880 const MCOperand &DstRegOp = Inst.getOperand(0);
1881 assert(DstRegOp.isReg() && "expected register operand kind");
1883 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
1884 Is32BitImm, IDLoc, Instructions))
1891 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1892 SmallVectorImpl<MCInst> &Instructions) {
1893 const MCOperand &DstRegOp = Inst.getOperand(0);
1894 assert(DstRegOp.isReg() && "expected register operand kind");
1896 const MCOperand &ImmOp = Inst.getOperand(2);
1897 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1898 "expected immediate operand kind");
1899 if (!ImmOp.isImm()) {
1900 expandLoadAddressSym(DstRegOp, ImmOp, Is32BitImm, IDLoc, Instructions);
1903 const MCOperand &SrcRegOp = Inst.getOperand(1);
1904 assert(SrcRegOp.isReg() && "expected register operand kind");
1906 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), SrcRegOp.getReg(),
1907 Is32BitImm, IDLoc, Instructions))
1914 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1915 SmallVectorImpl<MCInst> &Instructions) {
1916 const MCOperand &DstRegOp = Inst.getOperand(0);
1917 assert(DstRegOp.isReg() && "expected register operand kind");
1919 const MCOperand &ImmOp = Inst.getOperand(1);
1920 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1921 "expected immediate operand kind");
1922 if (!ImmOp.isImm()) {
1923 expandLoadAddressSym(DstRegOp, ImmOp, Is32BitImm, IDLoc, Instructions);
1927 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
1928 Is32BitImm, IDLoc, Instructions))
1934 void MipsAsmParser::expandLoadAddressSym(
1935 const MCOperand &DstRegOp, const MCOperand &SymOp, bool Is32BitSym,
1936 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1937 if (!AssemblerOptions.back()->isMacro())
1938 Warning(IDLoc, "macro instruction expanded into multiple instructions");
1940 if (Is32BitSym && isABI_N64())
1941 Warning(IDLoc, "instruction loads the 32-bit address of a 64-bit symbol");
1944 unsigned RegNo = DstRegOp.getReg();
1945 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
1946 const MCSymbolRefExpr *HiExpr =
1947 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1948 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1949 const MCSymbolRefExpr *LoExpr =
1950 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1951 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1953 // If it's a 64-bit architecture, expand to:
1954 // la d,sym => lui d,highest(sym)
1955 // ori d,d,higher(sym)
1957 // ori d,d,hi16(sym)
1959 // ori d,d,lo16(sym)
1960 const MCSymbolRefExpr *HighestExpr =
1961 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1962 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1963 const MCSymbolRefExpr *HigherExpr =
1964 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1965 MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1967 tmpInst.setOpcode(Mips::LUi);
1968 tmpInst.addOperand(MCOperand::createReg(RegNo));
1969 tmpInst.addOperand(MCOperand::createExpr(HighestExpr));
1970 Instructions.push_back(tmpInst);
1972 createLShiftOri<0>(MCOperand::createExpr(HigherExpr), RegNo, SMLoc(),
1974 createLShiftOri<16>(MCOperand::createExpr(HiExpr), RegNo, SMLoc(),
1976 createLShiftOri<16>(MCOperand::createExpr(LoExpr), RegNo, SMLoc(),
1979 // Otherwise, expand to:
1980 // la d,sym => lui d,hi16(sym)
1981 // ori d,d,lo16(sym)
1982 tmpInst.setOpcode(Mips::LUi);
1983 tmpInst.addOperand(MCOperand::createReg(RegNo));
1984 tmpInst.addOperand(MCOperand::createExpr(HiExpr));
1985 Instructions.push_back(tmpInst);
1987 createLShiftOri<0>(MCOperand::createExpr(LoExpr), RegNo, SMLoc(),
1992 bool MipsAsmParser::expandUncondBranchMMPseudo(
1993 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1994 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
1995 "unexpected number of operands");
1997 MCOperand Offset = Inst.getOperand(0);
1998 if (Offset.isExpr()) {
2000 Inst.setOpcode(Mips::BEQ_MM);
2001 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2002 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2003 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2005 assert(Offset.isImm() && "expected immediate operand kind");
2006 if (isIntN(11, Offset.getImm())) {
2007 // If offset fits into 11 bits then this instruction becomes microMIPS
2008 // 16-bit unconditional branch instruction.
2009 Inst.setOpcode(Mips::B16_MM);
2011 if (!isIntN(17, Offset.getImm()))
2012 Error(IDLoc, "branch target out of range");
2013 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2014 Error(IDLoc, "branch to misaligned address");
2016 Inst.setOpcode(Mips::BEQ_MM);
2017 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2018 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2019 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2022 Instructions.push_back(Inst);
2024 // If .set reorder is active, emit a NOP after the branch instruction.
2025 if (AssemblerOptions.back()->isReorder())
2026 createNop(true, IDLoc, Instructions);
2031 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2032 SmallVectorImpl<MCInst> &Instructions,
2033 bool isLoad, bool isImmOpnd) {
2034 const MCSymbolRefExpr *SR;
2036 unsigned ImmOffset, HiOffset, LoOffset;
2037 const MCExpr *ExprOffset;
2039 // 1st operand is either the source or destination register.
2040 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2041 unsigned RegOpNum = Inst.getOperand(0).getReg();
2042 // 2nd operand is the base register.
2043 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2044 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2045 // 3rd operand is either an immediate or expression.
2047 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2048 ImmOffset = Inst.getOperand(2).getImm();
2049 LoOffset = ImmOffset & 0x0000ffff;
2050 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2051 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2052 if (LoOffset & 0x8000)
2055 ExprOffset = Inst.getOperand(2).getExpr();
2056 // All instructions will have the same location.
2057 TempInst.setLoc(IDLoc);
2058 // These are some of the types of expansions we perform here:
2059 // 1) lw $8, sym => lui $8, %hi(sym)
2060 // lw $8, %lo(sym)($8)
2061 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2063 // lw $8, %lo(offset)($9)
2064 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2066 // lw $8, %lo(offset)($at)
2067 // 4) sw $8, sym => lui $at, %hi(sym)
2068 // sw $8, %lo(sym)($at)
2069 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2071 // sw $8, %lo(offset)($at)
2072 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2073 // ldc1 $f0, %lo(sym)($at)
2075 // For load instructions we can use the destination register as a temporary
2076 // if base and dst are different (examples 1 and 2) and if the base register
2077 // is general purpose otherwise we must use $at (example 6) and error if it's
2078 // not available. For stores we must use $at (examples 4 and 5) because we
2079 // must not clobber the source register setting up the offset.
2080 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2081 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2082 unsigned RegClassIDOp0 =
2083 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2084 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2085 (RegClassIDOp0 == Mips::GPR64RegClassID);
2086 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2087 TmpRegNum = RegOpNum;
2089 // At this point we need AT to perform the expansions and we exit if it is
2091 TmpRegNum = getATReg(IDLoc);
2096 TempInst.setOpcode(Mips::LUi);
2097 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2099 TempInst.addOperand(MCOperand::createImm(HiOffset));
2101 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2102 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
2103 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
2104 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
2106 TempInst.addOperand(MCOperand::createExpr(HiExpr));
2108 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2109 TempInst.addOperand(MCOperand::createExpr(HiExpr));
2112 // Add the instruction to the list.
2113 Instructions.push_back(TempInst);
2114 // Prepare TempInst for next instruction.
2116 // Add temp register to base.
2117 if (BaseRegNum != Mips::ZERO) {
2118 TempInst.setOpcode(Mips::ADDu);
2119 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2120 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2121 TempInst.addOperand(MCOperand::createReg(BaseRegNum));
2122 Instructions.push_back(TempInst);
2125 // And finally, create original instruction with low part
2126 // of offset and new base.
2127 TempInst.setOpcode(Inst.getOpcode());
2128 TempInst.addOperand(MCOperand::createReg(RegOpNum));
2129 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2131 TempInst.addOperand(MCOperand::createImm(LoOffset));
2133 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2134 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
2135 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
2137 TempInst.addOperand(MCOperand::createExpr(LoExpr));
2139 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2140 TempInst.addOperand(MCOperand::createExpr(LoExpr));
2143 Instructions.push_back(TempInst);
2148 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2149 SmallVectorImpl<MCInst> &Instructions) {
2150 unsigned OpNum = Inst.getNumOperands();
2151 unsigned Opcode = Inst.getOpcode();
2152 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2154 assert (Inst.getOperand(OpNum - 1).isImm() &&
2155 Inst.getOperand(OpNum - 2).isReg() &&
2156 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2158 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2159 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2160 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2161 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2162 // It can be implemented as SWM16 or LWM16 instruction.
2163 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2165 Inst.setOpcode(NewOpcode);
2166 Instructions.push_back(Inst);
2170 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
2171 SmallVectorImpl<MCInst> &Instructions) {
2173 if (hasShortDelaySlot) {
2174 NopInst.setOpcode(Mips::MOVE16_MM);
2175 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2176 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2178 NopInst.setOpcode(Mips::SLL);
2179 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2180 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2181 NopInst.addOperand(MCOperand::createImm(0));
2183 Instructions.push_back(NopInst);
2186 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
2188 SmallVectorImpl<MCInst> &Instructions) {
2190 AdduInst.setOpcode(Mips::ADDu);
2191 AdduInst.addOperand(MCOperand::createReg(DstReg));
2192 AdduInst.addOperand(MCOperand::createReg(SrcReg));
2193 AdduInst.addOperand(MCOperand::createReg(TrgReg));
2194 Instructions.push_back(AdduInst);
2197 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
2198 // As described by the Mips32r2 spec, the registers Rd and Rs for
2199 // jalr.hb must be different.
2200 unsigned Opcode = Inst.getOpcode();
2202 if (Opcode == Mips::JALR_HB &&
2203 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
2204 return Match_RequiresDifferentSrcAndDst;
2206 return Match_Success;
2209 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2210 OperandVector &Operands,
2212 uint64_t &ErrorInfo,
2213 bool MatchingInlineAsm) {
2216 SmallVector<MCInst, 8> Instructions;
2217 unsigned MatchResult =
2218 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
2220 switch (MatchResult) {
2221 case Match_Success: {
2222 if (processInstruction(Inst, IDLoc, Instructions))
2224 for (unsigned i = 0; i < Instructions.size(); i++)
2225 Out.EmitInstruction(Instructions[i], STI);
2228 case Match_MissingFeature:
2229 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2231 case Match_InvalidOperand: {
2232 SMLoc ErrorLoc = IDLoc;
2233 if (ErrorInfo != ~0ULL) {
2234 if (ErrorInfo >= Operands.size())
2235 return Error(IDLoc, "too few operands for instruction");
2237 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
2238 if (ErrorLoc == SMLoc())
2242 return Error(ErrorLoc, "invalid operand for instruction");
2244 case Match_MnemonicFail:
2245 return Error(IDLoc, "invalid instruction");
2246 case Match_RequiresDifferentSrcAndDst:
2247 return Error(IDLoc, "source and destination must be different");
2250 llvm_unreachable("Implement any new match types added!");
2253 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
2254 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
2255 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
2256 ") without \".set noat\"");
2260 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
2261 SMRange Range, bool ShowColors) {
2262 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
2263 Range, SMFixIt(Range, FixMsg),
2267 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
2270 CC = StringSwitch<unsigned>(Name)
2306 if (!(isABI_N32() || isABI_N64()))
2309 if (12 <= CC && CC <= 15) {
2310 // Name is one of t4-t7
2311 AsmToken RegTok = getLexer().peekTok();
2312 SMRange RegRange = RegTok.getLocRange();
2314 StringRef FixedName = StringSwitch<StringRef>(Name)
2320 assert(FixedName != "" && "Register name is not one of t4-t7.");
2322 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
2323 "Did you mean $" + FixedName + "?", RegRange);
2326 // Although SGI documentation just cuts out t0-t3 for n32/n64,
2327 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
2328 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
2329 if (8 <= CC && CC <= 11)
2333 CC = StringSwitch<unsigned>(Name)
2345 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
2348 CC = StringSwitch<unsigned>(Name)
2349 .Case("hwr_cpunum", 0)
2350 .Case("hwr_synci_step", 1)
2352 .Case("hwr_ccres", 3)
2353 .Case("hwr_ulr", 29)
2359 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2361 if (Name[0] == 'f') {
2362 StringRef NumString = Name.substr(1);
2364 if (NumString.getAsInteger(10, IntVal))
2365 return -1; // This is not an integer.
2366 if (IntVal > 31) // Maximum index for fpu register.
2373 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2375 if (Name.startswith("fcc")) {
2376 StringRef NumString = Name.substr(3);
2378 if (NumString.getAsInteger(10, IntVal))
2379 return -1; // This is not an integer.
2380 if (IntVal > 7) // There are only 8 fcc registers.
2387 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2389 if (Name.startswith("ac")) {
2390 StringRef NumString = Name.substr(2);
2392 if (NumString.getAsInteger(10, IntVal))
2393 return -1; // This is not an integer.
2394 if (IntVal > 3) // There are only 3 acc registers.
2401 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2404 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
2413 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
2416 CC = StringSwitch<unsigned>(Name)
2419 .Case("msaaccess", 2)
2421 .Case("msamodify", 4)
2422 .Case("msarequest", 5)
2424 .Case("msaunmap", 7)
2430 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
2431 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
2433 reportParseError(Loc,
2434 "pseudo-instruction requires $at, which is not available");
2437 unsigned AT = getReg(
2438 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
2442 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2443 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2446 unsigned MipsAsmParser::getGPR(int RegNo) {
2447 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2451 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2453 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2456 return getReg(RegClass, RegNum);
2459 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2460 MCAsmParser &Parser = getParser();
2461 DEBUG(dbgs() << "parseOperand\n");
2463 // Check if the current operand has a custom associated parser, if so, try to
2464 // custom parse the operand, or fallback to the general approach.
2465 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2466 if (ResTy == MatchOperand_Success)
2468 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2469 // there was a match, but an error occurred, in which case, just return that
2470 // the operand parsing failed.
2471 if (ResTy == MatchOperand_ParseFail)
2474 DEBUG(dbgs() << ".. Generic Parser\n");
2476 switch (getLexer().getKind()) {
2478 Error(Parser.getTok().getLoc(), "unexpected token in operand");
2480 case AsmToken::Dollar: {
2481 // Parse the register.
2482 SMLoc S = Parser.getTok().getLoc();
2484 // Almost all registers have been parsed by custom parsers. There is only
2485 // one exception to this. $zero (and it's alias $0) will reach this point
2486 // for div, divu, and similar instructions because it is not an operand
2487 // to the instruction definition but an explicit register. Special case
2488 // this situation for now.
2489 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
2492 // Maybe it is a symbol reference.
2493 StringRef Identifier;
2494 if (Parser.parseIdentifier(Identifier))
2497 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2498 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
2499 // Otherwise create a symbol reference.
2501 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
2503 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
2506 // Else drop to expression parsing.
2507 case AsmToken::LParen:
2508 case AsmToken::Minus:
2509 case AsmToken::Plus:
2510 case AsmToken::Integer:
2511 case AsmToken::Tilde:
2512 case AsmToken::String: {
2513 DEBUG(dbgs() << ".. generic integer\n");
2514 OperandMatchResultTy ResTy = parseImm(Operands);
2515 return ResTy != MatchOperand_Success;
2517 case AsmToken::Percent: {
2518 // It is a symbol reference or constant expression.
2519 const MCExpr *IdVal;
2520 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
2521 if (parseRelocOperand(IdVal))
2524 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2526 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2528 } // case AsmToken::Percent
2529 } // switch(getLexer().getKind())
2533 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
2534 StringRef RelocStr) {
2536 // Check the type of the expression.
2537 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
2538 // It's a constant, evaluate reloc value.
2540 switch (getVariantKind(RelocStr)) {
2541 case MCSymbolRefExpr::VK_Mips_ABS_LO:
2542 // Get the 1st 16-bits.
2543 Val = MCE->getValue() & 0xffff;
2545 case MCSymbolRefExpr::VK_Mips_ABS_HI:
2546 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
2547 // 16 bits being negative.
2548 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
2550 case MCSymbolRefExpr::VK_Mips_HIGHER:
2551 // Get the 3rd 16-bits.
2552 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
2554 case MCSymbolRefExpr::VK_Mips_HIGHEST:
2555 // Get the 4th 16-bits.
2556 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
2559 report_fatal_error("unsupported reloc value");
2561 return MCConstantExpr::Create(Val, getContext());
2564 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
2565 // It's a symbol, create a symbolic expression from the symbol.
2566 StringRef Symbol = MSRE->getSymbol().getName();
2567 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2568 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
2572 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2573 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2575 // Try to create target expression.
2576 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
2577 return MipsMCExpr::Create(VK, Expr, getContext());
2579 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
2580 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
2581 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
2585 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
2586 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
2587 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
2590 // Just return the original expression.
2594 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
2596 switch (Expr->getKind()) {
2597 case MCExpr::Constant:
2599 case MCExpr::SymbolRef:
2600 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
2601 case MCExpr::Binary:
2602 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2603 if (!isEvaluated(BE->getLHS()))
2605 return isEvaluated(BE->getRHS());
2608 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
2609 case MCExpr::Target:
2615 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
2616 MCAsmParser &Parser = getParser();
2617 Parser.Lex(); // Eat the % token.
2618 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
2619 if (Tok.isNot(AsmToken::Identifier))
2622 std::string Str = Tok.getIdentifier();
2624 Parser.Lex(); // Eat the identifier.
2625 // Now make an expression from the rest of the operand.
2626 const MCExpr *IdVal;
2629 if (getLexer().getKind() == AsmToken::LParen) {
2631 Parser.Lex(); // Eat the '(' token.
2632 if (getLexer().getKind() == AsmToken::Percent) {
2633 Parser.Lex(); // Eat the % token.
2634 const AsmToken &nextTok = Parser.getTok();
2635 if (nextTok.isNot(AsmToken::Identifier))
2638 Str += nextTok.getIdentifier();
2639 Parser.Lex(); // Eat the identifier.
2640 if (getLexer().getKind() != AsmToken::LParen)
2645 if (getParser().parseParenExpression(IdVal, EndLoc))
2648 while (getLexer().getKind() == AsmToken::RParen)
2649 Parser.Lex(); // Eat the ')' token.
2652 return true; // Parenthesis must follow the relocation operand.
2654 Res = evaluateRelocExpr(IdVal, Str);
2658 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2660 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2661 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2662 if (ResTy == MatchOperand_Success) {
2663 assert(Operands.size() == 1);
2664 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2665 StartLoc = Operand.getStartLoc();
2666 EndLoc = Operand.getEndLoc();
2668 // AFAIK, we only support numeric registers and named GPR's in CFI
2670 // Don't worry about eating tokens before failing. Using an unrecognised
2671 // register is a parse error.
2672 if (Operand.isGPRAsmReg()) {
2673 // Resolve to GPR32 or GPR64 appropriately.
2674 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2677 return (RegNo == (unsigned)-1);
2680 assert(Operands.size() == 0);
2681 return (RegNo == (unsigned)-1);
2684 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2685 MCAsmParser &Parser = getParser();
2689 while (getLexer().getKind() == AsmToken::LParen)
2692 switch (getLexer().getKind()) {
2695 case AsmToken::Identifier:
2696 case AsmToken::LParen:
2697 case AsmToken::Integer:
2698 case AsmToken::Minus:
2699 case AsmToken::Plus:
2701 Result = getParser().parseParenExpression(Res, S);
2703 Result = (getParser().parseExpression(Res));
2704 while (getLexer().getKind() == AsmToken::RParen)
2707 case AsmToken::Percent:
2708 Result = parseRelocOperand(Res);
2713 MipsAsmParser::OperandMatchResultTy
2714 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
2715 MCAsmParser &Parser = getParser();
2716 DEBUG(dbgs() << "parseMemOperand\n");
2717 const MCExpr *IdVal = nullptr;
2719 bool isParenExpr = false;
2720 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
2721 // First operand is the offset.
2722 S = Parser.getTok().getLoc();
2724 if (getLexer().getKind() == AsmToken::LParen) {
2729 if (getLexer().getKind() != AsmToken::Dollar) {
2730 if (parseMemOffset(IdVal, isParenExpr))
2731 return MatchOperand_ParseFail;
2733 const AsmToken &Tok = Parser.getTok(); // Get the next token.
2734 if (Tok.isNot(AsmToken::LParen)) {
2735 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2736 if (Mnemonic.getToken() == "la") {
2738 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2739 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2740 return MatchOperand_Success;
2742 if (Tok.is(AsmToken::EndOfStatement)) {
2744 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2746 // Zero register assumed, add a memory operand with ZERO as its base.
2747 // "Base" will be managed by k_Memory.
2748 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
2751 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2752 return MatchOperand_Success;
2754 Error(Parser.getTok().getLoc(), "'(' expected");
2755 return MatchOperand_ParseFail;
2758 Parser.Lex(); // Eat the '(' token.
2761 Res = parseAnyRegister(Operands);
2762 if (Res != MatchOperand_Success)
2765 if (Parser.getTok().isNot(AsmToken::RParen)) {
2766 Error(Parser.getTok().getLoc(), "')' expected");
2767 return MatchOperand_ParseFail;
2770 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2772 Parser.Lex(); // Eat the ')' token.
2775 IdVal = MCConstantExpr::Create(0, getContext());
2777 // Replace the register operand with the memory operand.
2778 std::unique_ptr<MipsOperand> op(
2779 static_cast<MipsOperand *>(Operands.back().release()));
2780 // Remove the register from the operands.
2781 // "op" will be managed by k_Memory.
2782 Operands.pop_back();
2783 // Add the memory operand.
2784 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2786 if (IdVal->EvaluateAsAbsolute(Imm))
2787 IdVal = MCConstantExpr::Create(Imm, getContext());
2788 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2789 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2793 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2794 return MatchOperand_Success;
2797 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2798 MCAsmParser &Parser = getParser();
2799 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
2801 SMLoc S = Parser.getTok().getLoc();
2803 if (Sym->isVariable())
2804 Expr = Sym->getVariableValue();
2807 if (Expr->getKind() == MCExpr::SymbolRef) {
2808 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2809 StringRef DefSymbol = Ref->getSymbol().getName();
2810 if (DefSymbol.startswith("$")) {
2811 OperandMatchResultTy ResTy =
2812 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2813 if (ResTy == MatchOperand_Success) {
2816 } else if (ResTy == MatchOperand_ParseFail)
2817 llvm_unreachable("Should never ParseFail");
2820 } else if (Expr->getKind() == MCExpr::Constant) {
2822 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2824 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2831 MipsAsmParser::OperandMatchResultTy
2832 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2833 StringRef Identifier,
2835 int Index = matchCPURegisterName(Identifier);
2837 Operands.push_back(MipsOperand::createGPRReg(
2838 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2839 return MatchOperand_Success;
2842 Index = matchHWRegsRegisterName(Identifier);
2844 Operands.push_back(MipsOperand::createHWRegsReg(
2845 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2846 return MatchOperand_Success;
2849 Index = matchFPURegisterName(Identifier);
2851 Operands.push_back(MipsOperand::createFGRReg(
2852 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2853 return MatchOperand_Success;
2856 Index = matchFCCRegisterName(Identifier);
2858 Operands.push_back(MipsOperand::createFCCReg(
2859 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2860 return MatchOperand_Success;
2863 Index = matchACRegisterName(Identifier);
2865 Operands.push_back(MipsOperand::createACCReg(
2866 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2867 return MatchOperand_Success;
2870 Index = matchMSA128RegisterName(Identifier);
2872 Operands.push_back(MipsOperand::createMSA128Reg(
2873 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2874 return MatchOperand_Success;
2877 Index = matchMSA128CtrlRegisterName(Identifier);
2879 Operands.push_back(MipsOperand::createMSACtrlReg(
2880 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2881 return MatchOperand_Success;
2884 return MatchOperand_NoMatch;
2887 MipsAsmParser::OperandMatchResultTy
2888 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2889 MCAsmParser &Parser = getParser();
2890 auto Token = Parser.getLexer().peekTok(false);
2892 if (Token.is(AsmToken::Identifier)) {
2893 DEBUG(dbgs() << ".. identifier\n");
2894 StringRef Identifier = Token.getIdentifier();
2895 OperandMatchResultTy ResTy =
2896 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2898 } else if (Token.is(AsmToken::Integer)) {
2899 DEBUG(dbgs() << ".. integer\n");
2900 Operands.push_back(MipsOperand::createNumericReg(
2901 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2903 return MatchOperand_Success;
2906 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2908 return MatchOperand_NoMatch;
2911 MipsAsmParser::OperandMatchResultTy
2912 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
2913 MCAsmParser &Parser = getParser();
2914 DEBUG(dbgs() << "parseAnyRegister\n");
2916 auto Token = Parser.getTok();
2918 SMLoc S = Token.getLoc();
2920 if (Token.isNot(AsmToken::Dollar)) {
2921 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2922 if (Token.is(AsmToken::Identifier)) {
2923 if (searchSymbolAlias(Operands))
2924 return MatchOperand_Success;
2926 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2927 return MatchOperand_NoMatch;
2929 DEBUG(dbgs() << ".. $\n");
2931 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
2932 if (ResTy == MatchOperand_Success) {
2934 Parser.Lex(); // identifier
2939 MipsAsmParser::OperandMatchResultTy
2940 MipsAsmParser::parseImm(OperandVector &Operands) {
2941 MCAsmParser &Parser = getParser();
2942 switch (getLexer().getKind()) {
2944 return MatchOperand_NoMatch;
2945 case AsmToken::LParen:
2946 case AsmToken::Minus:
2947 case AsmToken::Plus:
2948 case AsmToken::Integer:
2949 case AsmToken::Tilde:
2950 case AsmToken::String:
2954 const MCExpr *IdVal;
2955 SMLoc S = Parser.getTok().getLoc();
2956 if (getParser().parseExpression(IdVal))
2957 return MatchOperand_ParseFail;
2959 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2960 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2961 return MatchOperand_Success;
2964 MipsAsmParser::OperandMatchResultTy
2965 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
2966 MCAsmParser &Parser = getParser();
2967 DEBUG(dbgs() << "parseJumpTarget\n");
2969 SMLoc S = getLexer().getLoc();
2971 // Integers and expressions are acceptable
2972 OperandMatchResultTy ResTy = parseImm(Operands);
2973 if (ResTy != MatchOperand_NoMatch)
2976 // Registers are a valid target and have priority over symbols.
2977 ResTy = parseAnyRegister(Operands);
2978 if (ResTy != MatchOperand_NoMatch)
2981 const MCExpr *Expr = nullptr;
2982 if (Parser.parseExpression(Expr)) {
2983 // We have no way of knowing if a symbol was consumed so we must ParseFail
2984 return MatchOperand_ParseFail;
2987 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2988 return MatchOperand_Success;
2991 MipsAsmParser::OperandMatchResultTy
2992 MipsAsmParser::parseInvNum(OperandVector &Operands) {
2993 MCAsmParser &Parser = getParser();
2994 const MCExpr *IdVal;
2995 // If the first token is '$' we may have register operand.
2996 if (Parser.getTok().is(AsmToken::Dollar))
2997 return MatchOperand_NoMatch;
2998 SMLoc S = Parser.getTok().getLoc();
2999 if (getParser().parseExpression(IdVal))
3000 return MatchOperand_ParseFail;
3001 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
3002 assert(MCE && "Unexpected MCExpr type.");
3003 int64_t Val = MCE->getValue();
3004 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3005 Operands.push_back(MipsOperand::CreateImm(
3006 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
3007 return MatchOperand_Success;
3010 MipsAsmParser::OperandMatchResultTy
3011 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
3012 MCAsmParser &Parser = getParser();
3013 switch (getLexer().getKind()) {
3015 return MatchOperand_NoMatch;
3016 case AsmToken::LParen:
3017 case AsmToken::Plus:
3018 case AsmToken::Minus:
3019 case AsmToken::Integer:
3024 SMLoc S = Parser.getTok().getLoc();
3026 if (getParser().parseExpression(Expr))
3027 return MatchOperand_ParseFail;
3030 if (!Expr->EvaluateAsAbsolute(Val)) {
3031 Error(S, "expected immediate value");
3032 return MatchOperand_ParseFail;
3035 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
3036 // and because the CPU always adds one to the immediate field, the allowed
3037 // range becomes 1..4. We'll only check the range here and will deal
3038 // with the addition/subtraction when actually decoding/encoding
3040 if (Val < 1 || Val > 4) {
3041 Error(S, "immediate not in range (1..4)");
3042 return MatchOperand_ParseFail;
3046 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
3047 return MatchOperand_Success;
3050 MipsAsmParser::OperandMatchResultTy
3051 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3052 MCAsmParser &Parser = getParser();
3053 SmallVector<unsigned, 10> Regs;
3055 unsigned PrevReg = Mips::NoRegister;
3056 bool RegRange = false;
3057 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3059 if (Parser.getTok().isNot(AsmToken::Dollar))
3060 return MatchOperand_ParseFail;
3062 SMLoc S = Parser.getTok().getLoc();
3063 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3064 SMLoc E = getLexer().getLoc();
3065 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3066 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3068 // Remove last register operand because registers from register range
3069 // should be inserted first.
3070 if (RegNo == Mips::RA) {
3071 Regs.push_back(RegNo);
3073 unsigned TmpReg = PrevReg + 1;
3074 while (TmpReg <= RegNo) {
3075 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3076 Error(E, "invalid register operand");
3077 return MatchOperand_ParseFail;
3081 Regs.push_back(TmpReg++);
3087 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
3088 (RegNo != Mips::RA)) {
3089 Error(E, "$16 or $31 expected");
3090 return MatchOperand_ParseFail;
3091 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
3092 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3093 Error(E, "invalid register operand");
3094 return MatchOperand_ParseFail;
3095 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
3096 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3097 Error(E, "consecutive register numbers expected");
3098 return MatchOperand_ParseFail;
3101 Regs.push_back(RegNo);
3104 if (Parser.getTok().is(AsmToken::Minus))
3107 if (!Parser.getTok().isNot(AsmToken::Minus) &&
3108 !Parser.getTok().isNot(AsmToken::Comma)) {
3109 Error(E, "',' or '-' expected");
3110 return MatchOperand_ParseFail;
3113 Lex(); // Consume comma or minus
3114 if (Parser.getTok().isNot(AsmToken::Dollar))
3120 SMLoc E = Parser.getTok().getLoc();
3121 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3122 parseMemOperand(Operands);
3123 return MatchOperand_Success;
3126 MipsAsmParser::OperandMatchResultTy
3127 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
3128 MCAsmParser &Parser = getParser();
3130 SMLoc S = Parser.getTok().getLoc();
3131 if (parseAnyRegister(Operands) != MatchOperand_Success)
3132 return MatchOperand_ParseFail;
3134 SMLoc E = Parser.getTok().getLoc();
3135 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
3136 unsigned Reg = Op.getGPR32Reg();
3137 Operands.pop_back();
3138 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
3139 return MatchOperand_Success;
3142 MipsAsmParser::OperandMatchResultTy
3143 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
3144 MCAsmParser &Parser = getParser();
3145 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3146 SmallVector<unsigned, 10> Regs;
3148 if (Parser.getTok().isNot(AsmToken::Dollar))
3149 return MatchOperand_ParseFail;
3151 SMLoc S = Parser.getTok().getLoc();
3153 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3154 return MatchOperand_ParseFail;
3156 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3157 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3158 Regs.push_back(RegNo);
3160 SMLoc E = Parser.getTok().getLoc();
3161 if (Parser.getTok().isNot(AsmToken::Comma)) {
3162 Error(E, "',' expected");
3163 return MatchOperand_ParseFail;
3169 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3170 return MatchOperand_ParseFail;
3172 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3173 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3174 Regs.push_back(RegNo);
3176 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3178 return MatchOperand_Success;
3181 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
3183 MCSymbolRefExpr::VariantKind VK =
3184 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
3185 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
3186 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
3187 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
3188 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
3189 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
3190 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
3191 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
3192 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
3193 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
3194 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
3195 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
3196 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
3197 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
3198 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
3199 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
3200 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
3201 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
3202 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
3203 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
3204 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
3205 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
3206 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
3207 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
3208 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
3209 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
3210 .Default(MCSymbolRefExpr::VK_None);
3212 assert(VK != MCSymbolRefExpr::VK_None);
3217 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
3219 /// ::= '(', register, ')'
3220 /// handle it before we iterate so we don't get tripped up by the lack of
3222 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
3223 MCAsmParser &Parser = getParser();
3224 if (getLexer().is(AsmToken::LParen)) {
3226 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
3228 if (parseOperand(Operands, Name)) {
3229 SMLoc Loc = getLexer().getLoc();
3230 Parser.eatToEndOfStatement();
3231 return Error(Loc, "unexpected token in argument list");
3233 if (Parser.getTok().isNot(AsmToken::RParen)) {
3234 SMLoc Loc = getLexer().getLoc();
3235 Parser.eatToEndOfStatement();
3236 return Error(Loc, "unexpected token, expected ')'");
3239 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
3245 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
3246 /// either one of these.
3247 /// ::= '[', register, ']'
3248 /// ::= '[', integer, ']'
3249 /// handle it before we iterate so we don't get tripped up by the lack of
3251 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
3252 OperandVector &Operands) {
3253 MCAsmParser &Parser = getParser();
3254 if (getLexer().is(AsmToken::LBrac)) {
3256 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
3258 if (parseOperand(Operands, Name)) {
3259 SMLoc Loc = getLexer().getLoc();
3260 Parser.eatToEndOfStatement();
3261 return Error(Loc, "unexpected token in argument list");
3263 if (Parser.getTok().isNot(AsmToken::RBrac)) {
3264 SMLoc Loc = getLexer().getLoc();
3265 Parser.eatToEndOfStatement();
3266 return Error(Loc, "unexpected token, expected ']'");
3269 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
3275 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
3276 SMLoc NameLoc, OperandVector &Operands) {
3277 MCAsmParser &Parser = getParser();
3278 DEBUG(dbgs() << "ParseInstruction\n");
3280 // We have reached first instruction, module directive are now forbidden.
3281 getTargetStreamer().forbidModuleDirective();
3283 // Check if we have valid mnemonic
3284 if (!mnemonicIsValid(Name, 0)) {
3285 Parser.eatToEndOfStatement();
3286 return Error(NameLoc, "unknown instruction");
3288 // First operand in MCInst is instruction mnemonic.
3289 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
3291 // Read the remaining operands.
3292 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3293 // Read the first operand.
3294 if (parseOperand(Operands, Name)) {
3295 SMLoc Loc = getLexer().getLoc();
3296 Parser.eatToEndOfStatement();
3297 return Error(Loc, "unexpected token in argument list");
3299 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
3301 // AFAIK, parenthesis suffixes are never on the first operand
3303 while (getLexer().is(AsmToken::Comma)) {
3304 Parser.Lex(); // Eat the comma.
3305 // Parse and remember the operand.
3306 if (parseOperand(Operands, Name)) {
3307 SMLoc Loc = getLexer().getLoc();
3308 Parser.eatToEndOfStatement();
3309 return Error(Loc, "unexpected token in argument list");
3311 // Parse bracket and parenthesis suffixes before we iterate
3312 if (getLexer().is(AsmToken::LBrac)) {
3313 if (parseBracketSuffix(Name, Operands))
3315 } else if (getLexer().is(AsmToken::LParen) &&
3316 parseParenSuffix(Name, Operands))
3320 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3321 SMLoc Loc = getLexer().getLoc();
3322 Parser.eatToEndOfStatement();
3323 return Error(Loc, "unexpected token in argument list");
3325 Parser.Lex(); // Consume the EndOfStatement.
3329 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
3330 MCAsmParser &Parser = getParser();
3331 SMLoc Loc = getLexer().getLoc();
3332 Parser.eatToEndOfStatement();
3333 return Error(Loc, ErrorMsg);
3336 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
3337 return Error(Loc, ErrorMsg);
3340 bool MipsAsmParser::parseSetNoAtDirective() {
3341 MCAsmParser &Parser = getParser();
3342 // Line should look like: ".set noat".
3344 // Set the $at register to $0.
3345 AssemblerOptions.back()->setATRegIndex(0);
3347 Parser.Lex(); // Eat "noat".
3349 // If this is not the end of the statement, report an error.
3350 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3351 reportParseError("unexpected token, expected end of statement");
3355 getTargetStreamer().emitDirectiveSetNoAt();
3356 Parser.Lex(); // Consume the EndOfStatement.
3360 bool MipsAsmParser::parseSetAtDirective() {
3361 // Line can be: ".set at", which sets $at to $1
3362 // or ".set at=$reg", which sets $at to $reg.
3363 MCAsmParser &Parser = getParser();
3364 Parser.Lex(); // Eat "at".
3366 if (getLexer().is(AsmToken::EndOfStatement)) {
3367 // No register was specified, so we set $at to $1.
3368 AssemblerOptions.back()->setATRegIndex(1);
3370 getTargetStreamer().emitDirectiveSetAt();
3371 Parser.Lex(); // Consume the EndOfStatement.
3375 if (getLexer().isNot(AsmToken::Equal)) {
3376 reportParseError("unexpected token, expected equals sign");
3379 Parser.Lex(); // Eat "=".
3381 if (getLexer().isNot(AsmToken::Dollar)) {
3382 if (getLexer().is(AsmToken::EndOfStatement)) {
3383 reportParseError("no register specified");
3386 reportParseError("unexpected token, expected dollar sign '$'");
3390 Parser.Lex(); // Eat "$".
3392 // Find out what "reg" is.
3394 const AsmToken &Reg = Parser.getTok();
3395 if (Reg.is(AsmToken::Identifier)) {
3396 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
3397 } else if (Reg.is(AsmToken::Integer)) {
3398 AtRegNo = Reg.getIntVal();
3400 reportParseError("unexpected token, expected identifier or integer");
3404 // Check if $reg is a valid register. If it is, set $at to $reg.
3405 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
3406 reportParseError("invalid register");
3409 Parser.Lex(); // Eat "reg".
3411 // If this is not the end of the statement, report an error.
3412 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3413 reportParseError("unexpected token, expected end of statement");
3417 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
3419 Parser.Lex(); // Consume the EndOfStatement.
3423 bool MipsAsmParser::parseSetReorderDirective() {
3424 MCAsmParser &Parser = getParser();
3426 // If this is not the end of the statement, report an error.
3427 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3428 reportParseError("unexpected token, expected end of statement");
3431 AssemblerOptions.back()->setReorder();
3432 getTargetStreamer().emitDirectiveSetReorder();
3433 Parser.Lex(); // Consume the EndOfStatement.
3437 bool MipsAsmParser::parseSetNoReorderDirective() {
3438 MCAsmParser &Parser = getParser();
3440 // If this is not the end of the statement, report an error.
3441 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3442 reportParseError("unexpected token, expected end of statement");
3445 AssemblerOptions.back()->setNoReorder();
3446 getTargetStreamer().emitDirectiveSetNoReorder();
3447 Parser.Lex(); // Consume the EndOfStatement.
3451 bool MipsAsmParser::parseSetMacroDirective() {
3452 MCAsmParser &Parser = getParser();
3454 // If this is not the end of the statement, report an error.
3455 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3456 reportParseError("unexpected token, expected end of statement");
3459 AssemblerOptions.back()->setMacro();
3460 getTargetStreamer().emitDirectiveSetMacro();
3461 Parser.Lex(); // Consume the EndOfStatement.
3465 bool MipsAsmParser::parseSetNoMacroDirective() {
3466 MCAsmParser &Parser = getParser();
3468 // If this is not the end of the statement, report an error.
3469 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3470 reportParseError("unexpected token, expected end of statement");
3473 if (AssemblerOptions.back()->isReorder()) {
3474 reportParseError("`noreorder' must be set before `nomacro'");
3477 AssemblerOptions.back()->setNoMacro();
3478 getTargetStreamer().emitDirectiveSetNoMacro();
3479 Parser.Lex(); // Consume the EndOfStatement.
3483 bool MipsAsmParser::parseSetMsaDirective() {
3484 MCAsmParser &Parser = getParser();
3487 // If this is not the end of the statement, report an error.
3488 if (getLexer().isNot(AsmToken::EndOfStatement))
3489 return reportParseError("unexpected token, expected end of statement");
3491 setFeatureBits(Mips::FeatureMSA, "msa");
3492 getTargetStreamer().emitDirectiveSetMsa();
3496 bool MipsAsmParser::parseSetNoMsaDirective() {
3497 MCAsmParser &Parser = getParser();
3500 // If this is not the end of the statement, report an error.
3501 if (getLexer().isNot(AsmToken::EndOfStatement))
3502 return reportParseError("unexpected token, expected end of statement");
3504 clearFeatureBits(Mips::FeatureMSA, "msa");
3505 getTargetStreamer().emitDirectiveSetNoMsa();
3509 bool MipsAsmParser::parseSetNoDspDirective() {
3510 MCAsmParser &Parser = getParser();
3511 Parser.Lex(); // Eat "nodsp".
3513 // If this is not the end of the statement, report an error.
3514 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3515 reportParseError("unexpected token, expected end of statement");
3519 clearFeatureBits(Mips::FeatureDSP, "dsp");
3520 getTargetStreamer().emitDirectiveSetNoDsp();
3524 bool MipsAsmParser::parseSetMips16Directive() {
3525 MCAsmParser &Parser = getParser();
3526 Parser.Lex(); // Eat "mips16".
3528 // If this is not the end of the statement, report an error.
3529 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3530 reportParseError("unexpected token, expected end of statement");
3534 setFeatureBits(Mips::FeatureMips16, "mips16");
3535 getTargetStreamer().emitDirectiveSetMips16();
3536 Parser.Lex(); // Consume the EndOfStatement.
3540 bool MipsAsmParser::parseSetNoMips16Directive() {
3541 MCAsmParser &Parser = getParser();
3542 Parser.Lex(); // Eat "nomips16".
3544 // If this is not the end of the statement, report an error.
3545 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3546 reportParseError("unexpected token, expected end of statement");
3550 clearFeatureBits(Mips::FeatureMips16, "mips16");
3551 getTargetStreamer().emitDirectiveSetNoMips16();
3552 Parser.Lex(); // Consume the EndOfStatement.
3556 bool MipsAsmParser::parseSetFpDirective() {
3557 MCAsmParser &Parser = getParser();
3558 MipsABIFlagsSection::FpABIKind FpAbiVal;
3559 // Line can be: .set fp=32
3562 Parser.Lex(); // Eat fp token
3563 AsmToken Tok = Parser.getTok();
3564 if (Tok.isNot(AsmToken::Equal)) {
3565 reportParseError("unexpected token, expected equals sign '='");
3568 Parser.Lex(); // Eat '=' token.
3569 Tok = Parser.getTok();
3571 if (!parseFpABIValue(FpAbiVal, ".set"))
3574 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3575 reportParseError("unexpected token, expected end of statement");
3578 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
3579 Parser.Lex(); // Consume the EndOfStatement.
3583 bool MipsAsmParser::parseSetPopDirective() {
3584 MCAsmParser &Parser = getParser();
3585 SMLoc Loc = getLexer().getLoc();
3588 if (getLexer().isNot(AsmToken::EndOfStatement))
3589 return reportParseError("unexpected token, expected end of statement");
3591 // Always keep an element on the options "stack" to prevent the user
3592 // from changing the initial options. This is how we remember them.
3593 if (AssemblerOptions.size() == 2)
3594 return reportParseError(Loc, ".set pop with no .set push");
3596 AssemblerOptions.pop_back();
3597 setAvailableFeatures(AssemblerOptions.back()->getFeatures());
3599 getTargetStreamer().emitDirectiveSetPop();
3603 bool MipsAsmParser::parseSetPushDirective() {
3604 MCAsmParser &Parser = getParser();
3606 if (getLexer().isNot(AsmToken::EndOfStatement))
3607 return reportParseError("unexpected token, expected end of statement");
3609 // Create a copy of the current assembler options environment and push it.
3610 AssemblerOptions.push_back(
3611 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
3613 getTargetStreamer().emitDirectiveSetPush();
3617 bool MipsAsmParser::parseSetAssignment() {
3619 const MCExpr *Value;
3620 MCAsmParser &Parser = getParser();
3622 if (Parser.parseIdentifier(Name))
3623 reportParseError("expected identifier after .set");
3625 if (getLexer().isNot(AsmToken::Comma))
3626 return reportParseError("unexpected token, expected comma");
3629 if (Parser.parseExpression(Value))
3630 return reportParseError("expected valid expression after comma");
3632 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
3633 Sym->setVariableValue(Value);
3638 bool MipsAsmParser::parseSetMips0Directive() {
3639 MCAsmParser &Parser = getParser();
3641 if (getLexer().isNot(AsmToken::EndOfStatement))
3642 return reportParseError("unexpected token, expected end of statement");
3644 // Reset assembler options to their initial values.
3645 setAvailableFeatures(AssemblerOptions.front()->getFeatures());
3646 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
3648 getTargetStreamer().emitDirectiveSetMips0();
3652 bool MipsAsmParser::parseSetArchDirective() {
3653 MCAsmParser &Parser = getParser();
3655 if (getLexer().isNot(AsmToken::Equal))
3656 return reportParseError("unexpected token, expected equals sign");
3660 if (Parser.parseIdentifier(Arch))
3661 return reportParseError("expected arch identifier");
3663 StringRef ArchFeatureName =
3664 StringSwitch<StringRef>(Arch)
3665 .Case("mips1", "mips1")
3666 .Case("mips2", "mips2")
3667 .Case("mips3", "mips3")
3668 .Case("mips4", "mips4")
3669 .Case("mips5", "mips5")
3670 .Case("mips32", "mips32")
3671 .Case("mips32r2", "mips32r2")
3672 .Case("mips32r3", "mips32r3")
3673 .Case("mips32r5", "mips32r5")
3674 .Case("mips32r6", "mips32r6")
3675 .Case("mips64", "mips64")
3676 .Case("mips64r2", "mips64r2")
3677 .Case("mips64r3", "mips64r3")
3678 .Case("mips64r5", "mips64r5")
3679 .Case("mips64r6", "mips64r6")
3680 .Case("cnmips", "cnmips")
3681 .Case("r4000", "mips3") // This is an implementation of Mips3.
3684 if (ArchFeatureName.empty())
3685 return reportParseError("unsupported architecture");
3687 selectArch(ArchFeatureName);
3688 getTargetStreamer().emitDirectiveSetArch(Arch);
3692 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
3693 MCAsmParser &Parser = getParser();
3695 if (getLexer().isNot(AsmToken::EndOfStatement))
3696 return reportParseError("unexpected token, expected end of statement");
3700 llvm_unreachable("Unimplemented feature");
3701 case Mips::FeatureDSP:
3702 setFeatureBits(Mips::FeatureDSP, "dsp");
3703 getTargetStreamer().emitDirectiveSetDsp();
3705 case Mips::FeatureMicroMips:
3706 getTargetStreamer().emitDirectiveSetMicroMips();
3708 case Mips::FeatureMips1:
3709 selectArch("mips1");
3710 getTargetStreamer().emitDirectiveSetMips1();
3712 case Mips::FeatureMips2:
3713 selectArch("mips2");
3714 getTargetStreamer().emitDirectiveSetMips2();
3716 case Mips::FeatureMips3:
3717 selectArch("mips3");
3718 getTargetStreamer().emitDirectiveSetMips3();
3720 case Mips::FeatureMips4:
3721 selectArch("mips4");
3722 getTargetStreamer().emitDirectiveSetMips4();
3724 case Mips::FeatureMips5:
3725 selectArch("mips5");
3726 getTargetStreamer().emitDirectiveSetMips5();
3728 case Mips::FeatureMips32:
3729 selectArch("mips32");
3730 getTargetStreamer().emitDirectiveSetMips32();
3732 case Mips::FeatureMips32r2:
3733 selectArch("mips32r2");
3734 getTargetStreamer().emitDirectiveSetMips32R2();
3736 case Mips::FeatureMips32r3:
3737 selectArch("mips32r3");
3738 getTargetStreamer().emitDirectiveSetMips32R3();
3740 case Mips::FeatureMips32r5:
3741 selectArch("mips32r5");
3742 getTargetStreamer().emitDirectiveSetMips32R5();
3744 case Mips::FeatureMips32r6:
3745 selectArch("mips32r6");
3746 getTargetStreamer().emitDirectiveSetMips32R6();
3748 case Mips::FeatureMips64:
3749 selectArch("mips64");
3750 getTargetStreamer().emitDirectiveSetMips64();
3752 case Mips::FeatureMips64r2:
3753 selectArch("mips64r2");
3754 getTargetStreamer().emitDirectiveSetMips64R2();
3756 case Mips::FeatureMips64r3:
3757 selectArch("mips64r3");
3758 getTargetStreamer().emitDirectiveSetMips64R3();
3760 case Mips::FeatureMips64r5:
3761 selectArch("mips64r5");
3762 getTargetStreamer().emitDirectiveSetMips64R5();
3764 case Mips::FeatureMips64r6:
3765 selectArch("mips64r6");
3766 getTargetStreamer().emitDirectiveSetMips64R6();
3772 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
3773 MCAsmParser &Parser = getParser();
3774 if (getLexer().isNot(AsmToken::Comma)) {
3775 SMLoc Loc = getLexer().getLoc();
3776 Parser.eatToEndOfStatement();
3777 return Error(Loc, ErrorStr);
3780 Parser.Lex(); // Eat the comma.
3784 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
3785 if (AssemblerOptions.back()->isReorder())
3786 Warning(Loc, ".cpload should be inside a noreorder section");
3788 if (inMips16Mode()) {
3789 reportParseError(".cpload is not supported in Mips16 mode");
3793 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
3794 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
3795 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3796 reportParseError("expected register containing function address");
3800 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
3801 if (!RegOpnd.isGPRAsmReg()) {
3802 reportParseError(RegOpnd.getStartLoc(), "invalid register");
3806 // If this is not the end of the statement, report an error.
3807 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3808 reportParseError("unexpected token, expected end of statement");
3812 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
3816 bool MipsAsmParser::parseDirectiveCPSetup() {
3817 MCAsmParser &Parser = getParser();
3820 bool SaveIsReg = true;
3822 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3823 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3824 if (ResTy == MatchOperand_NoMatch) {
3825 reportParseError("expected register containing function address");
3826 Parser.eatToEndOfStatement();
3830 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3831 if (!FuncRegOpnd.isGPRAsmReg()) {
3832 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
3833 Parser.eatToEndOfStatement();
3837 FuncReg = FuncRegOpnd.getGPR32Reg();
3840 if (!eatComma("unexpected token, expected comma"))
3843 ResTy = parseAnyRegister(TmpReg);
3844 if (ResTy == MatchOperand_NoMatch) {
3845 const AsmToken &Tok = Parser.getTok();
3846 if (Tok.is(AsmToken::Integer)) {
3847 Save = Tok.getIntVal();
3851 reportParseError("expected save register or stack offset");
3852 Parser.eatToEndOfStatement();
3856 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3857 if (!SaveOpnd.isGPRAsmReg()) {
3858 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
3859 Parser.eatToEndOfStatement();
3862 Save = SaveOpnd.getGPR32Reg();
3865 if (!eatComma("unexpected token, expected comma"))
3869 if (Parser.parseExpression(Expr)) {
3870 reportParseError("expected expression");
3874 if (Expr->getKind() != MCExpr::SymbolRef) {
3875 reportParseError("expected symbol");
3878 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3880 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
3885 bool MipsAsmParser::parseDirectiveNaN() {
3886 MCAsmParser &Parser = getParser();
3887 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3888 const AsmToken &Tok = Parser.getTok();
3890 if (Tok.getString() == "2008") {
3892 getTargetStreamer().emitDirectiveNaN2008();
3894 } else if (Tok.getString() == "legacy") {
3896 getTargetStreamer().emitDirectiveNaNLegacy();
3900 // If we don't recognize the option passed to the .nan
3901 // directive (e.g. no option or unknown option), emit an error.
3902 reportParseError("invalid option in .nan directive");
3906 bool MipsAsmParser::parseDirectiveSet() {
3907 MCAsmParser &Parser = getParser();
3908 // Get the next token.
3909 const AsmToken &Tok = Parser.getTok();
3911 if (Tok.getString() == "noat") {
3912 return parseSetNoAtDirective();
3913 } else if (Tok.getString() == "at") {
3914 return parseSetAtDirective();
3915 } else if (Tok.getString() == "arch") {
3916 return parseSetArchDirective();
3917 } else if (Tok.getString() == "fp") {
3918 return parseSetFpDirective();
3919 } else if (Tok.getString() == "pop") {
3920 return parseSetPopDirective();
3921 } else if (Tok.getString() == "push") {
3922 return parseSetPushDirective();
3923 } else if (Tok.getString() == "reorder") {
3924 return parseSetReorderDirective();
3925 } else if (Tok.getString() == "noreorder") {
3926 return parseSetNoReorderDirective();
3927 } else if (Tok.getString() == "macro") {
3928 return parseSetMacroDirective();
3929 } else if (Tok.getString() == "nomacro") {
3930 return parseSetNoMacroDirective();
3931 } else if (Tok.getString() == "mips16") {
3932 return parseSetMips16Directive();
3933 } else if (Tok.getString() == "nomips16") {
3934 return parseSetNoMips16Directive();
3935 } else if (Tok.getString() == "nomicromips") {
3936 getTargetStreamer().emitDirectiveSetNoMicroMips();
3937 Parser.eatToEndOfStatement();
3939 } else if (Tok.getString() == "micromips") {
3940 return parseSetFeature(Mips::FeatureMicroMips);
3941 } else if (Tok.getString() == "mips0") {
3942 return parseSetMips0Directive();
3943 } else if (Tok.getString() == "mips1") {
3944 return parseSetFeature(Mips::FeatureMips1);
3945 } else if (Tok.getString() == "mips2") {
3946 return parseSetFeature(Mips::FeatureMips2);
3947 } else if (Tok.getString() == "mips3") {
3948 return parseSetFeature(Mips::FeatureMips3);
3949 } else if (Tok.getString() == "mips4") {
3950 return parseSetFeature(Mips::FeatureMips4);
3951 } else if (Tok.getString() == "mips5") {
3952 return parseSetFeature(Mips::FeatureMips5);
3953 } else if (Tok.getString() == "mips32") {
3954 return parseSetFeature(Mips::FeatureMips32);
3955 } else if (Tok.getString() == "mips32r2") {
3956 return parseSetFeature(Mips::FeatureMips32r2);
3957 } else if (Tok.getString() == "mips32r3") {
3958 return parseSetFeature(Mips::FeatureMips32r3);
3959 } else if (Tok.getString() == "mips32r5") {
3960 return parseSetFeature(Mips::FeatureMips32r5);
3961 } else if (Tok.getString() == "mips32r6") {
3962 return parseSetFeature(Mips::FeatureMips32r6);
3963 } else if (Tok.getString() == "mips64") {
3964 return parseSetFeature(Mips::FeatureMips64);
3965 } else if (Tok.getString() == "mips64r2") {
3966 return parseSetFeature(Mips::FeatureMips64r2);
3967 } else if (Tok.getString() == "mips64r3") {
3968 return parseSetFeature(Mips::FeatureMips64r3);
3969 } else if (Tok.getString() == "mips64r5") {
3970 return parseSetFeature(Mips::FeatureMips64r5);
3971 } else if (Tok.getString() == "mips64r6") {
3972 return parseSetFeature(Mips::FeatureMips64r6);
3973 } else if (Tok.getString() == "dsp") {
3974 return parseSetFeature(Mips::FeatureDSP);
3975 } else if (Tok.getString() == "nodsp") {
3976 return parseSetNoDspDirective();
3977 } else if (Tok.getString() == "msa") {
3978 return parseSetMsaDirective();
3979 } else if (Tok.getString() == "nomsa") {
3980 return parseSetNoMsaDirective();
3982 // It is just an identifier, look for an assignment.
3983 parseSetAssignment();
3990 /// parseDataDirective
3991 /// ::= .word [ expression (, expression)* ]
3992 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
3993 MCAsmParser &Parser = getParser();
3994 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3996 const MCExpr *Value;
3997 if (getParser().parseExpression(Value))
4000 getParser().getStreamer().EmitValue(Value, Size);
4002 if (getLexer().is(AsmToken::EndOfStatement))
4005 if (getLexer().isNot(AsmToken::Comma))
4006 return Error(L, "unexpected token, expected comma");
4015 /// parseDirectiveGpWord
4016 /// ::= .gpword local_sym
4017 bool MipsAsmParser::parseDirectiveGpWord() {
4018 MCAsmParser &Parser = getParser();
4019 const MCExpr *Value;
4020 // EmitGPRel32Value requires an expression, so we are using base class
4021 // method to evaluate the expression.
4022 if (getParser().parseExpression(Value))
4024 getParser().getStreamer().EmitGPRel32Value(Value);
4026 if (getLexer().isNot(AsmToken::EndOfStatement))
4027 return Error(getLexer().getLoc(),
4028 "unexpected token, expected end of statement");
4029 Parser.Lex(); // Eat EndOfStatement token.
4033 /// parseDirectiveGpDWord
4034 /// ::= .gpdword local_sym
4035 bool MipsAsmParser::parseDirectiveGpDWord() {
4036 MCAsmParser &Parser = getParser();
4037 const MCExpr *Value;
4038 // EmitGPRel64Value requires an expression, so we are using base class
4039 // method to evaluate the expression.
4040 if (getParser().parseExpression(Value))
4042 getParser().getStreamer().EmitGPRel64Value(Value);
4044 if (getLexer().isNot(AsmToken::EndOfStatement))
4045 return Error(getLexer().getLoc(),
4046 "unexpected token, expected end of statement");
4047 Parser.Lex(); // Eat EndOfStatement token.
4051 bool MipsAsmParser::parseDirectiveOption() {
4052 MCAsmParser &Parser = getParser();
4053 // Get the option token.
4054 AsmToken Tok = Parser.getTok();
4055 // At the moment only identifiers are supported.
4056 if (Tok.isNot(AsmToken::Identifier)) {
4057 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
4058 Parser.eatToEndOfStatement();
4062 StringRef Option = Tok.getIdentifier();
4064 if (Option == "pic0") {
4065 getTargetStreamer().emitDirectiveOptionPic0();
4067 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4068 Error(Parser.getTok().getLoc(),
4069 "unexpected token, expected end of statement");
4070 Parser.eatToEndOfStatement();
4075 if (Option == "pic2") {
4076 getTargetStreamer().emitDirectiveOptionPic2();
4078 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4079 Error(Parser.getTok().getLoc(),
4080 "unexpected token, expected end of statement");
4081 Parser.eatToEndOfStatement();
4087 Warning(Parser.getTok().getLoc(),
4088 "unknown option, expected 'pic0' or 'pic2'");
4089 Parser.eatToEndOfStatement();
4093 /// parseInsnDirective
4095 bool MipsAsmParser::parseInsnDirective() {
4096 // If this is not the end of the statement, report an error.
4097 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4098 reportParseError("unexpected token, expected end of statement");
4102 // The actual label marking happens in
4103 // MipsELFStreamer::createPendingLabelRelocs().
4104 getTargetStreamer().emitDirectiveInsn();
4106 getParser().Lex(); // Eat EndOfStatement token.
4110 /// parseDirectiveModule
4111 /// ::= .module oddspreg
4112 /// ::= .module nooddspreg
4113 /// ::= .module fp=value
4114 bool MipsAsmParser::parseDirectiveModule() {
4115 MCAsmParser &Parser = getParser();
4116 MCAsmLexer &Lexer = getLexer();
4117 SMLoc L = Lexer.getLoc();
4119 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
4120 // TODO : get a better message.
4121 reportParseError(".module directive must appear before any code");
4126 if (Parser.parseIdentifier(Option)) {
4127 reportParseError("expected .module option identifier");
4131 if (Option == "oddspreg") {
4132 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
4133 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4135 // If this is not the end of the statement, report an error.
4136 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4137 reportParseError("unexpected token, expected end of statement");
4141 return false; // parseDirectiveModule has finished successfully.
4142 } else if (Option == "nooddspreg") {
4144 Error(L, "'.module nooddspreg' requires the O32 ABI");
4148 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
4149 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4151 // If this is not the end of the statement, report an error.
4152 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4153 reportParseError("unexpected token, expected end of statement");
4157 return false; // parseDirectiveModule has finished successfully.
4158 } else if (Option == "fp") {
4159 return parseDirectiveModuleFP();
4161 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
4165 /// parseDirectiveModuleFP
4169 bool MipsAsmParser::parseDirectiveModuleFP() {
4170 MCAsmParser &Parser = getParser();
4171 MCAsmLexer &Lexer = getLexer();
4173 if (Lexer.isNot(AsmToken::Equal)) {
4174 reportParseError("unexpected token, expected equals sign '='");
4177 Parser.Lex(); // Eat '=' token.
4179 MipsABIFlagsSection::FpABIKind FpABI;
4180 if (!parseFpABIValue(FpABI, ".module"))
4183 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4184 reportParseError("unexpected token, expected end of statement");
4188 // Emit appropriate flags.
4189 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
4190 Parser.Lex(); // Consume the EndOfStatement.
4194 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
4195 StringRef Directive) {
4196 MCAsmParser &Parser = getParser();
4197 MCAsmLexer &Lexer = getLexer();
4199 if (Lexer.is(AsmToken::Identifier)) {
4200 StringRef Value = Parser.getTok().getString();
4203 if (Value != "xx") {
4204 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4209 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
4213 FpABI = MipsABIFlagsSection::FpABIKind::XX;
4217 if (Lexer.is(AsmToken::Integer)) {
4218 unsigned Value = Parser.getTok().getIntVal();
4221 if (Value != 32 && Value != 64) {
4222 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4228 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
4232 FpABI = MipsABIFlagsSection::FpABIKind::S32;
4234 FpABI = MipsABIFlagsSection::FpABIKind::S64;
4242 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
4243 MCAsmParser &Parser = getParser();
4244 StringRef IDVal = DirectiveID.getString();
4246 if (IDVal == ".cpload")
4247 return parseDirectiveCpLoad(DirectiveID.getLoc());
4248 if (IDVal == ".dword") {
4249 parseDataDirective(8, DirectiveID.getLoc());
4252 if (IDVal == ".ent") {
4253 StringRef SymbolName;
4255 if (Parser.parseIdentifier(SymbolName)) {
4256 reportParseError("expected identifier after .ent");
4260 // There's an undocumented extension that allows an integer to
4261 // follow the name of the procedure which AFAICS is ignored by GAS.
4262 // Example: .ent foo,2
4263 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4264 if (getLexer().isNot(AsmToken::Comma)) {
4265 // Even though we accept this undocumented extension for compatibility
4266 // reasons, the additional integer argument does not actually change
4267 // the behaviour of the '.ent' directive, so we would like to discourage
4268 // its use. We do this by not referring to the extended version in
4269 // error messages which are not directly related to its use.
4270 reportParseError("unexpected token, expected end of statement");
4273 Parser.Lex(); // Eat the comma.
4274 const MCExpr *DummyNumber;
4275 int64_t DummyNumberVal;
4276 // If the user was explicitly trying to use the extended version,
4277 // we still give helpful extension-related error messages.
4278 if (Parser.parseExpression(DummyNumber)) {
4279 reportParseError("expected number after comma");
4282 if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) {
4283 reportParseError("expected an absolute expression after comma");
4288 // If this is not the end of the statement, report an error.
4289 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4290 reportParseError("unexpected token, expected end of statement");
4294 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
4296 getTargetStreamer().emitDirectiveEnt(*Sym);
4301 if (IDVal == ".end") {
4302 StringRef SymbolName;
4304 if (Parser.parseIdentifier(SymbolName)) {
4305 reportParseError("expected identifier after .end");
4309 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4310 reportParseError("unexpected token, expected end of statement");
4314 if (CurrentFn == nullptr) {
4315 reportParseError(".end used without .ent");
4319 if ((SymbolName != CurrentFn->getName())) {
4320 reportParseError(".end symbol does not match .ent symbol");
4324 getTargetStreamer().emitDirectiveEnd(SymbolName);
4325 CurrentFn = nullptr;
4329 if (IDVal == ".frame") {
4330 // .frame $stack_reg, frame_size_in_bytes, $return_reg
4331 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4332 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4333 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4334 reportParseError("expected stack register");
4338 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4339 if (!StackRegOpnd.isGPRAsmReg()) {
4340 reportParseError(StackRegOpnd.getStartLoc(),
4341 "expected general purpose register");
4344 unsigned StackReg = StackRegOpnd.getGPR32Reg();
4346 if (Parser.getTok().is(AsmToken::Comma))
4349 reportParseError("unexpected token, expected comma");
4353 // Parse the frame size.
4354 const MCExpr *FrameSize;
4355 int64_t FrameSizeVal;
4357 if (Parser.parseExpression(FrameSize)) {
4358 reportParseError("expected frame size value");
4362 if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) {
4363 reportParseError("frame size not an absolute expression");
4367 if (Parser.getTok().is(AsmToken::Comma))
4370 reportParseError("unexpected token, expected comma");
4374 // Parse the return register.
4376 ResTy = parseAnyRegister(TmpReg);
4377 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4378 reportParseError("expected return register");
4382 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4383 if (!ReturnRegOpnd.isGPRAsmReg()) {
4384 reportParseError(ReturnRegOpnd.getStartLoc(),
4385 "expected general purpose register");
4389 // If this is not the end of the statement, report an error.
4390 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4391 reportParseError("unexpected token, expected end of statement");
4395 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
4396 ReturnRegOpnd.getGPR32Reg());
4400 if (IDVal == ".set") {
4401 return parseDirectiveSet();
4404 if (IDVal == ".mask" || IDVal == ".fmask") {
4405 // .mask bitmask, frame_offset
4406 // bitmask: One bit for each register used.
4407 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
4408 // first register is expected to be saved.
4410 // .mask 0x80000000, -4
4411 // .fmask 0x80000000, -4
4414 // Parse the bitmask
4415 const MCExpr *BitMask;
4418 if (Parser.parseExpression(BitMask)) {
4419 reportParseError("expected bitmask value");
4423 if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) {
4424 reportParseError("bitmask not an absolute expression");
4428 if (Parser.getTok().is(AsmToken::Comma))
4431 reportParseError("unexpected token, expected comma");
4435 // Parse the frame_offset
4436 const MCExpr *FrameOffset;
4437 int64_t FrameOffsetVal;
4439 if (Parser.parseExpression(FrameOffset)) {
4440 reportParseError("expected frame offset value");
4444 if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) {
4445 reportParseError("frame offset not an absolute expression");
4449 // If this is not the end of the statement, report an error.
4450 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4451 reportParseError("unexpected token, expected end of statement");
4455 if (IDVal == ".mask")
4456 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
4458 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
4462 if (IDVal == ".nan")
4463 return parseDirectiveNaN();
4465 if (IDVal == ".gpword") {
4466 parseDirectiveGpWord();
4470 if (IDVal == ".gpdword") {
4471 parseDirectiveGpDWord();
4475 if (IDVal == ".word") {
4476 parseDataDirective(4, DirectiveID.getLoc());
4480 if (IDVal == ".option")
4481 return parseDirectiveOption();
4483 if (IDVal == ".abicalls") {
4484 getTargetStreamer().emitDirectiveAbiCalls();
4485 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4486 Error(Parser.getTok().getLoc(),
4487 "unexpected token, expected end of statement");
4489 Parser.eatToEndOfStatement();
4494 if (IDVal == ".cpsetup")
4495 return parseDirectiveCPSetup();
4497 if (IDVal == ".module")
4498 return parseDirectiveModule();
4500 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
4501 return parseInternalDirectiveReallowModule();
4503 if (IDVal == ".insn")
4504 return parseInsnDirective();
4509 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
4510 // If this is not the end of the statement, report an error.
4511 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4512 reportParseError("unexpected token, expected end of statement");
4516 getTargetStreamer().reallowModuleDirective();
4518 getParser().Lex(); // Eat EndOfStatement token.
4522 extern "C" void LLVMInitializeMipsAsmParser() {
4523 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
4524 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
4525 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
4526 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
4529 #define GET_REGISTER_MATCHER
4530 #define GET_MATCHER_IMPLEMENTATION
4531 #include "MipsGenAsmMatcher.inc"