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(const FeatureBitset &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 const FeatureBitset &getFeatures() const { return Features; }
74 void setFeatures(const FeatureBitset &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;
87 FeatureBitset Features;
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 loadAndAddSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
190 unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc,
191 SmallVectorImpl<MCInst> &Instructions);
193 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
194 SmallVectorImpl<MCInst> &Instructions);
196 bool expandLoadAddressImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
197 SmallVectorImpl<MCInst> &Instructions);
199 bool expandLoadAddressReg(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
200 SmallVectorImpl<MCInst> &Instructions);
201 bool expandUncondBranchMMPseudo(MCInst &Inst, 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 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc,
212 SmallVectorImpl<MCInst> &Instructions);
214 bool expandCondBranches(MCInst &Inst, SMLoc IDLoc,
215 SmallVectorImpl<MCInst> &Instructions);
217 void createNop(bool hasShortDelaySlot, SMLoc IDLoc,
218 SmallVectorImpl<MCInst> &Instructions);
220 void createAddu(unsigned DstReg, unsigned SrcReg, unsigned TrgReg,
221 SmallVectorImpl<MCInst> &Instructions);
223 bool reportParseError(Twine ErrorMsg);
224 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
226 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
227 bool parseRelocOperand(const MCExpr *&Res);
229 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
231 bool isEvaluated(const MCExpr *Expr);
232 bool parseSetMips0Directive();
233 bool parseSetArchDirective();
234 bool parseSetFeature(uint64_t Feature);
235 bool parseDirectiveCpLoad(SMLoc Loc);
236 bool parseDirectiveCPSetup();
237 bool parseDirectiveNaN();
238 bool parseDirectiveSet();
239 bool parseDirectiveOption();
240 bool parseInsnDirective();
242 bool parseSetAtDirective();
243 bool parseSetNoAtDirective();
244 bool parseSetMacroDirective();
245 bool parseSetNoMacroDirective();
246 bool parseSetMsaDirective();
247 bool parseSetNoMsaDirective();
248 bool parseSetNoDspDirective();
249 bool parseSetReorderDirective();
250 bool parseSetNoReorderDirective();
251 bool parseSetMips16Directive();
252 bool parseSetNoMips16Directive();
253 bool parseSetFpDirective();
254 bool parseSetPopDirective();
255 bool parseSetPushDirective();
256 bool parseSetSoftFloatDirective();
257 bool parseSetHardFloatDirective();
259 bool parseSetAssignment();
261 bool parseDataDirective(unsigned Size, SMLoc L);
262 bool parseDirectiveGpWord();
263 bool parseDirectiveGpDWord();
264 bool parseDirectiveModule();
265 bool parseDirectiveModuleFP();
266 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
267 StringRef Directive);
269 bool parseInternalDirectiveReallowModule();
271 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
273 bool eatComma(StringRef ErrorStr);
275 int matchCPURegisterName(StringRef Symbol);
277 int matchHWRegsRegisterName(StringRef Symbol);
279 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
281 int matchFPURegisterName(StringRef Name);
283 int matchFCCRegisterName(StringRef Name);
285 int matchACRegisterName(StringRef Name);
287 int matchMSA128RegisterName(StringRef Name);
289 int matchMSA128CtrlRegisterName(StringRef Name);
291 unsigned getReg(int RC, int RegNo);
293 unsigned getGPR(int RegNo);
295 /// Returns the internal register number for the current AT. Also checks if
296 /// the current AT is unavailable (set to $0) and gives an error if it is.
297 /// This should be used in pseudo-instruction expansions which need AT.
298 unsigned getATReg(SMLoc Loc);
300 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
301 SmallVectorImpl<MCInst> &Instructions);
303 // Helper function that checks if the value of a vector index is within the
304 // boundaries of accepted values for each RegisterKind
305 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
306 bool validateMSAIndex(int Val, int RegKind);
308 // Selects a new architecture by updating the FeatureBits with the necessary
309 // info including implied dependencies.
310 // Internally, it clears all the feature bits related to *any* architecture
311 // and selects the new one using the ToggleFeature functionality of the
312 // MCSubtargetInfo object that handles implied dependencies. The reason we
313 // clear all the arch related bits manually is because ToggleFeature only
314 // clears the features that imply the feature being cleared and not the
315 // features implied by the feature being cleared. This is easier to see
317 // --------------------------------------------------
318 // | Feature | Implies |
319 // | -------------------------------------------------|
320 // | FeatureMips1 | None |
321 // | FeatureMips2 | FeatureMips1 |
322 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
323 // | FeatureMips4 | FeatureMips3 |
325 // --------------------------------------------------
327 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
328 // FeatureMipsGP64 | FeatureMips1)
329 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
330 void selectArch(StringRef ArchFeature) {
331 FeatureBitset FeatureBits = STI.getFeatureBits();
332 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
333 STI.setFeatureBits(FeatureBits);
334 setAvailableFeatures(
335 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
336 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
339 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
340 if (!(STI.getFeatureBits()[Feature])) {
341 setAvailableFeatures(
342 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
343 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
347 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
348 if (STI.getFeatureBits()[Feature]) {
349 setAvailableFeatures(
350 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
351 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
356 enum MipsMatchResultTy {
357 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
358 #define GET_OPERAND_DIAGNOSTIC_TYPES
359 #include "MipsGenAsmMatcher.inc"
360 #undef GET_OPERAND_DIAGNOSTIC_TYPES
364 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
365 const MCInstrInfo &MII, const MCTargetOptions &Options)
366 : MCTargetAsmParser(), STI(sti),
367 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
368 sti.getCPU(), Options)) {
369 MCAsmParserExtension::Initialize(parser);
371 parser.addAliasForDirective(".asciiz", ".asciz");
373 // Initialize the set of available features.
374 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
376 // Remember the initial assembler options. The user can not modify these.
377 AssemblerOptions.push_back(
378 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
380 // Create an assembler options environment for the user to modify.
381 AssemblerOptions.push_back(
382 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
384 getTargetStreamer().updateABIInfo(*this);
386 if (!isABI_O32() && !useOddSPReg() != 0)
387 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
392 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
393 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
395 bool isGP64bit() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
396 bool isFP64bit() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }
397 const MipsABIInfo &getABI() const { return ABI; }
398 bool isABI_N32() const { return ABI.IsN32(); }
399 bool isABI_N64() const { return ABI.IsN64(); }
400 bool isABI_O32() const { return ABI.IsO32(); }
401 bool isABI_FPXX() const { return STI.getFeatureBits()[Mips::FeatureFPXX]; }
403 bool useOddSPReg() const {
404 return !(STI.getFeatureBits()[Mips::FeatureNoOddSPReg]);
407 bool inMicroMipsMode() const {
408 return STI.getFeatureBits()[Mips::FeatureMicroMips];
410 bool hasMips1() const { return STI.getFeatureBits()[Mips::FeatureMips1]; }
411 bool hasMips2() const { return STI.getFeatureBits()[Mips::FeatureMips2]; }
412 bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
413 bool hasMips4() const { return STI.getFeatureBits()[Mips::FeatureMips4]; }
414 bool hasMips5() const { return STI.getFeatureBits()[Mips::FeatureMips5]; }
415 bool hasMips32() const {
416 return STI.getFeatureBits()[Mips::FeatureMips32];
418 bool hasMips64() const {
419 return STI.getFeatureBits()[Mips::FeatureMips64];
421 bool hasMips32r2() const {
422 return STI.getFeatureBits()[Mips::FeatureMips32r2];
424 bool hasMips64r2() const {
425 return STI.getFeatureBits()[Mips::FeatureMips64r2];
427 bool hasMips32r3() const {
428 return (STI.getFeatureBits()[Mips::FeatureMips32r3]);
430 bool hasMips64r3() const {
431 return (STI.getFeatureBits()[Mips::FeatureMips64r3]);
433 bool hasMips32r5() const {
434 return (STI.getFeatureBits()[Mips::FeatureMips32r5]);
436 bool hasMips64r5() const {
437 return (STI.getFeatureBits()[Mips::FeatureMips64r5]);
439 bool hasMips32r6() const {
440 return STI.getFeatureBits()[Mips::FeatureMips32r6];
442 bool hasMips64r6() const {
443 return STI.getFeatureBits()[Mips::FeatureMips64r6];
446 bool hasDSP() const { return STI.getFeatureBits()[Mips::FeatureDSP]; }
447 bool hasDSPR2() const { return STI.getFeatureBits()[Mips::FeatureDSPR2]; }
448 bool hasMSA() const { return STI.getFeatureBits()[Mips::FeatureMSA]; }
449 bool hasCnMips() const {
450 return (STI.getFeatureBits()[Mips::FeatureCnMips]);
453 bool inMips16Mode() const {
454 return STI.getFeatureBits()[Mips::FeatureMips16];
457 bool useSoftFloat() const {
458 return STI.getFeatureBits()[Mips::FeatureSoftFloat];
461 /// Warn if RegIndex is the same as the current AT.
462 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
464 void warnIfNoMacro(SMLoc Loc);
470 /// MipsOperand - Instances of this class represent a parsed Mips machine
472 class MipsOperand : public MCParsedAsmOperand {
474 /// Broad categories of register classes
475 /// The exact class is finalized by the render method.
477 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
478 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
480 RegKind_FCC = 4, /// FCC
481 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
482 RegKind_MSACtrl = 16, /// MSA control registers
483 RegKind_COP2 = 32, /// COP2
484 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
486 RegKind_CCR = 128, /// CCR
487 RegKind_HWRegs = 256, /// HWRegs
488 RegKind_COP3 = 512, /// COP3
490 /// Potentially any (e.g. $1)
491 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
492 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
493 RegKind_CCR | RegKind_HWRegs | RegKind_COP3
498 k_Immediate, /// An immediate (possibly involving symbol references)
499 k_Memory, /// Base + Offset Memory Address
500 k_PhysRegister, /// A physical register from the Mips namespace
501 k_RegisterIndex, /// A register index in one or more RegKind.
502 k_Token, /// A simple token
503 k_RegList, /// A physical register list
504 k_RegPair /// A pair of physical register
508 MipsOperand(KindTy K, MipsAsmParser &Parser)
509 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
512 /// For diagnostics, and checking the assembler temporary
513 MipsAsmParser &AsmParser;
521 unsigned Num; /// Register Number
525 unsigned Index; /// Index into the register class
526 RegKind Kind; /// Bitfield of the kinds it could possibly be
527 const MCRegisterInfo *RegInfo;
540 SmallVector<unsigned, 10> *List;
545 struct PhysRegOp PhysReg;
546 struct RegIdxOp RegIdx;
549 struct RegListOp RegList;
552 SMLoc StartLoc, EndLoc;
554 /// Internal constructor for register kinds
555 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
556 const MCRegisterInfo *RegInfo,
558 MipsAsmParser &Parser) {
559 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
560 Op->RegIdx.Index = Index;
561 Op->RegIdx.RegInfo = RegInfo;
562 Op->RegIdx.Kind = RegKind;
569 /// Coerce the register to GPR32 and return the real register for the current
571 unsigned getGPR32Reg() const {
572 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
573 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
574 unsigned ClassID = Mips::GPR32RegClassID;
575 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
578 /// Coerce the register to GPR32 and return the real register for the current
580 unsigned getGPRMM16Reg() const {
581 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
582 unsigned ClassID = Mips::GPR32RegClassID;
583 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
586 /// Coerce the register to GPR64 and return the real register for the current
588 unsigned getGPR64Reg() const {
589 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
590 unsigned ClassID = Mips::GPR64RegClassID;
591 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
595 /// Coerce the register to AFGR64 and return the real register for the current
597 unsigned getAFGR64Reg() const {
598 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
599 if (RegIdx.Index % 2 != 0)
600 AsmParser.Warning(StartLoc, "Float register should be even.");
601 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
602 .getRegister(RegIdx.Index / 2);
605 /// Coerce the register to FGR64 and return the real register for the current
607 unsigned getFGR64Reg() const {
608 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
609 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
610 .getRegister(RegIdx.Index);
613 /// Coerce the register to FGR32 and return the real register for the current
615 unsigned getFGR32Reg() const {
616 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
617 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
618 .getRegister(RegIdx.Index);
621 /// Coerce the register to FGRH32 and return the real register for the current
623 unsigned getFGRH32Reg() const {
624 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
625 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
626 .getRegister(RegIdx.Index);
629 /// Coerce the register to FCC and return the real register for the current
631 unsigned getFCCReg() const {
632 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
633 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
634 .getRegister(RegIdx.Index);
637 /// Coerce the register to MSA128 and return the real register for the current
639 unsigned getMSA128Reg() const {
640 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
641 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
643 unsigned ClassID = Mips::MSA128BRegClassID;
644 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
647 /// Coerce the register to MSACtrl and return the real register for the
649 unsigned getMSACtrlReg() const {
650 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
651 unsigned ClassID = Mips::MSACtrlRegClassID;
652 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
655 /// Coerce the register to COP2 and return the real register for the
657 unsigned getCOP2Reg() const {
658 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
659 unsigned ClassID = Mips::COP2RegClassID;
660 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
663 /// Coerce the register to COP3 and return the real register for the
665 unsigned getCOP3Reg() const {
666 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
667 unsigned ClassID = Mips::COP3RegClassID;
668 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
671 /// Coerce the register to ACC64DSP and return the real register for the
673 unsigned getACC64DSPReg() const {
674 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
675 unsigned ClassID = Mips::ACC64DSPRegClassID;
676 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
679 /// Coerce the register to HI32DSP and return the real register for the
681 unsigned getHI32DSPReg() const {
682 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
683 unsigned ClassID = Mips::HI32DSPRegClassID;
684 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
687 /// Coerce the register to LO32DSP and return the real register for the
689 unsigned getLO32DSPReg() const {
690 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
691 unsigned ClassID = Mips::LO32DSPRegClassID;
692 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
695 /// Coerce the register to CCR and return the real register for the
697 unsigned getCCRReg() const {
698 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
699 unsigned ClassID = Mips::CCRRegClassID;
700 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
703 /// Coerce the register to HWRegs and return the real register for the
705 unsigned getHWRegsReg() const {
706 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
707 unsigned ClassID = Mips::HWRegsRegClassID;
708 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
712 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
713 // Add as immediate when possible. Null MCExpr = 0.
715 Inst.addOperand(MCOperand::createImm(0));
716 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
717 Inst.addOperand(MCOperand::createImm(CE->getValue()));
719 Inst.addOperand(MCOperand::createExpr(Expr));
722 void addRegOperands(MCInst &Inst, unsigned N) const {
723 llvm_unreachable("Use a custom parser instead");
726 /// Render the operand to an MCInst as a GPR32
727 /// Asserts if the wrong number of operands are requested, or the operand
728 /// is not a k_RegisterIndex compatible with RegKind_GPR
729 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
730 assert(N == 1 && "Invalid number of operands!");
731 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
734 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
735 assert(N == 1 && "Invalid number of operands!");
736 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
739 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
740 assert(N == 1 && "Invalid number of operands!");
741 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
744 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
745 assert(N == 1 && "Invalid number of operands!");
746 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
749 /// Render the operand to an MCInst as a GPR64
750 /// Asserts if the wrong number of operands are requested, or the operand
751 /// is not a k_RegisterIndex compatible with RegKind_GPR
752 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
753 assert(N == 1 && "Invalid number of operands!");
754 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
757 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
758 assert(N == 1 && "Invalid number of operands!");
759 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
762 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
763 assert(N == 1 && "Invalid number of operands!");
764 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
767 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
768 assert(N == 1 && "Invalid number of operands!");
769 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
770 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
771 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
772 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
776 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
777 assert(N == 1 && "Invalid number of operands!");
778 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
781 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
782 assert(N == 1 && "Invalid number of operands!");
783 Inst.addOperand(MCOperand::createReg(getFCCReg()));
786 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
787 assert(N == 1 && "Invalid number of operands!");
788 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
791 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
792 assert(N == 1 && "Invalid number of operands!");
793 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
796 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
797 assert(N == 1 && "Invalid number of operands!");
798 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
801 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
802 assert(N == 1 && "Invalid number of operands!");
803 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
806 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
807 assert(N == 1 && "Invalid number of operands!");
808 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
811 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
812 assert(N == 1 && "Invalid number of operands!");
813 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
816 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
817 assert(N == 1 && "Invalid number of operands!");
818 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
821 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
822 assert(N == 1 && "Invalid number of operands!");
823 Inst.addOperand(MCOperand::createReg(getCCRReg()));
826 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
827 assert(N == 1 && "Invalid number of operands!");
828 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
831 void addImmOperands(MCInst &Inst, unsigned N) const {
832 assert(N == 1 && "Invalid number of operands!");
833 const MCExpr *Expr = getImm();
837 void addMemOperands(MCInst &Inst, unsigned N) const {
838 assert(N == 2 && "Invalid number of operands!");
840 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPR32Reg()));
842 const MCExpr *Expr = getMemOff();
846 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
847 assert(N == 2 && "Invalid number of operands!");
849 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
851 const MCExpr *Expr = getMemOff();
855 void addRegListOperands(MCInst &Inst, unsigned N) const {
856 assert(N == 1 && "Invalid number of operands!");
858 for (auto RegNo : getRegList())
859 Inst.addOperand(MCOperand::createReg(RegNo));
862 void addRegPairOperands(MCInst &Inst, unsigned N) const {
863 assert(N == 2 && "Invalid number of operands!");
864 unsigned RegNo = getRegPair();
865 Inst.addOperand(MCOperand::createReg(RegNo++));
866 Inst.addOperand(MCOperand::createReg(RegNo));
869 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
870 assert(N == 2 && "Invalid number of operands!");
871 for (auto RegNo : getRegList())
872 Inst.addOperand(MCOperand::createReg(RegNo));
875 bool isReg() const override {
876 // As a special case until we sort out the definition of div/divu, pretend
877 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
878 if (isGPRAsmReg() && RegIdx.Index == 0)
881 return Kind == k_PhysRegister;
883 bool isRegIdx() const { return Kind == k_RegisterIndex; }
884 bool isImm() const override { return Kind == k_Immediate; }
885 bool isConstantImm() const {
886 return isImm() && dyn_cast<MCConstantExpr>(getImm());
888 template <unsigned Bits> bool isUImm() const {
889 return isImm() && isConstantImm() && isUInt<Bits>(getConstantImm());
891 bool isToken() const override {
892 // Note: It's not possible to pretend that other operand kinds are tokens.
893 // The matcher emitter checks tokens first.
894 return Kind == k_Token;
896 bool isMem() const override { return Kind == k_Memory; }
897 bool isConstantMemOff() const {
898 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
900 template <unsigned Bits> bool isMemWithSimmOffset() const {
901 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
903 bool isMemWithGRPMM16Base() const {
904 return isMem() && getMemBase()->isMM16AsmReg();
906 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
907 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
908 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
910 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
911 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
912 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
913 && (getMemBase()->getGPR32Reg() == Mips::SP);
915 bool isRegList16() const {
919 int Size = RegList.List->size();
920 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
921 RegList.List->back() != Mips::RA)
924 int PrevReg = *RegList.List->begin();
925 for (int i = 1; i < Size - 1; i++) {
926 int Reg = (*(RegList.List))[i];
927 if ( Reg != PrevReg + 1)
934 bool isInvNum() const { return Kind == k_Immediate; }
935 bool isLSAImm() const {
936 if (!isConstantImm())
938 int64_t Val = getConstantImm();
939 return 1 <= Val && Val <= 4;
941 bool isRegList() const { return Kind == k_RegList; }
942 bool isMovePRegPair() const {
943 if (Kind != k_RegList || RegList.List->size() != 2)
946 unsigned R0 = RegList.List->front();
947 unsigned R1 = RegList.List->back();
949 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
950 (R0 == Mips::A1 && R1 == Mips::A3) ||
951 (R0 == Mips::A2 && R1 == Mips::A3) ||
952 (R0 == Mips::A0 && R1 == Mips::S5) ||
953 (R0 == Mips::A0 && R1 == Mips::S6) ||
954 (R0 == Mips::A0 && R1 == Mips::A1) ||
955 (R0 == Mips::A0 && R1 == Mips::A2) ||
956 (R0 == Mips::A0 && R1 == Mips::A3))
962 StringRef getToken() const {
963 assert(Kind == k_Token && "Invalid access!");
964 return StringRef(Tok.Data, Tok.Length);
966 bool isRegPair() const { return Kind == k_RegPair; }
968 unsigned getReg() const override {
969 // As a special case until we sort out the definition of div/divu, pretend
970 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
971 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
972 RegIdx.Kind & RegKind_GPR)
973 return getGPR32Reg(); // FIXME: GPR64 too
975 assert(Kind == k_PhysRegister && "Invalid access!");
979 const MCExpr *getImm() const {
980 assert((Kind == k_Immediate) && "Invalid access!");
984 int64_t getConstantImm() const {
985 const MCExpr *Val = getImm();
986 return static_cast<const MCConstantExpr *>(Val)->getValue();
989 MipsOperand *getMemBase() const {
990 assert((Kind == k_Memory) && "Invalid access!");
994 const MCExpr *getMemOff() const {
995 assert((Kind == k_Memory) && "Invalid access!");
999 int64_t getConstantMemOff() const {
1000 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1003 const SmallVectorImpl<unsigned> &getRegList() const {
1004 assert((Kind == k_RegList) && "Invalid access!");
1005 return *(RegList.List);
1008 unsigned getRegPair() const {
1009 assert((Kind == k_RegPair) && "Invalid access!");
1010 return RegIdx.Index;
1013 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1014 MipsAsmParser &Parser) {
1015 auto Op = make_unique<MipsOperand>(k_Token, Parser);
1016 Op->Tok.Data = Str.data();
1017 Op->Tok.Length = Str.size();
1023 /// Create a numeric register (e.g. $1). The exact register remains
1024 /// unresolved until an instruction successfully matches
1025 static std::unique_ptr<MipsOperand>
1026 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1027 SMLoc E, MipsAsmParser &Parser) {
1028 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1029 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1032 /// Create a register that is definitely a GPR.
1033 /// This is typically only used for named registers such as $gp.
1034 static std::unique_ptr<MipsOperand>
1035 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1036 MipsAsmParser &Parser) {
1037 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1040 /// Create a register that is definitely a FGR.
1041 /// This is typically only used for named registers such as $f0.
1042 static std::unique_ptr<MipsOperand>
1043 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1044 MipsAsmParser &Parser) {
1045 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1048 /// Create a register that is definitely a HWReg.
1049 /// This is typically only used for named registers such as $hwr_cpunum.
1050 static std::unique_ptr<MipsOperand>
1051 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1052 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1053 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1056 /// Create a register that is definitely an FCC.
1057 /// This is typically only used for named registers such as $fcc0.
1058 static std::unique_ptr<MipsOperand>
1059 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1060 MipsAsmParser &Parser) {
1061 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1064 /// Create a register that is definitely an ACC.
1065 /// This is typically only used for named registers such as $ac0.
1066 static std::unique_ptr<MipsOperand>
1067 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1068 MipsAsmParser &Parser) {
1069 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1072 /// Create a register that is definitely an MSA128.
1073 /// This is typically only used for named registers such as $w0.
1074 static std::unique_ptr<MipsOperand>
1075 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1076 SMLoc E, MipsAsmParser &Parser) {
1077 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1080 /// Create a register that is definitely an MSACtrl.
1081 /// This is typically only used for named registers such as $msaaccess.
1082 static std::unique_ptr<MipsOperand>
1083 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1084 SMLoc E, MipsAsmParser &Parser) {
1085 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1088 static std::unique_ptr<MipsOperand>
1089 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1090 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1097 static std::unique_ptr<MipsOperand>
1098 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1099 SMLoc E, MipsAsmParser &Parser) {
1100 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1101 Op->Mem.Base = Base.release();
1108 static std::unique_ptr<MipsOperand>
1109 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1110 MipsAsmParser &Parser) {
1111 assert (Regs.size() > 0 && "Empty list not allowed");
1113 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1114 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1115 Op->StartLoc = StartLoc;
1116 Op->EndLoc = EndLoc;
1120 static std::unique_ptr<MipsOperand>
1121 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1122 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1123 Op->RegIdx.Index = RegNo;
1129 bool isGPRAsmReg() const {
1130 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1132 bool isMM16AsmReg() const {
1133 if (!(isRegIdx() && RegIdx.Kind))
1135 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1136 || RegIdx.Index == 16 || RegIdx.Index == 17);
1138 bool isMM16AsmRegZero() const {
1139 if (!(isRegIdx() && RegIdx.Kind))
1141 return (RegIdx.Index == 0 ||
1142 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1143 RegIdx.Index == 17);
1145 bool isMM16AsmRegMoveP() const {
1146 if (!(isRegIdx() && RegIdx.Kind))
1148 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1149 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1151 bool isFGRAsmReg() const {
1152 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1153 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1155 bool isHWRegsAsmReg() const {
1156 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1158 bool isCCRAsmReg() const {
1159 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1161 bool isFCCAsmReg() const {
1162 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1164 if (!AsmParser.hasEightFccRegisters())
1165 return RegIdx.Index == 0;
1166 return RegIdx.Index <= 7;
1168 bool isACCAsmReg() const {
1169 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1171 bool isCOP2AsmReg() const {
1172 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1174 bool isCOP3AsmReg() const {
1175 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1177 bool isMSA128AsmReg() const {
1178 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1180 bool isMSACtrlAsmReg() const {
1181 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1184 /// getStartLoc - Get the location of the first token of this operand.
1185 SMLoc getStartLoc() const override { return StartLoc; }
1186 /// getEndLoc - Get the location of the last token of this operand.
1187 SMLoc getEndLoc() const override { return EndLoc; }
1189 virtual ~MipsOperand() {
1197 delete RegList.List;
1198 case k_PhysRegister:
1199 case k_RegisterIndex:
1206 void print(raw_ostream &OS) const override {
1215 Mem.Base->print(OS);
1220 case k_PhysRegister:
1221 OS << "PhysReg<" << PhysReg.Num << ">";
1223 case k_RegisterIndex:
1224 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1231 for (auto Reg : (*RegList.List))
1236 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1240 }; // class MipsOperand
1244 extern const MCInstrDesc MipsInsts[];
1246 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1247 return MipsInsts[Opcode];
1250 static bool hasShortDelaySlot(unsigned Opcode) {
1253 case Mips::JALRS_MM:
1254 case Mips::JALRS16_MM:
1255 case Mips::BGEZALS_MM:
1256 case Mips::BLTZALS_MM:
1263 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1264 SmallVectorImpl<MCInst> &Instructions) {
1265 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1269 if (MCID.isBranch() || MCID.isCall()) {
1270 const unsigned Opcode = Inst.getOpcode();
1280 assert(hasCnMips() && "instruction only valid for octeon cpus");
1287 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1288 Offset = Inst.getOperand(2);
1289 if (!Offset.isImm())
1290 break; // We'll deal with this situation later on when applying fixups.
1291 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1292 return Error(IDLoc, "branch target out of range");
1293 if (OffsetToAlignment(Offset.getImm(),
1294 1LL << (inMicroMipsMode() ? 1 : 2)))
1295 return Error(IDLoc, "branch to misaligned address");
1309 case Mips::BGEZAL_MM:
1310 case Mips::BLTZAL_MM:
1313 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1314 Offset = Inst.getOperand(1);
1315 if (!Offset.isImm())
1316 break; // We'll deal with this situation later on when applying fixups.
1317 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1318 return Error(IDLoc, "branch target out of range");
1319 if (OffsetToAlignment(Offset.getImm(),
1320 1LL << (inMicroMipsMode() ? 1 : 2)))
1321 return Error(IDLoc, "branch to misaligned address");
1323 case Mips::BEQZ16_MM:
1324 case Mips::BNEZ16_MM:
1325 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1326 Offset = Inst.getOperand(1);
1327 if (!Offset.isImm())
1328 break; // We'll deal with this situation later on when applying fixups.
1329 if (!isIntN(8, Offset.getImm()))
1330 return Error(IDLoc, "branch target out of range");
1331 if (OffsetToAlignment(Offset.getImm(), 2LL))
1332 return Error(IDLoc, "branch to misaligned address");
1337 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1338 // We still accept it but it is a normal nop.
1339 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1340 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1341 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1346 const unsigned Opcode = Inst.getOpcode();
1358 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1359 // The offset is handled above
1360 Opnd = Inst.getOperand(1);
1362 return Error(IDLoc, "expected immediate operand kind");
1363 Imm = Opnd.getImm();
1364 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1365 Opcode == Mips::BBIT1 ? 63 : 31))
1366 return Error(IDLoc, "immediate operand value out of range");
1368 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1370 Inst.getOperand(1).setImm(Imm - 32);
1378 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1380 Opnd = Inst.getOperand(3);
1382 return Error(IDLoc, "expected immediate operand kind");
1383 Imm = Opnd.getImm();
1384 if (Imm < 0 || Imm > 31)
1385 return Error(IDLoc, "immediate operand value out of range");
1387 Opnd = Inst.getOperand(2);
1389 return Error(IDLoc, "expected immediate operand kind");
1390 Imm = Opnd.getImm();
1391 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1392 Opcode == Mips::EXTS ? 63 : 31))
1393 return Error(IDLoc, "immediate operand value out of range");
1395 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1396 Inst.getOperand(2).setImm(Imm - 32);
1402 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1403 Opnd = Inst.getOperand(2);
1405 return Error(IDLoc, "expected immediate operand kind");
1406 Imm = Opnd.getImm();
1407 if (!isInt<10>(Imm))
1408 return Error(IDLoc, "immediate operand value out of range");
1413 if (MCID.mayLoad() || MCID.mayStore()) {
1414 // Check the offset of memory operand, if it is a symbol
1415 // reference or immediate we may have to expand instructions.
1416 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1417 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1418 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1419 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1420 MCOperand &Op = Inst.getOperand(i);
1422 int MemOffset = Op.getImm();
1423 if (MemOffset < -32768 || MemOffset > 32767) {
1424 // Offset can't exceed 16bit value.
1425 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1428 } else if (Op.isExpr()) {
1429 const MCExpr *Expr = Op.getExpr();
1430 if (Expr->getKind() == MCExpr::SymbolRef) {
1431 const MCSymbolRefExpr *SR =
1432 static_cast<const MCSymbolRefExpr *>(Expr);
1433 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1435 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1438 } else if (!isEvaluated(Expr)) {
1439 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1447 if (inMicroMipsMode()) {
1448 if (MCID.mayLoad()) {
1449 // Try to create 16-bit GP relative load instruction.
1450 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1451 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1452 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1453 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1454 MCOperand &Op = Inst.getOperand(i);
1456 int MemOffset = Op.getImm();
1457 MCOperand &DstReg = Inst.getOperand(0);
1458 MCOperand &BaseReg = Inst.getOperand(1);
1459 if (isIntN(9, MemOffset) && (MemOffset % 4 == 0) &&
1460 getContext().getRegisterInfo()->getRegClass(
1461 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1462 BaseReg.getReg() == Mips::GP) {
1464 TmpInst.setLoc(IDLoc);
1465 TmpInst.setOpcode(Mips::LWGP_MM);
1466 TmpInst.addOperand(MCOperand::createReg(DstReg.getReg()));
1467 TmpInst.addOperand(MCOperand::createReg(Mips::GP));
1468 TmpInst.addOperand(MCOperand::createImm(MemOffset));
1469 Instructions.push_back(TmpInst);
1477 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1482 switch (Inst.getOpcode()) {
1485 case Mips::ADDIUS5_MM:
1486 Opnd = Inst.getOperand(2);
1488 return Error(IDLoc, "expected immediate operand kind");
1489 Imm = Opnd.getImm();
1490 if (Imm < -8 || Imm > 7)
1491 return Error(IDLoc, "immediate operand value out of range");
1493 case Mips::ADDIUSP_MM:
1494 Opnd = Inst.getOperand(0);
1496 return Error(IDLoc, "expected immediate operand kind");
1497 Imm = Opnd.getImm();
1498 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1500 return Error(IDLoc, "immediate operand value out of range");
1502 case Mips::SLL16_MM:
1503 case Mips::SRL16_MM:
1504 Opnd = Inst.getOperand(2);
1506 return Error(IDLoc, "expected immediate operand kind");
1507 Imm = Opnd.getImm();
1508 if (Imm < 1 || Imm > 8)
1509 return Error(IDLoc, "immediate operand value out of range");
1512 Opnd = Inst.getOperand(1);
1514 return Error(IDLoc, "expected immediate operand kind");
1515 Imm = Opnd.getImm();
1516 if (Imm < -1 || Imm > 126)
1517 return Error(IDLoc, "immediate operand value out of range");
1519 case Mips::ADDIUR2_MM:
1520 Opnd = Inst.getOperand(2);
1522 return Error(IDLoc, "expected immediate operand kind");
1523 Imm = Opnd.getImm();
1524 if (!(Imm == 1 || Imm == -1 ||
1525 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1526 return Error(IDLoc, "immediate operand value out of range");
1528 case Mips::ADDIUR1SP_MM:
1529 Opnd = Inst.getOperand(1);
1531 return Error(IDLoc, "expected immediate operand kind");
1532 Imm = Opnd.getImm();
1533 if (OffsetToAlignment(Imm, 4LL))
1534 return Error(IDLoc, "misaligned immediate operand value");
1535 if (Imm < 0 || Imm > 255)
1536 return Error(IDLoc, "immediate operand value out of range");
1538 case Mips::ANDI16_MM:
1539 Opnd = Inst.getOperand(2);
1541 return Error(IDLoc, "expected immediate operand kind");
1542 Imm = Opnd.getImm();
1543 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1544 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1545 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1546 return Error(IDLoc, "immediate operand value out of range");
1548 case Mips::LBU16_MM:
1549 Opnd = Inst.getOperand(2);
1551 return Error(IDLoc, "expected immediate operand kind");
1552 Imm = Opnd.getImm();
1553 if (Imm < -1 || Imm > 14)
1554 return Error(IDLoc, "immediate operand value out of range");
1557 Opnd = Inst.getOperand(2);
1559 return Error(IDLoc, "expected immediate operand kind");
1560 Imm = Opnd.getImm();
1561 if (Imm < 0 || Imm > 15)
1562 return Error(IDLoc, "immediate operand value out of range");
1564 case Mips::LHU16_MM:
1566 Opnd = Inst.getOperand(2);
1568 return Error(IDLoc, "expected immediate operand kind");
1569 Imm = Opnd.getImm();
1570 if (Imm < 0 || Imm > 30 || (Imm % 2 != 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 (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1580 return Error(IDLoc, "immediate operand value out of range");
1584 Opnd = Inst.getOperand(2);
1586 return Error(IDLoc, "expected immediate operand kind");
1587 Imm = Opnd.getImm();
1588 if (!isUInt<5>(Imm))
1589 return Error(IDLoc, "immediate operand value out of range");
1591 case Mips::ADDIUPC_MM:
1592 MCOperand Opnd = Inst.getOperand(1);
1594 return Error(IDLoc, "expected immediate operand kind");
1595 int Imm = Opnd.getImm();
1596 if ((Imm % 4 != 0) || !isIntN(25, Imm))
1597 return Error(IDLoc, "immediate operand value out of range");
1602 if (needsExpansion(Inst)) {
1603 if (expandInstruction(Inst, IDLoc, Instructions))
1606 Instructions.push_back(Inst);
1608 // If this instruction has a delay slot and .set reorder is active,
1609 // emit a NOP after it.
1610 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1611 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1616 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1618 switch (Inst.getOpcode()) {
1619 case Mips::LoadImm32:
1620 case Mips::LoadImm64:
1621 case Mips::LoadAddrImm32:
1622 case Mips::LoadAddrReg32:
1623 case Mips::B_MM_Pseudo:
1626 case Mips::JalOneReg:
1627 case Mips::JalTwoReg:
1644 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1645 SmallVectorImpl<MCInst> &Instructions) {
1646 switch (Inst.getOpcode()) {
1647 default: llvm_unreachable("unimplemented expansion");
1648 case Mips::LoadImm32:
1649 return expandLoadImm(Inst, true, IDLoc, Instructions);
1650 case Mips::LoadImm64:
1651 return expandLoadImm(Inst, false, IDLoc, Instructions);
1652 case Mips::LoadAddrImm32:
1653 return expandLoadAddressImm(Inst, true, IDLoc, Instructions);
1654 case Mips::LoadAddrReg32:
1655 return expandLoadAddressReg(Inst, true, IDLoc, Instructions);
1656 case Mips::B_MM_Pseudo:
1657 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1660 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
1661 case Mips::JalOneReg:
1662 case Mips::JalTwoReg:
1663 return expandJalWithRegs(Inst, IDLoc, Instructions);
1666 return expandBranchImm(Inst, IDLoc, Instructions);
1675 return expandCondBranches(Inst, IDLoc, Instructions);
1680 template <unsigned ShiftAmount>
1681 void createLShiftOri(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1682 SmallVectorImpl<MCInst> &Instructions) {
1684 if (ShiftAmount >= 32) {
1685 tmpInst.setOpcode(Mips::DSLL32);
1686 tmpInst.addOperand(MCOperand::createReg(RegNo));
1687 tmpInst.addOperand(MCOperand::createReg(RegNo));
1688 tmpInst.addOperand(MCOperand::createImm(ShiftAmount - 32));
1689 tmpInst.setLoc(IDLoc);
1690 Instructions.push_back(tmpInst);
1692 } else if (ShiftAmount > 0) {
1693 tmpInst.setOpcode(Mips::DSLL);
1694 tmpInst.addOperand(MCOperand::createReg(RegNo));
1695 tmpInst.addOperand(MCOperand::createReg(RegNo));
1696 tmpInst.addOperand(MCOperand::createImm(ShiftAmount));
1697 tmpInst.setLoc(IDLoc);
1698 Instructions.push_back(tmpInst);
1701 // There's no need for an ORi if the immediate is 0.
1702 if (Operand.isImm() && Operand.getImm() == 0)
1705 tmpInst.setOpcode(Mips::ORi);
1706 tmpInst.addOperand(MCOperand::createReg(RegNo));
1707 tmpInst.addOperand(MCOperand::createReg(RegNo));
1708 tmpInst.addOperand(Operand);
1709 tmpInst.setLoc(IDLoc);
1710 Instructions.push_back(tmpInst);
1713 template <unsigned ShiftAmount>
1714 void createLShiftOri(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1715 SmallVectorImpl<MCInst> &Instructions) {
1716 createLShiftOri<ShiftAmount>(MCOperand::createImm(Value), RegNo, IDLoc,
1721 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
1722 SmallVectorImpl<MCInst> &Instructions) {
1723 // Create a JALR instruction which is going to replace the pseudo-JAL.
1725 JalrInst.setLoc(IDLoc);
1726 const MCOperand FirstRegOp = Inst.getOperand(0);
1727 const unsigned Opcode = Inst.getOpcode();
1729 if (Opcode == Mips::JalOneReg) {
1730 // jal $rs => jalr $rs
1731 if (inMicroMipsMode()) {
1732 JalrInst.setOpcode(Mips::JALR16_MM);
1733 JalrInst.addOperand(FirstRegOp);
1735 JalrInst.setOpcode(Mips::JALR);
1736 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1737 JalrInst.addOperand(FirstRegOp);
1739 } else if (Opcode == Mips::JalTwoReg) {
1740 // jal $rd, $rs => jalr $rd, $rs
1741 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1742 JalrInst.addOperand(FirstRegOp);
1743 const MCOperand SecondRegOp = Inst.getOperand(1);
1744 JalrInst.addOperand(SecondRegOp);
1746 Instructions.push_back(JalrInst);
1748 // If .set reorder is active, emit a NOP after it.
1749 if (AssemblerOptions.back()->isReorder()) {
1750 // This is a 32-bit NOP because these 2 pseudo-instructions
1751 // do not have a short delay slot.
1753 NopInst.setOpcode(Mips::SLL);
1754 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
1755 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
1756 NopInst.addOperand(MCOperand::createImm(0));
1757 Instructions.push_back(NopInst);
1763 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
1764 unsigned SrcReg, bool Is32BitImm, SMLoc IDLoc,
1765 SmallVectorImpl<MCInst> &Instructions) {
1766 if (!Is32BitImm && !isGP64bit()) {
1767 Error(IDLoc, "instruction requires a 64-bit architecture");
1771 bool UseSrcReg = false;
1772 if (SrcReg != Mips::NoRegister)
1777 tmpInst.setLoc(IDLoc);
1778 // FIXME: gas has a special case for values that are 000...1111, which
1779 // becomes a li -1 and then a dsrl
1780 if (0 <= ImmValue && ImmValue <= 65535) {
1781 // For unsigned and positive signed 16-bit values (0 <= j <= 65535):
1782 // li d,j => ori d,$zero,j
1784 SrcReg = isGP64bit() ? Mips::ZERO_64 : Mips::ZERO;
1785 tmpInst.setOpcode(Mips::ORi);
1786 tmpInst.addOperand(MCOperand::createReg(DstReg));
1787 tmpInst.addOperand(MCOperand::createReg(SrcReg));
1788 tmpInst.addOperand(MCOperand::createImm(ImmValue));
1789 Instructions.push_back(tmpInst);
1790 } else if (ImmValue < 0 && ImmValue >= -32768) {
1791 // For negative signed 16-bit values (-32768 <= j < 0):
1792 // li d,j => addiu d,$zero,j
1794 SrcReg = Mips::ZERO;
1795 tmpInst.setOpcode(Mips::ADDiu);
1796 tmpInst.addOperand(MCOperand::createReg(DstReg));
1797 tmpInst.addOperand(MCOperand::createReg(SrcReg));
1798 tmpInst.addOperand(MCOperand::createImm(ImmValue));
1799 Instructions.push_back(tmpInst);
1800 } else if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
1801 warnIfNoMacro(IDLoc);
1803 // For all other values which are representable as a 32-bit integer:
1804 // li d,j => lui d,hi16(j)
1806 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1807 uint16_t Bits15To0 = ImmValue & 0xffff;
1809 if (!Is32BitImm && !isInt<32>(ImmValue)) {
1810 // For DLI, expand to an ORi instead of a LUi to avoid sign-extending the
1812 tmpInst.setOpcode(Mips::ORi);
1813 tmpInst.addOperand(MCOperand::createReg(DstReg));
1814 tmpInst.addOperand(MCOperand::createReg(Mips::ZERO));
1815 tmpInst.addOperand(MCOperand::createImm(Bits31To16));
1816 tmpInst.setLoc(IDLoc);
1817 Instructions.push_back(tmpInst);
1818 // Move the value to the upper 16 bits by doing a 16-bit left shift.
1819 createLShiftOri<16>(0, DstReg, IDLoc, Instructions);
1821 tmpInst.setOpcode(Mips::LUi);
1822 tmpInst.addOperand(MCOperand::createReg(DstReg));
1823 tmpInst.addOperand(MCOperand::createImm(Bits31To16));
1824 Instructions.push_back(tmpInst);
1826 createLShiftOri<0>(Bits15To0, DstReg, IDLoc, Instructions);
1829 createAddu(DstReg, DstReg, SrcReg, Instructions);
1831 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1833 Error(IDLoc, "instruction requires a 32-bit immediate");
1836 warnIfNoMacro(IDLoc);
1838 // <------- lo32 ------>
1839 // <------- hi32 ------>
1840 // <- hi16 -> <- lo16 ->
1841 // _________________________________
1843 // | 16-bits | 16-bits | 16-bits |
1844 // |__________|__________|__________|
1846 // For any 64-bit value that is representable as a 48-bit integer:
1847 // li d,j => lui d,hi16(j)
1848 // ori d,d,hi16(lo32(j))
1850 // ori d,d,lo16(lo32(j))
1851 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1852 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1853 uint16_t Bits15To0 = ImmValue & 0xffff;
1855 tmpInst.setOpcode(Mips::LUi);
1856 tmpInst.addOperand(MCOperand::createReg(DstReg));
1857 tmpInst.addOperand(MCOperand::createImm(Bits47To32));
1858 Instructions.push_back(tmpInst);
1859 createLShiftOri<0>(Bits31To16, DstReg, IDLoc, Instructions);
1860 createLShiftOri<16>(Bits15To0, DstReg, IDLoc, Instructions);
1863 createAddu(DstReg, DstReg, SrcReg, Instructions);
1867 Error(IDLoc, "instruction requires a 32-bit immediate");
1870 warnIfNoMacro(IDLoc);
1872 // <------- hi32 ------> <------- lo32 ------>
1873 // <- hi16 -> <- lo16 ->
1874 // ___________________________________________
1876 // | 16-bits | 16-bits | 16-bits | 16-bits |
1877 // |__________|__________|__________|__________|
1879 // For all other values which are representable as a 64-bit integer:
1880 // li d,j => lui d,hi16(j)
1881 // ori d,d,lo16(hi32(j))
1883 // ori d,d,hi16(lo32(j))
1885 // ori d,d,lo16(lo32(j))
1886 uint16_t Bits63To48 = (ImmValue >> 48) & 0xffff;
1887 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1888 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1889 uint16_t Bits15To0 = ImmValue & 0xffff;
1891 tmpInst.setOpcode(Mips::LUi);
1892 tmpInst.addOperand(MCOperand::createReg(DstReg));
1893 tmpInst.addOperand(MCOperand::createImm(Bits63To48));
1894 Instructions.push_back(tmpInst);
1895 createLShiftOri<0>(Bits47To32, DstReg, IDLoc, Instructions);
1897 // When Bits31To16 is 0, do a left shift of 32 bits instead of doing
1898 // two left shifts of 16 bits.
1899 if (Bits31To16 == 0) {
1900 createLShiftOri<32>(Bits15To0, DstReg, IDLoc, Instructions);
1902 createLShiftOri<16>(Bits31To16, DstReg, IDLoc, Instructions);
1903 createLShiftOri<16>(Bits15To0, DstReg, IDLoc, Instructions);
1907 createAddu(DstReg, DstReg, SrcReg, Instructions);
1912 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1913 SmallVectorImpl<MCInst> &Instructions) {
1914 const MCOperand &ImmOp = Inst.getOperand(1);
1915 assert(ImmOp.isImm() && "expected immediate operand kind");
1916 const MCOperand &DstRegOp = Inst.getOperand(0);
1917 assert(DstRegOp.isReg() && "expected register operand kind");
1919 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
1920 Is32BitImm, IDLoc, Instructions))
1927 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1928 SmallVectorImpl<MCInst> &Instructions) {
1929 const MCOperand &DstRegOp = Inst.getOperand(0);
1930 assert(DstRegOp.isReg() && "expected register operand kind");
1932 const MCOperand &SrcRegOp = Inst.getOperand(1);
1933 assert(SrcRegOp.isReg() && "expected register operand kind");
1935 const MCOperand &ImmOp = Inst.getOperand(2);
1936 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1937 "expected immediate operand kind");
1938 if (!ImmOp.isImm()) {
1939 if (loadAndAddSymbolAddress(ImmOp.getExpr(), DstRegOp.getReg(),
1940 SrcRegOp.getReg(), Is32BitImm, IDLoc,
1947 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), SrcRegOp.getReg(),
1948 Is32BitImm, IDLoc, Instructions))
1955 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1956 SmallVectorImpl<MCInst> &Instructions) {
1957 const MCOperand &DstRegOp = Inst.getOperand(0);
1958 assert(DstRegOp.isReg() && "expected register operand kind");
1960 const MCOperand &ImmOp = Inst.getOperand(1);
1961 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1962 "expected immediate operand kind");
1963 if (!ImmOp.isImm()) {
1964 if (loadAndAddSymbolAddress(ImmOp.getExpr(), DstRegOp.getReg(),
1965 Mips::NoRegister, Is32BitImm, IDLoc,
1972 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
1973 Is32BitImm, IDLoc, Instructions))
1979 bool MipsAsmParser::loadAndAddSymbolAddress(
1980 const MCExpr *SymExpr, unsigned DstReg, unsigned SrcReg, bool Is32BitSym,
1981 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1982 warnIfNoMacro(IDLoc);
1984 if (Is32BitSym && isABI_N64())
1985 Warning(IDLoc, "instruction loads the 32-bit address of a 64-bit symbol");
1988 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymExpr);
1989 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::create(
1990 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1991 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::create(
1992 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1994 bool UseSrcReg = SrcReg != Mips::NoRegister;
1996 unsigned TmpReg = DstReg;
1997 if (UseSrcReg && (DstReg == SrcReg)) {
1998 // At this point we need AT to perform the expansions and we exit if it is
2000 unsigned ATReg = getATReg(IDLoc);
2007 // If it's a 64-bit architecture, expand to:
2008 // la d,sym => lui d,highest(sym)
2009 // ori d,d,higher(sym)
2011 // ori d,d,hi16(sym)
2013 // ori d,d,lo16(sym)
2014 const MCSymbolRefExpr *HighestExpr = MCSymbolRefExpr::create(
2015 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
2016 const MCSymbolRefExpr *HigherExpr = MCSymbolRefExpr::create(
2017 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
2019 tmpInst.setOpcode(Mips::LUi);
2020 tmpInst.addOperand(MCOperand::createReg(TmpReg));
2021 tmpInst.addOperand(MCOperand::createExpr(HighestExpr));
2022 Instructions.push_back(tmpInst);
2024 createLShiftOri<0>(MCOperand::createExpr(HigherExpr), TmpReg, SMLoc(),
2026 createLShiftOri<16>(MCOperand::createExpr(HiExpr), TmpReg, SMLoc(),
2028 createLShiftOri<16>(MCOperand::createExpr(LoExpr), TmpReg, SMLoc(),
2031 // Otherwise, expand to:
2032 // la d,sym => lui d,hi16(sym)
2033 // ori d,d,lo16(sym)
2034 tmpInst.setOpcode(Mips::LUi);
2035 tmpInst.addOperand(MCOperand::createReg(TmpReg));
2036 tmpInst.addOperand(MCOperand::createExpr(HiExpr));
2037 Instructions.push_back(tmpInst);
2039 createLShiftOri<0>(MCOperand::createExpr(LoExpr), TmpReg, SMLoc(),
2044 createAddu(DstReg, TmpReg, SrcReg, Instructions);
2049 bool MipsAsmParser::expandUncondBranchMMPseudo(
2050 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2051 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2052 "unexpected number of operands");
2054 MCOperand Offset = Inst.getOperand(0);
2055 if (Offset.isExpr()) {
2057 Inst.setOpcode(Mips::BEQ_MM);
2058 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2059 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2060 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2062 assert(Offset.isImm() && "expected immediate operand kind");
2063 if (isIntN(11, Offset.getImm())) {
2064 // If offset fits into 11 bits then this instruction becomes microMIPS
2065 // 16-bit unconditional branch instruction.
2066 Inst.setOpcode(Mips::B16_MM);
2068 if (!isIntN(17, Offset.getImm()))
2069 Error(IDLoc, "branch target out of range");
2070 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2071 Error(IDLoc, "branch to misaligned address");
2073 Inst.setOpcode(Mips::BEQ_MM);
2074 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2075 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2076 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2079 Instructions.push_back(Inst);
2081 // If .set reorder is active, emit a NOP after the branch instruction.
2082 if (AssemblerOptions.back()->isReorder())
2083 createNop(true, IDLoc, Instructions);
2088 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc,
2089 SmallVectorImpl<MCInst> &Instructions) {
2090 const MCOperand &DstRegOp = Inst.getOperand(0);
2091 assert(DstRegOp.isReg() && "expected register operand kind");
2093 const MCOperand &ImmOp = Inst.getOperand(1);
2094 assert(ImmOp.isImm() && "expected immediate operand kind");
2096 const MCOperand &MemOffsetOp = Inst.getOperand(2);
2097 assert(MemOffsetOp.isImm() && "expected immediate operand kind");
2099 unsigned OpCode = 0;
2100 switch(Inst.getOpcode()) {
2108 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2112 int64_t ImmValue = ImmOp.getImm();
2113 if (ImmValue == 0) {
2115 BranchInst.setOpcode(OpCode);
2116 BranchInst.addOperand(DstRegOp);
2117 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2118 BranchInst.addOperand(MemOffsetOp);
2119 Instructions.push_back(BranchInst);
2121 warnIfNoMacro(IDLoc);
2123 unsigned ATReg = getATReg(IDLoc);
2127 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), IDLoc,
2132 BranchInst.setOpcode(OpCode);
2133 BranchInst.addOperand(DstRegOp);
2134 BranchInst.addOperand(MCOperand::createReg(ATReg));
2135 BranchInst.addOperand(MemOffsetOp);
2136 Instructions.push_back(BranchInst);
2141 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2142 SmallVectorImpl<MCInst> &Instructions,
2143 bool isLoad, bool isImmOpnd) {
2145 unsigned ImmOffset, HiOffset, LoOffset;
2146 const MCExpr *ExprOffset;
2148 // 1st operand is either the source or destination register.
2149 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2150 unsigned RegOpNum = Inst.getOperand(0).getReg();
2151 // 2nd operand is the base register.
2152 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2153 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2154 // 3rd operand is either an immediate or expression.
2156 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2157 ImmOffset = Inst.getOperand(2).getImm();
2158 LoOffset = ImmOffset & 0x0000ffff;
2159 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2160 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2161 if (LoOffset & 0x8000)
2164 ExprOffset = Inst.getOperand(2).getExpr();
2165 // All instructions will have the same location.
2166 TempInst.setLoc(IDLoc);
2167 // These are some of the types of expansions we perform here:
2168 // 1) lw $8, sym => lui $8, %hi(sym)
2169 // lw $8, %lo(sym)($8)
2170 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2172 // lw $8, %lo(offset)($9)
2173 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2175 // lw $8, %lo(offset)($at)
2176 // 4) sw $8, sym => lui $at, %hi(sym)
2177 // sw $8, %lo(sym)($at)
2178 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2180 // sw $8, %lo(offset)($at)
2181 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2182 // ldc1 $f0, %lo(sym)($at)
2184 // For load instructions we can use the destination register as a temporary
2185 // if base and dst are different (examples 1 and 2) and if the base register
2186 // is general purpose otherwise we must use $at (example 6) and error if it's
2187 // not available. For stores we must use $at (examples 4 and 5) because we
2188 // must not clobber the source register setting up the offset.
2189 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2190 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2191 unsigned RegClassIDOp0 =
2192 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2193 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2194 (RegClassIDOp0 == Mips::GPR64RegClassID);
2195 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2196 TmpRegNum = RegOpNum;
2198 // At this point we need AT to perform the expansions and we exit if it is
2200 TmpRegNum = getATReg(IDLoc);
2205 TempInst.setOpcode(Mips::LUi);
2206 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2208 TempInst.addOperand(MCOperand::createImm(HiOffset));
2210 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2211 TempInst.addOperand(MCOperand::createExpr(HiExpr));
2213 // Add the instruction to the list.
2214 Instructions.push_back(TempInst);
2215 // Prepare TempInst for next instruction.
2217 // Add temp register to base.
2218 if (BaseRegNum != Mips::ZERO) {
2219 TempInst.setOpcode(Mips::ADDu);
2220 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2221 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2222 TempInst.addOperand(MCOperand::createReg(BaseRegNum));
2223 Instructions.push_back(TempInst);
2226 // And finally, create original instruction with low part
2227 // of offset and new base.
2228 TempInst.setOpcode(Inst.getOpcode());
2229 TempInst.addOperand(MCOperand::createReg(RegOpNum));
2230 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2232 TempInst.addOperand(MCOperand::createImm(LoOffset));
2234 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2235 TempInst.addOperand(MCOperand::createExpr(LoExpr));
2237 Instructions.push_back(TempInst);
2242 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2243 SmallVectorImpl<MCInst> &Instructions) {
2244 unsigned OpNum = Inst.getNumOperands();
2245 unsigned Opcode = Inst.getOpcode();
2246 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2248 assert (Inst.getOperand(OpNum - 1).isImm() &&
2249 Inst.getOperand(OpNum - 2).isReg() &&
2250 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2252 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2253 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2254 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2255 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2256 // It can be implemented as SWM16 or LWM16 instruction.
2257 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2259 Inst.setOpcode(NewOpcode);
2260 Instructions.push_back(Inst);
2264 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
2265 SmallVectorImpl<MCInst> &Instructions) {
2266 unsigned PseudoOpcode = Inst.getOpcode();
2267 unsigned SrcReg = Inst.getOperand(0).getReg();
2268 unsigned TrgReg = Inst.getOperand(1).getReg();
2269 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
2271 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2272 bool ReverseOrderSLT, IsUnsigned, AcceptsEquality;
2274 switch (PseudoOpcode) {
2277 AcceptsEquality = false;
2278 ReverseOrderSLT = false;
2279 IsUnsigned = (PseudoOpcode == Mips::BLTU);
2280 ZeroSrcOpcode = Mips::BGTZ;
2281 ZeroTrgOpcode = Mips::BLTZ;
2285 AcceptsEquality = true;
2286 ReverseOrderSLT = true;
2287 IsUnsigned = (PseudoOpcode == Mips::BLEU);
2288 ZeroSrcOpcode = Mips::BGEZ;
2289 ZeroTrgOpcode = Mips::BLEZ;
2293 AcceptsEquality = true;
2294 ReverseOrderSLT = false;
2295 IsUnsigned = (PseudoOpcode == Mips::BGEU);
2296 ZeroSrcOpcode = Mips::BLEZ;
2297 ZeroTrgOpcode = Mips::BGEZ;
2301 AcceptsEquality = false;
2302 ReverseOrderSLT = true;
2303 IsUnsigned = (PseudoOpcode == Mips::BGTU);
2304 ZeroSrcOpcode = Mips::BLTZ;
2305 ZeroTrgOpcode = Mips::BGTZ;
2308 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2312 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
2313 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
2314 if (IsSrcRegZero && IsTrgRegZero) {
2315 // FIXME: All of these Opcode-specific if's are needed for compatibility
2316 // with GAS' behaviour. However, they may not generate the most efficient
2317 // code in some circumstances.
2318 if (PseudoOpcode == Mips::BLT) {
2319 BranchInst.setOpcode(Mips::BLTZ);
2320 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2321 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2322 Instructions.push_back(BranchInst);
2325 if (PseudoOpcode == Mips::BLE) {
2326 BranchInst.setOpcode(Mips::BLEZ);
2327 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2328 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2329 Instructions.push_back(BranchInst);
2330 Warning(IDLoc, "branch is always taken");
2333 if (PseudoOpcode == Mips::BGE) {
2334 BranchInst.setOpcode(Mips::BGEZ);
2335 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2336 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2337 Instructions.push_back(BranchInst);
2338 Warning(IDLoc, "branch is always taken");
2341 if (PseudoOpcode == Mips::BGT) {
2342 BranchInst.setOpcode(Mips::BGTZ);
2343 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2344 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2345 Instructions.push_back(BranchInst);
2348 if (PseudoOpcode == Mips::BGTU) {
2349 BranchInst.setOpcode(Mips::BNE);
2350 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2351 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2352 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2353 Instructions.push_back(BranchInst);
2356 if (AcceptsEquality) {
2357 // If both registers are $0 and the pseudo-branch accepts equality, it
2358 // will always be taken, so we emit an unconditional branch.
2359 BranchInst.setOpcode(Mips::BEQ);
2360 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2361 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2362 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2363 Instructions.push_back(BranchInst);
2364 Warning(IDLoc, "branch is always taken");
2367 // If both registers are $0 and the pseudo-branch does not accept
2368 // equality, it will never be taken, so we don't have to emit anything.
2371 if (IsSrcRegZero || IsTrgRegZero) {
2372 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
2373 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
2374 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
2375 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
2376 // the pseudo-branch will never be taken, so we don't emit anything.
2377 // This only applies to unsigned pseudo-branches.
2380 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
2381 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
2382 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
2383 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
2384 // the pseudo-branch will always be taken, so we emit an unconditional
2386 // This only applies to unsigned pseudo-branches.
2387 BranchInst.setOpcode(Mips::BEQ);
2388 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2389 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2390 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2391 Instructions.push_back(BranchInst);
2392 Warning(IDLoc, "branch is always taken");
2396 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
2397 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
2398 // the pseudo-branch will be taken only when the non-zero register is
2399 // different from 0, so we emit a BNEZ.
2401 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
2402 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
2403 // the pseudo-branch will be taken only when the non-zero register is
2404 // equal to 0, so we emit a BEQZ.
2406 // Because only BLEU and BGEU branch on equality, we can use the
2407 // AcceptsEquality variable to decide when to emit the BEQZ.
2408 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2409 BranchInst.addOperand(
2410 MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2411 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2412 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2413 Instructions.push_back(BranchInst);
2416 // If we have a signed pseudo-branch and one of the registers is $0,
2417 // we can use an appropriate compare-to-zero branch. We select which one
2418 // to use in the switch statement above.
2419 BranchInst.setOpcode(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode);
2420 BranchInst.addOperand(MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2421 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2422 Instructions.push_back(BranchInst);
2426 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
2427 // expansions. If it is not available, we return.
2428 unsigned ATRegNum = getATReg(IDLoc);
2432 warnIfNoMacro(IDLoc);
2434 // SLT fits well with 2 of our 4 pseudo-branches:
2435 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
2436 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
2437 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
2438 // This is accomplished by using a BNEZ with the result of the SLT.
2440 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
2441 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
2442 // Because only BGE and BLE branch on equality, we can use the
2443 // AcceptsEquality variable to decide when to emit the BEQZ.
2444 // Note that the order of the SLT arguments doesn't change between
2447 // The same applies to the unsigned variants, except that SLTu is used
2450 SetInst.setOpcode(IsUnsigned ? Mips::SLTu : Mips::SLT);
2451 SetInst.addOperand(MCOperand::createReg(ATRegNum));
2452 SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? TrgReg : SrcReg));
2453 SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? SrcReg : TrgReg));
2454 Instructions.push_back(SetInst);
2456 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2457 BranchInst.addOperand(MCOperand::createReg(ATRegNum));
2458 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2459 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2460 Instructions.push_back(BranchInst);
2464 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
2465 SmallVectorImpl<MCInst> &Instructions) {
2467 if (hasShortDelaySlot) {
2468 NopInst.setOpcode(Mips::MOVE16_MM);
2469 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2470 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2472 NopInst.setOpcode(Mips::SLL);
2473 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2474 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2475 NopInst.addOperand(MCOperand::createImm(0));
2477 Instructions.push_back(NopInst);
2480 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
2482 SmallVectorImpl<MCInst> &Instructions) {
2484 AdduInst.setOpcode(Mips::ADDu);
2485 AdduInst.addOperand(MCOperand::createReg(DstReg));
2486 AdduInst.addOperand(MCOperand::createReg(SrcReg));
2487 AdduInst.addOperand(MCOperand::createReg(TrgReg));
2488 Instructions.push_back(AdduInst);
2491 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
2492 // As described by the Mips32r2 spec, the registers Rd and Rs for
2493 // jalr.hb must be different.
2494 unsigned Opcode = Inst.getOpcode();
2496 if (Opcode == Mips::JALR_HB &&
2497 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
2498 return Match_RequiresDifferentSrcAndDst;
2500 return Match_Success;
2503 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2504 OperandVector &Operands,
2506 uint64_t &ErrorInfo,
2507 bool MatchingInlineAsm) {
2510 SmallVector<MCInst, 8> Instructions;
2511 unsigned MatchResult =
2512 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
2514 switch (MatchResult) {
2515 case Match_Success: {
2516 if (processInstruction(Inst, IDLoc, Instructions))
2518 for (unsigned i = 0; i < Instructions.size(); i++)
2519 Out.EmitInstruction(Instructions[i], STI);
2522 case Match_MissingFeature:
2523 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2525 case Match_InvalidOperand: {
2526 SMLoc ErrorLoc = IDLoc;
2527 if (ErrorInfo != ~0ULL) {
2528 if (ErrorInfo >= Operands.size())
2529 return Error(IDLoc, "too few operands for instruction");
2531 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
2532 if (ErrorLoc == SMLoc())
2536 return Error(ErrorLoc, "invalid operand for instruction");
2538 case Match_MnemonicFail:
2539 return Error(IDLoc, "invalid instruction");
2540 case Match_RequiresDifferentSrcAndDst:
2541 return Error(IDLoc, "source and destination must be different");
2544 llvm_unreachable("Implement any new match types added!");
2547 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
2548 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
2549 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
2550 ") without \".set noat\"");
2553 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
2554 if (!AssemblerOptions.back()->isMacro())
2555 Warning(Loc, "macro instruction expanded into multiple instructions");
2559 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
2560 SMRange Range, bool ShowColors) {
2561 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
2562 Range, SMFixIt(Range, FixMsg),
2566 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
2569 CC = StringSwitch<unsigned>(Name)
2605 if (!(isABI_N32() || isABI_N64()))
2608 if (12 <= CC && CC <= 15) {
2609 // Name is one of t4-t7
2610 AsmToken RegTok = getLexer().peekTok();
2611 SMRange RegRange = RegTok.getLocRange();
2613 StringRef FixedName = StringSwitch<StringRef>(Name)
2619 assert(FixedName != "" && "Register name is not one of t4-t7.");
2621 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
2622 "Did you mean $" + FixedName + "?", RegRange);
2625 // Although SGI documentation just cuts out t0-t3 for n32/n64,
2626 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
2627 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
2628 if (8 <= CC && CC <= 11)
2632 CC = StringSwitch<unsigned>(Name)
2644 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
2647 CC = StringSwitch<unsigned>(Name)
2648 .Case("hwr_cpunum", 0)
2649 .Case("hwr_synci_step", 1)
2651 .Case("hwr_ccres", 3)
2652 .Case("hwr_ulr", 29)
2658 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2660 if (Name[0] == 'f') {
2661 StringRef NumString = Name.substr(1);
2663 if (NumString.getAsInteger(10, IntVal))
2664 return -1; // This is not an integer.
2665 if (IntVal > 31) // Maximum index for fpu register.
2672 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2674 if (Name.startswith("fcc")) {
2675 StringRef NumString = Name.substr(3);
2677 if (NumString.getAsInteger(10, IntVal))
2678 return -1; // This is not an integer.
2679 if (IntVal > 7) // There are only 8 fcc registers.
2686 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2688 if (Name.startswith("ac")) {
2689 StringRef NumString = Name.substr(2);
2691 if (NumString.getAsInteger(10, IntVal))
2692 return -1; // This is not an integer.
2693 if (IntVal > 3) // There are only 3 acc registers.
2700 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2703 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
2712 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
2715 CC = StringSwitch<unsigned>(Name)
2718 .Case("msaaccess", 2)
2720 .Case("msamodify", 4)
2721 .Case("msarequest", 5)
2723 .Case("msaunmap", 7)
2729 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
2730 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
2732 reportParseError(Loc,
2733 "pseudo-instruction requires $at, which is not available");
2736 unsigned AT = getReg(
2737 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
2741 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2742 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2745 unsigned MipsAsmParser::getGPR(int RegNo) {
2746 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2750 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2752 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2755 return getReg(RegClass, RegNum);
2758 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2759 MCAsmParser &Parser = getParser();
2760 DEBUG(dbgs() << "parseOperand\n");
2762 // Check if the current operand has a custom associated parser, if so, try to
2763 // custom parse the operand, or fallback to the general approach.
2764 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2765 if (ResTy == MatchOperand_Success)
2767 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2768 // there was a match, but an error occurred, in which case, just return that
2769 // the operand parsing failed.
2770 if (ResTy == MatchOperand_ParseFail)
2773 DEBUG(dbgs() << ".. Generic Parser\n");
2775 switch (getLexer().getKind()) {
2777 Error(Parser.getTok().getLoc(), "unexpected token in operand");
2779 case AsmToken::Dollar: {
2780 // Parse the register.
2781 SMLoc S = Parser.getTok().getLoc();
2783 // Almost all registers have been parsed by custom parsers. There is only
2784 // one exception to this. $zero (and it's alias $0) will reach this point
2785 // for div, divu, and similar instructions because it is not an operand
2786 // to the instruction definition but an explicit register. Special case
2787 // this situation for now.
2788 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
2791 // Maybe it is a symbol reference.
2792 StringRef Identifier;
2793 if (Parser.parseIdentifier(Identifier))
2796 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2797 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
2798 // Otherwise create a symbol reference.
2800 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
2802 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
2805 // Else drop to expression parsing.
2806 case AsmToken::LParen:
2807 case AsmToken::Minus:
2808 case AsmToken::Plus:
2809 case AsmToken::Integer:
2810 case AsmToken::Tilde:
2811 case AsmToken::String: {
2812 DEBUG(dbgs() << ".. generic integer\n");
2813 OperandMatchResultTy ResTy = parseImm(Operands);
2814 return ResTy != MatchOperand_Success;
2816 case AsmToken::Percent: {
2817 // It is a symbol reference or constant expression.
2818 const MCExpr *IdVal;
2819 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
2820 if (parseRelocOperand(IdVal))
2823 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2825 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2827 } // case AsmToken::Percent
2828 } // switch(getLexer().getKind())
2832 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
2833 StringRef RelocStr) {
2835 // Check the type of the expression.
2836 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
2837 // It's a constant, evaluate reloc value.
2839 switch (getVariantKind(RelocStr)) {
2840 case MCSymbolRefExpr::VK_Mips_ABS_LO:
2841 // Get the 1st 16-bits.
2842 Val = MCE->getValue() & 0xffff;
2844 case MCSymbolRefExpr::VK_Mips_ABS_HI:
2845 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
2846 // 16 bits being negative.
2847 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
2849 case MCSymbolRefExpr::VK_Mips_HIGHER:
2850 // Get the 3rd 16-bits.
2851 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
2853 case MCSymbolRefExpr::VK_Mips_HIGHEST:
2854 // Get the 4th 16-bits.
2855 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
2858 report_fatal_error("unsupported reloc value");
2860 return MCConstantExpr::create(Val, getContext());
2863 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
2864 // It's a symbol, create a symbolic expression from the symbol.
2865 const MCSymbol *Symbol = &MSRE->getSymbol();
2866 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2867 Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
2871 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2872 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2874 // Try to create target expression.
2875 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
2876 return MipsMCExpr::create(VK, Expr, getContext());
2878 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
2879 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
2880 Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
2884 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
2885 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
2886 Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
2889 // Just return the original expression.
2893 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
2895 switch (Expr->getKind()) {
2896 case MCExpr::Constant:
2898 case MCExpr::SymbolRef:
2899 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
2900 case MCExpr::Binary:
2901 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2902 if (!isEvaluated(BE->getLHS()))
2904 return isEvaluated(BE->getRHS());
2907 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
2908 case MCExpr::Target:
2914 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
2915 MCAsmParser &Parser = getParser();
2916 Parser.Lex(); // Eat the % token.
2917 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
2918 if (Tok.isNot(AsmToken::Identifier))
2921 std::string Str = Tok.getIdentifier();
2923 Parser.Lex(); // Eat the identifier.
2924 // Now make an expression from the rest of the operand.
2925 const MCExpr *IdVal;
2928 if (getLexer().getKind() == AsmToken::LParen) {
2930 Parser.Lex(); // Eat the '(' token.
2931 if (getLexer().getKind() == AsmToken::Percent) {
2932 Parser.Lex(); // Eat the % token.
2933 const AsmToken &nextTok = Parser.getTok();
2934 if (nextTok.isNot(AsmToken::Identifier))
2937 Str += nextTok.getIdentifier();
2938 Parser.Lex(); // Eat the identifier.
2939 if (getLexer().getKind() != AsmToken::LParen)
2944 if (getParser().parseParenExpression(IdVal, EndLoc))
2947 while (getLexer().getKind() == AsmToken::RParen)
2948 Parser.Lex(); // Eat the ')' token.
2951 return true; // Parenthesis must follow the relocation operand.
2953 Res = evaluateRelocExpr(IdVal, Str);
2957 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2959 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2960 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2961 if (ResTy == MatchOperand_Success) {
2962 assert(Operands.size() == 1);
2963 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2964 StartLoc = Operand.getStartLoc();
2965 EndLoc = Operand.getEndLoc();
2967 // AFAIK, we only support numeric registers and named GPR's in CFI
2969 // Don't worry about eating tokens before failing. Using an unrecognised
2970 // register is a parse error.
2971 if (Operand.isGPRAsmReg()) {
2972 // Resolve to GPR32 or GPR64 appropriately.
2973 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2976 return (RegNo == (unsigned)-1);
2979 assert(Operands.size() == 0);
2980 return (RegNo == (unsigned)-1);
2983 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2984 MCAsmParser &Parser = getParser();
2988 while (getLexer().getKind() == AsmToken::LParen)
2991 switch (getLexer().getKind()) {
2994 case AsmToken::Identifier:
2995 case AsmToken::LParen:
2996 case AsmToken::Integer:
2997 case AsmToken::Minus:
2998 case AsmToken::Plus:
3000 Result = getParser().parseParenExpression(Res, S);
3002 Result = (getParser().parseExpression(Res));
3003 while (getLexer().getKind() == AsmToken::RParen)
3006 case AsmToken::Percent:
3007 Result = parseRelocOperand(Res);
3012 MipsAsmParser::OperandMatchResultTy
3013 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
3014 MCAsmParser &Parser = getParser();
3015 DEBUG(dbgs() << "parseMemOperand\n");
3016 const MCExpr *IdVal = nullptr;
3018 bool isParenExpr = false;
3019 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
3020 // First operand is the offset.
3021 S = Parser.getTok().getLoc();
3023 if (getLexer().getKind() == AsmToken::LParen) {
3028 if (getLexer().getKind() != AsmToken::Dollar) {
3029 if (parseMemOffset(IdVal, isParenExpr))
3030 return MatchOperand_ParseFail;
3032 const AsmToken &Tok = Parser.getTok(); // Get the next token.
3033 if (Tok.isNot(AsmToken::LParen)) {
3034 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
3035 if (Mnemonic.getToken() == "la") {
3037 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3038 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3039 return MatchOperand_Success;
3041 if (Tok.is(AsmToken::EndOfStatement)) {
3043 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3045 // Zero register assumed, add a memory operand with ZERO as its base.
3046 // "Base" will be managed by k_Memory.
3047 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
3050 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
3051 return MatchOperand_Success;
3053 Error(Parser.getTok().getLoc(), "'(' expected");
3054 return MatchOperand_ParseFail;
3057 Parser.Lex(); // Eat the '(' token.
3060 Res = parseAnyRegister(Operands);
3061 if (Res != MatchOperand_Success)
3064 if (Parser.getTok().isNot(AsmToken::RParen)) {
3065 Error(Parser.getTok().getLoc(), "')' expected");
3066 return MatchOperand_ParseFail;
3069 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3071 Parser.Lex(); // Eat the ')' token.
3074 IdVal = MCConstantExpr::create(0, getContext());
3076 // Replace the register operand with the memory operand.
3077 std::unique_ptr<MipsOperand> op(
3078 static_cast<MipsOperand *>(Operands.back().release()));
3079 // Remove the register from the operands.
3080 // "op" will be managed by k_Memory.
3081 Operands.pop_back();
3082 // Add the memory operand.
3083 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
3085 if (IdVal->evaluateAsAbsolute(Imm))
3086 IdVal = MCConstantExpr::create(Imm, getContext());
3087 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
3088 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
3092 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
3093 return MatchOperand_Success;
3096 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
3097 MCAsmParser &Parser = getParser();
3098 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
3100 SMLoc S = Parser.getTok().getLoc();
3102 if (Sym->isVariable())
3103 Expr = Sym->getVariableValue();
3106 if (Expr->getKind() == MCExpr::SymbolRef) {
3107 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3108 StringRef DefSymbol = Ref->getSymbol().getName();
3109 if (DefSymbol.startswith("$")) {
3110 OperandMatchResultTy ResTy =
3111 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
3112 if (ResTy == MatchOperand_Success) {
3115 } else if (ResTy == MatchOperand_ParseFail)
3116 llvm_unreachable("Should never ParseFail");
3119 } else if (Expr->getKind() == MCExpr::Constant) {
3121 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
3123 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
3130 MipsAsmParser::OperandMatchResultTy
3131 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
3132 StringRef Identifier,
3134 int Index = matchCPURegisterName(Identifier);
3136 Operands.push_back(MipsOperand::createGPRReg(
3137 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3138 return MatchOperand_Success;
3141 Index = matchHWRegsRegisterName(Identifier);
3143 Operands.push_back(MipsOperand::createHWRegsReg(
3144 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3145 return MatchOperand_Success;
3148 Index = matchFPURegisterName(Identifier);
3150 Operands.push_back(MipsOperand::createFGRReg(
3151 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3152 return MatchOperand_Success;
3155 Index = matchFCCRegisterName(Identifier);
3157 Operands.push_back(MipsOperand::createFCCReg(
3158 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3159 return MatchOperand_Success;
3162 Index = matchACRegisterName(Identifier);
3164 Operands.push_back(MipsOperand::createACCReg(
3165 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3166 return MatchOperand_Success;
3169 Index = matchMSA128RegisterName(Identifier);
3171 Operands.push_back(MipsOperand::createMSA128Reg(
3172 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3173 return MatchOperand_Success;
3176 Index = matchMSA128CtrlRegisterName(Identifier);
3178 Operands.push_back(MipsOperand::createMSACtrlReg(
3179 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3180 return MatchOperand_Success;
3183 return MatchOperand_NoMatch;
3186 MipsAsmParser::OperandMatchResultTy
3187 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
3188 MCAsmParser &Parser = getParser();
3189 auto Token = Parser.getLexer().peekTok(false);
3191 if (Token.is(AsmToken::Identifier)) {
3192 DEBUG(dbgs() << ".. identifier\n");
3193 StringRef Identifier = Token.getIdentifier();
3194 OperandMatchResultTy ResTy =
3195 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
3197 } else if (Token.is(AsmToken::Integer)) {
3198 DEBUG(dbgs() << ".. integer\n");
3199 Operands.push_back(MipsOperand::createNumericReg(
3200 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
3202 return MatchOperand_Success;
3205 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
3207 return MatchOperand_NoMatch;
3210 MipsAsmParser::OperandMatchResultTy
3211 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
3212 MCAsmParser &Parser = getParser();
3213 DEBUG(dbgs() << "parseAnyRegister\n");
3215 auto Token = Parser.getTok();
3217 SMLoc S = Token.getLoc();
3219 if (Token.isNot(AsmToken::Dollar)) {
3220 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
3221 if (Token.is(AsmToken::Identifier)) {
3222 if (searchSymbolAlias(Operands))
3223 return MatchOperand_Success;
3225 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
3226 return MatchOperand_NoMatch;
3228 DEBUG(dbgs() << ".. $\n");
3230 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
3231 if (ResTy == MatchOperand_Success) {
3233 Parser.Lex(); // identifier
3238 MipsAsmParser::OperandMatchResultTy
3239 MipsAsmParser::parseImm(OperandVector &Operands) {
3240 MCAsmParser &Parser = getParser();
3241 switch (getLexer().getKind()) {
3243 return MatchOperand_NoMatch;
3244 case AsmToken::LParen:
3245 case AsmToken::Minus:
3246 case AsmToken::Plus:
3247 case AsmToken::Integer:
3248 case AsmToken::Tilde:
3249 case AsmToken::String:
3253 const MCExpr *IdVal;
3254 SMLoc S = Parser.getTok().getLoc();
3255 if (getParser().parseExpression(IdVal))
3256 return MatchOperand_ParseFail;
3258 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3259 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3260 return MatchOperand_Success;
3263 MipsAsmParser::OperandMatchResultTy
3264 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
3265 MCAsmParser &Parser = getParser();
3266 DEBUG(dbgs() << "parseJumpTarget\n");
3268 SMLoc S = getLexer().getLoc();
3270 // Integers and expressions are acceptable
3271 OperandMatchResultTy ResTy = parseImm(Operands);
3272 if (ResTy != MatchOperand_NoMatch)
3275 // Registers are a valid target and have priority over symbols.
3276 ResTy = parseAnyRegister(Operands);
3277 if (ResTy != MatchOperand_NoMatch)
3280 const MCExpr *Expr = nullptr;
3281 if (Parser.parseExpression(Expr)) {
3282 // We have no way of knowing if a symbol was consumed so we must ParseFail
3283 return MatchOperand_ParseFail;
3286 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
3287 return MatchOperand_Success;
3290 MipsAsmParser::OperandMatchResultTy
3291 MipsAsmParser::parseInvNum(OperandVector &Operands) {
3292 MCAsmParser &Parser = getParser();
3293 const MCExpr *IdVal;
3294 // If the first token is '$' we may have register operand.
3295 if (Parser.getTok().is(AsmToken::Dollar))
3296 return MatchOperand_NoMatch;
3297 SMLoc S = Parser.getTok().getLoc();
3298 if (getParser().parseExpression(IdVal))
3299 return MatchOperand_ParseFail;
3300 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
3301 assert(MCE && "Unexpected MCExpr type.");
3302 int64_t Val = MCE->getValue();
3303 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3304 Operands.push_back(MipsOperand::CreateImm(
3305 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
3306 return MatchOperand_Success;
3309 MipsAsmParser::OperandMatchResultTy
3310 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
3311 MCAsmParser &Parser = getParser();
3312 switch (getLexer().getKind()) {
3314 return MatchOperand_NoMatch;
3315 case AsmToken::LParen:
3316 case AsmToken::Plus:
3317 case AsmToken::Minus:
3318 case AsmToken::Integer:
3323 SMLoc S = Parser.getTok().getLoc();
3325 if (getParser().parseExpression(Expr))
3326 return MatchOperand_ParseFail;
3329 if (!Expr->evaluateAsAbsolute(Val)) {
3330 Error(S, "expected immediate value");
3331 return MatchOperand_ParseFail;
3334 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
3335 // and because the CPU always adds one to the immediate field, the allowed
3336 // range becomes 1..4. We'll only check the range here and will deal
3337 // with the addition/subtraction when actually decoding/encoding
3339 if (Val < 1 || Val > 4) {
3340 Error(S, "immediate not in range (1..4)");
3341 return MatchOperand_ParseFail;
3345 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
3346 return MatchOperand_Success;
3349 MipsAsmParser::OperandMatchResultTy
3350 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3351 MCAsmParser &Parser = getParser();
3352 SmallVector<unsigned, 10> Regs;
3354 unsigned PrevReg = Mips::NoRegister;
3355 bool RegRange = false;
3356 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3358 if (Parser.getTok().isNot(AsmToken::Dollar))
3359 return MatchOperand_ParseFail;
3361 SMLoc S = Parser.getTok().getLoc();
3362 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3363 SMLoc E = getLexer().getLoc();
3364 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3365 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3367 // Remove last register operand because registers from register range
3368 // should be inserted first.
3369 if (RegNo == Mips::RA) {
3370 Regs.push_back(RegNo);
3372 unsigned TmpReg = PrevReg + 1;
3373 while (TmpReg <= RegNo) {
3374 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3375 Error(E, "invalid register operand");
3376 return MatchOperand_ParseFail;
3380 Regs.push_back(TmpReg++);
3386 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
3387 (RegNo != Mips::RA)) {
3388 Error(E, "$16 or $31 expected");
3389 return MatchOperand_ParseFail;
3390 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
3391 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3392 Error(E, "invalid register operand");
3393 return MatchOperand_ParseFail;
3394 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
3395 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3396 Error(E, "consecutive register numbers expected");
3397 return MatchOperand_ParseFail;
3400 Regs.push_back(RegNo);
3403 if (Parser.getTok().is(AsmToken::Minus))
3406 if (!Parser.getTok().isNot(AsmToken::Minus) &&
3407 !Parser.getTok().isNot(AsmToken::Comma)) {
3408 Error(E, "',' or '-' expected");
3409 return MatchOperand_ParseFail;
3412 Lex(); // Consume comma or minus
3413 if (Parser.getTok().isNot(AsmToken::Dollar))
3419 SMLoc E = Parser.getTok().getLoc();
3420 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3421 parseMemOperand(Operands);
3422 return MatchOperand_Success;
3425 MipsAsmParser::OperandMatchResultTy
3426 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
3427 MCAsmParser &Parser = getParser();
3429 SMLoc S = Parser.getTok().getLoc();
3430 if (parseAnyRegister(Operands) != MatchOperand_Success)
3431 return MatchOperand_ParseFail;
3433 SMLoc E = Parser.getTok().getLoc();
3434 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
3435 unsigned Reg = Op.getGPR32Reg();
3436 Operands.pop_back();
3437 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
3438 return MatchOperand_Success;
3441 MipsAsmParser::OperandMatchResultTy
3442 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
3443 MCAsmParser &Parser = getParser();
3444 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3445 SmallVector<unsigned, 10> Regs;
3447 if (Parser.getTok().isNot(AsmToken::Dollar))
3448 return MatchOperand_ParseFail;
3450 SMLoc S = Parser.getTok().getLoc();
3452 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3453 return MatchOperand_ParseFail;
3455 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3456 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3457 Regs.push_back(RegNo);
3459 SMLoc E = Parser.getTok().getLoc();
3460 if (Parser.getTok().isNot(AsmToken::Comma)) {
3461 Error(E, "',' expected");
3462 return MatchOperand_ParseFail;
3468 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3469 return MatchOperand_ParseFail;
3471 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3472 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3473 Regs.push_back(RegNo);
3475 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3477 return MatchOperand_Success;
3480 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
3482 MCSymbolRefExpr::VariantKind VK =
3483 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
3484 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
3485 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
3486 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
3487 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
3488 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
3489 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
3490 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
3491 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
3492 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
3493 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
3494 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
3495 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
3496 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
3497 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
3498 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
3499 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
3500 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
3501 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
3502 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
3503 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
3504 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
3505 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
3506 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
3507 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
3508 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
3509 .Default(MCSymbolRefExpr::VK_None);
3511 assert(VK != MCSymbolRefExpr::VK_None);
3516 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
3518 /// ::= '(', register, ')'
3519 /// handle it before we iterate so we don't get tripped up by the lack of
3521 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
3522 MCAsmParser &Parser = getParser();
3523 if (getLexer().is(AsmToken::LParen)) {
3525 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
3527 if (parseOperand(Operands, Name)) {
3528 SMLoc Loc = getLexer().getLoc();
3529 Parser.eatToEndOfStatement();
3530 return Error(Loc, "unexpected token in argument list");
3532 if (Parser.getTok().isNot(AsmToken::RParen)) {
3533 SMLoc Loc = getLexer().getLoc();
3534 Parser.eatToEndOfStatement();
3535 return Error(Loc, "unexpected token, expected ')'");
3538 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
3544 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
3545 /// either one of these.
3546 /// ::= '[', register, ']'
3547 /// ::= '[', integer, ']'
3548 /// handle it before we iterate so we don't get tripped up by the lack of
3550 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
3551 OperandVector &Operands) {
3552 MCAsmParser &Parser = getParser();
3553 if (getLexer().is(AsmToken::LBrac)) {
3555 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
3557 if (parseOperand(Operands, Name)) {
3558 SMLoc Loc = getLexer().getLoc();
3559 Parser.eatToEndOfStatement();
3560 return Error(Loc, "unexpected token in argument list");
3562 if (Parser.getTok().isNot(AsmToken::RBrac)) {
3563 SMLoc Loc = getLexer().getLoc();
3564 Parser.eatToEndOfStatement();
3565 return Error(Loc, "unexpected token, expected ']'");
3568 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
3574 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
3575 SMLoc NameLoc, OperandVector &Operands) {
3576 MCAsmParser &Parser = getParser();
3577 DEBUG(dbgs() << "ParseInstruction\n");
3579 // We have reached first instruction, module directive are now forbidden.
3580 getTargetStreamer().forbidModuleDirective();
3582 // Check if we have valid mnemonic
3583 if (!mnemonicIsValid(Name, 0)) {
3584 Parser.eatToEndOfStatement();
3585 return Error(NameLoc, "unknown instruction");
3587 // First operand in MCInst is instruction mnemonic.
3588 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
3590 // Read the remaining operands.
3591 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3592 // Read the first operand.
3593 if (parseOperand(Operands, Name)) {
3594 SMLoc Loc = getLexer().getLoc();
3595 Parser.eatToEndOfStatement();
3596 return Error(Loc, "unexpected token in argument list");
3598 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
3600 // AFAIK, parenthesis suffixes are never on the first operand
3602 while (getLexer().is(AsmToken::Comma)) {
3603 Parser.Lex(); // Eat the comma.
3604 // Parse and remember the operand.
3605 if (parseOperand(Operands, Name)) {
3606 SMLoc Loc = getLexer().getLoc();
3607 Parser.eatToEndOfStatement();
3608 return Error(Loc, "unexpected token in argument list");
3610 // Parse bracket and parenthesis suffixes before we iterate
3611 if (getLexer().is(AsmToken::LBrac)) {
3612 if (parseBracketSuffix(Name, Operands))
3614 } else if (getLexer().is(AsmToken::LParen) &&
3615 parseParenSuffix(Name, Operands))
3619 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3620 SMLoc Loc = getLexer().getLoc();
3621 Parser.eatToEndOfStatement();
3622 return Error(Loc, "unexpected token in argument list");
3624 Parser.Lex(); // Consume the EndOfStatement.
3628 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
3629 MCAsmParser &Parser = getParser();
3630 SMLoc Loc = getLexer().getLoc();
3631 Parser.eatToEndOfStatement();
3632 return Error(Loc, ErrorMsg);
3635 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
3636 return Error(Loc, ErrorMsg);
3639 bool MipsAsmParser::parseSetNoAtDirective() {
3640 MCAsmParser &Parser = getParser();
3641 // Line should look like: ".set noat".
3643 // Set the $at register to $0.
3644 AssemblerOptions.back()->setATRegIndex(0);
3646 Parser.Lex(); // Eat "noat".
3648 // If this is not the end of the statement, report an error.
3649 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3650 reportParseError("unexpected token, expected end of statement");
3654 getTargetStreamer().emitDirectiveSetNoAt();
3655 Parser.Lex(); // Consume the EndOfStatement.
3659 bool MipsAsmParser::parseSetAtDirective() {
3660 // Line can be: ".set at", which sets $at to $1
3661 // or ".set at=$reg", which sets $at to $reg.
3662 MCAsmParser &Parser = getParser();
3663 Parser.Lex(); // Eat "at".
3665 if (getLexer().is(AsmToken::EndOfStatement)) {
3666 // No register was specified, so we set $at to $1.
3667 AssemblerOptions.back()->setATRegIndex(1);
3669 getTargetStreamer().emitDirectiveSetAt();
3670 Parser.Lex(); // Consume the EndOfStatement.
3674 if (getLexer().isNot(AsmToken::Equal)) {
3675 reportParseError("unexpected token, expected equals sign");
3678 Parser.Lex(); // Eat "=".
3680 if (getLexer().isNot(AsmToken::Dollar)) {
3681 if (getLexer().is(AsmToken::EndOfStatement)) {
3682 reportParseError("no register specified");
3685 reportParseError("unexpected token, expected dollar sign '$'");
3689 Parser.Lex(); // Eat "$".
3691 // Find out what "reg" is.
3693 const AsmToken &Reg = Parser.getTok();
3694 if (Reg.is(AsmToken::Identifier)) {
3695 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
3696 } else if (Reg.is(AsmToken::Integer)) {
3697 AtRegNo = Reg.getIntVal();
3699 reportParseError("unexpected token, expected identifier or integer");
3703 // Check if $reg is a valid register. If it is, set $at to $reg.
3704 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
3705 reportParseError("invalid register");
3708 Parser.Lex(); // Eat "reg".
3710 // If this is not the end of the statement, report an error.
3711 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3712 reportParseError("unexpected token, expected end of statement");
3716 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
3718 Parser.Lex(); // Consume the EndOfStatement.
3722 bool MipsAsmParser::parseSetReorderDirective() {
3723 MCAsmParser &Parser = getParser();
3725 // If this is not the end of the statement, report an error.
3726 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3727 reportParseError("unexpected token, expected end of statement");
3730 AssemblerOptions.back()->setReorder();
3731 getTargetStreamer().emitDirectiveSetReorder();
3732 Parser.Lex(); // Consume the EndOfStatement.
3736 bool MipsAsmParser::parseSetNoReorderDirective() {
3737 MCAsmParser &Parser = getParser();
3739 // If this is not the end of the statement, report an error.
3740 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3741 reportParseError("unexpected token, expected end of statement");
3744 AssemblerOptions.back()->setNoReorder();
3745 getTargetStreamer().emitDirectiveSetNoReorder();
3746 Parser.Lex(); // Consume the EndOfStatement.
3750 bool MipsAsmParser::parseSetMacroDirective() {
3751 MCAsmParser &Parser = getParser();
3753 // If this is not the end of the statement, report an error.
3754 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3755 reportParseError("unexpected token, expected end of statement");
3758 AssemblerOptions.back()->setMacro();
3759 getTargetStreamer().emitDirectiveSetMacro();
3760 Parser.Lex(); // Consume the EndOfStatement.
3764 bool MipsAsmParser::parseSetNoMacroDirective() {
3765 MCAsmParser &Parser = getParser();
3767 // If this is not the end of the statement, report an error.
3768 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3769 reportParseError("unexpected token, expected end of statement");
3772 if (AssemblerOptions.back()->isReorder()) {
3773 reportParseError("`noreorder' must be set before `nomacro'");
3776 AssemblerOptions.back()->setNoMacro();
3777 getTargetStreamer().emitDirectiveSetNoMacro();
3778 Parser.Lex(); // Consume the EndOfStatement.
3782 bool MipsAsmParser::parseSetMsaDirective() {
3783 MCAsmParser &Parser = getParser();
3786 // If this is not the end of the statement, report an error.
3787 if (getLexer().isNot(AsmToken::EndOfStatement))
3788 return reportParseError("unexpected token, expected end of statement");
3790 setFeatureBits(Mips::FeatureMSA, "msa");
3791 getTargetStreamer().emitDirectiveSetMsa();
3795 bool MipsAsmParser::parseSetNoMsaDirective() {
3796 MCAsmParser &Parser = getParser();
3799 // If this is not the end of the statement, report an error.
3800 if (getLexer().isNot(AsmToken::EndOfStatement))
3801 return reportParseError("unexpected token, expected end of statement");
3803 clearFeatureBits(Mips::FeatureMSA, "msa");
3804 getTargetStreamer().emitDirectiveSetNoMsa();
3808 bool MipsAsmParser::parseSetNoDspDirective() {
3809 MCAsmParser &Parser = getParser();
3810 Parser.Lex(); // Eat "nodsp".
3812 // If this is not the end of the statement, report an error.
3813 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3814 reportParseError("unexpected token, expected end of statement");
3818 clearFeatureBits(Mips::FeatureDSP, "dsp");
3819 getTargetStreamer().emitDirectiveSetNoDsp();
3823 bool MipsAsmParser::parseSetMips16Directive() {
3824 MCAsmParser &Parser = getParser();
3825 Parser.Lex(); // Eat "mips16".
3827 // If this is not the end of the statement, report an error.
3828 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3829 reportParseError("unexpected token, expected end of statement");
3833 setFeatureBits(Mips::FeatureMips16, "mips16");
3834 getTargetStreamer().emitDirectiveSetMips16();
3835 Parser.Lex(); // Consume the EndOfStatement.
3839 bool MipsAsmParser::parseSetNoMips16Directive() {
3840 MCAsmParser &Parser = getParser();
3841 Parser.Lex(); // Eat "nomips16".
3843 // If this is not the end of the statement, report an error.
3844 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3845 reportParseError("unexpected token, expected end of statement");
3849 clearFeatureBits(Mips::FeatureMips16, "mips16");
3850 getTargetStreamer().emitDirectiveSetNoMips16();
3851 Parser.Lex(); // Consume the EndOfStatement.
3855 bool MipsAsmParser::parseSetFpDirective() {
3856 MCAsmParser &Parser = getParser();
3857 MipsABIFlagsSection::FpABIKind FpAbiVal;
3858 // Line can be: .set fp=32
3861 Parser.Lex(); // Eat fp token
3862 AsmToken Tok = Parser.getTok();
3863 if (Tok.isNot(AsmToken::Equal)) {
3864 reportParseError("unexpected token, expected equals sign '='");
3867 Parser.Lex(); // Eat '=' token.
3868 Tok = Parser.getTok();
3870 if (!parseFpABIValue(FpAbiVal, ".set"))
3873 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3874 reportParseError("unexpected token, expected end of statement");
3877 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
3878 Parser.Lex(); // Consume the EndOfStatement.
3882 bool MipsAsmParser::parseSetPopDirective() {
3883 MCAsmParser &Parser = getParser();
3884 SMLoc Loc = getLexer().getLoc();
3887 if (getLexer().isNot(AsmToken::EndOfStatement))
3888 return reportParseError("unexpected token, expected end of statement");
3890 // Always keep an element on the options "stack" to prevent the user
3891 // from changing the initial options. This is how we remember them.
3892 if (AssemblerOptions.size() == 2)
3893 return reportParseError(Loc, ".set pop with no .set push");
3895 AssemblerOptions.pop_back();
3896 setAvailableFeatures(
3897 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
3898 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
3900 getTargetStreamer().emitDirectiveSetPop();
3904 bool MipsAsmParser::parseSetPushDirective() {
3905 MCAsmParser &Parser = getParser();
3907 if (getLexer().isNot(AsmToken::EndOfStatement))
3908 return reportParseError("unexpected token, expected end of statement");
3910 // Create a copy of the current assembler options environment and push it.
3911 AssemblerOptions.push_back(
3912 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
3914 getTargetStreamer().emitDirectiveSetPush();
3918 bool MipsAsmParser::parseSetSoftFloatDirective() {
3919 MCAsmParser &Parser = getParser();
3921 if (getLexer().isNot(AsmToken::EndOfStatement))
3922 return reportParseError("unexpected token, expected end of statement");
3924 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
3925 getTargetStreamer().emitDirectiveSetSoftFloat();
3929 bool MipsAsmParser::parseSetHardFloatDirective() {
3930 MCAsmParser &Parser = getParser();
3932 if (getLexer().isNot(AsmToken::EndOfStatement))
3933 return reportParseError("unexpected token, expected end of statement");
3935 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
3936 getTargetStreamer().emitDirectiveSetHardFloat();
3940 bool MipsAsmParser::parseSetAssignment() {
3942 const MCExpr *Value;
3943 MCAsmParser &Parser = getParser();
3945 if (Parser.parseIdentifier(Name))
3946 reportParseError("expected identifier after .set");
3948 if (getLexer().isNot(AsmToken::Comma))
3949 return reportParseError("unexpected token, expected comma");
3952 if (Parser.parseExpression(Value))
3953 return reportParseError("expected valid expression after comma");
3955 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
3956 Sym->setVariableValue(Value);
3961 bool MipsAsmParser::parseSetMips0Directive() {
3962 MCAsmParser &Parser = getParser();
3964 if (getLexer().isNot(AsmToken::EndOfStatement))
3965 return reportParseError("unexpected token, expected end of statement");
3967 // Reset assembler options to their initial values.
3968 setAvailableFeatures(
3969 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
3970 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
3971 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
3973 getTargetStreamer().emitDirectiveSetMips0();
3977 bool MipsAsmParser::parseSetArchDirective() {
3978 MCAsmParser &Parser = getParser();
3980 if (getLexer().isNot(AsmToken::Equal))
3981 return reportParseError("unexpected token, expected equals sign");
3985 if (Parser.parseIdentifier(Arch))
3986 return reportParseError("expected arch identifier");
3988 StringRef ArchFeatureName =
3989 StringSwitch<StringRef>(Arch)
3990 .Case("mips1", "mips1")
3991 .Case("mips2", "mips2")
3992 .Case("mips3", "mips3")
3993 .Case("mips4", "mips4")
3994 .Case("mips5", "mips5")
3995 .Case("mips32", "mips32")
3996 .Case("mips32r2", "mips32r2")
3997 .Case("mips32r3", "mips32r3")
3998 .Case("mips32r5", "mips32r5")
3999 .Case("mips32r6", "mips32r6")
4000 .Case("mips64", "mips64")
4001 .Case("mips64r2", "mips64r2")
4002 .Case("mips64r3", "mips64r3")
4003 .Case("mips64r5", "mips64r5")
4004 .Case("mips64r6", "mips64r6")
4005 .Case("cnmips", "cnmips")
4006 .Case("r4000", "mips3") // This is an implementation of Mips3.
4009 if (ArchFeatureName.empty())
4010 return reportParseError("unsupported architecture");
4012 selectArch(ArchFeatureName);
4013 getTargetStreamer().emitDirectiveSetArch(Arch);
4017 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
4018 MCAsmParser &Parser = getParser();
4020 if (getLexer().isNot(AsmToken::EndOfStatement))
4021 return reportParseError("unexpected token, expected end of statement");
4025 llvm_unreachable("Unimplemented feature");
4026 case Mips::FeatureDSP:
4027 setFeatureBits(Mips::FeatureDSP, "dsp");
4028 getTargetStreamer().emitDirectiveSetDsp();
4030 case Mips::FeatureMicroMips:
4031 getTargetStreamer().emitDirectiveSetMicroMips();
4033 case Mips::FeatureMips1:
4034 selectArch("mips1");
4035 getTargetStreamer().emitDirectiveSetMips1();
4037 case Mips::FeatureMips2:
4038 selectArch("mips2");
4039 getTargetStreamer().emitDirectiveSetMips2();
4041 case Mips::FeatureMips3:
4042 selectArch("mips3");
4043 getTargetStreamer().emitDirectiveSetMips3();
4045 case Mips::FeatureMips4:
4046 selectArch("mips4");
4047 getTargetStreamer().emitDirectiveSetMips4();
4049 case Mips::FeatureMips5:
4050 selectArch("mips5");
4051 getTargetStreamer().emitDirectiveSetMips5();
4053 case Mips::FeatureMips32:
4054 selectArch("mips32");
4055 getTargetStreamer().emitDirectiveSetMips32();
4057 case Mips::FeatureMips32r2:
4058 selectArch("mips32r2");
4059 getTargetStreamer().emitDirectiveSetMips32R2();
4061 case Mips::FeatureMips32r3:
4062 selectArch("mips32r3");
4063 getTargetStreamer().emitDirectiveSetMips32R3();
4065 case Mips::FeatureMips32r5:
4066 selectArch("mips32r5");
4067 getTargetStreamer().emitDirectiveSetMips32R5();
4069 case Mips::FeatureMips32r6:
4070 selectArch("mips32r6");
4071 getTargetStreamer().emitDirectiveSetMips32R6();
4073 case Mips::FeatureMips64:
4074 selectArch("mips64");
4075 getTargetStreamer().emitDirectiveSetMips64();
4077 case Mips::FeatureMips64r2:
4078 selectArch("mips64r2");
4079 getTargetStreamer().emitDirectiveSetMips64R2();
4081 case Mips::FeatureMips64r3:
4082 selectArch("mips64r3");
4083 getTargetStreamer().emitDirectiveSetMips64R3();
4085 case Mips::FeatureMips64r5:
4086 selectArch("mips64r5");
4087 getTargetStreamer().emitDirectiveSetMips64R5();
4089 case Mips::FeatureMips64r6:
4090 selectArch("mips64r6");
4091 getTargetStreamer().emitDirectiveSetMips64R6();
4097 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
4098 MCAsmParser &Parser = getParser();
4099 if (getLexer().isNot(AsmToken::Comma)) {
4100 SMLoc Loc = getLexer().getLoc();
4101 Parser.eatToEndOfStatement();
4102 return Error(Loc, ErrorStr);
4105 Parser.Lex(); // Eat the comma.
4109 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
4110 if (AssemblerOptions.back()->isReorder())
4111 Warning(Loc, ".cpload should be inside a noreorder section");
4113 if (inMips16Mode()) {
4114 reportParseError(".cpload is not supported in Mips16 mode");
4118 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
4119 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
4120 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4121 reportParseError("expected register containing function address");
4125 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
4126 if (!RegOpnd.isGPRAsmReg()) {
4127 reportParseError(RegOpnd.getStartLoc(), "invalid register");
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 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
4141 bool MipsAsmParser::parseDirectiveCPSetup() {
4142 MCAsmParser &Parser = getParser();
4145 bool SaveIsReg = true;
4147 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4148 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4149 if (ResTy == MatchOperand_NoMatch) {
4150 reportParseError("expected register containing function address");
4151 Parser.eatToEndOfStatement();
4155 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4156 if (!FuncRegOpnd.isGPRAsmReg()) {
4157 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
4158 Parser.eatToEndOfStatement();
4162 FuncReg = FuncRegOpnd.getGPR32Reg();
4165 if (!eatComma("unexpected token, expected comma"))
4168 ResTy = parseAnyRegister(TmpReg);
4169 if (ResTy == MatchOperand_NoMatch) {
4170 const AsmToken &Tok = Parser.getTok();
4171 if (Tok.is(AsmToken::Integer)) {
4172 Save = Tok.getIntVal();
4176 reportParseError("expected save register or stack offset");
4177 Parser.eatToEndOfStatement();
4181 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4182 if (!SaveOpnd.isGPRAsmReg()) {
4183 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
4184 Parser.eatToEndOfStatement();
4187 Save = SaveOpnd.getGPR32Reg();
4190 if (!eatComma("unexpected token, expected comma"))
4194 if (Parser.parseExpression(Expr)) {
4195 reportParseError("expected expression");
4199 if (Expr->getKind() != MCExpr::SymbolRef) {
4200 reportParseError("expected symbol");
4203 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
4205 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
4210 bool MipsAsmParser::parseDirectiveNaN() {
4211 MCAsmParser &Parser = getParser();
4212 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4213 const AsmToken &Tok = Parser.getTok();
4215 if (Tok.getString() == "2008") {
4217 getTargetStreamer().emitDirectiveNaN2008();
4219 } else if (Tok.getString() == "legacy") {
4221 getTargetStreamer().emitDirectiveNaNLegacy();
4225 // If we don't recognize the option passed to the .nan
4226 // directive (e.g. no option or unknown option), emit an error.
4227 reportParseError("invalid option in .nan directive");
4231 bool MipsAsmParser::parseDirectiveSet() {
4232 MCAsmParser &Parser = getParser();
4233 // Get the next token.
4234 const AsmToken &Tok = Parser.getTok();
4236 if (Tok.getString() == "noat") {
4237 return parseSetNoAtDirective();
4238 } else if (Tok.getString() == "at") {
4239 return parseSetAtDirective();
4240 } else if (Tok.getString() == "arch") {
4241 return parseSetArchDirective();
4242 } else if (Tok.getString() == "fp") {
4243 return parseSetFpDirective();
4244 } else if (Tok.getString() == "pop") {
4245 return parseSetPopDirective();
4246 } else if (Tok.getString() == "push") {
4247 return parseSetPushDirective();
4248 } else if (Tok.getString() == "reorder") {
4249 return parseSetReorderDirective();
4250 } else if (Tok.getString() == "noreorder") {
4251 return parseSetNoReorderDirective();
4252 } else if (Tok.getString() == "macro") {
4253 return parseSetMacroDirective();
4254 } else if (Tok.getString() == "nomacro") {
4255 return parseSetNoMacroDirective();
4256 } else if (Tok.getString() == "mips16") {
4257 return parseSetMips16Directive();
4258 } else if (Tok.getString() == "nomips16") {
4259 return parseSetNoMips16Directive();
4260 } else if (Tok.getString() == "nomicromips") {
4261 getTargetStreamer().emitDirectiveSetNoMicroMips();
4262 Parser.eatToEndOfStatement();
4264 } else if (Tok.getString() == "micromips") {
4265 return parseSetFeature(Mips::FeatureMicroMips);
4266 } else if (Tok.getString() == "mips0") {
4267 return parseSetMips0Directive();
4268 } else if (Tok.getString() == "mips1") {
4269 return parseSetFeature(Mips::FeatureMips1);
4270 } else if (Tok.getString() == "mips2") {
4271 return parseSetFeature(Mips::FeatureMips2);
4272 } else if (Tok.getString() == "mips3") {
4273 return parseSetFeature(Mips::FeatureMips3);
4274 } else if (Tok.getString() == "mips4") {
4275 return parseSetFeature(Mips::FeatureMips4);
4276 } else if (Tok.getString() == "mips5") {
4277 return parseSetFeature(Mips::FeatureMips5);
4278 } else if (Tok.getString() == "mips32") {
4279 return parseSetFeature(Mips::FeatureMips32);
4280 } else if (Tok.getString() == "mips32r2") {
4281 return parseSetFeature(Mips::FeatureMips32r2);
4282 } else if (Tok.getString() == "mips32r3") {
4283 return parseSetFeature(Mips::FeatureMips32r3);
4284 } else if (Tok.getString() == "mips32r5") {
4285 return parseSetFeature(Mips::FeatureMips32r5);
4286 } else if (Tok.getString() == "mips32r6") {
4287 return parseSetFeature(Mips::FeatureMips32r6);
4288 } else if (Tok.getString() == "mips64") {
4289 return parseSetFeature(Mips::FeatureMips64);
4290 } else if (Tok.getString() == "mips64r2") {
4291 return parseSetFeature(Mips::FeatureMips64r2);
4292 } else if (Tok.getString() == "mips64r3") {
4293 return parseSetFeature(Mips::FeatureMips64r3);
4294 } else if (Tok.getString() == "mips64r5") {
4295 return parseSetFeature(Mips::FeatureMips64r5);
4296 } else if (Tok.getString() == "mips64r6") {
4297 return parseSetFeature(Mips::FeatureMips64r6);
4298 } else if (Tok.getString() == "dsp") {
4299 return parseSetFeature(Mips::FeatureDSP);
4300 } else if (Tok.getString() == "nodsp") {
4301 return parseSetNoDspDirective();
4302 } else if (Tok.getString() == "msa") {
4303 return parseSetMsaDirective();
4304 } else if (Tok.getString() == "nomsa") {
4305 return parseSetNoMsaDirective();
4306 } else if (Tok.getString() == "softfloat") {
4307 return parseSetSoftFloatDirective();
4308 } else if (Tok.getString() == "hardfloat") {
4309 return parseSetHardFloatDirective();
4311 // It is just an identifier, look for an assignment.
4312 parseSetAssignment();
4319 /// parseDataDirective
4320 /// ::= .word [ expression (, expression)* ]
4321 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
4322 MCAsmParser &Parser = getParser();
4323 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4325 const MCExpr *Value;
4326 if (getParser().parseExpression(Value))
4329 getParser().getStreamer().EmitValue(Value, Size);
4331 if (getLexer().is(AsmToken::EndOfStatement))
4334 if (getLexer().isNot(AsmToken::Comma))
4335 return Error(L, "unexpected token, expected comma");
4344 /// parseDirectiveGpWord
4345 /// ::= .gpword local_sym
4346 bool MipsAsmParser::parseDirectiveGpWord() {
4347 MCAsmParser &Parser = getParser();
4348 const MCExpr *Value;
4349 // EmitGPRel32Value requires an expression, so we are using base class
4350 // method to evaluate the expression.
4351 if (getParser().parseExpression(Value))
4353 getParser().getStreamer().EmitGPRel32Value(Value);
4355 if (getLexer().isNot(AsmToken::EndOfStatement))
4356 return Error(getLexer().getLoc(),
4357 "unexpected token, expected end of statement");
4358 Parser.Lex(); // Eat EndOfStatement token.
4362 /// parseDirectiveGpDWord
4363 /// ::= .gpdword local_sym
4364 bool MipsAsmParser::parseDirectiveGpDWord() {
4365 MCAsmParser &Parser = getParser();
4366 const MCExpr *Value;
4367 // EmitGPRel64Value requires an expression, so we are using base class
4368 // method to evaluate the expression.
4369 if (getParser().parseExpression(Value))
4371 getParser().getStreamer().EmitGPRel64Value(Value);
4373 if (getLexer().isNot(AsmToken::EndOfStatement))
4374 return Error(getLexer().getLoc(),
4375 "unexpected token, expected end of statement");
4376 Parser.Lex(); // Eat EndOfStatement token.
4380 bool MipsAsmParser::parseDirectiveOption() {
4381 MCAsmParser &Parser = getParser();
4382 // Get the option token.
4383 AsmToken Tok = Parser.getTok();
4384 // At the moment only identifiers are supported.
4385 if (Tok.isNot(AsmToken::Identifier)) {
4386 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
4387 Parser.eatToEndOfStatement();
4391 StringRef Option = Tok.getIdentifier();
4393 if (Option == "pic0") {
4394 getTargetStreamer().emitDirectiveOptionPic0();
4396 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4397 Error(Parser.getTok().getLoc(),
4398 "unexpected token, expected end of statement");
4399 Parser.eatToEndOfStatement();
4404 if (Option == "pic2") {
4405 getTargetStreamer().emitDirectiveOptionPic2();
4407 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4408 Error(Parser.getTok().getLoc(),
4409 "unexpected token, expected end of statement");
4410 Parser.eatToEndOfStatement();
4416 Warning(Parser.getTok().getLoc(),
4417 "unknown option, expected 'pic0' or 'pic2'");
4418 Parser.eatToEndOfStatement();
4422 /// parseInsnDirective
4424 bool MipsAsmParser::parseInsnDirective() {
4425 // If this is not the end of the statement, report an error.
4426 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4427 reportParseError("unexpected token, expected end of statement");
4431 // The actual label marking happens in
4432 // MipsELFStreamer::createPendingLabelRelocs().
4433 getTargetStreamer().emitDirectiveInsn();
4435 getParser().Lex(); // Eat EndOfStatement token.
4439 /// parseDirectiveModule
4440 /// ::= .module oddspreg
4441 /// ::= .module nooddspreg
4442 /// ::= .module fp=value
4443 bool MipsAsmParser::parseDirectiveModule() {
4444 MCAsmParser &Parser = getParser();
4445 MCAsmLexer &Lexer = getLexer();
4446 SMLoc L = Lexer.getLoc();
4448 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
4449 // TODO : get a better message.
4450 reportParseError(".module directive must appear before any code");
4455 if (Parser.parseIdentifier(Option)) {
4456 reportParseError("expected .module option identifier");
4460 if (Option == "oddspreg") {
4461 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
4462 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4464 // If this is not the end of the statement, report an error.
4465 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4466 reportParseError("unexpected token, expected end of statement");
4470 return false; // parseDirectiveModule has finished successfully.
4471 } else if (Option == "nooddspreg") {
4473 Error(L, "'.module nooddspreg' requires the O32 ABI");
4477 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
4478 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4480 // If this is not the end of the statement, report an error.
4481 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4482 reportParseError("unexpected token, expected end of statement");
4486 return false; // parseDirectiveModule has finished successfully.
4487 } else if (Option == "fp") {
4488 return parseDirectiveModuleFP();
4490 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
4494 /// parseDirectiveModuleFP
4498 bool MipsAsmParser::parseDirectiveModuleFP() {
4499 MCAsmParser &Parser = getParser();
4500 MCAsmLexer &Lexer = getLexer();
4502 if (Lexer.isNot(AsmToken::Equal)) {
4503 reportParseError("unexpected token, expected equals sign '='");
4506 Parser.Lex(); // Eat '=' token.
4508 MipsABIFlagsSection::FpABIKind FpABI;
4509 if (!parseFpABIValue(FpABI, ".module"))
4512 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4513 reportParseError("unexpected token, expected end of statement");
4517 // Emit appropriate flags.
4518 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
4519 Parser.Lex(); // Consume the EndOfStatement.
4523 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
4524 StringRef Directive) {
4525 MCAsmParser &Parser = getParser();
4526 MCAsmLexer &Lexer = getLexer();
4528 if (Lexer.is(AsmToken::Identifier)) {
4529 StringRef Value = Parser.getTok().getString();
4532 if (Value != "xx") {
4533 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4538 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
4542 FpABI = MipsABIFlagsSection::FpABIKind::XX;
4546 if (Lexer.is(AsmToken::Integer)) {
4547 unsigned Value = Parser.getTok().getIntVal();
4550 if (Value != 32 && Value != 64) {
4551 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4557 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
4561 FpABI = MipsABIFlagsSection::FpABIKind::S32;
4563 FpABI = MipsABIFlagsSection::FpABIKind::S64;
4571 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
4572 MCAsmParser &Parser = getParser();
4573 StringRef IDVal = DirectiveID.getString();
4575 if (IDVal == ".cpload")
4576 return parseDirectiveCpLoad(DirectiveID.getLoc());
4577 if (IDVal == ".dword") {
4578 parseDataDirective(8, DirectiveID.getLoc());
4581 if (IDVal == ".ent") {
4582 StringRef SymbolName;
4584 if (Parser.parseIdentifier(SymbolName)) {
4585 reportParseError("expected identifier after .ent");
4589 // There's an undocumented extension that allows an integer to
4590 // follow the name of the procedure which AFAICS is ignored by GAS.
4591 // Example: .ent foo,2
4592 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4593 if (getLexer().isNot(AsmToken::Comma)) {
4594 // Even though we accept this undocumented extension for compatibility
4595 // reasons, the additional integer argument does not actually change
4596 // the behaviour of the '.ent' directive, so we would like to discourage
4597 // its use. We do this by not referring to the extended version in
4598 // error messages which are not directly related to its use.
4599 reportParseError("unexpected token, expected end of statement");
4602 Parser.Lex(); // Eat the comma.
4603 const MCExpr *DummyNumber;
4604 int64_t DummyNumberVal;
4605 // If the user was explicitly trying to use the extended version,
4606 // we still give helpful extension-related error messages.
4607 if (Parser.parseExpression(DummyNumber)) {
4608 reportParseError("expected number after comma");
4611 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
4612 reportParseError("expected an absolute expression after comma");
4617 // If this is not the end of the statement, report an error.
4618 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4619 reportParseError("unexpected token, expected end of statement");
4623 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
4625 getTargetStreamer().emitDirectiveEnt(*Sym);
4630 if (IDVal == ".end") {
4631 StringRef SymbolName;
4633 if (Parser.parseIdentifier(SymbolName)) {
4634 reportParseError("expected identifier after .end");
4638 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4639 reportParseError("unexpected token, expected end of statement");
4643 if (CurrentFn == nullptr) {
4644 reportParseError(".end used without .ent");
4648 if ((SymbolName != CurrentFn->getName())) {
4649 reportParseError(".end symbol does not match .ent symbol");
4653 getTargetStreamer().emitDirectiveEnd(SymbolName);
4654 CurrentFn = nullptr;
4658 if (IDVal == ".frame") {
4659 // .frame $stack_reg, frame_size_in_bytes, $return_reg
4660 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4661 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4662 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4663 reportParseError("expected stack register");
4667 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4668 if (!StackRegOpnd.isGPRAsmReg()) {
4669 reportParseError(StackRegOpnd.getStartLoc(),
4670 "expected general purpose register");
4673 unsigned StackReg = StackRegOpnd.getGPR32Reg();
4675 if (Parser.getTok().is(AsmToken::Comma))
4678 reportParseError("unexpected token, expected comma");
4682 // Parse the frame size.
4683 const MCExpr *FrameSize;
4684 int64_t FrameSizeVal;
4686 if (Parser.parseExpression(FrameSize)) {
4687 reportParseError("expected frame size value");
4691 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
4692 reportParseError("frame size not an absolute expression");
4696 if (Parser.getTok().is(AsmToken::Comma))
4699 reportParseError("unexpected token, expected comma");
4703 // Parse the return register.
4705 ResTy = parseAnyRegister(TmpReg);
4706 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4707 reportParseError("expected return register");
4711 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4712 if (!ReturnRegOpnd.isGPRAsmReg()) {
4713 reportParseError(ReturnRegOpnd.getStartLoc(),
4714 "expected general purpose register");
4718 // If this is not the end of the statement, report an error.
4719 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4720 reportParseError("unexpected token, expected end of statement");
4724 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
4725 ReturnRegOpnd.getGPR32Reg());
4729 if (IDVal == ".set") {
4730 return parseDirectiveSet();
4733 if (IDVal == ".mask" || IDVal == ".fmask") {
4734 // .mask bitmask, frame_offset
4735 // bitmask: One bit for each register used.
4736 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
4737 // first register is expected to be saved.
4739 // .mask 0x80000000, -4
4740 // .fmask 0x80000000, -4
4743 // Parse the bitmask
4744 const MCExpr *BitMask;
4747 if (Parser.parseExpression(BitMask)) {
4748 reportParseError("expected bitmask value");
4752 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
4753 reportParseError("bitmask not an absolute expression");
4757 if (Parser.getTok().is(AsmToken::Comma))
4760 reportParseError("unexpected token, expected comma");
4764 // Parse the frame_offset
4765 const MCExpr *FrameOffset;
4766 int64_t FrameOffsetVal;
4768 if (Parser.parseExpression(FrameOffset)) {
4769 reportParseError("expected frame offset value");
4773 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
4774 reportParseError("frame offset not an absolute expression");
4778 // If this is not the end of the statement, report an error.
4779 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4780 reportParseError("unexpected token, expected end of statement");
4784 if (IDVal == ".mask")
4785 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
4787 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
4791 if (IDVal == ".nan")
4792 return parseDirectiveNaN();
4794 if (IDVal == ".gpword") {
4795 parseDirectiveGpWord();
4799 if (IDVal == ".gpdword") {
4800 parseDirectiveGpDWord();
4804 if (IDVal == ".word") {
4805 parseDataDirective(4, DirectiveID.getLoc());
4809 if (IDVal == ".option")
4810 return parseDirectiveOption();
4812 if (IDVal == ".abicalls") {
4813 getTargetStreamer().emitDirectiveAbiCalls();
4814 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4815 Error(Parser.getTok().getLoc(),
4816 "unexpected token, expected end of statement");
4818 Parser.eatToEndOfStatement();
4823 if (IDVal == ".cpsetup")
4824 return parseDirectiveCPSetup();
4826 if (IDVal == ".module")
4827 return parseDirectiveModule();
4829 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
4830 return parseInternalDirectiveReallowModule();
4832 if (IDVal == ".insn")
4833 return parseInsnDirective();
4838 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
4839 // If this is not the end of the statement, report an error.
4840 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4841 reportParseError("unexpected token, expected end of statement");
4845 getTargetStreamer().reallowModuleDirective();
4847 getParser().Lex(); // Eat EndOfStatement token.
4851 extern "C" void LLVMInitializeMipsAsmParser() {
4852 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
4853 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
4854 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
4855 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
4858 #define GET_REGISTER_MATCHER
4859 #define GET_MATCHER_IMPLEMENTATION
4860 #include "MipsGenAsmMatcher.inc"