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(MCInst &Inst, SMLoc IDLoc,
198 SmallVectorImpl<MCInst> &Instructions);
200 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
201 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
204 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
205 SmallVectorImpl<MCInst> &Instructions);
207 void createNop(bool hasShortDelaySlot, SMLoc IDLoc,
208 SmallVectorImpl<MCInst> &Instructions);
210 void createAddu(unsigned DstReg, unsigned SrcReg, unsigned TrgReg,
211 SmallVectorImpl<MCInst> &Instructions);
213 bool reportParseError(Twine ErrorMsg);
214 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
216 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
217 bool parseRelocOperand(const MCExpr *&Res);
219 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
221 bool isEvaluated(const MCExpr *Expr);
222 bool parseSetMips0Directive();
223 bool parseSetArchDirective();
224 bool parseSetFeature(uint64_t Feature);
225 bool parseDirectiveCpLoad(SMLoc Loc);
226 bool parseDirectiveCPSetup();
227 bool parseDirectiveNaN();
228 bool parseDirectiveSet();
229 bool parseDirectiveOption();
230 bool parseInsnDirective();
232 bool parseSetAtDirective();
233 bool parseSetNoAtDirective();
234 bool parseSetMacroDirective();
235 bool parseSetNoMacroDirective();
236 bool parseSetMsaDirective();
237 bool parseSetNoMsaDirective();
238 bool parseSetNoDspDirective();
239 bool parseSetReorderDirective();
240 bool parseSetNoReorderDirective();
241 bool parseSetMips16Directive();
242 bool parseSetNoMips16Directive();
243 bool parseSetFpDirective();
244 bool parseSetPopDirective();
245 bool parseSetPushDirective();
247 bool parseSetAssignment();
249 bool parseDataDirective(unsigned Size, SMLoc L);
250 bool parseDirectiveGpWord();
251 bool parseDirectiveGpDWord();
252 bool parseDirectiveModule();
253 bool parseDirectiveModuleFP();
254 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
255 StringRef Directive);
257 bool parseInternalDirectiveReallowModule();
259 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
261 bool eatComma(StringRef ErrorStr);
263 int matchCPURegisterName(StringRef Symbol);
265 int matchHWRegsRegisterName(StringRef Symbol);
267 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
269 int matchFPURegisterName(StringRef Name);
271 int matchFCCRegisterName(StringRef Name);
273 int matchACRegisterName(StringRef Name);
275 int matchMSA128RegisterName(StringRef Name);
277 int matchMSA128CtrlRegisterName(StringRef Name);
279 unsigned getReg(int RC, int RegNo);
281 unsigned getGPR(int RegNo);
283 /// Returns the internal register number for the current AT. Also checks if
284 /// the current AT is unavailable (set to $0) and gives an error if it is.
285 /// This should be used in pseudo-instruction expansions which need AT.
286 unsigned getATReg(SMLoc Loc);
288 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
289 SmallVectorImpl<MCInst> &Instructions);
291 // Helper function that checks if the value of a vector index is within the
292 // boundaries of accepted values for each RegisterKind
293 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
294 bool validateMSAIndex(int Val, int RegKind);
296 // Selects a new architecture by updating the FeatureBits with the necessary
297 // info including implied dependencies.
298 // Internally, it clears all the feature bits related to *any* architecture
299 // and selects the new one using the ToggleFeature functionality of the
300 // MCSubtargetInfo object that handles implied dependencies. The reason we
301 // clear all the arch related bits manually is because ToggleFeature only
302 // clears the features that imply the feature being cleared and not the
303 // features implied by the feature being cleared. This is easier to see
305 // --------------------------------------------------
306 // | Feature | Implies |
307 // | -------------------------------------------------|
308 // | FeatureMips1 | None |
309 // | FeatureMips2 | FeatureMips1 |
310 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
311 // | FeatureMips4 | FeatureMips3 |
313 // --------------------------------------------------
315 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
316 // FeatureMipsGP64 | FeatureMips1)
317 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
318 void selectArch(StringRef ArchFeature) {
319 uint64_t FeatureBits = STI.getFeatureBits();
320 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
321 STI.setFeatureBits(FeatureBits);
322 setAvailableFeatures(
323 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
324 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
327 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
328 if (!(STI.getFeatureBits() & Feature)) {
329 setAvailableFeatures(
330 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
332 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
335 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
336 if (STI.getFeatureBits() & Feature) {
337 setAvailableFeatures(
338 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
340 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
344 enum MipsMatchResultTy {
345 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
346 #define GET_OPERAND_DIAGNOSTIC_TYPES
347 #include "MipsGenAsmMatcher.inc"
348 #undef GET_OPERAND_DIAGNOSTIC_TYPES
352 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
353 const MCInstrInfo &MII, const MCTargetOptions &Options)
354 : MCTargetAsmParser(), STI(sti),
355 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
356 sti.getCPU(), Options)) {
357 MCAsmParserExtension::Initialize(parser);
359 parser.addAliasForDirective(".asciiz", ".asciz");
361 // Initialize the set of available features.
362 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
364 // Remember the initial assembler options. The user can not modify these.
365 AssemblerOptions.push_back(
366 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
368 // Create an assembler options environment for the user to modify.
369 AssemblerOptions.push_back(
370 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
372 getTargetStreamer().updateABIInfo(*this);
374 if (!isABI_O32() && !useOddSPReg() != 0)
375 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
380 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
381 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
383 bool isGP64bit() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }
384 bool isFP64bit() const { return STI.getFeatureBits() & Mips::FeatureFP64Bit; }
385 const MipsABIInfo &getABI() const { return ABI; }
386 bool isABI_N32() const { return ABI.IsN32(); }
387 bool isABI_N64() const { return ABI.IsN64(); }
388 bool isABI_O32() const { return ABI.IsO32(); }
389 bool isABI_FPXX() const { return STI.getFeatureBits() & Mips::FeatureFPXX; }
391 bool useOddSPReg() const {
392 return !(STI.getFeatureBits() & Mips::FeatureNoOddSPReg);
395 bool inMicroMipsMode() const {
396 return STI.getFeatureBits() & Mips::FeatureMicroMips;
398 bool hasMips1() const { return STI.getFeatureBits() & Mips::FeatureMips1; }
399 bool hasMips2() const { return STI.getFeatureBits() & Mips::FeatureMips2; }
400 bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; }
401 bool hasMips4() const { return STI.getFeatureBits() & Mips::FeatureMips4; }
402 bool hasMips5() const { return STI.getFeatureBits() & Mips::FeatureMips5; }
403 bool hasMips32() const {
404 return (STI.getFeatureBits() & Mips::FeatureMips32);
406 bool hasMips64() const {
407 return (STI.getFeatureBits() & Mips::FeatureMips64);
409 bool hasMips32r2() const {
410 return (STI.getFeatureBits() & Mips::FeatureMips32r2);
412 bool hasMips64r2() const {
413 return (STI.getFeatureBits() & Mips::FeatureMips64r2);
415 bool hasMips32r3() const {
416 return (STI.getFeatureBits() & Mips::FeatureMips32r3);
418 bool hasMips64r3() const {
419 return (STI.getFeatureBits() & Mips::FeatureMips64r3);
421 bool hasMips32r5() const {
422 return (STI.getFeatureBits() & Mips::FeatureMips32r5);
424 bool hasMips64r5() const {
425 return (STI.getFeatureBits() & Mips::FeatureMips64r5);
427 bool hasMips32r6() const {
428 return (STI.getFeatureBits() & Mips::FeatureMips32r6);
430 bool hasMips64r6() const {
431 return (STI.getFeatureBits() & Mips::FeatureMips64r6);
433 bool hasCnMips() const {
434 return (STI.getFeatureBits() & Mips::FeatureCnMips);
436 bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); }
437 bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); }
438 bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); }
440 bool inMips16Mode() const {
441 return STI.getFeatureBits() & Mips::FeatureMips16;
444 bool useSoftFloat() const {
445 return (STI.getFeatureBits() & Mips::FeatureSoftFloat);
448 /// Warn if RegIndex is the same as the current AT.
449 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
455 /// MipsOperand - Instances of this class represent a parsed Mips machine
457 class MipsOperand : public MCParsedAsmOperand {
459 /// Broad categories of register classes
460 /// The exact class is finalized by the render method.
462 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
463 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
465 RegKind_FCC = 4, /// FCC
466 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
467 RegKind_MSACtrl = 16, /// MSA control registers
468 RegKind_COP2 = 32, /// COP2
469 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
471 RegKind_CCR = 128, /// CCR
472 RegKind_HWRegs = 256, /// HWRegs
473 RegKind_COP3 = 512, /// COP3
475 /// Potentially any (e.g. $1)
476 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
477 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
478 RegKind_CCR | RegKind_HWRegs | RegKind_COP3
483 k_Immediate, /// An immediate (possibly involving symbol references)
484 k_Memory, /// Base + Offset Memory Address
485 k_PhysRegister, /// A physical register from the Mips namespace
486 k_RegisterIndex, /// A register index in one or more RegKind.
487 k_Token, /// A simple token
488 k_RegList, /// A physical register list
489 k_RegPair /// A pair of physical register
493 MipsOperand(KindTy K, MipsAsmParser &Parser)
494 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
497 /// For diagnostics, and checking the assembler temporary
498 MipsAsmParser &AsmParser;
506 unsigned Num; /// Register Number
510 unsigned Index; /// Index into the register class
511 RegKind Kind; /// Bitfield of the kinds it could possibly be
512 const MCRegisterInfo *RegInfo;
525 SmallVector<unsigned, 10> *List;
530 struct PhysRegOp PhysReg;
531 struct RegIdxOp RegIdx;
534 struct RegListOp RegList;
537 SMLoc StartLoc, EndLoc;
539 /// Internal constructor for register kinds
540 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
541 const MCRegisterInfo *RegInfo,
543 MipsAsmParser &Parser) {
544 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
545 Op->RegIdx.Index = Index;
546 Op->RegIdx.RegInfo = RegInfo;
547 Op->RegIdx.Kind = RegKind;
554 /// Coerce the register to GPR32 and return the real register for the current
556 unsigned getGPR32Reg() const {
557 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
558 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
559 unsigned ClassID = Mips::GPR32RegClassID;
560 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
563 /// Coerce the register to GPR32 and return the real register for the current
565 unsigned getGPRMM16Reg() const {
566 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
567 unsigned ClassID = Mips::GPR32RegClassID;
568 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
571 /// Coerce the register to GPR64 and return the real register for the current
573 unsigned getGPR64Reg() const {
574 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
575 unsigned ClassID = Mips::GPR64RegClassID;
576 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
580 /// Coerce the register to AFGR64 and return the real register for the current
582 unsigned getAFGR64Reg() const {
583 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
584 if (RegIdx.Index % 2 != 0)
585 AsmParser.Warning(StartLoc, "Float register should be even.");
586 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
587 .getRegister(RegIdx.Index / 2);
590 /// Coerce the register to FGR64 and return the real register for the current
592 unsigned getFGR64Reg() const {
593 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
594 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
595 .getRegister(RegIdx.Index);
598 /// Coerce the register to FGR32 and return the real register for the current
600 unsigned getFGR32Reg() const {
601 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
602 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
603 .getRegister(RegIdx.Index);
606 /// Coerce the register to FGRH32 and return the real register for the current
608 unsigned getFGRH32Reg() const {
609 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
610 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
611 .getRegister(RegIdx.Index);
614 /// Coerce the register to FCC and return the real register for the current
616 unsigned getFCCReg() const {
617 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
618 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
619 .getRegister(RegIdx.Index);
622 /// Coerce the register to MSA128 and return the real register for the current
624 unsigned getMSA128Reg() const {
625 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
626 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
628 unsigned ClassID = Mips::MSA128BRegClassID;
629 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
632 /// Coerce the register to MSACtrl and return the real register for the
634 unsigned getMSACtrlReg() const {
635 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
636 unsigned ClassID = Mips::MSACtrlRegClassID;
637 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
640 /// Coerce the register to COP2 and return the real register for the
642 unsigned getCOP2Reg() const {
643 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
644 unsigned ClassID = Mips::COP2RegClassID;
645 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
648 /// Coerce the register to COP3 and return the real register for the
650 unsigned getCOP3Reg() const {
651 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
652 unsigned ClassID = Mips::COP3RegClassID;
653 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
656 /// Coerce the register to ACC64DSP and return the real register for the
658 unsigned getACC64DSPReg() const {
659 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
660 unsigned ClassID = Mips::ACC64DSPRegClassID;
661 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
664 /// Coerce the register to HI32DSP and return the real register for the
666 unsigned getHI32DSPReg() const {
667 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
668 unsigned ClassID = Mips::HI32DSPRegClassID;
669 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
672 /// Coerce the register to LO32DSP and return the real register for the
674 unsigned getLO32DSPReg() const {
675 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
676 unsigned ClassID = Mips::LO32DSPRegClassID;
677 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
680 /// Coerce the register to CCR and return the real register for the
682 unsigned getCCRReg() const {
683 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
684 unsigned ClassID = Mips::CCRRegClassID;
685 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
688 /// Coerce the register to HWRegs and return the real register for the
690 unsigned getHWRegsReg() const {
691 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
692 unsigned ClassID = Mips::HWRegsRegClassID;
693 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
697 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
698 // Add as immediate when possible. Null MCExpr = 0.
700 Inst.addOperand(MCOperand::CreateImm(0));
701 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
702 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
704 Inst.addOperand(MCOperand::CreateExpr(Expr));
707 void addRegOperands(MCInst &Inst, unsigned N) const {
708 llvm_unreachable("Use a custom parser instead");
711 /// Render the operand to an MCInst as a GPR32
712 /// Asserts if the wrong number of operands are requested, or the operand
713 /// is not a k_RegisterIndex compatible with RegKind_GPR
714 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
715 assert(N == 1 && "Invalid number of operands!");
716 Inst.addOperand(MCOperand::CreateReg(getGPR32Reg()));
719 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
720 assert(N == 1 && "Invalid number of operands!");
721 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
724 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
725 assert(N == 1 && "Invalid number of operands!");
726 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
729 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
730 assert(N == 1 && "Invalid number of operands!");
731 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
734 /// Render the operand to an MCInst as a GPR64
735 /// Asserts if the wrong number of operands are requested, or the operand
736 /// is not a k_RegisterIndex compatible with RegKind_GPR
737 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
738 assert(N == 1 && "Invalid number of operands!");
739 Inst.addOperand(MCOperand::CreateReg(getGPR64Reg()));
742 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
743 assert(N == 1 && "Invalid number of operands!");
744 Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg()));
747 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
748 assert(N == 1 && "Invalid number of operands!");
749 Inst.addOperand(MCOperand::CreateReg(getFGR64Reg()));
752 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
753 assert(N == 1 && "Invalid number of operands!");
754 Inst.addOperand(MCOperand::CreateReg(getFGR32Reg()));
755 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
756 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
757 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
761 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
762 assert(N == 1 && "Invalid number of operands!");
763 Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg()));
766 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
767 assert(N == 1 && "Invalid number of operands!");
768 Inst.addOperand(MCOperand::CreateReg(getFCCReg()));
771 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
772 assert(N == 1 && "Invalid number of operands!");
773 Inst.addOperand(MCOperand::CreateReg(getMSA128Reg()));
776 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
777 assert(N == 1 && "Invalid number of operands!");
778 Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg()));
781 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
782 assert(N == 1 && "Invalid number of operands!");
783 Inst.addOperand(MCOperand::CreateReg(getCOP2Reg()));
786 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
787 assert(N == 1 && "Invalid number of operands!");
788 Inst.addOperand(MCOperand::CreateReg(getCOP3Reg()));
791 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
792 assert(N == 1 && "Invalid number of operands!");
793 Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg()));
796 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
797 assert(N == 1 && "Invalid number of operands!");
798 Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg()));
801 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
802 assert(N == 1 && "Invalid number of operands!");
803 Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg()));
806 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
807 assert(N == 1 && "Invalid number of operands!");
808 Inst.addOperand(MCOperand::CreateReg(getCCRReg()));
811 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
812 assert(N == 1 && "Invalid number of operands!");
813 Inst.addOperand(MCOperand::CreateReg(getHWRegsReg()));
816 void addImmOperands(MCInst &Inst, unsigned N) const {
817 assert(N == 1 && "Invalid number of operands!");
818 const MCExpr *Expr = getImm();
822 void addMemOperands(MCInst &Inst, unsigned N) const {
823 assert(N == 2 && "Invalid number of operands!");
825 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg()));
827 const MCExpr *Expr = getMemOff();
831 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
832 assert(N == 2 && "Invalid number of operands!");
834 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPRMM16Reg()));
836 const MCExpr *Expr = getMemOff();
840 void addRegListOperands(MCInst &Inst, unsigned N) const {
841 assert(N == 1 && "Invalid number of operands!");
843 for (auto RegNo : getRegList())
844 Inst.addOperand(MCOperand::CreateReg(RegNo));
847 void addRegPairOperands(MCInst &Inst, unsigned N) const {
848 assert(N == 2 && "Invalid number of operands!");
849 unsigned RegNo = getRegPair();
850 Inst.addOperand(MCOperand::CreateReg(RegNo++));
851 Inst.addOperand(MCOperand::CreateReg(RegNo));
854 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
855 assert(N == 2 && "Invalid number of operands!");
856 for (auto RegNo : getRegList())
857 Inst.addOperand(MCOperand::CreateReg(RegNo));
860 bool isReg() const override {
861 // As a special case until we sort out the definition of div/divu, pretend
862 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
863 if (isGPRAsmReg() && RegIdx.Index == 0)
866 return Kind == k_PhysRegister;
868 bool isRegIdx() const { return Kind == k_RegisterIndex; }
869 bool isImm() const override { return Kind == k_Immediate; }
870 bool isConstantImm() const {
871 return isImm() && dyn_cast<MCConstantExpr>(getImm());
873 bool isToken() const override {
874 // Note: It's not possible to pretend that other operand kinds are tokens.
875 // The matcher emitter checks tokens first.
876 return Kind == k_Token;
878 bool isMem() const override { return Kind == k_Memory; }
879 bool isConstantMemOff() const {
880 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
882 template <unsigned Bits> bool isMemWithSimmOffset() const {
883 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
885 bool isMemWithGRPMM16Base() const {
886 return isMem() && getMemBase()->isMM16AsmReg();
888 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
889 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
890 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
892 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
893 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
894 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
895 && (getMemBase()->getGPR32Reg() == Mips::SP);
897 bool isRegList16() const {
901 int Size = RegList.List->size();
902 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
903 RegList.List->back() != Mips::RA)
906 int PrevReg = *RegList.List->begin();
907 for (int i = 1; i < Size - 1; i++) {
908 int Reg = (*(RegList.List))[i];
909 if ( Reg != PrevReg + 1)
916 bool isInvNum() const { return Kind == k_Immediate; }
917 bool isLSAImm() const {
918 if (!isConstantImm())
920 int64_t Val = getConstantImm();
921 return 1 <= Val && Val <= 4;
923 bool isRegList() const { return Kind == k_RegList; }
924 bool isMovePRegPair() const {
925 if (Kind != k_RegList || RegList.List->size() != 2)
928 unsigned R0 = RegList.List->front();
929 unsigned R1 = RegList.List->back();
931 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
932 (R0 == Mips::A1 && R1 == Mips::A3) ||
933 (R0 == Mips::A2 && R1 == Mips::A3) ||
934 (R0 == Mips::A0 && R1 == Mips::S5) ||
935 (R0 == Mips::A0 && R1 == Mips::S6) ||
936 (R0 == Mips::A0 && R1 == Mips::A1) ||
937 (R0 == Mips::A0 && R1 == Mips::A2) ||
938 (R0 == Mips::A0 && R1 == Mips::A3))
944 StringRef getToken() const {
945 assert(Kind == k_Token && "Invalid access!");
946 return StringRef(Tok.Data, Tok.Length);
948 bool isRegPair() const { return Kind == k_RegPair; }
950 unsigned getReg() const override {
951 // As a special case until we sort out the definition of div/divu, pretend
952 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
953 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
954 RegIdx.Kind & RegKind_GPR)
955 return getGPR32Reg(); // FIXME: GPR64 too
957 assert(Kind == k_PhysRegister && "Invalid access!");
961 const MCExpr *getImm() const {
962 assert((Kind == k_Immediate) && "Invalid access!");
966 int64_t getConstantImm() const {
967 const MCExpr *Val = getImm();
968 return static_cast<const MCConstantExpr *>(Val)->getValue();
971 MipsOperand *getMemBase() const {
972 assert((Kind == k_Memory) && "Invalid access!");
976 const MCExpr *getMemOff() const {
977 assert((Kind == k_Memory) && "Invalid access!");
981 int64_t getConstantMemOff() const {
982 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
985 const SmallVectorImpl<unsigned> &getRegList() const {
986 assert((Kind == k_RegList) && "Invalid access!");
987 return *(RegList.List);
990 unsigned getRegPair() const {
991 assert((Kind == k_RegPair) && "Invalid access!");
995 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
996 MipsAsmParser &Parser) {
997 auto Op = make_unique<MipsOperand>(k_Token, Parser);
998 Op->Tok.Data = Str.data();
999 Op->Tok.Length = Str.size();
1005 /// Create a numeric register (e.g. $1). The exact register remains
1006 /// unresolved until an instruction successfully matches
1007 static std::unique_ptr<MipsOperand>
1008 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1009 SMLoc E, MipsAsmParser &Parser) {
1010 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1011 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1014 /// Create a register that is definitely a GPR.
1015 /// This is typically only used for named registers such as $gp.
1016 static std::unique_ptr<MipsOperand>
1017 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1018 MipsAsmParser &Parser) {
1019 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1022 /// Create a register that is definitely a FGR.
1023 /// This is typically only used for named registers such as $f0.
1024 static std::unique_ptr<MipsOperand>
1025 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1026 MipsAsmParser &Parser) {
1027 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1030 /// Create a register that is definitely a HWReg.
1031 /// This is typically only used for named registers such as $hwr_cpunum.
1032 static std::unique_ptr<MipsOperand>
1033 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1034 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1035 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1038 /// Create a register that is definitely an FCC.
1039 /// This is typically only used for named registers such as $fcc0.
1040 static std::unique_ptr<MipsOperand>
1041 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1042 MipsAsmParser &Parser) {
1043 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1046 /// Create a register that is definitely an ACC.
1047 /// This is typically only used for named registers such as $ac0.
1048 static std::unique_ptr<MipsOperand>
1049 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1050 MipsAsmParser &Parser) {
1051 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1054 /// Create a register that is definitely an MSA128.
1055 /// This is typically only used for named registers such as $w0.
1056 static std::unique_ptr<MipsOperand>
1057 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1058 SMLoc E, MipsAsmParser &Parser) {
1059 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1062 /// Create a register that is definitely an MSACtrl.
1063 /// This is typically only used for named registers such as $msaaccess.
1064 static std::unique_ptr<MipsOperand>
1065 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1066 SMLoc E, MipsAsmParser &Parser) {
1067 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1070 static std::unique_ptr<MipsOperand>
1071 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1072 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1079 static std::unique_ptr<MipsOperand>
1080 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1081 SMLoc E, MipsAsmParser &Parser) {
1082 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1083 Op->Mem.Base = Base.release();
1090 static std::unique_ptr<MipsOperand>
1091 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1092 MipsAsmParser &Parser) {
1093 assert (Regs.size() > 0 && "Empty list not allowed");
1095 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1096 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1097 Op->StartLoc = StartLoc;
1098 Op->EndLoc = EndLoc;
1102 static std::unique_ptr<MipsOperand>
1103 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1104 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1105 Op->RegIdx.Index = RegNo;
1111 bool isGPRAsmReg() const {
1112 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1114 bool isMM16AsmReg() const {
1115 if (!(isRegIdx() && RegIdx.Kind))
1117 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1118 || RegIdx.Index == 16 || RegIdx.Index == 17);
1120 bool isMM16AsmRegZero() const {
1121 if (!(isRegIdx() && RegIdx.Kind))
1123 return (RegIdx.Index == 0 ||
1124 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1125 RegIdx.Index == 17);
1127 bool isMM16AsmRegMoveP() const {
1128 if (!(isRegIdx() && RegIdx.Kind))
1130 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1131 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1133 bool isFGRAsmReg() const {
1134 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1135 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1137 bool isHWRegsAsmReg() const {
1138 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1140 bool isCCRAsmReg() const {
1141 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1143 bool isFCCAsmReg() const {
1144 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1146 if (!AsmParser.hasEightFccRegisters())
1147 return RegIdx.Index == 0;
1148 return RegIdx.Index <= 7;
1150 bool isACCAsmReg() const {
1151 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1153 bool isCOP2AsmReg() const {
1154 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1156 bool isCOP3AsmReg() const {
1157 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1159 bool isMSA128AsmReg() const {
1160 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1162 bool isMSACtrlAsmReg() const {
1163 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1166 /// getStartLoc - Get the location of the first token of this operand.
1167 SMLoc getStartLoc() const override { return StartLoc; }
1168 /// getEndLoc - Get the location of the last token of this operand.
1169 SMLoc getEndLoc() const override { return EndLoc; }
1171 virtual ~MipsOperand() {
1179 delete RegList.List;
1180 case k_PhysRegister:
1181 case k_RegisterIndex:
1188 void print(raw_ostream &OS) const override {
1197 Mem.Base->print(OS);
1202 case k_PhysRegister:
1203 OS << "PhysReg<" << PhysReg.Num << ">";
1205 case k_RegisterIndex:
1206 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1213 for (auto Reg : (*RegList.List))
1218 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1222 }; // class MipsOperand
1226 extern const MCInstrDesc MipsInsts[];
1228 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1229 return MipsInsts[Opcode];
1232 static bool hasShortDelaySlot(unsigned Opcode) {
1235 case Mips::JALRS_MM:
1236 case Mips::JALRS16_MM:
1237 case Mips::BGEZALS_MM:
1238 case Mips::BLTZALS_MM:
1245 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1246 SmallVectorImpl<MCInst> &Instructions) {
1247 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1251 if (MCID.isBranch() || MCID.isCall()) {
1252 const unsigned Opcode = Inst.getOpcode();
1262 assert(hasCnMips() && "instruction only valid for octeon cpus");
1269 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1270 Offset = Inst.getOperand(2);
1271 if (!Offset.isImm())
1272 break; // We'll deal with this situation later on when applying fixups.
1273 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1274 return Error(IDLoc, "branch target out of range");
1275 if (OffsetToAlignment(Offset.getImm(),
1276 1LL << (inMicroMipsMode() ? 1 : 2)))
1277 return Error(IDLoc, "branch to misaligned address");
1291 case Mips::BGEZAL_MM:
1292 case Mips::BLTZAL_MM:
1295 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1296 Offset = Inst.getOperand(1);
1297 if (!Offset.isImm())
1298 break; // We'll deal with this situation later on when applying fixups.
1299 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1300 return Error(IDLoc, "branch target out of range");
1301 if (OffsetToAlignment(Offset.getImm(),
1302 1LL << (inMicroMipsMode() ? 1 : 2)))
1303 return Error(IDLoc, "branch to misaligned address");
1305 case Mips::BEQZ16_MM:
1306 case Mips::BNEZ16_MM:
1307 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1308 Offset = Inst.getOperand(1);
1309 if (!Offset.isImm())
1310 break; // We'll deal with this situation later on when applying fixups.
1311 if (!isIntN(8, Offset.getImm()))
1312 return Error(IDLoc, "branch target out of range");
1313 if (OffsetToAlignment(Offset.getImm(), 2LL))
1314 return Error(IDLoc, "branch to misaligned address");
1319 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1320 // We still accept it but it is a normal nop.
1321 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1322 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1323 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1328 const unsigned Opcode = Inst.getOpcode();
1340 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1341 // The offset is handled above
1342 Opnd = Inst.getOperand(1);
1344 return Error(IDLoc, "expected immediate operand kind");
1345 Imm = Opnd.getImm();
1346 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1347 Opcode == Mips::BBIT1 ? 63 : 31))
1348 return Error(IDLoc, "immediate operand value out of range");
1350 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1352 Inst.getOperand(1).setImm(Imm - 32);
1360 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1362 Opnd = Inst.getOperand(3);
1364 return Error(IDLoc, "expected immediate operand kind");
1365 Imm = Opnd.getImm();
1366 if (Imm < 0 || Imm > 31)
1367 return Error(IDLoc, "immediate operand value out of range");
1369 Opnd = Inst.getOperand(2);
1371 return Error(IDLoc, "expected immediate operand kind");
1372 Imm = Opnd.getImm();
1373 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1374 Opcode == Mips::EXTS ? 63 : 31))
1375 return Error(IDLoc, "immediate operand value out of range");
1377 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1378 Inst.getOperand(2).setImm(Imm - 32);
1384 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1385 Opnd = Inst.getOperand(2);
1387 return Error(IDLoc, "expected immediate operand kind");
1388 Imm = Opnd.getImm();
1389 if (!isInt<10>(Imm))
1390 return Error(IDLoc, "immediate operand value out of range");
1395 if (MCID.mayLoad() || MCID.mayStore()) {
1396 // Check the offset of memory operand, if it is a symbol
1397 // reference or immediate we may have to expand instructions.
1398 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1399 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1400 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1401 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1402 MCOperand &Op = Inst.getOperand(i);
1404 int MemOffset = Op.getImm();
1405 if (MemOffset < -32768 || MemOffset > 32767) {
1406 // Offset can't exceed 16bit value.
1407 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1410 } else if (Op.isExpr()) {
1411 const MCExpr *Expr = Op.getExpr();
1412 if (Expr->getKind() == MCExpr::SymbolRef) {
1413 const MCSymbolRefExpr *SR =
1414 static_cast<const MCSymbolRefExpr *>(Expr);
1415 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1417 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1420 } else if (!isEvaluated(Expr)) {
1421 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1429 if (inMicroMipsMode()) {
1430 if (MCID.mayLoad()) {
1431 // Try to create 16-bit GP relative load instruction.
1432 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1433 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1434 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1435 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1436 MCOperand &Op = Inst.getOperand(i);
1438 int MemOffset = Op.getImm();
1439 MCOperand &DstReg = Inst.getOperand(0);
1440 MCOperand &BaseReg = Inst.getOperand(1);
1441 if (isIntN(9, MemOffset) && (MemOffset % 4 == 0) &&
1442 getContext().getRegisterInfo()->getRegClass(
1443 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1444 BaseReg.getReg() == Mips::GP) {
1446 TmpInst.setLoc(IDLoc);
1447 TmpInst.setOpcode(Mips::LWGP_MM);
1448 TmpInst.addOperand(MCOperand::CreateReg(DstReg.getReg()));
1449 TmpInst.addOperand(MCOperand::CreateReg(Mips::GP));
1450 TmpInst.addOperand(MCOperand::CreateImm(MemOffset));
1451 Instructions.push_back(TmpInst);
1459 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1464 switch (Inst.getOpcode()) {
1467 case Mips::ADDIUS5_MM:
1468 Opnd = Inst.getOperand(2);
1470 return Error(IDLoc, "expected immediate operand kind");
1471 Imm = Opnd.getImm();
1472 if (Imm < -8 || Imm > 7)
1473 return Error(IDLoc, "immediate operand value out of range");
1475 case Mips::ADDIUSP_MM:
1476 Opnd = Inst.getOperand(0);
1478 return Error(IDLoc, "expected immediate operand kind");
1479 Imm = Opnd.getImm();
1480 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1482 return Error(IDLoc, "immediate operand value out of range");
1484 case Mips::SLL16_MM:
1485 case Mips::SRL16_MM:
1486 Opnd = Inst.getOperand(2);
1488 return Error(IDLoc, "expected immediate operand kind");
1489 Imm = Opnd.getImm();
1490 if (Imm < 1 || Imm > 8)
1491 return Error(IDLoc, "immediate operand value out of range");
1494 Opnd = Inst.getOperand(1);
1496 return Error(IDLoc, "expected immediate operand kind");
1497 Imm = Opnd.getImm();
1498 if (Imm < -1 || Imm > 126)
1499 return Error(IDLoc, "immediate operand value out of range");
1501 case Mips::ADDIUR2_MM:
1502 Opnd = Inst.getOperand(2);
1504 return Error(IDLoc, "expected immediate operand kind");
1505 Imm = Opnd.getImm();
1506 if (!(Imm == 1 || Imm == -1 ||
1507 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1508 return Error(IDLoc, "immediate operand value out of range");
1510 case Mips::ADDIUR1SP_MM:
1511 Opnd = Inst.getOperand(1);
1513 return Error(IDLoc, "expected immediate operand kind");
1514 Imm = Opnd.getImm();
1515 if (OffsetToAlignment(Imm, 4LL))
1516 return Error(IDLoc, "misaligned immediate operand value");
1517 if (Imm < 0 || Imm > 255)
1518 return Error(IDLoc, "immediate operand value out of range");
1520 case Mips::ANDI16_MM:
1521 Opnd = Inst.getOperand(2);
1523 return Error(IDLoc, "expected immediate operand kind");
1524 Imm = Opnd.getImm();
1525 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1526 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1527 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1528 return Error(IDLoc, "immediate operand value out of range");
1530 case Mips::LBU16_MM:
1531 Opnd = Inst.getOperand(2);
1533 return Error(IDLoc, "expected immediate operand kind");
1534 Imm = Opnd.getImm();
1535 if (Imm < -1 || Imm > 14)
1536 return Error(IDLoc, "immediate operand value out of range");
1539 Opnd = Inst.getOperand(2);
1541 return Error(IDLoc, "expected immediate operand kind");
1542 Imm = Opnd.getImm();
1543 if (Imm < 0 || Imm > 15)
1544 return Error(IDLoc, "immediate operand value out of range");
1546 case Mips::LHU16_MM:
1548 Opnd = Inst.getOperand(2);
1550 return Error(IDLoc, "expected immediate operand kind");
1551 Imm = Opnd.getImm();
1552 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1553 return Error(IDLoc, "immediate operand value out of range");
1557 Opnd = Inst.getOperand(2);
1559 return Error(IDLoc, "expected immediate operand kind");
1560 Imm = Opnd.getImm();
1561 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1562 return Error(IDLoc, "immediate operand value out of range");
1566 Opnd = Inst.getOperand(2);
1568 return Error(IDLoc, "expected immediate operand kind");
1569 Imm = Opnd.getImm();
1570 if (!isUInt<5>(Imm))
1571 return Error(IDLoc, "immediate operand value out of range");
1573 case Mips::ADDIUPC_MM:
1574 MCOperand Opnd = Inst.getOperand(1);
1576 return Error(IDLoc, "expected immediate operand kind");
1577 int Imm = Opnd.getImm();
1578 if ((Imm % 4 != 0) || !isIntN(25, Imm))
1579 return Error(IDLoc, "immediate operand value out of range");
1584 if (needsExpansion(Inst)) {
1585 if (expandInstruction(Inst, IDLoc, Instructions))
1588 Instructions.push_back(Inst);
1590 // If this instruction has a delay slot and .set reorder is active,
1591 // emit a NOP after it.
1592 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1593 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1598 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1600 switch (Inst.getOpcode()) {
1601 case Mips::LoadImm32:
1602 case Mips::LoadImm64:
1603 case Mips::LoadAddrImm32:
1604 case Mips::LoadAddrReg32:
1605 case Mips::B_MM_Pseudo:
1608 case Mips::JalOneReg:
1609 case Mips::JalTwoReg:
1616 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1617 SmallVectorImpl<MCInst> &Instructions) {
1618 switch (Inst.getOpcode()) {
1619 default: llvm_unreachable("unimplemented expansion");
1620 case Mips::LoadImm32:
1621 return expandLoadImm(Inst, true, IDLoc, Instructions);
1622 case Mips::LoadImm64:
1623 return expandLoadImm(Inst, false, IDLoc, Instructions);
1624 case Mips::LoadAddrImm32:
1625 return expandLoadAddressImm(Inst, true, IDLoc, Instructions);
1626 case Mips::LoadAddrReg32:
1627 return expandLoadAddressReg(Inst, true, IDLoc, Instructions);
1628 case Mips::B_MM_Pseudo:
1629 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1632 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
1633 case Mips::JalOneReg:
1634 case Mips::JalTwoReg:
1635 return expandJalWithRegs(Inst, IDLoc, Instructions);
1640 template <unsigned ShiftAmount>
1641 void createLShiftOri(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1642 SmallVectorImpl<MCInst> &Instructions) {
1644 if (ShiftAmount >= 32) {
1645 tmpInst.setOpcode(Mips::DSLL32);
1646 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1647 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1648 tmpInst.addOperand(MCOperand::CreateImm(ShiftAmount - 32));
1649 tmpInst.setLoc(IDLoc);
1650 Instructions.push_back(tmpInst);
1652 } else if (ShiftAmount > 0) {
1653 tmpInst.setOpcode(Mips::DSLL);
1654 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1655 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1656 tmpInst.addOperand(MCOperand::CreateImm(ShiftAmount));
1657 tmpInst.setLoc(IDLoc);
1658 Instructions.push_back(tmpInst);
1661 // There's no need for an ORi if the immediate is 0.
1662 if (Operand.isImm() && Operand.getImm() == 0)
1665 tmpInst.setOpcode(Mips::ORi);
1666 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1667 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1668 tmpInst.addOperand(Operand);
1669 tmpInst.setLoc(IDLoc);
1670 Instructions.push_back(tmpInst);
1673 template <unsigned ShiftAmount>
1674 void createLShiftOri(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1675 SmallVectorImpl<MCInst> &Instructions) {
1676 createLShiftOri<ShiftAmount>(MCOperand::CreateImm(Value), RegNo, IDLoc,
1681 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
1682 SmallVectorImpl<MCInst> &Instructions) {
1683 // Create a JALR instruction which is going to replace the pseudo-JAL.
1685 JalrInst.setLoc(IDLoc);
1686 const MCOperand FirstRegOp = Inst.getOperand(0);
1687 const unsigned Opcode = Inst.getOpcode();
1689 if (Opcode == Mips::JalOneReg) {
1690 // jal $rs => jalr $rs
1691 if (inMicroMipsMode()) {
1692 JalrInst.setOpcode(Mips::JALR16_MM);
1693 JalrInst.addOperand(FirstRegOp);
1695 JalrInst.setOpcode(Mips::JALR);
1696 JalrInst.addOperand(MCOperand::CreateReg(Mips::RA));
1697 JalrInst.addOperand(FirstRegOp);
1699 } else if (Opcode == Mips::JalTwoReg) {
1700 // jal $rd, $rs => jalr $rd, $rs
1701 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1702 JalrInst.addOperand(FirstRegOp);
1703 const MCOperand SecondRegOp = Inst.getOperand(1);
1704 JalrInst.addOperand(SecondRegOp);
1706 Instructions.push_back(JalrInst);
1708 // If .set reorder is active, emit a NOP after it.
1709 if (AssemblerOptions.back()->isReorder()) {
1710 // This is a 32-bit NOP because these 2 pseudo-instructions
1711 // do not have a short delay slot.
1713 NopInst.setOpcode(Mips::SLL);
1714 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1715 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1716 NopInst.addOperand(MCOperand::CreateImm(0));
1717 Instructions.push_back(NopInst);
1723 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
1724 unsigned SrcReg, bool Is32BitImm, SMLoc IDLoc,
1725 SmallVectorImpl<MCInst> &Instructions) {
1726 if (!Is32BitImm && !isGP64bit()) {
1727 Error(IDLoc, "instruction requires a 64-bit architecture");
1731 bool UseSrcReg = false;
1732 if (SrcReg != Mips::NoRegister)
1737 tmpInst.setLoc(IDLoc);
1738 // FIXME: gas has a special case for values that are 000...1111, which
1739 // becomes a li -1 and then a dsrl
1740 if (0 <= ImmValue && ImmValue <= 65535) {
1741 // For unsigned and positive signed 16-bit values (0 <= j <= 65535):
1742 // li d,j => ori d,$zero,j
1744 SrcReg = isGP64bit() ? Mips::ZERO_64 : Mips::ZERO;
1745 tmpInst.setOpcode(Mips::ORi);
1746 tmpInst.addOperand(MCOperand::CreateReg(DstReg));
1747 tmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1748 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1749 Instructions.push_back(tmpInst);
1750 } else if (ImmValue < 0 && ImmValue >= -32768) {
1751 // For negative signed 16-bit values (-32768 <= j < 0):
1752 // li d,j => addiu d,$zero,j
1754 SrcReg = Mips::ZERO;
1755 tmpInst.setOpcode(Mips::ADDiu);
1756 tmpInst.addOperand(MCOperand::CreateReg(DstReg));
1757 tmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1758 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1759 Instructions.push_back(tmpInst);
1760 } else if ((ImmValue & 0xffffffff) == ImmValue) {
1761 // For all other values which are representable as a 32-bit integer:
1762 // li d,j => lui d,hi16(j)
1764 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1765 uint16_t Bits15To0 = ImmValue & 0xffff;
1767 tmpInst.setOpcode(Mips::LUi);
1768 tmpInst.addOperand(MCOperand::CreateReg(DstReg));
1769 tmpInst.addOperand(MCOperand::CreateImm(Bits31To16));
1770 Instructions.push_back(tmpInst);
1771 createLShiftOri<0>(Bits15To0, DstReg, IDLoc, Instructions);
1774 createAddu(DstReg, DstReg, SrcReg, Instructions);
1776 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1778 Error(IDLoc, "instruction requires a 32-bit immediate");
1782 // <------- lo32 ------>
1783 // <------- hi32 ------>
1784 // <- hi16 -> <- lo16 ->
1785 // _________________________________
1787 // | 16-bits | 16-bits | 16-bits |
1788 // |__________|__________|__________|
1790 // For any 64-bit value that is representable as a 48-bit integer:
1791 // li d,j => lui d,hi16(j)
1792 // ori d,d,hi16(lo32(j))
1794 // ori d,d,lo16(lo32(j))
1795 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1796 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1797 uint16_t Bits15To0 = ImmValue & 0xffff;
1799 tmpInst.setOpcode(Mips::LUi);
1800 tmpInst.addOperand(MCOperand::CreateReg(DstReg));
1801 tmpInst.addOperand(MCOperand::CreateImm(Bits47To32));
1802 Instructions.push_back(tmpInst);
1803 createLShiftOri<0>(Bits31To16, DstReg, IDLoc, Instructions);
1804 createLShiftOri<16>(Bits15To0, DstReg, IDLoc, Instructions);
1807 createAddu(DstReg, DstReg, SrcReg, Instructions);
1811 Error(IDLoc, "instruction requires a 32-bit immediate");
1815 // <------- hi32 ------> <------- lo32 ------>
1816 // <- hi16 -> <- lo16 ->
1817 // ___________________________________________
1819 // | 16-bits | 16-bits | 16-bits | 16-bits |
1820 // |__________|__________|__________|__________|
1822 // For all other values which are representable as a 64-bit integer:
1823 // li d,j => lui d,hi16(j)
1824 // ori d,d,lo16(hi32(j))
1826 // ori d,d,hi16(lo32(j))
1828 // ori d,d,lo16(lo32(j))
1829 uint16_t Bits63To48 = (ImmValue >> 48) & 0xffff;
1830 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1831 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1832 uint16_t Bits15To0 = ImmValue & 0xffff;
1834 tmpInst.setOpcode(Mips::LUi);
1835 tmpInst.addOperand(MCOperand::CreateReg(DstReg));
1836 tmpInst.addOperand(MCOperand::CreateImm(Bits63To48));
1837 Instructions.push_back(tmpInst);
1838 createLShiftOri<0>(Bits47To32, DstReg, IDLoc, Instructions);
1840 // When Bits31To16 is 0, do a left shift of 32 bits instead of doing
1841 // two left shifts of 16 bits.
1842 if (Bits31To16 == 0) {
1843 createLShiftOri<32>(Bits15To0, DstReg, IDLoc, Instructions);
1845 createLShiftOri<16>(Bits31To16, DstReg, IDLoc, Instructions);
1846 createLShiftOri<16>(Bits15To0, DstReg, IDLoc, Instructions);
1850 createAddu(DstReg, DstReg, SrcReg, Instructions);
1855 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1856 SmallVectorImpl<MCInst> &Instructions) {
1857 const MCOperand &ImmOp = Inst.getOperand(1);
1858 assert(ImmOp.isImm() && "expected immediate operand kind");
1859 const MCOperand &DstRegOp = Inst.getOperand(0);
1860 assert(DstRegOp.isReg() && "expected register operand kind");
1862 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
1863 Is32BitImm, IDLoc, Instructions))
1870 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1871 SmallVectorImpl<MCInst> &Instructions) {
1872 const MCOperand &ImmOp = Inst.getOperand(2);
1873 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1874 "expected immediate operand kind");
1875 if (!ImmOp.isImm()) {
1876 expandLoadAddressSym(Inst, IDLoc, Instructions);
1879 const MCOperand &SrcRegOp = Inst.getOperand(1);
1880 assert(SrcRegOp.isReg() && "expected register operand kind");
1881 const MCOperand &DstRegOp = Inst.getOperand(0);
1882 assert(DstRegOp.isReg() && "expected register operand kind");
1884 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), SrcRegOp.getReg(),
1885 Is32BitImm, IDLoc, Instructions))
1892 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1893 SmallVectorImpl<MCInst> &Instructions) {
1894 const MCOperand &ImmOp = Inst.getOperand(1);
1895 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1896 "expected immediate operand kind");
1897 if (!ImmOp.isImm()) {
1898 expandLoadAddressSym(Inst, IDLoc, Instructions);
1901 const MCOperand &DstRegOp = Inst.getOperand(0);
1902 assert(DstRegOp.isReg() && "expected register operand kind");
1904 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
1905 Is32BitImm, IDLoc, Instructions))
1912 MipsAsmParser::expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
1913 SmallVectorImpl<MCInst> &Instructions) {
1914 // FIXME: If we do have a valid at register to use, we should generate a
1915 // slightly shorter sequence here.
1917 int ExprOperandNo = 1;
1918 // Sometimes the assembly parser will get the immediate expression as
1919 // a $zero + an immediate.
1920 if (Inst.getNumOperands() == 3) {
1921 assert(Inst.getOperand(1).getReg() ==
1922 (isGP64bit() ? Mips::ZERO_64 : Mips::ZERO));
1925 const MCOperand &SymOp = Inst.getOperand(ExprOperandNo);
1926 assert(SymOp.isExpr() && "expected symbol operand kind");
1927 const MCOperand &RegOp = Inst.getOperand(0);
1928 unsigned RegNo = RegOp.getReg();
1929 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
1930 const MCSymbolRefExpr *HiExpr =
1931 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1932 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1933 const MCSymbolRefExpr *LoExpr =
1934 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1935 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1937 // If it's a 64-bit architecture, expand to:
1938 // la d,sym => lui d,highest(sym)
1939 // ori d,d,higher(sym)
1941 // ori d,d,hi16(sym)
1943 // ori d,d,lo16(sym)
1944 const MCSymbolRefExpr *HighestExpr =
1945 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1946 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1947 const MCSymbolRefExpr *HigherExpr =
1948 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1949 MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1951 tmpInst.setOpcode(Mips::LUi);
1952 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1953 tmpInst.addOperand(MCOperand::CreateExpr(HighestExpr));
1954 Instructions.push_back(tmpInst);
1956 createLShiftOri<0>(MCOperand::CreateExpr(HigherExpr), RegNo, SMLoc(),
1958 createLShiftOri<16>(MCOperand::CreateExpr(HiExpr), RegNo, SMLoc(),
1960 createLShiftOri<16>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1963 // Otherwise, expand to:
1964 // la d,sym => lui d,hi16(sym)
1965 // ori d,d,lo16(sym)
1966 tmpInst.setOpcode(Mips::LUi);
1967 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1968 tmpInst.addOperand(MCOperand::CreateExpr(HiExpr));
1969 Instructions.push_back(tmpInst);
1971 createLShiftOri<0>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1976 bool MipsAsmParser::expandUncondBranchMMPseudo(
1977 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1978 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
1979 "unexpected number of operands");
1981 MCOperand Offset = Inst.getOperand(0);
1982 if (Offset.isExpr()) {
1984 Inst.setOpcode(Mips::BEQ_MM);
1985 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1986 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1987 Inst.addOperand(MCOperand::CreateExpr(Offset.getExpr()));
1989 assert(Offset.isImm() && "expected immediate operand kind");
1990 if (isIntN(11, Offset.getImm())) {
1991 // If offset fits into 11 bits then this instruction becomes microMIPS
1992 // 16-bit unconditional branch instruction.
1993 Inst.setOpcode(Mips::B16_MM);
1995 if (!isIntN(17, Offset.getImm()))
1996 Error(IDLoc, "branch target out of range");
1997 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
1998 Error(IDLoc, "branch to misaligned address");
2000 Inst.setOpcode(Mips::BEQ_MM);
2001 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2002 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2003 Inst.addOperand(MCOperand::CreateImm(Offset.getImm()));
2006 Instructions.push_back(Inst);
2008 // If .set reorder is active, emit a NOP after the branch instruction.
2009 if (AssemblerOptions.back()->isReorder())
2010 createNop(true, IDLoc, Instructions);
2015 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2016 SmallVectorImpl<MCInst> &Instructions,
2017 bool isLoad, bool isImmOpnd) {
2018 const MCSymbolRefExpr *SR;
2020 unsigned ImmOffset, HiOffset, LoOffset;
2021 const MCExpr *ExprOffset;
2023 // 1st operand is either the source or destination register.
2024 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2025 unsigned RegOpNum = Inst.getOperand(0).getReg();
2026 // 2nd operand is the base register.
2027 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2028 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2029 // 3rd operand is either an immediate or expression.
2031 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2032 ImmOffset = Inst.getOperand(2).getImm();
2033 LoOffset = ImmOffset & 0x0000ffff;
2034 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2035 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2036 if (LoOffset & 0x8000)
2039 ExprOffset = Inst.getOperand(2).getExpr();
2040 // All instructions will have the same location.
2041 TempInst.setLoc(IDLoc);
2042 // These are some of the types of expansions we perform here:
2043 // 1) lw $8, sym => lui $8, %hi(sym)
2044 // lw $8, %lo(sym)($8)
2045 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2047 // lw $8, %lo(offset)($9)
2048 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2050 // lw $8, %lo(offset)($at)
2051 // 4) sw $8, sym => lui $at, %hi(sym)
2052 // sw $8, %lo(sym)($at)
2053 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2055 // sw $8, %lo(offset)($at)
2056 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2057 // ldc1 $f0, %lo(sym)($at)
2059 // For load instructions we can use the destination register as a temporary
2060 // if base and dst are different (examples 1 and 2) and if the base register
2061 // is general purpose otherwise we must use $at (example 6) and error if it's
2062 // not available. For stores we must use $at (examples 4 and 5) because we
2063 // must not clobber the source register setting up the offset.
2064 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2065 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2066 unsigned RegClassIDOp0 =
2067 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2068 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2069 (RegClassIDOp0 == Mips::GPR64RegClassID);
2070 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2071 TmpRegNum = RegOpNum;
2073 // At this point we need AT to perform the expansions and we exit if it is
2075 TmpRegNum = getATReg(IDLoc);
2080 TempInst.setOpcode(Mips::LUi);
2081 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2083 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
2085 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2086 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
2087 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
2088 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
2090 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
2092 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2093 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
2096 // Add the instruction to the list.
2097 Instructions.push_back(TempInst);
2098 // Prepare TempInst for next instruction.
2100 // Add temp register to base.
2101 if (BaseRegNum != Mips::ZERO) {
2102 TempInst.setOpcode(Mips::ADDu);
2103 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2104 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2105 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
2106 Instructions.push_back(TempInst);
2109 // And finally, create original instruction with low part
2110 // of offset and new base.
2111 TempInst.setOpcode(Inst.getOpcode());
2112 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
2113 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2115 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
2117 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2118 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
2119 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
2121 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
2123 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2124 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
2127 Instructions.push_back(TempInst);
2132 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2133 SmallVectorImpl<MCInst> &Instructions) {
2134 unsigned OpNum = Inst.getNumOperands();
2135 unsigned Opcode = Inst.getOpcode();
2136 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2138 assert (Inst.getOperand(OpNum - 1).isImm() &&
2139 Inst.getOperand(OpNum - 2).isReg() &&
2140 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2142 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2143 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2144 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2145 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2146 // It can be implemented as SWM16 or LWM16 instruction.
2147 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2149 Inst.setOpcode(NewOpcode);
2150 Instructions.push_back(Inst);
2154 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
2155 SmallVectorImpl<MCInst> &Instructions) {
2157 if (hasShortDelaySlot) {
2158 NopInst.setOpcode(Mips::MOVE16_MM);
2159 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2160 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2162 NopInst.setOpcode(Mips::SLL);
2163 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2164 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2165 NopInst.addOperand(MCOperand::CreateImm(0));
2167 Instructions.push_back(NopInst);
2170 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
2172 SmallVectorImpl<MCInst> &Instructions) {
2174 AdduInst.setOpcode(Mips::ADDu);
2175 AdduInst.addOperand(MCOperand::CreateReg(DstReg));
2176 AdduInst.addOperand(MCOperand::CreateReg(SrcReg));
2177 AdduInst.addOperand(MCOperand::CreateReg(TrgReg));
2178 Instructions.push_back(AdduInst);
2181 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
2182 // As described by the Mips32r2 spec, the registers Rd and Rs for
2183 // jalr.hb must be different.
2184 unsigned Opcode = Inst.getOpcode();
2186 if (Opcode == Mips::JALR_HB &&
2187 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
2188 return Match_RequiresDifferentSrcAndDst;
2190 return Match_Success;
2193 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2194 OperandVector &Operands,
2196 uint64_t &ErrorInfo,
2197 bool MatchingInlineAsm) {
2200 SmallVector<MCInst, 8> Instructions;
2201 unsigned MatchResult =
2202 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
2204 switch (MatchResult) {
2205 case Match_Success: {
2206 if (processInstruction(Inst, IDLoc, Instructions))
2208 for (unsigned i = 0; i < Instructions.size(); i++)
2209 Out.EmitInstruction(Instructions[i], STI);
2212 case Match_MissingFeature:
2213 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2215 case Match_InvalidOperand: {
2216 SMLoc ErrorLoc = IDLoc;
2217 if (ErrorInfo != ~0ULL) {
2218 if (ErrorInfo >= Operands.size())
2219 return Error(IDLoc, "too few operands for instruction");
2221 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
2222 if (ErrorLoc == SMLoc())
2226 return Error(ErrorLoc, "invalid operand for instruction");
2228 case Match_MnemonicFail:
2229 return Error(IDLoc, "invalid instruction");
2230 case Match_RequiresDifferentSrcAndDst:
2231 return Error(IDLoc, "source and destination must be different");
2234 llvm_unreachable("Implement any new match types added!");
2237 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
2238 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
2239 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
2240 ") without \".set noat\"");
2244 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
2245 SMRange Range, bool ShowColors) {
2246 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
2247 Range, SMFixIt(Range, FixMsg),
2251 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
2254 CC = StringSwitch<unsigned>(Name)
2290 if (!(isABI_N32() || isABI_N64()))
2293 if (12 <= CC && CC <= 15) {
2294 // Name is one of t4-t7
2295 AsmToken RegTok = getLexer().peekTok();
2296 SMRange RegRange = RegTok.getLocRange();
2298 StringRef FixedName = StringSwitch<StringRef>(Name)
2304 assert(FixedName != "" && "Register name is not one of t4-t7.");
2306 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
2307 "Did you mean $" + FixedName + "?", RegRange);
2310 // Although SGI documentation just cuts out t0-t3 for n32/n64,
2311 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
2312 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
2313 if (8 <= CC && CC <= 11)
2317 CC = StringSwitch<unsigned>(Name)
2329 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
2332 CC = StringSwitch<unsigned>(Name)
2333 .Case("hwr_cpunum", 0)
2334 .Case("hwr_synci_step", 1)
2336 .Case("hwr_ccres", 3)
2337 .Case("hwr_ulr", 29)
2343 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2345 if (Name[0] == 'f') {
2346 StringRef NumString = Name.substr(1);
2348 if (NumString.getAsInteger(10, IntVal))
2349 return -1; // This is not an integer.
2350 if (IntVal > 31) // Maximum index for fpu register.
2357 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2359 if (Name.startswith("fcc")) {
2360 StringRef NumString = Name.substr(3);
2362 if (NumString.getAsInteger(10, IntVal))
2363 return -1; // This is not an integer.
2364 if (IntVal > 7) // There are only 8 fcc registers.
2371 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2373 if (Name.startswith("ac")) {
2374 StringRef NumString = Name.substr(2);
2376 if (NumString.getAsInteger(10, IntVal))
2377 return -1; // This is not an integer.
2378 if (IntVal > 3) // There are only 3 acc registers.
2385 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2388 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
2397 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
2400 CC = StringSwitch<unsigned>(Name)
2403 .Case("msaaccess", 2)
2405 .Case("msamodify", 4)
2406 .Case("msarequest", 5)
2408 .Case("msaunmap", 7)
2414 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
2415 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
2417 reportParseError(Loc,
2418 "pseudo-instruction requires $at, which is not available");
2421 unsigned AT = getReg(
2422 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
2426 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2427 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2430 unsigned MipsAsmParser::getGPR(int RegNo) {
2431 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2435 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2437 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2440 return getReg(RegClass, RegNum);
2443 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2444 MCAsmParser &Parser = getParser();
2445 DEBUG(dbgs() << "parseOperand\n");
2447 // Check if the current operand has a custom associated parser, if so, try to
2448 // custom parse the operand, or fallback to the general approach.
2449 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2450 if (ResTy == MatchOperand_Success)
2452 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2453 // there was a match, but an error occurred, in which case, just return that
2454 // the operand parsing failed.
2455 if (ResTy == MatchOperand_ParseFail)
2458 DEBUG(dbgs() << ".. Generic Parser\n");
2460 switch (getLexer().getKind()) {
2462 Error(Parser.getTok().getLoc(), "unexpected token in operand");
2464 case AsmToken::Dollar: {
2465 // Parse the register.
2466 SMLoc S = Parser.getTok().getLoc();
2468 // Almost all registers have been parsed by custom parsers. There is only
2469 // one exception to this. $zero (and it's alias $0) will reach this point
2470 // for div, divu, and similar instructions because it is not an operand
2471 // to the instruction definition but an explicit register. Special case
2472 // this situation for now.
2473 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
2476 // Maybe it is a symbol reference.
2477 StringRef Identifier;
2478 if (Parser.parseIdentifier(Identifier))
2481 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2482 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
2483 // Otherwise create a symbol reference.
2485 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
2487 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
2490 // Else drop to expression parsing.
2491 case AsmToken::LParen:
2492 case AsmToken::Minus:
2493 case AsmToken::Plus:
2494 case AsmToken::Integer:
2495 case AsmToken::Tilde:
2496 case AsmToken::String: {
2497 DEBUG(dbgs() << ".. generic integer\n");
2498 OperandMatchResultTy ResTy = parseImm(Operands);
2499 return ResTy != MatchOperand_Success;
2501 case AsmToken::Percent: {
2502 // It is a symbol reference or constant expression.
2503 const MCExpr *IdVal;
2504 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
2505 if (parseRelocOperand(IdVal))
2508 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2510 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2512 } // case AsmToken::Percent
2513 } // switch(getLexer().getKind())
2517 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
2518 StringRef RelocStr) {
2520 // Check the type of the expression.
2521 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
2522 // It's a constant, evaluate reloc value.
2524 switch (getVariantKind(RelocStr)) {
2525 case MCSymbolRefExpr::VK_Mips_ABS_LO:
2526 // Get the 1st 16-bits.
2527 Val = MCE->getValue() & 0xffff;
2529 case MCSymbolRefExpr::VK_Mips_ABS_HI:
2530 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
2531 // 16 bits being negative.
2532 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
2534 case MCSymbolRefExpr::VK_Mips_HIGHER:
2535 // Get the 3rd 16-bits.
2536 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
2538 case MCSymbolRefExpr::VK_Mips_HIGHEST:
2539 // Get the 4th 16-bits.
2540 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
2543 report_fatal_error("unsupported reloc value");
2545 return MCConstantExpr::Create(Val, getContext());
2548 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
2549 // It's a symbol, create a symbolic expression from the symbol.
2550 StringRef Symbol = MSRE->getSymbol().getName();
2551 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2552 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
2556 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2557 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2559 // Try to create target expression.
2560 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
2561 return MipsMCExpr::Create(VK, Expr, getContext());
2563 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
2564 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
2565 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
2569 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
2570 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
2571 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
2574 // Just return the original expression.
2578 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
2580 switch (Expr->getKind()) {
2581 case MCExpr::Constant:
2583 case MCExpr::SymbolRef:
2584 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
2585 case MCExpr::Binary:
2586 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2587 if (!isEvaluated(BE->getLHS()))
2589 return isEvaluated(BE->getRHS());
2592 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
2593 case MCExpr::Target:
2599 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
2600 MCAsmParser &Parser = getParser();
2601 Parser.Lex(); // Eat the % token.
2602 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
2603 if (Tok.isNot(AsmToken::Identifier))
2606 std::string Str = Tok.getIdentifier();
2608 Parser.Lex(); // Eat the identifier.
2609 // Now make an expression from the rest of the operand.
2610 const MCExpr *IdVal;
2613 if (getLexer().getKind() == AsmToken::LParen) {
2615 Parser.Lex(); // Eat the '(' token.
2616 if (getLexer().getKind() == AsmToken::Percent) {
2617 Parser.Lex(); // Eat the % token.
2618 const AsmToken &nextTok = Parser.getTok();
2619 if (nextTok.isNot(AsmToken::Identifier))
2622 Str += nextTok.getIdentifier();
2623 Parser.Lex(); // Eat the identifier.
2624 if (getLexer().getKind() != AsmToken::LParen)
2629 if (getParser().parseParenExpression(IdVal, EndLoc))
2632 while (getLexer().getKind() == AsmToken::RParen)
2633 Parser.Lex(); // Eat the ')' token.
2636 return true; // Parenthesis must follow the relocation operand.
2638 Res = evaluateRelocExpr(IdVal, Str);
2642 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2644 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2645 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2646 if (ResTy == MatchOperand_Success) {
2647 assert(Operands.size() == 1);
2648 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2649 StartLoc = Operand.getStartLoc();
2650 EndLoc = Operand.getEndLoc();
2652 // AFAIK, we only support numeric registers and named GPR's in CFI
2654 // Don't worry about eating tokens before failing. Using an unrecognised
2655 // register is a parse error.
2656 if (Operand.isGPRAsmReg()) {
2657 // Resolve to GPR32 or GPR64 appropriately.
2658 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2661 return (RegNo == (unsigned)-1);
2664 assert(Operands.size() == 0);
2665 return (RegNo == (unsigned)-1);
2668 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2669 MCAsmParser &Parser = getParser();
2673 while (getLexer().getKind() == AsmToken::LParen)
2676 switch (getLexer().getKind()) {
2679 case AsmToken::Identifier:
2680 case AsmToken::LParen:
2681 case AsmToken::Integer:
2682 case AsmToken::Minus:
2683 case AsmToken::Plus:
2685 Result = getParser().parseParenExpression(Res, S);
2687 Result = (getParser().parseExpression(Res));
2688 while (getLexer().getKind() == AsmToken::RParen)
2691 case AsmToken::Percent:
2692 Result = parseRelocOperand(Res);
2697 MipsAsmParser::OperandMatchResultTy
2698 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
2699 MCAsmParser &Parser = getParser();
2700 DEBUG(dbgs() << "parseMemOperand\n");
2701 const MCExpr *IdVal = nullptr;
2703 bool isParenExpr = false;
2704 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
2705 // First operand is the offset.
2706 S = Parser.getTok().getLoc();
2708 if (getLexer().getKind() == AsmToken::LParen) {
2713 if (getLexer().getKind() != AsmToken::Dollar) {
2714 if (parseMemOffset(IdVal, isParenExpr))
2715 return MatchOperand_ParseFail;
2717 const AsmToken &Tok = Parser.getTok(); // Get the next token.
2718 if (Tok.isNot(AsmToken::LParen)) {
2719 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2720 if (Mnemonic.getToken() == "la") {
2722 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2723 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2724 return MatchOperand_Success;
2726 if (Tok.is(AsmToken::EndOfStatement)) {
2728 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2730 // Zero register assumed, add a memory operand with ZERO as its base.
2731 // "Base" will be managed by k_Memory.
2732 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
2735 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2736 return MatchOperand_Success;
2738 Error(Parser.getTok().getLoc(), "'(' expected");
2739 return MatchOperand_ParseFail;
2742 Parser.Lex(); // Eat the '(' token.
2745 Res = parseAnyRegister(Operands);
2746 if (Res != MatchOperand_Success)
2749 if (Parser.getTok().isNot(AsmToken::RParen)) {
2750 Error(Parser.getTok().getLoc(), "')' expected");
2751 return MatchOperand_ParseFail;
2754 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2756 Parser.Lex(); // Eat the ')' token.
2759 IdVal = MCConstantExpr::Create(0, getContext());
2761 // Replace the register operand with the memory operand.
2762 std::unique_ptr<MipsOperand> op(
2763 static_cast<MipsOperand *>(Operands.back().release()));
2764 // Remove the register from the operands.
2765 // "op" will be managed by k_Memory.
2766 Operands.pop_back();
2767 // Add the memory operand.
2768 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2770 if (IdVal->EvaluateAsAbsolute(Imm))
2771 IdVal = MCConstantExpr::Create(Imm, getContext());
2772 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2773 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2777 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2778 return MatchOperand_Success;
2781 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2782 MCAsmParser &Parser = getParser();
2783 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2785 SMLoc S = Parser.getTok().getLoc();
2787 if (Sym->isVariable())
2788 Expr = Sym->getVariableValue();
2791 if (Expr->getKind() == MCExpr::SymbolRef) {
2792 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2793 StringRef DefSymbol = Ref->getSymbol().getName();
2794 if (DefSymbol.startswith("$")) {
2795 OperandMatchResultTy ResTy =
2796 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2797 if (ResTy == MatchOperand_Success) {
2800 } else if (ResTy == MatchOperand_ParseFail)
2801 llvm_unreachable("Should never ParseFail");
2804 } else if (Expr->getKind() == MCExpr::Constant) {
2806 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2808 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2815 MipsAsmParser::OperandMatchResultTy
2816 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2817 StringRef Identifier,
2819 int Index = matchCPURegisterName(Identifier);
2821 Operands.push_back(MipsOperand::createGPRReg(
2822 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2823 return MatchOperand_Success;
2826 Index = matchHWRegsRegisterName(Identifier);
2828 Operands.push_back(MipsOperand::createHWRegsReg(
2829 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2830 return MatchOperand_Success;
2833 Index = matchFPURegisterName(Identifier);
2835 Operands.push_back(MipsOperand::createFGRReg(
2836 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2837 return MatchOperand_Success;
2840 Index = matchFCCRegisterName(Identifier);
2842 Operands.push_back(MipsOperand::createFCCReg(
2843 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2844 return MatchOperand_Success;
2847 Index = matchACRegisterName(Identifier);
2849 Operands.push_back(MipsOperand::createACCReg(
2850 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2851 return MatchOperand_Success;
2854 Index = matchMSA128RegisterName(Identifier);
2856 Operands.push_back(MipsOperand::createMSA128Reg(
2857 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2858 return MatchOperand_Success;
2861 Index = matchMSA128CtrlRegisterName(Identifier);
2863 Operands.push_back(MipsOperand::createMSACtrlReg(
2864 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2865 return MatchOperand_Success;
2868 return MatchOperand_NoMatch;
2871 MipsAsmParser::OperandMatchResultTy
2872 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2873 MCAsmParser &Parser = getParser();
2874 auto Token = Parser.getLexer().peekTok(false);
2876 if (Token.is(AsmToken::Identifier)) {
2877 DEBUG(dbgs() << ".. identifier\n");
2878 StringRef Identifier = Token.getIdentifier();
2879 OperandMatchResultTy ResTy =
2880 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2882 } else if (Token.is(AsmToken::Integer)) {
2883 DEBUG(dbgs() << ".. integer\n");
2884 Operands.push_back(MipsOperand::createNumericReg(
2885 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2887 return MatchOperand_Success;
2890 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2892 return MatchOperand_NoMatch;
2895 MipsAsmParser::OperandMatchResultTy
2896 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
2897 MCAsmParser &Parser = getParser();
2898 DEBUG(dbgs() << "parseAnyRegister\n");
2900 auto Token = Parser.getTok();
2902 SMLoc S = Token.getLoc();
2904 if (Token.isNot(AsmToken::Dollar)) {
2905 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2906 if (Token.is(AsmToken::Identifier)) {
2907 if (searchSymbolAlias(Operands))
2908 return MatchOperand_Success;
2910 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2911 return MatchOperand_NoMatch;
2913 DEBUG(dbgs() << ".. $\n");
2915 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
2916 if (ResTy == MatchOperand_Success) {
2918 Parser.Lex(); // identifier
2923 MipsAsmParser::OperandMatchResultTy
2924 MipsAsmParser::parseImm(OperandVector &Operands) {
2925 MCAsmParser &Parser = getParser();
2926 switch (getLexer().getKind()) {
2928 return MatchOperand_NoMatch;
2929 case AsmToken::LParen:
2930 case AsmToken::Minus:
2931 case AsmToken::Plus:
2932 case AsmToken::Integer:
2933 case AsmToken::Tilde:
2934 case AsmToken::String:
2938 const MCExpr *IdVal;
2939 SMLoc S = Parser.getTok().getLoc();
2940 if (getParser().parseExpression(IdVal))
2941 return MatchOperand_ParseFail;
2943 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2944 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2945 return MatchOperand_Success;
2948 MipsAsmParser::OperandMatchResultTy
2949 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
2950 MCAsmParser &Parser = getParser();
2951 DEBUG(dbgs() << "parseJumpTarget\n");
2953 SMLoc S = getLexer().getLoc();
2955 // Integers and expressions are acceptable
2956 OperandMatchResultTy ResTy = parseImm(Operands);
2957 if (ResTy != MatchOperand_NoMatch)
2960 // Registers are a valid target and have priority over symbols.
2961 ResTy = parseAnyRegister(Operands);
2962 if (ResTy != MatchOperand_NoMatch)
2965 const MCExpr *Expr = nullptr;
2966 if (Parser.parseExpression(Expr)) {
2967 // We have no way of knowing if a symbol was consumed so we must ParseFail
2968 return MatchOperand_ParseFail;
2971 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2972 return MatchOperand_Success;
2975 MipsAsmParser::OperandMatchResultTy
2976 MipsAsmParser::parseInvNum(OperandVector &Operands) {
2977 MCAsmParser &Parser = getParser();
2978 const MCExpr *IdVal;
2979 // If the first token is '$' we may have register operand.
2980 if (Parser.getTok().is(AsmToken::Dollar))
2981 return MatchOperand_NoMatch;
2982 SMLoc S = Parser.getTok().getLoc();
2983 if (getParser().parseExpression(IdVal))
2984 return MatchOperand_ParseFail;
2985 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2986 assert(MCE && "Unexpected MCExpr type.");
2987 int64_t Val = MCE->getValue();
2988 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2989 Operands.push_back(MipsOperand::CreateImm(
2990 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
2991 return MatchOperand_Success;
2994 MipsAsmParser::OperandMatchResultTy
2995 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
2996 MCAsmParser &Parser = getParser();
2997 switch (getLexer().getKind()) {
2999 return MatchOperand_NoMatch;
3000 case AsmToken::LParen:
3001 case AsmToken::Plus:
3002 case AsmToken::Minus:
3003 case AsmToken::Integer:
3008 SMLoc S = Parser.getTok().getLoc();
3010 if (getParser().parseExpression(Expr))
3011 return MatchOperand_ParseFail;
3014 if (!Expr->EvaluateAsAbsolute(Val)) {
3015 Error(S, "expected immediate value");
3016 return MatchOperand_ParseFail;
3019 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
3020 // and because the CPU always adds one to the immediate field, the allowed
3021 // range becomes 1..4. We'll only check the range here and will deal
3022 // with the addition/subtraction when actually decoding/encoding
3024 if (Val < 1 || Val > 4) {
3025 Error(S, "immediate not in range (1..4)");
3026 return MatchOperand_ParseFail;
3030 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
3031 return MatchOperand_Success;
3034 MipsAsmParser::OperandMatchResultTy
3035 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3036 MCAsmParser &Parser = getParser();
3037 SmallVector<unsigned, 10> Regs;
3039 unsigned PrevReg = Mips::NoRegister;
3040 bool RegRange = false;
3041 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3043 if (Parser.getTok().isNot(AsmToken::Dollar))
3044 return MatchOperand_ParseFail;
3046 SMLoc S = Parser.getTok().getLoc();
3047 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3048 SMLoc E = getLexer().getLoc();
3049 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3050 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3052 // Remove last register operand because registers from register range
3053 // should be inserted first.
3054 if (RegNo == Mips::RA) {
3055 Regs.push_back(RegNo);
3057 unsigned TmpReg = PrevReg + 1;
3058 while (TmpReg <= RegNo) {
3059 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3060 Error(E, "invalid register operand");
3061 return MatchOperand_ParseFail;
3065 Regs.push_back(TmpReg++);
3071 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
3072 (RegNo != Mips::RA)) {
3073 Error(E, "$16 or $31 expected");
3074 return MatchOperand_ParseFail;
3075 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
3076 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3077 Error(E, "invalid register operand");
3078 return MatchOperand_ParseFail;
3079 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
3080 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3081 Error(E, "consecutive register numbers expected");
3082 return MatchOperand_ParseFail;
3085 Regs.push_back(RegNo);
3088 if (Parser.getTok().is(AsmToken::Minus))
3091 if (!Parser.getTok().isNot(AsmToken::Minus) &&
3092 !Parser.getTok().isNot(AsmToken::Comma)) {
3093 Error(E, "',' or '-' expected");
3094 return MatchOperand_ParseFail;
3097 Lex(); // Consume comma or minus
3098 if (Parser.getTok().isNot(AsmToken::Dollar))
3104 SMLoc E = Parser.getTok().getLoc();
3105 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3106 parseMemOperand(Operands);
3107 return MatchOperand_Success;
3110 MipsAsmParser::OperandMatchResultTy
3111 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
3112 MCAsmParser &Parser = getParser();
3114 SMLoc S = Parser.getTok().getLoc();
3115 if (parseAnyRegister(Operands) != MatchOperand_Success)
3116 return MatchOperand_ParseFail;
3118 SMLoc E = Parser.getTok().getLoc();
3119 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
3120 unsigned Reg = Op.getGPR32Reg();
3121 Operands.pop_back();
3122 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
3123 return MatchOperand_Success;
3126 MipsAsmParser::OperandMatchResultTy
3127 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
3128 MCAsmParser &Parser = getParser();
3129 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3130 SmallVector<unsigned, 10> Regs;
3132 if (Parser.getTok().isNot(AsmToken::Dollar))
3133 return MatchOperand_ParseFail;
3135 SMLoc S = Parser.getTok().getLoc();
3137 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3138 return MatchOperand_ParseFail;
3140 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3141 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3142 Regs.push_back(RegNo);
3144 SMLoc E = Parser.getTok().getLoc();
3145 if (Parser.getTok().isNot(AsmToken::Comma)) {
3146 Error(E, "',' expected");
3147 return MatchOperand_ParseFail;
3153 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3154 return MatchOperand_ParseFail;
3156 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3157 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3158 Regs.push_back(RegNo);
3160 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3162 return MatchOperand_Success;
3165 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
3167 MCSymbolRefExpr::VariantKind VK =
3168 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
3169 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
3170 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
3171 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
3172 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
3173 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
3174 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
3175 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
3176 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
3177 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
3178 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
3179 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
3180 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
3181 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
3182 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
3183 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
3184 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
3185 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
3186 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
3187 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
3188 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
3189 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
3190 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
3191 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
3192 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
3193 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
3194 .Default(MCSymbolRefExpr::VK_None);
3196 assert(VK != MCSymbolRefExpr::VK_None);
3201 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
3203 /// ::= '(', register, ')'
3204 /// handle it before we iterate so we don't get tripped up by the lack of
3206 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
3207 MCAsmParser &Parser = getParser();
3208 if (getLexer().is(AsmToken::LParen)) {
3210 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
3212 if (parseOperand(Operands, Name)) {
3213 SMLoc Loc = getLexer().getLoc();
3214 Parser.eatToEndOfStatement();
3215 return Error(Loc, "unexpected token in argument list");
3217 if (Parser.getTok().isNot(AsmToken::RParen)) {
3218 SMLoc Loc = getLexer().getLoc();
3219 Parser.eatToEndOfStatement();
3220 return Error(Loc, "unexpected token, expected ')'");
3223 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
3229 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
3230 /// either one of these.
3231 /// ::= '[', register, ']'
3232 /// ::= '[', integer, ']'
3233 /// handle it before we iterate so we don't get tripped up by the lack of
3235 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
3236 OperandVector &Operands) {
3237 MCAsmParser &Parser = getParser();
3238 if (getLexer().is(AsmToken::LBrac)) {
3240 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
3242 if (parseOperand(Operands, Name)) {
3243 SMLoc Loc = getLexer().getLoc();
3244 Parser.eatToEndOfStatement();
3245 return Error(Loc, "unexpected token in argument list");
3247 if (Parser.getTok().isNot(AsmToken::RBrac)) {
3248 SMLoc Loc = getLexer().getLoc();
3249 Parser.eatToEndOfStatement();
3250 return Error(Loc, "unexpected token, expected ']'");
3253 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
3259 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
3260 SMLoc NameLoc, OperandVector &Operands) {
3261 MCAsmParser &Parser = getParser();
3262 DEBUG(dbgs() << "ParseInstruction\n");
3264 // We have reached first instruction, module directive are now forbidden.
3265 getTargetStreamer().forbidModuleDirective();
3267 // Check if we have valid mnemonic
3268 if (!mnemonicIsValid(Name, 0)) {
3269 Parser.eatToEndOfStatement();
3270 return Error(NameLoc, "unknown instruction");
3272 // First operand in MCInst is instruction mnemonic.
3273 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
3275 // Read the remaining operands.
3276 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3277 // Read the first operand.
3278 if (parseOperand(Operands, Name)) {
3279 SMLoc Loc = getLexer().getLoc();
3280 Parser.eatToEndOfStatement();
3281 return Error(Loc, "unexpected token in argument list");
3283 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
3285 // AFAIK, parenthesis suffixes are never on the first operand
3287 while (getLexer().is(AsmToken::Comma)) {
3288 Parser.Lex(); // Eat the comma.
3289 // Parse and remember the operand.
3290 if (parseOperand(Operands, Name)) {
3291 SMLoc Loc = getLexer().getLoc();
3292 Parser.eatToEndOfStatement();
3293 return Error(Loc, "unexpected token in argument list");
3295 // Parse bracket and parenthesis suffixes before we iterate
3296 if (getLexer().is(AsmToken::LBrac)) {
3297 if (parseBracketSuffix(Name, Operands))
3299 } else if (getLexer().is(AsmToken::LParen) &&
3300 parseParenSuffix(Name, Operands))
3304 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3305 SMLoc Loc = getLexer().getLoc();
3306 Parser.eatToEndOfStatement();
3307 return Error(Loc, "unexpected token in argument list");
3309 Parser.Lex(); // Consume the EndOfStatement.
3313 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
3314 MCAsmParser &Parser = getParser();
3315 SMLoc Loc = getLexer().getLoc();
3316 Parser.eatToEndOfStatement();
3317 return Error(Loc, ErrorMsg);
3320 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
3321 return Error(Loc, ErrorMsg);
3324 bool MipsAsmParser::parseSetNoAtDirective() {
3325 MCAsmParser &Parser = getParser();
3326 // Line should look like: ".set noat".
3328 // Set the $at register to $0.
3329 AssemblerOptions.back()->setATRegIndex(0);
3331 Parser.Lex(); // Eat "noat".
3333 // If this is not the end of the statement, report an error.
3334 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3335 reportParseError("unexpected token, expected end of statement");
3339 getTargetStreamer().emitDirectiveSetNoAt();
3340 Parser.Lex(); // Consume the EndOfStatement.
3344 bool MipsAsmParser::parseSetAtDirective() {
3345 // Line can be: ".set at", which sets $at to $1
3346 // or ".set at=$reg", which sets $at to $reg.
3347 MCAsmParser &Parser = getParser();
3348 Parser.Lex(); // Eat "at".
3350 if (getLexer().is(AsmToken::EndOfStatement)) {
3351 // No register was specified, so we set $at to $1.
3352 AssemblerOptions.back()->setATRegIndex(1);
3354 getTargetStreamer().emitDirectiveSetAt();
3355 Parser.Lex(); // Consume the EndOfStatement.
3359 if (getLexer().isNot(AsmToken::Equal)) {
3360 reportParseError("unexpected token, expected equals sign");
3363 Parser.Lex(); // Eat "=".
3365 if (getLexer().isNot(AsmToken::Dollar)) {
3366 if (getLexer().is(AsmToken::EndOfStatement)) {
3367 reportParseError("no register specified");
3370 reportParseError("unexpected token, expected dollar sign '$'");
3374 Parser.Lex(); // Eat "$".
3376 // Find out what "reg" is.
3378 const AsmToken &Reg = Parser.getTok();
3379 if (Reg.is(AsmToken::Identifier)) {
3380 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
3381 } else if (Reg.is(AsmToken::Integer)) {
3382 AtRegNo = Reg.getIntVal();
3384 reportParseError("unexpected token, expected identifier or integer");
3388 // Check if $reg is a valid register. If it is, set $at to $reg.
3389 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
3390 reportParseError("invalid register");
3393 Parser.Lex(); // Eat "reg".
3395 // If this is not the end of the statement, report an error.
3396 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3397 reportParseError("unexpected token, expected end of statement");
3401 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
3403 Parser.Lex(); // Consume the EndOfStatement.
3407 bool MipsAsmParser::parseSetReorderDirective() {
3408 MCAsmParser &Parser = getParser();
3410 // If this is not the end of the statement, report an error.
3411 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3412 reportParseError("unexpected token, expected end of statement");
3415 AssemblerOptions.back()->setReorder();
3416 getTargetStreamer().emitDirectiveSetReorder();
3417 Parser.Lex(); // Consume the EndOfStatement.
3421 bool MipsAsmParser::parseSetNoReorderDirective() {
3422 MCAsmParser &Parser = getParser();
3424 // If this is not the end of the statement, report an error.
3425 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3426 reportParseError("unexpected token, expected end of statement");
3429 AssemblerOptions.back()->setNoReorder();
3430 getTargetStreamer().emitDirectiveSetNoReorder();
3431 Parser.Lex(); // Consume the EndOfStatement.
3435 bool MipsAsmParser::parseSetMacroDirective() {
3436 MCAsmParser &Parser = getParser();
3438 // If this is not the end of the statement, report an error.
3439 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3440 reportParseError("unexpected token, expected end of statement");
3443 AssemblerOptions.back()->setMacro();
3444 Parser.Lex(); // Consume the EndOfStatement.
3448 bool MipsAsmParser::parseSetNoMacroDirective() {
3449 MCAsmParser &Parser = getParser();
3451 // If this is not the end of the statement, report an error.
3452 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3453 reportParseError("unexpected token, expected end of statement");
3456 if (AssemblerOptions.back()->isReorder()) {
3457 reportParseError("`noreorder' must be set before `nomacro'");
3460 AssemblerOptions.back()->setNoMacro();
3461 Parser.Lex(); // Consume the EndOfStatement.
3465 bool MipsAsmParser::parseSetMsaDirective() {
3466 MCAsmParser &Parser = getParser();
3469 // If this is not the end of the statement, report an error.
3470 if (getLexer().isNot(AsmToken::EndOfStatement))
3471 return reportParseError("unexpected token, expected end of statement");
3473 setFeatureBits(Mips::FeatureMSA, "msa");
3474 getTargetStreamer().emitDirectiveSetMsa();
3478 bool MipsAsmParser::parseSetNoMsaDirective() {
3479 MCAsmParser &Parser = getParser();
3482 // If this is not the end of the statement, report an error.
3483 if (getLexer().isNot(AsmToken::EndOfStatement))
3484 return reportParseError("unexpected token, expected end of statement");
3486 clearFeatureBits(Mips::FeatureMSA, "msa");
3487 getTargetStreamer().emitDirectiveSetNoMsa();
3491 bool MipsAsmParser::parseSetNoDspDirective() {
3492 MCAsmParser &Parser = getParser();
3493 Parser.Lex(); // Eat "nodsp".
3495 // If this is not the end of the statement, report an error.
3496 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3497 reportParseError("unexpected token, expected end of statement");
3501 clearFeatureBits(Mips::FeatureDSP, "dsp");
3502 getTargetStreamer().emitDirectiveSetNoDsp();
3506 bool MipsAsmParser::parseSetMips16Directive() {
3507 MCAsmParser &Parser = getParser();
3508 Parser.Lex(); // Eat "mips16".
3510 // If this is not the end of the statement, report an error.
3511 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3512 reportParseError("unexpected token, expected end of statement");
3516 setFeatureBits(Mips::FeatureMips16, "mips16");
3517 getTargetStreamer().emitDirectiveSetMips16();
3518 Parser.Lex(); // Consume the EndOfStatement.
3522 bool MipsAsmParser::parseSetNoMips16Directive() {
3523 MCAsmParser &Parser = getParser();
3524 Parser.Lex(); // Eat "nomips16".
3526 // If this is not the end of the statement, report an error.
3527 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3528 reportParseError("unexpected token, expected end of statement");
3532 clearFeatureBits(Mips::FeatureMips16, "mips16");
3533 getTargetStreamer().emitDirectiveSetNoMips16();
3534 Parser.Lex(); // Consume the EndOfStatement.
3538 bool MipsAsmParser::parseSetFpDirective() {
3539 MCAsmParser &Parser = getParser();
3540 MipsABIFlagsSection::FpABIKind FpAbiVal;
3541 // Line can be: .set fp=32
3544 Parser.Lex(); // Eat fp token
3545 AsmToken Tok = Parser.getTok();
3546 if (Tok.isNot(AsmToken::Equal)) {
3547 reportParseError("unexpected token, expected equals sign '='");
3550 Parser.Lex(); // Eat '=' token.
3551 Tok = Parser.getTok();
3553 if (!parseFpABIValue(FpAbiVal, ".set"))
3556 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3557 reportParseError("unexpected token, expected end of statement");
3560 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
3561 Parser.Lex(); // Consume the EndOfStatement.
3565 bool MipsAsmParser::parseSetPopDirective() {
3566 MCAsmParser &Parser = getParser();
3567 SMLoc Loc = getLexer().getLoc();
3570 if (getLexer().isNot(AsmToken::EndOfStatement))
3571 return reportParseError("unexpected token, expected end of statement");
3573 // Always keep an element on the options "stack" to prevent the user
3574 // from changing the initial options. This is how we remember them.
3575 if (AssemblerOptions.size() == 2)
3576 return reportParseError(Loc, ".set pop with no .set push");
3578 AssemblerOptions.pop_back();
3579 setAvailableFeatures(AssemblerOptions.back()->getFeatures());
3581 getTargetStreamer().emitDirectiveSetPop();
3585 bool MipsAsmParser::parseSetPushDirective() {
3586 MCAsmParser &Parser = getParser();
3588 if (getLexer().isNot(AsmToken::EndOfStatement))
3589 return reportParseError("unexpected token, expected end of statement");
3591 // Create a copy of the current assembler options environment and push it.
3592 AssemblerOptions.push_back(
3593 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
3595 getTargetStreamer().emitDirectiveSetPush();
3599 bool MipsAsmParser::parseSetAssignment() {
3601 const MCExpr *Value;
3602 MCAsmParser &Parser = getParser();
3604 if (Parser.parseIdentifier(Name))
3605 reportParseError("expected identifier after .set");
3607 if (getLexer().isNot(AsmToken::Comma))
3608 return reportParseError("unexpected token, expected comma");
3611 if (Parser.parseExpression(Value))
3612 return reportParseError("expected valid expression after comma");
3614 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
3615 Sym->setVariableValue(Value);
3620 bool MipsAsmParser::parseSetMips0Directive() {
3621 MCAsmParser &Parser = getParser();
3623 if (getLexer().isNot(AsmToken::EndOfStatement))
3624 return reportParseError("unexpected token, expected end of statement");
3626 // Reset assembler options to their initial values.
3627 setAvailableFeatures(AssemblerOptions.front()->getFeatures());
3628 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
3630 getTargetStreamer().emitDirectiveSetMips0();
3634 bool MipsAsmParser::parseSetArchDirective() {
3635 MCAsmParser &Parser = getParser();
3637 if (getLexer().isNot(AsmToken::Equal))
3638 return reportParseError("unexpected token, expected equals sign");
3642 if (Parser.parseIdentifier(Arch))
3643 return reportParseError("expected arch identifier");
3645 StringRef ArchFeatureName =
3646 StringSwitch<StringRef>(Arch)
3647 .Case("mips1", "mips1")
3648 .Case("mips2", "mips2")
3649 .Case("mips3", "mips3")
3650 .Case("mips4", "mips4")
3651 .Case("mips5", "mips5")
3652 .Case("mips32", "mips32")
3653 .Case("mips32r2", "mips32r2")
3654 .Case("mips32r3", "mips32r3")
3655 .Case("mips32r5", "mips32r5")
3656 .Case("mips32r6", "mips32r6")
3657 .Case("mips64", "mips64")
3658 .Case("mips64r2", "mips64r2")
3659 .Case("mips64r3", "mips64r3")
3660 .Case("mips64r5", "mips64r5")
3661 .Case("mips64r6", "mips64r6")
3662 .Case("cnmips", "cnmips")
3663 .Case("r4000", "mips3") // This is an implementation of Mips3.
3666 if (ArchFeatureName.empty())
3667 return reportParseError("unsupported architecture");
3669 selectArch(ArchFeatureName);
3670 getTargetStreamer().emitDirectiveSetArch(Arch);
3674 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
3675 MCAsmParser &Parser = getParser();
3677 if (getLexer().isNot(AsmToken::EndOfStatement))
3678 return reportParseError("unexpected token, expected end of statement");
3682 llvm_unreachable("Unimplemented feature");
3683 case Mips::FeatureDSP:
3684 setFeatureBits(Mips::FeatureDSP, "dsp");
3685 getTargetStreamer().emitDirectiveSetDsp();
3687 case Mips::FeatureMicroMips:
3688 getTargetStreamer().emitDirectiveSetMicroMips();
3690 case Mips::FeatureMips1:
3691 selectArch("mips1");
3692 getTargetStreamer().emitDirectiveSetMips1();
3694 case Mips::FeatureMips2:
3695 selectArch("mips2");
3696 getTargetStreamer().emitDirectiveSetMips2();
3698 case Mips::FeatureMips3:
3699 selectArch("mips3");
3700 getTargetStreamer().emitDirectiveSetMips3();
3702 case Mips::FeatureMips4:
3703 selectArch("mips4");
3704 getTargetStreamer().emitDirectiveSetMips4();
3706 case Mips::FeatureMips5:
3707 selectArch("mips5");
3708 getTargetStreamer().emitDirectiveSetMips5();
3710 case Mips::FeatureMips32:
3711 selectArch("mips32");
3712 getTargetStreamer().emitDirectiveSetMips32();
3714 case Mips::FeatureMips32r2:
3715 selectArch("mips32r2");
3716 getTargetStreamer().emitDirectiveSetMips32R2();
3718 case Mips::FeatureMips32r3:
3719 selectArch("mips32r3");
3720 getTargetStreamer().emitDirectiveSetMips32R3();
3722 case Mips::FeatureMips32r5:
3723 selectArch("mips32r5");
3724 getTargetStreamer().emitDirectiveSetMips32R5();
3726 case Mips::FeatureMips32r6:
3727 selectArch("mips32r6");
3728 getTargetStreamer().emitDirectiveSetMips32R6();
3730 case Mips::FeatureMips64:
3731 selectArch("mips64");
3732 getTargetStreamer().emitDirectiveSetMips64();
3734 case Mips::FeatureMips64r2:
3735 selectArch("mips64r2");
3736 getTargetStreamer().emitDirectiveSetMips64R2();
3738 case Mips::FeatureMips64r3:
3739 selectArch("mips64r3");
3740 getTargetStreamer().emitDirectiveSetMips64R3();
3742 case Mips::FeatureMips64r5:
3743 selectArch("mips64r5");
3744 getTargetStreamer().emitDirectiveSetMips64R5();
3746 case Mips::FeatureMips64r6:
3747 selectArch("mips64r6");
3748 getTargetStreamer().emitDirectiveSetMips64R6();
3754 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
3755 MCAsmParser &Parser = getParser();
3756 if (getLexer().isNot(AsmToken::Comma)) {
3757 SMLoc Loc = getLexer().getLoc();
3758 Parser.eatToEndOfStatement();
3759 return Error(Loc, ErrorStr);
3762 Parser.Lex(); // Eat the comma.
3766 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
3767 if (AssemblerOptions.back()->isReorder())
3768 Warning(Loc, ".cpload should be inside a noreorder section");
3770 if (inMips16Mode()) {
3771 reportParseError(".cpload is not supported in Mips16 mode");
3775 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
3776 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
3777 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3778 reportParseError("expected register containing function address");
3782 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
3783 if (!RegOpnd.isGPRAsmReg()) {
3784 reportParseError(RegOpnd.getStartLoc(), "invalid register");
3788 // If this is not the end of the statement, report an error.
3789 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3790 reportParseError("unexpected token, expected end of statement");
3794 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
3798 bool MipsAsmParser::parseDirectiveCPSetup() {
3799 MCAsmParser &Parser = getParser();
3802 bool SaveIsReg = true;
3804 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3805 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3806 if (ResTy == MatchOperand_NoMatch) {
3807 reportParseError("expected register containing function address");
3808 Parser.eatToEndOfStatement();
3812 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3813 if (!FuncRegOpnd.isGPRAsmReg()) {
3814 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
3815 Parser.eatToEndOfStatement();
3819 FuncReg = FuncRegOpnd.getGPR32Reg();
3822 if (!eatComma("unexpected token, expected comma"))
3825 ResTy = parseAnyRegister(TmpReg);
3826 if (ResTy == MatchOperand_NoMatch) {
3827 const AsmToken &Tok = Parser.getTok();
3828 if (Tok.is(AsmToken::Integer)) {
3829 Save = Tok.getIntVal();
3833 reportParseError("expected save register or stack offset");
3834 Parser.eatToEndOfStatement();
3838 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3839 if (!SaveOpnd.isGPRAsmReg()) {
3840 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
3841 Parser.eatToEndOfStatement();
3844 Save = SaveOpnd.getGPR32Reg();
3847 if (!eatComma("unexpected token, expected comma"))
3851 if (Parser.parseExpression(Expr)) {
3852 reportParseError("expected expression");
3856 if (Expr->getKind() != MCExpr::SymbolRef) {
3857 reportParseError("expected symbol");
3860 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3862 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
3867 bool MipsAsmParser::parseDirectiveNaN() {
3868 MCAsmParser &Parser = getParser();
3869 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3870 const AsmToken &Tok = Parser.getTok();
3872 if (Tok.getString() == "2008") {
3874 getTargetStreamer().emitDirectiveNaN2008();
3876 } else if (Tok.getString() == "legacy") {
3878 getTargetStreamer().emitDirectiveNaNLegacy();
3882 // If we don't recognize the option passed to the .nan
3883 // directive (e.g. no option or unknown option), emit an error.
3884 reportParseError("invalid option in .nan directive");
3888 bool MipsAsmParser::parseDirectiveSet() {
3889 MCAsmParser &Parser = getParser();
3890 // Get the next token.
3891 const AsmToken &Tok = Parser.getTok();
3893 if (Tok.getString() == "noat") {
3894 return parseSetNoAtDirective();
3895 } else if (Tok.getString() == "at") {
3896 return parseSetAtDirective();
3897 } else if (Tok.getString() == "arch") {
3898 return parseSetArchDirective();
3899 } else if (Tok.getString() == "fp") {
3900 return parseSetFpDirective();
3901 } else if (Tok.getString() == "pop") {
3902 return parseSetPopDirective();
3903 } else if (Tok.getString() == "push") {
3904 return parseSetPushDirective();
3905 } else if (Tok.getString() == "reorder") {
3906 return parseSetReorderDirective();
3907 } else if (Tok.getString() == "noreorder") {
3908 return parseSetNoReorderDirective();
3909 } else if (Tok.getString() == "macro") {
3910 return parseSetMacroDirective();
3911 } else if (Tok.getString() == "nomacro") {
3912 return parseSetNoMacroDirective();
3913 } else if (Tok.getString() == "mips16") {
3914 return parseSetMips16Directive();
3915 } else if (Tok.getString() == "nomips16") {
3916 return parseSetNoMips16Directive();
3917 } else if (Tok.getString() == "nomicromips") {
3918 getTargetStreamer().emitDirectiveSetNoMicroMips();
3919 Parser.eatToEndOfStatement();
3921 } else if (Tok.getString() == "micromips") {
3922 return parseSetFeature(Mips::FeatureMicroMips);
3923 } else if (Tok.getString() == "mips0") {
3924 return parseSetMips0Directive();
3925 } else if (Tok.getString() == "mips1") {
3926 return parseSetFeature(Mips::FeatureMips1);
3927 } else if (Tok.getString() == "mips2") {
3928 return parseSetFeature(Mips::FeatureMips2);
3929 } else if (Tok.getString() == "mips3") {
3930 return parseSetFeature(Mips::FeatureMips3);
3931 } else if (Tok.getString() == "mips4") {
3932 return parseSetFeature(Mips::FeatureMips4);
3933 } else if (Tok.getString() == "mips5") {
3934 return parseSetFeature(Mips::FeatureMips5);
3935 } else if (Tok.getString() == "mips32") {
3936 return parseSetFeature(Mips::FeatureMips32);
3937 } else if (Tok.getString() == "mips32r2") {
3938 return parseSetFeature(Mips::FeatureMips32r2);
3939 } else if (Tok.getString() == "mips32r3") {
3940 return parseSetFeature(Mips::FeatureMips32r3);
3941 } else if (Tok.getString() == "mips32r5") {
3942 return parseSetFeature(Mips::FeatureMips32r5);
3943 } else if (Tok.getString() == "mips32r6") {
3944 return parseSetFeature(Mips::FeatureMips32r6);
3945 } else if (Tok.getString() == "mips64") {
3946 return parseSetFeature(Mips::FeatureMips64);
3947 } else if (Tok.getString() == "mips64r2") {
3948 return parseSetFeature(Mips::FeatureMips64r2);
3949 } else if (Tok.getString() == "mips64r3") {
3950 return parseSetFeature(Mips::FeatureMips64r3);
3951 } else if (Tok.getString() == "mips64r5") {
3952 return parseSetFeature(Mips::FeatureMips64r5);
3953 } else if (Tok.getString() == "mips64r6") {
3954 return parseSetFeature(Mips::FeatureMips64r6);
3955 } else if (Tok.getString() == "dsp") {
3956 return parseSetFeature(Mips::FeatureDSP);
3957 } else if (Tok.getString() == "nodsp") {
3958 return parseSetNoDspDirective();
3959 } else if (Tok.getString() == "msa") {
3960 return parseSetMsaDirective();
3961 } else if (Tok.getString() == "nomsa") {
3962 return parseSetNoMsaDirective();
3964 // It is just an identifier, look for an assignment.
3965 parseSetAssignment();
3972 /// parseDataDirective
3973 /// ::= .word [ expression (, expression)* ]
3974 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
3975 MCAsmParser &Parser = getParser();
3976 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3978 const MCExpr *Value;
3979 if (getParser().parseExpression(Value))
3982 getParser().getStreamer().EmitValue(Value, Size);
3984 if (getLexer().is(AsmToken::EndOfStatement))
3987 if (getLexer().isNot(AsmToken::Comma))
3988 return Error(L, "unexpected token, expected comma");
3997 /// parseDirectiveGpWord
3998 /// ::= .gpword local_sym
3999 bool MipsAsmParser::parseDirectiveGpWord() {
4000 MCAsmParser &Parser = getParser();
4001 const MCExpr *Value;
4002 // EmitGPRel32Value requires an expression, so we are using base class
4003 // method to evaluate the expression.
4004 if (getParser().parseExpression(Value))
4006 getParser().getStreamer().EmitGPRel32Value(Value);
4008 if (getLexer().isNot(AsmToken::EndOfStatement))
4009 return Error(getLexer().getLoc(),
4010 "unexpected token, expected end of statement");
4011 Parser.Lex(); // Eat EndOfStatement token.
4015 /// parseDirectiveGpDWord
4016 /// ::= .gpdword local_sym
4017 bool MipsAsmParser::parseDirectiveGpDWord() {
4018 MCAsmParser &Parser = getParser();
4019 const MCExpr *Value;
4020 // EmitGPRel64Value requires an expression, so we are using base class
4021 // method to evaluate the expression.
4022 if (getParser().parseExpression(Value))
4024 getParser().getStreamer().EmitGPRel64Value(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 bool MipsAsmParser::parseDirectiveOption() {
4034 MCAsmParser &Parser = getParser();
4035 // Get the option token.
4036 AsmToken Tok = Parser.getTok();
4037 // At the moment only identifiers are supported.
4038 if (Tok.isNot(AsmToken::Identifier)) {
4039 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
4040 Parser.eatToEndOfStatement();
4044 StringRef Option = Tok.getIdentifier();
4046 if (Option == "pic0") {
4047 getTargetStreamer().emitDirectiveOptionPic0();
4049 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4050 Error(Parser.getTok().getLoc(),
4051 "unexpected token, expected end of statement");
4052 Parser.eatToEndOfStatement();
4057 if (Option == "pic2") {
4058 getTargetStreamer().emitDirectiveOptionPic2();
4060 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4061 Error(Parser.getTok().getLoc(),
4062 "unexpected token, expected end of statement");
4063 Parser.eatToEndOfStatement();
4069 Warning(Parser.getTok().getLoc(),
4070 "unknown option, expected 'pic0' or 'pic2'");
4071 Parser.eatToEndOfStatement();
4075 /// parseInsnDirective
4077 bool MipsAsmParser::parseInsnDirective() {
4078 // If this is not the end of the statement, report an error.
4079 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4080 reportParseError("unexpected token, expected end of statement");
4084 // The actual label marking happens in
4085 // MipsELFStreamer::createPendingLabelRelocs().
4086 getTargetStreamer().emitDirectiveInsn();
4088 getParser().Lex(); // Eat EndOfStatement token.
4092 /// parseDirectiveModule
4093 /// ::= .module oddspreg
4094 /// ::= .module nooddspreg
4095 /// ::= .module fp=value
4096 bool MipsAsmParser::parseDirectiveModule() {
4097 MCAsmParser &Parser = getParser();
4098 MCAsmLexer &Lexer = getLexer();
4099 SMLoc L = Lexer.getLoc();
4101 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
4102 // TODO : get a better message.
4103 reportParseError(".module directive must appear before any code");
4108 if (Parser.parseIdentifier(Option)) {
4109 reportParseError("expected .module option identifier");
4113 if (Option == "oddspreg") {
4114 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
4115 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4117 // If this is not the end of the statement, report an error.
4118 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4119 reportParseError("unexpected token, expected end of statement");
4123 return false; // parseDirectiveModule has finished successfully.
4124 } else if (Option == "nooddspreg") {
4126 Error(L, "'.module nooddspreg' requires the O32 ABI");
4130 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
4131 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4133 // If this is not the end of the statement, report an error.
4134 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4135 reportParseError("unexpected token, expected end of statement");
4139 return false; // parseDirectiveModule has finished successfully.
4140 } else if (Option == "fp") {
4141 return parseDirectiveModuleFP();
4143 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
4147 /// parseDirectiveModuleFP
4151 bool MipsAsmParser::parseDirectiveModuleFP() {
4152 MCAsmParser &Parser = getParser();
4153 MCAsmLexer &Lexer = getLexer();
4155 if (Lexer.isNot(AsmToken::Equal)) {
4156 reportParseError("unexpected token, expected equals sign '='");
4159 Parser.Lex(); // Eat '=' token.
4161 MipsABIFlagsSection::FpABIKind FpABI;
4162 if (!parseFpABIValue(FpABI, ".module"))
4165 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4166 reportParseError("unexpected token, expected end of statement");
4170 // Emit appropriate flags.
4171 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
4172 Parser.Lex(); // Consume the EndOfStatement.
4176 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
4177 StringRef Directive) {
4178 MCAsmParser &Parser = getParser();
4179 MCAsmLexer &Lexer = getLexer();
4181 if (Lexer.is(AsmToken::Identifier)) {
4182 StringRef Value = Parser.getTok().getString();
4185 if (Value != "xx") {
4186 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4191 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
4195 FpABI = MipsABIFlagsSection::FpABIKind::XX;
4199 if (Lexer.is(AsmToken::Integer)) {
4200 unsigned Value = Parser.getTok().getIntVal();
4203 if (Value != 32 && Value != 64) {
4204 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4210 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
4214 FpABI = MipsABIFlagsSection::FpABIKind::S32;
4216 FpABI = MipsABIFlagsSection::FpABIKind::S64;
4224 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
4225 MCAsmParser &Parser = getParser();
4226 StringRef IDVal = DirectiveID.getString();
4228 if (IDVal == ".cpload")
4229 return parseDirectiveCpLoad(DirectiveID.getLoc());
4230 if (IDVal == ".dword") {
4231 parseDataDirective(8, DirectiveID.getLoc());
4234 if (IDVal == ".ent") {
4235 StringRef SymbolName;
4237 if (Parser.parseIdentifier(SymbolName)) {
4238 reportParseError("expected identifier after .ent");
4242 // There's an undocumented extension that allows an integer to
4243 // follow the name of the procedure which AFAICS is ignored by GAS.
4244 // Example: .ent foo,2
4245 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4246 if (getLexer().isNot(AsmToken::Comma)) {
4247 // Even though we accept this undocumented extension for compatibility
4248 // reasons, the additional integer argument does not actually change
4249 // the behaviour of the '.ent' directive, so we would like to discourage
4250 // its use. We do this by not referring to the extended version in
4251 // error messages which are not directly related to its use.
4252 reportParseError("unexpected token, expected end of statement");
4255 Parser.Lex(); // Eat the comma.
4256 const MCExpr *DummyNumber;
4257 int64_t DummyNumberVal;
4258 // If the user was explicitly trying to use the extended version,
4259 // we still give helpful extension-related error messages.
4260 if (Parser.parseExpression(DummyNumber)) {
4261 reportParseError("expected number after comma");
4264 if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) {
4265 reportParseError("expected an absolute expression after comma");
4270 // If this is not the end of the statement, report an error.
4271 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4272 reportParseError("unexpected token, expected end of statement");
4276 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
4278 getTargetStreamer().emitDirectiveEnt(*Sym);
4283 if (IDVal == ".end") {
4284 StringRef SymbolName;
4286 if (Parser.parseIdentifier(SymbolName)) {
4287 reportParseError("expected identifier after .end");
4291 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4292 reportParseError("unexpected token, expected end of statement");
4296 if (CurrentFn == nullptr) {
4297 reportParseError(".end used without .ent");
4301 if ((SymbolName != CurrentFn->getName())) {
4302 reportParseError(".end symbol does not match .ent symbol");
4306 getTargetStreamer().emitDirectiveEnd(SymbolName);
4307 CurrentFn = nullptr;
4311 if (IDVal == ".frame") {
4312 // .frame $stack_reg, frame_size_in_bytes, $return_reg
4313 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4314 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4315 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4316 reportParseError("expected stack register");
4320 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4321 if (!StackRegOpnd.isGPRAsmReg()) {
4322 reportParseError(StackRegOpnd.getStartLoc(),
4323 "expected general purpose register");
4326 unsigned StackReg = StackRegOpnd.getGPR32Reg();
4328 if (Parser.getTok().is(AsmToken::Comma))
4331 reportParseError("unexpected token, expected comma");
4335 // Parse the frame size.
4336 const MCExpr *FrameSize;
4337 int64_t FrameSizeVal;
4339 if (Parser.parseExpression(FrameSize)) {
4340 reportParseError("expected frame size value");
4344 if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) {
4345 reportParseError("frame size not an absolute expression");
4349 if (Parser.getTok().is(AsmToken::Comma))
4352 reportParseError("unexpected token, expected comma");
4356 // Parse the return register.
4358 ResTy = parseAnyRegister(TmpReg);
4359 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4360 reportParseError("expected return register");
4364 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4365 if (!ReturnRegOpnd.isGPRAsmReg()) {
4366 reportParseError(ReturnRegOpnd.getStartLoc(),
4367 "expected general purpose register");
4371 // If this is not the end of the statement, report an error.
4372 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4373 reportParseError("unexpected token, expected end of statement");
4377 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
4378 ReturnRegOpnd.getGPR32Reg());
4382 if (IDVal == ".set") {
4383 return parseDirectiveSet();
4386 if (IDVal == ".mask" || IDVal == ".fmask") {
4387 // .mask bitmask, frame_offset
4388 // bitmask: One bit for each register used.
4389 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
4390 // first register is expected to be saved.
4392 // .mask 0x80000000, -4
4393 // .fmask 0x80000000, -4
4396 // Parse the bitmask
4397 const MCExpr *BitMask;
4400 if (Parser.parseExpression(BitMask)) {
4401 reportParseError("expected bitmask value");
4405 if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) {
4406 reportParseError("bitmask not an absolute expression");
4410 if (Parser.getTok().is(AsmToken::Comma))
4413 reportParseError("unexpected token, expected comma");
4417 // Parse the frame_offset
4418 const MCExpr *FrameOffset;
4419 int64_t FrameOffsetVal;
4421 if (Parser.parseExpression(FrameOffset)) {
4422 reportParseError("expected frame offset value");
4426 if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) {
4427 reportParseError("frame offset not an absolute expression");
4431 // If this is not the end of the statement, report an error.
4432 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4433 reportParseError("unexpected token, expected end of statement");
4437 if (IDVal == ".mask")
4438 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
4440 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
4444 if (IDVal == ".nan")
4445 return parseDirectiveNaN();
4447 if (IDVal == ".gpword") {
4448 parseDirectiveGpWord();
4452 if (IDVal == ".gpdword") {
4453 parseDirectiveGpDWord();
4457 if (IDVal == ".word") {
4458 parseDataDirective(4, DirectiveID.getLoc());
4462 if (IDVal == ".option")
4463 return parseDirectiveOption();
4465 if (IDVal == ".abicalls") {
4466 getTargetStreamer().emitDirectiveAbiCalls();
4467 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4468 Error(Parser.getTok().getLoc(),
4469 "unexpected token, expected end of statement");
4471 Parser.eatToEndOfStatement();
4476 if (IDVal == ".cpsetup")
4477 return parseDirectiveCPSetup();
4479 if (IDVal == ".module")
4480 return parseDirectiveModule();
4482 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
4483 return parseInternalDirectiveReallowModule();
4485 if (IDVal == ".insn")
4486 return parseInsnDirective();
4491 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
4492 // If this is not the end of the statement, report an error.
4493 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4494 reportParseError("unexpected token, expected end of statement");
4498 getTargetStreamer().reallowModuleDirective();
4500 getParser().Lex(); // Eat EndOfStatement token.
4504 extern "C" void LLVMInitializeMipsAsmParser() {
4505 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
4506 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
4507 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
4508 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
4511 #define GET_REGISTER_MATCHER
4512 #define GET_MATCHER_IMPLEMENTATION
4513 #include "MipsGenAsmMatcher.inc"