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 loadSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
190 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 &ImmOp = Inst.getOperand(2);
1933 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1934 "expected immediate operand kind");
1935 if (!ImmOp.isImm()) {
1936 if (loadSymbolAddress(ImmOp.getExpr(), DstRegOp.getReg(), Is32BitImm, IDLoc,
1942 const MCOperand &SrcRegOp = Inst.getOperand(1);
1943 assert(SrcRegOp.isReg() && "expected register operand kind");
1945 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), SrcRegOp.getReg(),
1946 Is32BitImm, IDLoc, Instructions))
1953 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1954 SmallVectorImpl<MCInst> &Instructions) {
1955 const MCOperand &DstRegOp = Inst.getOperand(0);
1956 assert(DstRegOp.isReg() && "expected register operand kind");
1958 const MCOperand &ImmOp = Inst.getOperand(1);
1959 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1960 "expected immediate operand kind");
1961 if (!ImmOp.isImm()) {
1962 if (loadSymbolAddress(ImmOp.getExpr(), DstRegOp.getReg(), Is32BitImm, IDLoc,
1969 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
1970 Is32BitImm, IDLoc, Instructions))
1976 bool MipsAsmParser::loadSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
1977 bool Is32BitSym, SMLoc IDLoc,
1978 SmallVectorImpl<MCInst> &Instructions) {
1979 warnIfNoMacro(IDLoc);
1981 if (Is32BitSym && isABI_N64())
1982 Warning(IDLoc, "instruction loads the 32-bit address of a 64-bit symbol");
1985 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymExpr);
1986 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::create(
1987 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1988 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::create(
1989 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1992 // If it's a 64-bit architecture, expand to:
1993 // la d,sym => lui d,highest(sym)
1994 // ori d,d,higher(sym)
1996 // ori d,d,hi16(sym)
1998 // ori d,d,lo16(sym)
1999 const MCSymbolRefExpr *HighestExpr = MCSymbolRefExpr::create(
2000 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
2001 const MCSymbolRefExpr *HigherExpr = MCSymbolRefExpr::create(
2002 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
2004 tmpInst.setOpcode(Mips::LUi);
2005 tmpInst.addOperand(MCOperand::createReg(DstReg));
2006 tmpInst.addOperand(MCOperand::createExpr(HighestExpr));
2007 Instructions.push_back(tmpInst);
2009 createLShiftOri<0>(MCOperand::createExpr(HigherExpr), DstReg, SMLoc(),
2011 createLShiftOri<16>(MCOperand::createExpr(HiExpr), DstReg, SMLoc(),
2013 createLShiftOri<16>(MCOperand::createExpr(LoExpr), DstReg, SMLoc(),
2016 // Otherwise, expand to:
2017 // la d,sym => lui d,hi16(sym)
2018 // ori d,d,lo16(sym)
2019 tmpInst.setOpcode(Mips::LUi);
2020 tmpInst.addOperand(MCOperand::createReg(DstReg));
2021 tmpInst.addOperand(MCOperand::createExpr(HiExpr));
2022 Instructions.push_back(tmpInst);
2024 createLShiftOri<0>(MCOperand::createExpr(LoExpr), DstReg, SMLoc(),
2030 bool MipsAsmParser::expandUncondBranchMMPseudo(
2031 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2032 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2033 "unexpected number of operands");
2035 MCOperand Offset = Inst.getOperand(0);
2036 if (Offset.isExpr()) {
2038 Inst.setOpcode(Mips::BEQ_MM);
2039 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2040 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2041 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2043 assert(Offset.isImm() && "expected immediate operand kind");
2044 if (isIntN(11, Offset.getImm())) {
2045 // If offset fits into 11 bits then this instruction becomes microMIPS
2046 // 16-bit unconditional branch instruction.
2047 Inst.setOpcode(Mips::B16_MM);
2049 if (!isIntN(17, Offset.getImm()))
2050 Error(IDLoc, "branch target out of range");
2051 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2052 Error(IDLoc, "branch to misaligned address");
2054 Inst.setOpcode(Mips::BEQ_MM);
2055 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2056 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2057 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2060 Instructions.push_back(Inst);
2062 // If .set reorder is active, emit a NOP after the branch instruction.
2063 if (AssemblerOptions.back()->isReorder())
2064 createNop(true, IDLoc, Instructions);
2069 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc,
2070 SmallVectorImpl<MCInst> &Instructions) {
2071 const MCOperand &DstRegOp = Inst.getOperand(0);
2072 assert(DstRegOp.isReg() && "expected register operand kind");
2074 const MCOperand &ImmOp = Inst.getOperand(1);
2075 assert(ImmOp.isImm() && "expected immediate operand kind");
2077 const MCOperand &MemOffsetOp = Inst.getOperand(2);
2078 assert(MemOffsetOp.isImm() && "expected immediate operand kind");
2080 unsigned OpCode = 0;
2081 switch(Inst.getOpcode()) {
2089 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2093 int64_t ImmValue = ImmOp.getImm();
2094 if (ImmValue == 0) {
2096 BranchInst.setOpcode(OpCode);
2097 BranchInst.addOperand(DstRegOp);
2098 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2099 BranchInst.addOperand(MemOffsetOp);
2100 Instructions.push_back(BranchInst);
2102 warnIfNoMacro(IDLoc);
2104 unsigned ATReg = getATReg(IDLoc);
2108 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), IDLoc,
2113 BranchInst.setOpcode(OpCode);
2114 BranchInst.addOperand(DstRegOp);
2115 BranchInst.addOperand(MCOperand::createReg(ATReg));
2116 BranchInst.addOperand(MemOffsetOp);
2117 Instructions.push_back(BranchInst);
2122 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2123 SmallVectorImpl<MCInst> &Instructions,
2124 bool isLoad, bool isImmOpnd) {
2126 unsigned ImmOffset, HiOffset, LoOffset;
2127 const MCExpr *ExprOffset;
2129 // 1st operand is either the source or destination register.
2130 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2131 unsigned RegOpNum = Inst.getOperand(0).getReg();
2132 // 2nd operand is the base register.
2133 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2134 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2135 // 3rd operand is either an immediate or expression.
2137 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2138 ImmOffset = Inst.getOperand(2).getImm();
2139 LoOffset = ImmOffset & 0x0000ffff;
2140 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2141 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2142 if (LoOffset & 0x8000)
2145 ExprOffset = Inst.getOperand(2).getExpr();
2146 // All instructions will have the same location.
2147 TempInst.setLoc(IDLoc);
2148 // These are some of the types of expansions we perform here:
2149 // 1) lw $8, sym => lui $8, %hi(sym)
2150 // lw $8, %lo(sym)($8)
2151 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2153 // lw $8, %lo(offset)($9)
2154 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2156 // lw $8, %lo(offset)($at)
2157 // 4) sw $8, sym => lui $at, %hi(sym)
2158 // sw $8, %lo(sym)($at)
2159 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2161 // sw $8, %lo(offset)($at)
2162 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2163 // ldc1 $f0, %lo(sym)($at)
2165 // For load instructions we can use the destination register as a temporary
2166 // if base and dst are different (examples 1 and 2) and if the base register
2167 // is general purpose otherwise we must use $at (example 6) and error if it's
2168 // not available. For stores we must use $at (examples 4 and 5) because we
2169 // must not clobber the source register setting up the offset.
2170 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2171 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2172 unsigned RegClassIDOp0 =
2173 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2174 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2175 (RegClassIDOp0 == Mips::GPR64RegClassID);
2176 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2177 TmpRegNum = RegOpNum;
2179 // At this point we need AT to perform the expansions and we exit if it is
2181 TmpRegNum = getATReg(IDLoc);
2186 TempInst.setOpcode(Mips::LUi);
2187 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2189 TempInst.addOperand(MCOperand::createImm(HiOffset));
2191 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2192 TempInst.addOperand(MCOperand::createExpr(HiExpr));
2194 // Add the instruction to the list.
2195 Instructions.push_back(TempInst);
2196 // Prepare TempInst for next instruction.
2198 // Add temp register to base.
2199 if (BaseRegNum != Mips::ZERO) {
2200 TempInst.setOpcode(Mips::ADDu);
2201 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2202 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2203 TempInst.addOperand(MCOperand::createReg(BaseRegNum));
2204 Instructions.push_back(TempInst);
2207 // And finally, create original instruction with low part
2208 // of offset and new base.
2209 TempInst.setOpcode(Inst.getOpcode());
2210 TempInst.addOperand(MCOperand::createReg(RegOpNum));
2211 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2213 TempInst.addOperand(MCOperand::createImm(LoOffset));
2215 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2216 TempInst.addOperand(MCOperand::createExpr(LoExpr));
2218 Instructions.push_back(TempInst);
2223 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2224 SmallVectorImpl<MCInst> &Instructions) {
2225 unsigned OpNum = Inst.getNumOperands();
2226 unsigned Opcode = Inst.getOpcode();
2227 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2229 assert (Inst.getOperand(OpNum - 1).isImm() &&
2230 Inst.getOperand(OpNum - 2).isReg() &&
2231 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2233 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2234 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2235 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2236 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2237 // It can be implemented as SWM16 or LWM16 instruction.
2238 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2240 Inst.setOpcode(NewOpcode);
2241 Instructions.push_back(Inst);
2245 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
2246 SmallVectorImpl<MCInst> &Instructions) {
2247 unsigned PseudoOpcode = Inst.getOpcode();
2248 unsigned SrcReg = Inst.getOperand(0).getReg();
2249 unsigned TrgReg = Inst.getOperand(1).getReg();
2250 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
2252 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2253 bool ReverseOrderSLT, IsUnsigned, AcceptsEquality;
2255 switch (PseudoOpcode) {
2258 AcceptsEquality = false;
2259 ReverseOrderSLT = false;
2260 IsUnsigned = (PseudoOpcode == Mips::BLTU);
2261 ZeroSrcOpcode = Mips::BGTZ;
2262 ZeroTrgOpcode = Mips::BLTZ;
2266 AcceptsEquality = true;
2267 ReverseOrderSLT = true;
2268 IsUnsigned = (PseudoOpcode == Mips::BLEU);
2269 ZeroSrcOpcode = Mips::BGEZ;
2270 ZeroTrgOpcode = Mips::BLEZ;
2274 AcceptsEquality = true;
2275 ReverseOrderSLT = false;
2276 IsUnsigned = (PseudoOpcode == Mips::BGEU);
2277 ZeroSrcOpcode = Mips::BLEZ;
2278 ZeroTrgOpcode = Mips::BGEZ;
2282 AcceptsEquality = false;
2283 ReverseOrderSLT = true;
2284 IsUnsigned = (PseudoOpcode == Mips::BGTU);
2285 ZeroSrcOpcode = Mips::BLTZ;
2286 ZeroTrgOpcode = Mips::BGTZ;
2289 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2293 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
2294 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
2295 if (IsSrcRegZero && IsTrgRegZero) {
2296 // FIXME: All of these Opcode-specific if's are needed for compatibility
2297 // with GAS' behaviour. However, they may not generate the most efficient
2298 // code in some circumstances.
2299 if (PseudoOpcode == Mips::BLT) {
2300 BranchInst.setOpcode(Mips::BLTZ);
2301 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2302 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2303 Instructions.push_back(BranchInst);
2306 if (PseudoOpcode == Mips::BLE) {
2307 BranchInst.setOpcode(Mips::BLEZ);
2308 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2309 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2310 Instructions.push_back(BranchInst);
2311 Warning(IDLoc, "branch is always taken");
2314 if (PseudoOpcode == Mips::BGE) {
2315 BranchInst.setOpcode(Mips::BGEZ);
2316 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2317 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2318 Instructions.push_back(BranchInst);
2319 Warning(IDLoc, "branch is always taken");
2322 if (PseudoOpcode == Mips::BGT) {
2323 BranchInst.setOpcode(Mips::BGTZ);
2324 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2325 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2326 Instructions.push_back(BranchInst);
2329 if (PseudoOpcode == Mips::BGTU) {
2330 BranchInst.setOpcode(Mips::BNE);
2331 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2332 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2333 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2334 Instructions.push_back(BranchInst);
2337 if (AcceptsEquality) {
2338 // If both registers are $0 and the pseudo-branch accepts equality, it
2339 // will always be taken, so we emit an unconditional branch.
2340 BranchInst.setOpcode(Mips::BEQ);
2341 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2342 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2343 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2344 Instructions.push_back(BranchInst);
2345 Warning(IDLoc, "branch is always taken");
2348 // If both registers are $0 and the pseudo-branch does not accept
2349 // equality, it will never be taken, so we don't have to emit anything.
2352 if (IsSrcRegZero || IsTrgRegZero) {
2353 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
2354 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
2355 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
2356 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
2357 // the pseudo-branch will never be taken, so we don't emit anything.
2358 // This only applies to unsigned pseudo-branches.
2361 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
2362 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
2363 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
2364 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
2365 // the pseudo-branch will always be taken, so we emit an unconditional
2367 // This only applies to unsigned pseudo-branches.
2368 BranchInst.setOpcode(Mips::BEQ);
2369 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2370 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2371 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2372 Instructions.push_back(BranchInst);
2373 Warning(IDLoc, "branch is always taken");
2377 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
2378 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
2379 // the pseudo-branch will be taken only when the non-zero register is
2380 // different from 0, so we emit a BNEZ.
2382 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
2383 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
2384 // the pseudo-branch will be taken only when the non-zero register is
2385 // equal to 0, so we emit a BEQZ.
2387 // Because only BLEU and BGEU branch on equality, we can use the
2388 // AcceptsEquality variable to decide when to emit the BEQZ.
2389 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2390 BranchInst.addOperand(
2391 MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2392 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2393 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2394 Instructions.push_back(BranchInst);
2397 // If we have a signed pseudo-branch and one of the registers is $0,
2398 // we can use an appropriate compare-to-zero branch. We select which one
2399 // to use in the switch statement above.
2400 BranchInst.setOpcode(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode);
2401 BranchInst.addOperand(MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2402 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2403 Instructions.push_back(BranchInst);
2407 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
2408 // expansions. If it is not available, we return.
2409 unsigned ATRegNum = getATReg(IDLoc);
2413 warnIfNoMacro(IDLoc);
2415 // SLT fits well with 2 of our 4 pseudo-branches:
2416 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
2417 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
2418 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
2419 // This is accomplished by using a BNEZ with the result of the SLT.
2421 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
2422 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
2423 // Because only BGE and BLE branch on equality, we can use the
2424 // AcceptsEquality variable to decide when to emit the BEQZ.
2425 // Note that the order of the SLT arguments doesn't change between
2428 // The same applies to the unsigned variants, except that SLTu is used
2431 SetInst.setOpcode(IsUnsigned ? Mips::SLTu : Mips::SLT);
2432 SetInst.addOperand(MCOperand::createReg(ATRegNum));
2433 SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? TrgReg : SrcReg));
2434 SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? SrcReg : TrgReg));
2435 Instructions.push_back(SetInst);
2437 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2438 BranchInst.addOperand(MCOperand::createReg(ATRegNum));
2439 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2440 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2441 Instructions.push_back(BranchInst);
2445 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
2446 SmallVectorImpl<MCInst> &Instructions) {
2448 if (hasShortDelaySlot) {
2449 NopInst.setOpcode(Mips::MOVE16_MM);
2450 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2451 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2453 NopInst.setOpcode(Mips::SLL);
2454 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2455 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2456 NopInst.addOperand(MCOperand::createImm(0));
2458 Instructions.push_back(NopInst);
2461 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
2463 SmallVectorImpl<MCInst> &Instructions) {
2465 AdduInst.setOpcode(Mips::ADDu);
2466 AdduInst.addOperand(MCOperand::createReg(DstReg));
2467 AdduInst.addOperand(MCOperand::createReg(SrcReg));
2468 AdduInst.addOperand(MCOperand::createReg(TrgReg));
2469 Instructions.push_back(AdduInst);
2472 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
2473 // As described by the Mips32r2 spec, the registers Rd and Rs for
2474 // jalr.hb must be different.
2475 unsigned Opcode = Inst.getOpcode();
2477 if (Opcode == Mips::JALR_HB &&
2478 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
2479 return Match_RequiresDifferentSrcAndDst;
2481 return Match_Success;
2484 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2485 OperandVector &Operands,
2487 uint64_t &ErrorInfo,
2488 bool MatchingInlineAsm) {
2491 SmallVector<MCInst, 8> Instructions;
2492 unsigned MatchResult =
2493 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
2495 switch (MatchResult) {
2496 case Match_Success: {
2497 if (processInstruction(Inst, IDLoc, Instructions))
2499 for (unsigned i = 0; i < Instructions.size(); i++)
2500 Out.EmitInstruction(Instructions[i], STI);
2503 case Match_MissingFeature:
2504 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2506 case Match_InvalidOperand: {
2507 SMLoc ErrorLoc = IDLoc;
2508 if (ErrorInfo != ~0ULL) {
2509 if (ErrorInfo >= Operands.size())
2510 return Error(IDLoc, "too few operands for instruction");
2512 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
2513 if (ErrorLoc == SMLoc())
2517 return Error(ErrorLoc, "invalid operand for instruction");
2519 case Match_MnemonicFail:
2520 return Error(IDLoc, "invalid instruction");
2521 case Match_RequiresDifferentSrcAndDst:
2522 return Error(IDLoc, "source and destination must be different");
2525 llvm_unreachable("Implement any new match types added!");
2528 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
2529 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
2530 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
2531 ") without \".set noat\"");
2534 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
2535 if (!AssemblerOptions.back()->isMacro())
2536 Warning(Loc, "macro instruction expanded into multiple instructions");
2540 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
2541 SMRange Range, bool ShowColors) {
2542 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
2543 Range, SMFixIt(Range, FixMsg),
2547 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
2550 CC = StringSwitch<unsigned>(Name)
2586 if (!(isABI_N32() || isABI_N64()))
2589 if (12 <= CC && CC <= 15) {
2590 // Name is one of t4-t7
2591 AsmToken RegTok = getLexer().peekTok();
2592 SMRange RegRange = RegTok.getLocRange();
2594 StringRef FixedName = StringSwitch<StringRef>(Name)
2600 assert(FixedName != "" && "Register name is not one of t4-t7.");
2602 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
2603 "Did you mean $" + FixedName + "?", RegRange);
2606 // Although SGI documentation just cuts out t0-t3 for n32/n64,
2607 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
2608 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
2609 if (8 <= CC && CC <= 11)
2613 CC = StringSwitch<unsigned>(Name)
2625 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
2628 CC = StringSwitch<unsigned>(Name)
2629 .Case("hwr_cpunum", 0)
2630 .Case("hwr_synci_step", 1)
2632 .Case("hwr_ccres", 3)
2633 .Case("hwr_ulr", 29)
2639 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2641 if (Name[0] == 'f') {
2642 StringRef NumString = Name.substr(1);
2644 if (NumString.getAsInteger(10, IntVal))
2645 return -1; // This is not an integer.
2646 if (IntVal > 31) // Maximum index for fpu register.
2653 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2655 if (Name.startswith("fcc")) {
2656 StringRef NumString = Name.substr(3);
2658 if (NumString.getAsInteger(10, IntVal))
2659 return -1; // This is not an integer.
2660 if (IntVal > 7) // There are only 8 fcc registers.
2667 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2669 if (Name.startswith("ac")) {
2670 StringRef NumString = Name.substr(2);
2672 if (NumString.getAsInteger(10, IntVal))
2673 return -1; // This is not an integer.
2674 if (IntVal > 3) // There are only 3 acc registers.
2681 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2684 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
2693 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
2696 CC = StringSwitch<unsigned>(Name)
2699 .Case("msaaccess", 2)
2701 .Case("msamodify", 4)
2702 .Case("msarequest", 5)
2704 .Case("msaunmap", 7)
2710 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
2711 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
2713 reportParseError(Loc,
2714 "pseudo-instruction requires $at, which is not available");
2717 unsigned AT = getReg(
2718 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
2722 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2723 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2726 unsigned MipsAsmParser::getGPR(int RegNo) {
2727 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2731 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2733 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2736 return getReg(RegClass, RegNum);
2739 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2740 MCAsmParser &Parser = getParser();
2741 DEBUG(dbgs() << "parseOperand\n");
2743 // Check if the current operand has a custom associated parser, if so, try to
2744 // custom parse the operand, or fallback to the general approach.
2745 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2746 if (ResTy == MatchOperand_Success)
2748 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2749 // there was a match, but an error occurred, in which case, just return that
2750 // the operand parsing failed.
2751 if (ResTy == MatchOperand_ParseFail)
2754 DEBUG(dbgs() << ".. Generic Parser\n");
2756 switch (getLexer().getKind()) {
2758 Error(Parser.getTok().getLoc(), "unexpected token in operand");
2760 case AsmToken::Dollar: {
2761 // Parse the register.
2762 SMLoc S = Parser.getTok().getLoc();
2764 // Almost all registers have been parsed by custom parsers. There is only
2765 // one exception to this. $zero (and it's alias $0) will reach this point
2766 // for div, divu, and similar instructions because it is not an operand
2767 // to the instruction definition but an explicit register. Special case
2768 // this situation for now.
2769 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
2772 // Maybe it is a symbol reference.
2773 StringRef Identifier;
2774 if (Parser.parseIdentifier(Identifier))
2777 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2778 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
2779 // Otherwise create a symbol reference.
2781 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
2783 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
2786 // Else drop to expression parsing.
2787 case AsmToken::LParen:
2788 case AsmToken::Minus:
2789 case AsmToken::Plus:
2790 case AsmToken::Integer:
2791 case AsmToken::Tilde:
2792 case AsmToken::String: {
2793 DEBUG(dbgs() << ".. generic integer\n");
2794 OperandMatchResultTy ResTy = parseImm(Operands);
2795 return ResTy != MatchOperand_Success;
2797 case AsmToken::Percent: {
2798 // It is a symbol reference or constant expression.
2799 const MCExpr *IdVal;
2800 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
2801 if (parseRelocOperand(IdVal))
2804 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2806 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2808 } // case AsmToken::Percent
2809 } // switch(getLexer().getKind())
2813 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
2814 StringRef RelocStr) {
2816 // Check the type of the expression.
2817 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
2818 // It's a constant, evaluate reloc value.
2820 switch (getVariantKind(RelocStr)) {
2821 case MCSymbolRefExpr::VK_Mips_ABS_LO:
2822 // Get the 1st 16-bits.
2823 Val = MCE->getValue() & 0xffff;
2825 case MCSymbolRefExpr::VK_Mips_ABS_HI:
2826 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
2827 // 16 bits being negative.
2828 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
2830 case MCSymbolRefExpr::VK_Mips_HIGHER:
2831 // Get the 3rd 16-bits.
2832 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
2834 case MCSymbolRefExpr::VK_Mips_HIGHEST:
2835 // Get the 4th 16-bits.
2836 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
2839 report_fatal_error("unsupported reloc value");
2841 return MCConstantExpr::create(Val, getContext());
2844 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
2845 // It's a symbol, create a symbolic expression from the symbol.
2846 const MCSymbol *Symbol = &MSRE->getSymbol();
2847 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2848 Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
2852 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2853 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2855 // Try to create target expression.
2856 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
2857 return MipsMCExpr::create(VK, Expr, getContext());
2859 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
2860 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
2861 Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
2865 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
2866 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
2867 Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
2870 // Just return the original expression.
2874 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
2876 switch (Expr->getKind()) {
2877 case MCExpr::Constant:
2879 case MCExpr::SymbolRef:
2880 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
2881 case MCExpr::Binary:
2882 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2883 if (!isEvaluated(BE->getLHS()))
2885 return isEvaluated(BE->getRHS());
2888 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
2889 case MCExpr::Target:
2895 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
2896 MCAsmParser &Parser = getParser();
2897 Parser.Lex(); // Eat the % token.
2898 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
2899 if (Tok.isNot(AsmToken::Identifier))
2902 std::string Str = Tok.getIdentifier();
2904 Parser.Lex(); // Eat the identifier.
2905 // Now make an expression from the rest of the operand.
2906 const MCExpr *IdVal;
2909 if (getLexer().getKind() == AsmToken::LParen) {
2911 Parser.Lex(); // Eat the '(' token.
2912 if (getLexer().getKind() == AsmToken::Percent) {
2913 Parser.Lex(); // Eat the % token.
2914 const AsmToken &nextTok = Parser.getTok();
2915 if (nextTok.isNot(AsmToken::Identifier))
2918 Str += nextTok.getIdentifier();
2919 Parser.Lex(); // Eat the identifier.
2920 if (getLexer().getKind() != AsmToken::LParen)
2925 if (getParser().parseParenExpression(IdVal, EndLoc))
2928 while (getLexer().getKind() == AsmToken::RParen)
2929 Parser.Lex(); // Eat the ')' token.
2932 return true; // Parenthesis must follow the relocation operand.
2934 Res = evaluateRelocExpr(IdVal, Str);
2938 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2940 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2941 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2942 if (ResTy == MatchOperand_Success) {
2943 assert(Operands.size() == 1);
2944 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2945 StartLoc = Operand.getStartLoc();
2946 EndLoc = Operand.getEndLoc();
2948 // AFAIK, we only support numeric registers and named GPR's in CFI
2950 // Don't worry about eating tokens before failing. Using an unrecognised
2951 // register is a parse error.
2952 if (Operand.isGPRAsmReg()) {
2953 // Resolve to GPR32 or GPR64 appropriately.
2954 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2957 return (RegNo == (unsigned)-1);
2960 assert(Operands.size() == 0);
2961 return (RegNo == (unsigned)-1);
2964 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2965 MCAsmParser &Parser = getParser();
2969 while (getLexer().getKind() == AsmToken::LParen)
2972 switch (getLexer().getKind()) {
2975 case AsmToken::Identifier:
2976 case AsmToken::LParen:
2977 case AsmToken::Integer:
2978 case AsmToken::Minus:
2979 case AsmToken::Plus:
2981 Result = getParser().parseParenExpression(Res, S);
2983 Result = (getParser().parseExpression(Res));
2984 while (getLexer().getKind() == AsmToken::RParen)
2987 case AsmToken::Percent:
2988 Result = parseRelocOperand(Res);
2993 MipsAsmParser::OperandMatchResultTy
2994 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
2995 MCAsmParser &Parser = getParser();
2996 DEBUG(dbgs() << "parseMemOperand\n");
2997 const MCExpr *IdVal = nullptr;
2999 bool isParenExpr = false;
3000 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
3001 // First operand is the offset.
3002 S = Parser.getTok().getLoc();
3004 if (getLexer().getKind() == AsmToken::LParen) {
3009 if (getLexer().getKind() != AsmToken::Dollar) {
3010 if (parseMemOffset(IdVal, isParenExpr))
3011 return MatchOperand_ParseFail;
3013 const AsmToken &Tok = Parser.getTok(); // Get the next token.
3014 if (Tok.isNot(AsmToken::LParen)) {
3015 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
3016 if (Mnemonic.getToken() == "la") {
3018 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3019 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3020 return MatchOperand_Success;
3022 if (Tok.is(AsmToken::EndOfStatement)) {
3024 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3026 // Zero register assumed, add a memory operand with ZERO as its base.
3027 // "Base" will be managed by k_Memory.
3028 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
3031 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
3032 return MatchOperand_Success;
3034 Error(Parser.getTok().getLoc(), "'(' expected");
3035 return MatchOperand_ParseFail;
3038 Parser.Lex(); // Eat the '(' token.
3041 Res = parseAnyRegister(Operands);
3042 if (Res != MatchOperand_Success)
3045 if (Parser.getTok().isNot(AsmToken::RParen)) {
3046 Error(Parser.getTok().getLoc(), "')' expected");
3047 return MatchOperand_ParseFail;
3050 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3052 Parser.Lex(); // Eat the ')' token.
3055 IdVal = MCConstantExpr::create(0, getContext());
3057 // Replace the register operand with the memory operand.
3058 std::unique_ptr<MipsOperand> op(
3059 static_cast<MipsOperand *>(Operands.back().release()));
3060 // Remove the register from the operands.
3061 // "op" will be managed by k_Memory.
3062 Operands.pop_back();
3063 // Add the memory operand.
3064 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
3066 if (IdVal->evaluateAsAbsolute(Imm))
3067 IdVal = MCConstantExpr::create(Imm, getContext());
3068 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
3069 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
3073 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
3074 return MatchOperand_Success;
3077 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
3078 MCAsmParser &Parser = getParser();
3079 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
3081 SMLoc S = Parser.getTok().getLoc();
3083 if (Sym->isVariable())
3084 Expr = Sym->getVariableValue();
3087 if (Expr->getKind() == MCExpr::SymbolRef) {
3088 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3089 StringRef DefSymbol = Ref->getSymbol().getName();
3090 if (DefSymbol.startswith("$")) {
3091 OperandMatchResultTy ResTy =
3092 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
3093 if (ResTy == MatchOperand_Success) {
3096 } else if (ResTy == MatchOperand_ParseFail)
3097 llvm_unreachable("Should never ParseFail");
3100 } else if (Expr->getKind() == MCExpr::Constant) {
3102 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
3104 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
3111 MipsAsmParser::OperandMatchResultTy
3112 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
3113 StringRef Identifier,
3115 int Index = matchCPURegisterName(Identifier);
3117 Operands.push_back(MipsOperand::createGPRReg(
3118 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3119 return MatchOperand_Success;
3122 Index = matchHWRegsRegisterName(Identifier);
3124 Operands.push_back(MipsOperand::createHWRegsReg(
3125 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3126 return MatchOperand_Success;
3129 Index = matchFPURegisterName(Identifier);
3131 Operands.push_back(MipsOperand::createFGRReg(
3132 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3133 return MatchOperand_Success;
3136 Index = matchFCCRegisterName(Identifier);
3138 Operands.push_back(MipsOperand::createFCCReg(
3139 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3140 return MatchOperand_Success;
3143 Index = matchACRegisterName(Identifier);
3145 Operands.push_back(MipsOperand::createACCReg(
3146 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3147 return MatchOperand_Success;
3150 Index = matchMSA128RegisterName(Identifier);
3152 Operands.push_back(MipsOperand::createMSA128Reg(
3153 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3154 return MatchOperand_Success;
3157 Index = matchMSA128CtrlRegisterName(Identifier);
3159 Operands.push_back(MipsOperand::createMSACtrlReg(
3160 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3161 return MatchOperand_Success;
3164 return MatchOperand_NoMatch;
3167 MipsAsmParser::OperandMatchResultTy
3168 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
3169 MCAsmParser &Parser = getParser();
3170 auto Token = Parser.getLexer().peekTok(false);
3172 if (Token.is(AsmToken::Identifier)) {
3173 DEBUG(dbgs() << ".. identifier\n");
3174 StringRef Identifier = Token.getIdentifier();
3175 OperandMatchResultTy ResTy =
3176 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
3178 } else if (Token.is(AsmToken::Integer)) {
3179 DEBUG(dbgs() << ".. integer\n");
3180 Operands.push_back(MipsOperand::createNumericReg(
3181 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
3183 return MatchOperand_Success;
3186 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
3188 return MatchOperand_NoMatch;
3191 MipsAsmParser::OperandMatchResultTy
3192 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
3193 MCAsmParser &Parser = getParser();
3194 DEBUG(dbgs() << "parseAnyRegister\n");
3196 auto Token = Parser.getTok();
3198 SMLoc S = Token.getLoc();
3200 if (Token.isNot(AsmToken::Dollar)) {
3201 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
3202 if (Token.is(AsmToken::Identifier)) {
3203 if (searchSymbolAlias(Operands))
3204 return MatchOperand_Success;
3206 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
3207 return MatchOperand_NoMatch;
3209 DEBUG(dbgs() << ".. $\n");
3211 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
3212 if (ResTy == MatchOperand_Success) {
3214 Parser.Lex(); // identifier
3219 MipsAsmParser::OperandMatchResultTy
3220 MipsAsmParser::parseImm(OperandVector &Operands) {
3221 MCAsmParser &Parser = getParser();
3222 switch (getLexer().getKind()) {
3224 return MatchOperand_NoMatch;
3225 case AsmToken::LParen:
3226 case AsmToken::Minus:
3227 case AsmToken::Plus:
3228 case AsmToken::Integer:
3229 case AsmToken::Tilde:
3230 case AsmToken::String:
3234 const MCExpr *IdVal;
3235 SMLoc S = Parser.getTok().getLoc();
3236 if (getParser().parseExpression(IdVal))
3237 return MatchOperand_ParseFail;
3239 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3240 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3241 return MatchOperand_Success;
3244 MipsAsmParser::OperandMatchResultTy
3245 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
3246 MCAsmParser &Parser = getParser();
3247 DEBUG(dbgs() << "parseJumpTarget\n");
3249 SMLoc S = getLexer().getLoc();
3251 // Integers and expressions are acceptable
3252 OperandMatchResultTy ResTy = parseImm(Operands);
3253 if (ResTy != MatchOperand_NoMatch)
3256 // Registers are a valid target and have priority over symbols.
3257 ResTy = parseAnyRegister(Operands);
3258 if (ResTy != MatchOperand_NoMatch)
3261 const MCExpr *Expr = nullptr;
3262 if (Parser.parseExpression(Expr)) {
3263 // We have no way of knowing if a symbol was consumed so we must ParseFail
3264 return MatchOperand_ParseFail;
3267 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
3268 return MatchOperand_Success;
3271 MipsAsmParser::OperandMatchResultTy
3272 MipsAsmParser::parseInvNum(OperandVector &Operands) {
3273 MCAsmParser &Parser = getParser();
3274 const MCExpr *IdVal;
3275 // If the first token is '$' we may have register operand.
3276 if (Parser.getTok().is(AsmToken::Dollar))
3277 return MatchOperand_NoMatch;
3278 SMLoc S = Parser.getTok().getLoc();
3279 if (getParser().parseExpression(IdVal))
3280 return MatchOperand_ParseFail;
3281 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
3282 assert(MCE && "Unexpected MCExpr type.");
3283 int64_t Val = MCE->getValue();
3284 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3285 Operands.push_back(MipsOperand::CreateImm(
3286 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
3287 return MatchOperand_Success;
3290 MipsAsmParser::OperandMatchResultTy
3291 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
3292 MCAsmParser &Parser = getParser();
3293 switch (getLexer().getKind()) {
3295 return MatchOperand_NoMatch;
3296 case AsmToken::LParen:
3297 case AsmToken::Plus:
3298 case AsmToken::Minus:
3299 case AsmToken::Integer:
3304 SMLoc S = Parser.getTok().getLoc();
3306 if (getParser().parseExpression(Expr))
3307 return MatchOperand_ParseFail;
3310 if (!Expr->evaluateAsAbsolute(Val)) {
3311 Error(S, "expected immediate value");
3312 return MatchOperand_ParseFail;
3315 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
3316 // and because the CPU always adds one to the immediate field, the allowed
3317 // range becomes 1..4. We'll only check the range here and will deal
3318 // with the addition/subtraction when actually decoding/encoding
3320 if (Val < 1 || Val > 4) {
3321 Error(S, "immediate not in range (1..4)");
3322 return MatchOperand_ParseFail;
3326 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
3327 return MatchOperand_Success;
3330 MipsAsmParser::OperandMatchResultTy
3331 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3332 MCAsmParser &Parser = getParser();
3333 SmallVector<unsigned, 10> Regs;
3335 unsigned PrevReg = Mips::NoRegister;
3336 bool RegRange = false;
3337 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3339 if (Parser.getTok().isNot(AsmToken::Dollar))
3340 return MatchOperand_ParseFail;
3342 SMLoc S = Parser.getTok().getLoc();
3343 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3344 SMLoc E = getLexer().getLoc();
3345 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3346 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3348 // Remove last register operand because registers from register range
3349 // should be inserted first.
3350 if (RegNo == Mips::RA) {
3351 Regs.push_back(RegNo);
3353 unsigned TmpReg = PrevReg + 1;
3354 while (TmpReg <= RegNo) {
3355 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3356 Error(E, "invalid register operand");
3357 return MatchOperand_ParseFail;
3361 Regs.push_back(TmpReg++);
3367 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
3368 (RegNo != Mips::RA)) {
3369 Error(E, "$16 or $31 expected");
3370 return MatchOperand_ParseFail;
3371 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
3372 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3373 Error(E, "invalid register operand");
3374 return MatchOperand_ParseFail;
3375 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
3376 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3377 Error(E, "consecutive register numbers expected");
3378 return MatchOperand_ParseFail;
3381 Regs.push_back(RegNo);
3384 if (Parser.getTok().is(AsmToken::Minus))
3387 if (!Parser.getTok().isNot(AsmToken::Minus) &&
3388 !Parser.getTok().isNot(AsmToken::Comma)) {
3389 Error(E, "',' or '-' expected");
3390 return MatchOperand_ParseFail;
3393 Lex(); // Consume comma or minus
3394 if (Parser.getTok().isNot(AsmToken::Dollar))
3400 SMLoc E = Parser.getTok().getLoc();
3401 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3402 parseMemOperand(Operands);
3403 return MatchOperand_Success;
3406 MipsAsmParser::OperandMatchResultTy
3407 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
3408 MCAsmParser &Parser = getParser();
3410 SMLoc S = Parser.getTok().getLoc();
3411 if (parseAnyRegister(Operands) != MatchOperand_Success)
3412 return MatchOperand_ParseFail;
3414 SMLoc E = Parser.getTok().getLoc();
3415 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
3416 unsigned Reg = Op.getGPR32Reg();
3417 Operands.pop_back();
3418 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
3419 return MatchOperand_Success;
3422 MipsAsmParser::OperandMatchResultTy
3423 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
3424 MCAsmParser &Parser = getParser();
3425 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3426 SmallVector<unsigned, 10> Regs;
3428 if (Parser.getTok().isNot(AsmToken::Dollar))
3429 return MatchOperand_ParseFail;
3431 SMLoc S = Parser.getTok().getLoc();
3433 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3434 return MatchOperand_ParseFail;
3436 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3437 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3438 Regs.push_back(RegNo);
3440 SMLoc E = Parser.getTok().getLoc();
3441 if (Parser.getTok().isNot(AsmToken::Comma)) {
3442 Error(E, "',' expected");
3443 return MatchOperand_ParseFail;
3449 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3450 return MatchOperand_ParseFail;
3452 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3453 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3454 Regs.push_back(RegNo);
3456 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3458 return MatchOperand_Success;
3461 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
3463 MCSymbolRefExpr::VariantKind VK =
3464 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
3465 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
3466 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
3467 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
3468 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
3469 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
3470 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
3471 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
3472 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
3473 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
3474 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
3475 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
3476 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
3477 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
3478 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
3479 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
3480 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
3481 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
3482 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
3483 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
3484 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
3485 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
3486 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
3487 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
3488 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
3489 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
3490 .Default(MCSymbolRefExpr::VK_None);
3492 assert(VK != MCSymbolRefExpr::VK_None);
3497 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
3499 /// ::= '(', register, ')'
3500 /// handle it before we iterate so we don't get tripped up by the lack of
3502 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
3503 MCAsmParser &Parser = getParser();
3504 if (getLexer().is(AsmToken::LParen)) {
3506 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
3508 if (parseOperand(Operands, Name)) {
3509 SMLoc Loc = getLexer().getLoc();
3510 Parser.eatToEndOfStatement();
3511 return Error(Loc, "unexpected token in argument list");
3513 if (Parser.getTok().isNot(AsmToken::RParen)) {
3514 SMLoc Loc = getLexer().getLoc();
3515 Parser.eatToEndOfStatement();
3516 return Error(Loc, "unexpected token, expected ')'");
3519 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
3525 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
3526 /// either one of these.
3527 /// ::= '[', register, ']'
3528 /// ::= '[', integer, ']'
3529 /// handle it before we iterate so we don't get tripped up by the lack of
3531 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
3532 OperandVector &Operands) {
3533 MCAsmParser &Parser = getParser();
3534 if (getLexer().is(AsmToken::LBrac)) {
3536 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
3538 if (parseOperand(Operands, Name)) {
3539 SMLoc Loc = getLexer().getLoc();
3540 Parser.eatToEndOfStatement();
3541 return Error(Loc, "unexpected token in argument list");
3543 if (Parser.getTok().isNot(AsmToken::RBrac)) {
3544 SMLoc Loc = getLexer().getLoc();
3545 Parser.eatToEndOfStatement();
3546 return Error(Loc, "unexpected token, expected ']'");
3549 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
3555 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
3556 SMLoc NameLoc, OperandVector &Operands) {
3557 MCAsmParser &Parser = getParser();
3558 DEBUG(dbgs() << "ParseInstruction\n");
3560 // We have reached first instruction, module directive are now forbidden.
3561 getTargetStreamer().forbidModuleDirective();
3563 // Check if we have valid mnemonic
3564 if (!mnemonicIsValid(Name, 0)) {
3565 Parser.eatToEndOfStatement();
3566 return Error(NameLoc, "unknown instruction");
3568 // First operand in MCInst is instruction mnemonic.
3569 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
3571 // Read the remaining operands.
3572 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3573 // Read the first operand.
3574 if (parseOperand(Operands, Name)) {
3575 SMLoc Loc = getLexer().getLoc();
3576 Parser.eatToEndOfStatement();
3577 return Error(Loc, "unexpected token in argument list");
3579 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
3581 // AFAIK, parenthesis suffixes are never on the first operand
3583 while (getLexer().is(AsmToken::Comma)) {
3584 Parser.Lex(); // Eat the comma.
3585 // Parse and remember the operand.
3586 if (parseOperand(Operands, Name)) {
3587 SMLoc Loc = getLexer().getLoc();
3588 Parser.eatToEndOfStatement();
3589 return Error(Loc, "unexpected token in argument list");
3591 // Parse bracket and parenthesis suffixes before we iterate
3592 if (getLexer().is(AsmToken::LBrac)) {
3593 if (parseBracketSuffix(Name, Operands))
3595 } else if (getLexer().is(AsmToken::LParen) &&
3596 parseParenSuffix(Name, Operands))
3600 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3601 SMLoc Loc = getLexer().getLoc();
3602 Parser.eatToEndOfStatement();
3603 return Error(Loc, "unexpected token in argument list");
3605 Parser.Lex(); // Consume the EndOfStatement.
3609 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
3610 MCAsmParser &Parser = getParser();
3611 SMLoc Loc = getLexer().getLoc();
3612 Parser.eatToEndOfStatement();
3613 return Error(Loc, ErrorMsg);
3616 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
3617 return Error(Loc, ErrorMsg);
3620 bool MipsAsmParser::parseSetNoAtDirective() {
3621 MCAsmParser &Parser = getParser();
3622 // Line should look like: ".set noat".
3624 // Set the $at register to $0.
3625 AssemblerOptions.back()->setATRegIndex(0);
3627 Parser.Lex(); // Eat "noat".
3629 // If this is not the end of the statement, report an error.
3630 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3631 reportParseError("unexpected token, expected end of statement");
3635 getTargetStreamer().emitDirectiveSetNoAt();
3636 Parser.Lex(); // Consume the EndOfStatement.
3640 bool MipsAsmParser::parseSetAtDirective() {
3641 // Line can be: ".set at", which sets $at to $1
3642 // or ".set at=$reg", which sets $at to $reg.
3643 MCAsmParser &Parser = getParser();
3644 Parser.Lex(); // Eat "at".
3646 if (getLexer().is(AsmToken::EndOfStatement)) {
3647 // No register was specified, so we set $at to $1.
3648 AssemblerOptions.back()->setATRegIndex(1);
3650 getTargetStreamer().emitDirectiveSetAt();
3651 Parser.Lex(); // Consume the EndOfStatement.
3655 if (getLexer().isNot(AsmToken::Equal)) {
3656 reportParseError("unexpected token, expected equals sign");
3659 Parser.Lex(); // Eat "=".
3661 if (getLexer().isNot(AsmToken::Dollar)) {
3662 if (getLexer().is(AsmToken::EndOfStatement)) {
3663 reportParseError("no register specified");
3666 reportParseError("unexpected token, expected dollar sign '$'");
3670 Parser.Lex(); // Eat "$".
3672 // Find out what "reg" is.
3674 const AsmToken &Reg = Parser.getTok();
3675 if (Reg.is(AsmToken::Identifier)) {
3676 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
3677 } else if (Reg.is(AsmToken::Integer)) {
3678 AtRegNo = Reg.getIntVal();
3680 reportParseError("unexpected token, expected identifier or integer");
3684 // Check if $reg is a valid register. If it is, set $at to $reg.
3685 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
3686 reportParseError("invalid register");
3689 Parser.Lex(); // Eat "reg".
3691 // If this is not the end of the statement, report an error.
3692 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3693 reportParseError("unexpected token, expected end of statement");
3697 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
3699 Parser.Lex(); // Consume the EndOfStatement.
3703 bool MipsAsmParser::parseSetReorderDirective() {
3704 MCAsmParser &Parser = getParser();
3706 // If this is not the end of the statement, report an error.
3707 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3708 reportParseError("unexpected token, expected end of statement");
3711 AssemblerOptions.back()->setReorder();
3712 getTargetStreamer().emitDirectiveSetReorder();
3713 Parser.Lex(); // Consume the EndOfStatement.
3717 bool MipsAsmParser::parseSetNoReorderDirective() {
3718 MCAsmParser &Parser = getParser();
3720 // If this is not the end of the statement, report an error.
3721 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3722 reportParseError("unexpected token, expected end of statement");
3725 AssemblerOptions.back()->setNoReorder();
3726 getTargetStreamer().emitDirectiveSetNoReorder();
3727 Parser.Lex(); // Consume the EndOfStatement.
3731 bool MipsAsmParser::parseSetMacroDirective() {
3732 MCAsmParser &Parser = getParser();
3734 // If this is not the end of the statement, report an error.
3735 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3736 reportParseError("unexpected token, expected end of statement");
3739 AssemblerOptions.back()->setMacro();
3740 getTargetStreamer().emitDirectiveSetMacro();
3741 Parser.Lex(); // Consume the EndOfStatement.
3745 bool MipsAsmParser::parseSetNoMacroDirective() {
3746 MCAsmParser &Parser = getParser();
3748 // If this is not the end of the statement, report an error.
3749 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3750 reportParseError("unexpected token, expected end of statement");
3753 if (AssemblerOptions.back()->isReorder()) {
3754 reportParseError("`noreorder' must be set before `nomacro'");
3757 AssemblerOptions.back()->setNoMacro();
3758 getTargetStreamer().emitDirectiveSetNoMacro();
3759 Parser.Lex(); // Consume the EndOfStatement.
3763 bool MipsAsmParser::parseSetMsaDirective() {
3764 MCAsmParser &Parser = getParser();
3767 // If this is not the end of the statement, report an error.
3768 if (getLexer().isNot(AsmToken::EndOfStatement))
3769 return reportParseError("unexpected token, expected end of statement");
3771 setFeatureBits(Mips::FeatureMSA, "msa");
3772 getTargetStreamer().emitDirectiveSetMsa();
3776 bool MipsAsmParser::parseSetNoMsaDirective() {
3777 MCAsmParser &Parser = getParser();
3780 // If this is not the end of the statement, report an error.
3781 if (getLexer().isNot(AsmToken::EndOfStatement))
3782 return reportParseError("unexpected token, expected end of statement");
3784 clearFeatureBits(Mips::FeatureMSA, "msa");
3785 getTargetStreamer().emitDirectiveSetNoMsa();
3789 bool MipsAsmParser::parseSetNoDspDirective() {
3790 MCAsmParser &Parser = getParser();
3791 Parser.Lex(); // Eat "nodsp".
3793 // If this is not the end of the statement, report an error.
3794 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3795 reportParseError("unexpected token, expected end of statement");
3799 clearFeatureBits(Mips::FeatureDSP, "dsp");
3800 getTargetStreamer().emitDirectiveSetNoDsp();
3804 bool MipsAsmParser::parseSetMips16Directive() {
3805 MCAsmParser &Parser = getParser();
3806 Parser.Lex(); // Eat "mips16".
3808 // If this is not the end of the statement, report an error.
3809 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3810 reportParseError("unexpected token, expected end of statement");
3814 setFeatureBits(Mips::FeatureMips16, "mips16");
3815 getTargetStreamer().emitDirectiveSetMips16();
3816 Parser.Lex(); // Consume the EndOfStatement.
3820 bool MipsAsmParser::parseSetNoMips16Directive() {
3821 MCAsmParser &Parser = getParser();
3822 Parser.Lex(); // Eat "nomips16".
3824 // If this is not the end of the statement, report an error.
3825 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3826 reportParseError("unexpected token, expected end of statement");
3830 clearFeatureBits(Mips::FeatureMips16, "mips16");
3831 getTargetStreamer().emitDirectiveSetNoMips16();
3832 Parser.Lex(); // Consume the EndOfStatement.
3836 bool MipsAsmParser::parseSetFpDirective() {
3837 MCAsmParser &Parser = getParser();
3838 MipsABIFlagsSection::FpABIKind FpAbiVal;
3839 // Line can be: .set fp=32
3842 Parser.Lex(); // Eat fp token
3843 AsmToken Tok = Parser.getTok();
3844 if (Tok.isNot(AsmToken::Equal)) {
3845 reportParseError("unexpected token, expected equals sign '='");
3848 Parser.Lex(); // Eat '=' token.
3849 Tok = Parser.getTok();
3851 if (!parseFpABIValue(FpAbiVal, ".set"))
3854 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3855 reportParseError("unexpected token, expected end of statement");
3858 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
3859 Parser.Lex(); // Consume the EndOfStatement.
3863 bool MipsAsmParser::parseSetPopDirective() {
3864 MCAsmParser &Parser = getParser();
3865 SMLoc Loc = getLexer().getLoc();
3868 if (getLexer().isNot(AsmToken::EndOfStatement))
3869 return reportParseError("unexpected token, expected end of statement");
3871 // Always keep an element on the options "stack" to prevent the user
3872 // from changing the initial options. This is how we remember them.
3873 if (AssemblerOptions.size() == 2)
3874 return reportParseError(Loc, ".set pop with no .set push");
3876 AssemblerOptions.pop_back();
3877 setAvailableFeatures(
3878 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
3879 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
3881 getTargetStreamer().emitDirectiveSetPop();
3885 bool MipsAsmParser::parseSetPushDirective() {
3886 MCAsmParser &Parser = getParser();
3888 if (getLexer().isNot(AsmToken::EndOfStatement))
3889 return reportParseError("unexpected token, expected end of statement");
3891 // Create a copy of the current assembler options environment and push it.
3892 AssemblerOptions.push_back(
3893 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
3895 getTargetStreamer().emitDirectiveSetPush();
3899 bool MipsAsmParser::parseSetSoftFloatDirective() {
3900 MCAsmParser &Parser = getParser();
3902 if (getLexer().isNot(AsmToken::EndOfStatement))
3903 return reportParseError("unexpected token, expected end of statement");
3905 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
3906 getTargetStreamer().emitDirectiveSetSoftFloat();
3910 bool MipsAsmParser::parseSetHardFloatDirective() {
3911 MCAsmParser &Parser = getParser();
3913 if (getLexer().isNot(AsmToken::EndOfStatement))
3914 return reportParseError("unexpected token, expected end of statement");
3916 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
3917 getTargetStreamer().emitDirectiveSetHardFloat();
3921 bool MipsAsmParser::parseSetAssignment() {
3923 const MCExpr *Value;
3924 MCAsmParser &Parser = getParser();
3926 if (Parser.parseIdentifier(Name))
3927 reportParseError("expected identifier after .set");
3929 if (getLexer().isNot(AsmToken::Comma))
3930 return reportParseError("unexpected token, expected comma");
3933 if (Parser.parseExpression(Value))
3934 return reportParseError("expected valid expression after comma");
3936 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
3937 Sym->setVariableValue(Value);
3942 bool MipsAsmParser::parseSetMips0Directive() {
3943 MCAsmParser &Parser = getParser();
3945 if (getLexer().isNot(AsmToken::EndOfStatement))
3946 return reportParseError("unexpected token, expected end of statement");
3948 // Reset assembler options to their initial values.
3949 setAvailableFeatures(
3950 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
3951 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
3952 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
3954 getTargetStreamer().emitDirectiveSetMips0();
3958 bool MipsAsmParser::parseSetArchDirective() {
3959 MCAsmParser &Parser = getParser();
3961 if (getLexer().isNot(AsmToken::Equal))
3962 return reportParseError("unexpected token, expected equals sign");
3966 if (Parser.parseIdentifier(Arch))
3967 return reportParseError("expected arch identifier");
3969 StringRef ArchFeatureName =
3970 StringSwitch<StringRef>(Arch)
3971 .Case("mips1", "mips1")
3972 .Case("mips2", "mips2")
3973 .Case("mips3", "mips3")
3974 .Case("mips4", "mips4")
3975 .Case("mips5", "mips5")
3976 .Case("mips32", "mips32")
3977 .Case("mips32r2", "mips32r2")
3978 .Case("mips32r3", "mips32r3")
3979 .Case("mips32r5", "mips32r5")
3980 .Case("mips32r6", "mips32r6")
3981 .Case("mips64", "mips64")
3982 .Case("mips64r2", "mips64r2")
3983 .Case("mips64r3", "mips64r3")
3984 .Case("mips64r5", "mips64r5")
3985 .Case("mips64r6", "mips64r6")
3986 .Case("cnmips", "cnmips")
3987 .Case("r4000", "mips3") // This is an implementation of Mips3.
3990 if (ArchFeatureName.empty())
3991 return reportParseError("unsupported architecture");
3993 selectArch(ArchFeatureName);
3994 getTargetStreamer().emitDirectiveSetArch(Arch);
3998 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
3999 MCAsmParser &Parser = getParser();
4001 if (getLexer().isNot(AsmToken::EndOfStatement))
4002 return reportParseError("unexpected token, expected end of statement");
4006 llvm_unreachable("Unimplemented feature");
4007 case Mips::FeatureDSP:
4008 setFeatureBits(Mips::FeatureDSP, "dsp");
4009 getTargetStreamer().emitDirectiveSetDsp();
4011 case Mips::FeatureMicroMips:
4012 getTargetStreamer().emitDirectiveSetMicroMips();
4014 case Mips::FeatureMips1:
4015 selectArch("mips1");
4016 getTargetStreamer().emitDirectiveSetMips1();
4018 case Mips::FeatureMips2:
4019 selectArch("mips2");
4020 getTargetStreamer().emitDirectiveSetMips2();
4022 case Mips::FeatureMips3:
4023 selectArch("mips3");
4024 getTargetStreamer().emitDirectiveSetMips3();
4026 case Mips::FeatureMips4:
4027 selectArch("mips4");
4028 getTargetStreamer().emitDirectiveSetMips4();
4030 case Mips::FeatureMips5:
4031 selectArch("mips5");
4032 getTargetStreamer().emitDirectiveSetMips5();
4034 case Mips::FeatureMips32:
4035 selectArch("mips32");
4036 getTargetStreamer().emitDirectiveSetMips32();
4038 case Mips::FeatureMips32r2:
4039 selectArch("mips32r2");
4040 getTargetStreamer().emitDirectiveSetMips32R2();
4042 case Mips::FeatureMips32r3:
4043 selectArch("mips32r3");
4044 getTargetStreamer().emitDirectiveSetMips32R3();
4046 case Mips::FeatureMips32r5:
4047 selectArch("mips32r5");
4048 getTargetStreamer().emitDirectiveSetMips32R5();
4050 case Mips::FeatureMips32r6:
4051 selectArch("mips32r6");
4052 getTargetStreamer().emitDirectiveSetMips32R6();
4054 case Mips::FeatureMips64:
4055 selectArch("mips64");
4056 getTargetStreamer().emitDirectiveSetMips64();
4058 case Mips::FeatureMips64r2:
4059 selectArch("mips64r2");
4060 getTargetStreamer().emitDirectiveSetMips64R2();
4062 case Mips::FeatureMips64r3:
4063 selectArch("mips64r3");
4064 getTargetStreamer().emitDirectiveSetMips64R3();
4066 case Mips::FeatureMips64r5:
4067 selectArch("mips64r5");
4068 getTargetStreamer().emitDirectiveSetMips64R5();
4070 case Mips::FeatureMips64r6:
4071 selectArch("mips64r6");
4072 getTargetStreamer().emitDirectiveSetMips64R6();
4078 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
4079 MCAsmParser &Parser = getParser();
4080 if (getLexer().isNot(AsmToken::Comma)) {
4081 SMLoc Loc = getLexer().getLoc();
4082 Parser.eatToEndOfStatement();
4083 return Error(Loc, ErrorStr);
4086 Parser.Lex(); // Eat the comma.
4090 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
4091 if (AssemblerOptions.back()->isReorder())
4092 Warning(Loc, ".cpload should be inside a noreorder section");
4094 if (inMips16Mode()) {
4095 reportParseError(".cpload is not supported in Mips16 mode");
4099 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
4100 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
4101 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4102 reportParseError("expected register containing function address");
4106 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
4107 if (!RegOpnd.isGPRAsmReg()) {
4108 reportParseError(RegOpnd.getStartLoc(), "invalid register");
4112 // If this is not the end of the statement, report an error.
4113 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4114 reportParseError("unexpected token, expected end of statement");
4118 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
4122 bool MipsAsmParser::parseDirectiveCPSetup() {
4123 MCAsmParser &Parser = getParser();
4126 bool SaveIsReg = true;
4128 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4129 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4130 if (ResTy == MatchOperand_NoMatch) {
4131 reportParseError("expected register containing function address");
4132 Parser.eatToEndOfStatement();
4136 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4137 if (!FuncRegOpnd.isGPRAsmReg()) {
4138 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
4139 Parser.eatToEndOfStatement();
4143 FuncReg = FuncRegOpnd.getGPR32Reg();
4146 if (!eatComma("unexpected token, expected comma"))
4149 ResTy = parseAnyRegister(TmpReg);
4150 if (ResTy == MatchOperand_NoMatch) {
4151 const AsmToken &Tok = Parser.getTok();
4152 if (Tok.is(AsmToken::Integer)) {
4153 Save = Tok.getIntVal();
4157 reportParseError("expected save register or stack offset");
4158 Parser.eatToEndOfStatement();
4162 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4163 if (!SaveOpnd.isGPRAsmReg()) {
4164 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
4165 Parser.eatToEndOfStatement();
4168 Save = SaveOpnd.getGPR32Reg();
4171 if (!eatComma("unexpected token, expected comma"))
4175 if (Parser.parseExpression(Expr)) {
4176 reportParseError("expected expression");
4180 if (Expr->getKind() != MCExpr::SymbolRef) {
4181 reportParseError("expected symbol");
4184 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
4186 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
4191 bool MipsAsmParser::parseDirectiveNaN() {
4192 MCAsmParser &Parser = getParser();
4193 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4194 const AsmToken &Tok = Parser.getTok();
4196 if (Tok.getString() == "2008") {
4198 getTargetStreamer().emitDirectiveNaN2008();
4200 } else if (Tok.getString() == "legacy") {
4202 getTargetStreamer().emitDirectiveNaNLegacy();
4206 // If we don't recognize the option passed to the .nan
4207 // directive (e.g. no option or unknown option), emit an error.
4208 reportParseError("invalid option in .nan directive");
4212 bool MipsAsmParser::parseDirectiveSet() {
4213 MCAsmParser &Parser = getParser();
4214 // Get the next token.
4215 const AsmToken &Tok = Parser.getTok();
4217 if (Tok.getString() == "noat") {
4218 return parseSetNoAtDirective();
4219 } else if (Tok.getString() == "at") {
4220 return parseSetAtDirective();
4221 } else if (Tok.getString() == "arch") {
4222 return parseSetArchDirective();
4223 } else if (Tok.getString() == "fp") {
4224 return parseSetFpDirective();
4225 } else if (Tok.getString() == "pop") {
4226 return parseSetPopDirective();
4227 } else if (Tok.getString() == "push") {
4228 return parseSetPushDirective();
4229 } else if (Tok.getString() == "reorder") {
4230 return parseSetReorderDirective();
4231 } else if (Tok.getString() == "noreorder") {
4232 return parseSetNoReorderDirective();
4233 } else if (Tok.getString() == "macro") {
4234 return parseSetMacroDirective();
4235 } else if (Tok.getString() == "nomacro") {
4236 return parseSetNoMacroDirective();
4237 } else if (Tok.getString() == "mips16") {
4238 return parseSetMips16Directive();
4239 } else if (Tok.getString() == "nomips16") {
4240 return parseSetNoMips16Directive();
4241 } else if (Tok.getString() == "nomicromips") {
4242 getTargetStreamer().emitDirectiveSetNoMicroMips();
4243 Parser.eatToEndOfStatement();
4245 } else if (Tok.getString() == "micromips") {
4246 return parseSetFeature(Mips::FeatureMicroMips);
4247 } else if (Tok.getString() == "mips0") {
4248 return parseSetMips0Directive();
4249 } else if (Tok.getString() == "mips1") {
4250 return parseSetFeature(Mips::FeatureMips1);
4251 } else if (Tok.getString() == "mips2") {
4252 return parseSetFeature(Mips::FeatureMips2);
4253 } else if (Tok.getString() == "mips3") {
4254 return parseSetFeature(Mips::FeatureMips3);
4255 } else if (Tok.getString() == "mips4") {
4256 return parseSetFeature(Mips::FeatureMips4);
4257 } else if (Tok.getString() == "mips5") {
4258 return parseSetFeature(Mips::FeatureMips5);
4259 } else if (Tok.getString() == "mips32") {
4260 return parseSetFeature(Mips::FeatureMips32);
4261 } else if (Tok.getString() == "mips32r2") {
4262 return parseSetFeature(Mips::FeatureMips32r2);
4263 } else if (Tok.getString() == "mips32r3") {
4264 return parseSetFeature(Mips::FeatureMips32r3);
4265 } else if (Tok.getString() == "mips32r5") {
4266 return parseSetFeature(Mips::FeatureMips32r5);
4267 } else if (Tok.getString() == "mips32r6") {
4268 return parseSetFeature(Mips::FeatureMips32r6);
4269 } else if (Tok.getString() == "mips64") {
4270 return parseSetFeature(Mips::FeatureMips64);
4271 } else if (Tok.getString() == "mips64r2") {
4272 return parseSetFeature(Mips::FeatureMips64r2);
4273 } else if (Tok.getString() == "mips64r3") {
4274 return parseSetFeature(Mips::FeatureMips64r3);
4275 } else if (Tok.getString() == "mips64r5") {
4276 return parseSetFeature(Mips::FeatureMips64r5);
4277 } else if (Tok.getString() == "mips64r6") {
4278 return parseSetFeature(Mips::FeatureMips64r6);
4279 } else if (Tok.getString() == "dsp") {
4280 return parseSetFeature(Mips::FeatureDSP);
4281 } else if (Tok.getString() == "nodsp") {
4282 return parseSetNoDspDirective();
4283 } else if (Tok.getString() == "msa") {
4284 return parseSetMsaDirective();
4285 } else if (Tok.getString() == "nomsa") {
4286 return parseSetNoMsaDirective();
4287 } else if (Tok.getString() == "softfloat") {
4288 return parseSetSoftFloatDirective();
4289 } else if (Tok.getString() == "hardfloat") {
4290 return parseSetHardFloatDirective();
4292 // It is just an identifier, look for an assignment.
4293 parseSetAssignment();
4300 /// parseDataDirective
4301 /// ::= .word [ expression (, expression)* ]
4302 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
4303 MCAsmParser &Parser = getParser();
4304 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4306 const MCExpr *Value;
4307 if (getParser().parseExpression(Value))
4310 getParser().getStreamer().EmitValue(Value, Size);
4312 if (getLexer().is(AsmToken::EndOfStatement))
4315 if (getLexer().isNot(AsmToken::Comma))
4316 return Error(L, "unexpected token, expected comma");
4325 /// parseDirectiveGpWord
4326 /// ::= .gpword local_sym
4327 bool MipsAsmParser::parseDirectiveGpWord() {
4328 MCAsmParser &Parser = getParser();
4329 const MCExpr *Value;
4330 // EmitGPRel32Value requires an expression, so we are using base class
4331 // method to evaluate the expression.
4332 if (getParser().parseExpression(Value))
4334 getParser().getStreamer().EmitGPRel32Value(Value);
4336 if (getLexer().isNot(AsmToken::EndOfStatement))
4337 return Error(getLexer().getLoc(),
4338 "unexpected token, expected end of statement");
4339 Parser.Lex(); // Eat EndOfStatement token.
4343 /// parseDirectiveGpDWord
4344 /// ::= .gpdword local_sym
4345 bool MipsAsmParser::parseDirectiveGpDWord() {
4346 MCAsmParser &Parser = getParser();
4347 const MCExpr *Value;
4348 // EmitGPRel64Value requires an expression, so we are using base class
4349 // method to evaluate the expression.
4350 if (getParser().parseExpression(Value))
4352 getParser().getStreamer().EmitGPRel64Value(Value);
4354 if (getLexer().isNot(AsmToken::EndOfStatement))
4355 return Error(getLexer().getLoc(),
4356 "unexpected token, expected end of statement");
4357 Parser.Lex(); // Eat EndOfStatement token.
4361 bool MipsAsmParser::parseDirectiveOption() {
4362 MCAsmParser &Parser = getParser();
4363 // Get the option token.
4364 AsmToken Tok = Parser.getTok();
4365 // At the moment only identifiers are supported.
4366 if (Tok.isNot(AsmToken::Identifier)) {
4367 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
4368 Parser.eatToEndOfStatement();
4372 StringRef Option = Tok.getIdentifier();
4374 if (Option == "pic0") {
4375 getTargetStreamer().emitDirectiveOptionPic0();
4377 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4378 Error(Parser.getTok().getLoc(),
4379 "unexpected token, expected end of statement");
4380 Parser.eatToEndOfStatement();
4385 if (Option == "pic2") {
4386 getTargetStreamer().emitDirectiveOptionPic2();
4388 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4389 Error(Parser.getTok().getLoc(),
4390 "unexpected token, expected end of statement");
4391 Parser.eatToEndOfStatement();
4397 Warning(Parser.getTok().getLoc(),
4398 "unknown option, expected 'pic0' or 'pic2'");
4399 Parser.eatToEndOfStatement();
4403 /// parseInsnDirective
4405 bool MipsAsmParser::parseInsnDirective() {
4406 // If this is not the end of the statement, report an error.
4407 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4408 reportParseError("unexpected token, expected end of statement");
4412 // The actual label marking happens in
4413 // MipsELFStreamer::createPendingLabelRelocs().
4414 getTargetStreamer().emitDirectiveInsn();
4416 getParser().Lex(); // Eat EndOfStatement token.
4420 /// parseDirectiveModule
4421 /// ::= .module oddspreg
4422 /// ::= .module nooddspreg
4423 /// ::= .module fp=value
4424 bool MipsAsmParser::parseDirectiveModule() {
4425 MCAsmParser &Parser = getParser();
4426 MCAsmLexer &Lexer = getLexer();
4427 SMLoc L = Lexer.getLoc();
4429 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
4430 // TODO : get a better message.
4431 reportParseError(".module directive must appear before any code");
4436 if (Parser.parseIdentifier(Option)) {
4437 reportParseError("expected .module option identifier");
4441 if (Option == "oddspreg") {
4442 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
4443 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4445 // If this is not the end of the statement, report an error.
4446 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4447 reportParseError("unexpected token, expected end of statement");
4451 return false; // parseDirectiveModule has finished successfully.
4452 } else if (Option == "nooddspreg") {
4454 Error(L, "'.module nooddspreg' requires the O32 ABI");
4458 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
4459 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4461 // If this is not the end of the statement, report an error.
4462 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4463 reportParseError("unexpected token, expected end of statement");
4467 return false; // parseDirectiveModule has finished successfully.
4468 } else if (Option == "fp") {
4469 return parseDirectiveModuleFP();
4471 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
4475 /// parseDirectiveModuleFP
4479 bool MipsAsmParser::parseDirectiveModuleFP() {
4480 MCAsmParser &Parser = getParser();
4481 MCAsmLexer &Lexer = getLexer();
4483 if (Lexer.isNot(AsmToken::Equal)) {
4484 reportParseError("unexpected token, expected equals sign '='");
4487 Parser.Lex(); // Eat '=' token.
4489 MipsABIFlagsSection::FpABIKind FpABI;
4490 if (!parseFpABIValue(FpABI, ".module"))
4493 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4494 reportParseError("unexpected token, expected end of statement");
4498 // Emit appropriate flags.
4499 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
4500 Parser.Lex(); // Consume the EndOfStatement.
4504 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
4505 StringRef Directive) {
4506 MCAsmParser &Parser = getParser();
4507 MCAsmLexer &Lexer = getLexer();
4509 if (Lexer.is(AsmToken::Identifier)) {
4510 StringRef Value = Parser.getTok().getString();
4513 if (Value != "xx") {
4514 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4519 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
4523 FpABI = MipsABIFlagsSection::FpABIKind::XX;
4527 if (Lexer.is(AsmToken::Integer)) {
4528 unsigned Value = Parser.getTok().getIntVal();
4531 if (Value != 32 && Value != 64) {
4532 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4538 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
4542 FpABI = MipsABIFlagsSection::FpABIKind::S32;
4544 FpABI = MipsABIFlagsSection::FpABIKind::S64;
4552 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
4553 MCAsmParser &Parser = getParser();
4554 StringRef IDVal = DirectiveID.getString();
4556 if (IDVal == ".cpload")
4557 return parseDirectiveCpLoad(DirectiveID.getLoc());
4558 if (IDVal == ".dword") {
4559 parseDataDirective(8, DirectiveID.getLoc());
4562 if (IDVal == ".ent") {
4563 StringRef SymbolName;
4565 if (Parser.parseIdentifier(SymbolName)) {
4566 reportParseError("expected identifier after .ent");
4570 // There's an undocumented extension that allows an integer to
4571 // follow the name of the procedure which AFAICS is ignored by GAS.
4572 // Example: .ent foo,2
4573 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4574 if (getLexer().isNot(AsmToken::Comma)) {
4575 // Even though we accept this undocumented extension for compatibility
4576 // reasons, the additional integer argument does not actually change
4577 // the behaviour of the '.ent' directive, so we would like to discourage
4578 // its use. We do this by not referring to the extended version in
4579 // error messages which are not directly related to its use.
4580 reportParseError("unexpected token, expected end of statement");
4583 Parser.Lex(); // Eat the comma.
4584 const MCExpr *DummyNumber;
4585 int64_t DummyNumberVal;
4586 // If the user was explicitly trying to use the extended version,
4587 // we still give helpful extension-related error messages.
4588 if (Parser.parseExpression(DummyNumber)) {
4589 reportParseError("expected number after comma");
4592 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
4593 reportParseError("expected an absolute expression after comma");
4598 // If this is not the end of the statement, report an error.
4599 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4600 reportParseError("unexpected token, expected end of statement");
4604 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
4606 getTargetStreamer().emitDirectiveEnt(*Sym);
4611 if (IDVal == ".end") {
4612 StringRef SymbolName;
4614 if (Parser.parseIdentifier(SymbolName)) {
4615 reportParseError("expected identifier after .end");
4619 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4620 reportParseError("unexpected token, expected end of statement");
4624 if (CurrentFn == nullptr) {
4625 reportParseError(".end used without .ent");
4629 if ((SymbolName != CurrentFn->getName())) {
4630 reportParseError(".end symbol does not match .ent symbol");
4634 getTargetStreamer().emitDirectiveEnd(SymbolName);
4635 CurrentFn = nullptr;
4639 if (IDVal == ".frame") {
4640 // .frame $stack_reg, frame_size_in_bytes, $return_reg
4641 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4642 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4643 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4644 reportParseError("expected stack register");
4648 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4649 if (!StackRegOpnd.isGPRAsmReg()) {
4650 reportParseError(StackRegOpnd.getStartLoc(),
4651 "expected general purpose register");
4654 unsigned StackReg = StackRegOpnd.getGPR32Reg();
4656 if (Parser.getTok().is(AsmToken::Comma))
4659 reportParseError("unexpected token, expected comma");
4663 // Parse the frame size.
4664 const MCExpr *FrameSize;
4665 int64_t FrameSizeVal;
4667 if (Parser.parseExpression(FrameSize)) {
4668 reportParseError("expected frame size value");
4672 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
4673 reportParseError("frame size not an absolute expression");
4677 if (Parser.getTok().is(AsmToken::Comma))
4680 reportParseError("unexpected token, expected comma");
4684 // Parse the return register.
4686 ResTy = parseAnyRegister(TmpReg);
4687 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4688 reportParseError("expected return register");
4692 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4693 if (!ReturnRegOpnd.isGPRAsmReg()) {
4694 reportParseError(ReturnRegOpnd.getStartLoc(),
4695 "expected general purpose register");
4699 // If this is not the end of the statement, report an error.
4700 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4701 reportParseError("unexpected token, expected end of statement");
4705 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
4706 ReturnRegOpnd.getGPR32Reg());
4710 if (IDVal == ".set") {
4711 return parseDirectiveSet();
4714 if (IDVal == ".mask" || IDVal == ".fmask") {
4715 // .mask bitmask, frame_offset
4716 // bitmask: One bit for each register used.
4717 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
4718 // first register is expected to be saved.
4720 // .mask 0x80000000, -4
4721 // .fmask 0x80000000, -4
4724 // Parse the bitmask
4725 const MCExpr *BitMask;
4728 if (Parser.parseExpression(BitMask)) {
4729 reportParseError("expected bitmask value");
4733 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
4734 reportParseError("bitmask not an absolute expression");
4738 if (Parser.getTok().is(AsmToken::Comma))
4741 reportParseError("unexpected token, expected comma");
4745 // Parse the frame_offset
4746 const MCExpr *FrameOffset;
4747 int64_t FrameOffsetVal;
4749 if (Parser.parseExpression(FrameOffset)) {
4750 reportParseError("expected frame offset value");
4754 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
4755 reportParseError("frame offset not an absolute expression");
4759 // If this is not the end of the statement, report an error.
4760 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4761 reportParseError("unexpected token, expected end of statement");
4765 if (IDVal == ".mask")
4766 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
4768 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
4772 if (IDVal == ".nan")
4773 return parseDirectiveNaN();
4775 if (IDVal == ".gpword") {
4776 parseDirectiveGpWord();
4780 if (IDVal == ".gpdword") {
4781 parseDirectiveGpDWord();
4785 if (IDVal == ".word") {
4786 parseDataDirective(4, DirectiveID.getLoc());
4790 if (IDVal == ".option")
4791 return parseDirectiveOption();
4793 if (IDVal == ".abicalls") {
4794 getTargetStreamer().emitDirectiveAbiCalls();
4795 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4796 Error(Parser.getTok().getLoc(),
4797 "unexpected token, expected end of statement");
4799 Parser.eatToEndOfStatement();
4804 if (IDVal == ".cpsetup")
4805 return parseDirectiveCPSetup();
4807 if (IDVal == ".module")
4808 return parseDirectiveModule();
4810 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
4811 return parseInternalDirectiveReallowModule();
4813 if (IDVal == ".insn")
4814 return parseInsnDirective();
4819 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
4820 // If this is not the end of the statement, report an error.
4821 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4822 reportParseError("unexpected token, expected end of statement");
4826 getTargetStreamer().reallowModuleDirective();
4828 getParser().Lex(); // Eat EndOfStatement token.
4832 extern "C" void LLVMInitializeMipsAsmParser() {
4833 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
4834 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
4835 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
4836 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
4839 #define GET_REGISTER_MATCHER
4840 #define GET_MATCHER_IMPLEMENTATION
4841 #include "MipsGenAsmMatcher.inc"