1 //===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "MCTargetDesc/MipsABIInfo.h"
11 #include "MCTargetDesc/MipsMCExpr.h"
12 #include "MCTargetDesc/MipsMCTargetDesc.h"
13 #include "MipsRegisterInfo.h"
14 #include "MipsTargetStreamer.h"
15 #include "llvm/ADT/APInt.h"
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/ADT/StringSwitch.h"
18 #include "llvm/MC/MCContext.h"
19 #include "llvm/MC/MCExpr.h"
20 #include "llvm/MC/MCInst.h"
21 #include "llvm/MC/MCInstBuilder.h"
22 #include "llvm/MC/MCParser/MCAsmLexer.h"
23 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
24 #include "llvm/MC/MCStreamer.h"
25 #include "llvm/MC/MCSubtargetInfo.h"
26 #include "llvm/MC/MCSymbol.h"
27 #include "llvm/MC/MCTargetAsmParser.h"
28 #include "llvm/Support/Debug.h"
29 #include "llvm/Support/MathExtras.h"
30 #include "llvm/Support/SourceMgr.h"
31 #include "llvm/Support/TargetRegistry.h"
32 #include "llvm/Support/raw_ostream.h"
37 #define DEBUG_TYPE "mips-asm-parser"
44 class MipsAssemblerOptions {
46 MipsAssemblerOptions(uint64_t Features_) :
47 ATReg(1), Reorder(true), Macro(true), Features(Features_) {}
49 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
50 ATReg = Opts->getATRegIndex();
51 Reorder = Opts->isReorder();
52 Macro = Opts->isMacro();
53 Features = Opts->getFeatures();
56 unsigned getATRegIndex() const { return ATReg; }
57 bool setATRegIndex(unsigned Reg) {
65 bool isReorder() const { return Reorder; }
66 void setReorder() { Reorder = true; }
67 void setNoReorder() { Reorder = false; }
69 bool isMacro() const { return Macro; }
70 void setMacro() { Macro = true; }
71 void setNoMacro() { Macro = false; }
73 uint64_t getFeatures() const { return Features; }
74 void setFeatures(uint64_t Features_) { Features = Features_; }
76 // Set of features that are either architecture features or referenced
77 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
78 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
79 // The reason we need this mask is explained in the selectArch function.
80 // FIXME: Ideally we would like TableGen to generate this information.
81 static const FeatureBitset AllArchRelatedMask;
91 const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
92 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
93 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
94 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
95 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
96 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
97 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
98 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
99 Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008
103 class MipsAsmParser : public MCTargetAsmParser {
104 MipsTargetStreamer &getTargetStreamer() {
105 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
106 return static_cast<MipsTargetStreamer &>(TS);
109 MCSubtargetInfo &STI;
111 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
112 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
113 // nullptr, which indicates that no function is currently
114 // selected. This usually happens after an '.end func'
117 // Print a warning along with its fix-it message at the given range.
118 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
119 SMRange Range, bool ShowColors = true);
121 #define GET_ASSEMBLER_HEADER
122 #include "MipsGenAsmMatcher.inc"
124 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
126 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
127 OperandVector &Operands, MCStreamer &Out,
129 bool MatchingInlineAsm) override;
131 /// Parse a register as used in CFI directives
132 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
134 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
136 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
138 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
139 SMLoc NameLoc, OperandVector &Operands) override;
141 bool ParseDirective(AsmToken DirectiveID) override;
143 MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
145 MipsAsmParser::OperandMatchResultTy
146 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
147 StringRef Identifier, SMLoc S);
149 MipsAsmParser::OperandMatchResultTy
150 matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
152 MipsAsmParser::OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
154 MipsAsmParser::OperandMatchResultTy parseImm(OperandVector &Operands);
156 MipsAsmParser::OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
158 MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
160 MipsAsmParser::OperandMatchResultTy parseLSAImm(OperandVector &Operands);
162 MipsAsmParser::OperandMatchResultTy
163 parseRegisterPair (OperandVector &Operands);
165 MipsAsmParser::OperandMatchResultTy
166 parseMovePRegPair(OperandVector &Operands);
168 MipsAsmParser::OperandMatchResultTy
169 parseRegisterList (OperandVector &Operands);
171 bool searchSymbolAlias(OperandVector &Operands);
173 bool parseOperand(OperandVector &, StringRef Mnemonic);
175 bool needsExpansion(MCInst &Inst);
177 // Expands assembly pseudo instructions.
178 // Returns false on success, true otherwise.
179 bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
180 SmallVectorImpl<MCInst> &Instructions);
182 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
183 SmallVectorImpl<MCInst> &Instructions);
185 bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
186 bool Is32BitImm, SMLoc IDLoc,
187 SmallVectorImpl<MCInst> &Instructions);
189 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
190 SmallVectorImpl<MCInst> &Instructions);
192 bool expandLoadAddressImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
193 SmallVectorImpl<MCInst> &Instructions);
195 bool expandLoadAddressReg(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
196 SmallVectorImpl<MCInst> &Instructions);
197 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
198 SmallVectorImpl<MCInst> &Instructions);
200 void expandLoadAddressSym(const MCOperand &DstRegOp, const MCOperand &SymOp,
201 bool Is32BitSym, SMLoc IDLoc,
202 SmallVectorImpl<MCInst> &Instructions);
204 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
205 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
208 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
209 SmallVectorImpl<MCInst> &Instructions);
211 void createNop(bool hasShortDelaySlot, SMLoc IDLoc,
212 SmallVectorImpl<MCInst> &Instructions);
214 void createAddu(unsigned DstReg, unsigned SrcReg, unsigned TrgReg,
215 SmallVectorImpl<MCInst> &Instructions);
217 bool reportParseError(Twine ErrorMsg);
218 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
220 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
221 bool parseRelocOperand(const MCExpr *&Res);
223 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
225 bool isEvaluated(const MCExpr *Expr);
226 bool parseSetMips0Directive();
227 bool parseSetArchDirective();
228 bool parseSetFeature(uint64_t Feature);
229 bool parseDirectiveCpLoad(SMLoc Loc);
230 bool parseDirectiveCPSetup();
231 bool parseDirectiveNaN();
232 bool parseDirectiveSet();
233 bool parseDirectiveOption();
234 bool parseInsnDirective();
236 bool parseSetAtDirective();
237 bool parseSetNoAtDirective();
238 bool parseSetMacroDirective();
239 bool parseSetNoMacroDirective();
240 bool parseSetMsaDirective();
241 bool parseSetNoMsaDirective();
242 bool parseSetNoDspDirective();
243 bool parseSetReorderDirective();
244 bool parseSetNoReorderDirective();
245 bool parseSetMips16Directive();
246 bool parseSetNoMips16Directive();
247 bool parseSetFpDirective();
248 bool parseSetPopDirective();
249 bool parseSetPushDirective();
250 bool parseSetSoftFloatDirective();
251 bool parseSetHardFloatDirective();
253 bool parseSetAssignment();
255 bool parseDataDirective(unsigned Size, SMLoc L);
256 bool parseDirectiveGpWord();
257 bool parseDirectiveGpDWord();
258 bool parseDirectiveModule();
259 bool parseDirectiveModuleFP();
260 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
261 StringRef Directive);
263 bool parseInternalDirectiveReallowModule();
265 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
267 bool eatComma(StringRef ErrorStr);
269 int matchCPURegisterName(StringRef Symbol);
271 int matchHWRegsRegisterName(StringRef Symbol);
273 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
275 int matchFPURegisterName(StringRef Name);
277 int matchFCCRegisterName(StringRef Name);
279 int matchACRegisterName(StringRef Name);
281 int matchMSA128RegisterName(StringRef Name);
283 int matchMSA128CtrlRegisterName(StringRef Name);
285 unsigned getReg(int RC, int RegNo);
287 unsigned getGPR(int RegNo);
289 /// Returns the internal register number for the current AT. Also checks if
290 /// the current AT is unavailable (set to $0) and gives an error if it is.
291 /// This should be used in pseudo-instruction expansions which need AT.
292 unsigned getATReg(SMLoc Loc);
294 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
295 SmallVectorImpl<MCInst> &Instructions);
297 // Helper function that checks if the value of a vector index is within the
298 // boundaries of accepted values for each RegisterKind
299 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
300 bool validateMSAIndex(int Val, int RegKind);
302 // Selects a new architecture by updating the FeatureBits with the necessary
303 // info including implied dependencies.
304 // Internally, it clears all the feature bits related to *any* architecture
305 // and selects the new one using the ToggleFeature functionality of the
306 // MCSubtargetInfo object that handles implied dependencies. The reason we
307 // clear all the arch related bits manually is because ToggleFeature only
308 // clears the features that imply the feature being cleared and not the
309 // features implied by the feature being cleared. This is easier to see
311 // --------------------------------------------------
312 // | Feature | Implies |
313 // | -------------------------------------------------|
314 // | FeatureMips1 | None |
315 // | FeatureMips2 | FeatureMips1 |
316 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
317 // | FeatureMips4 | FeatureMips3 |
319 // --------------------------------------------------
321 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
322 // FeatureMipsGP64 | FeatureMips1)
323 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
324 void selectArch(StringRef ArchFeature) {
325 FeatureBitset FeatureBits = STI.getFeatureBits();
326 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
327 STI.setFeatureBits(FeatureBits);
328 setAvailableFeatures(
329 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
330 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
333 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
334 if (!(STI.getFeatureBits()[Feature])) {
335 setAvailableFeatures(
336 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
338 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
341 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
342 if (STI.getFeatureBits()[Feature]) {
343 setAvailableFeatures(
344 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
346 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
350 enum MipsMatchResultTy {
351 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
352 #define GET_OPERAND_DIAGNOSTIC_TYPES
353 #include "MipsGenAsmMatcher.inc"
354 #undef GET_OPERAND_DIAGNOSTIC_TYPES
358 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
359 const MCInstrInfo &MII, const MCTargetOptions &Options)
360 : MCTargetAsmParser(), STI(sti),
361 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
362 sti.getCPU(), Options)) {
363 MCAsmParserExtension::Initialize(parser);
365 parser.addAliasForDirective(".asciiz", ".asciz");
367 // Initialize the set of available features.
368 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
370 // Remember the initial assembler options. The user can not modify these.
371 AssemblerOptions.push_back(
372 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
374 // Create an assembler options environment for the user to modify.
375 AssemblerOptions.push_back(
376 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
378 getTargetStreamer().updateABIInfo(*this);
380 if (!isABI_O32() && !useOddSPReg() != 0)
381 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
386 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
387 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
389 bool isGP64bit() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
390 bool isFP64bit() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }
391 const MipsABIInfo &getABI() const { return ABI; }
392 bool isABI_N32() const { return ABI.IsN32(); }
393 bool isABI_N64() const { return ABI.IsN64(); }
394 bool isABI_O32() const { return ABI.IsO32(); }
395 bool isABI_FPXX() const { return STI.getFeatureBits()[Mips::FeatureFPXX]; }
397 bool useOddSPReg() const {
398 return !(STI.getFeatureBits()[Mips::FeatureNoOddSPReg]);
401 bool inMicroMipsMode() const {
402 return STI.getFeatureBits()[Mips::FeatureMicroMips];
404 bool hasMips1() const { return STI.getFeatureBits()[Mips::FeatureMips1]; }
405 bool hasMips2() const { return STI.getFeatureBits()[Mips::FeatureMips2]; }
406 bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
407 bool hasMips4() const { return STI.getFeatureBits()[Mips::FeatureMips4]; }
408 bool hasMips5() const { return STI.getFeatureBits()[Mips::FeatureMips5]; }
409 bool hasMips32() const {
410 return STI.getFeatureBits()[Mips::FeatureMips32];
412 bool hasMips64() const {
413 return STI.getFeatureBits()[Mips::FeatureMips64];
415 bool hasMips32r2() const {
416 return STI.getFeatureBits()[Mips::FeatureMips32r2];
418 bool hasMips64r2() const {
419 return STI.getFeatureBits()[Mips::FeatureMips64r2];
421 bool hasMips32r3() const {
422 return (STI.getFeatureBits()[Mips::FeatureMips32r3]);
424 bool hasMips64r3() const {
425 return (STI.getFeatureBits()[Mips::FeatureMips64r3]);
427 bool hasMips32r5() const {
428 return (STI.getFeatureBits()[Mips::FeatureMips32r5]);
430 bool hasMips64r5() const {
431 return (STI.getFeatureBits()[Mips::FeatureMips64r5]);
433 bool hasMips32r6() const {
434 return STI.getFeatureBits()[Mips::FeatureMips32r6];
436 bool hasMips64r6() const {
437 return STI.getFeatureBits()[Mips::FeatureMips64r6];
440 bool hasDSP() const { return STI.getFeatureBits()[Mips::FeatureDSP]; }
441 bool hasDSPR2() const { return STI.getFeatureBits()[Mips::FeatureDSPR2]; }
442 bool hasMSA() const { return STI.getFeatureBits()[Mips::FeatureMSA]; }
443 bool hasCnMips() const {
444 return (STI.getFeatureBits()[Mips::FeatureCnMips]);
447 bool inMips16Mode() const {
448 return STI.getFeatureBits()[Mips::FeatureMips16];
451 bool useSoftFloat() const {
452 return STI.getFeatureBits()[Mips::FeatureSoftFloat];
455 /// Warn if RegIndex is the same as the current AT.
456 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
458 void warnIfNoMacro(SMLoc Loc);
464 /// MipsOperand - Instances of this class represent a parsed Mips machine
466 class MipsOperand : public MCParsedAsmOperand {
468 /// Broad categories of register classes
469 /// The exact class is finalized by the render method.
471 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
472 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
474 RegKind_FCC = 4, /// FCC
475 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
476 RegKind_MSACtrl = 16, /// MSA control registers
477 RegKind_COP2 = 32, /// COP2
478 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
480 RegKind_CCR = 128, /// CCR
481 RegKind_HWRegs = 256, /// HWRegs
482 RegKind_COP3 = 512, /// COP3
484 /// Potentially any (e.g. $1)
485 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
486 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
487 RegKind_CCR | RegKind_HWRegs | RegKind_COP3
492 k_Immediate, /// An immediate (possibly involving symbol references)
493 k_Memory, /// Base + Offset Memory Address
494 k_PhysRegister, /// A physical register from the Mips namespace
495 k_RegisterIndex, /// A register index in one or more RegKind.
496 k_Token, /// A simple token
497 k_RegList, /// A physical register list
498 k_RegPair /// A pair of physical register
502 MipsOperand(KindTy K, MipsAsmParser &Parser)
503 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
506 /// For diagnostics, and checking the assembler temporary
507 MipsAsmParser &AsmParser;
515 unsigned Num; /// Register Number
519 unsigned Index; /// Index into the register class
520 RegKind Kind; /// Bitfield of the kinds it could possibly be
521 const MCRegisterInfo *RegInfo;
534 SmallVector<unsigned, 10> *List;
539 struct PhysRegOp PhysReg;
540 struct RegIdxOp RegIdx;
543 struct RegListOp RegList;
546 SMLoc StartLoc, EndLoc;
548 /// Internal constructor for register kinds
549 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
550 const MCRegisterInfo *RegInfo,
552 MipsAsmParser &Parser) {
553 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
554 Op->RegIdx.Index = Index;
555 Op->RegIdx.RegInfo = RegInfo;
556 Op->RegIdx.Kind = RegKind;
563 /// Coerce the register to GPR32 and return the real register for the current
565 unsigned getGPR32Reg() const {
566 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
567 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
568 unsigned ClassID = Mips::GPR32RegClassID;
569 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
572 /// Coerce the register to GPR32 and return the real register for the current
574 unsigned getGPRMM16Reg() const {
575 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
576 unsigned ClassID = Mips::GPR32RegClassID;
577 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
580 /// Coerce the register to GPR64 and return the real register for the current
582 unsigned getGPR64Reg() const {
583 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
584 unsigned ClassID = Mips::GPR64RegClassID;
585 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
589 /// Coerce the register to AFGR64 and return the real register for the current
591 unsigned getAFGR64Reg() const {
592 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
593 if (RegIdx.Index % 2 != 0)
594 AsmParser.Warning(StartLoc, "Float register should be even.");
595 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
596 .getRegister(RegIdx.Index / 2);
599 /// Coerce the register to FGR64 and return the real register for the current
601 unsigned getFGR64Reg() const {
602 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
603 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
604 .getRegister(RegIdx.Index);
607 /// Coerce the register to FGR32 and return the real register for the current
609 unsigned getFGR32Reg() const {
610 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
611 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
612 .getRegister(RegIdx.Index);
615 /// Coerce the register to FGRH32 and return the real register for the current
617 unsigned getFGRH32Reg() const {
618 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
619 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
620 .getRegister(RegIdx.Index);
623 /// Coerce the register to FCC and return the real register for the current
625 unsigned getFCCReg() const {
626 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
627 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
628 .getRegister(RegIdx.Index);
631 /// Coerce the register to MSA128 and return the real register for the current
633 unsigned getMSA128Reg() const {
634 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
635 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
637 unsigned ClassID = Mips::MSA128BRegClassID;
638 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
641 /// Coerce the register to MSACtrl and return the real register for the
643 unsigned getMSACtrlReg() const {
644 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
645 unsigned ClassID = Mips::MSACtrlRegClassID;
646 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
649 /// Coerce the register to COP2 and return the real register for the
651 unsigned getCOP2Reg() const {
652 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
653 unsigned ClassID = Mips::COP2RegClassID;
654 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
657 /// Coerce the register to COP3 and return the real register for the
659 unsigned getCOP3Reg() const {
660 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
661 unsigned ClassID = Mips::COP3RegClassID;
662 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
665 /// Coerce the register to ACC64DSP and return the real register for the
667 unsigned getACC64DSPReg() const {
668 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
669 unsigned ClassID = Mips::ACC64DSPRegClassID;
670 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
673 /// Coerce the register to HI32DSP and return the real register for the
675 unsigned getHI32DSPReg() const {
676 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
677 unsigned ClassID = Mips::HI32DSPRegClassID;
678 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
681 /// Coerce the register to LO32DSP and return the real register for the
683 unsigned getLO32DSPReg() const {
684 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
685 unsigned ClassID = Mips::LO32DSPRegClassID;
686 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
689 /// Coerce the register to CCR and return the real register for the
691 unsigned getCCRReg() const {
692 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
693 unsigned ClassID = Mips::CCRRegClassID;
694 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
697 /// Coerce the register to HWRegs and return the real register for the
699 unsigned getHWRegsReg() const {
700 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
701 unsigned ClassID = Mips::HWRegsRegClassID;
702 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
706 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
707 // Add as immediate when possible. Null MCExpr = 0.
709 Inst.addOperand(MCOperand::createImm(0));
710 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
711 Inst.addOperand(MCOperand::createImm(CE->getValue()));
713 Inst.addOperand(MCOperand::createExpr(Expr));
716 void addRegOperands(MCInst &Inst, unsigned N) const {
717 llvm_unreachable("Use a custom parser instead");
720 /// Render the operand to an MCInst as a GPR32
721 /// Asserts if the wrong number of operands are requested, or the operand
722 /// is not a k_RegisterIndex compatible with RegKind_GPR
723 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
724 assert(N == 1 && "Invalid number of operands!");
725 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
728 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
729 assert(N == 1 && "Invalid number of operands!");
730 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
733 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
734 assert(N == 1 && "Invalid number of operands!");
735 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
738 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
739 assert(N == 1 && "Invalid number of operands!");
740 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
743 /// Render the operand to an MCInst as a GPR64
744 /// Asserts if the wrong number of operands are requested, or the operand
745 /// is not a k_RegisterIndex compatible with RegKind_GPR
746 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
747 assert(N == 1 && "Invalid number of operands!");
748 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
751 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
752 assert(N == 1 && "Invalid number of operands!");
753 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
756 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
757 assert(N == 1 && "Invalid number of operands!");
758 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
761 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
762 assert(N == 1 && "Invalid number of operands!");
763 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
764 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
765 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
766 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
770 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
771 assert(N == 1 && "Invalid number of operands!");
772 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
775 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
776 assert(N == 1 && "Invalid number of operands!");
777 Inst.addOperand(MCOperand::createReg(getFCCReg()));
780 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
781 assert(N == 1 && "Invalid number of operands!");
782 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
785 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
786 assert(N == 1 && "Invalid number of operands!");
787 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
790 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
791 assert(N == 1 && "Invalid number of operands!");
792 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
795 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
796 assert(N == 1 && "Invalid number of operands!");
797 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
800 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
801 assert(N == 1 && "Invalid number of operands!");
802 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
805 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
806 assert(N == 1 && "Invalid number of operands!");
807 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
810 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
811 assert(N == 1 && "Invalid number of operands!");
812 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
815 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
816 assert(N == 1 && "Invalid number of operands!");
817 Inst.addOperand(MCOperand::createReg(getCCRReg()));
820 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
821 assert(N == 1 && "Invalid number of operands!");
822 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
825 void addImmOperands(MCInst &Inst, unsigned N) const {
826 assert(N == 1 && "Invalid number of operands!");
827 const MCExpr *Expr = getImm();
831 void addMemOperands(MCInst &Inst, unsigned N) const {
832 assert(N == 2 && "Invalid number of operands!");
834 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPR32Reg()));
836 const MCExpr *Expr = getMemOff();
840 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
841 assert(N == 2 && "Invalid number of operands!");
843 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
845 const MCExpr *Expr = getMemOff();
849 void addRegListOperands(MCInst &Inst, unsigned N) const {
850 assert(N == 1 && "Invalid number of operands!");
852 for (auto RegNo : getRegList())
853 Inst.addOperand(MCOperand::createReg(RegNo));
856 void addRegPairOperands(MCInst &Inst, unsigned N) const {
857 assert(N == 2 && "Invalid number of operands!");
858 unsigned RegNo = getRegPair();
859 Inst.addOperand(MCOperand::createReg(RegNo++));
860 Inst.addOperand(MCOperand::createReg(RegNo));
863 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
864 assert(N == 2 && "Invalid number of operands!");
865 for (auto RegNo : getRegList())
866 Inst.addOperand(MCOperand::createReg(RegNo));
869 bool isReg() const override {
870 // As a special case until we sort out the definition of div/divu, pretend
871 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
872 if (isGPRAsmReg() && RegIdx.Index == 0)
875 return Kind == k_PhysRegister;
877 bool isRegIdx() const { return Kind == k_RegisterIndex; }
878 bool isImm() const override { return Kind == k_Immediate; }
879 bool isConstantImm() const {
880 return isImm() && dyn_cast<MCConstantExpr>(getImm());
882 bool isToken() const override {
883 // Note: It's not possible to pretend that other operand kinds are tokens.
884 // The matcher emitter checks tokens first.
885 return Kind == k_Token;
887 bool isMem() const override { return Kind == k_Memory; }
888 bool isConstantMemOff() const {
889 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
891 template <unsigned Bits> bool isMemWithSimmOffset() const {
892 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
894 bool isMemWithGRPMM16Base() const {
895 return isMem() && getMemBase()->isMM16AsmReg();
897 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
898 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
899 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
901 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
902 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
903 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
904 && (getMemBase()->getGPR32Reg() == Mips::SP);
906 bool isRegList16() const {
910 int Size = RegList.List->size();
911 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
912 RegList.List->back() != Mips::RA)
915 int PrevReg = *RegList.List->begin();
916 for (int i = 1; i < Size - 1; i++) {
917 int Reg = (*(RegList.List))[i];
918 if ( Reg != PrevReg + 1)
925 bool isInvNum() const { return Kind == k_Immediate; }
926 bool isLSAImm() const {
927 if (!isConstantImm())
929 int64_t Val = getConstantImm();
930 return 1 <= Val && Val <= 4;
932 bool isRegList() const { return Kind == k_RegList; }
933 bool isMovePRegPair() const {
934 if (Kind != k_RegList || RegList.List->size() != 2)
937 unsigned R0 = RegList.List->front();
938 unsigned R1 = RegList.List->back();
940 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
941 (R0 == Mips::A1 && R1 == Mips::A3) ||
942 (R0 == Mips::A2 && R1 == Mips::A3) ||
943 (R0 == Mips::A0 && R1 == Mips::S5) ||
944 (R0 == Mips::A0 && R1 == Mips::S6) ||
945 (R0 == Mips::A0 && R1 == Mips::A1) ||
946 (R0 == Mips::A0 && R1 == Mips::A2) ||
947 (R0 == Mips::A0 && R1 == Mips::A3))
953 StringRef getToken() const {
954 assert(Kind == k_Token && "Invalid access!");
955 return StringRef(Tok.Data, Tok.Length);
957 bool isRegPair() const { return Kind == k_RegPair; }
959 unsigned getReg() const override {
960 // As a special case until we sort out the definition of div/divu, pretend
961 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
962 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
963 RegIdx.Kind & RegKind_GPR)
964 return getGPR32Reg(); // FIXME: GPR64 too
966 assert(Kind == k_PhysRegister && "Invalid access!");
970 const MCExpr *getImm() const {
971 assert((Kind == k_Immediate) && "Invalid access!");
975 int64_t getConstantImm() const {
976 const MCExpr *Val = getImm();
977 return static_cast<const MCConstantExpr *>(Val)->getValue();
980 MipsOperand *getMemBase() const {
981 assert((Kind == k_Memory) && "Invalid access!");
985 const MCExpr *getMemOff() const {
986 assert((Kind == k_Memory) && "Invalid access!");
990 int64_t getConstantMemOff() const {
991 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
994 const SmallVectorImpl<unsigned> &getRegList() const {
995 assert((Kind == k_RegList) && "Invalid access!");
996 return *(RegList.List);
999 unsigned getRegPair() const {
1000 assert((Kind == k_RegPair) && "Invalid access!");
1001 return RegIdx.Index;
1004 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1005 MipsAsmParser &Parser) {
1006 auto Op = make_unique<MipsOperand>(k_Token, Parser);
1007 Op->Tok.Data = Str.data();
1008 Op->Tok.Length = Str.size();
1014 /// Create a numeric register (e.g. $1). The exact register remains
1015 /// unresolved until an instruction successfully matches
1016 static std::unique_ptr<MipsOperand>
1017 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1018 SMLoc E, MipsAsmParser &Parser) {
1019 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1020 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1023 /// Create a register that is definitely a GPR.
1024 /// This is typically only used for named registers such as $gp.
1025 static std::unique_ptr<MipsOperand>
1026 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1027 MipsAsmParser &Parser) {
1028 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1031 /// Create a register that is definitely a FGR.
1032 /// This is typically only used for named registers such as $f0.
1033 static std::unique_ptr<MipsOperand>
1034 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1035 MipsAsmParser &Parser) {
1036 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1039 /// Create a register that is definitely a HWReg.
1040 /// This is typically only used for named registers such as $hwr_cpunum.
1041 static std::unique_ptr<MipsOperand>
1042 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1043 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1044 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1047 /// Create a register that is definitely an FCC.
1048 /// This is typically only used for named registers such as $fcc0.
1049 static std::unique_ptr<MipsOperand>
1050 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1051 MipsAsmParser &Parser) {
1052 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1055 /// Create a register that is definitely an ACC.
1056 /// This is typically only used for named registers such as $ac0.
1057 static std::unique_ptr<MipsOperand>
1058 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1059 MipsAsmParser &Parser) {
1060 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1063 /// Create a register that is definitely an MSA128.
1064 /// This is typically only used for named registers such as $w0.
1065 static std::unique_ptr<MipsOperand>
1066 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1067 SMLoc E, MipsAsmParser &Parser) {
1068 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1071 /// Create a register that is definitely an MSACtrl.
1072 /// This is typically only used for named registers such as $msaaccess.
1073 static std::unique_ptr<MipsOperand>
1074 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1075 SMLoc E, MipsAsmParser &Parser) {
1076 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1079 static std::unique_ptr<MipsOperand>
1080 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1081 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1088 static std::unique_ptr<MipsOperand>
1089 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1090 SMLoc E, MipsAsmParser &Parser) {
1091 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1092 Op->Mem.Base = Base.release();
1099 static std::unique_ptr<MipsOperand>
1100 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1101 MipsAsmParser &Parser) {
1102 assert (Regs.size() > 0 && "Empty list not allowed");
1104 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1105 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1106 Op->StartLoc = StartLoc;
1107 Op->EndLoc = EndLoc;
1111 static std::unique_ptr<MipsOperand>
1112 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1113 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1114 Op->RegIdx.Index = RegNo;
1120 bool isGPRAsmReg() const {
1121 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1123 bool isMM16AsmReg() const {
1124 if (!(isRegIdx() && RegIdx.Kind))
1126 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1127 || RegIdx.Index == 16 || RegIdx.Index == 17);
1129 bool isMM16AsmRegZero() const {
1130 if (!(isRegIdx() && RegIdx.Kind))
1132 return (RegIdx.Index == 0 ||
1133 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1134 RegIdx.Index == 17);
1136 bool isMM16AsmRegMoveP() const {
1137 if (!(isRegIdx() && RegIdx.Kind))
1139 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1140 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1142 bool isFGRAsmReg() const {
1143 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1144 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1146 bool isHWRegsAsmReg() const {
1147 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1149 bool isCCRAsmReg() const {
1150 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1152 bool isFCCAsmReg() const {
1153 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1155 if (!AsmParser.hasEightFccRegisters())
1156 return RegIdx.Index == 0;
1157 return RegIdx.Index <= 7;
1159 bool isACCAsmReg() const {
1160 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1162 bool isCOP2AsmReg() const {
1163 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1165 bool isCOP3AsmReg() const {
1166 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1168 bool isMSA128AsmReg() const {
1169 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1171 bool isMSACtrlAsmReg() const {
1172 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1175 /// getStartLoc - Get the location of the first token of this operand.
1176 SMLoc getStartLoc() const override { return StartLoc; }
1177 /// getEndLoc - Get the location of the last token of this operand.
1178 SMLoc getEndLoc() const override { return EndLoc; }
1180 virtual ~MipsOperand() {
1188 delete RegList.List;
1189 case k_PhysRegister:
1190 case k_RegisterIndex:
1197 void print(raw_ostream &OS) const override {
1206 Mem.Base->print(OS);
1211 case k_PhysRegister:
1212 OS << "PhysReg<" << PhysReg.Num << ">";
1214 case k_RegisterIndex:
1215 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1222 for (auto Reg : (*RegList.List))
1227 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1231 }; // class MipsOperand
1235 extern const MCInstrDesc MipsInsts[];
1237 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1238 return MipsInsts[Opcode];
1241 static bool hasShortDelaySlot(unsigned Opcode) {
1244 case Mips::JALRS_MM:
1245 case Mips::JALRS16_MM:
1246 case Mips::BGEZALS_MM:
1247 case Mips::BLTZALS_MM:
1254 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1255 SmallVectorImpl<MCInst> &Instructions) {
1256 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1260 if (MCID.isBranch() || MCID.isCall()) {
1261 const unsigned Opcode = Inst.getOpcode();
1271 assert(hasCnMips() && "instruction only valid for octeon cpus");
1278 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1279 Offset = Inst.getOperand(2);
1280 if (!Offset.isImm())
1281 break; // We'll deal with this situation later on when applying fixups.
1282 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1283 return Error(IDLoc, "branch target out of range");
1284 if (OffsetToAlignment(Offset.getImm(),
1285 1LL << (inMicroMipsMode() ? 1 : 2)))
1286 return Error(IDLoc, "branch to misaligned address");
1300 case Mips::BGEZAL_MM:
1301 case Mips::BLTZAL_MM:
1304 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1305 Offset = Inst.getOperand(1);
1306 if (!Offset.isImm())
1307 break; // We'll deal with this situation later on when applying fixups.
1308 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1309 return Error(IDLoc, "branch target out of range");
1310 if (OffsetToAlignment(Offset.getImm(),
1311 1LL << (inMicroMipsMode() ? 1 : 2)))
1312 return Error(IDLoc, "branch to misaligned address");
1314 case Mips::BEQZ16_MM:
1315 case Mips::BNEZ16_MM:
1316 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1317 Offset = Inst.getOperand(1);
1318 if (!Offset.isImm())
1319 break; // We'll deal with this situation later on when applying fixups.
1320 if (!isIntN(8, Offset.getImm()))
1321 return Error(IDLoc, "branch target out of range");
1322 if (OffsetToAlignment(Offset.getImm(), 2LL))
1323 return Error(IDLoc, "branch to misaligned address");
1328 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1329 // We still accept it but it is a normal nop.
1330 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1331 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1332 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1337 const unsigned Opcode = Inst.getOpcode();
1349 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1350 // The offset is handled above
1351 Opnd = Inst.getOperand(1);
1353 return Error(IDLoc, "expected immediate operand kind");
1354 Imm = Opnd.getImm();
1355 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1356 Opcode == Mips::BBIT1 ? 63 : 31))
1357 return Error(IDLoc, "immediate operand value out of range");
1359 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1361 Inst.getOperand(1).setImm(Imm - 32);
1369 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1371 Opnd = Inst.getOperand(3);
1373 return Error(IDLoc, "expected immediate operand kind");
1374 Imm = Opnd.getImm();
1375 if (Imm < 0 || Imm > 31)
1376 return Error(IDLoc, "immediate operand value out of range");
1378 Opnd = Inst.getOperand(2);
1380 return Error(IDLoc, "expected immediate operand kind");
1381 Imm = Opnd.getImm();
1382 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1383 Opcode == Mips::EXTS ? 63 : 31))
1384 return Error(IDLoc, "immediate operand value out of range");
1386 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1387 Inst.getOperand(2).setImm(Imm - 32);
1393 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1394 Opnd = Inst.getOperand(2);
1396 return Error(IDLoc, "expected immediate operand kind");
1397 Imm = Opnd.getImm();
1398 if (!isInt<10>(Imm))
1399 return Error(IDLoc, "immediate operand value out of range");
1404 if (MCID.mayLoad() || MCID.mayStore()) {
1405 // Check the offset of memory operand, if it is a symbol
1406 // reference or immediate we may have to expand instructions.
1407 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1408 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1409 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1410 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1411 MCOperand &Op = Inst.getOperand(i);
1413 int MemOffset = Op.getImm();
1414 if (MemOffset < -32768 || MemOffset > 32767) {
1415 // Offset can't exceed 16bit value.
1416 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1419 } else if (Op.isExpr()) {
1420 const MCExpr *Expr = Op.getExpr();
1421 if (Expr->getKind() == MCExpr::SymbolRef) {
1422 const MCSymbolRefExpr *SR =
1423 static_cast<const MCSymbolRefExpr *>(Expr);
1424 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1426 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1429 } else if (!isEvaluated(Expr)) {
1430 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1438 if (inMicroMipsMode()) {
1439 if (MCID.mayLoad()) {
1440 // Try to create 16-bit GP relative load instruction.
1441 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1442 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1443 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1444 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1445 MCOperand &Op = Inst.getOperand(i);
1447 int MemOffset = Op.getImm();
1448 MCOperand &DstReg = Inst.getOperand(0);
1449 MCOperand &BaseReg = Inst.getOperand(1);
1450 if (isIntN(9, MemOffset) && (MemOffset % 4 == 0) &&
1451 getContext().getRegisterInfo()->getRegClass(
1452 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1453 BaseReg.getReg() == Mips::GP) {
1455 TmpInst.setLoc(IDLoc);
1456 TmpInst.setOpcode(Mips::LWGP_MM);
1457 TmpInst.addOperand(MCOperand::createReg(DstReg.getReg()));
1458 TmpInst.addOperand(MCOperand::createReg(Mips::GP));
1459 TmpInst.addOperand(MCOperand::createImm(MemOffset));
1460 Instructions.push_back(TmpInst);
1468 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1473 switch (Inst.getOpcode()) {
1476 case Mips::ADDIUS5_MM:
1477 Opnd = Inst.getOperand(2);
1479 return Error(IDLoc, "expected immediate operand kind");
1480 Imm = Opnd.getImm();
1481 if (Imm < -8 || Imm > 7)
1482 return Error(IDLoc, "immediate operand value out of range");
1484 case Mips::ADDIUSP_MM:
1485 Opnd = Inst.getOperand(0);
1487 return Error(IDLoc, "expected immediate operand kind");
1488 Imm = Opnd.getImm();
1489 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1491 return Error(IDLoc, "immediate operand value out of range");
1493 case Mips::SLL16_MM:
1494 case Mips::SRL16_MM:
1495 Opnd = Inst.getOperand(2);
1497 return Error(IDLoc, "expected immediate operand kind");
1498 Imm = Opnd.getImm();
1499 if (Imm < 1 || Imm > 8)
1500 return Error(IDLoc, "immediate operand value out of range");
1503 Opnd = Inst.getOperand(1);
1505 return Error(IDLoc, "expected immediate operand kind");
1506 Imm = Opnd.getImm();
1507 if (Imm < -1 || Imm > 126)
1508 return Error(IDLoc, "immediate operand value out of range");
1510 case Mips::ADDIUR2_MM:
1511 Opnd = Inst.getOperand(2);
1513 return Error(IDLoc, "expected immediate operand kind");
1514 Imm = Opnd.getImm();
1515 if (!(Imm == 1 || Imm == -1 ||
1516 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1517 return Error(IDLoc, "immediate operand value out of range");
1519 case Mips::ADDIUR1SP_MM:
1520 Opnd = Inst.getOperand(1);
1522 return Error(IDLoc, "expected immediate operand kind");
1523 Imm = Opnd.getImm();
1524 if (OffsetToAlignment(Imm, 4LL))
1525 return Error(IDLoc, "misaligned immediate operand value");
1526 if (Imm < 0 || Imm > 255)
1527 return Error(IDLoc, "immediate operand value out of range");
1529 case Mips::ANDI16_MM:
1530 Opnd = Inst.getOperand(2);
1532 return Error(IDLoc, "expected immediate operand kind");
1533 Imm = Opnd.getImm();
1534 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1535 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1536 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1537 return Error(IDLoc, "immediate operand value out of range");
1539 case Mips::LBU16_MM:
1540 Opnd = Inst.getOperand(2);
1542 return Error(IDLoc, "expected immediate operand kind");
1543 Imm = Opnd.getImm();
1544 if (Imm < -1 || Imm > 14)
1545 return Error(IDLoc, "immediate operand value out of range");
1548 Opnd = Inst.getOperand(2);
1550 return Error(IDLoc, "expected immediate operand kind");
1551 Imm = Opnd.getImm();
1552 if (Imm < 0 || Imm > 15)
1553 return Error(IDLoc, "immediate operand value out of range");
1555 case Mips::LHU16_MM:
1557 Opnd = Inst.getOperand(2);
1559 return Error(IDLoc, "expected immediate operand kind");
1560 Imm = Opnd.getImm();
1561 if (Imm < 0 || Imm > 30 || (Imm % 2 != 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 (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1571 return Error(IDLoc, "immediate operand value out of range");
1575 Opnd = Inst.getOperand(2);
1577 return Error(IDLoc, "expected immediate operand kind");
1578 Imm = Opnd.getImm();
1579 if (!isUInt<5>(Imm))
1580 return Error(IDLoc, "immediate operand value out of range");
1582 case Mips::ADDIUPC_MM:
1583 MCOperand Opnd = Inst.getOperand(1);
1585 return Error(IDLoc, "expected immediate operand kind");
1586 int Imm = Opnd.getImm();
1587 if ((Imm % 4 != 0) || !isIntN(25, Imm))
1588 return Error(IDLoc, "immediate operand value out of range");
1593 if (needsExpansion(Inst)) {
1594 if (expandInstruction(Inst, IDLoc, Instructions))
1597 Instructions.push_back(Inst);
1599 // If this instruction has a delay slot and .set reorder is active,
1600 // emit a NOP after it.
1601 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1602 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1607 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1609 switch (Inst.getOpcode()) {
1610 case Mips::LoadImm32:
1611 case Mips::LoadImm64:
1612 case Mips::LoadAddrImm32:
1613 case Mips::LoadAddrReg32:
1614 case Mips::B_MM_Pseudo:
1617 case Mips::JalOneReg:
1618 case Mips::JalTwoReg:
1625 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1626 SmallVectorImpl<MCInst> &Instructions) {
1627 switch (Inst.getOpcode()) {
1628 default: llvm_unreachable("unimplemented expansion");
1629 case Mips::LoadImm32:
1630 return expandLoadImm(Inst, true, IDLoc, Instructions);
1631 case Mips::LoadImm64:
1632 return expandLoadImm(Inst, false, IDLoc, Instructions);
1633 case Mips::LoadAddrImm32:
1634 return expandLoadAddressImm(Inst, true, IDLoc, Instructions);
1635 case Mips::LoadAddrReg32:
1636 return expandLoadAddressReg(Inst, true, IDLoc, Instructions);
1637 case Mips::B_MM_Pseudo:
1638 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1641 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
1642 case Mips::JalOneReg:
1643 case Mips::JalTwoReg:
1644 return expandJalWithRegs(Inst, IDLoc, Instructions);
1649 template <unsigned ShiftAmount>
1650 void createLShiftOri(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1651 SmallVectorImpl<MCInst> &Instructions) {
1653 if (ShiftAmount >= 32) {
1654 tmpInst.setOpcode(Mips::DSLL32);
1655 tmpInst.addOperand(MCOperand::createReg(RegNo));
1656 tmpInst.addOperand(MCOperand::createReg(RegNo));
1657 tmpInst.addOperand(MCOperand::createImm(ShiftAmount - 32));
1658 tmpInst.setLoc(IDLoc);
1659 Instructions.push_back(tmpInst);
1661 } else if (ShiftAmount > 0) {
1662 tmpInst.setOpcode(Mips::DSLL);
1663 tmpInst.addOperand(MCOperand::createReg(RegNo));
1664 tmpInst.addOperand(MCOperand::createReg(RegNo));
1665 tmpInst.addOperand(MCOperand::createImm(ShiftAmount));
1666 tmpInst.setLoc(IDLoc);
1667 Instructions.push_back(tmpInst);
1670 // There's no need for an ORi if the immediate is 0.
1671 if (Operand.isImm() && Operand.getImm() == 0)
1674 tmpInst.setOpcode(Mips::ORi);
1675 tmpInst.addOperand(MCOperand::createReg(RegNo));
1676 tmpInst.addOperand(MCOperand::createReg(RegNo));
1677 tmpInst.addOperand(Operand);
1678 tmpInst.setLoc(IDLoc);
1679 Instructions.push_back(tmpInst);
1682 template <unsigned ShiftAmount>
1683 void createLShiftOri(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1684 SmallVectorImpl<MCInst> &Instructions) {
1685 createLShiftOri<ShiftAmount>(MCOperand::createImm(Value), RegNo, IDLoc,
1690 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
1691 SmallVectorImpl<MCInst> &Instructions) {
1692 // Create a JALR instruction which is going to replace the pseudo-JAL.
1694 JalrInst.setLoc(IDLoc);
1695 const MCOperand FirstRegOp = Inst.getOperand(0);
1696 const unsigned Opcode = Inst.getOpcode();
1698 if (Opcode == Mips::JalOneReg) {
1699 // jal $rs => jalr $rs
1700 if (inMicroMipsMode()) {
1701 JalrInst.setOpcode(Mips::JALR16_MM);
1702 JalrInst.addOperand(FirstRegOp);
1704 JalrInst.setOpcode(Mips::JALR);
1705 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1706 JalrInst.addOperand(FirstRegOp);
1708 } else if (Opcode == Mips::JalTwoReg) {
1709 // jal $rd, $rs => jalr $rd, $rs
1710 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1711 JalrInst.addOperand(FirstRegOp);
1712 const MCOperand SecondRegOp = Inst.getOperand(1);
1713 JalrInst.addOperand(SecondRegOp);
1715 Instructions.push_back(JalrInst);
1717 // If .set reorder is active, emit a NOP after it.
1718 if (AssemblerOptions.back()->isReorder()) {
1719 // This is a 32-bit NOP because these 2 pseudo-instructions
1720 // do not have a short delay slot.
1722 NopInst.setOpcode(Mips::SLL);
1723 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
1724 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
1725 NopInst.addOperand(MCOperand::createImm(0));
1726 Instructions.push_back(NopInst);
1732 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
1733 unsigned SrcReg, bool Is32BitImm, SMLoc IDLoc,
1734 SmallVectorImpl<MCInst> &Instructions) {
1735 if (!Is32BitImm && !isGP64bit()) {
1736 Error(IDLoc, "instruction requires a 64-bit architecture");
1740 bool UseSrcReg = false;
1741 if (SrcReg != Mips::NoRegister)
1746 tmpInst.setLoc(IDLoc);
1747 // FIXME: gas has a special case for values that are 000...1111, which
1748 // becomes a li -1 and then a dsrl
1749 if (0 <= ImmValue && ImmValue <= 65535) {
1750 // For unsigned and positive signed 16-bit values (0 <= j <= 65535):
1751 // li d,j => ori d,$zero,j
1753 SrcReg = isGP64bit() ? Mips::ZERO_64 : Mips::ZERO;
1754 tmpInst.setOpcode(Mips::ORi);
1755 tmpInst.addOperand(MCOperand::createReg(DstReg));
1756 tmpInst.addOperand(MCOperand::createReg(SrcReg));
1757 tmpInst.addOperand(MCOperand::createImm(ImmValue));
1758 Instructions.push_back(tmpInst);
1759 } else if (ImmValue < 0 && ImmValue >= -32768) {
1760 // For negative signed 16-bit values (-32768 <= j < 0):
1761 // li d,j => addiu d,$zero,j
1763 SrcReg = Mips::ZERO;
1764 tmpInst.setOpcode(Mips::ADDiu);
1765 tmpInst.addOperand(MCOperand::createReg(DstReg));
1766 tmpInst.addOperand(MCOperand::createReg(SrcReg));
1767 tmpInst.addOperand(MCOperand::createImm(ImmValue));
1768 Instructions.push_back(tmpInst);
1769 } else if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
1770 warnIfNoMacro(IDLoc);
1772 // For all other values which are representable as a 32-bit integer:
1773 // li d,j => lui d,hi16(j)
1775 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1776 uint16_t Bits15To0 = ImmValue & 0xffff;
1778 if (!Is32BitImm && !isInt<32>(ImmValue)) {
1779 // For DLI, expand to an ORi instead of a LUi to avoid sign-extending the
1781 tmpInst.setOpcode(Mips::ORi);
1782 tmpInst.addOperand(MCOperand::createReg(DstReg));
1783 tmpInst.addOperand(MCOperand::createReg(Mips::ZERO));
1784 tmpInst.addOperand(MCOperand::createImm(Bits31To16));
1785 tmpInst.setLoc(IDLoc);
1786 Instructions.push_back(tmpInst);
1787 // Move the value to the upper 16 bits by doing a 16-bit left shift.
1788 createLShiftOri<16>(0, DstReg, IDLoc, Instructions);
1790 tmpInst.setOpcode(Mips::LUi);
1791 tmpInst.addOperand(MCOperand::createReg(DstReg));
1792 tmpInst.addOperand(MCOperand::createImm(Bits31To16));
1793 Instructions.push_back(tmpInst);
1795 createLShiftOri<0>(Bits15To0, DstReg, IDLoc, Instructions);
1798 createAddu(DstReg, DstReg, SrcReg, Instructions);
1800 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1802 Error(IDLoc, "instruction requires a 32-bit immediate");
1805 warnIfNoMacro(IDLoc);
1807 // <------- lo32 ------>
1808 // <------- hi32 ------>
1809 // <- hi16 -> <- lo16 ->
1810 // _________________________________
1812 // | 16-bits | 16-bits | 16-bits |
1813 // |__________|__________|__________|
1815 // For any 64-bit value that is representable as a 48-bit integer:
1816 // li d,j => lui d,hi16(j)
1817 // ori d,d,hi16(lo32(j))
1819 // ori d,d,lo16(lo32(j))
1820 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1821 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1822 uint16_t Bits15To0 = ImmValue & 0xffff;
1824 tmpInst.setOpcode(Mips::LUi);
1825 tmpInst.addOperand(MCOperand::createReg(DstReg));
1826 tmpInst.addOperand(MCOperand::createImm(Bits47To32));
1827 Instructions.push_back(tmpInst);
1828 createLShiftOri<0>(Bits31To16, DstReg, IDLoc, Instructions);
1829 createLShiftOri<16>(Bits15To0, DstReg, IDLoc, Instructions);
1832 createAddu(DstReg, DstReg, SrcReg, Instructions);
1836 Error(IDLoc, "instruction requires a 32-bit immediate");
1839 warnIfNoMacro(IDLoc);
1841 // <------- hi32 ------> <------- lo32 ------>
1842 // <- hi16 -> <- lo16 ->
1843 // ___________________________________________
1845 // | 16-bits | 16-bits | 16-bits | 16-bits |
1846 // |__________|__________|__________|__________|
1848 // For all other values which are representable as a 64-bit integer:
1849 // li d,j => lui d,hi16(j)
1850 // ori d,d,lo16(hi32(j))
1852 // ori d,d,hi16(lo32(j))
1854 // ori d,d,lo16(lo32(j))
1855 uint16_t Bits63To48 = (ImmValue >> 48) & 0xffff;
1856 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1857 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1858 uint16_t Bits15To0 = ImmValue & 0xffff;
1860 tmpInst.setOpcode(Mips::LUi);
1861 tmpInst.addOperand(MCOperand::createReg(DstReg));
1862 tmpInst.addOperand(MCOperand::createImm(Bits63To48));
1863 Instructions.push_back(tmpInst);
1864 createLShiftOri<0>(Bits47To32, DstReg, IDLoc, Instructions);
1866 // When Bits31To16 is 0, do a left shift of 32 bits instead of doing
1867 // two left shifts of 16 bits.
1868 if (Bits31To16 == 0) {
1869 createLShiftOri<32>(Bits15To0, DstReg, IDLoc, Instructions);
1871 createLShiftOri<16>(Bits31To16, DstReg, IDLoc, Instructions);
1872 createLShiftOri<16>(Bits15To0, DstReg, IDLoc, Instructions);
1876 createAddu(DstReg, DstReg, SrcReg, Instructions);
1881 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1882 SmallVectorImpl<MCInst> &Instructions) {
1883 const MCOperand &ImmOp = Inst.getOperand(1);
1884 assert(ImmOp.isImm() && "expected immediate operand kind");
1885 const MCOperand &DstRegOp = Inst.getOperand(0);
1886 assert(DstRegOp.isReg() && "expected register operand kind");
1888 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
1889 Is32BitImm, IDLoc, Instructions))
1896 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1897 SmallVectorImpl<MCInst> &Instructions) {
1898 const MCOperand &DstRegOp = Inst.getOperand(0);
1899 assert(DstRegOp.isReg() && "expected register operand kind");
1901 const MCOperand &ImmOp = Inst.getOperand(2);
1902 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1903 "expected immediate operand kind");
1904 if (!ImmOp.isImm()) {
1905 expandLoadAddressSym(DstRegOp, ImmOp, Is32BitImm, IDLoc, Instructions);
1908 const MCOperand &SrcRegOp = Inst.getOperand(1);
1909 assert(SrcRegOp.isReg() && "expected register operand kind");
1911 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), SrcRegOp.getReg(),
1912 Is32BitImm, IDLoc, Instructions))
1919 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1920 SmallVectorImpl<MCInst> &Instructions) {
1921 const MCOperand &DstRegOp = Inst.getOperand(0);
1922 assert(DstRegOp.isReg() && "expected register operand kind");
1924 const MCOperand &ImmOp = Inst.getOperand(1);
1925 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1926 "expected immediate operand kind");
1927 if (!ImmOp.isImm()) {
1928 expandLoadAddressSym(DstRegOp, ImmOp, Is32BitImm, IDLoc, Instructions);
1932 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
1933 Is32BitImm, IDLoc, Instructions))
1939 void MipsAsmParser::expandLoadAddressSym(
1940 const MCOperand &DstRegOp, const MCOperand &SymOp, bool Is32BitSym,
1941 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1942 warnIfNoMacro(IDLoc);
1944 if (Is32BitSym && isABI_N64())
1945 Warning(IDLoc, "instruction loads the 32-bit address of a 64-bit symbol");
1948 unsigned RegNo = DstRegOp.getReg();
1949 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
1950 const MCSymbolRefExpr *HiExpr =
1951 MCSymbolRefExpr::create(Symbol->getSymbol().getName(),
1952 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1953 const MCSymbolRefExpr *LoExpr =
1954 MCSymbolRefExpr::create(Symbol->getSymbol().getName(),
1955 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1957 // If it's a 64-bit architecture, expand to:
1958 // la d,sym => lui d,highest(sym)
1959 // ori d,d,higher(sym)
1961 // ori d,d,hi16(sym)
1963 // ori d,d,lo16(sym)
1964 const MCSymbolRefExpr *HighestExpr =
1965 MCSymbolRefExpr::create(Symbol->getSymbol().getName(),
1966 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1967 const MCSymbolRefExpr *HigherExpr =
1968 MCSymbolRefExpr::create(Symbol->getSymbol().getName(),
1969 MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1971 tmpInst.setOpcode(Mips::LUi);
1972 tmpInst.addOperand(MCOperand::createReg(RegNo));
1973 tmpInst.addOperand(MCOperand::createExpr(HighestExpr));
1974 Instructions.push_back(tmpInst);
1976 createLShiftOri<0>(MCOperand::createExpr(HigherExpr), RegNo, SMLoc(),
1978 createLShiftOri<16>(MCOperand::createExpr(HiExpr), RegNo, SMLoc(),
1980 createLShiftOri<16>(MCOperand::createExpr(LoExpr), RegNo, SMLoc(),
1983 // Otherwise, expand to:
1984 // la d,sym => lui d,hi16(sym)
1985 // ori d,d,lo16(sym)
1986 tmpInst.setOpcode(Mips::LUi);
1987 tmpInst.addOperand(MCOperand::createReg(RegNo));
1988 tmpInst.addOperand(MCOperand::createExpr(HiExpr));
1989 Instructions.push_back(tmpInst);
1991 createLShiftOri<0>(MCOperand::createExpr(LoExpr), RegNo, SMLoc(),
1996 bool MipsAsmParser::expandUncondBranchMMPseudo(
1997 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1998 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
1999 "unexpected number of operands");
2001 MCOperand Offset = Inst.getOperand(0);
2002 if (Offset.isExpr()) {
2004 Inst.setOpcode(Mips::BEQ_MM);
2005 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2006 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2007 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2009 assert(Offset.isImm() && "expected immediate operand kind");
2010 if (isIntN(11, Offset.getImm())) {
2011 // If offset fits into 11 bits then this instruction becomes microMIPS
2012 // 16-bit unconditional branch instruction.
2013 Inst.setOpcode(Mips::B16_MM);
2015 if (!isIntN(17, Offset.getImm()))
2016 Error(IDLoc, "branch target out of range");
2017 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2018 Error(IDLoc, "branch to misaligned address");
2020 Inst.setOpcode(Mips::BEQ_MM);
2021 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2022 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2023 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2026 Instructions.push_back(Inst);
2028 // If .set reorder is active, emit a NOP after the branch instruction.
2029 if (AssemblerOptions.back()->isReorder())
2030 createNop(true, IDLoc, Instructions);
2035 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2036 SmallVectorImpl<MCInst> &Instructions,
2037 bool isLoad, bool isImmOpnd) {
2038 const MCSymbolRefExpr *SR;
2040 unsigned ImmOffset, HiOffset, LoOffset;
2041 const MCExpr *ExprOffset;
2043 // 1st operand is either the source or destination register.
2044 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2045 unsigned RegOpNum = Inst.getOperand(0).getReg();
2046 // 2nd operand is the base register.
2047 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2048 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2049 // 3rd operand is either an immediate or expression.
2051 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2052 ImmOffset = Inst.getOperand(2).getImm();
2053 LoOffset = ImmOffset & 0x0000ffff;
2054 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2055 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2056 if (LoOffset & 0x8000)
2059 ExprOffset = Inst.getOperand(2).getExpr();
2060 // All instructions will have the same location.
2061 TempInst.setLoc(IDLoc);
2062 // These are some of the types of expansions we perform here:
2063 // 1) lw $8, sym => lui $8, %hi(sym)
2064 // lw $8, %lo(sym)($8)
2065 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2067 // lw $8, %lo(offset)($9)
2068 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2070 // lw $8, %lo(offset)($at)
2071 // 4) sw $8, sym => lui $at, %hi(sym)
2072 // sw $8, %lo(sym)($at)
2073 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2075 // sw $8, %lo(offset)($at)
2076 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2077 // ldc1 $f0, %lo(sym)($at)
2079 // For load instructions we can use the destination register as a temporary
2080 // if base and dst are different (examples 1 and 2) and if the base register
2081 // is general purpose otherwise we must use $at (example 6) and error if it's
2082 // not available. For stores we must use $at (examples 4 and 5) because we
2083 // must not clobber the source register setting up the offset.
2084 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2085 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2086 unsigned RegClassIDOp0 =
2087 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2088 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2089 (RegClassIDOp0 == Mips::GPR64RegClassID);
2090 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2091 TmpRegNum = RegOpNum;
2093 // At this point we need AT to perform the expansions and we exit if it is
2095 TmpRegNum = getATReg(IDLoc);
2100 TempInst.setOpcode(Mips::LUi);
2101 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2103 TempInst.addOperand(MCOperand::createImm(HiOffset));
2105 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2106 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
2107 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::create(
2108 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
2110 TempInst.addOperand(MCOperand::createExpr(HiExpr));
2112 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2113 TempInst.addOperand(MCOperand::createExpr(HiExpr));
2116 // Add the instruction to the list.
2117 Instructions.push_back(TempInst);
2118 // Prepare TempInst for next instruction.
2120 // Add temp register to base.
2121 if (BaseRegNum != Mips::ZERO) {
2122 TempInst.setOpcode(Mips::ADDu);
2123 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2124 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2125 TempInst.addOperand(MCOperand::createReg(BaseRegNum));
2126 Instructions.push_back(TempInst);
2129 // And finally, create original instruction with low part
2130 // of offset and new base.
2131 TempInst.setOpcode(Inst.getOpcode());
2132 TempInst.addOperand(MCOperand::createReg(RegOpNum));
2133 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2135 TempInst.addOperand(MCOperand::createImm(LoOffset));
2137 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2138 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::create(
2139 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
2141 TempInst.addOperand(MCOperand::createExpr(LoExpr));
2143 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2144 TempInst.addOperand(MCOperand::createExpr(LoExpr));
2147 Instructions.push_back(TempInst);
2152 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2153 SmallVectorImpl<MCInst> &Instructions) {
2154 unsigned OpNum = Inst.getNumOperands();
2155 unsigned Opcode = Inst.getOpcode();
2156 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2158 assert (Inst.getOperand(OpNum - 1).isImm() &&
2159 Inst.getOperand(OpNum - 2).isReg() &&
2160 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2162 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2163 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2164 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2165 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2166 // It can be implemented as SWM16 or LWM16 instruction.
2167 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2169 Inst.setOpcode(NewOpcode);
2170 Instructions.push_back(Inst);
2174 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
2175 SmallVectorImpl<MCInst> &Instructions) {
2177 if (hasShortDelaySlot) {
2178 NopInst.setOpcode(Mips::MOVE16_MM);
2179 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2180 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2182 NopInst.setOpcode(Mips::SLL);
2183 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2184 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2185 NopInst.addOperand(MCOperand::createImm(0));
2187 Instructions.push_back(NopInst);
2190 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
2192 SmallVectorImpl<MCInst> &Instructions) {
2194 AdduInst.setOpcode(Mips::ADDu);
2195 AdduInst.addOperand(MCOperand::createReg(DstReg));
2196 AdduInst.addOperand(MCOperand::createReg(SrcReg));
2197 AdduInst.addOperand(MCOperand::createReg(TrgReg));
2198 Instructions.push_back(AdduInst);
2201 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
2202 // As described by the Mips32r2 spec, the registers Rd and Rs for
2203 // jalr.hb must be different.
2204 unsigned Opcode = Inst.getOpcode();
2206 if (Opcode == Mips::JALR_HB &&
2207 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
2208 return Match_RequiresDifferentSrcAndDst;
2210 return Match_Success;
2213 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2214 OperandVector &Operands,
2216 uint64_t &ErrorInfo,
2217 bool MatchingInlineAsm) {
2220 SmallVector<MCInst, 8> Instructions;
2221 unsigned MatchResult =
2222 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
2224 switch (MatchResult) {
2225 case Match_Success: {
2226 if (processInstruction(Inst, IDLoc, Instructions))
2228 for (unsigned i = 0; i < Instructions.size(); i++)
2229 Out.EmitInstruction(Instructions[i], STI);
2232 case Match_MissingFeature:
2233 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2235 case Match_InvalidOperand: {
2236 SMLoc ErrorLoc = IDLoc;
2237 if (ErrorInfo != ~0ULL) {
2238 if (ErrorInfo >= Operands.size())
2239 return Error(IDLoc, "too few operands for instruction");
2241 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
2242 if (ErrorLoc == SMLoc())
2246 return Error(ErrorLoc, "invalid operand for instruction");
2248 case Match_MnemonicFail:
2249 return Error(IDLoc, "invalid instruction");
2250 case Match_RequiresDifferentSrcAndDst:
2251 return Error(IDLoc, "source and destination must be different");
2254 llvm_unreachable("Implement any new match types added!");
2257 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
2258 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
2259 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
2260 ") without \".set noat\"");
2263 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
2264 if (!AssemblerOptions.back()->isMacro())
2265 Warning(Loc, "macro instruction expanded into multiple instructions");
2269 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
2270 SMRange Range, bool ShowColors) {
2271 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
2272 Range, SMFixIt(Range, FixMsg),
2276 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
2279 CC = StringSwitch<unsigned>(Name)
2315 if (!(isABI_N32() || isABI_N64()))
2318 if (12 <= CC && CC <= 15) {
2319 // Name is one of t4-t7
2320 AsmToken RegTok = getLexer().peekTok();
2321 SMRange RegRange = RegTok.getLocRange();
2323 StringRef FixedName = StringSwitch<StringRef>(Name)
2329 assert(FixedName != "" && "Register name is not one of t4-t7.");
2331 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
2332 "Did you mean $" + FixedName + "?", RegRange);
2335 // Although SGI documentation just cuts out t0-t3 for n32/n64,
2336 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
2337 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
2338 if (8 <= CC && CC <= 11)
2342 CC = StringSwitch<unsigned>(Name)
2354 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
2357 CC = StringSwitch<unsigned>(Name)
2358 .Case("hwr_cpunum", 0)
2359 .Case("hwr_synci_step", 1)
2361 .Case("hwr_ccres", 3)
2362 .Case("hwr_ulr", 29)
2368 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2370 if (Name[0] == 'f') {
2371 StringRef NumString = Name.substr(1);
2373 if (NumString.getAsInteger(10, IntVal))
2374 return -1; // This is not an integer.
2375 if (IntVal > 31) // Maximum index for fpu register.
2382 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2384 if (Name.startswith("fcc")) {
2385 StringRef NumString = Name.substr(3);
2387 if (NumString.getAsInteger(10, IntVal))
2388 return -1; // This is not an integer.
2389 if (IntVal > 7) // There are only 8 fcc registers.
2396 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2398 if (Name.startswith("ac")) {
2399 StringRef NumString = Name.substr(2);
2401 if (NumString.getAsInteger(10, IntVal))
2402 return -1; // This is not an integer.
2403 if (IntVal > 3) // There are only 3 acc registers.
2410 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2413 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
2422 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
2425 CC = StringSwitch<unsigned>(Name)
2428 .Case("msaaccess", 2)
2430 .Case("msamodify", 4)
2431 .Case("msarequest", 5)
2433 .Case("msaunmap", 7)
2439 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
2440 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
2442 reportParseError(Loc,
2443 "pseudo-instruction requires $at, which is not available");
2446 unsigned AT = getReg(
2447 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
2451 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2452 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2455 unsigned MipsAsmParser::getGPR(int RegNo) {
2456 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2460 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2462 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2465 return getReg(RegClass, RegNum);
2468 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2469 MCAsmParser &Parser = getParser();
2470 DEBUG(dbgs() << "parseOperand\n");
2472 // Check if the current operand has a custom associated parser, if so, try to
2473 // custom parse the operand, or fallback to the general approach.
2474 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2475 if (ResTy == MatchOperand_Success)
2477 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2478 // there was a match, but an error occurred, in which case, just return that
2479 // the operand parsing failed.
2480 if (ResTy == MatchOperand_ParseFail)
2483 DEBUG(dbgs() << ".. Generic Parser\n");
2485 switch (getLexer().getKind()) {
2487 Error(Parser.getTok().getLoc(), "unexpected token in operand");
2489 case AsmToken::Dollar: {
2490 // Parse the register.
2491 SMLoc S = Parser.getTok().getLoc();
2493 // Almost all registers have been parsed by custom parsers. There is only
2494 // one exception to this. $zero (and it's alias $0) will reach this point
2495 // for div, divu, and similar instructions because it is not an operand
2496 // to the instruction definition but an explicit register. Special case
2497 // this situation for now.
2498 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
2501 // Maybe it is a symbol reference.
2502 StringRef Identifier;
2503 if (Parser.parseIdentifier(Identifier))
2506 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2507 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
2508 // Otherwise create a symbol reference.
2510 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
2512 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
2515 // Else drop to expression parsing.
2516 case AsmToken::LParen:
2517 case AsmToken::Minus:
2518 case AsmToken::Plus:
2519 case AsmToken::Integer:
2520 case AsmToken::Tilde:
2521 case AsmToken::String: {
2522 DEBUG(dbgs() << ".. generic integer\n");
2523 OperandMatchResultTy ResTy = parseImm(Operands);
2524 return ResTy != MatchOperand_Success;
2526 case AsmToken::Percent: {
2527 // It is a symbol reference or constant expression.
2528 const MCExpr *IdVal;
2529 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
2530 if (parseRelocOperand(IdVal))
2533 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2535 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2537 } // case AsmToken::Percent
2538 } // switch(getLexer().getKind())
2542 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
2543 StringRef RelocStr) {
2545 // Check the type of the expression.
2546 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
2547 // It's a constant, evaluate reloc value.
2549 switch (getVariantKind(RelocStr)) {
2550 case MCSymbolRefExpr::VK_Mips_ABS_LO:
2551 // Get the 1st 16-bits.
2552 Val = MCE->getValue() & 0xffff;
2554 case MCSymbolRefExpr::VK_Mips_ABS_HI:
2555 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
2556 // 16 bits being negative.
2557 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
2559 case MCSymbolRefExpr::VK_Mips_HIGHER:
2560 // Get the 3rd 16-bits.
2561 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
2563 case MCSymbolRefExpr::VK_Mips_HIGHEST:
2564 // Get the 4th 16-bits.
2565 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
2568 report_fatal_error("unsupported reloc value");
2570 return MCConstantExpr::create(Val, getContext());
2573 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
2574 // It's a symbol, create a symbolic expression from the symbol.
2575 StringRef Symbol = MSRE->getSymbol().getName();
2576 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2577 Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
2581 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2582 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2584 // Try to create target expression.
2585 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
2586 return MipsMCExpr::create(VK, Expr, getContext());
2588 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
2589 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
2590 Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
2594 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
2595 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
2596 Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
2599 // Just return the original expression.
2603 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
2605 switch (Expr->getKind()) {
2606 case MCExpr::Constant:
2608 case MCExpr::SymbolRef:
2609 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
2610 case MCExpr::Binary:
2611 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2612 if (!isEvaluated(BE->getLHS()))
2614 return isEvaluated(BE->getRHS());
2617 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
2618 case MCExpr::Target:
2624 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
2625 MCAsmParser &Parser = getParser();
2626 Parser.Lex(); // Eat the % token.
2627 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
2628 if (Tok.isNot(AsmToken::Identifier))
2631 std::string Str = Tok.getIdentifier();
2633 Parser.Lex(); // Eat the identifier.
2634 // Now make an expression from the rest of the operand.
2635 const MCExpr *IdVal;
2638 if (getLexer().getKind() == AsmToken::LParen) {
2640 Parser.Lex(); // Eat the '(' token.
2641 if (getLexer().getKind() == AsmToken::Percent) {
2642 Parser.Lex(); // Eat the % token.
2643 const AsmToken &nextTok = Parser.getTok();
2644 if (nextTok.isNot(AsmToken::Identifier))
2647 Str += nextTok.getIdentifier();
2648 Parser.Lex(); // Eat the identifier.
2649 if (getLexer().getKind() != AsmToken::LParen)
2654 if (getParser().parseParenExpression(IdVal, EndLoc))
2657 while (getLexer().getKind() == AsmToken::RParen)
2658 Parser.Lex(); // Eat the ')' token.
2661 return true; // Parenthesis must follow the relocation operand.
2663 Res = evaluateRelocExpr(IdVal, Str);
2667 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2669 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2670 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2671 if (ResTy == MatchOperand_Success) {
2672 assert(Operands.size() == 1);
2673 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2674 StartLoc = Operand.getStartLoc();
2675 EndLoc = Operand.getEndLoc();
2677 // AFAIK, we only support numeric registers and named GPR's in CFI
2679 // Don't worry about eating tokens before failing. Using an unrecognised
2680 // register is a parse error.
2681 if (Operand.isGPRAsmReg()) {
2682 // Resolve to GPR32 or GPR64 appropriately.
2683 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2686 return (RegNo == (unsigned)-1);
2689 assert(Operands.size() == 0);
2690 return (RegNo == (unsigned)-1);
2693 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2694 MCAsmParser &Parser = getParser();
2698 while (getLexer().getKind() == AsmToken::LParen)
2701 switch (getLexer().getKind()) {
2704 case AsmToken::Identifier:
2705 case AsmToken::LParen:
2706 case AsmToken::Integer:
2707 case AsmToken::Minus:
2708 case AsmToken::Plus:
2710 Result = getParser().parseParenExpression(Res, S);
2712 Result = (getParser().parseExpression(Res));
2713 while (getLexer().getKind() == AsmToken::RParen)
2716 case AsmToken::Percent:
2717 Result = parseRelocOperand(Res);
2722 MipsAsmParser::OperandMatchResultTy
2723 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
2724 MCAsmParser &Parser = getParser();
2725 DEBUG(dbgs() << "parseMemOperand\n");
2726 const MCExpr *IdVal = nullptr;
2728 bool isParenExpr = false;
2729 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
2730 // First operand is the offset.
2731 S = Parser.getTok().getLoc();
2733 if (getLexer().getKind() == AsmToken::LParen) {
2738 if (getLexer().getKind() != AsmToken::Dollar) {
2739 if (parseMemOffset(IdVal, isParenExpr))
2740 return MatchOperand_ParseFail;
2742 const AsmToken &Tok = Parser.getTok(); // Get the next token.
2743 if (Tok.isNot(AsmToken::LParen)) {
2744 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2745 if (Mnemonic.getToken() == "la") {
2747 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2748 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2749 return MatchOperand_Success;
2751 if (Tok.is(AsmToken::EndOfStatement)) {
2753 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2755 // Zero register assumed, add a memory operand with ZERO as its base.
2756 // "Base" will be managed by k_Memory.
2757 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
2760 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2761 return MatchOperand_Success;
2763 Error(Parser.getTok().getLoc(), "'(' expected");
2764 return MatchOperand_ParseFail;
2767 Parser.Lex(); // Eat the '(' token.
2770 Res = parseAnyRegister(Operands);
2771 if (Res != MatchOperand_Success)
2774 if (Parser.getTok().isNot(AsmToken::RParen)) {
2775 Error(Parser.getTok().getLoc(), "')' expected");
2776 return MatchOperand_ParseFail;
2779 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2781 Parser.Lex(); // Eat the ')' token.
2784 IdVal = MCConstantExpr::create(0, getContext());
2786 // Replace the register operand with the memory operand.
2787 std::unique_ptr<MipsOperand> op(
2788 static_cast<MipsOperand *>(Operands.back().release()));
2789 // Remove the register from the operands.
2790 // "op" will be managed by k_Memory.
2791 Operands.pop_back();
2792 // Add the memory operand.
2793 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2795 if (IdVal->evaluateAsAbsolute(Imm))
2796 IdVal = MCConstantExpr::create(Imm, getContext());
2797 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2798 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2802 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2803 return MatchOperand_Success;
2806 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2807 MCAsmParser &Parser = getParser();
2808 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
2810 SMLoc S = Parser.getTok().getLoc();
2812 if (Sym->isVariable())
2813 Expr = Sym->getVariableValue();
2816 if (Expr->getKind() == MCExpr::SymbolRef) {
2817 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2818 StringRef DefSymbol = Ref->getSymbol().getName();
2819 if (DefSymbol.startswith("$")) {
2820 OperandMatchResultTy ResTy =
2821 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2822 if (ResTy == MatchOperand_Success) {
2825 } else if (ResTy == MatchOperand_ParseFail)
2826 llvm_unreachable("Should never ParseFail");
2829 } else if (Expr->getKind() == MCExpr::Constant) {
2831 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2833 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2840 MipsAsmParser::OperandMatchResultTy
2841 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2842 StringRef Identifier,
2844 int Index = matchCPURegisterName(Identifier);
2846 Operands.push_back(MipsOperand::createGPRReg(
2847 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2848 return MatchOperand_Success;
2851 Index = matchHWRegsRegisterName(Identifier);
2853 Operands.push_back(MipsOperand::createHWRegsReg(
2854 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2855 return MatchOperand_Success;
2858 Index = matchFPURegisterName(Identifier);
2860 Operands.push_back(MipsOperand::createFGRReg(
2861 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2862 return MatchOperand_Success;
2865 Index = matchFCCRegisterName(Identifier);
2867 Operands.push_back(MipsOperand::createFCCReg(
2868 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2869 return MatchOperand_Success;
2872 Index = matchACRegisterName(Identifier);
2874 Operands.push_back(MipsOperand::createACCReg(
2875 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2876 return MatchOperand_Success;
2879 Index = matchMSA128RegisterName(Identifier);
2881 Operands.push_back(MipsOperand::createMSA128Reg(
2882 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2883 return MatchOperand_Success;
2886 Index = matchMSA128CtrlRegisterName(Identifier);
2888 Operands.push_back(MipsOperand::createMSACtrlReg(
2889 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2890 return MatchOperand_Success;
2893 return MatchOperand_NoMatch;
2896 MipsAsmParser::OperandMatchResultTy
2897 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2898 MCAsmParser &Parser = getParser();
2899 auto Token = Parser.getLexer().peekTok(false);
2901 if (Token.is(AsmToken::Identifier)) {
2902 DEBUG(dbgs() << ".. identifier\n");
2903 StringRef Identifier = Token.getIdentifier();
2904 OperandMatchResultTy ResTy =
2905 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2907 } else if (Token.is(AsmToken::Integer)) {
2908 DEBUG(dbgs() << ".. integer\n");
2909 Operands.push_back(MipsOperand::createNumericReg(
2910 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2912 return MatchOperand_Success;
2915 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2917 return MatchOperand_NoMatch;
2920 MipsAsmParser::OperandMatchResultTy
2921 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
2922 MCAsmParser &Parser = getParser();
2923 DEBUG(dbgs() << "parseAnyRegister\n");
2925 auto Token = Parser.getTok();
2927 SMLoc S = Token.getLoc();
2929 if (Token.isNot(AsmToken::Dollar)) {
2930 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2931 if (Token.is(AsmToken::Identifier)) {
2932 if (searchSymbolAlias(Operands))
2933 return MatchOperand_Success;
2935 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2936 return MatchOperand_NoMatch;
2938 DEBUG(dbgs() << ".. $\n");
2940 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
2941 if (ResTy == MatchOperand_Success) {
2943 Parser.Lex(); // identifier
2948 MipsAsmParser::OperandMatchResultTy
2949 MipsAsmParser::parseImm(OperandVector &Operands) {
2950 MCAsmParser &Parser = getParser();
2951 switch (getLexer().getKind()) {
2953 return MatchOperand_NoMatch;
2954 case AsmToken::LParen:
2955 case AsmToken::Minus:
2956 case AsmToken::Plus:
2957 case AsmToken::Integer:
2958 case AsmToken::Tilde:
2959 case AsmToken::String:
2963 const MCExpr *IdVal;
2964 SMLoc S = Parser.getTok().getLoc();
2965 if (getParser().parseExpression(IdVal))
2966 return MatchOperand_ParseFail;
2968 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2969 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2970 return MatchOperand_Success;
2973 MipsAsmParser::OperandMatchResultTy
2974 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
2975 MCAsmParser &Parser = getParser();
2976 DEBUG(dbgs() << "parseJumpTarget\n");
2978 SMLoc S = getLexer().getLoc();
2980 // Integers and expressions are acceptable
2981 OperandMatchResultTy ResTy = parseImm(Operands);
2982 if (ResTy != MatchOperand_NoMatch)
2985 // Registers are a valid target and have priority over symbols.
2986 ResTy = parseAnyRegister(Operands);
2987 if (ResTy != MatchOperand_NoMatch)
2990 const MCExpr *Expr = nullptr;
2991 if (Parser.parseExpression(Expr)) {
2992 // We have no way of knowing if a symbol was consumed so we must ParseFail
2993 return MatchOperand_ParseFail;
2996 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2997 return MatchOperand_Success;
3000 MipsAsmParser::OperandMatchResultTy
3001 MipsAsmParser::parseInvNum(OperandVector &Operands) {
3002 MCAsmParser &Parser = getParser();
3003 const MCExpr *IdVal;
3004 // If the first token is '$' we may have register operand.
3005 if (Parser.getTok().is(AsmToken::Dollar))
3006 return MatchOperand_NoMatch;
3007 SMLoc S = Parser.getTok().getLoc();
3008 if (getParser().parseExpression(IdVal))
3009 return MatchOperand_ParseFail;
3010 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
3011 assert(MCE && "Unexpected MCExpr type.");
3012 int64_t Val = MCE->getValue();
3013 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3014 Operands.push_back(MipsOperand::CreateImm(
3015 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
3016 return MatchOperand_Success;
3019 MipsAsmParser::OperandMatchResultTy
3020 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
3021 MCAsmParser &Parser = getParser();
3022 switch (getLexer().getKind()) {
3024 return MatchOperand_NoMatch;
3025 case AsmToken::LParen:
3026 case AsmToken::Plus:
3027 case AsmToken::Minus:
3028 case AsmToken::Integer:
3033 SMLoc S = Parser.getTok().getLoc();
3035 if (getParser().parseExpression(Expr))
3036 return MatchOperand_ParseFail;
3039 if (!Expr->evaluateAsAbsolute(Val)) {
3040 Error(S, "expected immediate value");
3041 return MatchOperand_ParseFail;
3044 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
3045 // and because the CPU always adds one to the immediate field, the allowed
3046 // range becomes 1..4. We'll only check the range here and will deal
3047 // with the addition/subtraction when actually decoding/encoding
3049 if (Val < 1 || Val > 4) {
3050 Error(S, "immediate not in range (1..4)");
3051 return MatchOperand_ParseFail;
3055 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
3056 return MatchOperand_Success;
3059 MipsAsmParser::OperandMatchResultTy
3060 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3061 MCAsmParser &Parser = getParser();
3062 SmallVector<unsigned, 10> Regs;
3064 unsigned PrevReg = Mips::NoRegister;
3065 bool RegRange = false;
3066 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3068 if (Parser.getTok().isNot(AsmToken::Dollar))
3069 return MatchOperand_ParseFail;
3071 SMLoc S = Parser.getTok().getLoc();
3072 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3073 SMLoc E = getLexer().getLoc();
3074 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3075 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3077 // Remove last register operand because registers from register range
3078 // should be inserted first.
3079 if (RegNo == Mips::RA) {
3080 Regs.push_back(RegNo);
3082 unsigned TmpReg = PrevReg + 1;
3083 while (TmpReg <= RegNo) {
3084 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3085 Error(E, "invalid register operand");
3086 return MatchOperand_ParseFail;
3090 Regs.push_back(TmpReg++);
3096 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
3097 (RegNo != Mips::RA)) {
3098 Error(E, "$16 or $31 expected");
3099 return MatchOperand_ParseFail;
3100 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
3101 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3102 Error(E, "invalid register operand");
3103 return MatchOperand_ParseFail;
3104 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
3105 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3106 Error(E, "consecutive register numbers expected");
3107 return MatchOperand_ParseFail;
3110 Regs.push_back(RegNo);
3113 if (Parser.getTok().is(AsmToken::Minus))
3116 if (!Parser.getTok().isNot(AsmToken::Minus) &&
3117 !Parser.getTok().isNot(AsmToken::Comma)) {
3118 Error(E, "',' or '-' expected");
3119 return MatchOperand_ParseFail;
3122 Lex(); // Consume comma or minus
3123 if (Parser.getTok().isNot(AsmToken::Dollar))
3129 SMLoc E = Parser.getTok().getLoc();
3130 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3131 parseMemOperand(Operands);
3132 return MatchOperand_Success;
3135 MipsAsmParser::OperandMatchResultTy
3136 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
3137 MCAsmParser &Parser = getParser();
3139 SMLoc S = Parser.getTok().getLoc();
3140 if (parseAnyRegister(Operands) != MatchOperand_Success)
3141 return MatchOperand_ParseFail;
3143 SMLoc E = Parser.getTok().getLoc();
3144 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
3145 unsigned Reg = Op.getGPR32Reg();
3146 Operands.pop_back();
3147 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
3148 return MatchOperand_Success;
3151 MipsAsmParser::OperandMatchResultTy
3152 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
3153 MCAsmParser &Parser = getParser();
3154 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3155 SmallVector<unsigned, 10> Regs;
3157 if (Parser.getTok().isNot(AsmToken::Dollar))
3158 return MatchOperand_ParseFail;
3160 SMLoc S = Parser.getTok().getLoc();
3162 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3163 return MatchOperand_ParseFail;
3165 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3166 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3167 Regs.push_back(RegNo);
3169 SMLoc E = Parser.getTok().getLoc();
3170 if (Parser.getTok().isNot(AsmToken::Comma)) {
3171 Error(E, "',' expected");
3172 return MatchOperand_ParseFail;
3178 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3179 return MatchOperand_ParseFail;
3181 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3182 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3183 Regs.push_back(RegNo);
3185 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3187 return MatchOperand_Success;
3190 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
3192 MCSymbolRefExpr::VariantKind VK =
3193 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
3194 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
3195 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
3196 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
3197 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
3198 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
3199 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
3200 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
3201 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
3202 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
3203 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
3204 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
3205 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
3206 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
3207 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
3208 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
3209 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
3210 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
3211 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
3212 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
3213 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
3214 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
3215 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
3216 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
3217 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
3218 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
3219 .Default(MCSymbolRefExpr::VK_None);
3221 assert(VK != MCSymbolRefExpr::VK_None);
3226 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
3228 /// ::= '(', register, ')'
3229 /// handle it before we iterate so we don't get tripped up by the lack of
3231 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
3232 MCAsmParser &Parser = getParser();
3233 if (getLexer().is(AsmToken::LParen)) {
3235 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
3237 if (parseOperand(Operands, Name)) {
3238 SMLoc Loc = getLexer().getLoc();
3239 Parser.eatToEndOfStatement();
3240 return Error(Loc, "unexpected token in argument list");
3242 if (Parser.getTok().isNot(AsmToken::RParen)) {
3243 SMLoc Loc = getLexer().getLoc();
3244 Parser.eatToEndOfStatement();
3245 return Error(Loc, "unexpected token, expected ')'");
3248 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
3254 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
3255 /// either one of these.
3256 /// ::= '[', register, ']'
3257 /// ::= '[', integer, ']'
3258 /// handle it before we iterate so we don't get tripped up by the lack of
3260 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
3261 OperandVector &Operands) {
3262 MCAsmParser &Parser = getParser();
3263 if (getLexer().is(AsmToken::LBrac)) {
3265 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
3267 if (parseOperand(Operands, Name)) {
3268 SMLoc Loc = getLexer().getLoc();
3269 Parser.eatToEndOfStatement();
3270 return Error(Loc, "unexpected token in argument list");
3272 if (Parser.getTok().isNot(AsmToken::RBrac)) {
3273 SMLoc Loc = getLexer().getLoc();
3274 Parser.eatToEndOfStatement();
3275 return Error(Loc, "unexpected token, expected ']'");
3278 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
3284 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
3285 SMLoc NameLoc, OperandVector &Operands) {
3286 MCAsmParser &Parser = getParser();
3287 DEBUG(dbgs() << "ParseInstruction\n");
3289 // We have reached first instruction, module directive are now forbidden.
3290 getTargetStreamer().forbidModuleDirective();
3292 // Check if we have valid mnemonic
3293 if (!mnemonicIsValid(Name, 0)) {
3294 Parser.eatToEndOfStatement();
3295 return Error(NameLoc, "unknown instruction");
3297 // First operand in MCInst is instruction mnemonic.
3298 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
3300 // Read the remaining operands.
3301 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3302 // Read the first operand.
3303 if (parseOperand(Operands, Name)) {
3304 SMLoc Loc = getLexer().getLoc();
3305 Parser.eatToEndOfStatement();
3306 return Error(Loc, "unexpected token in argument list");
3308 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
3310 // AFAIK, parenthesis suffixes are never on the first operand
3312 while (getLexer().is(AsmToken::Comma)) {
3313 Parser.Lex(); // Eat the comma.
3314 // Parse and remember the operand.
3315 if (parseOperand(Operands, Name)) {
3316 SMLoc Loc = getLexer().getLoc();
3317 Parser.eatToEndOfStatement();
3318 return Error(Loc, "unexpected token in argument list");
3320 // Parse bracket and parenthesis suffixes before we iterate
3321 if (getLexer().is(AsmToken::LBrac)) {
3322 if (parseBracketSuffix(Name, Operands))
3324 } else if (getLexer().is(AsmToken::LParen) &&
3325 parseParenSuffix(Name, Operands))
3329 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3330 SMLoc Loc = getLexer().getLoc();
3331 Parser.eatToEndOfStatement();
3332 return Error(Loc, "unexpected token in argument list");
3334 Parser.Lex(); // Consume the EndOfStatement.
3338 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
3339 MCAsmParser &Parser = getParser();
3340 SMLoc Loc = getLexer().getLoc();
3341 Parser.eatToEndOfStatement();
3342 return Error(Loc, ErrorMsg);
3345 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
3346 return Error(Loc, ErrorMsg);
3349 bool MipsAsmParser::parseSetNoAtDirective() {
3350 MCAsmParser &Parser = getParser();
3351 // Line should look like: ".set noat".
3353 // Set the $at register to $0.
3354 AssemblerOptions.back()->setATRegIndex(0);
3356 Parser.Lex(); // Eat "noat".
3358 // If this is not the end of the statement, report an error.
3359 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3360 reportParseError("unexpected token, expected end of statement");
3364 getTargetStreamer().emitDirectiveSetNoAt();
3365 Parser.Lex(); // Consume the EndOfStatement.
3369 bool MipsAsmParser::parseSetAtDirective() {
3370 // Line can be: ".set at", which sets $at to $1
3371 // or ".set at=$reg", which sets $at to $reg.
3372 MCAsmParser &Parser = getParser();
3373 Parser.Lex(); // Eat "at".
3375 if (getLexer().is(AsmToken::EndOfStatement)) {
3376 // No register was specified, so we set $at to $1.
3377 AssemblerOptions.back()->setATRegIndex(1);
3379 getTargetStreamer().emitDirectiveSetAt();
3380 Parser.Lex(); // Consume the EndOfStatement.
3384 if (getLexer().isNot(AsmToken::Equal)) {
3385 reportParseError("unexpected token, expected equals sign");
3388 Parser.Lex(); // Eat "=".
3390 if (getLexer().isNot(AsmToken::Dollar)) {
3391 if (getLexer().is(AsmToken::EndOfStatement)) {
3392 reportParseError("no register specified");
3395 reportParseError("unexpected token, expected dollar sign '$'");
3399 Parser.Lex(); // Eat "$".
3401 // Find out what "reg" is.
3403 const AsmToken &Reg = Parser.getTok();
3404 if (Reg.is(AsmToken::Identifier)) {
3405 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
3406 } else if (Reg.is(AsmToken::Integer)) {
3407 AtRegNo = Reg.getIntVal();
3409 reportParseError("unexpected token, expected identifier or integer");
3413 // Check if $reg is a valid register. If it is, set $at to $reg.
3414 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
3415 reportParseError("invalid register");
3418 Parser.Lex(); // Eat "reg".
3420 // If this is not the end of the statement, report an error.
3421 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3422 reportParseError("unexpected token, expected end of statement");
3426 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
3428 Parser.Lex(); // Consume the EndOfStatement.
3432 bool MipsAsmParser::parseSetReorderDirective() {
3433 MCAsmParser &Parser = getParser();
3435 // If this is not the end of the statement, report an error.
3436 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3437 reportParseError("unexpected token, expected end of statement");
3440 AssemblerOptions.back()->setReorder();
3441 getTargetStreamer().emitDirectiveSetReorder();
3442 Parser.Lex(); // Consume the EndOfStatement.
3446 bool MipsAsmParser::parseSetNoReorderDirective() {
3447 MCAsmParser &Parser = getParser();
3449 // If this is not the end of the statement, report an error.
3450 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3451 reportParseError("unexpected token, expected end of statement");
3454 AssemblerOptions.back()->setNoReorder();
3455 getTargetStreamer().emitDirectiveSetNoReorder();
3456 Parser.Lex(); // Consume the EndOfStatement.
3460 bool MipsAsmParser::parseSetMacroDirective() {
3461 MCAsmParser &Parser = getParser();
3463 // If this is not the end of the statement, report an error.
3464 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3465 reportParseError("unexpected token, expected end of statement");
3468 AssemblerOptions.back()->setMacro();
3469 getTargetStreamer().emitDirectiveSetMacro();
3470 Parser.Lex(); // Consume the EndOfStatement.
3474 bool MipsAsmParser::parseSetNoMacroDirective() {
3475 MCAsmParser &Parser = getParser();
3477 // If this is not the end of the statement, report an error.
3478 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3479 reportParseError("unexpected token, expected end of statement");
3482 if (AssemblerOptions.back()->isReorder()) {
3483 reportParseError("`noreorder' must be set before `nomacro'");
3486 AssemblerOptions.back()->setNoMacro();
3487 getTargetStreamer().emitDirectiveSetNoMacro();
3488 Parser.Lex(); // Consume the EndOfStatement.
3492 bool MipsAsmParser::parseSetMsaDirective() {
3493 MCAsmParser &Parser = getParser();
3496 // If this is not the end of the statement, report an error.
3497 if (getLexer().isNot(AsmToken::EndOfStatement))
3498 return reportParseError("unexpected token, expected end of statement");
3500 setFeatureBits(Mips::FeatureMSA, "msa");
3501 getTargetStreamer().emitDirectiveSetMsa();
3505 bool MipsAsmParser::parseSetNoMsaDirective() {
3506 MCAsmParser &Parser = getParser();
3509 // If this is not the end of the statement, report an error.
3510 if (getLexer().isNot(AsmToken::EndOfStatement))
3511 return reportParseError("unexpected token, expected end of statement");
3513 clearFeatureBits(Mips::FeatureMSA, "msa");
3514 getTargetStreamer().emitDirectiveSetNoMsa();
3518 bool MipsAsmParser::parseSetNoDspDirective() {
3519 MCAsmParser &Parser = getParser();
3520 Parser.Lex(); // Eat "nodsp".
3522 // If this is not the end of the statement, report an error.
3523 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3524 reportParseError("unexpected token, expected end of statement");
3528 clearFeatureBits(Mips::FeatureDSP, "dsp");
3529 getTargetStreamer().emitDirectiveSetNoDsp();
3533 bool MipsAsmParser::parseSetMips16Directive() {
3534 MCAsmParser &Parser = getParser();
3535 Parser.Lex(); // Eat "mips16".
3537 // If this is not the end of the statement, report an error.
3538 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3539 reportParseError("unexpected token, expected end of statement");
3543 setFeatureBits(Mips::FeatureMips16, "mips16");
3544 getTargetStreamer().emitDirectiveSetMips16();
3545 Parser.Lex(); // Consume the EndOfStatement.
3549 bool MipsAsmParser::parseSetNoMips16Directive() {
3550 MCAsmParser &Parser = getParser();
3551 Parser.Lex(); // Eat "nomips16".
3553 // If this is not the end of the statement, report an error.
3554 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3555 reportParseError("unexpected token, expected end of statement");
3559 clearFeatureBits(Mips::FeatureMips16, "mips16");
3560 getTargetStreamer().emitDirectiveSetNoMips16();
3561 Parser.Lex(); // Consume the EndOfStatement.
3565 bool MipsAsmParser::parseSetFpDirective() {
3566 MCAsmParser &Parser = getParser();
3567 MipsABIFlagsSection::FpABIKind FpAbiVal;
3568 // Line can be: .set fp=32
3571 Parser.Lex(); // Eat fp token
3572 AsmToken Tok = Parser.getTok();
3573 if (Tok.isNot(AsmToken::Equal)) {
3574 reportParseError("unexpected token, expected equals sign '='");
3577 Parser.Lex(); // Eat '=' token.
3578 Tok = Parser.getTok();
3580 if (!parseFpABIValue(FpAbiVal, ".set"))
3583 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3584 reportParseError("unexpected token, expected end of statement");
3587 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
3588 Parser.Lex(); // Consume the EndOfStatement.
3592 bool MipsAsmParser::parseSetPopDirective() {
3593 MCAsmParser &Parser = getParser();
3594 SMLoc Loc = getLexer().getLoc();
3597 if (getLexer().isNot(AsmToken::EndOfStatement))
3598 return reportParseError("unexpected token, expected end of statement");
3600 // Always keep an element on the options "stack" to prevent the user
3601 // from changing the initial options. This is how we remember them.
3602 if (AssemblerOptions.size() == 2)
3603 return reportParseError(Loc, ".set pop with no .set push");
3605 AssemblerOptions.pop_back();
3606 setAvailableFeatures(AssemblerOptions.back()->getFeatures());
3608 getTargetStreamer().emitDirectiveSetPop();
3612 bool MipsAsmParser::parseSetPushDirective() {
3613 MCAsmParser &Parser = getParser();
3615 if (getLexer().isNot(AsmToken::EndOfStatement))
3616 return reportParseError("unexpected token, expected end of statement");
3618 // Create a copy of the current assembler options environment and push it.
3619 AssemblerOptions.push_back(
3620 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
3622 getTargetStreamer().emitDirectiveSetPush();
3626 bool MipsAsmParser::parseSetSoftFloatDirective() {
3627 MCAsmParser &Parser = getParser();
3629 if (getLexer().isNot(AsmToken::EndOfStatement))
3630 return reportParseError("unexpected token, expected end of statement");
3632 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
3633 getTargetStreamer().emitDirectiveSetSoftFloat();
3637 bool MipsAsmParser::parseSetHardFloatDirective() {
3638 MCAsmParser &Parser = getParser();
3640 if (getLexer().isNot(AsmToken::EndOfStatement))
3641 return reportParseError("unexpected token, expected end of statement");
3643 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
3644 getTargetStreamer().emitDirectiveSetHardFloat();
3648 bool MipsAsmParser::parseSetAssignment() {
3650 const MCExpr *Value;
3651 MCAsmParser &Parser = getParser();
3653 if (Parser.parseIdentifier(Name))
3654 reportParseError("expected identifier after .set");
3656 if (getLexer().isNot(AsmToken::Comma))
3657 return reportParseError("unexpected token, expected comma");
3660 if (Parser.parseExpression(Value))
3661 return reportParseError("expected valid expression after comma");
3663 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
3664 Sym->setVariableValue(Value);
3669 bool MipsAsmParser::parseSetMips0Directive() {
3670 MCAsmParser &Parser = getParser();
3672 if (getLexer().isNot(AsmToken::EndOfStatement))
3673 return reportParseError("unexpected token, expected end of statement");
3675 // Reset assembler options to their initial values.
3676 setAvailableFeatures(AssemblerOptions.front()->getFeatures());
3677 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
3679 getTargetStreamer().emitDirectiveSetMips0();
3683 bool MipsAsmParser::parseSetArchDirective() {
3684 MCAsmParser &Parser = getParser();
3686 if (getLexer().isNot(AsmToken::Equal))
3687 return reportParseError("unexpected token, expected equals sign");
3691 if (Parser.parseIdentifier(Arch))
3692 return reportParseError("expected arch identifier");
3694 StringRef ArchFeatureName =
3695 StringSwitch<StringRef>(Arch)
3696 .Case("mips1", "mips1")
3697 .Case("mips2", "mips2")
3698 .Case("mips3", "mips3")
3699 .Case("mips4", "mips4")
3700 .Case("mips5", "mips5")
3701 .Case("mips32", "mips32")
3702 .Case("mips32r2", "mips32r2")
3703 .Case("mips32r3", "mips32r3")
3704 .Case("mips32r5", "mips32r5")
3705 .Case("mips32r6", "mips32r6")
3706 .Case("mips64", "mips64")
3707 .Case("mips64r2", "mips64r2")
3708 .Case("mips64r3", "mips64r3")
3709 .Case("mips64r5", "mips64r5")
3710 .Case("mips64r6", "mips64r6")
3711 .Case("cnmips", "cnmips")
3712 .Case("r4000", "mips3") // This is an implementation of Mips3.
3715 if (ArchFeatureName.empty())
3716 return reportParseError("unsupported architecture");
3718 selectArch(ArchFeatureName);
3719 getTargetStreamer().emitDirectiveSetArch(Arch);
3723 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
3724 MCAsmParser &Parser = getParser();
3726 if (getLexer().isNot(AsmToken::EndOfStatement))
3727 return reportParseError("unexpected token, expected end of statement");
3731 llvm_unreachable("Unimplemented feature");
3732 case Mips::FeatureDSP:
3733 setFeatureBits(Mips::FeatureDSP, "dsp");
3734 getTargetStreamer().emitDirectiveSetDsp();
3736 case Mips::FeatureMicroMips:
3737 getTargetStreamer().emitDirectiveSetMicroMips();
3739 case Mips::FeatureMips1:
3740 selectArch("mips1");
3741 getTargetStreamer().emitDirectiveSetMips1();
3743 case Mips::FeatureMips2:
3744 selectArch("mips2");
3745 getTargetStreamer().emitDirectiveSetMips2();
3747 case Mips::FeatureMips3:
3748 selectArch("mips3");
3749 getTargetStreamer().emitDirectiveSetMips3();
3751 case Mips::FeatureMips4:
3752 selectArch("mips4");
3753 getTargetStreamer().emitDirectiveSetMips4();
3755 case Mips::FeatureMips5:
3756 selectArch("mips5");
3757 getTargetStreamer().emitDirectiveSetMips5();
3759 case Mips::FeatureMips32:
3760 selectArch("mips32");
3761 getTargetStreamer().emitDirectiveSetMips32();
3763 case Mips::FeatureMips32r2:
3764 selectArch("mips32r2");
3765 getTargetStreamer().emitDirectiveSetMips32R2();
3767 case Mips::FeatureMips32r3:
3768 selectArch("mips32r3");
3769 getTargetStreamer().emitDirectiveSetMips32R3();
3771 case Mips::FeatureMips32r5:
3772 selectArch("mips32r5");
3773 getTargetStreamer().emitDirectiveSetMips32R5();
3775 case Mips::FeatureMips32r6:
3776 selectArch("mips32r6");
3777 getTargetStreamer().emitDirectiveSetMips32R6();
3779 case Mips::FeatureMips64:
3780 selectArch("mips64");
3781 getTargetStreamer().emitDirectiveSetMips64();
3783 case Mips::FeatureMips64r2:
3784 selectArch("mips64r2");
3785 getTargetStreamer().emitDirectiveSetMips64R2();
3787 case Mips::FeatureMips64r3:
3788 selectArch("mips64r3");
3789 getTargetStreamer().emitDirectiveSetMips64R3();
3791 case Mips::FeatureMips64r5:
3792 selectArch("mips64r5");
3793 getTargetStreamer().emitDirectiveSetMips64R5();
3795 case Mips::FeatureMips64r6:
3796 selectArch("mips64r6");
3797 getTargetStreamer().emitDirectiveSetMips64R6();
3803 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
3804 MCAsmParser &Parser = getParser();
3805 if (getLexer().isNot(AsmToken::Comma)) {
3806 SMLoc Loc = getLexer().getLoc();
3807 Parser.eatToEndOfStatement();
3808 return Error(Loc, ErrorStr);
3811 Parser.Lex(); // Eat the comma.
3815 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
3816 if (AssemblerOptions.back()->isReorder())
3817 Warning(Loc, ".cpload should be inside a noreorder section");
3819 if (inMips16Mode()) {
3820 reportParseError(".cpload is not supported in Mips16 mode");
3824 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
3825 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
3826 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3827 reportParseError("expected register containing function address");
3831 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
3832 if (!RegOpnd.isGPRAsmReg()) {
3833 reportParseError(RegOpnd.getStartLoc(), "invalid register");
3837 // If this is not the end of the statement, report an error.
3838 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3839 reportParseError("unexpected token, expected end of statement");
3843 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
3847 bool MipsAsmParser::parseDirectiveCPSetup() {
3848 MCAsmParser &Parser = getParser();
3851 bool SaveIsReg = true;
3853 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3854 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3855 if (ResTy == MatchOperand_NoMatch) {
3856 reportParseError("expected register containing function address");
3857 Parser.eatToEndOfStatement();
3861 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3862 if (!FuncRegOpnd.isGPRAsmReg()) {
3863 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
3864 Parser.eatToEndOfStatement();
3868 FuncReg = FuncRegOpnd.getGPR32Reg();
3871 if (!eatComma("unexpected token, expected comma"))
3874 ResTy = parseAnyRegister(TmpReg);
3875 if (ResTy == MatchOperand_NoMatch) {
3876 const AsmToken &Tok = Parser.getTok();
3877 if (Tok.is(AsmToken::Integer)) {
3878 Save = Tok.getIntVal();
3882 reportParseError("expected save register or stack offset");
3883 Parser.eatToEndOfStatement();
3887 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3888 if (!SaveOpnd.isGPRAsmReg()) {
3889 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
3890 Parser.eatToEndOfStatement();
3893 Save = SaveOpnd.getGPR32Reg();
3896 if (!eatComma("unexpected token, expected comma"))
3900 if (Parser.parseExpression(Expr)) {
3901 reportParseError("expected expression");
3905 if (Expr->getKind() != MCExpr::SymbolRef) {
3906 reportParseError("expected symbol");
3909 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3911 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
3916 bool MipsAsmParser::parseDirectiveNaN() {
3917 MCAsmParser &Parser = getParser();
3918 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3919 const AsmToken &Tok = Parser.getTok();
3921 if (Tok.getString() == "2008") {
3923 getTargetStreamer().emitDirectiveNaN2008();
3925 } else if (Tok.getString() == "legacy") {
3927 getTargetStreamer().emitDirectiveNaNLegacy();
3931 // If we don't recognize the option passed to the .nan
3932 // directive (e.g. no option or unknown option), emit an error.
3933 reportParseError("invalid option in .nan directive");
3937 bool MipsAsmParser::parseDirectiveSet() {
3938 MCAsmParser &Parser = getParser();
3939 // Get the next token.
3940 const AsmToken &Tok = Parser.getTok();
3942 if (Tok.getString() == "noat") {
3943 return parseSetNoAtDirective();
3944 } else if (Tok.getString() == "at") {
3945 return parseSetAtDirective();
3946 } else if (Tok.getString() == "arch") {
3947 return parseSetArchDirective();
3948 } else if (Tok.getString() == "fp") {
3949 return parseSetFpDirective();
3950 } else if (Tok.getString() == "pop") {
3951 return parseSetPopDirective();
3952 } else if (Tok.getString() == "push") {
3953 return parseSetPushDirective();
3954 } else if (Tok.getString() == "reorder") {
3955 return parseSetReorderDirective();
3956 } else if (Tok.getString() == "noreorder") {
3957 return parseSetNoReorderDirective();
3958 } else if (Tok.getString() == "macro") {
3959 return parseSetMacroDirective();
3960 } else if (Tok.getString() == "nomacro") {
3961 return parseSetNoMacroDirective();
3962 } else if (Tok.getString() == "mips16") {
3963 return parseSetMips16Directive();
3964 } else if (Tok.getString() == "nomips16") {
3965 return parseSetNoMips16Directive();
3966 } else if (Tok.getString() == "nomicromips") {
3967 getTargetStreamer().emitDirectiveSetNoMicroMips();
3968 Parser.eatToEndOfStatement();
3970 } else if (Tok.getString() == "micromips") {
3971 return parseSetFeature(Mips::FeatureMicroMips);
3972 } else if (Tok.getString() == "mips0") {
3973 return parseSetMips0Directive();
3974 } else if (Tok.getString() == "mips1") {
3975 return parseSetFeature(Mips::FeatureMips1);
3976 } else if (Tok.getString() == "mips2") {
3977 return parseSetFeature(Mips::FeatureMips2);
3978 } else if (Tok.getString() == "mips3") {
3979 return parseSetFeature(Mips::FeatureMips3);
3980 } else if (Tok.getString() == "mips4") {
3981 return parseSetFeature(Mips::FeatureMips4);
3982 } else if (Tok.getString() == "mips5") {
3983 return parseSetFeature(Mips::FeatureMips5);
3984 } else if (Tok.getString() == "mips32") {
3985 return parseSetFeature(Mips::FeatureMips32);
3986 } else if (Tok.getString() == "mips32r2") {
3987 return parseSetFeature(Mips::FeatureMips32r2);
3988 } else if (Tok.getString() == "mips32r3") {
3989 return parseSetFeature(Mips::FeatureMips32r3);
3990 } else if (Tok.getString() == "mips32r5") {
3991 return parseSetFeature(Mips::FeatureMips32r5);
3992 } else if (Tok.getString() == "mips32r6") {
3993 return parseSetFeature(Mips::FeatureMips32r6);
3994 } else if (Tok.getString() == "mips64") {
3995 return parseSetFeature(Mips::FeatureMips64);
3996 } else if (Tok.getString() == "mips64r2") {
3997 return parseSetFeature(Mips::FeatureMips64r2);
3998 } else if (Tok.getString() == "mips64r3") {
3999 return parseSetFeature(Mips::FeatureMips64r3);
4000 } else if (Tok.getString() == "mips64r5") {
4001 return parseSetFeature(Mips::FeatureMips64r5);
4002 } else if (Tok.getString() == "mips64r6") {
4003 return parseSetFeature(Mips::FeatureMips64r6);
4004 } else if (Tok.getString() == "dsp") {
4005 return parseSetFeature(Mips::FeatureDSP);
4006 } else if (Tok.getString() == "nodsp") {
4007 return parseSetNoDspDirective();
4008 } else if (Tok.getString() == "msa") {
4009 return parseSetMsaDirective();
4010 } else if (Tok.getString() == "nomsa") {
4011 return parseSetNoMsaDirective();
4012 } else if (Tok.getString() == "softfloat") {
4013 return parseSetSoftFloatDirective();
4014 } else if (Tok.getString() == "hardfloat") {
4015 return parseSetHardFloatDirective();
4017 // It is just an identifier, look for an assignment.
4018 parseSetAssignment();
4025 /// parseDataDirective
4026 /// ::= .word [ expression (, expression)* ]
4027 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
4028 MCAsmParser &Parser = getParser();
4029 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4031 const MCExpr *Value;
4032 if (getParser().parseExpression(Value))
4035 getParser().getStreamer().EmitValue(Value, Size);
4037 if (getLexer().is(AsmToken::EndOfStatement))
4040 if (getLexer().isNot(AsmToken::Comma))
4041 return Error(L, "unexpected token, expected comma");
4050 /// parseDirectiveGpWord
4051 /// ::= .gpword local_sym
4052 bool MipsAsmParser::parseDirectiveGpWord() {
4053 MCAsmParser &Parser = getParser();
4054 const MCExpr *Value;
4055 // EmitGPRel32Value requires an expression, so we are using base class
4056 // method to evaluate the expression.
4057 if (getParser().parseExpression(Value))
4059 getParser().getStreamer().EmitGPRel32Value(Value);
4061 if (getLexer().isNot(AsmToken::EndOfStatement))
4062 return Error(getLexer().getLoc(),
4063 "unexpected token, expected end of statement");
4064 Parser.Lex(); // Eat EndOfStatement token.
4068 /// parseDirectiveGpDWord
4069 /// ::= .gpdword local_sym
4070 bool MipsAsmParser::parseDirectiveGpDWord() {
4071 MCAsmParser &Parser = getParser();
4072 const MCExpr *Value;
4073 // EmitGPRel64Value requires an expression, so we are using base class
4074 // method to evaluate the expression.
4075 if (getParser().parseExpression(Value))
4077 getParser().getStreamer().EmitGPRel64Value(Value);
4079 if (getLexer().isNot(AsmToken::EndOfStatement))
4080 return Error(getLexer().getLoc(),
4081 "unexpected token, expected end of statement");
4082 Parser.Lex(); // Eat EndOfStatement token.
4086 bool MipsAsmParser::parseDirectiveOption() {
4087 MCAsmParser &Parser = getParser();
4088 // Get the option token.
4089 AsmToken Tok = Parser.getTok();
4090 // At the moment only identifiers are supported.
4091 if (Tok.isNot(AsmToken::Identifier)) {
4092 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
4093 Parser.eatToEndOfStatement();
4097 StringRef Option = Tok.getIdentifier();
4099 if (Option == "pic0") {
4100 getTargetStreamer().emitDirectiveOptionPic0();
4102 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4103 Error(Parser.getTok().getLoc(),
4104 "unexpected token, expected end of statement");
4105 Parser.eatToEndOfStatement();
4110 if (Option == "pic2") {
4111 getTargetStreamer().emitDirectiveOptionPic2();
4113 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4114 Error(Parser.getTok().getLoc(),
4115 "unexpected token, expected end of statement");
4116 Parser.eatToEndOfStatement();
4122 Warning(Parser.getTok().getLoc(),
4123 "unknown option, expected 'pic0' or 'pic2'");
4124 Parser.eatToEndOfStatement();
4128 /// parseInsnDirective
4130 bool MipsAsmParser::parseInsnDirective() {
4131 // If this is not the end of the statement, report an error.
4132 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4133 reportParseError("unexpected token, expected end of statement");
4137 // The actual label marking happens in
4138 // MipsELFStreamer::createPendingLabelRelocs().
4139 getTargetStreamer().emitDirectiveInsn();
4141 getParser().Lex(); // Eat EndOfStatement token.
4145 /// parseDirectiveModule
4146 /// ::= .module oddspreg
4147 /// ::= .module nooddspreg
4148 /// ::= .module fp=value
4149 bool MipsAsmParser::parseDirectiveModule() {
4150 MCAsmParser &Parser = getParser();
4151 MCAsmLexer &Lexer = getLexer();
4152 SMLoc L = Lexer.getLoc();
4154 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
4155 // TODO : get a better message.
4156 reportParseError(".module directive must appear before any code");
4161 if (Parser.parseIdentifier(Option)) {
4162 reportParseError("expected .module option identifier");
4166 if (Option == "oddspreg") {
4167 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
4168 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4170 // If this is not the end of the statement, report an error.
4171 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4172 reportParseError("unexpected token, expected end of statement");
4176 return false; // parseDirectiveModule has finished successfully.
4177 } else if (Option == "nooddspreg") {
4179 Error(L, "'.module nooddspreg' requires the O32 ABI");
4183 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
4184 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4186 // If this is not the end of the statement, report an error.
4187 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4188 reportParseError("unexpected token, expected end of statement");
4192 return false; // parseDirectiveModule has finished successfully.
4193 } else if (Option == "fp") {
4194 return parseDirectiveModuleFP();
4196 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
4200 /// parseDirectiveModuleFP
4204 bool MipsAsmParser::parseDirectiveModuleFP() {
4205 MCAsmParser &Parser = getParser();
4206 MCAsmLexer &Lexer = getLexer();
4208 if (Lexer.isNot(AsmToken::Equal)) {
4209 reportParseError("unexpected token, expected equals sign '='");
4212 Parser.Lex(); // Eat '=' token.
4214 MipsABIFlagsSection::FpABIKind FpABI;
4215 if (!parseFpABIValue(FpABI, ".module"))
4218 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4219 reportParseError("unexpected token, expected end of statement");
4223 // Emit appropriate flags.
4224 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
4225 Parser.Lex(); // Consume the EndOfStatement.
4229 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
4230 StringRef Directive) {
4231 MCAsmParser &Parser = getParser();
4232 MCAsmLexer &Lexer = getLexer();
4234 if (Lexer.is(AsmToken::Identifier)) {
4235 StringRef Value = Parser.getTok().getString();
4238 if (Value != "xx") {
4239 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4244 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
4248 FpABI = MipsABIFlagsSection::FpABIKind::XX;
4252 if (Lexer.is(AsmToken::Integer)) {
4253 unsigned Value = Parser.getTok().getIntVal();
4256 if (Value != 32 && Value != 64) {
4257 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4263 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
4267 FpABI = MipsABIFlagsSection::FpABIKind::S32;
4269 FpABI = MipsABIFlagsSection::FpABIKind::S64;
4277 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
4278 MCAsmParser &Parser = getParser();
4279 StringRef IDVal = DirectiveID.getString();
4281 if (IDVal == ".cpload")
4282 return parseDirectiveCpLoad(DirectiveID.getLoc());
4283 if (IDVal == ".dword") {
4284 parseDataDirective(8, DirectiveID.getLoc());
4287 if (IDVal == ".ent") {
4288 StringRef SymbolName;
4290 if (Parser.parseIdentifier(SymbolName)) {
4291 reportParseError("expected identifier after .ent");
4295 // There's an undocumented extension that allows an integer to
4296 // follow the name of the procedure which AFAICS is ignored by GAS.
4297 // Example: .ent foo,2
4298 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4299 if (getLexer().isNot(AsmToken::Comma)) {
4300 // Even though we accept this undocumented extension for compatibility
4301 // reasons, the additional integer argument does not actually change
4302 // the behaviour of the '.ent' directive, so we would like to discourage
4303 // its use. We do this by not referring to the extended version in
4304 // error messages which are not directly related to its use.
4305 reportParseError("unexpected token, expected end of statement");
4308 Parser.Lex(); // Eat the comma.
4309 const MCExpr *DummyNumber;
4310 int64_t DummyNumberVal;
4311 // If the user was explicitly trying to use the extended version,
4312 // we still give helpful extension-related error messages.
4313 if (Parser.parseExpression(DummyNumber)) {
4314 reportParseError("expected number after comma");
4317 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
4318 reportParseError("expected an absolute expression after comma");
4323 // If this is not the end of the statement, report an error.
4324 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4325 reportParseError("unexpected token, expected end of statement");
4329 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
4331 getTargetStreamer().emitDirectiveEnt(*Sym);
4336 if (IDVal == ".end") {
4337 StringRef SymbolName;
4339 if (Parser.parseIdentifier(SymbolName)) {
4340 reportParseError("expected identifier after .end");
4344 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4345 reportParseError("unexpected token, expected end of statement");
4349 if (CurrentFn == nullptr) {
4350 reportParseError(".end used without .ent");
4354 if ((SymbolName != CurrentFn->getName())) {
4355 reportParseError(".end symbol does not match .ent symbol");
4359 getTargetStreamer().emitDirectiveEnd(SymbolName);
4360 CurrentFn = nullptr;
4364 if (IDVal == ".frame") {
4365 // .frame $stack_reg, frame_size_in_bytes, $return_reg
4366 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4367 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4368 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4369 reportParseError("expected stack register");
4373 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4374 if (!StackRegOpnd.isGPRAsmReg()) {
4375 reportParseError(StackRegOpnd.getStartLoc(),
4376 "expected general purpose register");
4379 unsigned StackReg = StackRegOpnd.getGPR32Reg();
4381 if (Parser.getTok().is(AsmToken::Comma))
4384 reportParseError("unexpected token, expected comma");
4388 // Parse the frame size.
4389 const MCExpr *FrameSize;
4390 int64_t FrameSizeVal;
4392 if (Parser.parseExpression(FrameSize)) {
4393 reportParseError("expected frame size value");
4397 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
4398 reportParseError("frame size not an absolute expression");
4402 if (Parser.getTok().is(AsmToken::Comma))
4405 reportParseError("unexpected token, expected comma");
4409 // Parse the return register.
4411 ResTy = parseAnyRegister(TmpReg);
4412 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4413 reportParseError("expected return register");
4417 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4418 if (!ReturnRegOpnd.isGPRAsmReg()) {
4419 reportParseError(ReturnRegOpnd.getStartLoc(),
4420 "expected general purpose register");
4424 // If this is not the end of the statement, report an error.
4425 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4426 reportParseError("unexpected token, expected end of statement");
4430 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
4431 ReturnRegOpnd.getGPR32Reg());
4435 if (IDVal == ".set") {
4436 return parseDirectiveSet();
4439 if (IDVal == ".mask" || IDVal == ".fmask") {
4440 // .mask bitmask, frame_offset
4441 // bitmask: One bit for each register used.
4442 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
4443 // first register is expected to be saved.
4445 // .mask 0x80000000, -4
4446 // .fmask 0x80000000, -4
4449 // Parse the bitmask
4450 const MCExpr *BitMask;
4453 if (Parser.parseExpression(BitMask)) {
4454 reportParseError("expected bitmask value");
4458 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
4459 reportParseError("bitmask not an absolute expression");
4463 if (Parser.getTok().is(AsmToken::Comma))
4466 reportParseError("unexpected token, expected comma");
4470 // Parse the frame_offset
4471 const MCExpr *FrameOffset;
4472 int64_t FrameOffsetVal;
4474 if (Parser.parseExpression(FrameOffset)) {
4475 reportParseError("expected frame offset value");
4479 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
4480 reportParseError("frame offset not an absolute expression");
4484 // If this is not the end of the statement, report an error.
4485 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4486 reportParseError("unexpected token, expected end of statement");
4490 if (IDVal == ".mask")
4491 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
4493 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
4497 if (IDVal == ".nan")
4498 return parseDirectiveNaN();
4500 if (IDVal == ".gpword") {
4501 parseDirectiveGpWord();
4505 if (IDVal == ".gpdword") {
4506 parseDirectiveGpDWord();
4510 if (IDVal == ".word") {
4511 parseDataDirective(4, DirectiveID.getLoc());
4515 if (IDVal == ".option")
4516 return parseDirectiveOption();
4518 if (IDVal == ".abicalls") {
4519 getTargetStreamer().emitDirectiveAbiCalls();
4520 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4521 Error(Parser.getTok().getLoc(),
4522 "unexpected token, expected end of statement");
4524 Parser.eatToEndOfStatement();
4529 if (IDVal == ".cpsetup")
4530 return parseDirectiveCPSetup();
4532 if (IDVal == ".module")
4533 return parseDirectiveModule();
4535 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
4536 return parseInternalDirectiveReallowModule();
4538 if (IDVal == ".insn")
4539 return parseInsnDirective();
4544 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
4545 // If this is not the end of the statement, report an error.
4546 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4547 reportParseError("unexpected token, expected end of statement");
4551 getTargetStreamer().reallowModuleDirective();
4553 getParser().Lex(); // Eat EndOfStatement token.
4557 extern "C" void LLVMInitializeMipsAsmParser() {
4558 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
4559 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
4560 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
4561 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
4564 #define GET_REGISTER_MATCHER
4565 #define GET_MATCHER_IMPLEMENTATION
4566 #include "MipsGenAsmMatcher.inc"