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());
1995 // If it's a 64-bit architecture, expand to:
1996 // la d,sym => lui d,highest(sym)
1997 // ori d,d,higher(sym)
1999 // ori d,d,hi16(sym)
2001 // ori d,d,lo16(sym)
2002 const MCSymbolRefExpr *HighestExpr = MCSymbolRefExpr::create(
2003 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
2004 const MCSymbolRefExpr *HigherExpr = MCSymbolRefExpr::create(
2005 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
2007 tmpInst.setOpcode(Mips::LUi);
2008 tmpInst.addOperand(MCOperand::createReg(DstReg));
2009 tmpInst.addOperand(MCOperand::createExpr(HighestExpr));
2010 Instructions.push_back(tmpInst);
2012 createLShiftOri<0>(MCOperand::createExpr(HigherExpr), DstReg, SMLoc(),
2014 createLShiftOri<16>(MCOperand::createExpr(HiExpr), DstReg, SMLoc(),
2016 createLShiftOri<16>(MCOperand::createExpr(LoExpr), DstReg, SMLoc(),
2019 // Otherwise, expand to:
2020 // la d,sym => lui d,hi16(sym)
2021 // ori d,d,lo16(sym)
2022 tmpInst.setOpcode(Mips::LUi);
2023 tmpInst.addOperand(MCOperand::createReg(DstReg));
2024 tmpInst.addOperand(MCOperand::createExpr(HiExpr));
2025 Instructions.push_back(tmpInst);
2027 createLShiftOri<0>(MCOperand::createExpr(LoExpr), DstReg, SMLoc(),
2031 if (SrcReg != Mips::NoRegister)
2032 createAddu(DstReg, DstReg, SrcReg, Instructions);
2037 bool MipsAsmParser::expandUncondBranchMMPseudo(
2038 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2039 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2040 "unexpected number of operands");
2042 MCOperand Offset = Inst.getOperand(0);
2043 if (Offset.isExpr()) {
2045 Inst.setOpcode(Mips::BEQ_MM);
2046 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2047 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2048 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2050 assert(Offset.isImm() && "expected immediate operand kind");
2051 if (isIntN(11, Offset.getImm())) {
2052 // If offset fits into 11 bits then this instruction becomes microMIPS
2053 // 16-bit unconditional branch instruction.
2054 Inst.setOpcode(Mips::B16_MM);
2056 if (!isIntN(17, Offset.getImm()))
2057 Error(IDLoc, "branch target out of range");
2058 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2059 Error(IDLoc, "branch to misaligned address");
2061 Inst.setOpcode(Mips::BEQ_MM);
2062 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2063 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2064 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2067 Instructions.push_back(Inst);
2069 // If .set reorder is active, emit a NOP after the branch instruction.
2070 if (AssemblerOptions.back()->isReorder())
2071 createNop(true, IDLoc, Instructions);
2076 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc,
2077 SmallVectorImpl<MCInst> &Instructions) {
2078 const MCOperand &DstRegOp = Inst.getOperand(0);
2079 assert(DstRegOp.isReg() && "expected register operand kind");
2081 const MCOperand &ImmOp = Inst.getOperand(1);
2082 assert(ImmOp.isImm() && "expected immediate operand kind");
2084 const MCOperand &MemOffsetOp = Inst.getOperand(2);
2085 assert(MemOffsetOp.isImm() && "expected immediate operand kind");
2087 unsigned OpCode = 0;
2088 switch(Inst.getOpcode()) {
2096 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2100 int64_t ImmValue = ImmOp.getImm();
2101 if (ImmValue == 0) {
2103 BranchInst.setOpcode(OpCode);
2104 BranchInst.addOperand(DstRegOp);
2105 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2106 BranchInst.addOperand(MemOffsetOp);
2107 Instructions.push_back(BranchInst);
2109 warnIfNoMacro(IDLoc);
2111 unsigned ATReg = getATReg(IDLoc);
2115 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), IDLoc,
2120 BranchInst.setOpcode(OpCode);
2121 BranchInst.addOperand(DstRegOp);
2122 BranchInst.addOperand(MCOperand::createReg(ATReg));
2123 BranchInst.addOperand(MemOffsetOp);
2124 Instructions.push_back(BranchInst);
2129 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2130 SmallVectorImpl<MCInst> &Instructions,
2131 bool isLoad, bool isImmOpnd) {
2133 unsigned ImmOffset, HiOffset, LoOffset;
2134 const MCExpr *ExprOffset;
2136 // 1st operand is either the source or destination register.
2137 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2138 unsigned RegOpNum = Inst.getOperand(0).getReg();
2139 // 2nd operand is the base register.
2140 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2141 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2142 // 3rd operand is either an immediate or expression.
2144 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2145 ImmOffset = Inst.getOperand(2).getImm();
2146 LoOffset = ImmOffset & 0x0000ffff;
2147 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2148 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2149 if (LoOffset & 0x8000)
2152 ExprOffset = Inst.getOperand(2).getExpr();
2153 // All instructions will have the same location.
2154 TempInst.setLoc(IDLoc);
2155 // These are some of the types of expansions we perform here:
2156 // 1) lw $8, sym => lui $8, %hi(sym)
2157 // lw $8, %lo(sym)($8)
2158 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2160 // lw $8, %lo(offset)($9)
2161 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2163 // lw $8, %lo(offset)($at)
2164 // 4) sw $8, sym => lui $at, %hi(sym)
2165 // sw $8, %lo(sym)($at)
2166 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2168 // sw $8, %lo(offset)($at)
2169 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2170 // ldc1 $f0, %lo(sym)($at)
2172 // For load instructions we can use the destination register as a temporary
2173 // if base and dst are different (examples 1 and 2) and if the base register
2174 // is general purpose otherwise we must use $at (example 6) and error if it's
2175 // not available. For stores we must use $at (examples 4 and 5) because we
2176 // must not clobber the source register setting up the offset.
2177 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2178 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2179 unsigned RegClassIDOp0 =
2180 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2181 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2182 (RegClassIDOp0 == Mips::GPR64RegClassID);
2183 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2184 TmpRegNum = RegOpNum;
2186 // At this point we need AT to perform the expansions and we exit if it is
2188 TmpRegNum = getATReg(IDLoc);
2193 TempInst.setOpcode(Mips::LUi);
2194 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2196 TempInst.addOperand(MCOperand::createImm(HiOffset));
2198 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2199 TempInst.addOperand(MCOperand::createExpr(HiExpr));
2201 // Add the instruction to the list.
2202 Instructions.push_back(TempInst);
2203 // Prepare TempInst for next instruction.
2205 // Add temp register to base.
2206 if (BaseRegNum != Mips::ZERO) {
2207 TempInst.setOpcode(Mips::ADDu);
2208 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2209 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2210 TempInst.addOperand(MCOperand::createReg(BaseRegNum));
2211 Instructions.push_back(TempInst);
2214 // And finally, create original instruction with low part
2215 // of offset and new base.
2216 TempInst.setOpcode(Inst.getOpcode());
2217 TempInst.addOperand(MCOperand::createReg(RegOpNum));
2218 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2220 TempInst.addOperand(MCOperand::createImm(LoOffset));
2222 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2223 TempInst.addOperand(MCOperand::createExpr(LoExpr));
2225 Instructions.push_back(TempInst);
2230 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2231 SmallVectorImpl<MCInst> &Instructions) {
2232 unsigned OpNum = Inst.getNumOperands();
2233 unsigned Opcode = Inst.getOpcode();
2234 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2236 assert (Inst.getOperand(OpNum - 1).isImm() &&
2237 Inst.getOperand(OpNum - 2).isReg() &&
2238 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2240 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2241 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2242 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2243 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2244 // It can be implemented as SWM16 or LWM16 instruction.
2245 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2247 Inst.setOpcode(NewOpcode);
2248 Instructions.push_back(Inst);
2252 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
2253 SmallVectorImpl<MCInst> &Instructions) {
2254 unsigned PseudoOpcode = Inst.getOpcode();
2255 unsigned SrcReg = Inst.getOperand(0).getReg();
2256 unsigned TrgReg = Inst.getOperand(1).getReg();
2257 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
2259 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2260 bool ReverseOrderSLT, IsUnsigned, AcceptsEquality;
2262 switch (PseudoOpcode) {
2265 AcceptsEquality = false;
2266 ReverseOrderSLT = false;
2267 IsUnsigned = (PseudoOpcode == Mips::BLTU);
2268 ZeroSrcOpcode = Mips::BGTZ;
2269 ZeroTrgOpcode = Mips::BLTZ;
2273 AcceptsEquality = true;
2274 ReverseOrderSLT = true;
2275 IsUnsigned = (PseudoOpcode == Mips::BLEU);
2276 ZeroSrcOpcode = Mips::BGEZ;
2277 ZeroTrgOpcode = Mips::BLEZ;
2281 AcceptsEquality = true;
2282 ReverseOrderSLT = false;
2283 IsUnsigned = (PseudoOpcode == Mips::BGEU);
2284 ZeroSrcOpcode = Mips::BLEZ;
2285 ZeroTrgOpcode = Mips::BGEZ;
2289 AcceptsEquality = false;
2290 ReverseOrderSLT = true;
2291 IsUnsigned = (PseudoOpcode == Mips::BGTU);
2292 ZeroSrcOpcode = Mips::BLTZ;
2293 ZeroTrgOpcode = Mips::BGTZ;
2296 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2300 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
2301 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
2302 if (IsSrcRegZero && IsTrgRegZero) {
2303 // FIXME: All of these Opcode-specific if's are needed for compatibility
2304 // with GAS' behaviour. However, they may not generate the most efficient
2305 // code in some circumstances.
2306 if (PseudoOpcode == Mips::BLT) {
2307 BranchInst.setOpcode(Mips::BLTZ);
2308 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2309 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2310 Instructions.push_back(BranchInst);
2313 if (PseudoOpcode == Mips::BLE) {
2314 BranchInst.setOpcode(Mips::BLEZ);
2315 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2316 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2317 Instructions.push_back(BranchInst);
2318 Warning(IDLoc, "branch is always taken");
2321 if (PseudoOpcode == Mips::BGE) {
2322 BranchInst.setOpcode(Mips::BGEZ);
2323 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2324 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2325 Instructions.push_back(BranchInst);
2326 Warning(IDLoc, "branch is always taken");
2329 if (PseudoOpcode == Mips::BGT) {
2330 BranchInst.setOpcode(Mips::BGTZ);
2331 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2332 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2333 Instructions.push_back(BranchInst);
2336 if (PseudoOpcode == Mips::BGTU) {
2337 BranchInst.setOpcode(Mips::BNE);
2338 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2339 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2340 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2341 Instructions.push_back(BranchInst);
2344 if (AcceptsEquality) {
2345 // If both registers are $0 and the pseudo-branch accepts equality, it
2346 // will always be taken, so we emit an unconditional branch.
2347 BranchInst.setOpcode(Mips::BEQ);
2348 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2349 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2350 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2351 Instructions.push_back(BranchInst);
2352 Warning(IDLoc, "branch is always taken");
2355 // If both registers are $0 and the pseudo-branch does not accept
2356 // equality, it will never be taken, so we don't have to emit anything.
2359 if (IsSrcRegZero || IsTrgRegZero) {
2360 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
2361 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
2362 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
2363 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
2364 // the pseudo-branch will never be taken, so we don't emit anything.
2365 // This only applies to unsigned pseudo-branches.
2368 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
2369 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
2370 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
2371 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
2372 // the pseudo-branch will always be taken, so we emit an unconditional
2374 // This only applies to unsigned pseudo-branches.
2375 BranchInst.setOpcode(Mips::BEQ);
2376 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2377 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2378 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2379 Instructions.push_back(BranchInst);
2380 Warning(IDLoc, "branch is always taken");
2384 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
2385 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
2386 // the pseudo-branch will be taken only when the non-zero register is
2387 // different from 0, so we emit a BNEZ.
2389 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
2390 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
2391 // the pseudo-branch will be taken only when the non-zero register is
2392 // equal to 0, so we emit a BEQZ.
2394 // Because only BLEU and BGEU branch on equality, we can use the
2395 // AcceptsEquality variable to decide when to emit the BEQZ.
2396 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2397 BranchInst.addOperand(
2398 MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2399 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2400 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2401 Instructions.push_back(BranchInst);
2404 // If we have a signed pseudo-branch and one of the registers is $0,
2405 // we can use an appropriate compare-to-zero branch. We select which one
2406 // to use in the switch statement above.
2407 BranchInst.setOpcode(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode);
2408 BranchInst.addOperand(MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2409 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2410 Instructions.push_back(BranchInst);
2414 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
2415 // expansions. If it is not available, we return.
2416 unsigned ATRegNum = getATReg(IDLoc);
2420 warnIfNoMacro(IDLoc);
2422 // SLT fits well with 2 of our 4 pseudo-branches:
2423 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
2424 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
2425 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
2426 // This is accomplished by using a BNEZ with the result of the SLT.
2428 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
2429 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
2430 // Because only BGE and BLE branch on equality, we can use the
2431 // AcceptsEquality variable to decide when to emit the BEQZ.
2432 // Note that the order of the SLT arguments doesn't change between
2435 // The same applies to the unsigned variants, except that SLTu is used
2438 SetInst.setOpcode(IsUnsigned ? Mips::SLTu : Mips::SLT);
2439 SetInst.addOperand(MCOperand::createReg(ATRegNum));
2440 SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? TrgReg : SrcReg));
2441 SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? SrcReg : TrgReg));
2442 Instructions.push_back(SetInst);
2444 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2445 BranchInst.addOperand(MCOperand::createReg(ATRegNum));
2446 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2447 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2448 Instructions.push_back(BranchInst);
2452 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
2453 SmallVectorImpl<MCInst> &Instructions) {
2455 if (hasShortDelaySlot) {
2456 NopInst.setOpcode(Mips::MOVE16_MM);
2457 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2458 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2460 NopInst.setOpcode(Mips::SLL);
2461 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2462 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2463 NopInst.addOperand(MCOperand::createImm(0));
2465 Instructions.push_back(NopInst);
2468 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
2470 SmallVectorImpl<MCInst> &Instructions) {
2472 AdduInst.setOpcode(Mips::ADDu);
2473 AdduInst.addOperand(MCOperand::createReg(DstReg));
2474 AdduInst.addOperand(MCOperand::createReg(SrcReg));
2475 AdduInst.addOperand(MCOperand::createReg(TrgReg));
2476 Instructions.push_back(AdduInst);
2479 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
2480 // As described by the Mips32r2 spec, the registers Rd and Rs for
2481 // jalr.hb must be different.
2482 unsigned Opcode = Inst.getOpcode();
2484 if (Opcode == Mips::JALR_HB &&
2485 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
2486 return Match_RequiresDifferentSrcAndDst;
2488 return Match_Success;
2491 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2492 OperandVector &Operands,
2494 uint64_t &ErrorInfo,
2495 bool MatchingInlineAsm) {
2498 SmallVector<MCInst, 8> Instructions;
2499 unsigned MatchResult =
2500 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
2502 switch (MatchResult) {
2503 case Match_Success: {
2504 if (processInstruction(Inst, IDLoc, Instructions))
2506 for (unsigned i = 0; i < Instructions.size(); i++)
2507 Out.EmitInstruction(Instructions[i], STI);
2510 case Match_MissingFeature:
2511 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2513 case Match_InvalidOperand: {
2514 SMLoc ErrorLoc = IDLoc;
2515 if (ErrorInfo != ~0ULL) {
2516 if (ErrorInfo >= Operands.size())
2517 return Error(IDLoc, "too few operands for instruction");
2519 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
2520 if (ErrorLoc == SMLoc())
2524 return Error(ErrorLoc, "invalid operand for instruction");
2526 case Match_MnemonicFail:
2527 return Error(IDLoc, "invalid instruction");
2528 case Match_RequiresDifferentSrcAndDst:
2529 return Error(IDLoc, "source and destination must be different");
2532 llvm_unreachable("Implement any new match types added!");
2535 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
2536 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
2537 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
2538 ") without \".set noat\"");
2541 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
2542 if (!AssemblerOptions.back()->isMacro())
2543 Warning(Loc, "macro instruction expanded into multiple instructions");
2547 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
2548 SMRange Range, bool ShowColors) {
2549 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
2550 Range, SMFixIt(Range, FixMsg),
2554 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
2557 CC = StringSwitch<unsigned>(Name)
2593 if (!(isABI_N32() || isABI_N64()))
2596 if (12 <= CC && CC <= 15) {
2597 // Name is one of t4-t7
2598 AsmToken RegTok = getLexer().peekTok();
2599 SMRange RegRange = RegTok.getLocRange();
2601 StringRef FixedName = StringSwitch<StringRef>(Name)
2607 assert(FixedName != "" && "Register name is not one of t4-t7.");
2609 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
2610 "Did you mean $" + FixedName + "?", RegRange);
2613 // Although SGI documentation just cuts out t0-t3 for n32/n64,
2614 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
2615 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
2616 if (8 <= CC && CC <= 11)
2620 CC = StringSwitch<unsigned>(Name)
2632 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
2635 CC = StringSwitch<unsigned>(Name)
2636 .Case("hwr_cpunum", 0)
2637 .Case("hwr_synci_step", 1)
2639 .Case("hwr_ccres", 3)
2640 .Case("hwr_ulr", 29)
2646 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2648 if (Name[0] == 'f') {
2649 StringRef NumString = Name.substr(1);
2651 if (NumString.getAsInteger(10, IntVal))
2652 return -1; // This is not an integer.
2653 if (IntVal > 31) // Maximum index for fpu register.
2660 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2662 if (Name.startswith("fcc")) {
2663 StringRef NumString = Name.substr(3);
2665 if (NumString.getAsInteger(10, IntVal))
2666 return -1; // This is not an integer.
2667 if (IntVal > 7) // There are only 8 fcc registers.
2674 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2676 if (Name.startswith("ac")) {
2677 StringRef NumString = Name.substr(2);
2679 if (NumString.getAsInteger(10, IntVal))
2680 return -1; // This is not an integer.
2681 if (IntVal > 3) // There are only 3 acc registers.
2688 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2691 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
2700 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
2703 CC = StringSwitch<unsigned>(Name)
2706 .Case("msaaccess", 2)
2708 .Case("msamodify", 4)
2709 .Case("msarequest", 5)
2711 .Case("msaunmap", 7)
2717 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
2718 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
2720 reportParseError(Loc,
2721 "pseudo-instruction requires $at, which is not available");
2724 unsigned AT = getReg(
2725 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
2729 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2730 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2733 unsigned MipsAsmParser::getGPR(int RegNo) {
2734 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2738 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2740 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2743 return getReg(RegClass, RegNum);
2746 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2747 MCAsmParser &Parser = getParser();
2748 DEBUG(dbgs() << "parseOperand\n");
2750 // Check if the current operand has a custom associated parser, if so, try to
2751 // custom parse the operand, or fallback to the general approach.
2752 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2753 if (ResTy == MatchOperand_Success)
2755 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2756 // there was a match, but an error occurred, in which case, just return that
2757 // the operand parsing failed.
2758 if (ResTy == MatchOperand_ParseFail)
2761 DEBUG(dbgs() << ".. Generic Parser\n");
2763 switch (getLexer().getKind()) {
2765 Error(Parser.getTok().getLoc(), "unexpected token in operand");
2767 case AsmToken::Dollar: {
2768 // Parse the register.
2769 SMLoc S = Parser.getTok().getLoc();
2771 // Almost all registers have been parsed by custom parsers. There is only
2772 // one exception to this. $zero (and it's alias $0) will reach this point
2773 // for div, divu, and similar instructions because it is not an operand
2774 // to the instruction definition but an explicit register. Special case
2775 // this situation for now.
2776 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
2779 // Maybe it is a symbol reference.
2780 StringRef Identifier;
2781 if (Parser.parseIdentifier(Identifier))
2784 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2785 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
2786 // Otherwise create a symbol reference.
2788 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
2790 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
2793 // Else drop to expression parsing.
2794 case AsmToken::LParen:
2795 case AsmToken::Minus:
2796 case AsmToken::Plus:
2797 case AsmToken::Integer:
2798 case AsmToken::Tilde:
2799 case AsmToken::String: {
2800 DEBUG(dbgs() << ".. generic integer\n");
2801 OperandMatchResultTy ResTy = parseImm(Operands);
2802 return ResTy != MatchOperand_Success;
2804 case AsmToken::Percent: {
2805 // It is a symbol reference or constant expression.
2806 const MCExpr *IdVal;
2807 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
2808 if (parseRelocOperand(IdVal))
2811 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2813 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2815 } // case AsmToken::Percent
2816 } // switch(getLexer().getKind())
2820 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
2821 StringRef RelocStr) {
2823 // Check the type of the expression.
2824 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
2825 // It's a constant, evaluate reloc value.
2827 switch (getVariantKind(RelocStr)) {
2828 case MCSymbolRefExpr::VK_Mips_ABS_LO:
2829 // Get the 1st 16-bits.
2830 Val = MCE->getValue() & 0xffff;
2832 case MCSymbolRefExpr::VK_Mips_ABS_HI:
2833 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
2834 // 16 bits being negative.
2835 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
2837 case MCSymbolRefExpr::VK_Mips_HIGHER:
2838 // Get the 3rd 16-bits.
2839 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
2841 case MCSymbolRefExpr::VK_Mips_HIGHEST:
2842 // Get the 4th 16-bits.
2843 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
2846 report_fatal_error("unsupported reloc value");
2848 return MCConstantExpr::create(Val, getContext());
2851 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
2852 // It's a symbol, create a symbolic expression from the symbol.
2853 const MCSymbol *Symbol = &MSRE->getSymbol();
2854 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2855 Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
2859 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2860 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2862 // Try to create target expression.
2863 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
2864 return MipsMCExpr::create(VK, Expr, getContext());
2866 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
2867 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
2868 Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
2872 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
2873 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
2874 Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
2877 // Just return the original expression.
2881 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
2883 switch (Expr->getKind()) {
2884 case MCExpr::Constant:
2886 case MCExpr::SymbolRef:
2887 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
2888 case MCExpr::Binary:
2889 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2890 if (!isEvaluated(BE->getLHS()))
2892 return isEvaluated(BE->getRHS());
2895 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
2896 case MCExpr::Target:
2902 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
2903 MCAsmParser &Parser = getParser();
2904 Parser.Lex(); // Eat the % token.
2905 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
2906 if (Tok.isNot(AsmToken::Identifier))
2909 std::string Str = Tok.getIdentifier();
2911 Parser.Lex(); // Eat the identifier.
2912 // Now make an expression from the rest of the operand.
2913 const MCExpr *IdVal;
2916 if (getLexer().getKind() == AsmToken::LParen) {
2918 Parser.Lex(); // Eat the '(' token.
2919 if (getLexer().getKind() == AsmToken::Percent) {
2920 Parser.Lex(); // Eat the % token.
2921 const AsmToken &nextTok = Parser.getTok();
2922 if (nextTok.isNot(AsmToken::Identifier))
2925 Str += nextTok.getIdentifier();
2926 Parser.Lex(); // Eat the identifier.
2927 if (getLexer().getKind() != AsmToken::LParen)
2932 if (getParser().parseParenExpression(IdVal, EndLoc))
2935 while (getLexer().getKind() == AsmToken::RParen)
2936 Parser.Lex(); // Eat the ')' token.
2939 return true; // Parenthesis must follow the relocation operand.
2941 Res = evaluateRelocExpr(IdVal, Str);
2945 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2947 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2948 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2949 if (ResTy == MatchOperand_Success) {
2950 assert(Operands.size() == 1);
2951 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2952 StartLoc = Operand.getStartLoc();
2953 EndLoc = Operand.getEndLoc();
2955 // AFAIK, we only support numeric registers and named GPR's in CFI
2957 // Don't worry about eating tokens before failing. Using an unrecognised
2958 // register is a parse error.
2959 if (Operand.isGPRAsmReg()) {
2960 // Resolve to GPR32 or GPR64 appropriately.
2961 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2964 return (RegNo == (unsigned)-1);
2967 assert(Operands.size() == 0);
2968 return (RegNo == (unsigned)-1);
2971 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2972 MCAsmParser &Parser = getParser();
2976 while (getLexer().getKind() == AsmToken::LParen)
2979 switch (getLexer().getKind()) {
2982 case AsmToken::Identifier:
2983 case AsmToken::LParen:
2984 case AsmToken::Integer:
2985 case AsmToken::Minus:
2986 case AsmToken::Plus:
2988 Result = getParser().parseParenExpression(Res, S);
2990 Result = (getParser().parseExpression(Res));
2991 while (getLexer().getKind() == AsmToken::RParen)
2994 case AsmToken::Percent:
2995 Result = parseRelocOperand(Res);
3000 MipsAsmParser::OperandMatchResultTy
3001 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
3002 MCAsmParser &Parser = getParser();
3003 DEBUG(dbgs() << "parseMemOperand\n");
3004 const MCExpr *IdVal = nullptr;
3006 bool isParenExpr = false;
3007 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
3008 // First operand is the offset.
3009 S = Parser.getTok().getLoc();
3011 if (getLexer().getKind() == AsmToken::LParen) {
3016 if (getLexer().getKind() != AsmToken::Dollar) {
3017 if (parseMemOffset(IdVal, isParenExpr))
3018 return MatchOperand_ParseFail;
3020 const AsmToken &Tok = Parser.getTok(); // Get the next token.
3021 if (Tok.isNot(AsmToken::LParen)) {
3022 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
3023 if (Mnemonic.getToken() == "la") {
3025 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3026 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3027 return MatchOperand_Success;
3029 if (Tok.is(AsmToken::EndOfStatement)) {
3031 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3033 // Zero register assumed, add a memory operand with ZERO as its base.
3034 // "Base" will be managed by k_Memory.
3035 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
3038 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
3039 return MatchOperand_Success;
3041 Error(Parser.getTok().getLoc(), "'(' expected");
3042 return MatchOperand_ParseFail;
3045 Parser.Lex(); // Eat the '(' token.
3048 Res = parseAnyRegister(Operands);
3049 if (Res != MatchOperand_Success)
3052 if (Parser.getTok().isNot(AsmToken::RParen)) {
3053 Error(Parser.getTok().getLoc(), "')' expected");
3054 return MatchOperand_ParseFail;
3057 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3059 Parser.Lex(); // Eat the ')' token.
3062 IdVal = MCConstantExpr::create(0, getContext());
3064 // Replace the register operand with the memory operand.
3065 std::unique_ptr<MipsOperand> op(
3066 static_cast<MipsOperand *>(Operands.back().release()));
3067 // Remove the register from the operands.
3068 // "op" will be managed by k_Memory.
3069 Operands.pop_back();
3070 // Add the memory operand.
3071 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
3073 if (IdVal->evaluateAsAbsolute(Imm))
3074 IdVal = MCConstantExpr::create(Imm, getContext());
3075 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
3076 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
3080 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
3081 return MatchOperand_Success;
3084 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
3085 MCAsmParser &Parser = getParser();
3086 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
3088 SMLoc S = Parser.getTok().getLoc();
3090 if (Sym->isVariable())
3091 Expr = Sym->getVariableValue();
3094 if (Expr->getKind() == MCExpr::SymbolRef) {
3095 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3096 StringRef DefSymbol = Ref->getSymbol().getName();
3097 if (DefSymbol.startswith("$")) {
3098 OperandMatchResultTy ResTy =
3099 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
3100 if (ResTy == MatchOperand_Success) {
3103 } else if (ResTy == MatchOperand_ParseFail)
3104 llvm_unreachable("Should never ParseFail");
3107 } else if (Expr->getKind() == MCExpr::Constant) {
3109 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
3111 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
3118 MipsAsmParser::OperandMatchResultTy
3119 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
3120 StringRef Identifier,
3122 int Index = matchCPURegisterName(Identifier);
3124 Operands.push_back(MipsOperand::createGPRReg(
3125 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3126 return MatchOperand_Success;
3129 Index = matchHWRegsRegisterName(Identifier);
3131 Operands.push_back(MipsOperand::createHWRegsReg(
3132 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3133 return MatchOperand_Success;
3136 Index = matchFPURegisterName(Identifier);
3138 Operands.push_back(MipsOperand::createFGRReg(
3139 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3140 return MatchOperand_Success;
3143 Index = matchFCCRegisterName(Identifier);
3145 Operands.push_back(MipsOperand::createFCCReg(
3146 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3147 return MatchOperand_Success;
3150 Index = matchACRegisterName(Identifier);
3152 Operands.push_back(MipsOperand::createACCReg(
3153 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3154 return MatchOperand_Success;
3157 Index = matchMSA128RegisterName(Identifier);
3159 Operands.push_back(MipsOperand::createMSA128Reg(
3160 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3161 return MatchOperand_Success;
3164 Index = matchMSA128CtrlRegisterName(Identifier);
3166 Operands.push_back(MipsOperand::createMSACtrlReg(
3167 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3168 return MatchOperand_Success;
3171 return MatchOperand_NoMatch;
3174 MipsAsmParser::OperandMatchResultTy
3175 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
3176 MCAsmParser &Parser = getParser();
3177 auto Token = Parser.getLexer().peekTok(false);
3179 if (Token.is(AsmToken::Identifier)) {
3180 DEBUG(dbgs() << ".. identifier\n");
3181 StringRef Identifier = Token.getIdentifier();
3182 OperandMatchResultTy ResTy =
3183 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
3185 } else if (Token.is(AsmToken::Integer)) {
3186 DEBUG(dbgs() << ".. integer\n");
3187 Operands.push_back(MipsOperand::createNumericReg(
3188 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
3190 return MatchOperand_Success;
3193 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
3195 return MatchOperand_NoMatch;
3198 MipsAsmParser::OperandMatchResultTy
3199 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
3200 MCAsmParser &Parser = getParser();
3201 DEBUG(dbgs() << "parseAnyRegister\n");
3203 auto Token = Parser.getTok();
3205 SMLoc S = Token.getLoc();
3207 if (Token.isNot(AsmToken::Dollar)) {
3208 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
3209 if (Token.is(AsmToken::Identifier)) {
3210 if (searchSymbolAlias(Operands))
3211 return MatchOperand_Success;
3213 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
3214 return MatchOperand_NoMatch;
3216 DEBUG(dbgs() << ".. $\n");
3218 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
3219 if (ResTy == MatchOperand_Success) {
3221 Parser.Lex(); // identifier
3226 MipsAsmParser::OperandMatchResultTy
3227 MipsAsmParser::parseImm(OperandVector &Operands) {
3228 MCAsmParser &Parser = getParser();
3229 switch (getLexer().getKind()) {
3231 return MatchOperand_NoMatch;
3232 case AsmToken::LParen:
3233 case AsmToken::Minus:
3234 case AsmToken::Plus:
3235 case AsmToken::Integer:
3236 case AsmToken::Tilde:
3237 case AsmToken::String:
3241 const MCExpr *IdVal;
3242 SMLoc S = Parser.getTok().getLoc();
3243 if (getParser().parseExpression(IdVal))
3244 return MatchOperand_ParseFail;
3246 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3247 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3248 return MatchOperand_Success;
3251 MipsAsmParser::OperandMatchResultTy
3252 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
3253 MCAsmParser &Parser = getParser();
3254 DEBUG(dbgs() << "parseJumpTarget\n");
3256 SMLoc S = getLexer().getLoc();
3258 // Integers and expressions are acceptable
3259 OperandMatchResultTy ResTy = parseImm(Operands);
3260 if (ResTy != MatchOperand_NoMatch)
3263 // Registers are a valid target and have priority over symbols.
3264 ResTy = parseAnyRegister(Operands);
3265 if (ResTy != MatchOperand_NoMatch)
3268 const MCExpr *Expr = nullptr;
3269 if (Parser.parseExpression(Expr)) {
3270 // We have no way of knowing if a symbol was consumed so we must ParseFail
3271 return MatchOperand_ParseFail;
3274 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
3275 return MatchOperand_Success;
3278 MipsAsmParser::OperandMatchResultTy
3279 MipsAsmParser::parseInvNum(OperandVector &Operands) {
3280 MCAsmParser &Parser = getParser();
3281 const MCExpr *IdVal;
3282 // If the first token is '$' we may have register operand.
3283 if (Parser.getTok().is(AsmToken::Dollar))
3284 return MatchOperand_NoMatch;
3285 SMLoc S = Parser.getTok().getLoc();
3286 if (getParser().parseExpression(IdVal))
3287 return MatchOperand_ParseFail;
3288 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
3289 assert(MCE && "Unexpected MCExpr type.");
3290 int64_t Val = MCE->getValue();
3291 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3292 Operands.push_back(MipsOperand::CreateImm(
3293 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
3294 return MatchOperand_Success;
3297 MipsAsmParser::OperandMatchResultTy
3298 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
3299 MCAsmParser &Parser = getParser();
3300 switch (getLexer().getKind()) {
3302 return MatchOperand_NoMatch;
3303 case AsmToken::LParen:
3304 case AsmToken::Plus:
3305 case AsmToken::Minus:
3306 case AsmToken::Integer:
3311 SMLoc S = Parser.getTok().getLoc();
3313 if (getParser().parseExpression(Expr))
3314 return MatchOperand_ParseFail;
3317 if (!Expr->evaluateAsAbsolute(Val)) {
3318 Error(S, "expected immediate value");
3319 return MatchOperand_ParseFail;
3322 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
3323 // and because the CPU always adds one to the immediate field, the allowed
3324 // range becomes 1..4. We'll only check the range here and will deal
3325 // with the addition/subtraction when actually decoding/encoding
3327 if (Val < 1 || Val > 4) {
3328 Error(S, "immediate not in range (1..4)");
3329 return MatchOperand_ParseFail;
3333 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
3334 return MatchOperand_Success;
3337 MipsAsmParser::OperandMatchResultTy
3338 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3339 MCAsmParser &Parser = getParser();
3340 SmallVector<unsigned, 10> Regs;
3342 unsigned PrevReg = Mips::NoRegister;
3343 bool RegRange = false;
3344 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3346 if (Parser.getTok().isNot(AsmToken::Dollar))
3347 return MatchOperand_ParseFail;
3349 SMLoc S = Parser.getTok().getLoc();
3350 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3351 SMLoc E = getLexer().getLoc();
3352 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3353 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3355 // Remove last register operand because registers from register range
3356 // should be inserted first.
3357 if (RegNo == Mips::RA) {
3358 Regs.push_back(RegNo);
3360 unsigned TmpReg = PrevReg + 1;
3361 while (TmpReg <= RegNo) {
3362 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3363 Error(E, "invalid register operand");
3364 return MatchOperand_ParseFail;
3368 Regs.push_back(TmpReg++);
3374 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
3375 (RegNo != Mips::RA)) {
3376 Error(E, "$16 or $31 expected");
3377 return MatchOperand_ParseFail;
3378 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
3379 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3380 Error(E, "invalid register operand");
3381 return MatchOperand_ParseFail;
3382 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
3383 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3384 Error(E, "consecutive register numbers expected");
3385 return MatchOperand_ParseFail;
3388 Regs.push_back(RegNo);
3391 if (Parser.getTok().is(AsmToken::Minus))
3394 if (!Parser.getTok().isNot(AsmToken::Minus) &&
3395 !Parser.getTok().isNot(AsmToken::Comma)) {
3396 Error(E, "',' or '-' expected");
3397 return MatchOperand_ParseFail;
3400 Lex(); // Consume comma or minus
3401 if (Parser.getTok().isNot(AsmToken::Dollar))
3407 SMLoc E = Parser.getTok().getLoc();
3408 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3409 parseMemOperand(Operands);
3410 return MatchOperand_Success;
3413 MipsAsmParser::OperandMatchResultTy
3414 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
3415 MCAsmParser &Parser = getParser();
3417 SMLoc S = Parser.getTok().getLoc();
3418 if (parseAnyRegister(Operands) != MatchOperand_Success)
3419 return MatchOperand_ParseFail;
3421 SMLoc E = Parser.getTok().getLoc();
3422 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
3423 unsigned Reg = Op.getGPR32Reg();
3424 Operands.pop_back();
3425 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
3426 return MatchOperand_Success;
3429 MipsAsmParser::OperandMatchResultTy
3430 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
3431 MCAsmParser &Parser = getParser();
3432 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3433 SmallVector<unsigned, 10> Regs;
3435 if (Parser.getTok().isNot(AsmToken::Dollar))
3436 return MatchOperand_ParseFail;
3438 SMLoc S = Parser.getTok().getLoc();
3440 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3441 return MatchOperand_ParseFail;
3443 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3444 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3445 Regs.push_back(RegNo);
3447 SMLoc E = Parser.getTok().getLoc();
3448 if (Parser.getTok().isNot(AsmToken::Comma)) {
3449 Error(E, "',' expected");
3450 return MatchOperand_ParseFail;
3456 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3457 return MatchOperand_ParseFail;
3459 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3460 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3461 Regs.push_back(RegNo);
3463 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3465 return MatchOperand_Success;
3468 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
3470 MCSymbolRefExpr::VariantKind VK =
3471 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
3472 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
3473 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
3474 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
3475 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
3476 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
3477 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
3478 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
3479 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
3480 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
3481 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
3482 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
3483 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
3484 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
3485 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
3486 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
3487 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
3488 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
3489 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
3490 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
3491 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
3492 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
3493 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
3494 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
3495 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
3496 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
3497 .Default(MCSymbolRefExpr::VK_None);
3499 assert(VK != MCSymbolRefExpr::VK_None);
3504 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
3506 /// ::= '(', register, ')'
3507 /// handle it before we iterate so we don't get tripped up by the lack of
3509 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
3510 MCAsmParser &Parser = getParser();
3511 if (getLexer().is(AsmToken::LParen)) {
3513 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
3515 if (parseOperand(Operands, Name)) {
3516 SMLoc Loc = getLexer().getLoc();
3517 Parser.eatToEndOfStatement();
3518 return Error(Loc, "unexpected token in argument list");
3520 if (Parser.getTok().isNot(AsmToken::RParen)) {
3521 SMLoc Loc = getLexer().getLoc();
3522 Parser.eatToEndOfStatement();
3523 return Error(Loc, "unexpected token, expected ')'");
3526 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
3532 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
3533 /// either one of these.
3534 /// ::= '[', register, ']'
3535 /// ::= '[', integer, ']'
3536 /// handle it before we iterate so we don't get tripped up by the lack of
3538 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
3539 OperandVector &Operands) {
3540 MCAsmParser &Parser = getParser();
3541 if (getLexer().is(AsmToken::LBrac)) {
3543 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
3545 if (parseOperand(Operands, Name)) {
3546 SMLoc Loc = getLexer().getLoc();
3547 Parser.eatToEndOfStatement();
3548 return Error(Loc, "unexpected token in argument list");
3550 if (Parser.getTok().isNot(AsmToken::RBrac)) {
3551 SMLoc Loc = getLexer().getLoc();
3552 Parser.eatToEndOfStatement();
3553 return Error(Loc, "unexpected token, expected ']'");
3556 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
3562 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
3563 SMLoc NameLoc, OperandVector &Operands) {
3564 MCAsmParser &Parser = getParser();
3565 DEBUG(dbgs() << "ParseInstruction\n");
3567 // We have reached first instruction, module directive are now forbidden.
3568 getTargetStreamer().forbidModuleDirective();
3570 // Check if we have valid mnemonic
3571 if (!mnemonicIsValid(Name, 0)) {
3572 Parser.eatToEndOfStatement();
3573 return Error(NameLoc, "unknown instruction");
3575 // First operand in MCInst is instruction mnemonic.
3576 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
3578 // Read the remaining operands.
3579 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3580 // Read the first operand.
3581 if (parseOperand(Operands, Name)) {
3582 SMLoc Loc = getLexer().getLoc();
3583 Parser.eatToEndOfStatement();
3584 return Error(Loc, "unexpected token in argument list");
3586 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
3588 // AFAIK, parenthesis suffixes are never on the first operand
3590 while (getLexer().is(AsmToken::Comma)) {
3591 Parser.Lex(); // Eat the comma.
3592 // Parse and remember the operand.
3593 if (parseOperand(Operands, Name)) {
3594 SMLoc Loc = getLexer().getLoc();
3595 Parser.eatToEndOfStatement();
3596 return Error(Loc, "unexpected token in argument list");
3598 // Parse bracket and parenthesis suffixes before we iterate
3599 if (getLexer().is(AsmToken::LBrac)) {
3600 if (parseBracketSuffix(Name, Operands))
3602 } else if (getLexer().is(AsmToken::LParen) &&
3603 parseParenSuffix(Name, Operands))
3607 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3608 SMLoc Loc = getLexer().getLoc();
3609 Parser.eatToEndOfStatement();
3610 return Error(Loc, "unexpected token in argument list");
3612 Parser.Lex(); // Consume the EndOfStatement.
3616 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
3617 MCAsmParser &Parser = getParser();
3618 SMLoc Loc = getLexer().getLoc();
3619 Parser.eatToEndOfStatement();
3620 return Error(Loc, ErrorMsg);
3623 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
3624 return Error(Loc, ErrorMsg);
3627 bool MipsAsmParser::parseSetNoAtDirective() {
3628 MCAsmParser &Parser = getParser();
3629 // Line should look like: ".set noat".
3631 // Set the $at register to $0.
3632 AssemblerOptions.back()->setATRegIndex(0);
3634 Parser.Lex(); // Eat "noat".
3636 // If this is not the end of the statement, report an error.
3637 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3638 reportParseError("unexpected token, expected end of statement");
3642 getTargetStreamer().emitDirectiveSetNoAt();
3643 Parser.Lex(); // Consume the EndOfStatement.
3647 bool MipsAsmParser::parseSetAtDirective() {
3648 // Line can be: ".set at", which sets $at to $1
3649 // or ".set at=$reg", which sets $at to $reg.
3650 MCAsmParser &Parser = getParser();
3651 Parser.Lex(); // Eat "at".
3653 if (getLexer().is(AsmToken::EndOfStatement)) {
3654 // No register was specified, so we set $at to $1.
3655 AssemblerOptions.back()->setATRegIndex(1);
3657 getTargetStreamer().emitDirectiveSetAt();
3658 Parser.Lex(); // Consume the EndOfStatement.
3662 if (getLexer().isNot(AsmToken::Equal)) {
3663 reportParseError("unexpected token, expected equals sign");
3666 Parser.Lex(); // Eat "=".
3668 if (getLexer().isNot(AsmToken::Dollar)) {
3669 if (getLexer().is(AsmToken::EndOfStatement)) {
3670 reportParseError("no register specified");
3673 reportParseError("unexpected token, expected dollar sign '$'");
3677 Parser.Lex(); // Eat "$".
3679 // Find out what "reg" is.
3681 const AsmToken &Reg = Parser.getTok();
3682 if (Reg.is(AsmToken::Identifier)) {
3683 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
3684 } else if (Reg.is(AsmToken::Integer)) {
3685 AtRegNo = Reg.getIntVal();
3687 reportParseError("unexpected token, expected identifier or integer");
3691 // Check if $reg is a valid register. If it is, set $at to $reg.
3692 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
3693 reportParseError("invalid register");
3696 Parser.Lex(); // Eat "reg".
3698 // If this is not the end of the statement, report an error.
3699 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3700 reportParseError("unexpected token, expected end of statement");
3704 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
3706 Parser.Lex(); // Consume the EndOfStatement.
3710 bool MipsAsmParser::parseSetReorderDirective() {
3711 MCAsmParser &Parser = getParser();
3713 // If this is not the end of the statement, report an error.
3714 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3715 reportParseError("unexpected token, expected end of statement");
3718 AssemblerOptions.back()->setReorder();
3719 getTargetStreamer().emitDirectiveSetReorder();
3720 Parser.Lex(); // Consume the EndOfStatement.
3724 bool MipsAsmParser::parseSetNoReorderDirective() {
3725 MCAsmParser &Parser = getParser();
3727 // If this is not the end of the statement, report an error.
3728 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3729 reportParseError("unexpected token, expected end of statement");
3732 AssemblerOptions.back()->setNoReorder();
3733 getTargetStreamer().emitDirectiveSetNoReorder();
3734 Parser.Lex(); // Consume the EndOfStatement.
3738 bool MipsAsmParser::parseSetMacroDirective() {
3739 MCAsmParser &Parser = getParser();
3741 // If this is not the end of the statement, report an error.
3742 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3743 reportParseError("unexpected token, expected end of statement");
3746 AssemblerOptions.back()->setMacro();
3747 getTargetStreamer().emitDirectiveSetMacro();
3748 Parser.Lex(); // Consume the EndOfStatement.
3752 bool MipsAsmParser::parseSetNoMacroDirective() {
3753 MCAsmParser &Parser = getParser();
3755 // If this is not the end of the statement, report an error.
3756 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3757 reportParseError("unexpected token, expected end of statement");
3760 if (AssemblerOptions.back()->isReorder()) {
3761 reportParseError("`noreorder' must be set before `nomacro'");
3764 AssemblerOptions.back()->setNoMacro();
3765 getTargetStreamer().emitDirectiveSetNoMacro();
3766 Parser.Lex(); // Consume the EndOfStatement.
3770 bool MipsAsmParser::parseSetMsaDirective() {
3771 MCAsmParser &Parser = getParser();
3774 // If this is not the end of the statement, report an error.
3775 if (getLexer().isNot(AsmToken::EndOfStatement))
3776 return reportParseError("unexpected token, expected end of statement");
3778 setFeatureBits(Mips::FeatureMSA, "msa");
3779 getTargetStreamer().emitDirectiveSetMsa();
3783 bool MipsAsmParser::parseSetNoMsaDirective() {
3784 MCAsmParser &Parser = getParser();
3787 // If this is not the end of the statement, report an error.
3788 if (getLexer().isNot(AsmToken::EndOfStatement))
3789 return reportParseError("unexpected token, expected end of statement");
3791 clearFeatureBits(Mips::FeatureMSA, "msa");
3792 getTargetStreamer().emitDirectiveSetNoMsa();
3796 bool MipsAsmParser::parseSetNoDspDirective() {
3797 MCAsmParser &Parser = getParser();
3798 Parser.Lex(); // Eat "nodsp".
3800 // If this is not the end of the statement, report an error.
3801 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3802 reportParseError("unexpected token, expected end of statement");
3806 clearFeatureBits(Mips::FeatureDSP, "dsp");
3807 getTargetStreamer().emitDirectiveSetNoDsp();
3811 bool MipsAsmParser::parseSetMips16Directive() {
3812 MCAsmParser &Parser = getParser();
3813 Parser.Lex(); // Eat "mips16".
3815 // If this is not the end of the statement, report an error.
3816 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3817 reportParseError("unexpected token, expected end of statement");
3821 setFeatureBits(Mips::FeatureMips16, "mips16");
3822 getTargetStreamer().emitDirectiveSetMips16();
3823 Parser.Lex(); // Consume the EndOfStatement.
3827 bool MipsAsmParser::parseSetNoMips16Directive() {
3828 MCAsmParser &Parser = getParser();
3829 Parser.Lex(); // Eat "nomips16".
3831 // If this is not the end of the statement, report an error.
3832 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3833 reportParseError("unexpected token, expected end of statement");
3837 clearFeatureBits(Mips::FeatureMips16, "mips16");
3838 getTargetStreamer().emitDirectiveSetNoMips16();
3839 Parser.Lex(); // Consume the EndOfStatement.
3843 bool MipsAsmParser::parseSetFpDirective() {
3844 MCAsmParser &Parser = getParser();
3845 MipsABIFlagsSection::FpABIKind FpAbiVal;
3846 // Line can be: .set fp=32
3849 Parser.Lex(); // Eat fp token
3850 AsmToken Tok = Parser.getTok();
3851 if (Tok.isNot(AsmToken::Equal)) {
3852 reportParseError("unexpected token, expected equals sign '='");
3855 Parser.Lex(); // Eat '=' token.
3856 Tok = Parser.getTok();
3858 if (!parseFpABIValue(FpAbiVal, ".set"))
3861 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3862 reportParseError("unexpected token, expected end of statement");
3865 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
3866 Parser.Lex(); // Consume the EndOfStatement.
3870 bool MipsAsmParser::parseSetPopDirective() {
3871 MCAsmParser &Parser = getParser();
3872 SMLoc Loc = getLexer().getLoc();
3875 if (getLexer().isNot(AsmToken::EndOfStatement))
3876 return reportParseError("unexpected token, expected end of statement");
3878 // Always keep an element on the options "stack" to prevent the user
3879 // from changing the initial options. This is how we remember them.
3880 if (AssemblerOptions.size() == 2)
3881 return reportParseError(Loc, ".set pop with no .set push");
3883 AssemblerOptions.pop_back();
3884 setAvailableFeatures(
3885 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
3886 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
3888 getTargetStreamer().emitDirectiveSetPop();
3892 bool MipsAsmParser::parseSetPushDirective() {
3893 MCAsmParser &Parser = getParser();
3895 if (getLexer().isNot(AsmToken::EndOfStatement))
3896 return reportParseError("unexpected token, expected end of statement");
3898 // Create a copy of the current assembler options environment and push it.
3899 AssemblerOptions.push_back(
3900 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
3902 getTargetStreamer().emitDirectiveSetPush();
3906 bool MipsAsmParser::parseSetSoftFloatDirective() {
3907 MCAsmParser &Parser = getParser();
3909 if (getLexer().isNot(AsmToken::EndOfStatement))
3910 return reportParseError("unexpected token, expected end of statement");
3912 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
3913 getTargetStreamer().emitDirectiveSetSoftFloat();
3917 bool MipsAsmParser::parseSetHardFloatDirective() {
3918 MCAsmParser &Parser = getParser();
3920 if (getLexer().isNot(AsmToken::EndOfStatement))
3921 return reportParseError("unexpected token, expected end of statement");
3923 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
3924 getTargetStreamer().emitDirectiveSetHardFloat();
3928 bool MipsAsmParser::parseSetAssignment() {
3930 const MCExpr *Value;
3931 MCAsmParser &Parser = getParser();
3933 if (Parser.parseIdentifier(Name))
3934 reportParseError("expected identifier after .set");
3936 if (getLexer().isNot(AsmToken::Comma))
3937 return reportParseError("unexpected token, expected comma");
3940 if (Parser.parseExpression(Value))
3941 return reportParseError("expected valid expression after comma");
3943 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
3944 Sym->setVariableValue(Value);
3949 bool MipsAsmParser::parseSetMips0Directive() {
3950 MCAsmParser &Parser = getParser();
3952 if (getLexer().isNot(AsmToken::EndOfStatement))
3953 return reportParseError("unexpected token, expected end of statement");
3955 // Reset assembler options to their initial values.
3956 setAvailableFeatures(
3957 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
3958 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
3959 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
3961 getTargetStreamer().emitDirectiveSetMips0();
3965 bool MipsAsmParser::parseSetArchDirective() {
3966 MCAsmParser &Parser = getParser();
3968 if (getLexer().isNot(AsmToken::Equal))
3969 return reportParseError("unexpected token, expected equals sign");
3973 if (Parser.parseIdentifier(Arch))
3974 return reportParseError("expected arch identifier");
3976 StringRef ArchFeatureName =
3977 StringSwitch<StringRef>(Arch)
3978 .Case("mips1", "mips1")
3979 .Case("mips2", "mips2")
3980 .Case("mips3", "mips3")
3981 .Case("mips4", "mips4")
3982 .Case("mips5", "mips5")
3983 .Case("mips32", "mips32")
3984 .Case("mips32r2", "mips32r2")
3985 .Case("mips32r3", "mips32r3")
3986 .Case("mips32r5", "mips32r5")
3987 .Case("mips32r6", "mips32r6")
3988 .Case("mips64", "mips64")
3989 .Case("mips64r2", "mips64r2")
3990 .Case("mips64r3", "mips64r3")
3991 .Case("mips64r5", "mips64r5")
3992 .Case("mips64r6", "mips64r6")
3993 .Case("cnmips", "cnmips")
3994 .Case("r4000", "mips3") // This is an implementation of Mips3.
3997 if (ArchFeatureName.empty())
3998 return reportParseError("unsupported architecture");
4000 selectArch(ArchFeatureName);
4001 getTargetStreamer().emitDirectiveSetArch(Arch);
4005 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
4006 MCAsmParser &Parser = getParser();
4008 if (getLexer().isNot(AsmToken::EndOfStatement))
4009 return reportParseError("unexpected token, expected end of statement");
4013 llvm_unreachable("Unimplemented feature");
4014 case Mips::FeatureDSP:
4015 setFeatureBits(Mips::FeatureDSP, "dsp");
4016 getTargetStreamer().emitDirectiveSetDsp();
4018 case Mips::FeatureMicroMips:
4019 getTargetStreamer().emitDirectiveSetMicroMips();
4021 case Mips::FeatureMips1:
4022 selectArch("mips1");
4023 getTargetStreamer().emitDirectiveSetMips1();
4025 case Mips::FeatureMips2:
4026 selectArch("mips2");
4027 getTargetStreamer().emitDirectiveSetMips2();
4029 case Mips::FeatureMips3:
4030 selectArch("mips3");
4031 getTargetStreamer().emitDirectiveSetMips3();
4033 case Mips::FeatureMips4:
4034 selectArch("mips4");
4035 getTargetStreamer().emitDirectiveSetMips4();
4037 case Mips::FeatureMips5:
4038 selectArch("mips5");
4039 getTargetStreamer().emitDirectiveSetMips5();
4041 case Mips::FeatureMips32:
4042 selectArch("mips32");
4043 getTargetStreamer().emitDirectiveSetMips32();
4045 case Mips::FeatureMips32r2:
4046 selectArch("mips32r2");
4047 getTargetStreamer().emitDirectiveSetMips32R2();
4049 case Mips::FeatureMips32r3:
4050 selectArch("mips32r3");
4051 getTargetStreamer().emitDirectiveSetMips32R3();
4053 case Mips::FeatureMips32r5:
4054 selectArch("mips32r5");
4055 getTargetStreamer().emitDirectiveSetMips32R5();
4057 case Mips::FeatureMips32r6:
4058 selectArch("mips32r6");
4059 getTargetStreamer().emitDirectiveSetMips32R6();
4061 case Mips::FeatureMips64:
4062 selectArch("mips64");
4063 getTargetStreamer().emitDirectiveSetMips64();
4065 case Mips::FeatureMips64r2:
4066 selectArch("mips64r2");
4067 getTargetStreamer().emitDirectiveSetMips64R2();
4069 case Mips::FeatureMips64r3:
4070 selectArch("mips64r3");
4071 getTargetStreamer().emitDirectiveSetMips64R3();
4073 case Mips::FeatureMips64r5:
4074 selectArch("mips64r5");
4075 getTargetStreamer().emitDirectiveSetMips64R5();
4077 case Mips::FeatureMips64r6:
4078 selectArch("mips64r6");
4079 getTargetStreamer().emitDirectiveSetMips64R6();
4085 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
4086 MCAsmParser &Parser = getParser();
4087 if (getLexer().isNot(AsmToken::Comma)) {
4088 SMLoc Loc = getLexer().getLoc();
4089 Parser.eatToEndOfStatement();
4090 return Error(Loc, ErrorStr);
4093 Parser.Lex(); // Eat the comma.
4097 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
4098 if (AssemblerOptions.back()->isReorder())
4099 Warning(Loc, ".cpload should be inside a noreorder section");
4101 if (inMips16Mode()) {
4102 reportParseError(".cpload is not supported in Mips16 mode");
4106 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
4107 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
4108 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4109 reportParseError("expected register containing function address");
4113 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
4114 if (!RegOpnd.isGPRAsmReg()) {
4115 reportParseError(RegOpnd.getStartLoc(), "invalid register");
4119 // If this is not the end of the statement, report an error.
4120 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4121 reportParseError("unexpected token, expected end of statement");
4125 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
4129 bool MipsAsmParser::parseDirectiveCPSetup() {
4130 MCAsmParser &Parser = getParser();
4133 bool SaveIsReg = true;
4135 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4136 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4137 if (ResTy == MatchOperand_NoMatch) {
4138 reportParseError("expected register containing function address");
4139 Parser.eatToEndOfStatement();
4143 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4144 if (!FuncRegOpnd.isGPRAsmReg()) {
4145 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
4146 Parser.eatToEndOfStatement();
4150 FuncReg = FuncRegOpnd.getGPR32Reg();
4153 if (!eatComma("unexpected token, expected comma"))
4156 ResTy = parseAnyRegister(TmpReg);
4157 if (ResTy == MatchOperand_NoMatch) {
4158 const AsmToken &Tok = Parser.getTok();
4159 if (Tok.is(AsmToken::Integer)) {
4160 Save = Tok.getIntVal();
4164 reportParseError("expected save register or stack offset");
4165 Parser.eatToEndOfStatement();
4169 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4170 if (!SaveOpnd.isGPRAsmReg()) {
4171 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
4172 Parser.eatToEndOfStatement();
4175 Save = SaveOpnd.getGPR32Reg();
4178 if (!eatComma("unexpected token, expected comma"))
4182 if (Parser.parseExpression(Expr)) {
4183 reportParseError("expected expression");
4187 if (Expr->getKind() != MCExpr::SymbolRef) {
4188 reportParseError("expected symbol");
4191 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
4193 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
4198 bool MipsAsmParser::parseDirectiveNaN() {
4199 MCAsmParser &Parser = getParser();
4200 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4201 const AsmToken &Tok = Parser.getTok();
4203 if (Tok.getString() == "2008") {
4205 getTargetStreamer().emitDirectiveNaN2008();
4207 } else if (Tok.getString() == "legacy") {
4209 getTargetStreamer().emitDirectiveNaNLegacy();
4213 // If we don't recognize the option passed to the .nan
4214 // directive (e.g. no option or unknown option), emit an error.
4215 reportParseError("invalid option in .nan directive");
4219 bool MipsAsmParser::parseDirectiveSet() {
4220 MCAsmParser &Parser = getParser();
4221 // Get the next token.
4222 const AsmToken &Tok = Parser.getTok();
4224 if (Tok.getString() == "noat") {
4225 return parseSetNoAtDirective();
4226 } else if (Tok.getString() == "at") {
4227 return parseSetAtDirective();
4228 } else if (Tok.getString() == "arch") {
4229 return parseSetArchDirective();
4230 } else if (Tok.getString() == "fp") {
4231 return parseSetFpDirective();
4232 } else if (Tok.getString() == "pop") {
4233 return parseSetPopDirective();
4234 } else if (Tok.getString() == "push") {
4235 return parseSetPushDirective();
4236 } else if (Tok.getString() == "reorder") {
4237 return parseSetReorderDirective();
4238 } else if (Tok.getString() == "noreorder") {
4239 return parseSetNoReorderDirective();
4240 } else if (Tok.getString() == "macro") {
4241 return parseSetMacroDirective();
4242 } else if (Tok.getString() == "nomacro") {
4243 return parseSetNoMacroDirective();
4244 } else if (Tok.getString() == "mips16") {
4245 return parseSetMips16Directive();
4246 } else if (Tok.getString() == "nomips16") {
4247 return parseSetNoMips16Directive();
4248 } else if (Tok.getString() == "nomicromips") {
4249 getTargetStreamer().emitDirectiveSetNoMicroMips();
4250 Parser.eatToEndOfStatement();
4252 } else if (Tok.getString() == "micromips") {
4253 return parseSetFeature(Mips::FeatureMicroMips);
4254 } else if (Tok.getString() == "mips0") {
4255 return parseSetMips0Directive();
4256 } else if (Tok.getString() == "mips1") {
4257 return parseSetFeature(Mips::FeatureMips1);
4258 } else if (Tok.getString() == "mips2") {
4259 return parseSetFeature(Mips::FeatureMips2);
4260 } else if (Tok.getString() == "mips3") {
4261 return parseSetFeature(Mips::FeatureMips3);
4262 } else if (Tok.getString() == "mips4") {
4263 return parseSetFeature(Mips::FeatureMips4);
4264 } else if (Tok.getString() == "mips5") {
4265 return parseSetFeature(Mips::FeatureMips5);
4266 } else if (Tok.getString() == "mips32") {
4267 return parseSetFeature(Mips::FeatureMips32);
4268 } else if (Tok.getString() == "mips32r2") {
4269 return parseSetFeature(Mips::FeatureMips32r2);
4270 } else if (Tok.getString() == "mips32r3") {
4271 return parseSetFeature(Mips::FeatureMips32r3);
4272 } else if (Tok.getString() == "mips32r5") {
4273 return parseSetFeature(Mips::FeatureMips32r5);
4274 } else if (Tok.getString() == "mips32r6") {
4275 return parseSetFeature(Mips::FeatureMips32r6);
4276 } else if (Tok.getString() == "mips64") {
4277 return parseSetFeature(Mips::FeatureMips64);
4278 } else if (Tok.getString() == "mips64r2") {
4279 return parseSetFeature(Mips::FeatureMips64r2);
4280 } else if (Tok.getString() == "mips64r3") {
4281 return parseSetFeature(Mips::FeatureMips64r3);
4282 } else if (Tok.getString() == "mips64r5") {
4283 return parseSetFeature(Mips::FeatureMips64r5);
4284 } else if (Tok.getString() == "mips64r6") {
4285 return parseSetFeature(Mips::FeatureMips64r6);
4286 } else if (Tok.getString() == "dsp") {
4287 return parseSetFeature(Mips::FeatureDSP);
4288 } else if (Tok.getString() == "nodsp") {
4289 return parseSetNoDspDirective();
4290 } else if (Tok.getString() == "msa") {
4291 return parseSetMsaDirective();
4292 } else if (Tok.getString() == "nomsa") {
4293 return parseSetNoMsaDirective();
4294 } else if (Tok.getString() == "softfloat") {
4295 return parseSetSoftFloatDirective();
4296 } else if (Tok.getString() == "hardfloat") {
4297 return parseSetHardFloatDirective();
4299 // It is just an identifier, look for an assignment.
4300 parseSetAssignment();
4307 /// parseDataDirective
4308 /// ::= .word [ expression (, expression)* ]
4309 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
4310 MCAsmParser &Parser = getParser();
4311 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4313 const MCExpr *Value;
4314 if (getParser().parseExpression(Value))
4317 getParser().getStreamer().EmitValue(Value, Size);
4319 if (getLexer().is(AsmToken::EndOfStatement))
4322 if (getLexer().isNot(AsmToken::Comma))
4323 return Error(L, "unexpected token, expected comma");
4332 /// parseDirectiveGpWord
4333 /// ::= .gpword local_sym
4334 bool MipsAsmParser::parseDirectiveGpWord() {
4335 MCAsmParser &Parser = getParser();
4336 const MCExpr *Value;
4337 // EmitGPRel32Value requires an expression, so we are using base class
4338 // method to evaluate the expression.
4339 if (getParser().parseExpression(Value))
4341 getParser().getStreamer().EmitGPRel32Value(Value);
4343 if (getLexer().isNot(AsmToken::EndOfStatement))
4344 return Error(getLexer().getLoc(),
4345 "unexpected token, expected end of statement");
4346 Parser.Lex(); // Eat EndOfStatement token.
4350 /// parseDirectiveGpDWord
4351 /// ::= .gpdword local_sym
4352 bool MipsAsmParser::parseDirectiveGpDWord() {
4353 MCAsmParser &Parser = getParser();
4354 const MCExpr *Value;
4355 // EmitGPRel64Value requires an expression, so we are using base class
4356 // method to evaluate the expression.
4357 if (getParser().parseExpression(Value))
4359 getParser().getStreamer().EmitGPRel64Value(Value);
4361 if (getLexer().isNot(AsmToken::EndOfStatement))
4362 return Error(getLexer().getLoc(),
4363 "unexpected token, expected end of statement");
4364 Parser.Lex(); // Eat EndOfStatement token.
4368 bool MipsAsmParser::parseDirectiveOption() {
4369 MCAsmParser &Parser = getParser();
4370 // Get the option token.
4371 AsmToken Tok = Parser.getTok();
4372 // At the moment only identifiers are supported.
4373 if (Tok.isNot(AsmToken::Identifier)) {
4374 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
4375 Parser.eatToEndOfStatement();
4379 StringRef Option = Tok.getIdentifier();
4381 if (Option == "pic0") {
4382 getTargetStreamer().emitDirectiveOptionPic0();
4384 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4385 Error(Parser.getTok().getLoc(),
4386 "unexpected token, expected end of statement");
4387 Parser.eatToEndOfStatement();
4392 if (Option == "pic2") {
4393 getTargetStreamer().emitDirectiveOptionPic2();
4395 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4396 Error(Parser.getTok().getLoc(),
4397 "unexpected token, expected end of statement");
4398 Parser.eatToEndOfStatement();
4404 Warning(Parser.getTok().getLoc(),
4405 "unknown option, expected 'pic0' or 'pic2'");
4406 Parser.eatToEndOfStatement();
4410 /// parseInsnDirective
4412 bool MipsAsmParser::parseInsnDirective() {
4413 // If this is not the end of the statement, report an error.
4414 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4415 reportParseError("unexpected token, expected end of statement");
4419 // The actual label marking happens in
4420 // MipsELFStreamer::createPendingLabelRelocs().
4421 getTargetStreamer().emitDirectiveInsn();
4423 getParser().Lex(); // Eat EndOfStatement token.
4427 /// parseDirectiveModule
4428 /// ::= .module oddspreg
4429 /// ::= .module nooddspreg
4430 /// ::= .module fp=value
4431 bool MipsAsmParser::parseDirectiveModule() {
4432 MCAsmParser &Parser = getParser();
4433 MCAsmLexer &Lexer = getLexer();
4434 SMLoc L = Lexer.getLoc();
4436 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
4437 // TODO : get a better message.
4438 reportParseError(".module directive must appear before any code");
4443 if (Parser.parseIdentifier(Option)) {
4444 reportParseError("expected .module option identifier");
4448 if (Option == "oddspreg") {
4449 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
4450 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4452 // If this is not the end of the statement, report an error.
4453 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4454 reportParseError("unexpected token, expected end of statement");
4458 return false; // parseDirectiveModule has finished successfully.
4459 } else if (Option == "nooddspreg") {
4461 Error(L, "'.module nooddspreg' requires the O32 ABI");
4465 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
4466 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4468 // If this is not the end of the statement, report an error.
4469 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4470 reportParseError("unexpected token, expected end of statement");
4474 return false; // parseDirectiveModule has finished successfully.
4475 } else if (Option == "fp") {
4476 return parseDirectiveModuleFP();
4478 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
4482 /// parseDirectiveModuleFP
4486 bool MipsAsmParser::parseDirectiveModuleFP() {
4487 MCAsmParser &Parser = getParser();
4488 MCAsmLexer &Lexer = getLexer();
4490 if (Lexer.isNot(AsmToken::Equal)) {
4491 reportParseError("unexpected token, expected equals sign '='");
4494 Parser.Lex(); // Eat '=' token.
4496 MipsABIFlagsSection::FpABIKind FpABI;
4497 if (!parseFpABIValue(FpABI, ".module"))
4500 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4501 reportParseError("unexpected token, expected end of statement");
4505 // Emit appropriate flags.
4506 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
4507 Parser.Lex(); // Consume the EndOfStatement.
4511 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
4512 StringRef Directive) {
4513 MCAsmParser &Parser = getParser();
4514 MCAsmLexer &Lexer = getLexer();
4516 if (Lexer.is(AsmToken::Identifier)) {
4517 StringRef Value = Parser.getTok().getString();
4520 if (Value != "xx") {
4521 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4526 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
4530 FpABI = MipsABIFlagsSection::FpABIKind::XX;
4534 if (Lexer.is(AsmToken::Integer)) {
4535 unsigned Value = Parser.getTok().getIntVal();
4538 if (Value != 32 && Value != 64) {
4539 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4545 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
4549 FpABI = MipsABIFlagsSection::FpABIKind::S32;
4551 FpABI = MipsABIFlagsSection::FpABIKind::S64;
4559 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
4560 MCAsmParser &Parser = getParser();
4561 StringRef IDVal = DirectiveID.getString();
4563 if (IDVal == ".cpload")
4564 return parseDirectiveCpLoad(DirectiveID.getLoc());
4565 if (IDVal == ".dword") {
4566 parseDataDirective(8, DirectiveID.getLoc());
4569 if (IDVal == ".ent") {
4570 StringRef SymbolName;
4572 if (Parser.parseIdentifier(SymbolName)) {
4573 reportParseError("expected identifier after .ent");
4577 // There's an undocumented extension that allows an integer to
4578 // follow the name of the procedure which AFAICS is ignored by GAS.
4579 // Example: .ent foo,2
4580 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4581 if (getLexer().isNot(AsmToken::Comma)) {
4582 // Even though we accept this undocumented extension for compatibility
4583 // reasons, the additional integer argument does not actually change
4584 // the behaviour of the '.ent' directive, so we would like to discourage
4585 // its use. We do this by not referring to the extended version in
4586 // error messages which are not directly related to its use.
4587 reportParseError("unexpected token, expected end of statement");
4590 Parser.Lex(); // Eat the comma.
4591 const MCExpr *DummyNumber;
4592 int64_t DummyNumberVal;
4593 // If the user was explicitly trying to use the extended version,
4594 // we still give helpful extension-related error messages.
4595 if (Parser.parseExpression(DummyNumber)) {
4596 reportParseError("expected number after comma");
4599 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
4600 reportParseError("expected an absolute expression after comma");
4605 // If this is not the end of the statement, report an error.
4606 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4607 reportParseError("unexpected token, expected end of statement");
4611 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
4613 getTargetStreamer().emitDirectiveEnt(*Sym);
4618 if (IDVal == ".end") {
4619 StringRef SymbolName;
4621 if (Parser.parseIdentifier(SymbolName)) {
4622 reportParseError("expected identifier after .end");
4626 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4627 reportParseError("unexpected token, expected end of statement");
4631 if (CurrentFn == nullptr) {
4632 reportParseError(".end used without .ent");
4636 if ((SymbolName != CurrentFn->getName())) {
4637 reportParseError(".end symbol does not match .ent symbol");
4641 getTargetStreamer().emitDirectiveEnd(SymbolName);
4642 CurrentFn = nullptr;
4646 if (IDVal == ".frame") {
4647 // .frame $stack_reg, frame_size_in_bytes, $return_reg
4648 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4649 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4650 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4651 reportParseError("expected stack register");
4655 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4656 if (!StackRegOpnd.isGPRAsmReg()) {
4657 reportParseError(StackRegOpnd.getStartLoc(),
4658 "expected general purpose register");
4661 unsigned StackReg = StackRegOpnd.getGPR32Reg();
4663 if (Parser.getTok().is(AsmToken::Comma))
4666 reportParseError("unexpected token, expected comma");
4670 // Parse the frame size.
4671 const MCExpr *FrameSize;
4672 int64_t FrameSizeVal;
4674 if (Parser.parseExpression(FrameSize)) {
4675 reportParseError("expected frame size value");
4679 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
4680 reportParseError("frame size not an absolute expression");
4684 if (Parser.getTok().is(AsmToken::Comma))
4687 reportParseError("unexpected token, expected comma");
4691 // Parse the return register.
4693 ResTy = parseAnyRegister(TmpReg);
4694 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4695 reportParseError("expected return register");
4699 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4700 if (!ReturnRegOpnd.isGPRAsmReg()) {
4701 reportParseError(ReturnRegOpnd.getStartLoc(),
4702 "expected general purpose register");
4706 // If this is not the end of the statement, report an error.
4707 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4708 reportParseError("unexpected token, expected end of statement");
4712 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
4713 ReturnRegOpnd.getGPR32Reg());
4717 if (IDVal == ".set") {
4718 return parseDirectiveSet();
4721 if (IDVal == ".mask" || IDVal == ".fmask") {
4722 // .mask bitmask, frame_offset
4723 // bitmask: One bit for each register used.
4724 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
4725 // first register is expected to be saved.
4727 // .mask 0x80000000, -4
4728 // .fmask 0x80000000, -4
4731 // Parse the bitmask
4732 const MCExpr *BitMask;
4735 if (Parser.parseExpression(BitMask)) {
4736 reportParseError("expected bitmask value");
4740 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
4741 reportParseError("bitmask not an absolute expression");
4745 if (Parser.getTok().is(AsmToken::Comma))
4748 reportParseError("unexpected token, expected comma");
4752 // Parse the frame_offset
4753 const MCExpr *FrameOffset;
4754 int64_t FrameOffsetVal;
4756 if (Parser.parseExpression(FrameOffset)) {
4757 reportParseError("expected frame offset value");
4761 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
4762 reportParseError("frame offset not an absolute expression");
4766 // If this is not the end of the statement, report an error.
4767 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4768 reportParseError("unexpected token, expected end of statement");
4772 if (IDVal == ".mask")
4773 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
4775 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
4779 if (IDVal == ".nan")
4780 return parseDirectiveNaN();
4782 if (IDVal == ".gpword") {
4783 parseDirectiveGpWord();
4787 if (IDVal == ".gpdword") {
4788 parseDirectiveGpDWord();
4792 if (IDVal == ".word") {
4793 parseDataDirective(4, DirectiveID.getLoc());
4797 if (IDVal == ".option")
4798 return parseDirectiveOption();
4800 if (IDVal == ".abicalls") {
4801 getTargetStreamer().emitDirectiveAbiCalls();
4802 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4803 Error(Parser.getTok().getLoc(),
4804 "unexpected token, expected end of statement");
4806 Parser.eatToEndOfStatement();
4811 if (IDVal == ".cpsetup")
4812 return parseDirectiveCPSetup();
4814 if (IDVal == ".module")
4815 return parseDirectiveModule();
4817 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
4818 return parseInternalDirectiveReallowModule();
4820 if (IDVal == ".insn")
4821 return parseInsnDirective();
4826 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
4827 // If this is not the end of the statement, report an error.
4828 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4829 reportParseError("unexpected token, expected end of statement");
4833 getTargetStreamer().reallowModuleDirective();
4835 getParser().Lex(); // Eat EndOfStatement token.
4839 extern "C" void LLVMInitializeMipsAsmParser() {
4840 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
4841 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
4842 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
4843 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
4846 #define GET_REGISTER_MATCHER
4847 #define GET_MATCHER_IMPLEMENTATION
4848 #include "MipsGenAsmMatcher.inc"